Integrations
State
Tiny, typed stores built on TanStack Store. Ship a persistent theme store out of the box and a task-board store as a worked example.
Theme store
The themeStore keeps { mode, resolved } in sync with
localStorage and prefers-color-scheme. It's applied to the DOM
automatically when the module loads, so you don't need a provider.
import { themeStore, setThemeMode, toggleTheme, useResolvedTheme } from '@kana-consultant/ui-kit'
themeStore.state
themeStore.subscribe((next) => console.log(next))
setThemeMode('system')
toggleTheme()
function Status() {
return <span>{useResolvedTheme()}</span>
} Task board store (example)
A reference implementation of a collection store with CRUD, filter state, and derived selectors. Copy the shape or use it directly for task-style data.
import {
createTaskStore,
addTask,
removeTask,
updateTask,
toggleDone,
setSearch,
setStatusFilter,
useTasks,
useTaskCounts,
useFilters,
EStatus,
EPriority,
} from '@kana-consultant/ui-kit'
const store = createTaskStore([
{
id: 't1',
title: 'Ship the thing',
status: EStatus.InProgress,
priority: EPriority.High,
},
])
addTask(store, {
id: 't2',
title: 'Write the changelog',
status: EStatus.Todo,
priority: EPriority.Medium,
})
setSearch(store, 'changelog')
setStatusFilter(store, EStatus.Todo)
function Board() {
const tasks = useTasks(store)
const counts = useTaskCounts(store)
const filters = useFilters(store)
return <span>{tasks.length} match · {counts[EStatus.Done]} done</span>
} Mutations
addTask(store, task)— prepend to the listremoveTask(store, id)— remove by idupdateTask(store, id, patch)— shallow merge into matching taskmoveTask(store, id, status)— change columntoggleDone(store, id, done)— Done ↔ Todo shortcutsetSearch(store, query)— filter by title / description / tagsetStatusFilter(store, status | 'all')— filter by status
Selectors (React)
useTasks(store)— filtered list, re-renders only when it changesuseTaskCounts(store)— map of status → countuseFilters(store)— active filters