Skip to content
kitn AI/UI

Button

kai-button

Handles every action in the UI, from the primary submit down to a quiet icon in a toolbar.

  • Shadow DOM
  • 5 variants
  • Named + URL icons
  • Emits kai-click

Put the label as light-DOM text inside the element. Set variant and size, 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), ghost, outline, destructive.

Square sizes are icon / icon-sm; set label for the accessible name. icon takes a named icon, an image URL, or a data-URI.

icon-trailing sits after the label.

For a glyph the icon prop can’t name, slot it into slot="icon"; it wins over the prop. Keep label for the accessible name.

The label is the default slot; icon is the one named seam:

SlotModePurpose
injectThe button's label. Omit it for an icon-only button (pair with `aria-label`).
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 button is a single ::part, so radius, padding, color, and weight restyle from outside while variant / size stay 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
theme'auto'Color mode (`auto` follows prefers-color-scheme).
variant'default'Visual style. Defaults to `default` (filled).
size'md'Size token: the square glyph-only sizes, or the text-button sizes. Defaults to `md`.
icon—Leading icon: a named icon (e.g. `"mic"`, `"plus"`), an image URL/data-URI, or plain text. Renders before any slotted label.
iconTrailing—Trailing icon, after the label (e.g. `"chevron-down"` for a menu affordance).
label—Accessible name for an icon-only button. Ignored when visible text is slotted -- the visible text wins.
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. Default is centered; 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.
MethodSignatureNotes
(options?: FocusOptions): voidFocus the inner `<button>` (host.focus() would focus the wrapper).
(): voidBlur the inner `<button>`.
(): voidProgrammatically activate the button. Runs the same path as a user click and fires kai-click. Forwarding to the inner button means `disabled` is respected automatically.

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

Button