Skip to content
Back to skills

Component Demo

ASecurity

Create demonstration pages for components and hooks.

  • 666 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added February 8, 2026
developmenttypescriptgoreactnodetesting

Works with

  • cli

Security analysis

A100/100

Scanned February 12, 2026

npx -y skills add majiayu000/claude-skill-registry --skill component-demo --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Component Demo?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Component Demo
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/majiayu000-component-demo/badge)](https://www.skillsdirectory.com/skills/majiayu000-component-demo)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: "component demo"
description: "Create demonstration pages for components and hooks."
license: Proprietary
---

# Component Demo Skill

This skill guides the creation and maintenance of components and their demo pages in the Protobox component showcase.

## When to Use This Skill

Use this skill when:
- Creating new custom components in `src/components/`
- Creating new custom hooks in `src/hooks/`
- Updating existing components or hooks
- Planning feature additions that involve reusable components

## Component Development Workflow

### Phase 1: Planning - Ask About Demo Pages

**IMPORTANT:** When planning to create a new component or hook, ALWAYS ask the user:

> "Would you like me to create a demo page for this [component/hook] in the component showcase?"

Options to present:
1. **Yes, create demo page** - Create both the component and a showcase demo
2. **Yes, standalone demo** - Create component and a standalone demo page at `/[name]-demo`
3. **Yes, playground** - Create an interactive playground with props controls (Storybook-like)
4. **No demo needed** - Just create the component/hook

### Phase 2: Component Creation

Create the component in the appropriate location:
- Custom components: `src/components/[ComponentName].tsx`
- Custom hooks: `src/hooks/[hookName].tsx`
- UI components: Use `npx shadcn-ui@latest add [component]` for shadcn components

Follow component best practices from `src/components/README.md`:
- Simple default usage with sensible defaults
- Accept `style`, `className`, and native element props
- Use composition for icons (via props, not hardcoded)
- Standard heights: 16px, 20px, 40px
- Support dark mode with Tailwind `dark:` variants

### Phase 3: Demo Page Creation (if requested)

#### A. For Component Showcase (`/components/[name]`)

1. **Create Content Component** in `src/components/DemoShowcase/[Name]Content.tsx`:
   - Extract core demo functionality without page wrappers
   - Remove: `min-h-screen`, full-page padding, headers, back links
   - Keep: interactive elements, controls, examples
   - Use Card components to organize examples
   - Include usage code examples

2. **Register in Demo Registry** (`src/components/DemoShowcase/demoRegistry.tsx`):
   ```tsx
   // Add lazy import
   const [Name]Content = lazy(() => import('./[Name]Content'))

   // Add to DEMO_REGISTRY array
   {
     id: '[name]',
     label: '[Display Name]',
     section: 'Hooks' | 'Components',
     component: [Name]Content,
     description: 'Brief description',
     path: '/components/[name]',
   }
   ```

3. **Add Route** in `src/App.tsx`:
   ```tsx
   // Add lazy import at top
   const [Name]Content = lazy(() => import('./components/DemoShowcase/[Name]Content'))

   // Add route inside <Route path="/components"> nested routes
   <Route
     path="[name]"
     element={
       <Suspense fallback={<div>Loading...</div>}>
         <[Name]Content />
       </Suspense>
     }
   />
   ```

#### B. For Standalone Demo Page (`/[name]-demo`)

1. **Create Page Component** in `src/pages/[Name]Demo.tsx`:
   - Include full-page wrapper with proper styling
   - Add header with title and description
   - Organize examples using Card components
   - Include code examples showing usage
   - Add back link to home

2. **Add Route** in `src/App.tsx`:
   ```tsx
   import [Name]Demo from './pages/[Name]Demo'

   <Route path="/[name]-demo" Component={[Name]Demo} />
   ```

#### C. For Component Playground (`/components/[name]-playground`)

Playgrounds provide an interactive, Storybook-like environment with a canvas and props controls.

1. **Analyze Component Props:**
   - Read the target component's source file
   - Parse the TypeScript Props interface
   - Categorize props as controllable or complex

2. **Guide Prop Selection - Present to User:**
   > "I analyzed [ComponentName] and found these props:
   >
   > **Recommended for playground (controllable):**
   > - `variant`: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'
   > - `size`: 'default' | 'sm' | 'lg' | 'icon'
   > - `disabled`: boolean
   >
   > **Complex props (not controllable):**
   > - `onClick`: function
   > - `asChild`: boolean (affects render behavior)
   > - `ref`: React ref
   >
   > Which props would you like to expose in the playground?"

3. **Create Playground Content** in `src/components/DemoShowcase/[Name]PlaygroundContent.tsx`:
   ```tsx
   import PlaygroundCanvas, { PropSchema } from './PlaygroundCanvas'
   import { Button } from '@/components/ui/button'

   const propSchema: PropSchema = {
     variant: {
       type: 'select',
       options: ['default', 'destructive', 'outline', 'secondary', 'ghost', 'link'],
       defaultValue: 'default',
     },
     size: {
       type: 'select',
       options: ['default', 'sm', 'lg', 'icon'],
       defaultValue: 'default',
     },
     disabled: {
       type: 'boolean',
       defaultValue: false,
     },
     children: {
       type: 'string',
       defaultValue: 'Button',
     },
   }

   export default function ButtonPlaygroundContent() {
     return (
       <PlaygroundCanvas
         componentName="Button"
         propSchema={propSchema}
         defaultProps={{ children: 'Click Me' }}
       >
         {(props) => <Button {...props}>{props.children as string}</Button>}
       </PlaygroundCanvas>
     )
   }
   ```

4. **Register in Demo Registry** (`src/components/DemoShowcase/demoRegistry.tsx`):
   ```tsx
   // Add lazy import
   const [Name]PlaygroundContent = lazy(() => import('./[Name]PlaygroundContent'))

   // Add to DEMO_REGISTRY array
   {
     id: '[name]-playground',
     label: '[Name] Playground',
     section: 'Components',
     component: [Name]PlaygroundContent,
     description: 'Interactive playground for [Name]',
     path: '/components/[name]-playground',
     type: 'playground',
   }
   ```

5. **Add Route** in `src/App.tsx`:
   ```tsx
   const [Name]PlaygroundContent = lazy(() => import('./components/DemoShowcase/[Name]PlaygroundContent'))

   <Route
     path="[name]-playground"
     element={
       <Suspense fallback={<div>Loading...</div>}>
         <[Name]PlaygroundContent />
       </Suspense>
     }
   />
   ```

### Prop Type Mapping Reference

When analyzing TypeScript props, map types to Leva controls:

| TypeScript Type | PropSchema Type | Notes |
|-----------------|-----------------|-------|
| `string` | `'string'` | Text input |
| `number` | `'number'` | Slider (add min/max/step) |
| `boolean` | `'boolean'` | Checkbox toggle |
| `'a' \| 'b' \| 'c'` | `'select'` | Dropdown with options array |
| `enum Foo { A, B }` | `'select'` | Extract enum values as options |
| `React.ReactNode` | `'string'` | For simple text children |
| Color strings | `'color'` | Color picker |
| `() => void` | Skip | Not controllable |
| Complex objects | Skip | Not controllable |
| `React.Ref` | Skip | Not controllable |

### PropSchema Format

```tsx
import { PropSchema } from '@/components/DemoShowcase/PlaygroundCanvas'

const schema: PropSchema = {
  propName: {
    type: 'string' | 'number' | 'boolean' | 'select' | 'color',
    label?: string,           // Custom label (defaults to propName)
    defaultValue?: unknown,   // Initial value
    options?: string[],       // For 'select' type
    min?: number,             // For 'number' type
    max?: number,             // For 'number' type
    step?: number,            // For 'number' type
  }
}
```

### Phase 4: Component Updates - Check for Existing Demos

**CRITICAL:** When updating an existing component or hook, ALWAYS check if demo pages exist:

1. **Search for Demo Pages:**
   - Check `src/components/DemoShowcase/` for `[Name]Content.tsx` or `[Name]PlaygroundContent.tsx`
   - Check `src/pages/` for `[Name]Demo.tsx`
   - Check `demoRegistry.tsx` for entries (including `type: 'playground'`)

2. **If Demo Pages Exist:**
   - Update them to reflect new functionality
   - Add examples demonstrating new features
   - Update code examples
   - Test that demos still work correctly

3. **Prompt User:**
   > "I found existing demo pages for this [component/hook]. I'll update them to include the new [feature/changes]."

## Demo Content Best Practices

### Structure

Organize demo content with clear sections:

```tsx
<div className="space-y-8">
  {/* Example 1: Basic Usage */}
  <Card className="p-6 space-y-3">
    <div className="flex items-center gap-2">
      <Badge variant="secondary">Basic</Badge>
      <span className="text-xs text-zinc-500 dark:text-zinc-400">
        Configuration details
      </span>
    </div>
    {/* Demo content */}
  </Card>

  {/* More examples... */}

  {/* Code Example */}
  <Card className="p-6 space-y-3 bg-zinc-50 dark:bg-zinc-900">
    <Badge variant="outline">Usage Example</Badge>
    <pre className="text-xs text-zinc-700 dark:text-zinc-300 overflow-x-auto">
      <code>{`// Code example here`}</code>
    </pre>
  </Card>
</div>
```

### Example Categories

Include diverse examples:
1. **Basic** - Simple default usage
2. **Advanced** - Complex configurations
3. **Interactive** - User-controlled examples
4. **Variants** - Different visual styles or behaviors
5. **Edge Cases** - Boundary conditions
6. **Code Examples** - Implementation snippets

### Styling

- Use Card components for grouping examples
- Add Badge components for labeling examples
- Include configuration details in muted text
- Support dark mode throughout
- Add visual indicators for interactive elements
- Show state changes clearly

## Component Showcase Navigation

The navigation is automatically generated from `demoRegistry.tsx`:
- **Hooks** section: Custom React hooks
- **Components** section: UI components, libraries, demos

Demos are displayed in the order they appear in `DEMO_REGISTRY`.

## Testing Checklist

After creating or updating component demos:

- [ ] Navigate to the demo route
- [ ] Verify all examples render correctly
- [ ] Test interactive elements (buttons, inputs, controls)
- [ ] Check dark mode appearance
- [ ] Verify code examples are accurate
- [ ] Test on different screen sizes
- [ ] Check TypeScript compilation
- [ ] Verify navigation active state

### Additional Checks for Playgrounds

- [ ] Verify Leva props panel appears (top-right corner)
- [ ] Test that prop changes update the component in real-time
- [ ] Verify navigation collapse toggle works
- [ ] Check canvas centering at different sizes
- [ ] Test all prop controls (selects, inputs, toggles)

## Examples

### Example 1: Creating a New Hook with Demo

```
User: "Create a useDebounce hook"

Claude:
1. Asks: "Would you like me to create a demo page for this hook in the component showcase?"
2. User selects: "Yes, create demo page"
3. Creates:
   - src/hooks/useDebounce.tsx (the hook)
   - src/components/DemoShowcase/DebounceContent.tsx (demo)
   - Updates demoRegistry.tsx
   - Updates App.tsx with route
```

### Example 2: Updating Existing Component

```
User: "Add a 'size' prop to the Button component"

Claude:
1. Searches for existing demos
2. Finds: N/A (Button is shadcn component, no custom demo)
3. Updates Button usage examples in existing demos if needed
```

### Example 3: Updating Hook with Demo

```
User: "Add a 'delay' option to useTypewriter"

Claude:
1. Updates src/hooks/useTypewriter.tsx
2. Searches and finds: src/components/DemoShowcase/TypewriterContent.tsx
3. Announces: "I found the existing TypewriterContent demo. I'll add an example showing the new delay option."
4. Adds new Card with delay example
5. Updates code example to include delay option
```

### Example 4: Creating a Component Playground

```
User: "Create a playground for the Badge component"

Claude:
1. Asks: "Would you like me to create a demo page for this component?"
2. User selects: "Yes, playground"
3. Claude reads src/components/ui/badge.tsx
4. Analyzes BadgeProps interface and presents:
   "I found these props:

   **Controllable:**
   - variant: 'default' | 'secondary' | 'destructive' | 'outline'
   - children: ReactNode (as string)

   **Not controllable:**
   - className: styling (skip)

   Which props would you like to expose?"
5. User selects: "variant and children"
6. Creates:
   - src/components/DemoShowcase/BadgePlaygroundContent.tsx
   - Updates demoRegistry.tsx with type: 'playground'
   - Updates App.tsx with route
```

## File Locations Reference

- Component showcase layout: `src/pages/ComponentShowcase.tsx`
- Demo registry: `src/components/DemoShowcase/demoRegistry.tsx`
- Navigation: `src/components/DemoShowcase/DemoNavigation.tsx`
- Demo content: `src/components/DemoShowcase/[Name]Content.tsx`
- Playground content: `src/components/DemoShowcase/[Name]PlaygroundContent.tsx`
- Playground canvas: `src/components/DemoShowcase/PlaygroundCanvas.tsx`
- Standalone demos: `src/pages/[Name]Demo.tsx`
- Routes: `src/App.tsx`

## Key Principles

1. **Always ask** - Don't assume whether demos are wanted
2. **Always search** - Check for existing demos before updating
3. **Keep demos updated** - When components change, demos should reflect it
4. **Provide variety** - Show multiple use cases, not just basic usage
5. **Make it interactive** - Let users experiment with controls
6. **Include code** - Show implementation examples
7. **Support dark mode** - Test in both themes
8. **Organize clearly** - Use consistent structure across demos

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.