Keyboard
No component-specific keymap. Inherits standard browser focus / activation behaviour.
Svelte 5 {@attach} factories. Glue ARIA / keyboard / focus onto any DOM node you choose. **Best when you want full control over markup and styling.**
<script lang="ts">
import { createTable } from '@kumiki/headless/table';
const ctl = createTable({});
</script>
<div {@attach ctl.root}>
<!-- your markup -->
</div>Compound components (<Root> / <Trigger> / …). Markup is fixed; styling is not. Same trade-off as a typical headless UI library.
pnpm add @kumiki/components<script lang="ts">
import { Table, type SortState } from '@kumiki/components/table';
let sort = $state<SortState | null>(null);
let selection = $state(new Set<string>());
</script>
<Table.Root
{sort}
onSortChange={(s) => (sort = s)}
{selection}
onSelectionChange={(s) => (selection = s)}
selectionMode="multiple"
>
<Table.Caption>Members</Table.Caption>
<Table.Header>
<Table.HeaderRow>
<Table.SelectAllCell />
<Table.HeaderCell column="name" sortable>Name</Table.HeaderCell>
</Table.HeaderRow>
</Table.Header>
<Table.Body>
{#each rows as row (row.id)}
<Table.Row rowId={row.id} selectable>
<Table.SelectCell />
<Table.Cell>{row.name}</Table.Cell>
</Table.Row>
{/each}
</Table.Body>
</Table.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 Table } from '@kumiki/atelier/table';
import type { SortState } from '@kumiki/components/table';
let sort = $state<SortState | null>(null);
let selection = $state(new Set<string>());
const rows = [
{ id: '1', name: 'Akari', role: 'Eng' },
{ id: '2', name: 'Ben', role: 'PM' },
];
</script>
<Table.Root
{sort}
onSortChange={(s) => (sort = s)}
{selection}
onSelectionChange={(s) => (selection = s)}
selectionMode="multiple"
>
<Table.Caption>Members</Table.Caption>
<Table.Header>
<Table.HeaderRow>
<Table.SelectAllCell />
<Table.HeaderCell column="name" sortable>Name</Table.HeaderCell>
<Table.HeaderCell column="role">Role</Table.HeaderCell>
</Table.HeaderRow>
</Table.Header>
<Table.Body>
{#each rows as row (row.id)}
<Table.Row rowId={row.id} selectable>
<Table.SelectCell />
<Table.Cell>{row.name}</Table.Cell>
<Table.Cell>{row.role}</Table.Cell>
</Table.Row>
{/each}
</Table.Body>
</Table.Root>/ accessibility
axe-core — run on every PR (LTR + RTL × every documented state).
No component-specific keymap. Inherits standard browser focus / activation behaviour.