diff --git a/.claude/agents/code-reviewer.md b/.claude/agents/code-reviewer.md index 2bced5e..69f9d6e 100644 --- a/.claude/agents/code-reviewer.md +++ b/.claude/agents/code-reviewer.md @@ -6,7 +6,7 @@ Principal reviewer only — identify issues; do not implement fixes. Adapted fro 1. Git diff for the branch (`git diff main...HEAD`) 2. The GitHub issue being implemented (acceptance criteria are the spec) -3. Standards: `CLAUDE.md` (architecture invariants) and the parent PRD (issue #1, Implementation & Testing Decisions) +3. Standards: `CLAUDE.md`, `standards/slideshow.md`, and the parent PRD (issue #1, Implementation & Testing Decisions) ## Lenses diff --git a/.claude/skills/composition-patterns/SKILL.md b/.claude/skills/composition-patterns/SKILL.md new file mode 100644 index 0000000..87c323b --- /dev/null +++ b/.claude/skills/composition-patterns/SKILL.md @@ -0,0 +1,42 @@ +--- +name: composition-patterns +description: React composition patterns for the editor shell. Use when refactoring components with boolean prop proliferation, splitting large components, or designing flexible component APIs in src/editor-shell/. +metadata: + tags: react, composition, architecture, editor-shell + source: vercel-labs/agent-skills (subset) +--- + +## When to use + +Load this skill before adding or refactoring UI in `src/editor-shell/`. Read `standards/slideshow.md` alongside these rules. + +Triggers: + +- A component file approaches or exceeds the 300-line cap +- Adding boolean props to customize component behavior (`isEditing`, `showFooter`, etc.) +- One component handles multiple slide/dialog/panel modes via conditionals +- Sibling components need shared state (e.g. drag preview + storyboard grid) + +## Applicable rules (this project) + +Only three rules from the Vercel composition-patterns skill apply at current scale. Read the full rule file before implementing: + +| Priority | Rule | File | +| -------- | ---- | ---- | +| CRITICAL | Avoid boolean prop proliferation | [rules/architecture-avoid-boolean-props.md](rules/architecture-avoid-boolean-props.md) | +| MEDIUM | Explicit variant components | [rules/patterns-explicit-variants.md](rules/patterns-explicit-variants.md) | +| HIGH | Lift state into providers | [rules/state-lift-state.md](rules/state-lift-state.md) | + +## Not applicable yet + +Skip these until the codebase needs them: + +- `architecture-compound-components` — no shared compound context yet +- `state-context-interface` / `state-decouple-implementation` — state still lives in App with callback props +- `patterns-children-over-render-props` — no render-prop APIs +- `react19-no-forwardref` — not using forwardRef + +## Local examples + +- `TitleSlideDialog` and `SlideSettingsDialog` are explicit variants (not one dialog with `isTitle` boolean) +- App lifts state; dialogs receive data + callbacks — provider pattern becomes relevant when siblings outside the dialog need the same state diff --git a/.claude/skills/composition-patterns/rules/architecture-avoid-boolean-props.md b/.claude/skills/composition-patterns/rules/architecture-avoid-boolean-props.md new file mode 100644 index 0000000..ccee19c --- /dev/null +++ b/.claude/skills/composition-patterns/rules/architecture-avoid-boolean-props.md @@ -0,0 +1,100 @@ +--- +title: Avoid Boolean Prop Proliferation +impact: CRITICAL +impactDescription: prevents unmaintainable component variants +tags: composition, props, architecture +--- + +## Avoid Boolean Prop Proliferation + +Don't add boolean props like `isThread`, `isEditing`, `isDMThread` to customize +component behavior. Each boolean doubles possible states and creates +unmaintainable conditional logic. Use composition instead. + +**Incorrect (boolean props create exponential complexity):** + +```tsx +function Composer({ + onSubmit, + isThread, + channelId, + isDMThread, + dmId, + isEditing, + isForwarding, +}: Props) { + return ( +
+
+ + {isDMThread ? ( + + ) : isThread ? ( + + ) : null} + {isEditing ? ( + + ) : isForwarding ? ( + + ) : ( + + )} +