diff --git a/plans/button.md b/plans/button.md new file mode 100644 index 0000000..d140a44 --- /dev/null +++ b/plans/button.md @@ -0,0 +1,68 @@ +# 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 { + 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 ` + + + + ), +} + +export const AllVariants: Story = { + render: () => ( +
+ + + +
+ ), +} + +export const AllColours: Story = { + render: () => ( +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ ), } export const Disabled: Story = { - args: { children: 'Disabled', disabled: true }, + render: () => ( +
+ + + +
+ ), } diff --git a/src/components/ui/Button/Button.tsx b/src/components/ui/Button/Button.tsx index 84244ad..c5b0a26 100644 --- a/src/components/ui/Button/Button.tsx +++ b/src/components/ui/Button/Button.tsx @@ -2,30 +2,82 @@ import { forwardRef, type ButtonHTMLAttributes } from 'react' import { cn } from '@/lib/utils' export interface ButtonProps extends ButtonHTMLAttributes { - variant?: 'primary' | 'secondary' | 'danger' - size?: 'sm' | 'md' | 'lg' + variant?: 'primary' | 'secondary' | 'tertiary' + color?: 'navy' | 'red' | 'light' | 'surface' + size?: 'default' | 'comfortable' | 'compact' + leftIcon?: React.ReactNode + rightIcon?: React.ReactNode +} + +const variantColorStyles: Record> = { + primary: { + navy: 'bg-blue-01 text-white hover:bg-blue-01/90 active:bg-blue-01/80', + red: 'bg-red-02 text-white hover:bg-red-02/90 active:bg-red-02/80', + light: 'bg-blue-04 text-blue-01 hover:bg-blue-04/80 active:bg-blue-04/60', + surface: 'bg-grey-01 text-white hover:bg-grey-01/90 active:bg-grey-01/80', + }, + secondary: { + navy: 'border-2 border-blue-01 text-blue-01 hover:bg-blue-01/5 active:bg-blue-01/10', + red: 'border-2 border-red-02 text-red-02 hover:bg-red-02/5 active:bg-red-02/10', + light: 'border-2 border-blue-01 text-blue-01 hover:bg-blue-01/5 active:bg-blue-01/10', + surface: 'border-2 border-grey-01 text-grey-01 hover:bg-grey-01/5 active:bg-grey-01/10', + }, + tertiary: { + navy: 'text-blue-01 hover:bg-blue-01/5 active:bg-blue-01/10', + red: 'text-red-02 hover:bg-red-02/5 active:bg-red-02/10', + light: 'text-blue-01 hover:bg-blue-01/5 active:bg-blue-01/10', + surface: 'text-grey-01 hover:bg-grey-01/5 active:bg-grey-01/10', + }, +} + +const sizeStyles: Record = { + default: 'h-12 px-6 text-body gap-2', + comfortable: 'h-10 px-5 text-body gap-2', + compact: 'h-9 px-4 text-small gap-1.5', +} + +const iconSizeStyles: Record = { + default: 'size-6', + comfortable: 'size-5', + compact: 'size-5', } export const Button = forwardRef( - ({ className, variant = 'primary', size = 'md', children, ...props }, ref) => { + ( + { + variant = 'primary', + color = 'navy', + size = 'default', + leftIcon, + rightIcon, + disabled, + className, + children, + ...props + }, + ref, + ) => { return ( ) },