Skip Link
nswds-ui/skip-linkFreeComponent
Focus-revealed bypass links (SkipLink + SkipLinks landmark) that let keyboard and screen-reader users jump past repeated blocks, with the same AAA colour variants as the Masthead.
Install it
npx shadcn@latest add https://raw.githubusercontent.com/digitalnsw/nswds-ui/main/apps/registry/public/r/skip-link.jsonSource
1'use client'23import { cva, type VariantProps } from 'class-variance-authority'4import React from 'react'56import { cn } from '@/lib/utils'78// Same curated WCAG 2.2 AAA (7:1) pairs as the Masthead — the two components9// are designed to be themed together, mirroring how the legacy10// `masthead-theme` option drove both `.nsw-masthead--light` and11// `.nsw-skip--light`. Kept as a local map (not imported from masthead.tsx) so12// each file stays standalone for registry distribution.13const skipLinkColors = {14 dark: 'bg-primary-800 text-white dark:bg-primary-950',15 light: 'bg-grey-100 text-grey-900',16 white: 'bg-white text-grey-900',17 grey: 'bg-grey-800 text-white',18}1920const skipLinkVariants = cva(21 [22 // Parked above the viewport until focused (legacy translateY(-101%)23 // pattern) — still in the tab order, so it is the first thing keyboard24 // and screen-reader users reach.25 'absolute inset-x-0 top-0 w-full -translate-y-[101%]',26 'motion-safe:transition-transform',27 'focus:translate-y-0',28 // min-h-11 keeps the revealed bar at ≥44px — 2.5.5 Target Size (AAA).29 //30 // text-base, not the legacy text-xs: this is the first thing a keyboard or31 // screen-magnifier user meets on the page, and 12px is below the smallest32 // step DESIGN.md names for running copy. font-medium keeps it in the33 // system's label voice. The bar is min-h-11, and 16px text on py-2 comes34 // to 40px, so the floor still governs the height — nothing moves.35 'group flex min-h-11 items-center px-4 py-2 text-base font-medium no-underline',36 // The visible focus indicator is the ring around the label span37 // (2.4.13 Focus Appearance): outline-current guarantees it contrasts with38 // the bar on every colour variant. outline-hidden (not outline-none) on39 // the anchor keeps a forced-colors fallback outline.40 'focus:outline-hidden',41 ],42 {43 variants: {44 color: skipLinkColors,45 },46 defaultVariants: {47 color: 'dark',48 },49 },50)5152/**53 * Move focus to the skip target. Fragment navigation alone only moves the54 * sequential-focus starting point; explicitly focusing the target makes55 * screen readers announce it. Non-focusable targets get a temporary56 * `tabindex="-1"` (removed on blur), matching the legacy skip-to behaviour.57 */58function focusSkipTarget(event: React.MouseEvent<HTMLAnchorElement>) {59 const hash = event.currentTarget.hash60 if (!hash || hash === '#') {61 return62 }6364 let id = hash.slice(1)65// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from @nswds/ui
All 46 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Aspect Ratioaspect-ratio | @nswds/ui | Components | Free | 2 deps · 2 files | |
| Badgebadge | @nswds/ui | Components | Free | 4 deps · 2 files | |
| Buttonbutton | @nswds/ui | Components | Free | 4 deps · 2 files | |
| Cardcard | @nswds/ui | Components | Free | 2 deps · 2 files | |
| Collapsiblecollapsible | @nswds/ui | Components | Free | 1 dep | |
| Drawerdrawer | @nswds/ui | Components | Free | 3 deps · 2 files | |
| Expandable Searchexpandable-search | @nswds/ui | Components | Free | 3 deps · 2 files | |
| Fieldfield | @nswds/ui | Components | Free | 4 deps · 2 files |
