xiaohongshu
xiaohongshu
Create demonstration pages for components and hooks.
Full skill instructions
This skill guides the creation and maintenance of components and their demo pages in the Protobox component showcase.
Use this skill when:
src/components/src/hooks/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:
/[name]-demoCreate the component in the appropriate location:
src/components/[ComponentName].tsxsrc/hooks/[hookName].tsxnpx shadcn-ui@latest add [component] for shadcn componentsFollow component best practices from src/components/README.md:
style, className, and native element propsdark: variants/components/[name])Create Content Component in src/components/DemoShowcase/[Name]Content.tsx:
min-h-screen, full-page padding, headers, back linksRegister in Demo Registry (src/components/DemoShowcase/demoRegistry.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]',
}
Add Route in src/App.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>
}
/>
/[name]-demo)Create Page Component in src/pages/[Name]Demo.tsx:
Add Route in src/App.tsx:
import [Name]Demo from './pages/[Name]Demo'
<Route path="/[name]-demo" Component={[Name]Demo} />
/components/[name]-playground)Playgrounds provide an interactive, Storybook-like environment with a canvas and props controls.
Analyze Component Props:
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: booleanComplex props (not controllable):
onClick: functionasChild: boolean (affects render behavior)ref: React refWhich props would you like to expose in the playground?"
Create Playground Content in src/components/DemoShowcase/[Name]PlaygroundContent.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>
)
}
Register in Demo Registry (src/components/DemoShowcase/demoRegistry.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',
}
Add Route in src/App.tsx:
const [Name]PlaygroundContent = lazy(() => import('./components/DemoShowcase/[Name]PlaygroundContent'))
<Route
path="[name]-playground"
element={
<Suspense fallback={<div>Loading...</div>}>
<[Name]PlaygroundContent />
</Suspense>
}
/>
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 |
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
}
}
CRITICAL: When updating an existing component or hook, ALWAYS check if demo pages exist:
Search for Demo Pages:
src/components/DemoShowcase/ for [Name]Content.tsx or [Name]PlaygroundContent.tsxsrc/pages/ for [Name]Demo.tsxdemoRegistry.tsx for entries (including type: 'playground')If Demo Pages Exist:
Prompt User:
"I found existing demo pages for this [component/hook]. I'll update them to include the new [feature/changes]."
Organize demo content with clear sections:
<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>
Include diverse examples:
The navigation is automatically generated from demoRegistry.tsx:
Demos are displayed in the order they appear in DEMO_REGISTRY.
After creating or updating component demos:
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
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
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
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
src/pages/ComponentShowcase.tsxsrc/components/DemoShowcase/demoRegistry.tsxsrc/components/DemoShowcase/DemoNavigation.tsxsrc/components/DemoShowcase/[Name]Content.tsxsrc/components/DemoShowcase/[Name]PlaygroundContent.tsxsrc/components/DemoShowcase/PlaygroundCanvas.tsxsrc/pages/[Name]Demo.tsxsrc/App.tsxxiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience