Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Apply React composition patterns to build flexible, maintainable components without boolean prop sprawl
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
rules/patterns-explicit-variants.md
1---2title: Create Explicit Component Variants3impact: MEDIUM4impactDescription: self-documenting code, no hidden conditionals5tags: composition, variants, architecture6---78## Create Explicit Component Variants910Instead of one component with many boolean props, create explicit variant11components. Each variant composes the pieces it needs. The code documents12itself.1314**Incorrect (one component, many modes):**1516```tsx17// What does this component actually render?18<Composer19isThread20isEditing={false}21channelId='abc'22showAttachments23showFormatting={false}24/>25```2627**Correct (explicit variants):**2829```tsx30// Immediately clear what this renders31<ThreadComposer channelId="abc" />3233// Or34<EditMessageComposer messageId="xyz" />3536// Or37<ForwardMessageComposer messageId="123" />38```3940Each implementation is unique, explicit and self-contained. Yet they can each41use shared parts.4243**Implementation:**4445```tsx46function ThreadComposer({ channelId }: { channelId: string }) {47return (48<ThreadProvider channelId={channelId}>49<Composer.Frame>50<Composer.Input />51<AlsoSendToChannelField channelId={channelId} />52<Composer.Footer>53<Composer.Formatting />54<Composer.Emojis />55<Composer.Submit />56</Composer.Footer>57</Composer.Frame>58</ThreadProvider>59)60}6162function EditMessageComposer({ messageId }: { messageId: string }) {63return (64<EditMessageProvider messageId={messageId}>65<Composer.Frame>66<Composer.Input />67<Composer.Footer>68<Composer.Formatting />69<Composer.Emojis />70<Composer.CancelEdit />71<Composer.SaveEdit />72</Composer.Footer>73</Composer.Frame>74</EditMessageProvider>75)76}7778function ForwardMessageComposer({ messageId }: { messageId: string }) {79return (80<ForwardMessageProvider messageId={messageId}>81<Composer.Frame>82<Composer.Input placeholder="Add a message, if you'd like." />83<Composer.Footer>84<Composer.Formatting />85<Composer.Emojis />86<Composer.Mentions />87</Composer.Footer>88</Composer.Frame>89</ForwardMessageProvider>90)91}92```9394Each variant is explicit about:9596- What provider/state it uses97- What UI elements it includes98- What actions are available99100No boolean prop combinations to reason about. No impossible states.101