feat: add empty state and expand overlay qa
This commit is contained in:
+133
@@ -0,0 +1,133 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user