mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
feat(docs): add keyboard-accessible skip to content link (#47515)
https://github.com/user-attachments/assets/30438e3c-b9aa-411b-be38-3fdcd50f7dc6 Closes DOCS-92 ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## Problem Screenreaders have to navigate our main menu on every page. This comes from a very old request. 2024. 😱 ## Solution A 'Skip to Content' button is standard a11y practice. This PR improves keyboard navigation by letting users bypass the top nav and sidebar to jump directly to main content. ## Tophatting 1. Go to any page in our docs. Try a sample of different layouts. 2. Use TAB to navigate. See 'Skip to Content' appear. **Note:** You may need to SHIFT + TAB if your keyboard focus is past the main navigation. Mouse clicks can shift focus. 3. Press ENTER. 4. Continue to TAB and see the next links focused are in the main body. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a “skip to content” button in the docs to improve keyboard navigation. * **Accessibility / UX** * Made the main content area programmatically focusable and adjusted scroll positioning for smoother jumps. * **Style** * Removed the prior global skip-link styles in favor of component-based skip-to-content behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
a1716edc3c
commit
4f05124ce7
4 files changed
+26
-8
No files matched your search
@@ -4,6 +4,7 @@ import 'ui-patterns/ShimmeringLoader/index.css'
|
||||
import '../styles/globals.css'
|
||||
import '../styles/prism-okaidia.css'
|
||||
|
||||
import { SkipToContent } from '~/components/SkipToContent'
|
||||
import { GlobalProviders } from '~/features/app.providers'
|
||||
import { TopNavSkeleton } from '~/layouts/MainSkeleton'
|
||||
import { BASE_PATH, IS_PRODUCTION } from '~/lib/constants'
|
||||
@@ -54,6 +55,7 @@ const RootLayout = ({ children }: { children: React.ReactNode }) => {
|
||||
return (
|
||||
<html lang="en" className={`${manrope.variable} ${inter.variable}`} suppressHydrationWarning>
|
||||
<body>
|
||||
<SkipToContent />
|
||||
<TelemetryTagManager />
|
||||
<GlobalProviders>
|
||||
<TopNavSkeleton>{children}</TopNavSkeleton>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { DOCS_CONTENT_CONTAINER_ID } from '~/features/ui/helpers.constants'
|
||||
import Link from 'next/link'
|
||||
import { Button, cn } from 'ui'
|
||||
|
||||
const SkipToContent = () => {
|
||||
return (
|
||||
<Button
|
||||
size="tiny"
|
||||
variant="default"
|
||||
asChild
|
||||
className={cn(
|
||||
'fixed top-0 left-4 z-[100] w-auto',
|
||||
'-translate-y-full focus-visible:translate-y-4',
|
||||
'transition-transform duration-200 ease-out'
|
||||
)}
|
||||
>
|
||||
<Link href={`#${DOCS_CONTENT_CONTAINER_ID}`}>Skip to content</Link>
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
||||
export { SkipToContent }
|
||||
@@ -283,8 +283,9 @@ const Container = memo(function Container({
|
||||
<main
|
||||
// used by layout to scroll to top
|
||||
id={DOCS_CONTENT_CONTAINER_ID}
|
||||
tabIndex={-1}
|
||||
className={cn(
|
||||
'w-full transition-all ease-out relative',
|
||||
'w-full transition-all ease-out relative scroll-mt-(--header-height)',
|
||||
// desktop override any margin styles
|
||||
'lg:ml-0',
|
||||
className
|
||||
|
||||
@@ -406,13 +406,6 @@ th code {
|
||||
image-rendering: high-quality;
|
||||
}
|
||||
|
||||
.skip-link {
|
||||
@apply sr-only;
|
||||
}
|
||||
.skip-link:focus {
|
||||
@apply not-sr-only;
|
||||
}
|
||||
|
||||
/* Code blocks need margin applied when in content container */
|
||||
.prose :where(.shiki:not(.shiki-wrapper *), .shiki-wrapper) {
|
||||
margin-block: 2rem;
|
||||
|
||||
Reference in new issue
Block a user