Skip to content
kitn AI/UI

Button

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

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>

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.

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.

icon-trailing sits after the label — a chevron-down reads as a menu affordance.

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:

SlotModePurpose
replaceA 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>

The whole button is one ::part — restyle radius, padding, color, or weight from outside while keeping variant/size as the defaults.

PartPurposeExample
The button element. Restyle radius, padding, colors, or weight from outside; the `variant`/`size` props set the defaults.
kai-button::part(button) { border-radius: 9999px; font-weight: 600 }
PropertyTypeDefaultNotes
variant'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'md'Size token. `icon` / `icon-sm` are square (for icon-only buttons); `sm` / `md` / `lg` size text buttons. Defaults to `md`.
iconLeading icon: a named icon (e.g. `"mic"`, `"plus"`), an image URL/data-URI, or plain text. Renders before any slotted label.
iconTrailingTrailing icon, after the label (e.g. `"chevron-down"` for a menu affordance).
labelAccessible name. REQUIRED for icon-only buttons (no visible text); ignored when you slot visible text, which already names the button.
disabledfalseDisable the button (non-interactive, dimmed).
fullfalseStretch the button to the full width of its container (a block button) — e.g. a card CTA or a stacked action. Attribute: `full`.
align'center'Justify the button's content: `start`, `center` (default), or `end`. Combine with `full` for a full-width, left-aligned button.
type'button'Native button `type`. Defaults to `button` (so it never submits a form).
EventDetailNotes
The button was activated (pointer or keyboard). Carries no detail. The native `click` also bubbles (composed) for consumers who prefer it.

This element wraps these SolidJS components — reach for them directly when you need finer control than the props expose.

Button