# Button A clickable element that triggers an action. ## Props | Name | Type | Default | Description | | --- | --- | --- | --- | | `variant` | `"primary" \| "secondary" \| "ghost" \| "danger"` | `primary` | Visual style variant. | | `size` | `"sm" \| "md" \| "lg"` | `md` | Button size. | | `disabled` | `boolean` | `false` | Disable the button — non-interactive and visually muted. | | `loading` | `boolean` | `false` | Show a loading indicator instead of children. | | `fullWidth` | `boolean` | `false` | Stretch the button to fill its container's width. | | `onClick` | `(() => void)` | — | Click handler. | | `children` \* | `ReactNode` | — | Button label. | ## Interactive **`Interactive.stories.tsx`** ```tsx import { Button, type ButtonProps } from '../../../src/pixie/Button.js'; /** * Interactive story: every prop in `args` becomes a control below the * preview. Changing a control re-mounts the story with the new props. */ export const args: ButtonProps & { children: string } = { variant: 'primary', size: 'md', disabled: false, loading: false, fullWidth: false, children: 'Click me', }; /** * Optional explicit control types. If omitted, Markbook infers from the * runtime arg value (boolean → checkbox, number → number input, else text). */ export const argTypes = { variant: { control: 'select' as const, options: ['primary', 'secondary', 'ghost', 'danger'], }, size: { control: 'select' as const, options: ['sm', 'md', 'lg'] }, disabled: { control: 'boolean' as const }, loading: { control: 'boolean' as const }, fullWidth: { control: 'boolean' as const }, children: { control: 'text' as const }, }; export const parameters = { layout: 'centered' as const, }; export default function Interactive(props: typeof args) { return ); ``` **`Variants.module.css`** ```css /* CSS Module — class names are scoped/hashed by Vite. */ .row { display: flex; gap: 0.5rem; flex-wrap: wrap; padding: 0.75rem; border: 1px dashed var(--mb-accent, #6c5ce7); border-radius: 6px; } ``` ## Sizes **`Sizes.stories.tsx`** ```tsx import { Button } from '../../../src/pixie/Button.js'; import styles from './Sizes.module.css'; export default () => (
); ``` **`Sizes.module.css`** ```css .row { display: flex; gap: 0.5rem; align-items: center; } ``` ## Loading **`Loading.stories.tsx`** ```tsx import { Button } from '../../../src/pixie/Button.js'; export default () => ; ``` ## Disabled **`Disabled.stories.tsx`** ```tsx import { Button } from '../../../src/pixie/Button.js'; export default () => ; ``` ## Full width **`FullWidth.stories.tsx`** ```tsx import { Button } from '../../../src/pixie/Button.js'; export default () => (
); ```