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>
69 lines
2.4 KiB
Markdown
69 lines
2.4 KiB
Markdown
# 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)
|
||
|
||
```tsx
|
||
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
|