Keyboard
| Key | Effect |
|---|---|
| Focus / Hover | Open after delay. |
| Escape | Dismiss when content is hovered. |
Pure state machines (FSMs). No DOM. Run in server, Vitest, Worker. Reach for these when you only want the behavior.
Hover / focus tooltip with open-delay + group sharing.
pnpm add @kumiki/machinesimport { createTooltipMachine } from '@kumiki/machines/tooltip';
const m = createTooltipMachine({ openDelay: 0, closeDelay: 0 });
m.send({ type: 'OPEN' });
console.log(m.state); // 'open'
m.send({ type: 'ESCAPE' });
console.log(m.state); // 'closed'Svelte 5 {@attach} factories. Glue ARIA / keyboard / focus onto any DOM node you choose. **Best when you want full control over markup and styling.**
pnpm add @kumiki/headless<script lang="ts">
import { createTooltip } from '@kumiki/headless/tooltip';
const t = createTooltip({ openDelay: 500, closeDelay: 200 });
</script>
<button {@attach t.trigger} aria-label="Save">⌘S</button>
<div {@attach t.content}>Save (Cmd/Ctrl + S)</div>Compound components (<Root> / <Trigger> / …). Markup is fixed; styling is not. Same trade-off as a typical headless UI library.
pnpm add @kumiki/components/tooltip<script lang="ts">
import * as Tooltip from '@kumiki/components/tooltip';
</script>
<Tooltip.Root>
<Tooltip.Trigger>?</Tooltip.Trigger>
<Tooltip.Content>Help text shown on hover or focus.</Tooltip.Content>
</Tooltip.Root><!-- 0 ms open delay = no debounce; instant. closeDelay still applies. -->
<Tooltip.Root openDelay={0} closeDelay={150} disableHoverableContent>
<Tooltip.Trigger aria-label="Save">⌘S</Tooltip.Trigger>
<Tooltip.Content>Save (Cmd/Ctrl + S)</Tooltip.Content>
</Tooltip.Root>Styled, copy-paste presets (preview). Run pnpm kumiki add to drop the source into your project, then edit freely.
Live preview…
pnpm add @kumiki/atelier<script lang="ts">
import { Tailwind as Tooltip } from '@kumiki/atelier/tooltip';
</script>
<Tooltip.Root>
<Tooltip.Trigger>Save</Tooltip.Trigger>
<Tooltip.Content>Saves the document (⌘S)</Tooltip.Content>
</Tooltip.Root>/ accessibility
axe-core — run on every PR (LTR + RTL × every documented state).
| Key | Effect |
|---|---|
| Focus / Hover | Open after delay. |
| Escape | Dismiss when content is hovered. |