chore: agentic upgrade
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
---
|
||||
name: composition-patterns
|
||||
description: Use when writing, reviewing, or refactoring React component APIs that risk boolean prop proliferation, renderHeader/renderFooter-style slots, prop drilling, trapped local state, context-provider architecture, compound components, explicit variants, or React 19 ref/context composition patterns.
|
||||
---
|
||||
|
||||
# Composition Patterns
|
||||
|
||||
## Overview
|
||||
|
||||
Apply scalable React composition patterns from Vercel's `composition-patterns`
|
||||
skill, adapted for this Next.js/FSD repository. Prefer explicit composed APIs
|
||||
over configuration-heavy components, and keep reusable UI parts decoupled from
|
||||
state implementations.
|
||||
|
||||
## Workflow
|
||||
|
||||
1. Identify whether the component is becoming a mode switcher.
|
||||
Look for multiple boolean props, conditional branches that choose whole UI
|
||||
regions, `renderHeader`/`renderFooter` props, or impossible prop
|
||||
combinations.
|
||||
2. Split behavior into explicit variants when the rendered structure differs.
|
||||
Prefer names such as `ThreadComposer`, `EditComposer`, or
|
||||
`ForwardComposer` over one `Composer` with `isThread`, `isEditing`, and
|
||||
`isForwarding`.
|
||||
3. Extract shared pieces into compound components when consumers need to
|
||||
arrange the parts themselves. Use `Root`/`Provider`, `Frame`, `Header`,
|
||||
`Body`, `Footer`, `Trigger`, `Content`, `Action`, or domain-specific names
|
||||
that fit the existing component.
|
||||
4. Lift shared state into a provider boundary when siblings or custom outer UI
|
||||
need the same state/actions. Keep visual nesting separate from state access:
|
||||
components only need to be inside the provider, not inside the same DOM box.
|
||||
5. Define a context contract with `state`, `actions`, and `meta` when multiple
|
||||
providers can drive the same UI. UI subcomponents consume the contract, while
|
||||
providers decide whether state comes from local hooks, server-synced data,
|
||||
forms, or feature-specific stores.
|
||||
6. In this React 19 repo, pass `ref` as a normal prop and use `use(Context)` for
|
||||
context reads where the surrounding codebase allows it. Preserve existing
|
||||
conventions if a nearby component has not migrated yet.
|
||||
|
||||
## Decision Rules
|
||||
|
||||
- Do not add a boolean prop to control a large behavior branch until checking
|
||||
whether an explicit variant or child composition would make the state space
|
||||
clearer.
|
||||
- Use children for static structure composition. Keep render props for cases
|
||||
where the parent must pass item data, measurements, or callback-local state
|
||||
back into the child.
|
||||
- Keep providers as the only layer that knows a concrete state implementation.
|
||||
Subcomponents should not import feature stores or synchronization hooks unless
|
||||
they are provider components.
|
||||
- Avoid prop drilling through compound components. Put shared state/actions in a
|
||||
typed context and expose narrow subcomponents.
|
||||
- Keep FSD boundaries intact: shared compound UI belongs under `src/shared/ui`;
|
||||
feature-specific variants and providers belong in the appropriate feature,
|
||||
entity, widget, or page layer.
|
||||
|
||||
## Reference
|
||||
|
||||
Read `references/rules.md` when you need examples, a review checklist, or the
|
||||
upstream rule inventory. It summarizes all files from:
|
||||
`https://github.com/vercel-labs/agent-skills/tree/main/skills/composition-patterns`
|
||||
at commit `ce3e64e468f8fa09a2d075d102771838061fdac0`.
|
||||
@@ -0,0 +1,4 @@
|
||||
interface:
|
||||
display_name: "Composition Patterns"
|
||||
short_description: "Apply scalable React composition patterns."
|
||||
default_prompt: "Use composition patterns to refactor or design a React component API."
|
||||
@@ -0,0 +1,91 @@
|
||||
# React Composition Rules
|
||||
|
||||
This reference distills the upstream Vercel `composition-patterns` skill. The
|
||||
upstream directory was inspected as a whole: `SKILL.md`, `README.md`,
|
||||
`metadata.json`, generated `AGENTS.md`, `_sections.md`, `_template.md`, and all
|
||||
rule files under `rules/`.
|
||||
|
||||
## Rule Inventory
|
||||
|
||||
| Area | Rule | Use it to |
|
||||
| --- | --- | --- |
|
||||
| Architecture | Avoid boolean prop proliferation | Replace mode booleans with explicit composed variants. |
|
||||
| Architecture | Use compound components | Let consumers arrange subcomponents that share context. |
|
||||
| State | Decouple state management from UI | Keep concrete hooks/stores inside providers. |
|
||||
| State | Define generic context interfaces | Share UI across providers using `state`, `actions`, `meta`. |
|
||||
| State | Lift state into providers | Let outer/sibling components access composer-like state without refs or effects. |
|
||||
| Patterns | Create explicit component variants | Make each mode self-documenting and impossible-state-free. |
|
||||
| Patterns | Prefer children over render props | Use children for structure; reserve render props for data callbacks. |
|
||||
| React 19 | Ref and context API changes | Use ref as a prop and `use(Context)` when the codebase is React 19+. |
|
||||
|
||||
## Core Principles
|
||||
|
||||
- Composition over configuration: let consumers assemble behavior from parts
|
||||
instead of adding props for every mode.
|
||||
- State belongs at the provider boundary when more than one child or sibling
|
||||
needs it.
|
||||
- Compound internals should read shared context, not receive long prop chains.
|
||||
- Explicit variants are clearer than a single component with many conditional
|
||||
branches.
|
||||
|
||||
## Refactoring Checklist
|
||||
|
||||
1. Count behavior flags and conditional branches. Two or more mode booleans are
|
||||
a strong signal to split variants.
|
||||
2. Identify shared primitives. Extract the stable pieces first: frame, input,
|
||||
header, footer, trigger, content, action, item, or slot-like sections.
|
||||
3. Decide the provider boundary. Put it around every component that needs the
|
||||
shared state, even if some of those components are visually outside the main
|
||||
frame.
|
||||
4. Define the context shape before wiring UI. Prefer:
|
||||
|
||||
```ts
|
||||
interface ComponentContextValue {
|
||||
state: ComponentState
|
||||
actions: ComponentActions
|
||||
meta: ComponentMeta
|
||||
}
|
||||
```
|
||||
|
||||
5. Move implementation-specific hooks into provider variants. For example,
|
||||
`LocalComposerProvider`, `ChannelComposerProvider`, and
|
||||
`EditComposerProvider` can implement the same UI contract.
|
||||
6. Replace `renderX` props with children when the consumer is only placing
|
||||
static structure.
|
||||
7. Keep render props when the parent must provide data to each render, such as
|
||||
list items, indices, or measured layout values.
|
||||
8. For React 19 code, avoid adding new `forwardRef` wrappers unless compatibility
|
||||
with React 18 or an existing library API requires it.
|
||||
|
||||
## Review Smells
|
||||
|
||||
- A component accepts several props named `is*`, `show*`, `has*`, or `mode` and
|
||||
uses them to render different major sections.
|
||||
- A caller can pass contradictory props, such as `isEditing` and `isForwarding`.
|
||||
- A reusable UI component imports a feature store, route-specific hook, or sync
|
||||
mechanism directly.
|
||||
- State is copied upward through `useEffect` solely so another sibling can read
|
||||
it.
|
||||
- A submit button reads state from a ref because the state is trapped inside a
|
||||
child component.
|
||||
- `renderHeader`, `renderFooter`, or `renderActions` props are used only to place
|
||||
static nodes.
|
||||
|
||||
## Repo Adaptation
|
||||
|
||||
- Put generic primitives in `src/shared/ui/<Component>/` with the repo's usual
|
||||
source, SCSS module, test, story, and barrel layout.
|
||||
- Keep feature-specific provider variants out of `shared` if they import
|
||||
feature/entity/page state.
|
||||
- Export public compound pieces through `index.ts` instead of deep imports.
|
||||
- Coordinate with `react-best-practices` for performance, Server Component
|
||||
boundaries, serialization, and client bundle impact.
|
||||
- Coordinate with `storybook-ai-best-practices` when adding stories so each
|
||||
compound part, variant, and state has focused examples.
|
||||
|
||||
## Source Notes
|
||||
|
||||
The upstream skill is version `1.0.0`, dated January 2026, and references React
|
||||
documentation for context and the `use` API. Its generated `AGENTS.md` is a
|
||||
compiled form of the individual rules, so prefer this distilled reference for
|
||||
day-to-day work and consult the upstream repo only when refreshing the skill.
|
||||
Reference in New Issue
Block a user