Files
cadence-ui/CONTRIBUTING.md
T

5.1 KiB

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:

  • DESIGN.md
  • roadmap.md
  • packages/ui/src/lib/contracts.ts
  • apps/docs/src/component-authoring.stories.tsx
  • docs/harness-engineering.md
  • docs/orchestration.md when the work may be split across agents

Then inspect the closest existing component before adding a new one.

Default workflow

  1. Create or update an execution plan in docs/exec-plans/ when the change is non-trivial.
  2. Confirm the component or change fits the current system layers.
  3. Reuse the existing contract helpers, slot names, state naming, and variant conventions.
  4. Add or update Storybook stories so behavior is reviewable.
  5. Add or update tests before treating the component as done.
  6. 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:

pnpm lint
pnpm typecheck
pnpm test

Harness shortcuts:

pnpm harness:select
pnpm harness:validate:static
pnpm harness:validate:changed
pnpm harness:validate:component
pnpm harness:validate:docs
pnpm harness:validate:consumers

Docs and smoke checks:

pnpm dev:docs
pnpm build:docs
pnpm test:e2e:smoke

Broader gates:

pnpm harness:validate:pr
pnpm harness:validate:release

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