From 5b648d5bb24333692c2ffe87e2a7813b5e4ee001 Mon Sep 17 00:00:00 2001 From: Richard Ward Date: Wed, 31 Dec 2025 01:03:50 +0000 Subject: [PATCH] code: storybook,src,loadpackagecomponents (1 files) --- storybook/src/utils/loadPackageComponents.ts | 102 +++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 storybook/src/utils/loadPackageComponents.ts diff --git a/storybook/src/utils/loadPackageComponents.ts b/storybook/src/utils/loadPackageComponents.ts new file mode 100644 index 000000000..4af5b855d --- /dev/null +++ b/storybook/src/utils/loadPackageComponents.ts @@ -0,0 +1,102 @@ +/** + * Dynamic Package Component Loader + * + * Loads component definitions from packages/*/seed/components.json + * and generates React components from the metadata + */ + +export interface ComponentDefinition { + id: string + type: string + props?: Record + children?: ComponentDefinition[] + className?: string + style?: Record + text?: string +} + +export interface PackageComponents { + packageId: string + components: Record +} + +/** + * Load components.json from a package + */ +export async function loadPackageComponents(packageId: string): Promise { + try { + const response = await fetch(`/packages/${packageId}/seed/components.json`) + if (!response.ok) { + console.warn(`No components.json found for package: ${packageId}`) + return null + } + + const data = await response.json() + return { + packageId, + components: data.components || data + } + } catch (error) { + console.error(`Failed to load components for ${packageId}:`, error) + return null + } +} + +/** + * Convert a component definition to React element + */ +export function renderComponentDefinition(def: ComponentDefinition): React.ReactElement { + const { type, props = {}, children, className, style, text } = def + + // Map component types to HTML elements + const elementMap: Record = { + 'Text': 'span', + 'Heading': 'h1', + 'Button': 'button', + 'Card': 'div', + 'Box': 'div', + 'Section': 'section', + 'Nav': 'nav', + 'Input': 'input', + 'Table': 'table', + 'TableRow': 'tr', + 'TableCell': 'td', + 'Badge': 'span', + } + + const element = elementMap[type] || 'div' + + const finalProps = { + ...props, + className: className ? `${type.toLowerCase()} ${className}` : type.toLowerCase(), + style: style || {} + } + + const childElements = children?.map((child, idx) => + renderComponentDefinition({ ...child, props: { ...child.props, key: idx } }) + ) || [] + + return React.createElement( + element, + finalProps, + text || childElements + ) +} + +/** + * Load all components from multiple packages + */ +export async function loadMultiplePackageComponents( + packageIds: string[] +): Promise> { + const results = await Promise.all( + packageIds.map(id => loadPackageComponents(id)) + ) + + return results.reduce((acc, result) => { + if (result) { + acc[result.packageId] = result + } + return acc + }, {} as Record) +}