|
| 1 | +# Developer Portal Documentation Instructions |
| 2 | + |
| 3 | +## Core Principle: Stories Are the Single Source of Truth |
| 4 | + |
| 5 | +When working on the Storybook-to-MDX documentation system: |
| 6 | + |
| 7 | +**ALWAYS fix the story first. NEVER add workarounds to the generator.** |
| 8 | + |
| 9 | +## Why This Matters |
| 10 | + |
| 11 | +The generator (`scripts/generate-superset-components.mjs`) should be lightweight - it extracts data from stories and passes it through. When you add special cases to the generator: |
| 12 | +- It becomes harder to maintain |
| 13 | +- Stories diverge from their docs representation |
| 14 | +- Future stories need to know about generator quirks |
| 15 | + |
| 16 | +When you fix stories to match the expected patterns: |
| 17 | +- Stories work identically in Storybook and Docs |
| 18 | +- The generator stays simple and predictable |
| 19 | +- Patterns are consistent and learnable |
| 20 | + |
| 21 | +## Story Patterns for Docs Generation |
| 22 | + |
| 23 | +### Required Structure |
| 24 | +```tsx |
| 25 | +// Use inline export default (NOT const meta = ...; export default meta) |
| 26 | +export default { |
| 27 | + title: 'Components/MyComponent', |
| 28 | + component: MyComponent, |
| 29 | +}; |
| 30 | + |
| 31 | +// Name interactive stories with Interactive prefix |
| 32 | +export const InteractiveMyComponent: Story = { |
| 33 | + args: { |
| 34 | + // Default prop values |
| 35 | + }, |
| 36 | + argTypes: { |
| 37 | + // Control definitions - MUST be at story level, not meta level |
| 38 | + propName: { |
| 39 | + control: { type: 'select' }, |
| 40 | + options: ['a', 'b', 'c'], |
| 41 | + description: 'What this prop does', |
| 42 | + }, |
| 43 | + }, |
| 44 | +}; |
| 45 | +``` |
| 46 | + |
| 47 | +### For Components with Variants (size × style grids) |
| 48 | +```tsx |
| 49 | +const sizes = ['small', 'medium', 'large']; |
| 50 | +const variants = ['primary', 'secondary', 'danger']; |
| 51 | + |
| 52 | +InteractiveButton.parameters = { |
| 53 | + docs: { |
| 54 | + gallery: { |
| 55 | + component: 'Button', |
| 56 | + sizes, |
| 57 | + styles: variants, |
| 58 | + sizeProp: 'size', |
| 59 | + styleProp: 'variant', |
| 60 | + }, |
| 61 | + }, |
| 62 | +}; |
| 63 | +``` |
| 64 | + |
| 65 | +### For Components Requiring Children |
| 66 | +```tsx |
| 67 | +InteractiveIconTooltip.parameters = { |
| 68 | + docs: { |
| 69 | + // Component descriptors with dot notation for nested components |
| 70 | + sampleChildren: [{ component: 'Icons.InfoCircleOutlined', props: { iconSize: 'l' } }], |
| 71 | + }, |
| 72 | +}; |
| 73 | +``` |
| 74 | + |
| 75 | +### For Custom Live Code Examples |
| 76 | +```tsx |
| 77 | +InteractiveMyComponent.parameters = { |
| 78 | + docs: { |
| 79 | + liveExample: `function Demo() { |
| 80 | + return <MyComponent prop="value">Content</MyComponent>; |
| 81 | +}`, |
| 82 | + }, |
| 83 | +}; |
| 84 | +``` |
| 85 | + |
| 86 | +### For Complex Props (objects, arrays) |
| 87 | +```tsx |
| 88 | +InteractiveMenu.parameters = { |
| 89 | + docs: { |
| 90 | + staticProps: { |
| 91 | + items: [ |
| 92 | + { key: '1', label: 'Item 1' }, |
| 93 | + { key: '2', label: 'Item 2' }, |
| 94 | + ], |
| 95 | + }, |
| 96 | + }, |
| 97 | +}; |
| 98 | +``` |
| 99 | + |
| 100 | +## Common Issues and How to Fix Them (in the Story) |
| 101 | + |
| 102 | +| Issue | Wrong Approach | Right Approach | |
| 103 | +|-------|---------------|----------------| |
| 104 | +| Component not generated | Add pattern to generator | Change story to use inline `export default` | |
| 105 | +| Control shows as text instead of select | Add special case in generator | Add `argTypes` with `control: { type: 'select' }` | |
| 106 | +| Missing children/content | Modify StorybookWrapper | Add `parameters.docs.sampleChildren` | |
| 107 | +| Gallery not showing | Add to generator output | Add `parameters.docs.gallery` config | |
| 108 | +| Wrong live example | Hardcode in generator | Add `parameters.docs.liveExample` | |
| 109 | + |
| 110 | +## Files |
| 111 | + |
| 112 | +- **Generator**: `docs/scripts/generate-superset-components.mjs` |
| 113 | +- **Wrapper**: `docs/src/components/StorybookWrapper.jsx` |
| 114 | +- **Output**: `docs/developer_portal/components/` |
| 115 | +- **Stories**: `superset-frontend/packages/superset-ui-core/src/components/*/` |
0 commit comments