home / skills / fusengine / agents / component-composition

This skill helps you design reusable component APIs and patterns such as children, slots, and render props to improve UI composition.

npx playbooks add skill fusengine/agents --skill component-composition

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
2.7 KB
---
name: component-composition
description: Use when creating reusable components, component APIs, or complex hierarchies. Covers children, slots, compound components, render props.
versions:
  react: "19"
user-invocable: true
allowed-tools: Read, Write, Edit, Glob, Grep
related-skills: generating-components
---

# Component Composition

## Agent Workflow (MANDATORY)

Before implementation, use `TeamCreate` to spawn 3 agents:

1. **fuse-ai-pilot:explore-codebase** - Check existing composition patterns
2. **fuse-ai-pilot:research-expert** - React 19 composition patterns

After: Run **fuse-ai-pilot:sniper** for validation.

---

## Overview

| Pattern | Use Case | Complexity |
|---------|----------|------------|
| Children | Simple containers | Low |
| Slots | Named regions | Medium |
| Compound | Related sub-components | Medium |
| Render Props | Custom rendering | High |

---

## Quick Reference

### Children Pattern

```tsx
function Card({ children }: { children: React.ReactNode }) {
  return <div className="bg-surface rounded-2xl p-6">{children}</div>;
}
```

### Slots Pattern

```tsx
function Card({ header, footer, children }: CardProps) {
  return (
    <div className="bg-surface rounded-2xl">
      {header && <div className="px-6 py-4 border-b">{header}</div>}
      <div className="p-6">{children}</div>
      {footer && <div className="px-6 py-4 border-t">{footer}</div>}
    </div>
  );
}
```

### Compound Components

```tsx
function Card({ children, variant }) {
  return (
    <CardContext.Provider value={{ variant }}>
      <div className="bg-surface rounded-2xl">{children}</div>
    </CardContext.Provider>
  );
}

Card.Header = ({ children }) => <div className="px-6 py-4">{children}</div>;
Card.Body = ({ children }) => <div className="p-6">{children}</div>;
Card.Footer = ({ children }) => <div className="px-6 py-4">{children}</div>;

// Usage
<Card>
  <Card.Header>Title</Card.Header>
  <Card.Body>Content</Card.Body>
</Card>
```

### Polymorphic Components

```tsx
function Button<T extends React.ElementType = "button">({
  as,
  children,
  ...props
}: ButtonProps<T>) {
  const Component = as || "button";
  return <Component className="btn" {...props}>{children}</Component>;
}

// Usage
<Button as="a" href="/link">Link</Button>
```

---

## Validation Checklist

```
[ ] Appropriate pattern for complexity
[ ] TypeScript props properly typed
[ ] displayName set on forwardRef
[ ] Max 2-3 composition levels
```

---

## Best Practices

### DO
- Use children for simple nesting
- Use slots for named regions (max 3-4)
- Forward refs for form elements
- Set displayName

### DON'T
- Over-engineer simple components
- Create deep nesting (max 2 levels)
- Forget TypeScript types
- Skip ref forwarding

Overview

This skill helps teams design and implement reusable UI components and component APIs in TypeScript. It codifies composition patterns—children, slots, compound components, render props, and polymorphic components—and provides a lightweight validation workflow. Use it to choose the right pattern for complexity, enforce TypeScript typings, and keep hierarchies maintainable.

How this skill works

It inspects component intent and recommends a composition pattern based on complexity and naming. The skill guides TypeScript prop typings, ref forwarding, and displayName conventions, and it includes a short validation checklist to apply after implementation. It also prescribes spawning review agents to explore existing patterns and validate the final design.

When to use it

  • Creating simple container components where content is passed directly
  • Designing components that need named regions (headers, footers, sidebars)
  • Building related sub-components that share context (compound components)
  • Implementing highly customizable rendering surfaces (render props or polymorphic components)
  • Reviewing or refactoring existing component hierarchies to reduce depth and improve types

Best practices

  • Prefer children for simple nesting and small, single-slot components
  • Limit named slots to 3–4 to avoid API complexity
  • Use Context and static sub-components for compound components to share state
  • Forward refs for interactive or form elements and set displayName on forwardRef components
  • Keep composition depth shallow—aim for 2 levels, max 3
  • Fully type props in TypeScript and avoid implicit any

Example use cases

  • Card component with children for basic content layouts
  • Card with header and footer props implementing slot-like regions
  • Card compound API with Card.Header, Card.Body, Card.Footer using context to share variant state
  • Polymorphic Button component that accepts an "as" prop to render as different HTML elements
  • Advanced layout component exposing a render-prop for consumers to control inner markup

FAQ

How do I choose between slots and compound components?

Use slots when you need a small number of named regions and simple placement. Use compound components when sub-components need access to shared state or context.

When should I use polymorphic components?

Use polymorphic components when a single API should render multiple HTML elements (like button vs link) while preserving props and accessibility. They add complexity, so use them for reusable primitives.