Fixtures
Provide concrete values for component-type props — icons, badges, or any React element.
What are fixtures
Some props accept React components rather than primitive values. A prop typed as icon?: LucideIcon can't be controlled with a text input. Fixtures give jc a set of named values to offer in a visual picker.
Create a fixture plugin
tsx
import { defineFixtures } from 'jc'
import { Star, Heart, Zap, Download, Trash2 } from 'lucide-react'
import { createElement } from 'react'
function icon(Comp: typeof Star, size = 20) {
return {
render: () => createElement(Comp, { size }),
renderPreview: () => createElement(Comp, { size: 14 }),
component: Comp,
}
}
export const lucideFixtures = defineFixtures({
name: 'lucide',
fixtures: [
{ key: 'star', label: 'Star', category: 'icons', ...icon(Star) },
{ key: 'heart', label: 'Heart', category: 'icons', ...icon(Heart) },
{ key: 'zap', label: 'Zap', category: 'icons', ...icon(Zap) },
{ key: 'download', label: 'Download', category: 'icons', ...icon(Download) },
{ key: 'trash', label: 'Trash', category: 'icons', ...icon(Trash2) },
],
})Fields reference
| Field | Type | Description |
|---|---|---|
| key | string | Unique identifier within the plugin |
| label | string | Display name shown in the picker UI |
| category | string | Group label — determines which prop kinds use this fixture |
| render | () => ReactNode | Full-size preview rendered in the picker grid |
| renderPreview | () => ReactNode | Compact preview for the selected-value thumbnail |
| component | ComponentType | The actual value passed as the prop at runtime |
How matching works
jc detects the kind of each prop from its TypeScript type. A prop typed as LucideIcon gets kind: "icon". The showcase then looks for fixtures in the matching category:
| Prop Kind | Fixture Category |
|---|---|
| icon | icons |
| element | elements |
| node | nodes |
The kind detection uses a layered heuristic: type pattern matching first (e.g.
LucideIcon → icon), then prop name heuristics (e.g. leadingIcon → icon), with source regex as a tiebreaker.Multiple plugins
Pass an array of plugins. All fixtures are merged and available in the controls:
tsx
<ShowcaseApp
meta={meta}
registry={registry}
fixtures={[lucideFixtures, heroiconFixtures, customFixtures]}
/>When multiple plugins define values in the same category, keys are qualified with the plugin name to avoid collisions: lucide:star vs heroicon:star.