Files
metabuilder/storybook/json-loader/DynamicStory.tsx
copilot-swe-agent[bot] bccc336c7e refactor: replace code generation with direct JSON interpretation
- Removed code generators (e2e/generators, storybook/generators)
- Created JSON test runner that executes Playwright tests directly from JSON
- Created JSON story loader that renders Storybook stories directly from JSON
- No intermediate code generation - JSON is executable/renderable at runtime
- json-packages.spec.ts auto-discovers and runs all package tests from JSON
- DynamicStory component renders stories from JSON definitions
- True meta/abstract architecture: configuration itself is executable
- Single source of truth: JSON definitions only (no generated .spec.ts or .stories.tsx)
- Changes to JSON take effect immediately without regeneration
- Added comprehensive READMEs explaining the interpretation approach

Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
2026-01-16 18:59:13 +00:00

82 lines
1.9 KiB
TypeScript

/**
* Dynamic Storybook Story Renderer
*
* Renders Storybook stories directly from JSON definitions.
* Used by Storybook to display stories without code generation.
*/
import React from 'react'
import type { StorybookDefinition, Story } from './storybook-json-loader'
import { loadJSONPackage } from '../../frontends/nextjs/src/lib/packages/json/functions/load-json-package'
import { JSONComponentRenderer } from '../../frontends/nextjs/src/components/JSONComponentRenderer'
import { join } from 'path'
interface DynamicStoryProps {
packageName: string
storyDef: StorybookDefinition
story: Story
packagesDir: string
}
/**
* Render a single story from JSON definition
*/
export async function DynamicStory({
packageName,
storyDef,
story,
packagesDir
}: DynamicStoryProps) {
// Load the package components
const pkg = await loadJSONPackage(join(packagesDir, packageName))
// Find the component to render
const component = pkg.components?.find(
c => c.id === story.render || c.name === story.render
)
if (!component) {
return (
<div style={{ padding: '1rem', border: '1px solid red', borderRadius: '4px' }}>
<strong>Component not found:</strong> {story.render}
<br />
<small>Package: {packageName}</small>
</div>
)
}
// Merge story args with default context
const props = {
...storyDef.defaultContext,
...story.args,
}
return (
<JSONComponentRenderer
component={component}
props={props}
allComponents={pkg.components}
/>
)
}
/**
* Create story metadata for Storybook
*/
export function createStoryMeta(storyDef: StorybookDefinition) {
return {
title: storyDef.category
? `${storyDef.category}/${storyDef.title}`
: storyDef.title,
parameters: {
...storyDef.parameters,
docs: {
description: {
component: storyDef.description
}
}
},
argTypes: storyDef.argTypes,
}
}