From 3843f9f28f8c4702cd786719a94de8ae3442e0cd Mon Sep 17 00:00:00 2001 From: 87xie Date: Fri, 30 Aug 2024 00:59:13 +0800 Subject: [PATCH 1/5] [v3] reduce focus-visible style conflicts with external components --- .changeset/wild-llamas-prove.md | 7 + packages/nextra-theme-blog/src/styles.css | 77 ++--- packages/nextra-theme-docs/css/styles.css | 301 +++++++++--------- .../nextra-theme-docs/src/components/404.tsx | 2 +- .../src/components/anchor.tsx | 6 +- .../src/components/back-to-top.tsx | 1 + .../src/components/banner.tsx | 2 +- .../src/components/bleed.tsx | 2 +- .../src/components/breadcrumb.tsx | 2 +- .../src/components/footer.tsx | 2 +- .../src/components/input.tsx | 1 + .../src/components/nav-links.tsx | 2 +- .../src/components/navbar.tsx | 2 +- .../src/components/search.tsx | 2 +- .../src/components/select.tsx | 2 +- .../src/components/sidebar.tsx | 2 +- .../src/components/skip-nav.tsx | 2 +- .../nextra-theme-docs/src/components/toc.tsx | 2 +- .../nextra-theme-docs/src/mdx-components.tsx | 5 +- .../nextra/src/client/components/button.tsx | 1 + .../nextra/src/client/components/cards.tsx | 1 + .../src/client/components/file-tree.tsx | 2 +- packages/nextra/src/client/components/pre.tsx | 2 +- .../nextra/src/client/components/tabs.tsx | 4 +- packages/nextra/styles/focus-ring.css | 25 ++ 25 files changed, 245 insertions(+), 212 deletions(-) create mode 100644 .changeset/wild-llamas-prove.md create mode 100644 packages/nextra/styles/focus-ring.css diff --git a/.changeset/wild-llamas-prove.md b/.changeset/wild-llamas-prove.md new file mode 100644 index 00000000000..9cdcfb9c5c9 --- /dev/null +++ b/.changeset/wild-llamas-prove.md @@ -0,0 +1,7 @@ +--- +'nextra-theme-blog': patch +'nextra-theme-docs': patch +'nextra': patch +--- + +reduce focus-visible style conflicts with external components. diff --git a/packages/nextra-theme-blog/src/styles.css b/packages/nextra-theme-blog/src/styles.css index cf7e12b3d95..978e9e23209 100644 --- a/packages/nextra-theme-blog/src/styles.css +++ b/packages/nextra-theme-blog/src/styles.css @@ -1,46 +1,51 @@ -@import 'tailwindcss/base'; -@import 'tailwindcss/components'; -@import 'tailwindcss/utilities'; -@import 'nextra/styles/code-block.css'; -@import 'nextra/styles/subheading-anchor.css'; -@import 'nextra/styles/scrollbar.css'; -@import 'nextra/styles/steps.css'; -@import 'nextra/styles/cards.css'; - -html { - @apply _scroll-pt-5; -} +@import 'tailwindcss/base' layer(nextra-base); +@import 'tailwindcss/components' layer(nextra-components); +@import 'nextra/styles/focus-ring.css' layer(nextra-components); +@import 'nextra/styles/code-block.css' layer(nextra-components); +@import 'nextra/styles/subheading-anchor.css' layer(nextra-components); +@import 'nextra/styles/scrollbar.css' layer(nextra-components); +@import 'nextra/styles/steps.css' layer(nextra-components); +@import 'nextra/styles/cards.css' layer(nextra-components); +@import 'tailwindcss/utilities' layer(nextra-utilities); + +@layer nextra-base { + html { + @apply _scroll-pt-5; + } -body { - @apply _px-4 _bg-[rgb(var(--nextra-bg))]; -} + body { + @apply _px-4 _bg-[rgb(var(--nextra-bg))]; + } -article { - @apply _mx-auto _block _pt-20 _pb-32; -} + article { + @apply _mx-auto _block _pt-20 _pb-32; + } -article img { - @apply _mx-auto; -} + article img { + @apply _mx-auto; + } -h1 { - letter-spacing: -0.03em; + h1 { + letter-spacing: -0.03em; + } } -._prose code { - &:before, - &:after { - @apply _hidden; +@layer nextra-components { + ._prose code { + &:before, + &:after { + @apply _hidden; + } + .line { + @apply _font-normal; + } } - .line { - @apply _font-normal; - } -} -._prose .nextra-callout p { - @apply _m-0; -} + ._prose .nextra-callout p { + @apply _m-0; + } -.footnotes a[data-footnote-backref] { - font-family: initial; + .footnotes a[data-footnote-backref] { + font-family: initial; + } } diff --git a/packages/nextra-theme-docs/css/styles.css b/packages/nextra-theme-docs/css/styles.css index 14222949671..a176aea6a60 100644 --- a/packages/nextra-theme-docs/css/styles.css +++ b/packages/nextra-theme-docs/css/styles.css @@ -1,193 +1,182 @@ -@import 'tailwindcss/base'; -@import 'tailwindcss/components'; -@import 'tailwindcss/utilities'; -@import 'nextra/styles/code-block.css'; -@import 'nextra/styles/subheading-anchor.css'; -@import 'nextra/styles/scrollbar.css'; -@import 'nextra/styles/steps.css'; -@import 'nextra/styles/cards.css'; -@import './hamburger.css'; -@import './typesetting-article.css'; - -html { - @apply _antialiased _text-base _scroll-pt-[--nextra-navbar-height]; - font-feature-settings: - 'rlig' 1, - 'calt' 1, - 'ss01' 1; - -webkit-tap-highlight-color: transparent; -} +@import 'tailwindcss/base' layer(nextra-base); +@import 'tailwindcss/components' layer(nextra-components); +@import 'nextra/styles/code-block.css' layer(nextra-components); +@import 'nextra/styles/subheading-anchor.css' layer(nextra-components); +@import 'nextra/styles/scrollbar.css' layer(nextra-components); +@import 'nextra/styles/steps.css' layer(nextra-components); +@import 'nextra/styles/cards.css' layer(nextra-components); +@import 'nextra/styles/focus-ring.css' layer(nextra-components); +@import './hamburger.css' layer(nextra-components); +@import './typesetting-article.css' layer(nextra-components); +@import 'tailwindcss/utilities' layer(nextre-utilities); + +@layer nextra-base { + html { + @apply _antialiased _text-base _scroll-pt-[--nextra-navbar-height]; + font-feature-settings: + 'rlig' 1, + 'calt' 1, + 'ss01' 1; + -webkit-tap-highlight-color: transparent; + } -body { - @apply _w-full dark:_text-gray-100; -} + body { + @apply _w-full dark:_text-gray-100; + } -a, -summary, -button, -input, -[tabindex]:not([tabindex='-1']) { - &:focus-visible { - @apply _outline-none; - @apply _ring-2 _ring-primary-200 _ring-offset-1 _ring-offset-primary-300 dark:_ring-primary-800 dark:_ring-offset-primary-700; + /* Content Typography */ + summary::-webkit-details-marker { + @apply _hidden; + } + input[type='search'] { + &::-webkit-search-decoration, + &::-webkit-search-cancel-button, + &::-webkit-search-results-button, + &::-webkit-search-results-decoration { + -webkit-appearance: none; + } } } -a, -summary { - @apply _rounded; -} +@layer nextra-components { + .nextra-content { + @apply _text-slate-700 dark:_text-slate-200; + } -.nextra-content { - @apply _text-slate-700 dark:_text-slate-200; -} + @media (max-width: 767px) { + .nextra-sidebar-container { + @apply _fixed _pt-[calc(var(--nextra-navbar-height))] _top-0 _w-full _bottom-0 _z-[15] _overscroll-contain; + transition: transform 0.8s cubic-bezier(0.52, 0.16, 0.04, 1); + will-change: transform, opacity; + contain: layout style; + backface-visibility: hidden; + + & > .nextra-scrollbar { + mask-image: linear-gradient(to bottom, transparent, #000 20px), + linear-gradient(to left, #000 10px, transparent 10px); + } + } -@media (max-width: 767px) { - .nextra-sidebar-container { - @apply _fixed _pt-[calc(var(--nextra-navbar-height))] _top-0 _w-full _bottom-0 _z-[15] _overscroll-contain; - transition: transform 0.8s cubic-bezier(0.52, 0.16, 0.04, 1); - will-change: transform, opacity; - contain: layout style; - backface-visibility: hidden; + .nextra-banner-container ~ div { + .nextra-sidebar-container { + @apply _pt-[6.5rem]; + } - & > .nextra-scrollbar { - mask-image: linear-gradient(to bottom, transparent, #000 20px), - linear-gradient(to left, #000 10px, transparent 10px); + &.nextra-nav-container { + @apply _top-10 md:_top-0; + } } - } - .nextra-banner-container ~ div { - .nextra-sidebar-container { - @apply _pt-[6.5rem]; + .nextra-banner-hidden { + .nextra-banner-container ~ div .nextra-sidebar-container { + @apply _pt-16; + } + + .nextra-nav-container { + @apply !_top-0; + } } - &.nextra-nav-container { - @apply _top-10 md:_top-0; + + .nextra-search .excerpt { + @apply _overflow-hidden _text-ellipsis; + display: -webkit-box; + line-clamp: 1; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; } } - .nextra-banner-hidden { - .nextra-banner-container ~ div .nextra-sidebar-container { - @apply _pt-16; - } - .nextra-nav-container { - @apply !_top-0; + + @media (prefers-reduced-motion: reduce) and (max-width: 767px) { + article:before, + .nextra-sidebar-container, + .nextra-sidebar-container.open, + body.resizing .nextra-sidebar-container { + @apply _transition-none; } } - .nextra-search .excerpt { - @apply _overflow-hidden _text-ellipsis; - display: -webkit-box; - line-clamp: 1; - -webkit-line-clamp: 1; - -webkit-box-orient: vertical; - } -} -@media (prefers-reduced-motion: reduce) and (max-width: 767px) { - article:before, - .nextra-sidebar-container, - .nextra-sidebar-container.open, - body.resizing .nextra-sidebar-container { - @apply _transition-none; + @media (min-width: 768px) { + .nextra-toc > .div, + .nextra-sidebar-container { + mask-image: linear-gradient(to bottom, transparent, #000 20px), + linear-gradient(to left, #000 10px, transparent 10px); + } } -} -/* Content Typography */ -summary::-webkit-details-marker { - @apply _hidden; -} + .nextra-banner-hidden .nextra-banner-container { + @apply _hidden; + } -@media (min-width: 768px) { - .nextra-toc > .div, .nextra-sidebar-container { - mask-image: linear-gradient(to bottom, transparent, #000 20px), - linear-gradient(to left, #000 10px, transparent 10px); - } -} + [data-toggle-animation='show'] button { + opacity: 0; + animation: nextra-fadein 1s ease 0.2s forwards; + } -input[type='search'] { - &::-webkit-search-decoration, - &::-webkit-search-cancel-button, - &::-webkit-search-results-button, - &::-webkit-search-results-decoration { - -webkit-appearance: none; + [data-toggle-animation='hide'] button { + opacity: 0; + animation: nextra-fadein2 1s ease 0.2s forwards; + } } -} -.contains-task-list { - @apply _ml-0 _list-none; - input[type='checkbox'] { - @apply _mr-1; + .footnotes a[data-footnote-backref] { + font-family: initial; } -} -.nextra-banner-hidden .nextra-banner-container { - @apply _hidden; -} + @keyframes nextra-fadein { + 0% { + opacity: 0; + } -.nextra-sidebar-container { - [data-toggle-animation='show'] button { - opacity: 0; - animation: nextra-fadein 1s ease 0.2s forwards; - } - [data-toggle-animation='hide'] button { - opacity: 0; - animation: nextra-fadein2 1s ease 0.2s forwards; + 100% { + opacity: 1; + } } -} -.footnotes a[data-footnote-backref] { - font-family: initial; -} + @keyframes nextra-fadein2 { + 0% { + opacity: 0; + } -@keyframes nextra-fadein { - 0% { - opacity: 0; - } - 100% { - opacity: 1; + 100% { + opacity: 1; + } } -} -@keyframes nextra-fadein2 { - 0% { - opacity: 0; - } - 100% { - opacity: 1; + body, + .nextra-nav-container-blur, + .nextra-toc-footer, + .nextra-sidebar-footer { + @apply _bg-[rgb(var(--nextra-bg))]; } -} -body, -.nextra-nav-container-blur, -.nextra-toc-footer, -.nextra-sidebar-footer { - @apply _bg-[rgb(var(--nextra-bg))]; -} -.nextra-sidebar-container { - @apply max-md:_bg-[rgb(var(--nextra-bg))]; -} + .nextra-sidebar-container { + @apply max-md:_bg-[rgb(var(--nextra-bg))]; + } -.nextra-nav-container-blur { - @apply _pointer-events-none _absolute _z-[-1] _size-full; - @apply _shadow-[0_2px_4px_rgba(0,0,0,.02),0_1px_0_rgba(0,0,0,.06)]; - @apply dark:_shadow-[0_-1px_0_rgba(255,255,255,.1)_inset]; - @apply contrast-more:_shadow-[0_0_0_1px_#000]; - @apply contrast-more:dark:_shadow-[0_0_0_1px_#fff]; - @apply _backdrop-blur-md _bg-[rgba(var(--nextra-bg),.7)]; -} + .nextra-nav-container-blur { + @apply _pointer-events-none _absolute _z-[-1] _size-full; + @apply _shadow-[0_2px_4px_rgba(0,0,0,.02),0_1px_0_rgba(0,0,0,.06)]; + @apply dark:_shadow-[0_-1px_0_rgba(255,255,255,.1)_inset]; + @apply contrast-more:_shadow-[0_0_0_1px_#000]; + @apply contrast-more:dark:_shadow-[0_0_0_1px_#fff]; + @apply _backdrop-blur-md _bg-[rgba(var(--nextra-bg),.7)]; + } -.nextra-toc-footer, -.nextra-sidebar-footer { - @apply _border-t dark:_border-neutral-800; - @apply contrast-more:_shadow-none contrast-more:_border-neutral-400 contrast-more:dark:_border-neutral-400; - @apply _shadow-[0_-12px_16px_rgb(var(--nextra-bg))]; -} + .nextra-toc-footer, + .nextra-sidebar-footer { + @apply _border-t dark:_border-neutral-800; + @apply contrast-more:_shadow-none contrast-more:_border-neutral-400 contrast-more:dark:_border-neutral-400; + @apply _shadow-[0_-12px_16px_rgb(var(--nextra-bg))]; + } -.nextra-search-results { - @apply _border _border-gray-200 _text-gray-100 dark:_border-neutral-800; - @apply _absolute _top-full _z-20 _mt-2 _overflow-auto _overscroll-contain _rounded-xl _py-2.5 _shadow-xl; - @apply _max-h-[min(calc(50vh-11rem-env(safe-area-inset-bottom)),400px)]; - @apply md:_max-h-[min(calc(100vh-5rem-env(safe-area-inset-bottom)),400px)]; - @apply _inset-x-0 ltr:md:_left-auto rtl:md:_right-auto; - @apply contrast-more:_border contrast-more:_border-gray-900 contrast-more:dark:_border-gray-50; - @apply _backdrop-blur-lg _bg-[rgb(var(--nextra-bg),.8)]; + .nextra-search-results { + @apply _border _border-gray-200 _text-gray-100 dark:_border-neutral-800; + @apply _absolute _top-full _z-20 _mt-2 _overflow-auto _overscroll-contain _rounded-xl _py-2.5 _shadow-xl; + @apply _max-h-[min(calc(50vh-11rem-env(safe-area-inset-bottom)),400px)]; + @apply md:_max-h-[min(calc(100vh-5rem-env(safe-area-inset-bottom)),400px)]; + @apply _inset-x-0 ltr:md:_left-auto rtl:md:_right-auto; + @apply contrast-more:_border contrast-more:_border-gray-900 contrast-more:dark:_border-gray-50; + @apply _backdrop-blur-lg _bg-[rgb(var(--nextra-bg),.8)]; + } } diff --git a/packages/nextra-theme-docs/src/components/404.tsx b/packages/nextra-theme-docs/src/components/404.tsx index 6711b4630bd..711b69a22fb 100644 --- a/packages/nextra-theme-docs/src/components/404.tsx +++ b/packages/nextra-theme-docs/src/components/404.tsx @@ -24,7 +24,7 @@ export function NotFoundPage(): ReactElement | null { labels })} newWindow - className="_text-primary-600 _underline _decoration-from-font [text-underline-position:from-font]" + className="nextra-focus-ring _text-primary-600 _underline _decoration-from-font [text-underline-position:from-font]" > {renderComponent(content)} diff --git a/packages/nextra-theme-docs/src/components/anchor.tsx b/packages/nextra-theme-docs/src/components/anchor.tsx index 4210a69f106..55cc349a58d 100644 --- a/packages/nextra-theme-docs/src/components/anchor.tsx +++ b/packages/nextra-theme-docs/src/components/anchor.tsx @@ -2,6 +2,7 @@ import NextLink from 'next/link' import type { ComponentProps, ReactElement } from 'react' import { forwardRef } from 'react' +import cn from 'clsx' export type AnchorProps = Omit, 'ref'> & { newWindow?: boolean @@ -9,7 +10,7 @@ export type AnchorProps = Omit, 'ref'> & { export const Anchor = forwardRef( ( - { href = '', children, newWindow, ...props }, + { href = '', children, newWindow, className, ...props }, // ref is used in forwardedRef ): ReactElement => { @@ -18,6 +19,7 @@ export const Anchor = forwardRef( ( } return ( - + {children} ) diff --git a/packages/nextra-theme-docs/src/components/back-to-top.tsx b/packages/nextra-theme-docs/src/components/back-to-top.tsx index e141649dd7d..f8c5ee1d8d0 100644 --- a/packages/nextra-theme-docs/src/components/back-to-top.tsx +++ b/packages/nextra-theme-docs/src/components/back-to-top.tsx @@ -30,6 +30,7 @@ export function BackToTop({ onClick={scrollToTop} disabled={hidden} className={cn( + 'nextra-focus-ring', '_flex _items-center _gap-1.5 _transition _opacity-100 disabled:_opacity-0', className )} diff --git a/packages/nextra-theme-docs/src/components/banner.tsx b/packages/nextra-theme-docs/src/components/banner.tsx index 814b5150208..a6cc07cf7a2 100644 --- a/packages/nextra-theme-docs/src/components/banner.tsx +++ b/packages/nextra-theme-docs/src/components/banner.tsx @@ -31,7 +31,7 @@ export function Banner(): ReactElement | null {