Contributing
The repo
packages/
core config · tokens · themes · Provider · styled · motion
components the main kit
hooks platform-aware hooks
icons emoji generated glyph packages
dates carousel map media graphics sheet mediaquery
plugins build integrations
demo the cross-platform gallery (private)
story-runtime the shared CSF resolver (private)
apps/
app Expo example
web Next.js example
storybook aggregate Storybook (GitHub Pages)
docs this site
scripts/
docs/ the docs generatorspnpm install
pnpm --filter @knitui/components storybook # work on components
pnpm --filter @knitui/docs dev # work on the docs (port 3001)
pnpm test && pnpm lint && pnpm typecheck # what CI runsAdding a component
A component is not done until all five exist:
Component.tsx— astyled(Box)frame, sized fromcontrolMetrics, coloured through the variant ladder, with a typed slot map if it has parts.Component.stories.tsx— CSF3, starting with aPlaygroundstory, withargTypesdescriptions (they become the docs' controls panel and the prop descriptions), and aStylesstory showing per-slot styling.Component.test.tsx— jsdom, asserting real host elements (getByRole("button"), not atestID) so a refactor that drops semantics fails.index.ts— the component plus its types, re-exported from the package barrel.- A docs page —
pnpm docs:generatescaffolds it from the story; you write the prose, the accessibility notes and the platform notes.
The Button folder is the reference for a simple
control, Combobox for a compound one.
Conventions that are enforced
pnpm check:naming— file and export naming.- Every package lints with
eslint .(noteslint src). - Prettier runs through ESLint, so
pnpm lint:fixformats. - A focus ring may only be applied to something focusable — there is a guardrail test for the pairing.
- Story titles are the docs routes.
Inputs/Buttonbecomes/docs/components/inputs/button, so a title is an API decision.
Documentation is generated
Do not hand-write a prop table or copy an example into prose. The docs read:
- stories for examples, captions (JSDoc) and controls (
argTypes); - TypeScript declarations for props, defaults and slot keys;
- the config for token, sizing and motion tables;
CHANGELOG.mdfor release history.
pnpm docs:generate refreshes all of it. CI fails if the committed output is stale
or if a component has stories but no page.
Releasing
pnpm changeset # describe the change and pick the bumpMerging to main opens a version PR; merging that publishes to npm. Pushing to
main alone does not publish.