Pixie
View as Markdown

Button

A clickable element that triggers an action.

Props#

NameTypeDefaultDescription
variant"primary" | "secondary" | "ghost" | "danger"primaryVisual style variant.
size"sm" | "md" | "lg"mdButton size.
disabledbooleanfalseDisable the button — non-interactive and visually muted.
loadingbooleanfalseShow a loading indicator instead of children.
fullWidthbooleanfalseStretch the button to fill its container's width.
onClick(() => void)Click handler.
children*ReactNodeButton label.

Interactive#

Show code
Interactive.stories.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 <Button {...props} />;
}

Variants#

Show code
import { Button } from '../../../src/pixie/Button.js';
import styles from './Variants.module.css';

export default () => (
  <div className={styles.row}>
    <Button variant="primary">Primary</Button>
    <Button variant="secondary">Secondary</Button>
    <Button variant="ghost">Ghost</Button>
    <Button variant="danger">Delete</Button>
  </div>
);

Sizes#

Show code
import { Button } from '../../../src/pixie/Button.js';
import styles from './Sizes.module.css';

export default () => (
  <div className={styles.row}>
    <Button size="sm">Small</Button>
    <Button size="md">Medium</Button>
    <Button size="lg">Large</Button>
  </div>
);

Loading#

Show code
Loading.stories.tsx
import { Button } from '../../../src/pixie/Button.js';

export default () => <Button loading>Saving</Button>;

Disabled#

Show code
Disabled.stories.tsx
import { Button } from '../../../src/pixie/Button.js';

export default () => <Button disabled>Unavailable</Button>;

Full width#

Show code
FullWidth.stories.tsx
import { Button } from '../../../src/pixie/Button.js';

export default () => (
  <div style={{ width: 320 }}>
    <Button fullWidth>Full width</Button>
  </div>
);