Button
nswds-ui/buttonFreeComponent
A button component with variants and sizes.
Install it
npx shadcn@latest add https://raw.githubusercontent.com/digitalnsw/nswds-ui/main/apps/registry/public/r/button.jsonSource
1'use client'23import { Button as ButtonPrimitive } from '@base-ui/react/button'4import { cva, type VariantProps } from 'class-variance-authority'5import clsx from 'clsx'6import React from 'react'78import { cn } from '@/lib/utils'910import { Link } from '@/components/link'11import { Spinner } from '@/components/spinner'1213const styles = {14 base: [15 // Base16 'relative isolate inline-flex items-baseline justify-center gap-x-2 rounded-sm border text-base/7 font-bold motion-safe:transition-all',17 // Height floor, published per size step as `--btn-h` (see `styles.size`).18 // A floor rather than a fixed height so a wrapped label can still grow.19 'min-h-(--btn-h)',20 // Border width, so the size steps can subtract it from their padding and21 // keep the outer box identical across variants. `outline` and `surface`22 // draw a 2px border and raise this to match; everything else stays 1px.23 // Without it the steps subtracted a hard-coded 1px and those two variants24 // came out 2px taller than `solid` at every step and breakpoint.25 '[--btn-border-w:1px]',26 // Focus — deliberately `focus:` (paints on pointer clicks too), unlike27 // Link/Input which use `focus-visible:`. Buttons give click feedback with28 // the ring; links only ring for keyboard/AT focus. Do not "unify" this.29 // The ring is offset 2px, so it lands on the *page* rather than on the30 // button. `--btn-bg` is the ink (see the note above `styles.colors`), which31 // flips for dark mode, so the ring follows the theme for every variant —32 // including `solid`, whose ring used to be its own fill colour and so went33 // near-invisible on a dark surface.34 'focus:outline focus:outline-2 focus:outline-offset-2 focus:outline-(--btn-bg)',35 // Disabled36 'data-disabled:opacity-50 data-disabled:pointer-events-none',37 // State overlays, derived from the ink rather than restated per colour.38 // Deriving them means they follow `--btn-bg` wherever it comes from: the39 // colour token, its dark-mode counterpart, or a surface that re-points the40 // ink at its own (`[--btn-bg:var(--footer-ink)]` in footer.tsx and41 // footer-cta.tsx). `solid` overrides both with its white/black pair at42 // `data-[variant=solid]:` — an attribute selector, so it outranks these43 // regardless of source order. `oklab` matches the interpolation space44 // Tailwind's own `/10` alpha modifier emits, so the painted colour is45// … 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 | |
| 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 | |
| Footerfooter | @nswds/ui | Components | Free | 3 deps · 2 files |
