Pulled ALL skills from 15 source repositories: - anthropics/skills: 16 (docs, design, MCP, testing) - obra/superpowers: 14 (TDD, debugging, agents, planning) - coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth) - better-auth/skills: 5 (auth patterns) - vercel-labs/agent-skills: 5 (React, design, Vercel) - antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo) - Plus 13 individual skills from various repos Mosaic Stack is not limited to coding — the Orchestrator and subagents serve coding, business, design, marketing, writing, logistics, analysis, and more. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
101 lines
2.3 KiB
Markdown
101 lines
2.3 KiB
Markdown
---
|
|
title: Create Explicit Component Variants
|
|
impact: MEDIUM
|
|
impactDescription: self-documenting code, no hidden conditionals
|
|
tags: composition, variants, architecture
|
|
---
|
|
|
|
## Create Explicit Component Variants
|
|
|
|
Instead of one component with many boolean props, create explicit variant
|
|
components. Each variant composes the pieces it needs. The code documents
|
|
itself.
|
|
|
|
**Incorrect (one component, many modes):**
|
|
|
|
```tsx
|
|
// What does this component actually render?
|
|
<Composer
|
|
isThread
|
|
isEditing={false}
|
|
channelId='abc'
|
|
showAttachments
|
|
showFormatting={false}
|
|
/>
|
|
```
|
|
|
|
**Correct (explicit variants):**
|
|
|
|
```tsx
|
|
// Immediately clear what this renders
|
|
<ThreadComposer channelId="abc" />
|
|
|
|
// Or
|
|
<EditMessageComposer messageId="xyz" />
|
|
|
|
// Or
|
|
<ForwardMessageComposer messageId="123" />
|
|
```
|
|
|
|
Each implementation is unique, explicit and self-contained. Yet they can each
|
|
use shared parts.
|
|
|
|
**Implementation:**
|
|
|
|
```tsx
|
|
function ThreadComposer({ channelId }: { channelId: string }) {
|
|
return (
|
|
<ThreadProvider channelId={channelId}>
|
|
<Composer.Frame>
|
|
<Composer.Input />
|
|
<AlsoSendToChannelField channelId={channelId} />
|
|
<Composer.Footer>
|
|
<Composer.Formatting />
|
|
<Composer.Emojis />
|
|
<Composer.Submit />
|
|
</Composer.Footer>
|
|
</Composer.Frame>
|
|
</ThreadProvider>
|
|
)
|
|
}
|
|
|
|
function EditMessageComposer({ messageId }: { messageId: string }) {
|
|
return (
|
|
<EditMessageProvider messageId={messageId}>
|
|
<Composer.Frame>
|
|
<Composer.Input />
|
|
<Composer.Footer>
|
|
<Composer.Formatting />
|
|
<Composer.Emojis />
|
|
<Composer.CancelEdit />
|
|
<Composer.SaveEdit />
|
|
</Composer.Footer>
|
|
</Composer.Frame>
|
|
</EditMessageProvider>
|
|
)
|
|
}
|
|
|
|
function ForwardMessageComposer({ messageId }: { messageId: string }) {
|
|
return (
|
|
<ForwardMessageProvider messageId={messageId}>
|
|
<Composer.Frame>
|
|
<Composer.Input placeholder="Add a message, if you'd like." />
|
|
<Composer.Footer>
|
|
<Composer.Formatting />
|
|
<Composer.Emojis />
|
|
<Composer.Mentions />
|
|
</Composer.Footer>
|
|
</Composer.Frame>
|
|
</ForwardMessageProvider>
|
|
)
|
|
}
|
|
```
|
|
|
|
Each variant is explicit about:
|
|
|
|
- What provider/state it uses
|
|
- What UI elements it includes
|
|
- What actions are available
|
|
|
|
No boolean prop combinations to reason about. No impossible states.
|