GitHub

/ button

Button

@kumiki/headless/button

Svelte 5 attachment for Button — drives aria-busy/aria-disabled + click/Enter/Space gating with no DOM markup of its own.

This component, layer by layer

Styled, copy-paste presets (preview). Run pnpm kumiki add to drop the source into your project, then edit freely.

Live preview

Live preview…

Install
pnpm add @kumiki/atelier
Drop-in styled Button (Tailwind v4)
<script lang="ts">
  import { Tailwind as Button } from '@kumiki/atelier/button';
  let busy = $state(false);
</script>

<Button.Root variant="primary" size="md" loading={busy} onclick={() => (busy = !busy)}>
  Save
</Button.Root>

<Button.Root variant="danger">Delete</Button.Root>
<Button.Root variant="ghost" size="sm">Cancel</Button.Root>
Vanilla CSS variant
<script lang="ts">
  import { Vanilla as Button } from '@kumiki/atelier/button';
</script>

<Button.Root variant="primary">Save</Button.Root>

<!-- Override CSS custom properties via global stylesheet:
     .kumiki-button { --kumiki-button-bg: hsl(170 60% 40%); } -->
Copy into your project
pnpm kumiki add button
# Drops a vanilla-CSS or Tailwind button preset into your repo,
# under `src/lib/components/button` (path is configurable).
# Edit the variants/sizes to match your design system.

/ accessibility

Accessibility

axe-core — run on every PR (LTR + RTL × every documented state).

Keyboard

No component-specific keymap. Inherits standard browser focus / activation behaviour.

Test discipline

  • axe-core — run on every PR (LTR + RTL × every documented state).
  • APG keyboard tests — Playwright, hand-written per pattern.
  • VoiceOver / NVDA — Guidepup nightly schedule.
  • Type-level required names — title / aria-label / aria-labelledby.
Read the W3C ARIA APG pattern ↗