Expandable Search
nswds-ui/expandable-searchFreeComponent
A 48px search button that expands into a text field on focus, with ink-derived surface colours matching the footer palette.
Install it
npx shadcn@latest add https://raw.githubusercontent.com/digitalnsw/nswds-ui/main/apps/registry/public/r/expandable-search.jsonSource
1'use client'23import { cva, type VariantProps } from 'class-variance-authority'4import React from 'react'56import { cn } from '@/lib/utils'78import { IconSearch } from '@/icons/search'910/**11 * Surface colours the search can be themed with — the footer's thirteen-name12 * vocabulary (see `footerColors` in footer.tsx) plus `default`, the nswds-app13 * grey-100 chip that headers embed on a white surface.14 *15 * Every derived colour resolves from a single `--search-ink` token, so a16 * variant only declares its surface utilities and that one value. This map17 * replaces the FOUR parallel 14-entry cva tables in the nswds-app source18 * (surface / collapsed / button / focus): each of those tables was a manual19 * projection of the same underlying ink, so they are collapsed into the20 * derivations below.21 *22 * The derivations are written literally here (once) rather than per-variant:23 * Tailwind scans source text for class names, so a template-built arbitrary24 * property would never be emitted. Mirrors footer.tsx (`--footer-*`) and25 * link.tsx (`--link-halo`).26 *27 * Expanded text/surface pairs are the ones verified for footer.tsx: every28 * light pair clears WCAG 2.2 AA (1.4.3, 4.5:1) — the worst are `primary-600`29 * (4.57:1) and `accent-600` (5.18:1) — and in dark mode all clear AAA (worst30 * 13.6:1). The collapsed chip renders no text, only the icon, which paints in31 * the same ink.32 */33const expandableSearchVariants = cva(34 [35 // `group/search` is named so the submit button's group-focus-within hook36 // can't collide with an ancestor's bare `group` (e.g. inside a card).37 'group/search relative inline-block rounded-sm select-none',38 // Halo for the submit button's hover / the form's focus-within state, a39 // heavier press halo, and the placeholder colour — all mixed down from40 // the ink. 70% ink keeps the placeholder related to but visibly lighter41 // than the entered text (the source used grey-700 / current at 70%42 // opacity). Dilution costs contrast, though, so the percentage routes43 // through --search-placeholder-pct and the surfaces whose 70% composite44 // fails 1.4.3 raise it to 100% in the variant map below. Verified by45 // alpha-compositing the mix over each surface (light mode): at 70%46 // primary-600 is 3.0:1, accent-600 3.1:1 and accent-400 4.48:1 — all47 // AA failures, cured by full ink (4.57 / 5.18 / 8.34:1). The eleven48 // surfaces that keep 70% all clear 4.5:1, the closest being49// … 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 | |
| Fieldfield | @nswds/ui | Components | Free | 4 deps · 2 files | |
| Footerfooter | @nswds/ui | Components | Free | 3 deps · 2 files |
