From d39963e9a47ad5aea361ccfbde8df39678c1988c Mon Sep 17 00:00:00 2001 From: cbaucom Date: Wed, 10 Jun 2026 22:24:32 -0400 Subject: [PATCH 1/2] refactor(editor-shell): extract slide dialogs and persistence helpers Split App.tsx below the architecture file-size cap by moving TitleSlideDialog, SlideSettingsDialog, and slide JSON helpers into dedicated modules. Behavior unchanged. Co-authored-by: Cursor --- .claude/skills/composition-patterns/SKILL.md | 42 +++ .../rules/architecture-avoid-boolean-props.md | 100 ++++++ .../rules/patterns-explicit-variants.md | 100 ++++++ .../rules/state-lift-state.md | 125 +++++++ CLAUDE.md | 2 +- src/editor-shell/App.tsx | 311 +----------------- src/editor-shell/SlideSettingsDialog.tsx | 128 +++++++ src/editor-shell/TitleSlideDialog.tsx | 118 +++++++ src/editor-shell/slidePersistence.ts | 57 ++++ 9 files changed, 676 insertions(+), 307 deletions(-) create mode 100644 .claude/skills/composition-patterns/SKILL.md create mode 100644 .claude/skills/composition-patterns/rules/architecture-avoid-boolean-props.md create mode 100644 .claude/skills/composition-patterns/rules/patterns-explicit-variants.md create mode 100644 .claude/skills/composition-patterns/rules/state-lift-state.md create mode 100644 src/editor-shell/SlideSettingsDialog.tsx create mode 100644 src/editor-shell/TitleSlideDialog.tsx create mode 100644 src/editor-shell/slidePersistence.ts diff --git a/.claude/skills/composition-patterns/SKILL.md b/.claude/skills/composition-patterns/SKILL.md new file mode 100644 index 0000000..7c83494 --- /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/react.md` and `standards/architecture.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 ? ( + + ) : ( + + )} +