Skip to content

Commit 6b507ce

Browse files
committed
Merge branch 'master' into feat/enhanced-mentions
# Conflicts: # src/components/Message/__tests__/__snapshots__/MessageText.test.tsx.snap
2 parents 70241a5 + 4c934ae commit 6b507ce

145 files changed

Lines changed: 11770 additions & 526 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/skills/vercel-composition-patterns/AGENTS.md

Lines changed: 946 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# React Composition Patterns
2+
3+
A structured repository for React composition patterns that scale. These
4+
patterns help avoid boolean prop proliferation by using compound components,
5+
lifting state, and composing internals.
6+
7+
## Structure
8+
9+
- `rules/` - Individual rule files (one per rule)
10+
- `_sections.md` - Section metadata (titles, impacts, descriptions)
11+
- `_template.md` - Template for creating new rules
12+
- `area-description.md` - Individual rule files
13+
- `metadata.json` - Document metadata (version, organization, abstract)
14+
- **`AGENTS.md`** - Compiled output (generated)
15+
16+
## Rules
17+
18+
### Component Architecture (CRITICAL)
19+
20+
- `architecture-avoid-boolean-props.md` - Don't add boolean props to customize
21+
behavior
22+
- `architecture-compound-components.md` - Structure as compound components with
23+
shared context
24+
25+
### State Management (HIGH)
26+
27+
- `state-lift-state.md` - Lift state into provider components
28+
- `state-context-interface.md` - Define clear context interfaces
29+
(state/actions/meta)
30+
- `state-decouple-implementation.md` - Decouple state management from UI
31+
32+
### Implementation Patterns (MEDIUM)
33+
34+
- `patterns-children-over-render-props.md` - Prefer children over renderX props
35+
- `patterns-explicit-variants.md` - Create explicit component variants
36+
37+
## Core Principles
38+
39+
1. **Composition over configuration** — Instead of adding props, let consumers
40+
compose
41+
2. **Lift your state** — State in providers, not trapped in components
42+
3. **Compose your internals** — Subcomponents access context, not props
43+
4. **Explicit variants** — Create ThreadComposer, EditComposer, not Composer
44+
with isThread
45+
46+
## Creating a New Rule
47+
48+
1. Copy `rules/_template.md` to `rules/area-description.md`
49+
2. Choose the appropriate area prefix:
50+
- `architecture-` for Component Architecture
51+
- `state-` for State Management
52+
- `patterns-` for Implementation Patterns
53+
3. Fill in the frontmatter and content
54+
4. Ensure you have clear examples with explanations
55+
56+
## Impact Levels
57+
58+
- `CRITICAL` - Foundational patterns, prevents unmaintainable code
59+
- `HIGH` - Significant maintainability improvements
60+
- `MEDIUM` - Good practices for cleaner code
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
---
2+
name: vercel-composition-patterns
3+
description:
4+
React composition patterns that scale. Use when refactoring components with
5+
boolean prop proliferation, building flexible component libraries, or
6+
designing reusable APIs. Triggers on tasks involving compound components,
7+
render props, context providers, or component architecture. Includes React 19
8+
API changes.
9+
license: MIT
10+
metadata:
11+
author: vercel
12+
version: '1.0.0'
13+
---
14+
15+
# React Composition Patterns
16+
17+
Composition patterns for building flexible, maintainable React components. Avoid
18+
boolean prop proliferation by using compound components, lifting state, and
19+
composing internals. These patterns make codebases easier for both humans and AI
20+
agents to work with as they scale.
21+
22+
## When to Apply
23+
24+
Reference these guidelines when:
25+
26+
- Refactoring components with many boolean props
27+
- Building reusable component libraries
28+
- Designing flexible component APIs
29+
- Reviewing component architecture
30+
- Working with compound components or context providers
31+
32+
## Rule Categories by Priority
33+
34+
| Priority | Category | Impact | Prefix |
35+
| -------- | ----------------------- | ------ | --------------- |
36+
| 1 | Component Architecture | HIGH | `architecture-` |
37+
| 2 | State Management | MEDIUM | `state-` |
38+
| 3 | Implementation Patterns | MEDIUM | `patterns-` |
39+
| 4 | React 19 APIs | MEDIUM | `react19-` |
40+
41+
## Quick Reference
42+
43+
### 1. Component Architecture (HIGH)
44+
45+
- `architecture-avoid-boolean-props` - Don't add boolean props to customize
46+
behavior; use composition
47+
- `architecture-compound-components` - Structure complex components with shared
48+
context
49+
50+
### 2. State Management (MEDIUM)
51+
52+
- `state-decouple-implementation` - Provider is the only place that knows how
53+
state is managed
54+
- `state-context-interface` - Define generic interface with state, actions, meta
55+
for dependency injection
56+
- `state-lift-state` - Move state into provider components for sibling access
57+
58+
### 3. Implementation Patterns (MEDIUM)
59+
60+
- `patterns-explicit-variants` - Create explicit variant components instead of
61+
boolean modes
62+
- `patterns-children-over-render-props` - Use children for composition instead
63+
of renderX props
64+
65+
### 4. React 19 APIs (MEDIUM)
66+
67+
> **⚠️ React 19+ only.** Skip this section if using React 18 or earlier.
68+
69+
- `react19-no-forwardref` - Don't use `forwardRef`; use `use()` instead of `useContext()`
70+
71+
## How to Use
72+
73+
Read individual rule files for detailed explanations and code examples:
74+
75+
```
76+
rules/architecture-avoid-boolean-props.md
77+
rules/state-context-interface.md
78+
```
79+
80+
Each rule file contains:
81+
82+
- Brief explanation of why it matters
83+
- Incorrect code example with explanation
84+
- Correct code example with explanation
85+
- Additional context and references
86+
87+
## Full Compiled Document
88+
89+
For the complete guide with all rules expanded: `AGENTS.md`
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"version": "1.0.0",
3+
"organization": "Engineering",
4+
"date": "January 2026",
5+
"abstract": "Composition patterns for building flexible, maintainable React components. Avoid boolean prop proliferation by using compound components, lifting state, and composing internals. These patterns make codebases easier for both humans and AI agents to work with as they scale.",
6+
"references": [
7+
"https://react.dev",
8+
"https://react.dev/learn/passing-data-deeply-with-context",
9+
"https://react.dev/reference/react/use"
10+
]
11+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Sections
2+
3+
This file defines all sections, their ordering, impact levels, and descriptions.
4+
The section ID (in parentheses) is the filename prefix used to group rules.
5+
6+
---
7+
8+
## 1. Component Architecture (architecture)
9+
10+
**Impact:** HIGH
11+
**Description:** Fundamental patterns for structuring components to avoid prop
12+
proliferation and enable flexible composition.
13+
14+
## 2. State Management (state)
15+
16+
**Impact:** MEDIUM
17+
**Description:** Patterns for lifting state and managing shared context across
18+
composed components.
19+
20+
## 3. Implementation Patterns (patterns)
21+
22+
**Impact:** MEDIUM
23+
**Description:** Specific techniques for implementing compound components and
24+
context providers.
25+
26+
## 4. React 19 APIs (react19)
27+
28+
**Impact:** MEDIUM
29+
**Description:** React 19+ only. Don't use `forwardRef`; use `use()` instead of `useContext()`.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
title: Rule Title Here
3+
impact: MEDIUM
4+
impactDescription: brief description of impact
5+
tags: composition, components
6+
---
7+
8+
## Rule Title Here
9+
10+
Brief explanation of the rule and why it matters.
11+
12+
**Incorrect:**
13+
14+
```tsx
15+
// Bad code example
16+
```
17+
18+
**Correct:**
19+
20+
```tsx
21+
// Good code example
22+
```
23+
24+
Reference: [Link](https://example.com)
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
---
2+
title: Avoid Boolean Prop Proliferation
3+
impact: CRITICAL
4+
impactDescription: prevents unmaintainable component variants
5+
tags: composition, props, architecture
6+
---
7+
8+
## Avoid Boolean Prop Proliferation
9+
10+
Don't add boolean props like `isThread`, `isEditing`, `isDMThread` to customize
11+
component behavior. Each boolean doubles possible states and creates
12+
unmaintainable conditional logic. Use composition instead.
13+
14+
**Incorrect (boolean props create exponential complexity):**
15+
16+
```tsx
17+
function Composer({
18+
onSubmit,
19+
isThread,
20+
channelId,
21+
isDMThread,
22+
dmId,
23+
isEditing,
24+
isForwarding,
25+
}: Props) {
26+
return (
27+
<form>
28+
<Header />
29+
<Input />
30+
{isDMThread ? (
31+
<AlsoSendToDMField id={dmId} />
32+
) : isThread ? (
33+
<AlsoSendToChannelField id={channelId} />
34+
) : null}
35+
{isEditing ? (
36+
<EditActions />
37+
) : isForwarding ? (
38+
<ForwardActions />
39+
) : (
40+
<DefaultActions />
41+
)}
42+
<Footer onSubmit={onSubmit} />
43+
</form>
44+
)
45+
}
46+
```
47+
48+
**Correct (composition eliminates conditionals):**
49+
50+
```tsx
51+
// Channel composer
52+
function ChannelComposer() {
53+
return (
54+
<Composer.Frame>
55+
<Composer.Header />
56+
<Composer.Input />
57+
<Composer.Footer>
58+
<Composer.Attachments />
59+
<Composer.Formatting />
60+
<Composer.Emojis />
61+
<Composer.Submit />
62+
</Composer.Footer>
63+
</Composer.Frame>
64+
)
65+
}
66+
67+
// Thread composer - adds "also send to channel" field
68+
function ThreadComposer({ channelId }: { channelId: string }) {
69+
return (
70+
<Composer.Frame>
71+
<Composer.Header />
72+
<Composer.Input />
73+
<AlsoSendToChannelField id={channelId} />
74+
<Composer.Footer>
75+
<Composer.Formatting />
76+
<Composer.Emojis />
77+
<Composer.Submit />
78+
</Composer.Footer>
79+
</Composer.Frame>
80+
)
81+
}
82+
83+
// Edit composer - different footer actions
84+
function EditComposer() {
85+
return (
86+
<Composer.Frame>
87+
<Composer.Input />
88+
<Composer.Footer>
89+
<Composer.Formatting />
90+
<Composer.Emojis />
91+
<Composer.CancelEdit />
92+
<Composer.SaveEdit />
93+
</Composer.Footer>
94+
</Composer.Frame>
95+
)
96+
}
97+
```
98+
99+
Each variant is explicit about what it renders. We can share internals without
100+
sharing a single monolithic parent.

0 commit comments

Comments
 (0)