kai-button
The kit’s button as a drop-in web component — five variants, text and icon sizes, leading and trailing icons, and a slot for your own SVG. Compose polished, theme-aware controls instead of hand-rolling a <button> plus hover styles.
- Shadow DOM
- 5 variants
- Named + URL icons
- Emits kai-click
Preview
Section titled “Preview”Put the label as light-DOM text inside the element. Set variant and size for emphasis and footprint, add icon for a leading glyph, and listen for kai-click. For an icon-only button, drop the text, set size="icon", and name it with label.
<kai-button variant="subtle" size="icon" icon="mic" label="Voice input"></kai-button><kai-button variant="ghost" icon-trailing="chevron-down">High</kai-button><kai-button>Send</kai-button>Examples
Section titled “Examples”Variants
Section titled “Variants”variant sets the emphasis: default (filled), subtle (muted text, hover tint — the toolbar look), ghost (transparent, hover fill), outline, and destructive.
sm, md (default), and lg size text buttons.
Icon-only
Section titled “Icon-only”Drop the text, use a square size (icon / icon-sm), and set label for the accessible name. icon takes a named icon, an image URL, or a data-URI.
Trailing icon
Section titled “Trailing icon”icon-trailing sits after the label — a chevron-down reads as a menu affordance.
Custom icon via slot
Section titled “Custom icon via slot”For a glyph the icon prop can’t name — your own SVG, an icon library — slot it into slot="icon"; it wins over the icon prop. Keep label for the accessible name.
The label is the default slot; icon is the one named seam:
| Slot | Mode | Purpose |
|---|---|---|
| icon | replace | A custom leading icon (any inline SVG, inherits `currentColor`). Wins over the `icon` prop. |
<kai-button label="Ship"> <svg slot="icon" viewBox="0 0 24 24" width="16" height="16"><!-- your glyph --></svg> Ship it</kai-button>Styling
Section titled “Styling”The whole button is one ::part — restyle radius, padding, color, or weight from outside while keeping variant/size as the defaults.
| Part | Purpose | Example |
|---|---|---|
| button | The button element. Restyle radius, padding, colors, or weight from outside; the `variant`/`size` props set the defaults. | |
| Property | Type | Default | Notes |
|---|---|---|---|
| variant | "default" | "subtle" | "ghost" | "outline" | "destructive" | 'default' | Visual style. `default` (filled), `subtle` (muted text, hover tint — the toolbar icon look), `ghost` (transparent, hover fill), `outline`, or `destructive`. Defaults to `default`. |
| size | "sm" | "md" | "lg" | "icon" | "icon-sm" | 'md' | Size token. `icon` / `icon-sm` are square (for icon-only buttons); `sm` / `md` / `lg` size text buttons. Defaults to `md`. |
| icon | string | — | Leading icon: a named icon (e.g. `"mic"`, `"plus"`), an image URL/data-URI, or plain text. Renders before any slotted label. |
| iconTrailing | string | — | Trailing icon, after the label (e.g. `"chevron-down"` for a menu affordance). |
| label | string | — | Accessible name. REQUIRED for icon-only buttons (no visible text); ignored when you slot visible text, which already names the button. |
| disabled | boolean | false | Disable the button (non-interactive, dimmed). |
| full | boolean | false | Stretch the button to the full width of its container (a block button) — e.g. a card CTA or a stacked action. Attribute: `full`. |
| align | "start" | "center" | "end" | 'center' | Justify the button's content: `start`, `center` (default), or `end`. Combine with `full` for a full-width, left-aligned button. |
| type | "button" | "submit" | "reset" | 'button' | Native button `type`. Defaults to `button` (so it never submits a form). |
Events
Section titled “Events”| Event | Detail | Notes |
|---|---|---|
| kai-click | — | The button was activated (pointer or keyboard). Carries no detail. The native `click` also bubbles (composed) for consumers who prefer it. |
Composed from
Section titled “Composed from”This element wraps these SolidJS components — reach for them directly when you need finer control than the props expose.