Component conventions
Where components live
- Reusable, presentational components:
packages/ui/src/(@enode/ui) —Button,TagPill,Sheet,SortableList,BottomSheetCard,LottieCircle, … These are the components worth a Storybook story. - App-specific feature components: under each app's
src/app/— composed from co-locateduse-*hooks. Mostly tied to live session state, so generally not good Storybook candidates without a mock.
Storybook
Stories document the reusable @enode/ui layer, co-located with the component as
ComponentName.stories.tsx. Storybook renders them with the real design tokens
(Tailwind v4 + @enode/ui/styles/design-system.css, wired in
docs-site/.storybook).
Currently covered:
packages/ui/src/button.stories.tsx— all variants, sizes, disabled, rounded pill, leading/trailing icon.packages/ui/src/tag-pill.stories.tsx— contrast swap, no-colour fallback, interactive, long-content truncation.
Adding a story
-
Pick a reusable
@enode/uicomponent with meaningful visual states. Skip provider-only wrappers, route-only pages, and components that need live backend state without a safe mock. -
Create
ComponentName.stories.tsxnext to the component. -
Use Component Story Format with TypeScript:
import type { Meta, StoryObj } from "@storybook/react";import { fn } from "storybook/test";import { MyComponent } from "./my-component";const meta = {title: "UI/MyComponent",component: MyComponent,tags: ["autodocs"],args: { onChange: fn() },} satisfies Meta<typeof MyComponent>;export default meta;type Story = StoryObj<typeof meta>;export const Default: Story = { args: { /* realistic props */ } }; -
For
ReactNode/callback props, setargTypes: { prop: { control: false } }and add dedicated stories — editable controls produce broken values. -
Only document states the component actually supports. Use realistic args, mock callbacks with
fn(), never call real APIs, never invent props. -
Run
npm run storybookto preview,npm run docs:storybookto build.
TODO:
Sheet/BottomSheetCard/SortableListare reusable but need a small amount of mock wiring (portals, drag context). Add stories when those mocks are in place — do not force a story that fakes behavior.