Files
agent-skills/skills/vercel-react-native-skills/rules/design-system-compound-components.md
Jason Woltje f5792c40be feat: Complete fleet — 94 skills across 10+ domains
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>
2026-02-16 16:27:42 -06:00

67 lines
1.6 KiB
Markdown

---
title: Use Compound Components Over Polymorphic Children
impact: MEDIUM
impactDescription: flexible composition, clearer API
tags: design-system, components, composition
---
## Use Compound Components Over Polymorphic Children
Don't create components that can accept a string if they aren't a text node. If
a component can receive a string child, it must be a dedicated `*Text`
component. For components like buttons, which can have both a View (or
Pressable) together with text, use compound components, such a `Button`,
`ButtonText`, and `ButtonIcon`.
**Incorrect (polymorphic children):**
```tsx
import { Pressable, Text } from 'react-native'
type ButtonProps = {
children: string | React.ReactNode
icon?: React.ReactNode
}
function Button({ children, icon }: ButtonProps) {
return (
<Pressable>
{icon}
{typeof children === 'string' ? <Text>{children}</Text> : children}
</Pressable>
)
}
// Usage is ambiguous
<Button icon={<Icon />}>Save</Button>
<Button><CustomText>Save</CustomText></Button>
```
**Correct (compound components):**
```tsx
import { Pressable, Text } from 'react-native'
function Button({ children }: { children: React.ReactNode }) {
return <Pressable>{children}</Pressable>
}
function ButtonText({ children }: { children: React.ReactNode }) {
return <Text>{children}</Text>
}
function ButtonIcon({ children }: { children: React.ReactNode }) {
return <>{children}</>
}
// Usage is explicit and composable
<Button>
<ButtonIcon><SaveIcon /></ButtonIcon>
<ButtonText>Save</ButtonText>
</Button>
<Button>
<ButtonText>Cancel</ButtonText>
</Button>
```