Button
Triggers an action or navigation. Supports multiple visual variants, sizes, loading and disabled states.
Variants
Primary Secondary Ghost Danger Success Warning
| 1 | <nana-button variant="primary">Primary</nana-button> |
| 2 | <nana-button variant="secondary">Secondary</nana-button> |
| 3 | <nana-button variant="ghost">Ghost</nana-button> |
| 4 | <nana-button variant="danger">Danger</nana-button> |
| 5 | <nana-button variant="success">Success</nana-button> |
| 6 | <nana-button variant="warning">Warning</nana-button> |
Sizes
XSmall Small Medium Large XLarge
| 1 | <nana-button size="xs">XSmall</nana-button> |
| 2 | <nana-button size="sm">Small</nana-button> |
| 3 | <nana-button size="md">Medium</nana-button> |
| 4 | <nana-button size="lg">Large</nana-button> |
| 5 | <nana-button size="xl">XLarge</nana-button> |
States
Disabled Loading
| 1 | <nana-button disabled>Disabled</nana-button> |
| 2 | <nana-button loading>Loading</nana-button> |
Customization
Reach for the simplest tool that does the job — most of the time that's a
variant
and a size,
not custom CSS:
- Variants carry the design decisions —
primary, secondary, danger… - Size controls scale — don't set padding or font-size by hand.
- Boolean props (
disabled, loading, full-width) are behaviour. - Slots (
prefix / suffix) compose content like icons.
When you need to match a brand, there are exactly two theming hooks — a small
set of CSS variables for colour and
radius, and the base part for
everything else. (Plain CSS like
nana-button { background: red }
can't reach into the Shadow DOM, which is why these exist.)
Buy now Pill Subscribe
CSS variables — colour & radius
| 1 | /* Set a brand colour — hover and active states follow automatically. |
| 2 | Scope it to a subtree, or use the style attribute for one instance. */ |
| 3 | .checkout { |
| 4 | --nana-button-bg: #2563eb; |
| 5 | --nana-button-radius: 9999px; |
| 6 | } |
| 1 | <!-- A single instance — one variable is enough --> |
| 2 | <nana-button style="--nana-button-bg:#2563eb">Buy now</nana-button> |
Parts — everything else
| 1 | <!-- Parts: full CSS control for anything a variable doesn't cover --> |
| 2 | <style> |
| 3 | nana-button.cta::part(base) { |
| 4 | text-transform: uppercase; |
| 5 | letter-spacing: 0.05em; |
| 6 | background: linear-gradient(90deg, #2563eb, #0ea5e9); |
| 7 | color: #fff; |
| 8 | } |
| 9 | </style> |
| 10 | <nana-button class="cta">Subscribe</nana-button> |
Props
| Attribute | Type | Default | Description |
variant | primary | secondary | ghost | danger | success | warning | primary | Visual style |
size | xs | sm | md | lg | xl | md | Button size |
disabled | boolean | false | Disables interaction |
loading | boolean | false | Shows spinner, disables button |
full-width | boolean | false | Stretches to 100% width |
type | button | submit | reset | button | Native button type |
Events
| Event | Detail | Description |
nana-click | — | Fired on click (not fired when disabled or loading) |
Slots
| Slot | Description |
| (default) | Button label |
prefix | Icon or content before label |
suffix | Icon or content after label |
CSS Custom Properties
| Property | Description |
--nana-button-bg | Background colour — the hover state derives from it automatically |
--nana-button-color | Text colour |
--nana-button-radius | Corner radius (overrides the rounded attribute) |
CSS Parts
| Part | Description |
base | The underlying <button> or <a> element |
loader | The spinner shown while loading |