React Component Library AGENTS.md
AGENTS.md for a React component library: composition-first APIs, prop naming rules, required Storybook stories, and accessibility checks that gate every new component.
Use when: Use in a repository that publishes reusable React components so agents design composable prop APIs, write stories alongside components, and treat accessibility failures as build failures.
The skill file
Claude Code · AGENTS.mdAGENTS.md3210 chars
# AGENTS.md — React Component Library
This package publishes reusable components consumed by multiple product teams. Every public prop is API surface: renames and removals are breaking changes. Default to additive changes.
## Commands
```bash
pnpm test # vitest + @testing-library/react
pnpm storybook # → http://localhost:6006
pnpm build # library build (tsup) — must pass before PR
pnpm lint && pnpm typecheck
pnpm test:a11y # axe checks against all stories — failures block merge
```
## Component anatomy
Each component is a directory:
```
src/components/Select/
Select.tsx
Select.test.tsx
Select.stories.tsx # required — no component ships without stories
index.ts # re-exports the public surface only
```
Export from `src/index.ts` explicitly. Anything not exported there is private and may change freely.
## Composition over configuration
- Build compound components, not prop bags. A `Select` with `label`, `helperText`, `errorText`, `prefixIcon`, `suffixIcon` props is wrong; `Select.Trigger`, `Select.Option`, paired with `Field.Label`/`Field.Error`, is right.
- Accept `children` wherever content goes. Props that take ReactNode for layout slots (`icon={<X/>}`) are a smell — prefer a child component.
- Use context internally to wire compound parts together; never require consumers to thread state between siblings manually.
- Wrap rather than fork: variants of an existing component compose it, they do not copy its file.
## Prop API rules
- Booleans are positive and prefixed: `isDisabled`, `isLoading` — never `notActive` or bare `disabled` mixed with `isOpen` in the same component.
- Event handlers are `on<Event>`: `onValueChange(value)` with the data first, raw DOM event last if needed.
- Every interactive component supports both controlled (`value` + `onValueChange`) and uncontrolled (`defaultValue`) modes.
- Spread `...rest` onto the root element, merge `className` with the internal classes, and forward `ref` (React 19: take `ref` as a regular prop).
- No `style`-object props for theming — variants go through the `variant`/`size` props backed by <your-styling-solution>.
## Accessibility (gating, not aspirational)
- Interactive elements are real `<button>`, `<a>`, `<input>` — never a `div` with `onClick`.
- Follow the matching WAI-ARIA Authoring Practices pattern for keyboard support; document the keymap in the story's docs block.
- Visible focus ring on every focusable element; never `outline: none` without a replacement.
- Every form control is labelable; icon-only buttons require an `aria-label` prop, enforced by types (use a union that demands it).
- `pnpm test:a11y` must pass. Do not add axe exclusions without a comment linking to a tracked issue.
## Stories and tests
- Stories cover: default, each variant/size, disabled, loading/empty, error, and a long-content stress case.
- Tests use Testing Library queries by role/name (`getByRole("button", { name: /save/i })`) — no `getByTestId` unless there is genuinely no accessible handle, which usually means the markup is wrong.
- Test behavior through user interactions (`userEvent`), not implementation details or snapshots.
Install
drop into your repoSave this to your project or home directory so Claude Code can load it.
path./AGENTS.md
Discussion
What people are saying
Forks
0 forks of this skillLoading forks…