Files
ADS3-Design-System/plans/button.md
Richie 40d53f86dd Add Button component with NSW DS variants, colours, sizes, and icons
Pill-shaped button with three variants (primary/secondary/tertiary),
four colour schemes (navy/red/light/surface), three sizes, and optional
left/right icon slots. 17 Storybook stories cover all combinations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-21 11:56:03 +10:00

2.4 KiB
Raw Blame History

Button Component Plan

Source

Example pasted into Figma Examples page (node 10:20). Original has 5 properties × many values = 360+ variants. We're building the light-mode subset.

Props (React)

interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: 'primary' | 'secondary' | 'tertiary'
  color?: 'navy' | 'red' | 'light' | 'surface'
  size?: 'default' | 'comfortable' | 'compact'
  leftIcon?: React.ReactNode
  rightIcon?: React.ReactNode
}
  • children is the label text
  • States (hover, active, focus, disabled) handled via CSS pseudo-classes
  • Uses forwardRef to wrap <button>

Colour Scheme Mapping

Prop value Example name Primary bg Primary text Secondary border Our tokens
navy Navy #002664 white #002664 blue-01, white
red Red #D7153A white #D7153A red-02, white
light On Primary (Teal) #CBEDFD #002664 #002664 blue-04, blue-01
surface On Surface #22272B white #22272B grey-01*, white

*Note: source uses #22272B, our grey-01 is #3D3D3D. Close enough for now — revisit if the NSW DS specifies #22272B.

Variant × Colour behaviour

  • Primary: filled background, white or dark text
  • Secondary: transparent bg, 2px border, coloured text
  • Tertiary: no fill, no border, coloured text (ghost)

Sizes

Size Height Padding Typography
Default 48px 24px horizontal Body Strong (16/24 bold)
Comfortable 40px 20px horizontal Body Strong (16/24 bold)
Compact 36px 16px horizontal Small Strong (14/19 bold)

Shared Styling

  • Border radius: rounded-full (pill shape, 9999px)
  • Icon size: 24px (default), 20px (compact)
  • Content gap: 8px
  • Focus ring: 2px border offset (matches example's "Border" layer)
  • Disabled: opacity 50%, cursor not-allowed

Hover/Active States

  • Primary: overlay with white at ~10% opacity (hover), ~20% (active)
  • Secondary/Tertiary: bg fill at ~5% opacity (hover), ~10% (active)
  • Implementation: CSS hover: and active: with bg-opacity modifiers

Build Order

  1. Add tokens (if needed) to tokens.css
  2. Build React component + stories
  3. Build Figma component on Components page (rebind to our variables)
  4. Code Connect link
  5. addon-designs embed in story

Questions resolved

  • All four colour schemes included
  • Icon slots as ReactNode
  • No dark mode