Component · 01
Button
Lifts off the page on hover and presses into it on click, like a stamp. Built on a native button, so keyboard and screen reader behaviour comes for free.
Variants
<Button variant="primary">Primary</Button>
<Button>Secondary</Button>
<Button variant="ghost">Ghost</Button>Sizes
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>With an icon
SVGs inside a button are sized to the text and never shrink.
<Button variant="primary">
Continue <ArrowIcon />
</Button>States
Loading keeps focus on the button, so a keyboard user does not lose their place; disabled removes it from the tab order.
<Button loading variant="primary">Saving</Button>
<Button disabled>Disabled</Button>
<Button disabled variant="ghost">Disabled</Button>As a link
render swaps the element and keeps its props. Style stays identical.
<Button render={<a href="https://github.com" />}>
GitHub
</Button>Override with Tailwind
All gnoud-ui styles live in a cascade layer, so your utilities win without !important.
<Button className="w-full rounded-full">Full width, pill</Button>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "primary" | "secondary" | "ghost" | "secondary" | Visual weight. Use one primary per screen. |
| size | "sm" | "md" | "lg" | "md" | Height and padding. |
| loading | boolean | false | Shows a spinner and ignores clicks. Stays focusable (aria-disabled), sets aria-busy. |
| disabled | boolean | false | Native disabled on a <button>; aria-disabled on a custom element. |
| render | ReactElement | - | Render another element, e.g. a link, keeping its own props. |
| type | string | "button" | Defaults to button so it never submits a form by accident. |
All other props of <button> (including ref) are passed through.