React Component Library AGENTS.md
Claude CodeAGENTS.mdCoding
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.
Get this skill
Add the skill file with the CLI, by hand, or over MCP.Save this to your project or home directory so Claude Code can load it.
npx goodprompts add react-component-agents-mdSaves to
./AGENTS.mdnpx goodprompts add react-component-agents-mdSaves to
./AGENTS.mdSkill file
AGENTS.md3,210 characters# 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.