63 lines
3.2 KiB
Markdown
63 lines
3.2 KiB
Markdown
---
|
|
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`.
|