← 返回 Skills 市场
wpank

Frontend Composition Patterns

作者 wpank · GitHub ↗ · v1.0.0
cross-platform ✓ 安全检测通过
805
总下载
0
收藏
4
当前安装
1
版本数
在 OpenClaw 中安装
/install composition-patterns
功能描述
Build flexible React components using compound components, context providers, and explicit variants to avoid boolean prop proliferation and improve scalability.
使用说明 (SKILL.md)

React Composition Patterns

Build flexible, maintainable React components using compound components, context providers, and explicit variants. Avoid boolean prop proliferation.

WHAT

Composition patterns that scale:

  • Compound components with shared context
  • State/actions/meta context interface for dependency injection
  • Explicit variant components over boolean props
  • Lifted state in provider components
  • Children composition over render props

WHEN

  • Refactoring components with many boolean props
  • Building reusable component libraries
  • Designing flexible component APIs
  • Creating compound components (Card, Dialog, Form, etc.)
  • Components need shared state across sibling elements

KEYWORDS

composition, compound components, context, provider, boolean props, variants, react patterns, component architecture, render props, children

Source: Vercel Engineering

Installation

OpenClaw / Moltbot / Clawbot

npx clawhub@latest install composition-patterns

Core Principle

Avoid boolean prop proliferation. Each boolean doubles possible states.

// BAD: 4 booleans = 16 possible states
\x3CComposer isThread isDMThread isEditing isForwarding />

// GOOD: Explicit variants, clear intent
\x3CThreadComposer channelId="abc" />
\x3CEditComposer messageId="xyz" />

Pattern 1: Compound Components

Structure complex components with shared context. Consumers compose what they need.

const ComposerContext = createContext\x3CComposerContextValue | null>(null)

// Provider handles state
function ComposerProvider({ children, state, actions, meta }: ProviderProps) {
  return (
    \x3CComposerContext value={{ state, actions, meta }}>
      {children}
    \x3C/ComposerContext>
  )
}

// Subcomponents access context
function ComposerInput() {
  const { state, actions: { update }, meta: { inputRef } } = use(ComposerContext)
  return (
    \x3CTextInput
      ref={inputRef}
      value={state.input}
      onChangeText={(text) => update(s => ({ ...s, input: text }))}
    />
  )
}

function ComposerSubmit() {
  const { actions: { submit } } = use(ComposerContext)
  return \x3CButton onPress={submit}>Send\x3C/Button>
}

// Export as namespace
const Composer = {
  Provider: ComposerProvider,
  Frame: ComposerFrame,
  Input: ComposerInput,
  Submit: ComposerSubmit,
  Header: ComposerHeader,
  Footer: ComposerFooter,
}

Usage:

\x3CComposer.Provider state={state} actions={actions} meta={meta}>
  \x3CComposer.Frame>
    \x3CComposer.Header />
    \x3CComposer.Input />
    \x3CComposer.Footer>
      \x3CComposer.Formatting />
      \x3CComposer.Submit />
    \x3C/Composer.Footer>
  \x3C/Composer.Frame>
\x3C/Composer.Provider>

Pattern 2: Generic Context Interface

Define a contract any provider can implement: state, actions, meta.

interface ComposerState {
  input: string
  attachments: Attachment[]
  isSubmitting: boolean
}

interface ComposerActions {
  update: (updater: (state: ComposerState) => ComposerState) => void
  submit: () => void
}

interface ComposerMeta {
  inputRef: React.RefObject\x3CTextInput>
}

interface ComposerContextValue {
  state: ComposerState
  actions: ComposerActions
  meta: ComposerMeta
}

Same UI, different providers:

// Local state provider
function ForwardMessageProvider({ children }) {
  const [state, setState] = useState(initialState)
  return (
    \x3CComposerContext value={{
      state,
      actions: { update: setState, submit: useForwardMessage() },
      meta: { inputRef: useRef(null) },
    }}>
      {children}
    \x3C/ComposerContext>
  )
}

// Global synced state provider  
function ChannelProvider({ channelId, children }) {
  const { state, update, submit } = useGlobalChannel(channelId)
  return (
    \x3CComposerContext value={{
      state,
      actions: { update, submit },
      meta: { inputRef: useRef(null) },
    }}>
      {children}
    \x3C/ComposerContext>
  )
}

Both work with the same \x3CComposer.Input /> component.


Pattern 3: Explicit Variants

Create named components for each use case instead of boolean modes.

// BAD: What does this render?
\x3CComposer
  isThread
  isEditing={false}
  channelId="abc"
  showAttachments
/>

// GOOD: Self-documenting
\x3CThreadComposer channelId="abc" />

Implementation:

function ThreadComposer({ channelId }: { channelId: string }) {
  return (
    \x3CThreadProvider channelId={channelId}>
      \x3CComposer.Frame>
        \x3CComposer.Input />
        \x3CAlsoSendToChannelField channelId={channelId} />
        \x3CComposer.Footer>
          \x3CComposer.Formatting />
          \x3CComposer.Submit />
        \x3C/Composer.Footer>
      \x3C/Composer.Frame>
    \x3C/ThreadProvider>
  )
}

function EditComposer({ messageId }: { messageId: string }) {
  return (
    \x3CEditProvider messageId={messageId}>
      \x3CComposer.Frame>
        \x3CComposer.Input />
        \x3CComposer.Footer>
          \x3CComposer.CancelEdit />
          \x3CComposer.SaveEdit />
        \x3C/Composer.Footer>
      \x3C/Composer.Frame>
    \x3C/EditProvider>
  )
}

Pattern 4: Lifted State

Components outside the visual hierarchy can access state via provider.

function ForwardMessageDialog() {
  return (
    \x3CForwardMessageProvider>
      \x3CDialog>
        {/* Composer UI */}
        \x3CComposer.Frame>
          \x3CComposer.Input placeholder="Add a message" />
          \x3CComposer.Footer>
            \x3CComposer.Formatting />
          \x3C/Composer.Footer>
        \x3C/Composer.Frame>

        {/* Preview OUTSIDE composer but reads its state */}
        \x3CMessagePreview />

        {/* Actions OUTSIDE composer but can submit */}
        \x3CDialogActions>
          \x3CCancelButton />
          \x3CForwardButton />
        \x3C/DialogActions>
      \x3C/Dialog>
    \x3C/ForwardMessageProvider>
  )
}

// Can access context despite being outside Composer.Frame
function ForwardButton() {
  const { actions: { submit } } = use(ComposerContext)
  return \x3CButton onPress={submit}>Forward\x3C/Button>
}

function MessagePreview() {
  const { state } = use(ComposerContext)
  return \x3CPreview message={state.input} attachments={state.attachments} />
}

Key insight: Provider boundary matters, not visual nesting.


Pattern 5: Children Over Render Props

Use children for composition, render props only when passing data.

// BAD: Render props for structure
\x3CComposer
  renderHeader={() => \x3CCustomHeader />}
  renderFooter={() => \x3CFormatting />}
  renderActions={() => \x3CSubmit />}
/>

// GOOD: Children for structure
\x3CComposer.Frame>
  \x3CCustomHeader />
  \x3CComposer.Input />
  \x3CComposer.Footer>
    \x3CFormatting />
    \x3CSubmit />
  \x3C/Composer.Footer>
\x3C/Composer.Frame>

When render props ARE appropriate:

// Passing data to children
\x3CList
  data={items}
  renderItem={({ item, index }) => \x3CItem item={item} index={index} />}
/>

Pattern 6: Decouple State from UI

Only the provider knows how state is managed. UI consumes the interface.

// BAD: UI coupled to state implementation
function ChannelComposer({ channelId }) {
  const state = useGlobalChannelState(channelId)  // Knows about global state
  const { submit } = useChannelSync(channelId)    // Knows about sync
  
  return \x3CComposer.Input value={state.input} onChange={...} />
}

// GOOD: State isolated in provider
function ChannelProvider({ channelId, children }) {
  const { state, update, submit } = useGlobalChannel(channelId)
  
  return (
    \x3CComposer.Provider
      state={state}
      actions={{ update, submit }}
      meta={{ inputRef: useRef(null) }}
    >
      {children}
    \x3C/Composer.Provider>
  )
}

// UI only knows the interface
function ChannelComposer() {
  return (
    \x3CComposer.Frame>
      \x3CComposer.Input />  {/* Works with any provider */}
      \x3CComposer.Submit />
    \x3C/Composer.Frame>
  )
}

Quick Reference

Anti-Pattern Solution
Boolean props Explicit variant components
Render props for structure Children composition
State in component Lift to provider
Coupled to state impl Generic context interface
Many conditional renders Compose pieces explicitly

Files

  • rules/architecture-avoid-boolean-props.md - Detailed boolean prop guidance
  • rules/architecture-compound-components.md - Compound component pattern
  • rules/state-context-interface.md - Context interface design
  • rules/state-decouple-implementation.md - State isolation
  • rules/state-lift-state.md - Provider pattern
  • rules/patterns-explicit-variants.md - Variant components
  • rules/patterns-children-over-render-props.md - Composition over callbacks

NEVER

  • Add boolean props to customize behavior (use composition)
  • Create components with more than 2-3 boolean mode props
  • Couple UI components to specific state implementations
  • Use render props when children would work
  • Trap state inside components when siblings need access
安全使用建议
This skill is documentation-only and appears coherent with its purpose. It does not request credentials or contain executable code in the bundle. Before installing or running any suggested npx commands, verify the remote repository and author (the SKILL.md mentions 'Vercel Engineering' but the package metadata lacks a homepage), and inspect the files you will fetch — npx and similar tools execute code from remote sources, so only run them against trusted origins. If you only want the guidance, you can read the included Markdown files without running installers.
功能分析
Type: OpenClaw Skill Name: composition-patterns Version: 1.0.0 The skill bundle is benign. All files are either metadata or documentation/instructional markdown explaining React composition patterns. The code examples provided are illustrative TypeScript React (tsx) and not intended for execution by the AI agent as shell commands. The `SKILL.md` and `README.md` files contain standard installation instructions for the skill itself, including `npx clawhub@latest install` and `npx add` commands that fetch from a seemingly legitimate GitHub repository (https://github.com/wpank/ai/tree/main/skills/frontend/composition-patterns). There is no evidence of malicious intent, data exfiltration, unauthorized execution, persistence mechanisms, or harmful prompt injection attempts against the agent.
能力评估
Purpose & Capability
The skill's name, files, and SKILL.md all describe React composition patterns and related guidance. There are no declared binaries, env vars, or unrelated dependencies that would be inconsistent with a documentation/reference skill. One minor note: the package metadata has no user-visible description/homepage even though SKILL.md claims a source ('Vercel Engineering'), which reduces provenance but doesn't indicate malicious intent.
Instruction Scope
SKILL.md contains only documentation and example code (React/TypeScript patterns). It does not instruct the agent to read local files, environment variables, or transmit data to external endpoints. It does include installation instructions (npx clawhub install, and README examples that copy files into local skill folders) — those are user-side commands, not runtime agent instructions. Be aware that running the provided npx commands would fetch remote code.
Install Mechanism
No install spec is embedded in the skill bundle; this is instruction-only. The README suggests installing via npx and copying files from a GitHub tree URL. Those are common for docs-style skills; they do imply fetching remote content if you run them, so inspect the remote repo before executing any npx commands.
Credentials
The skill requests no environment variables, credentials, or config paths. This is proportionate for a documentation/reference skill.
Persistence & Privilege
(always) is false and the skill does not request any elevated or persistent system privileges. There are no instructions that modify other skills or system-wide agent settings.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install composition-patterns
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /composition-patterns 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v1.0.0
- Initial release of react-composition-patterns. - Documents key React composition techniques: compound components, context providers, explicit variants, and state management separation. - Emphasizes avoiding boolean prop proliferation in favor of variant components. - Includes practical examples and anti-patterns for building flexible, maintainable component libraries. - Installation instructions provided for OpenClaw ecosystem.
元数据
Slug composition-patterns
版本 1.0.0
许可证
累计安装 4
当前安装数 4
历史版本数 1
常见问题

Frontend Composition Patterns 是什么?

Build flexible React components using compound components, context providers, and explicit variants to avoid boolean prop proliferation and improve scalability. 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 805 次。

如何安装 Frontend Composition Patterns?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install composition-patterns」即可一键安装,无需额外配置。

Frontend Composition Patterns 是免费的吗?

是的,Frontend Composition Patterns 完全免费(开源免费),可自由下载、安装和使用。

Frontend Composition Patterns 支持哪些平台?

Frontend Composition Patterns 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 Frontend Composition Patterns?

由 wpank(@wpank)开发并维护,当前版本 v1.0.0。

💬 留言讨论