Component specification
The contract every Simal UI component defines before it is released.
A component is not complete when its default state looks right. Its specification is the set of decisions below, captured in code, stories, tests, and generated documentation.
Required contract
| Area | The specification must answer |
|---|---|
| Intent | What problem does this solve, and what does it deliberately not solve? |
| Public API | Which props are controlled, uncontrolled, required, and platform-only? |
| States | Default, focused, pressed, selected, loading, disabled, empty, error, and read-only as applicable |
| Variants | Which variants are semantic, and when should each be used? |
| Content | Label, helper, error, truncation, localization, RTL, and long-text behavior |
| Platforms | What is shared, what differs, and why is the difference native rather than accidental? |
| Tokens | Which semantic color, type, radius, spacing, and motion decisions it consumes |
| Accessibility | Name, role, state, focus order, target size, keyboard behavior, and announcements |
| Composition | Valid children/adornments and the layouts where the component must remain stable |
| Verification | Unit behavior, Storybook matrix, visual baselines, and any required product E2E |
Story matrix
Every public component needs a Playground plus stories for the states that can
change layout, meaning, or accessibility. A useful minimum is:
- default and content-stress cases;
- each visual variant;
- disabled and read-only when supported;
- loading and error when supported;
- selected/open/checked states for interactive collections;
- adornments and long localized labels where supported;
- a composition example when spacing depends on surrounding controls.
The global theme toolbar provides light and dark. Visual regression captures both. Platform-specific behavior that cannot be represented faithfully by React Native Web must be called out in the story description and verified on a device separately.
Story metadata is the source of documentation
Component pages are generated from Storybook:
- the doc comment above
metabecomes the component description; argTypesbecomes the props table;- each story's doc comment and render source become an example;
- the live preview embeds the same Storybook runtime used by visual tests.
Do not hand-edit generated component MDX. Improve the story, then run
pnpm docs:sync.
Definition of done
A shared component is releasable only when:
- its API is exported from the intended public entry point;
- the states above are represented or explicitly marked not applicable;
- important behavior has an active Jest test;
- Storybook builds with no runtime error;
- light and dark visual baselines are reviewed;
- the accessibility panel has no new serious or critical violation;
- generated docs include a description, import, props, and live examples;
- package lint, type-check, tests, visual regression, and docs build pass;
- a consumer-facing change has a release note and a new tag.
A green TypeScript build is not visual verification. A green Storybook build is not native-device verification. Report each boundary honestly.