Files
cadence-ui/CONTRIBUTING.md
T

134 lines
4.6 KiB
Markdown

# Contributing
This repo treats components as source-owned product infrastructure, not generated vendor
artifacts. Changes should preserve the existing token system, component contract, and docs
discipline instead of introducing parallel patterns.
## Before you start
Read the current contract and docs baseline first:
- `roadmap.md`
- `packages/ui/src/lib/contracts.ts`
- `apps/docs/src/component-authoring.stories.tsx`
Then inspect the closest existing component before adding a new one.
## Default workflow
1. Confirm the component or change fits the current system layers.
2. Reuse the existing contract helpers, slot names, state naming, and variant conventions.
3. Add or update Storybook stories so behavior is reviewable.
4. Add or update tests before treating the component as done.
5. Run the relevant validation commands locally.
## Authoring rules
These are the baseline rules for public components in `packages/ui`:
- Expose `className` on every styled public component.
- Forward `ref` on every focusable or measurable public component.
- Use `asChild` only when the root is intentionally polymorphic.
- Prefer controlled and uncontrolled APIs together when the component manages user state.
- Represent boolean UI states with empty-string `data-*` attributes.
- Represent finite machine states with stable `data-state="..."` values.
- Name stylable internal parts with `data-slot`.
- Keep `variant` semantic and `size` meaningful; do not add one-off booleans that fragment the API.
## Styling and token rules
- Consume tokens and motion recipes instead of hardcoded brand values.
- Prefer semantic roles such as `primary`, `muted`, `destructive`, `surface`, and `card`.
- Keep shared layout, focus, and interaction primitives in the CVA base string.
- Avoid `transition-all`.
- Prefer animating `transform` and `opacity`.
- Use `data-state` driven animation where possible.
## Theme and reduced motion expectations
Every meaningful UI change should be reviewed under:
- the default theme
- alternate themes when contrast or surface depth could shift
- reduced motion
Practical expectations:
- The component should remain usable when motion is reduced.
- Motion should communicate state or hierarchy, not hide missing feedback.
- Theme differences should come from tokens, not conditional component styling forks.
## Storybook expectations
Storybook is not just a gallery. It is the review surface for API, anatomy, and behavior.
Minimum story recipe:
- `Playground`: one opinionated default example
- `States`: only when the component has meaningful state comparisons
- `Anatomy`: document stable slots and public `data-*` hooks
- `Accessibility` or `Motion`: choose whichever behavior is easiest to misunderstand
Writing rules:
- Use `docs.description.component` to explain when to choose the component.
- Use real product language instead of filler copy.
- Keep examples narrow and intentional.
- If a story exists only to explain slots, accessibility, or motion, say that directly.
## Testing and QA expectations
Component work is not done until the behavior is covered at the right level.
Use the following baseline:
- Unit and interaction tests in `packages/ui/src/components/*.test.tsx`
- Storybook interaction coverage where a representative `play` flow adds signal
- Playwright smoke coverage for high-value cross-component flows
Common things to cover:
- trigger and close behavior
- keyboard behavior
- controlled and uncontrolled state
- slot and `data-*` attributes that consumers rely on
- invalid, disabled, loading, or required state where relevant
- reduced motion behavior when the component has meaningful animation
## Validation commands
Run the narrowest useful set while working, then the broader set before opening a PR.
Core checks:
```bash
pnpm lint
pnpm typecheck
pnpm test
```
Docs and smoke checks:
```bash
pnpm dev:docs
pnpm build:docs
pnpm test:e2e:smoke
```
## Practical repo guidance
- Keep shared integration points small. If you only need a new component, avoid unrelated changes.
- Treat `packages/ui/src/index.ts` as a shared export surface and change it deliberately.
- Prefer adding a sibling pattern over mutating an existing component unless the API itself is wrong.
- If a change needs a new dependency, justify it against the repo's current stack and complexity budget.
## Definition of done
A component or pattern change is ready when:
- the implementation uses tokens and follows the current contract
- the docs explain when to use it and how it is structured
- tests cover the important behavior
- accessibility and reduced motion were considered explicitly
- the repo's standard validation commands pass