@adieyal/catalogue-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/schemas/render-node.ts","../src/schemas/control-spec.ts","../src/schemas/component.ts","../src/schemas/scenario.ts","../src/registry/loader.ts","../src/registry/validator.ts","../src/render/renderer.ts","../src/ui/theme-toggle.ts","../src/ui/resizer.ts","../src/ui/code-panel.ts","../src/app/router.ts","../src/app/pages/landing.ts","../src/app/pages/component.ts","../src/playground/codegen.ts","../src/playground/controls.ts","../src/app/pages/playground.ts","../src/app/pages/harness.ts","../src/app/app.ts"],"sourcesContent":["import { z } from 'zod';\n\n/**\n * RenderNode represents a declarative DOM structure that can be\n * rendered to actual DOM elements or serialized to HTML.\n */\n\n// Base render node without recursive children (for Zod lazy reference)\nconst BaseRenderNodeSchema = z.object({\n /** Element tag name (e.g., 'div', 'my-component') */\n element: z.string().min(1),\n\n /** DOM attributes (set via setAttribute) */\n attrs: z.record(z.union([z.string(), z.number(), z.boolean(), z.null()])).optional(),\n\n /** DOM properties (set directly on element, for objects/arrays) */\n props: z.record(z.unknown()).optional(),\n\n /** Text content (mutually exclusive with children) */\n text: z.string().optional(),\n});\n\n// Recursive RenderNode schema\nexport const RenderNodeSchema: z.ZodType<RenderNode> = BaseRenderNodeSchema.extend({\n /** Named slots - content to render with slot attribute */\n slots: z.record(z.union([\n z.string(),\n z.lazy(() => RenderNodeSchema),\n z.array(z.lazy(() => RenderNodeSchema))\n ])).optional(),\n\n /** Child elements */\n children: z.array(z.lazy(() => RenderNodeSchema)).optional(),\n});\n\nexport interface RenderNode {\n element: string;\n attrs?: Record<string, string | number | boolean | null>;\n props?: Record<string, unknown>;\n slots?: Record<string, string | RenderNode | RenderNode[]>;\n children?: RenderNode[];\n text?: string;\n}\n\nexport type { RenderNode as RenderNodeType };\n\nexport function validateRenderNode(data: unknown): { success: true; data: RenderNode } | { success: false; errors: string[] } {\n const result = RenderNodeSchema.safeParse(data);\n if (!result.success) {\n return {\n success: false,\n errors: result.error.errors.map(e => `${e.path.join('.')}: ${e.message}`)\n };\n }\n return { success: true, data: result.data };\n}\n","import { z } from 'zod';\n\n/**\n * ControlSpec defines the type and configuration of playground controls\n * that allow users to interactively modify component properties.\n */\n\nconst TextControlSchema = z.object({\n type: z.literal('text'),\n label: z.string().optional(),\n defaultValue: z.string().optional(),\n placeholder: z.string().optional(),\n});\n\nconst NumberControlSchema = z.object({\n type: z.literal('number'),\n label: z.string().optional(),\n defaultValue: z.number().optional(),\n min: z.number().optional(),\n max: z.number().optional(),\n step: z.number().optional(),\n});\n\nconst BooleanControlSchema = z.object({\n type: z.literal('boolean'),\n label: z.string().optional(),\n defaultValue: z.boolean().optional(),\n});\n\nconst SelectControlSchema = z.object({\n type: z.literal('select'),\n label: z.string().optional(),\n defaultValue: z.string().optional(),\n options: z.array(z.union([\n z.string(),\n z.object({\n label: z.string(),\n value: z.string(),\n })\n ])),\n});\n\nconst RadioControlSchema = z.object({\n type: z.literal('radio'),\n label: z.string().optional(),\n defaultValue: z.string().optional(),\n options: z.array(z.union([\n z.string(),\n z.object({\n label: z.string(),\n value: z.string(),\n })\n ])),\n});\n\nconst ColorControlSchema = z.object({\n type: z.literal('color'),\n label: z.string().optional(),\n defaultValue: z.string().optional(),\n});\n\nconst RangeControlSchema = z.object({\n type: z.literal('range'),\n label: z.string().optional(),\n defaultValue: z.number().optional(),\n min: z.number(),\n max: z.number(),\n step: z.number().optional(),\n});\n\nconst JsonControlSchema = z.object({\n type: z.literal('json'),\n label: z.string().optional(),\n defaultValue: z.unknown().optional(),\n});\n\nexport const ControlSpecSchema = z.discriminatedUnion('type', [\n TextControlSchema,\n NumberControlSchema,\n BooleanControlSchema,\n SelectControlSchema,\n RadioControlSchema,\n ColorControlSchema,\n RangeControlSchema,\n JsonControlSchema,\n]);\n\nexport type ControlSpec = z.infer<typeof ControlSpecSchema>;\n\nexport type TextControl = z.infer<typeof TextControlSchema>;\nexport type NumberControl = z.infer<typeof NumberControlSchema>;\nexport type BooleanControl = z.infer<typeof BooleanControlSchema>;\nexport type SelectControl = z.infer<typeof SelectControlSchema>;\nexport type RadioControl = z.infer<typeof RadioControlSchema>;\nexport type ColorControl = z.infer<typeof ColorControlSchema>;\nexport type RangeControl = z.infer<typeof RangeControlSchema>;\nexport type JsonControl = z.infer<typeof JsonControlSchema>;\n\nexport function validateControlSpec(data: unknown): { success: true; data: ControlSpec } | { success: false; errors: string[] } {\n const result = ControlSpecSchema.safeParse(data);\n if (!result.success) {\n return {\n success: false,\n errors: result.error.errors.map(e => `${e.path.join('.')}: ${e.message}`)\n };\n }\n return { success: true, data: result.data };\n}\n","import { z } from 'zod';\nimport { ControlSpecSchema } from './control-spec.js';\n\n/**\n * Component schema defines the structure of a component.json file\n * in the registry. Each component has metadata, exports, and playground config.\n */\n\nexport const ComponentStatusSchema = z.enum(['stable', 'beta', 'deprecated']);\nexport type ComponentStatus = z.infer<typeof ComponentStatusSchema>;\n\nexport const ComponentKindSchema = z.enum(['standalone', 'subcomponent', 'feature']);\nexport type ComponentKind = z.infer<typeof ComponentKindSchema>;\n\nexport const ComponentExportsSchema = z.object({\n /** Custom element tag name (must be kebab-case with at least one hyphen) */\n customElement: z.string().regex(/^[a-z][a-z0-9]*-[a-z0-9-]+$/, {\n message: 'Custom element name must be kebab-case with at least one hyphen (e.g., \"my-button\")'\n }),\n /** npm package name (optional, defaults to consumer's package) */\n package: z.string().optional(),\n /** Entry point path (optional, defaults to main entry) */\n entry: z.string().optional(),\n});\n\nexport const PlaygroundConfigSchema = z.object({\n /** ID of the primary scenario to use as default in playground */\n primaryScenarioId: z.string().min(1),\n /** Control definitions keyed by property name */\n controls: z.record(ControlSpecSchema),\n});\n\nexport const ComponentSchema = z.object({\n /** Unique identifier for the component (kebab-case) */\n id: z.string().min(1).regex(/^[a-z][a-z0-9-]*$/, {\n message: 'Component ID must be kebab-case starting with a letter'\n }),\n\n /** Human-readable title */\n title: z.string().min(1),\n\n /** Component maturity status */\n status: ComponentStatusSchema,\n\n /** Component kind */\n kind: ComponentKindSchema,\n\n /** Optional description */\n description: z.string().optional(),\n\n /** Tags for search and filtering */\n tags: z.array(z.string()).optional(),\n\n /** Category ID (must match a category defined in config) */\n category: z.string().regex(/^[a-z][a-z0-9-]*$/, {\n message: 'Category must be kebab-case starting with a letter'\n }).optional(),\n\n /** Export configuration */\n exports: ComponentExportsSchema,\n\n /** Playground configuration */\n playground: PlaygroundConfigSchema,\n\n /** Parent component ID (required when kind is 'subcomponent') */\n parentId: z.string().optional(),\n\n /** List of subcomponent IDs */\n subcomponents: z.array(z.string()).optional(),\n}).refine(\n (data) => {\n // If kind is 'subcomponent', parentId must be provided\n if (data.kind === 'subcomponent' && !data.parentId) {\n return false;\n }\n return true;\n },\n {\n message: 'Subcomponents must have a parentId',\n path: ['parentId'],\n }\n);\n\nexport type Component = z.infer<typeof ComponentSchema>;\nexport type ComponentExports = z.infer<typeof ComponentExportsSchema>;\nexport type PlaygroundConfig = z.infer<typeof PlaygroundConfigSchema>;\n\nexport interface ComponentValidationResult {\n success: boolean;\n data?: Component;\n errors?: Array<{\n path: string;\n message: string;\n }>;\n}\n\nexport function validateComponent(data: unknown): ComponentValidationResult {\n const result = ComponentSchema.safeParse(data);\n if (!result.success) {\n return {\n success: false,\n errors: result.error.errors.map(e => ({\n path: e.path.join('.') || '(root)',\n message: e.message,\n })),\n };\n }\n return { success: true, data: result.data };\n}\n\nexport function formatComponentErrors(errors: Array<{ path: string; message: string }>, filePath?: string): string {\n const prefix = filePath ? `${filePath}: ` : '';\n return errors.map(e => `${prefix}${e.path}: ${e.message}`).join('\\n');\n}\n","import { z } from 'zod';\nimport { RenderNodeSchema, type RenderNode } from './render-node.js';\n\n/**\n * Scenario schema defines the structure of a scenario.json file.\n * Scenarios define specific component configurations for documentation,\n * testing, and the catalogue UI.\n *\n * This schema is also used for example.json files, which have identical structure.\n */\n\nexport const ScenarioSchema = z.object({\n /** Unique identifier for the scenario (kebab-case) */\n id: z.string().min(1).regex(/^[a-z][a-z0-9-]*$/, {\n message: 'Scenario ID must be kebab-case starting with a letter'\n }),\n\n /** Human-readable title */\n title: z.string().min(1),\n\n /** Optional description explaining the scenario */\n description: z.string().optional(),\n\n /** Component ID this scenario belongs to */\n componentId: z.string().min(1),\n\n /** Tags for search and filtering */\n tags: z.array(z.string()).optional(),\n\n /** The RenderNode tree that defines the DOM structure */\n render: RenderNodeSchema,\n\n /** Optional viewport configuration for screenshots */\n viewport: z.object({\n width: z.number().positive().optional(),\n height: z.number().positive().optional(),\n }).optional(),\n\n /** Optional background color override */\n background: z.string().optional(),\n\n /** Whether this is the primary scenario (shown first) */\n primary: z.boolean().optional(),\n});\n\nexport type Scenario = z.infer<typeof ScenarioSchema>;\n\n// Alias for examples - identical schema\nexport const ExampleSchema = ScenarioSchema;\nexport type Example = Scenario;\n\nexport interface ScenarioValidationResult {\n success: boolean;\n data?: Scenario;\n errors?: Array<{\n path: string;\n message: string;\n }>;\n}\n\nexport function validateScenario(data: unknown): ScenarioValidationResult {\n const result = ScenarioSchema.safeParse(data);\n if (!result.success) {\n return {\n success: false,\n errors: result.error.errors.map(e => ({\n path: e.path.join('.') || '(root)',\n message: e.message,\n })),\n };\n }\n return { success: true, data: result.data };\n}\n\nexport function validateExample(data: unknown): ScenarioValidationResult {\n return validateScenario(data);\n}\n\nexport function formatScenarioErrors(errors: Array<{ path: string; message: string }>, filePath?: string): string {\n const prefix = filePath ? `${filePath}: ` : '';\n return errors.map(e => `${prefix}${e.path}: ${e.message}`).join('\\n');\n}\n","import { validateComponent, validateScenario, validateExample } from '../schemas/index.js';\nimport type { Component, Scenario } from '../schemas/index.js';\nimport type { Registry, RegistryComponent, RegistryScenario, RegistryExample, ValidationError, CategoriesConfig, CategoryDefinition } from './types.js';\n\n/**\n * Registry loader for the component catalogue.\n * Handles loading and parsing registry data in both dev and build modes.\n */\n\nexport interface RawRegistryData {\n components: Array<{\n filePath: string;\n data: unknown;\n docs?: string;\n }>;\n scenarios: Array<{\n filePath: string;\n data: unknown;\n }>;\n examples: Array<{\n filePath: string;\n data: unknown;\n }>;\n categories?: CategoriesConfig;\n}\n\nexport interface LoadResult {\n registry: Registry;\n errors: ValidationError[];\n}\n\n/**\n * Parse and validate raw registry data into a typed Registry.\n */\nexport function loadRegistry(raw: RawRegistryData): LoadResult {\n const errors: ValidationError[] = [];\n const components = new Map<string, RegistryComponent>();\n const scenarios = new Map<string, RegistryScenario>();\n const examples = new Map<string, RegistryExample>();\n\n // Parse components\n for (const { filePath, data, docs } of raw.components) {\n const result = validateComponent(data);\n if (!result.success) {\n for (const error of result.errors || []) {\n errors.push({\n file: filePath,\n path: error.path,\n message: error.message,\n });\n }\n } else if (result.data) {\n const component = result.data;\n components.set(component.id, {\n ...component,\n filePath,\n docs,\n scenarios: [],\n });\n }\n }\n\n // Parse scenarios and link to components\n for (const { filePath, data } of raw.scenarios) {\n const result = validateScenario(data);\n if (!result.success) {\n for (const error of result.errors || []) {\n errors.push({\n file: filePath,\n path: error.path,\n message: error.message,\n });\n }\n } else if (result.data) {\n const scenarioData = result.data;\n const scenario: RegistryScenario = {\n ...scenarioData,\n filePath,\n };\n scenarios.set(scenarioData.id, scenario);\n\n // Link to component\n const component = components.get(scenarioData.componentId);\n if (component) {\n component.scenarios.push(scenario);\n }\n }\n }\n\n // Parse examples\n for (const { filePath, data } of raw.examples) {\n const result = validateExample(data);\n if (!result.success) {\n for (const error of result.errors || []) {\n errors.push({\n file: filePath,\n path: error.path,\n message: error.message,\n });\n }\n } else if (result.data) {\n const exampleData = result.data;\n examples.set(exampleData.id, {\n ...exampleData,\n filePath,\n });\n }\n }\n\n const categories: CategoriesConfig = raw.categories ?? {\n items: [],\n uncategorisedLabel: 'Other',\n };\n\n return {\n registry: { components, scenarios, examples, categories },\n errors,\n };\n}\n\n/**\n * Create an empty registry.\n */\nexport function createEmptyRegistry(): Registry {\n return {\n components: new Map(),\n scenarios: new Map(),\n examples: new Map(),\n categories: { items: [], uncategorisedLabel: 'Other' },\n };\n}\n\n/**\n * Get all standalone components (not subcomponents).\n */\nexport function getStandaloneComponents(registry: Registry): RegistryComponent[] {\n return Array.from(registry.components.values())\n .filter(c => c.kind !== 'subcomponent');\n}\n\n/**\n * Get subcomponents of a component.\n */\nexport function getSubcomponents(registry: Registry, parentId: string): RegistryComponent[] {\n return Array.from(registry.components.values())\n .filter(c => c.parentId === parentId);\n}\n\n/**\n * Search components by query.\n */\nexport function searchComponents(\n registry: Registry,\n query: string,\n filters?: {\n status?: string[];\n kind?: string[];\n tags?: string[];\n }\n): RegistryComponent[] {\n const queryLower = query.toLowerCase();\n\n return Array.from(registry.components.values())\n .filter(component => {\n // Skip subcomponents in main search\n if (component.kind === 'subcomponent') {\n return false;\n }\n\n // Text search\n if (query) {\n const matchesId = component.id.toLowerCase().includes(queryLower);\n const matchesTitle = component.title.toLowerCase().includes(queryLower);\n const matchesTags = component.tags?.some(tag =>\n tag.toLowerCase().includes(queryLower)\n );\n const matchesDescription = component.description?.toLowerCase().includes(queryLower);\n\n if (!matchesId && !matchesTitle && !matchesTags && !matchesDescription) {\n return false;\n }\n }\n\n // Filter by status\n if (filters?.status?.length && !filters.status.includes(component.status)) {\n return false;\n }\n\n // Filter by kind\n if (filters?.kind?.length && !filters.kind.includes(component.kind)) {\n return false;\n }\n\n // Filter by tags\n if (filters?.tags?.length) {\n const hasMatchingTag = component.tags?.some(tag =>\n filters.tags!.includes(tag)\n );\n if (!hasMatchingTag) {\n return false;\n }\n }\n\n return true;\n });\n}\n\nexport interface GroupedComponents {\n /** Category definition, or null for uncategorised */\n category: CategoryDefinition | null;\n /** Components in this category */\n components: RegistryComponent[];\n}\n\n/**\n * Group standalone components by category.\n */\nexport function getComponentsByCategory(registry: Registry): GroupedComponents[] {\n const standalone = getStandaloneComponents(registry);\n const categorised = new Map<string, RegistryComponent[]>();\n const uncategorised: RegistryComponent[] = [];\n\n for (const component of standalone) {\n if (component.category) {\n if (!categorised.has(component.category)) {\n categorised.set(component.category, []);\n }\n categorised.get(component.category)!.push(component);\n } else {\n uncategorised.push(component);\n }\n }\n\n const result: GroupedComponents[] = [];\n\n // Add categories in defined order\n for (const cat of registry.categories.items) {\n const components = categorised.get(cat.id) || [];\n if (components.length > 0) {\n result.push({ category: cat, components });\n }\n }\n\n // Add uncategorised at end\n if (uncategorised.length > 0) {\n result.push({ category: null, components: uncategorised });\n }\n\n return result;\n}\n","import type { Registry, ValidationError, ValidationResult } from './types.js';\n\n/**\n * Cross-reference validator for the component registry.\n * Validates relationships between components, scenarios, and examples.\n */\n\nexport function validateRegistry(registry: Registry): ValidationResult {\n const errors: ValidationError[] = [];\n const warnings: ValidationError[] = [];\n\n // Check for duplicate IDs\n const allIds = new Map<string, string[]>();\n\n for (const [id, component] of registry.components) {\n if (!allIds.has(id)) {\n allIds.set(id, []);\n }\n allIds.get(id)!.push(component.filePath);\n }\n\n for (const [id, scenario] of registry.scenarios) {\n if (!allIds.has(id)) {\n allIds.set(id, []);\n }\n allIds.get(id)!.push(scenario.filePath);\n }\n\n for (const [id, example] of registry.examples) {\n if (!allIds.has(id)) {\n allIds.set(id, []);\n }\n allIds.get(id)!.push(example.filePath);\n }\n\n for (const [id, files] of allIds) {\n if (files.length > 1) {\n errors.push({\n file: files.join(', '),\n path: 'id',\n message: `Duplicate ID \"${id}\" found in multiple files`,\n });\n }\n }\n\n // Validate component references\n for (const [id, component] of registry.components) {\n // Check primaryScenarioId exists\n const primaryId = component.playground.primaryScenarioId;\n const hasScenario = component.scenarios.some(s => s.id === primaryId);\n if (!hasScenario) {\n errors.push({\n file: component.filePath,\n path: 'playground.primaryScenarioId',\n message: `Primary scenario \"${primaryId}\" not found for component \"${id}\"`,\n });\n }\n\n // Check parentId exists (for subcomponents)\n if (component.parentId) {\n if (!registry.components.has(component.parentId)) {\n errors.push({\n file: component.filePath,\n path: 'parentId',\n message: `Parent component \"${component.parentId}\" not found for component \"${id}\"`,\n });\n }\n }\n\n // Check subcomponents exist\n if (component.subcomponents) {\n for (const subId of component.subcomponents) {\n if (!registry.components.has(subId)) {\n errors.push({\n file: component.filePath,\n path: 'subcomponents',\n message: `Subcomponent \"${subId}\" not found for component \"${id}\"`,\n });\n } else {\n const sub = registry.components.get(subId)!;\n if (sub.parentId !== id) {\n warnings.push({\n file: component.filePath,\n path: 'subcomponents',\n message: `Subcomponent \"${subId}\" has different parentId \"${sub.parentId}\" than expected \"${id}\"`,\n });\n }\n }\n }\n }\n\n // Check component has at least one scenario\n if (component.scenarios.length === 0) {\n errors.push({\n file: component.filePath,\n path: 'scenarios',\n message: `Component \"${id}\" has no scenarios`,\n });\n }\n }\n\n // Validate scenario references\n for (const [id, scenario] of registry.scenarios) {\n if (!registry.components.has(scenario.componentId)) {\n errors.push({\n file: scenario.filePath,\n path: 'componentId',\n message: `Component \"${scenario.componentId}\" not found for scenario \"${id}\"`,\n });\n }\n }\n\n // Validate example references\n for (const [id, example] of registry.examples) {\n if (!registry.components.has(example.componentId)) {\n errors.push({\n file: example.filePath,\n path: 'componentId',\n message: `Component \"${example.componentId}\" not found for example \"${id}\"`,\n });\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\nexport function formatValidationErrors(result: ValidationResult): string {\n const lines: string[] = [];\n\n if (result.errors.length > 0) {\n lines.push('Errors:');\n for (const error of result.errors) {\n lines.push(` ${error.file}: ${error.path}: ${error.message}`);\n }\n }\n\n if (result.warnings.length > 0) {\n lines.push('Warnings:');\n for (const warning of result.warnings) {\n lines.push(` ${warning.file}: ${warning.path}: ${warning.message}`);\n }\n }\n\n return lines.join('\\n');\n}\n","import type { RenderNode } from '../schemas/index.js';\n\n/**\n * RenderNode → DOM renderer.\n * Converts declarative RenderNode trees into actual DOM elements.\n */\n\nexport interface RenderOptions {\n /** Container element to render into */\n container: Element;\n /** Whether to clear the container before rendering */\n clear?: boolean;\n /** Callback when an error occurs */\n onError?: (error: Error, node: RenderNode) => void;\n}\n\nexport interface RenderResult {\n /** The root element that was created */\n element: Element;\n /** Any errors that occurred during rendering */\n errors: Array<{ node: RenderNode; error: Error }>;\n}\n\n/**\n * Render a single RenderNode to a DOM element.\n */\nexport function renderNode(node: RenderNode): Element {\n const el = document.createElement(node.element);\n\n // Apply attributes (via setAttribute)\n if (node.attrs) {\n for (const [key, value] of Object.entries(node.attrs)) {\n if (value === null || value === undefined) {\n continue;\n }\n if (typeof value === 'boolean') {\n if (value) {\n el.setAttribute(key, '');\n }\n // false = don't set the attribute (HTML convention)\n } else {\n el.setAttribute(key, String(value));\n }\n }\n }\n\n // Apply properties (direct assignment for objects/arrays)\n if (node.props) {\n for (const [key, value] of Object.entries(node.props)) {\n (el as unknown as Record<string, unknown>)[key] = value;\n }\n }\n\n // Handle text content\n if (node.text !== undefined) {\n el.textContent = node.text;\n }\n\n // Handle slots\n if (node.slots) {\n for (const [slotName, content] of Object.entries(node.slots)) {\n renderSlotContent(el, slotName, content);\n }\n }\n\n // Handle children\n if (node.children) {\n for (const child of node.children) {\n const childEl = renderNode(child);\n el.appendChild(childEl);\n }\n }\n\n return el;\n}\n\n/**\n * Render slot content into an element.\n */\nfunction renderSlotContent(\n parent: Element,\n slotName: string,\n content: string | RenderNode | RenderNode[]\n): void {\n if (typeof content === 'string') {\n // Text slot content\n const span = document.createElement('span');\n if (slotName !== 'default') {\n span.setAttribute('slot', slotName);\n }\n span.textContent = content;\n parent.appendChild(span);\n } else if (Array.isArray(content)) {\n // Multiple elements in slot\n for (const node of content) {\n const el = renderNode(node);\n if (slotName !== 'default') {\n el.setAttribute('slot', slotName);\n }\n parent.appendChild(el);\n }\n } else {\n // Single RenderNode\n const el = renderNode(content);\n if (slotName !== 'default') {\n el.setAttribute('slot', slotName);\n }\n parent.appendChild(el);\n }\n}\n\n/**\n * Render a RenderNode tree into a container.\n */\nexport function render(node: RenderNode, options: RenderOptions): RenderResult {\n const errors: Array<{ node: RenderNode; error: Error }> = [];\n\n if (options.clear) {\n options.container.innerHTML = '';\n }\n\n try {\n const element = renderNode(node);\n options.container.appendChild(element);\n return { element, errors };\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n errors.push({ node, error: err });\n options.onError?.(err, node);\n\n // Create error marker element\n const errorEl = document.createElement('div');\n errorEl.setAttribute('data-catalogue-error', '');\n errorEl.textContent = `Render error: ${err.message}`;\n errorEl.style.cssText = 'color: red; padding: 1em; border: 1px solid red; font-family: monospace;';\n options.container.appendChild(errorEl);\n\n return { element: errorEl, errors };\n }\n}\n\n/**\n * Update an existing element with new properties.\n * Used for live playground updates.\n */\nexport function updateElement(\n element: Element,\n attrs?: Record<string, string | number | boolean | null>,\n props?: Record<string, unknown>\n): void {\n // Update attributes\n if (attrs) {\n // Remove attributes that are no longer present\n const attrNames = element.getAttributeNames();\n for (const name of attrNames) {\n if (!(name in attrs)) {\n element.removeAttribute(name);\n }\n }\n\n // Set new/updated attributes\n for (const [key, value] of Object.entries(attrs)) {\n if (value === null || value === undefined) {\n element.removeAttribute(key);\n } else if (typeof value === 'boolean') {\n if (value) {\n element.setAttribute(key, '');\n } else {\n element.removeAttribute(key);\n }\n } else {\n element.setAttribute(key, String(value));\n }\n }\n }\n\n // Update properties\n if (props) {\n for (const [key, value] of Object.entries(props)) {\n (element as unknown as Record<string, unknown>)[key] = value;\n }\n }\n}\n\n/**\n * Apply a RenderNode's configuration to an existing element.\n * Useful for playground where we update rather than recreate.\n */\nexport function applyNodeToElement(element: Element, node: RenderNode): void {\n updateElement(element, node.attrs, node.props);\n\n // Update text content if specified\n if (node.text !== undefined) {\n element.textContent = node.text;\n }\n}\n","/**\n * Theme toggle component for light/dark mode switching.\n * Persists preference to localStorage and respects system preference.\n */\n\nconst THEME_KEY = 'catalogue-theme';\n\nexport type Theme = 'light' | 'dark';\n\n/**\n * Get the initial theme based on localStorage or system preference.\n */\nexport function getInitialTheme(): Theme {\n const stored = localStorage.getItem(THEME_KEY);\n if (stored === 'dark' || stored === 'light') {\n return stored;\n }\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n}\n\n/**\n * Set the theme and persist to localStorage.\n */\nexport function setTheme(theme: Theme): void {\n localStorage.setItem(THEME_KEY, theme);\n document.documentElement.setAttribute('data-theme', theme);\n\n // Also update all catalogue containers\n document.querySelectorAll('[data-catalogue-container]').forEach(el => {\n el.setAttribute('data-theme', theme);\n });\n}\n\n/**\n * Toggle between light and dark themes.\n */\nexport function toggleTheme(): Theme {\n const current = document.documentElement.getAttribute('data-theme') as Theme || 'light';\n const next = current === 'light' ? 'dark' : 'light';\n setTheme(next);\n return next;\n}\n\n/**\n * Initialize the theme on page load.\n */\nexport function initTheme(): Theme {\n const theme = getInitialTheme();\n setTheme(theme);\n return theme;\n}\n\n/**\n * Create a theme toggle button element.\n */\nexport function createThemeToggle(): HTMLButtonElement {\n const button = document.createElement('button');\n button.className = 'catalogue-theme-toggle';\n button.setAttribute('type', 'button');\n button.setAttribute('aria-label', 'Toggle theme');\n button.setAttribute('title', 'Toggle light/dark theme');\n\n const updateIcon = () => {\n const currentTheme = document.documentElement.getAttribute('data-theme') || 'light';\n button.innerHTML = currentTheme === 'light'\n ? '<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\"/></svg>'\n : '<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"5\"/><line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"3\"/><line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\"/><line x1=\"4.22\" y1=\"4.22\" x2=\"5.64\" y2=\"5.64\"/><line x1=\"18.36\" y1=\"18.36\" x2=\"19.78\" y2=\"19.78\"/><line x1=\"1\" y1=\"12\" x2=\"3\" y2=\"12\"/><line x1=\"21\" y1=\"12\" x2=\"23\" y2=\"12\"/><line x1=\"4.22\" y1=\"19.78\" x2=\"5.64\" y2=\"18.36\"/><line x1=\"18.36\" y1=\"5.64\" x2=\"19.78\" y2=\"4.22\"/></svg>';\n };\n\n updateIcon();\n\n button.addEventListener('click', () => {\n toggleTheme();\n updateIcon();\n });\n\n return button;\n}\n","/**\n * Resizable container component for playground and harness views.\n * Supports drag-to-resize with dimension display and breakpoint presets.\n */\n\nexport interface ResizerOptions {\n /** Initial width (CSS value) */\n initialWidth?: string;\n /** Initial height (CSS value) */\n initialHeight?: string;\n /** Minimum width in pixels */\n minWidth?: number;\n /** Minimum height in pixels */\n minHeight?: number;\n /** Maximum width in pixels */\n maxWidth?: number;\n /** Maximum height in pixels */\n maxHeight?: number;\n /** Callback when dimensions change */\n onResize?: (width: number, height: number) => void;\n /** Callback when full screen mode changes */\n onFullScreenChange?: (isFullScreen: boolean) => void;\n /** Enable smooth transitions for preset changes */\n animatePresets?: boolean;\n}\n\nexport interface Breakpoint {\n name: string;\n width: number;\n height: number;\n /** If true, this breakpoint fills available space */\n fullScreen?: boolean;\n}\n\nexport const DEFAULT_BREAKPOINTS: Breakpoint[] = [\n { name: 'Mobile S', width: 320, height: 568 },\n { name: 'Mobile M', width: 375, height: 667 },\n { name: 'Mobile L', width: 425, height: 812 },\n { name: 'Tablet', width: 768, height: 1024 },\n { name: 'Laptop', width: 1024, height: 768 },\n { name: 'Desktop', width: 1440, height: 900 },\n { name: 'Full', width: 0, height: 0, fullScreen: true },\n];\n\nexport interface ResizerElements {\n wrapper: HTMLDivElement;\n container: HTMLDivElement;\n content: HTMLDivElement;\n handleRight: HTMLDivElement;\n handleBottom: HTMLDivElement;\n handleCorner: HTMLDivElement;\n dimensionLabel: HTMLDivElement;\n /** Set dimensions with optional animation */\n setSize: (width: number | 'full', height: number | 'full', animate?: boolean) => void;\n /** Check if currently in full screen mode */\n isFullScreen: () => boolean;\n}\n\n/** CSS for smooth transitions */\nconst TRANSITION_STYLE = 'width 0.3s ease, height 0.3s ease';\n\n/**\n * Create a resizable container.\n */\nexport function createResizer(options: ResizerOptions = {}): ResizerElements {\n const {\n initialWidth = '100%',\n initialHeight = 'auto',\n minWidth = 200,\n minHeight = 100,\n maxWidth = 2000,\n maxHeight = 2000,\n onResize,\n onFullScreenChange,\n animatePresets = true,\n } = options;\n\n let isFullScreenMode = false;\n\n // Wrapper for the whole resizer\n const wrapper = document.createElement('div');\n wrapper.className = 'catalogue-resizer-wrapper';\n\n // Container that gets resized\n const container = document.createElement('div');\n container.className = 'catalogue-resizer';\n container.setAttribute('data-catalogue-container', '');\n container.style.width = initialWidth;\n container.style.height = initialHeight;\n container.style.minWidth = `${minWidth}px`;\n container.style.minHeight = `${minHeight}px`;\n\n // Content area inside the container\n const content = document.createElement('div');\n content.className = 'catalogue-resizer-content';\n content.style.cssText = 'container-type: inline-size; width: 100%; height: 100%;';\n container.appendChild(content);\n\n // Resize handles\n const handleRight = document.createElement('div');\n handleRight.className = 'catalogue-resizer-handle catalogue-resizer-handle-right';\n\n const handleBottom = document.createElement('div');\n handleBottom.className = 'catalogue-resizer-handle catalogue-resizer-handle-bottom';\n\n const handleCorner = document.createElement('div');\n handleCorner.className = 'catalogue-resizer-handle catalogue-resizer-handle-corner';\n\n container.appendChild(handleRight);\n container.appendChild(handleBottom);\n container.appendChild(handleCorner);\n\n // Dimension label\n const dimensionLabel = document.createElement('div');\n dimensionLabel.className = 'catalogue-resizer-dimensions';\n container.appendChild(dimensionLabel);\n\n const updateDimensionLabel = () => {\n if (isFullScreenMode) {\n dimensionLabel.textContent = 'Full Screen';\n } else {\n const rect = container.getBoundingClientRect();\n dimensionLabel.textContent = `${Math.round(rect.width)} × ${Math.round(rect.height)}`;\n }\n };\n\n // Enable/disable transition\n const setTransition = (enabled: boolean) => {\n container.style.transition = enabled ? TRANSITION_STYLE : 'none';\n };\n\n // Resize logic\n let isResizing = false;\n let startX = 0;\n let startY = 0;\n let startWidth = 0;\n let startHeight = 0;\n let resizeMode: 'right' | 'bottom' | 'corner' = 'corner';\n\n const onMouseDown = (e: MouseEvent, mode: 'right' | 'bottom' | 'corner') => {\n // Exit full screen mode when manually resizing\n if (isFullScreenMode) {\n isFullScreenMode = false;\n container.classList.remove('catalogue-resizer-fullscreen');\n onFullScreenChange?.(false);\n }\n\n isResizing = true;\n resizeMode = mode;\n startX = e.clientX;\n startY = e.clientY;\n const rect = container.getBoundingClientRect();\n startWidth = rect.width;\n startHeight = rect.height;\n\n // Disable transition during drag\n setTransition(false);\n\n document.body.style.cursor = mode === 'corner' ? 'nwse-resize' : mode === 'right' ? 'ew-resize' : 'ns-resize';\n document.body.style.userSelect = 'none';\n e.preventDefault();\n };\n\n const onMouseMove = (e: MouseEvent) => {\n if (!isResizing) return;\n\n const deltaX = e.clientX - startX;\n const deltaY = e.clientY - startY;\n\n let newWidth = startWidth;\n let newHeight = startHeight;\n\n if (resizeMode === 'right' || resizeMode === 'corner') {\n newWidth = Math.max(minWidth, Math.min(maxWidth, startWidth + deltaX));\n }\n\n if (resizeMode === 'bottom' || resizeMode === 'corner') {\n newHeight = Math.max(minHeight, Math.min(maxHeight, startHeight + deltaY));\n }\n\n container.style.width = `${newWidth}px`;\n container.style.height = `${newHeight}px`;\n\n updateDimensionLabel();\n onResize?.(newWidth, newHeight);\n };\n\n const onMouseUp = () => {\n if (isResizing) {\n isResizing = false;\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n }\n };\n\n handleRight.addEventListener('mousedown', (e) => onMouseDown(e, 'right'));\n handleBottom.addEventListener('mousedown', (e) => onMouseDown(e, 'bottom'));\n handleCorner.addEventListener('mousedown', (e) => onMouseDown(e, 'corner'));\n\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n\n wrapper.appendChild(container);\n\n // Update dimension label after transition ends\n container.addEventListener('transitionend', updateDimensionLabel);\n\n // Initial dimension update\n requestAnimationFrame(updateDimensionLabel);\n\n // Set size method with animation support\n const setSize = (width: number | 'full', height: number | 'full', animate = animatePresets) => {\n const wasFullScreen = isFullScreenMode;\n\n if (width === 'full' || height === 'full') {\n // Full screen mode\n isFullScreenMode = true;\n container.classList.add('catalogue-resizer-fullscreen');\n setTransition(animate);\n container.style.width = '100%';\n container.style.height = '100%';\n updateDimensionLabel();\n\n // Notify if state changed\n if (!wasFullScreen) {\n onFullScreenChange?.(true);\n }\n\n // Get actual dimensions after layout\n requestAnimationFrame(() => {\n const rect = container.getBoundingClientRect();\n onResize?.(rect.width, rect.height);\n });\n } else {\n // Fixed size mode\n isFullScreenMode = false;\n container.classList.remove('catalogue-resizer-fullscreen');\n setTransition(animate);\n container.style.width = `${width}px`;\n container.style.height = `${height}px`;\n updateDimensionLabel();\n onResize?.(width, height);\n\n // Notify if state changed\n if (wasFullScreen) {\n onFullScreenChange?.(false);\n }\n }\n };\n\n const isFullScreen = () => isFullScreenMode;\n\n return {\n wrapper,\n container,\n content,\n handleRight,\n handleBottom,\n handleCorner,\n dimensionLabel,\n setSize,\n isFullScreen,\n };\n}\n\n/**\n * Create breakpoint preset buttons.\n */\nexport function createBreakpointPresets(\n resizer: ResizerElements,\n breakpoints: Breakpoint[] = DEFAULT_BREAKPOINTS,\n onSelect?: (breakpoint: Breakpoint) => void\n): HTMLDivElement {\n const presets = document.createElement('div');\n presets.className = 'catalogue-breakpoint-presets';\n\n let activeButton: HTMLButtonElement | null = null;\n\n for (const bp of breakpoints) {\n const button = document.createElement('button');\n button.className = 'catalogue-breakpoint-button';\n button.textContent = bp.name;\n button.title = bp.fullScreen ? 'Fill available space' : `${bp.width} × ${bp.height}`;\n button.type = 'button';\n\n button.addEventListener('click', () => {\n // Update active state\n activeButton?.classList.remove('active');\n button.classList.add('active');\n activeButton = button;\n\n if (bp.fullScreen) {\n resizer.setSize('full', 'full', true);\n } else {\n resizer.setSize(bp.width, bp.height, true);\n resizer.dimensionLabel.textContent = `${bp.width} × ${bp.height}`;\n }\n onSelect?.(bp);\n });\n\n presets.appendChild(button);\n }\n\n return presets;\n}\n\n/**\n * Set specific dimensions on a resizer.\n */\nexport function setResizerDimensions(\n resizer: ResizerElements,\n width: number | 'full',\n height: number | 'full',\n animate = true\n): void {\n resizer.setSize(width, height, animate);\n}\n\n/**\n * Get CSS styles for the resizer component.\n */\nexport function getResizerStyles(): string {\n return `\n .catalogue-resizer-wrapper {\n display: flex;\n justify-content: center;\n padding: 1rem;\n min-height: 200px;\n background: var(--catalogue-bg-secondary, #f5f5f5);\n }\n\n .catalogue-resizer {\n position: relative;\n background: var(--catalogue-bg, #fff);\n border: 1px solid var(--catalogue-border, #e0e0e0);\n border-radius: 4px;\n overflow: hidden;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n }\n\n .catalogue-resizer-fullscreen {\n border-radius: 0;\n }\n\n .catalogue-resizer-content {\n width: 100%;\n height: 100%;\n overflow: auto;\n }\n\n .catalogue-resizer-handle {\n position: absolute;\n background: transparent;\n z-index: 10;\n }\n\n .catalogue-resizer-handle-right {\n top: 0;\n right: -4px;\n width: 8px;\n height: 100%;\n cursor: ew-resize;\n }\n\n .catalogue-resizer-handle-bottom {\n bottom: -4px;\n left: 0;\n width: 100%;\n height: 8px;\n cursor: ns-resize;\n }\n\n .catalogue-resizer-handle-corner {\n bottom: -4px;\n right: -4px;\n width: 16px;\n height: 16px;\n cursor: nwse-resize;\n }\n\n .catalogue-resizer-handle-corner::after {\n content: '';\n position: absolute;\n bottom: 4px;\n right: 4px;\n width: 8px;\n height: 8px;\n border-right: 2px solid var(--catalogue-border, #ccc);\n border-bottom: 2px solid var(--catalogue-border, #ccc);\n }\n\n .catalogue-resizer-dimensions {\n position: absolute;\n bottom: 8px;\n right: 8px;\n padding: 2px 6px;\n font-size: 11px;\n font-family: monospace;\n background: rgba(0, 0, 0, 0.6);\n color: #fff;\n border-radius: 3px;\n pointer-events: none;\n opacity: 0.8;\n }\n\n .catalogue-breakpoint-presets {\n display: flex;\n gap: 0.5rem;\n flex-wrap: wrap;\n padding: 0.5rem;\n background: var(--catalogue-bg, #fff);\n border-bottom: 1px solid var(--catalogue-border, #e0e0e0);\n }\n\n .catalogue-breakpoint-button {\n padding: 0.25rem 0.75rem;\n font-size: 0.8rem;\n border: 1px solid var(--catalogue-border, #ddd);\n border-radius: 4px;\n background: var(--catalogue-bg, #fff);\n color: var(--catalogue-text, #333);\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .catalogue-breakpoint-button:hover {\n background: var(--catalogue-bg-hover, #f0f0f0);\n border-color: var(--catalogue-border-hover, #bbb);\n }\n\n .catalogue-breakpoint-button.active {\n background: var(--catalogue-primary, #3b82f6);\n border-color: var(--catalogue-primary, #3b82f6);\n color: #fff;\n }\n\n /* Full screen mode - hides sidebar and header */\n .catalogue-playground-fullscreen {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 1000;\n background: var(--catalogue-bg, #fff);\n }\n\n .catalogue-playground-fullscreen .catalogue-playground-header,\n .catalogue-playground-fullscreen .catalogue-playground-sidebar {\n display: none;\n }\n\n .catalogue-playground-fullscreen .catalogue-playground-main {\n height: 100%;\n }\n\n .catalogue-playground-fullscreen .catalogue-playground-preview-section {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n\n .catalogue-playground-fullscreen .catalogue-resizer-wrapper {\n flex: 1;\n padding: 0;\n }\n\n .catalogue-playground-fullscreen .catalogue-resizer {\n width: 100% !important;\n height: 100% !important;\n border-radius: 0;\n border: none;\n box-shadow: none;\n }\n\n .catalogue-playground-fullscreen .catalogue-breakpoint-presets {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n z-index: 10;\n background: rgba(255, 255, 255, 0.95);\n border-bottom: 1px solid var(--catalogue-border, #e0e0e0);\n }\n\n [data-theme=\"dark\"] .catalogue-playground-fullscreen .catalogue-breakpoint-presets {\n background: rgba(30, 30, 30, 0.95);\n }\n `;\n}\n","/**\n * Code panel component for displaying and copying HTML snippets.\n */\n\nexport interface CodePanelOptions {\n /** Code content to display */\n code: string;\n /** Language for syntax highlighting hints */\n language?: 'html' | 'javascript' | 'json';\n /** Whether the panel is collapsible */\n collapsible?: boolean;\n /** Initial collapsed state */\n collapsed?: boolean;\n /** Title for the panel */\n title?: string;\n}\n\nexport interface CodePanelElements {\n wrapper: HTMLDivElement;\n header: HTMLDivElement;\n content: HTMLPreElement;\n copyButton: HTMLButtonElement;\n}\n\n/**\n * Create a code panel with copy functionality.\n */\nexport function createCodePanel(options: CodePanelOptions): CodePanelElements {\n const {\n code,\n language = 'html',\n collapsible = true,\n collapsed = false,\n title = 'Code',\n } = options;\n\n const wrapper = document.createElement('div');\n wrapper.className = 'catalogue-code-panel';\n wrapper.setAttribute('data-language', language);\n if (collapsed) {\n wrapper.setAttribute('data-collapsed', '');\n }\n\n // Header with title and copy button\n const header = document.createElement('div');\n header.className = 'catalogue-code-panel-header';\n\n const titleEl = document.createElement('span');\n titleEl.className = 'catalogue-code-panel-title';\n titleEl.textContent = title;\n\n if (collapsible) {\n titleEl.style.cursor = 'pointer';\n titleEl.addEventListener('click', () => {\n if (wrapper.hasAttribute('data-collapsed')) {\n wrapper.removeAttribute('data-collapsed');\n } else {\n wrapper.setAttribute('data-collapsed', '');\n }\n });\n }\n\n const copyButton = document.createElement('button');\n copyButton.className = 'catalogue-code-panel-copy';\n copyButton.type = 'button';\n copyButton.textContent = 'Copy';\n copyButton.title = 'Copy to clipboard';\n\n copyButton.addEventListener('click', async () => {\n try {\n await navigator.clipboard.writeText(code);\n copyButton.textContent = 'Copied!';\n copyButton.classList.add('copied');\n setTimeout(() => {\n copyButton.textContent = 'Copy';\n copyButton.classList.remove('copied');\n }, 2000);\n } catch (err) {\n copyButton.textContent = 'Failed';\n setTimeout(() => {\n copyButton.textContent = 'Copy';\n }, 2000);\n }\n });\n\n header.appendChild(titleEl);\n header.appendChild(copyButton);\n\n // Code content\n const content = document.createElement('pre');\n content.className = 'catalogue-code-panel-content';\n\n const codeEl = document.createElement('code');\n codeEl.className = `language-${language}`;\n codeEl.textContent = code;\n content.appendChild(codeEl);\n\n wrapper.appendChild(header);\n wrapper.appendChild(content);\n\n return {\n wrapper,\n header,\n content,\n copyButton,\n };\n}\n\n/**\n * Update the code content in a code panel.\n */\nexport function updateCodePanel(panel: CodePanelElements, code: string): void {\n const codeEl = panel.content.querySelector('code');\n if (codeEl) {\n codeEl.textContent = code;\n }\n\n // Update the copy button handler\n const newCopyButton = panel.copyButton.cloneNode(true) as HTMLButtonElement;\n newCopyButton.addEventListener('click', async () => {\n try {\n await navigator.clipboard.writeText(code);\n newCopyButton.textContent = 'Copied!';\n newCopyButton.classList.add('copied');\n setTimeout(() => {\n newCopyButton.textContent = 'Copy';\n newCopyButton.classList.remove('copied');\n }, 2000);\n } catch (err) {\n newCopyButton.textContent = 'Failed';\n setTimeout(() => {\n newCopyButton.textContent = 'Copy';\n }, 2000);\n }\n });\n\n panel.copyButton.replaceWith(newCopyButton);\n panel.copyButton = newCopyButton;\n}\n\n/**\n * Format HTML code for display.\n */\nexport function formatHtml(html: string, indent: number = 2): string {\n // Simple HTML formatting - just ensure consistent indentation\n const lines = html.split('\\n');\n let level = 0;\n const indentStr = ' '.repeat(indent);\n\n return lines\n .map(line => {\n const trimmed = line.trim();\n if (!trimmed) return '';\n\n // Decrease level for closing tags\n if (trimmed.startsWith('</')) {\n level = Math.max(0, level - 1);\n }\n\n const result = indentStr.repeat(level) + trimmed;\n\n // Increase level for opening tags (not self-closing)\n if (\n trimmed.startsWith('<') &&\n !trimmed.startsWith('</') &&\n !trimmed.endsWith('/>') &&\n !trimmed.includes('</') // inline closing\n ) {\n level++;\n }\n\n return result;\n })\n .filter(line => line.length > 0)\n .join('\\n');\n}\n","/**\n * Client-side router for the catalogue app.\n * Handles hash-based routing for simplicity and static hosting compatibility.\n */\n\nexport interface Route {\n pattern: RegExp;\n handler: (params: Record<string, string>, query: URLSearchParams) => void;\n}\n\nexport interface RouterOptions {\n /** Base path for the application */\n basePath?: string;\n /** Root element to render into */\n root: HTMLElement;\n /** Called when no route matches */\n onNotFound?: (path: string) => void;\n}\n\nexport class Router {\n private routes: Route[] = [];\n private options: RouterOptions;\n\n constructor(options: RouterOptions) {\n this.options = options;\n this.setupListeners();\n }\n\n /**\n * Add a route.\n */\n route(pattern: string, handler: Route['handler']): this {\n // Convert pattern to regex\n // :param becomes named capture group\n const regexPattern = pattern\n .replace(/\\//g, '\\\\/')\n .replace(/:([a-zA-Z]+)/g, '(?<$1>[^/]+)');\n\n this.routes.push({\n pattern: new RegExp(`^${regexPattern}$`),\n handler,\n });\n\n return this;\n }\n\n /**\n * Navigate to a path.\n */\n navigate(path: string): void {\n window.location.hash = path;\n }\n\n /**\n * Get current path from hash.\n */\n getCurrentPath(): string {\n const hash = window.location.hash.slice(1); // Remove #\n return hash || '/';\n }\n\n /**\n * Get query parameters from current URL.\n */\n getQueryParams(): URLSearchParams {\n const hash = window.location.hash.slice(1);\n const queryIndex = hash.indexOf('?');\n if (queryIndex === -1) {\n return new URLSearchParams();\n }\n return new URLSearchParams(hash.slice(queryIndex + 1));\n }\n\n /**\n * Resolve the current route.\n */\n resolve(): void {\n const hash = window.location.hash.slice(1) || '/';\n const queryIndex = hash.indexOf('?');\n const path = queryIndex === -1 ? hash : hash.slice(0, queryIndex);\n const query = this.getQueryParams();\n\n for (const route of this.routes) {\n const match = path.match(route.pattern);\n if (match) {\n const params = match.groups || {};\n route.handler(params, query);\n return;\n }\n }\n\n // No route matched\n this.options.onNotFound?.(path);\n }\n\n /**\n * Start listening for route changes.\n */\n private setupListeners(): void {\n window.addEventListener('hashchange', () => this.resolve());\n // Also resolve on initial load\n window.addEventListener('DOMContentLoaded', () => this.resolve());\n }\n\n /**\n * Manually trigger route resolution.\n */\n start(): void {\n this.resolve();\n }\n}\n\n/**\n * Create a navigation link element.\n */\nexport function createNavLink(href: string, text: string, className?: string): HTMLAnchorElement {\n const link = document.createElement('a');\n link.href = `#${href}`;\n link.textContent = text;\n if (className) {\n link.className = className;\n }\n return link;\n}\n\n/**\n * Parse route parameters from a URL pattern match.\n */\nexport function parseRouteParams(pattern: string, path: string): Record<string, string> | null {\n const regexPattern = pattern\n .replace(/\\//g, '\\\\/')\n .replace(/:([a-zA-Z]+)/g, '(?<$1>[^/]+)');\n\n const regex = new RegExp(`^${regexPattern}$`);\n const match = path.match(regex);\n\n if (!match) return null;\n return match.groups || {};\n}\n","/**\n * Landing page - Component list with search and filters.\n */\n\nimport type { Registry, RegistryComponent, GroupedComponents, CategoryDefinition } from '../../registry/index.js';\nimport { searchComponents, getComponentsByCategory } from '../../registry/index.js';\nimport { createNavLink } from '../router.js';\n\nexport interface LandingPageOptions {\n registry: Registry;\n onNavigate: (path: string) => void;\n}\n\nexport interface LandingPageElements {\n root: HTMLDivElement;\n searchInput: HTMLInputElement;\n filterContainer: HTMLDivElement;\n componentList: HTMLDivElement;\n}\n\n/**\n * Create the landing page.\n */\nexport function createLandingPage(options: LandingPageOptions): LandingPageElements {\n const { registry, onNavigate } = options;\n\n const root = document.createElement('div');\n root.className = 'catalogue-landing';\n root.setAttribute('data-catalogue-root', '');\n\n // Header\n const header = document.createElement('header');\n header.className = 'catalogue-landing-header';\n\n const title = document.createElement('h1');\n title.className = 'catalogue-landing-title';\n title.textContent = 'Component Catalogue';\n header.appendChild(title);\n\n root.appendChild(header);\n\n // Search and filters\n const controls = document.createElement('div');\n controls.className = 'catalogue-landing-controls';\n\n const searchInput = document.createElement('input');\n searchInput.type = 'search';\n searchInput.className = 'catalogue-search-input';\n searchInput.placeholder = 'Search components...';\n searchInput.setAttribute('aria-label', 'Search components');\n controls.appendChild(searchInput);\n\n const filterContainer = document.createElement('div');\n filterContainer.className = 'catalogue-filters';\n\n // Status filter\n const statusFilter = createFilterGroup('Status', [\n { value: 'stable', label: 'Stable' },\n { value: 'beta', label: 'Beta' },\n { value: 'deprecated', label: 'Deprecated' },\n ]);\n filterContainer.appendChild(statusFilter.container);\n\n // Kind filter\n const kindFilter = createFilterGroup('Kind', [\n { value: 'standalone', label: 'Standalone' },\n { value: 'feature', label: 'Feature' },\n ]);\n filterContainer.appendChild(kindFilter.container);\n\n controls.appendChild(filterContainer);\n\n // Expand/Collapse toggle (only shown when categories exist)\n const hasCategories = registry.categories.items.length > 0;\n let expandCollapseToggle: HTMLButtonElement | null = null;\n\n if (hasCategories) {\n expandCollapseToggle = document.createElement('button');\n expandCollapseToggle.className = 'catalogue-expand-toggle';\n expandCollapseToggle.textContent = 'Collapse All';\n expandCollapseToggle.setAttribute('data-expanded', 'true');\n controls.appendChild(expandCollapseToggle);\n }\n\n root.appendChild(controls);\n\n // Component list\n const componentList = document.createElement('div');\n componentList.className = 'catalogue-component-list';\n root.appendChild(componentList);\n\n // Get all status and kind checkboxes\n const statusCheckboxes = statusFilter.container.querySelectorAll<HTMLInputElement>('input[type=\"checkbox\"]');\n const kindCheckboxes = kindFilter.container.querySelectorAll<HTMLInputElement>('input[type=\"checkbox\"]');\n\n // Render function\n const renderComponents = () => {\n const query = searchInput.value;\n\n const selectedStatuses = Array.from(statusCheckboxes)\n .filter(cb => cb.checked)\n .map(cb => cb.value);\n\n const selectedKinds = Array.from(kindCheckboxes)\n .filter(cb => cb.checked)\n .map(cb => cb.value);\n\n const filters = {\n status: selectedStatuses.length > 0 ? selectedStatuses : undefined,\n kind: selectedKinds.length > 0 ? selectedKinds : undefined,\n };\n\n const isFiltering = !!(query || filters.status || filters.kind);\n\n componentList.innerHTML = '';\n\n if (hasCategories && !isFiltering) {\n // Grouped view by category\n componentList.classList.remove('catalogue-component-list--flat');\n const grouped = getComponentsByCategory(registry);\n\n if (grouped.length === 0) {\n const empty = document.createElement('div');\n empty.className = 'catalogue-empty-state';\n empty.textContent = 'No components found';\n componentList.appendChild(empty);\n return;\n }\n\n for (const group of grouped) {\n const section = createCategorySection(group, registry.categories.uncategorisedLabel, onNavigate);\n componentList.appendChild(section);\n }\n } else {\n // Flat view (filtering or no categories defined)\n componentList.classList.add('catalogue-component-list--flat');\n const components = isFiltering\n ? searchComponents(registry, query, filters)\n : getComponentsByCategory(registry).flatMap(g => g.components);\n\n if (components.length === 0) {\n const empty = document.createElement('div');\n empty.className = 'catalogue-empty-state';\n empty.textContent = 'No components found';\n componentList.appendChild(empty);\n return;\n }\n\n for (const component of components) {\n const card = createComponentCard(component, onNavigate);\n componentList.appendChild(card);\n }\n }\n };\n\n // Event listeners\n searchInput.addEventListener('input', () => {\n renderComponents();\n });\n\n statusCheckboxes.forEach(cb => {\n cb.addEventListener('change', renderComponents);\n });\n\n kindCheckboxes.forEach(cb => {\n cb.addEventListener('change', renderComponents);\n });\n\n // Expand/Collapse toggle handler\n if (expandCollapseToggle) {\n expandCollapseToggle.addEventListener('click', () => {\n const isExpanded = expandCollapseToggle!.getAttribute('data-expanded') === 'true';\n const details = componentList.querySelectorAll<HTMLDetailsElement>('.catalogue-category-section');\n\n details.forEach(d => {\n d.open = !isExpanded;\n });\n\n expandCollapseToggle!.setAttribute('data-expanded', String(!isExpanded));\n expandCollapseToggle!.textContent = isExpanded ? 'Expand All' : 'Collapse All';\n });\n }\n\n // Initial render\n renderComponents();\n\n return {\n root,\n searchInput,\n filterContainer,\n componentList,\n };\n}\n\n/**\n * Create a category section with collapsible content.\n */\nfunction createCategorySection(\n group: GroupedComponents,\n uncategorisedLabel: string,\n onNavigate: (path: string) => void\n): HTMLDetailsElement {\n const details = document.createElement('details');\n details.className = 'catalogue-category-section';\n details.open = true;\n\n const summary = document.createElement('summary');\n summary.className = 'catalogue-category-header';\n\n const label = group.category?.label ?? uncategorisedLabel;\n\n const labelSpan = document.createElement('span');\n labelSpan.className = 'catalogue-category-label';\n labelSpan.textContent = label;\n\n const countSpan = document.createElement('span');\n countSpan.className = 'catalogue-category-count';\n countSpan.textContent = `(${group.components.length})`;\n\n summary.appendChild(labelSpan);\n summary.appendChild(countSpan);\n\n if (group.category?.description) {\n summary.title = group.category.description;\n }\n\n details.appendChild(summary);\n\n const content = document.createElement('div');\n content.className = 'catalogue-category-content';\n\n for (const component of group.components) {\n const card = createComponentCard(component, onNavigate);\n content.appendChild(card);\n }\n\n details.appendChild(content);\n return details;\n}\n\n/**\n * Create a filter group with checkboxes.\n */\nfunction createFilterGroup(\n label: string,\n options: Array<{ value: string; label: string }>\n): { container: HTMLDivElement } {\n const container = document.createElement('div');\n container.className = 'catalogue-filter-group';\n\n const labelEl = document.createElement('span');\n labelEl.className = 'catalogue-filter-label';\n labelEl.textContent = label;\n container.appendChild(labelEl);\n\n for (const option of options) {\n const checkbox = document.createElement('label');\n checkbox.className = 'catalogue-filter-option';\n\n const input = document.createElement('input');\n input.type = 'checkbox';\n input.value = option.value;\n\n const text = document.createElement('span');\n text.textContent = option.label;\n\n checkbox.appendChild(input);\n checkbox.appendChild(text);\n container.appendChild(checkbox);\n }\n\n return { container };\n}\n\n/**\n * Create a component card element.\n */\nfunction createComponentCard(\n component: RegistryComponent,\n onNavigate: (path: string) => void\n): HTMLDivElement {\n const card = document.createElement('div');\n card.className = 'catalogue-component-card';\n card.setAttribute('data-status', component.status);\n card.setAttribute('data-kind', component.kind);\n\n // Header with title and status\n const header = document.createElement('div');\n header.className = 'catalogue-component-card-header';\n\n const title = document.createElement('h3');\n title.className = 'catalogue-component-card-title';\n\n const link = createNavLink(`/component/${component.id}`, component.title);\n link.addEventListener('click', (e) => {\n e.preventDefault();\n onNavigate(`/component/${component.id}`);\n });\n title.appendChild(link);\n\n const badge = document.createElement('span');\n badge.className = 'catalogue-status-badge';\n badge.setAttribute('data-status', component.status);\n badge.textContent = component.status;\n\n header.appendChild(title);\n header.appendChild(badge);\n card.appendChild(header);\n\n // Description\n if (component.description) {\n const desc = document.createElement('p');\n desc.className = 'catalogue-component-card-description';\n desc.textContent = component.description;\n card.appendChild(desc);\n }\n\n // Tags\n if (component.tags && component.tags.length > 0) {\n const tagsContainer = document.createElement('div');\n tagsContainer.className = 'catalogue-component-card-tags';\n\n for (const tag of component.tags) {\n const tagEl = document.createElement('span');\n tagEl.className = 'catalogue-tag';\n tagEl.textContent = tag;\n tagsContainer.appendChild(tagEl);\n }\n\n card.appendChild(tagsContainer);\n }\n\n // Scenario count\n const meta = document.createElement('div');\n meta.className = 'catalogue-component-card-meta';\n meta.textContent = `${component.scenarios.length} scenario${component.scenarios.length !== 1 ? 's' : ''}`;\n card.appendChild(meta);\n\n return card;\n}\n\n/**\n * Render the landing page into a container.\n */\nexport function renderLandingPage(\n container: HTMLElement,\n options: LandingPageOptions\n): LandingPageElements {\n container.innerHTML = '';\n const page = createLandingPage(options);\n container.appendChild(page.root);\n return page;\n}\n","/**\n * Component detail page - Shows variants, documentation, and hierarchy.\n */\n\nimport { marked } from 'marked';\nimport type { Registry, RegistryComponent, RegistryScenario } from '../../registry/index.js';\nimport { getSubcomponents } from '../../registry/index.js';\nimport { render } from '../../render/index.js';\nimport { createNavLink } from '../router.js';\n\nexport interface ComponentPageOptions {\n registry: Registry;\n componentId: string;\n onNavigate: (path: string) => void;\n}\n\nexport interface ComponentPageElements {\n root: HTMLDivElement;\n header: HTMLElement;\n variantsGrid: HTMLDivElement;\n docsSection: HTMLDivElement | null;\n}\n\n/**\n * Create the component detail page.\n */\nexport function createComponentPage(options: ComponentPageOptions): ComponentPageElements | null {\n const { registry, componentId, onNavigate } = options;\n\n const component = registry.components.get(componentId);\n if (!component) {\n return null;\n }\n\n const root = document.createElement('div');\n root.className = 'catalogue-component-page';\n root.setAttribute('data-catalogue-root', '');\n\n // Breadcrumb\n const breadcrumb = document.createElement('nav');\n breadcrumb.className = 'catalogue-breadcrumb';\n breadcrumb.setAttribute('aria-label', 'Breadcrumb');\n\n const homeLink = createNavLink('/', 'Components');\n homeLink.addEventListener('click', (e) => {\n e.preventDefault();\n onNavigate('/');\n });\n breadcrumb.appendChild(homeLink);\n\n const separator = document.createElement('span');\n separator.className = 'catalogue-breadcrumb-separator';\n separator.textContent = '/';\n breadcrumb.appendChild(separator);\n\n // If subcomponent, show parent link\n if (component.parentId) {\n const parent = registry.components.get(component.parentId);\n if (parent) {\n const parentLink = createNavLink(`/component/${parent.id}`, parent.title);\n parentLink.addEventListener('click', (e) => {\n e.preventDefault();\n onNavigate(`/component/${parent.id}`);\n });\n breadcrumb.appendChild(parentLink);\n\n const sep2 = document.createElement('span');\n sep2.className = 'catalogue-breadcrumb-separator';\n sep2.textContent = '/';\n breadcrumb.appendChild(sep2);\n }\n }\n\n const current = document.createElement('span');\n current.className = 'catalogue-breadcrumb-current';\n current.textContent = component.title;\n breadcrumb.appendChild(current);\n\n root.appendChild(breadcrumb);\n\n // Header\n const header = document.createElement('header');\n header.className = 'catalogue-component-header';\n\n const titleRow = document.createElement('div');\n titleRow.className = 'catalogue-component-title-row';\n\n const title = document.createElement('h1');\n title.className = 'catalogue-component-title';\n title.textContent = component.title;\n titleRow.appendChild(title);\n\n const badge = document.createElement('span');\n badge.className = 'catalogue-status-badge';\n badge.setAttribute('data-status', component.status);\n badge.textContent = component.status;\n titleRow.appendChild(badge);\n\n header.appendChild(titleRow);\n\n if (component.description) {\n const desc = document.createElement('p');\n desc.className = 'catalogue-component-description';\n desc.textContent = component.description;\n header.appendChild(desc);\n }\n\n // Tags\n if (component.tags && component.tags.length > 0) {\n const tagsContainer = document.createElement('div');\n tagsContainer.className = 'catalogue-component-tags';\n\n for (const tag of component.tags) {\n const tagEl = document.createElement('span');\n tagEl.className = 'catalogue-tag';\n tagEl.textContent = tag;\n tagsContainer.appendChild(tagEl);\n }\n\n header.appendChild(tagsContainer);\n }\n\n // Actions\n const actions = document.createElement('div');\n actions.className = 'catalogue-component-actions';\n\n const playgroundLink = document.createElement('a');\n playgroundLink.href = `#/playground/${component.id}`;\n playgroundLink.className = 'catalogue-button catalogue-button-primary';\n playgroundLink.textContent = 'Open Playground';\n playgroundLink.addEventListener('click', (e) => {\n e.preventDefault();\n onNavigate(`/playground/${component.id}`);\n });\n actions.appendChild(playgroundLink);\n\n header.appendChild(actions);\n root.appendChild(header);\n\n // Subcomponents (if any)\n const subcomponents = getSubcomponents(registry, componentId);\n if (subcomponents.length > 0) {\n const subsSection = document.createElement('section');\n subsSection.className = 'catalogue-subcomponents-section';\n\n const subsTitle = document.createElement('h2');\n subsTitle.textContent = 'Subcomponents';\n subsSection.appendChild(subsTitle);\n\n const subsList = document.createElement('div');\n subsList.className = 'catalogue-subcomponents-list';\n\n for (const sub of subcomponents) {\n const subCard = document.createElement('div');\n subCard.className = 'catalogue-subcomponent-card';\n\n const subLink = createNavLink(`/component/${sub.id}`, sub.title);\n subLink.addEventListener('click', (e) => {\n e.preventDefault();\n onNavigate(`/component/${sub.id}`);\n });\n subCard.appendChild(subLink);\n\n if (sub.description) {\n const subDesc = document.createElement('p');\n subDesc.textContent = sub.description;\n subCard.appendChild(subDesc);\n }\n\n subsList.appendChild(subCard);\n }\n\n subsSection.appendChild(subsList);\n root.appendChild(subsSection);\n }\n\n // Variants grid\n const variantsSection = document.createElement('section');\n variantsSection.className = 'catalogue-variants-section';\n\n const variantsTitle = document.createElement('h2');\n variantsTitle.textContent = 'Variants';\n variantsSection.appendChild(variantsTitle);\n\n const variantsGrid = document.createElement('div');\n variantsGrid.className = 'catalogue-variants-grid';\n\n // Sort scenarios - primary first\n const sortedScenarios = [...component.scenarios].sort((a, b) => {\n if (a.id === component.playground.primaryScenarioId) return -1;\n if (b.id === component.playground.primaryScenarioId) return 1;\n return 0;\n });\n\n for (const scenario of sortedScenarios) {\n const card = createScenarioCard(scenario, component, onNavigate);\n variantsGrid.appendChild(card);\n }\n\n variantsSection.appendChild(variantsGrid);\n root.appendChild(variantsSection);\n\n // Documentation section\n let docsSection: HTMLDivElement | null = null;\n\n if (component.docs) {\n docsSection = document.createElement('div');\n docsSection.className = 'catalogue-docs-section';\n\n const docsTitle = document.createElement('h2');\n docsTitle.textContent = 'Documentation';\n docsSection.appendChild(docsTitle);\n\n const docsContent = document.createElement('div');\n docsContent.className = 'catalogue-docs-content';\n docsContent.innerHTML = marked.parse(component.docs) as string;\n docsSection.appendChild(docsContent);\n\n root.appendChild(docsSection);\n }\n\n return {\n root,\n header,\n variantsGrid,\n docsSection,\n };\n}\n\n/**\n * Create a scenario card element.\n */\nfunction createScenarioCard(\n scenario: RegistryScenario,\n component: RegistryComponent,\n onNavigate: (path: string) => void\n): HTMLDivElement {\n const card = document.createElement('div');\n card.className = 'catalogue-scenario-card';\n\n const isPrimary = scenario.id === component.playground.primaryScenarioId;\n if (isPrimary) {\n card.classList.add('catalogue-scenario-card-primary');\n }\n\n // Preview container\n const preview = document.createElement('div');\n preview.className = 'catalogue-scenario-preview';\n preview.setAttribute('data-catalogue-container', '');\n\n // Render the scenario\n try {\n render(scenario.render, { container: preview, clear: true });\n } catch (err) {\n const error = document.createElement('div');\n error.className = 'catalogue-scenario-error';\n error.textContent = `Render error: ${err instanceof Error ? err.message : 'Unknown error'}`;\n preview.appendChild(error);\n }\n\n card.appendChild(preview);\n\n // Info section\n const info = document.createElement('div');\n info.className = 'catalogue-scenario-info';\n\n const titleRow = document.createElement('div');\n titleRow.className = 'catalogue-scenario-title-row';\n\n const title = document.createElement('h3');\n title.className = 'catalogue-scenario-title';\n title.textContent = scenario.title;\n titleRow.appendChild(title);\n\n if (isPrimary) {\n const primaryBadge = document.createElement('span');\n primaryBadge.className = 'catalogue-primary-badge';\n primaryBadge.textContent = 'Primary';\n titleRow.appendChild(primaryBadge);\n }\n\n info.appendChild(titleRow);\n\n if (scenario.description) {\n const desc = document.createElement('p');\n desc.className = 'catalogue-scenario-description';\n desc.textContent = scenario.description;\n info.appendChild(desc);\n }\n\n // Links\n const links = document.createElement('div');\n links.className = 'catalogue-scenario-links';\n\n const harnessLink = document.createElement('a');\n harnessLink.href = `#/harness/${scenario.id}`;\n harnessLink.className = 'catalogue-link';\n harnessLink.textContent = 'Harness';\n harnessLink.addEventListener('click', (e) => {\n e.preventDefault();\n onNavigate(`/harness/${scenario.id}`);\n });\n links.appendChild(harnessLink);\n\n info.appendChild(links);\n card.appendChild(info);\n\n return card;\n}\n\n/**\n * Render the component page into a container.\n */\nexport function renderComponentPage(\n container: HTMLElement,\n options: ComponentPageOptions\n): ComponentPageElements | null {\n container.innerHTML = '';\n\n const page = createComponentPage(options);\n if (!page) {\n const notFound = document.createElement('div');\n notFound.className = 'catalogue-not-found';\n notFound.textContent = `Component \"${options.componentId}\" not found`;\n container.appendChild(notFound);\n return null;\n }\n\n container.appendChild(page.root);\n return page;\n}\n","/**\n * HTML code generation from RenderNode.\n * Generates deterministic, copy-pasteable HTML snippets.\n */\n\nimport type { RenderNode } from '../schemas/index.js';\n\nexport interface CodegenOptions {\n /** Indentation string (default: 2 spaces) */\n indent?: string;\n /** Include script tag for complex props */\n includeScript?: boolean;\n /** ID to use for element reference in script */\n elementId?: string;\n}\n\n/**\n * Generate HTML from a RenderNode.\n */\nexport function generateHtml(node: RenderNode, options: CodegenOptions = {}): string {\n const { indent = ' ', includeScript = true, elementId } = options;\n\n const lines: string[] = [];\n const propsToSet: Array<{ key: string; value: unknown }> = [];\n\n generateNodeHtml(node, lines, propsToSet, '', indent, elementId);\n\n // If we have complex props, add a script tag\n if (includeScript && propsToSet.length > 0) {\n lines.push('');\n lines.push('<script type=\"module\">');\n\n const selector = elementId ? `#${elementId}` : node.element;\n lines.push(`${indent}const el = document.querySelector('${selector}');`);\n\n for (const { key, value } of propsToSet) {\n const valueStr = JSON.stringify(value);\n lines.push(`${indent}el.${key} = ${valueStr};`);\n }\n\n lines.push('</script>');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Generate HTML for a single node recursively.\n */\nfunction generateNodeHtml(\n node: RenderNode,\n lines: string[],\n propsToSet: Array<{ key: string; value: unknown }>,\n currentIndent: string,\n indentStep: string,\n elementId?: string\n): void {\n // Build opening tag\n let openTag = `<${node.element}`;\n\n // Add ID if specified\n if (elementId) {\n openTag += ` id=\"${escapeAttr(elementId)}\"`;\n }\n\n // Add attributes\n if (node.attrs) {\n for (const [key, value] of Object.entries(node.attrs)) {\n if (value === null || value === undefined) {\n continue;\n }\n if (typeof value === 'boolean') {\n if (value) {\n openTag += ` ${key}`;\n }\n // false = omit attribute\n } else {\n openTag += ` ${key}=\"${escapeAttr(String(value))}\"`;\n }\n }\n }\n\n // Track props that need script assignment\n if (node.props) {\n for (const [key, value] of Object.entries(node.props)) {\n propsToSet.push({ key, value });\n }\n }\n\n // Determine if we need a closing tag\n const hasContent = node.text !== undefined || node.children?.length || node.slots && Object.keys(node.slots).length > 0;\n const selfClosingTags = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n 'link', 'meta', 'param', 'source', 'track', 'wbr'\n ]);\n\n if (!hasContent && selfClosingTags.has(node.element)) {\n lines.push(`${currentIndent}${openTag} />`);\n return;\n }\n\n openTag += '>';\n\n // Simple text content on same line\n if (node.text !== undefined && !node.children?.length && !node.slots) {\n lines.push(`${currentIndent}${openTag}${escapeHtml(node.text)}</${node.element}>`);\n return;\n }\n\n lines.push(`${currentIndent}${openTag}`);\n\n const childIndent = currentIndent + indentStep;\n\n // Render text content\n if (node.text !== undefined) {\n lines.push(`${childIndent}${escapeHtml(node.text)}`);\n }\n\n // Render slots\n if (node.slots) {\n for (const [slotName, content] of Object.entries(node.slots)) {\n renderSlotContent(content, slotName, lines, propsToSet, childIndent, indentStep);\n }\n }\n\n // Render children\n if (node.children) {\n for (const child of node.children) {\n generateNodeHtml(child, lines, propsToSet, childIndent, indentStep);\n }\n }\n\n lines.push(`${currentIndent}</${node.element}>`);\n}\n\n/**\n * Render slot content to HTML.\n */\nfunction renderSlotContent(\n content: string | RenderNode | RenderNode[],\n slotName: string,\n lines: string[],\n propsToSet: Array<{ key: string; value: unknown }>,\n currentIndent: string,\n indentStep: string\n): void {\n if (typeof content === 'string') {\n // Text slot content\n if (slotName === 'default') {\n lines.push(`${currentIndent}${escapeHtml(content)}`);\n } else {\n lines.push(`${currentIndent}<span slot=\"${escapeAttr(slotName)}\">${escapeHtml(content)}</span>`);\n }\n } else if (Array.isArray(content)) {\n for (const node of content) {\n const nodeWithSlot = slotName === 'default' ? node : addSlotAttr(node, slotName);\n generateNodeHtml(nodeWithSlot, lines, propsToSet, currentIndent, indentStep);\n }\n } else {\n const nodeWithSlot = slotName === 'default' ? content : addSlotAttr(content, slotName);\n generateNodeHtml(nodeWithSlot, lines, propsToSet, currentIndent, indentStep);\n }\n}\n\n/**\n * Add slot attribute to a render node.\n */\nfunction addSlotAttr(node: RenderNode, slotName: string): RenderNode {\n return {\n ...node,\n attrs: {\n ...node.attrs,\n slot: slotName,\n },\n };\n}\n\n/**\n * Escape HTML entities.\n */\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\n}\n\n/**\n * Escape attribute value.\n */\nfunction escapeAttr(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/\"/g, '&quot;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\n}\n\n/**\n * Generate just the HTML without script tags.\n */\nexport function generateHtmlOnly(node: RenderNode, options: Omit<CodegenOptions, 'includeScript'> = {}): string {\n return generateHtml(node, { ...options, includeScript: false });\n}\n\n/**\n * Generate JavaScript code for setting complex properties.\n */\nexport function generatePropsScript(\n node: RenderNode,\n selector: string,\n options: { indent?: string } = {}\n): string | null {\n const { indent = ' ' } = options;\n\n if (!node.props || Object.keys(node.props).length === 0) {\n return null;\n }\n\n const lines: string[] = [];\n lines.push(`const el = document.querySelector('${selector}');`);\n\n for (const [key, value] of Object.entries(node.props)) {\n const valueStr = JSON.stringify(value);\n lines.push(`el.${key} = ${valueStr};`);\n }\n\n return lines.map(line => `${indent}${line}`).join('\\n');\n}\n","/**\n * Control panel generator for the playground.\n * Creates form controls based on component.json control specs.\n */\n\nimport type { RegistryComponent } from '../registry/index.js';\nimport type { ControlSpec } from '../schemas/index.js';\n\nexport interface ControlsOptions {\n component: RegistryComponent;\n values: Record<string, unknown>;\n onChange: (propName: string, value: unknown) => void;\n}\n\nexport interface ControlsElements {\n container: HTMLDivElement;\n controls: Map<string, HTMLElement>;\n}\n\n/**\n * Create the controls panel for a component.\n */\nexport function createControls(options: ControlsOptions): ControlsElements {\n const { component, values, onChange } = options;\n\n const container = document.createElement('div');\n container.className = 'catalogue-controls';\n\n const controls = new Map<string, HTMLElement>();\n\n for (const [propName, spec] of Object.entries(component.playground.controls)) {\n const control = createControl(propName, spec, values[propName], (value) => {\n onChange(propName, value);\n });\n\n controls.set(propName, control.wrapper);\n container.appendChild(control.wrapper);\n }\n\n return { container, controls };\n}\n\ninterface ControlElements {\n wrapper: HTMLDivElement;\n input: HTMLElement;\n}\n\n/**\n * Create a single control based on its spec.\n */\nfunction createControl(\n propName: string,\n spec: ControlSpec,\n initialValue: unknown,\n onChange: (value: unknown) => void\n): ControlElements {\n const wrapper = document.createElement('div');\n wrapper.className = 'catalogue-control';\n wrapper.setAttribute('data-control-type', spec.type);\n\n const label = document.createElement('label');\n label.className = 'catalogue-control-label';\n label.textContent = spec.label || propName;\n\n wrapper.appendChild(label);\n\n let input: HTMLElement;\n\n switch (spec.type) {\n case 'text':\n input = createTextControl(propName, spec, initialValue as string | undefined, onChange);\n break;\n case 'number':\n input = createNumberControl(propName, spec, initialValue as number | undefined, onChange);\n break;\n case 'boolean':\n input = createBooleanControl(propName, spec, initialValue as boolean | undefined, onChange);\n break;\n case 'select':\n input = createSelectControl(propName, spec, initialValue as string | undefined, onChange);\n break;\n case 'radio':\n input = createRadioControl(propName, spec, initialValue as string | undefined, onChange);\n break;\n case 'color':\n input = createColorControl(propName, spec, initialValue as string | undefined, onChange);\n break;\n case 'range':\n input = createRangeControl(propName, spec, initialValue as number | undefined, onChange);\n break;\n case 'json':\n input = createJsonControl(propName, spec, initialValue, onChange);\n break;\n default:\n input = document.createElement('span');\n input.textContent = `Unknown control type`;\n }\n\n wrapper.appendChild(input);\n\n return { wrapper, input };\n}\n\nfunction createTextControl(\n propName: string,\n spec: { defaultValue?: string; placeholder?: string },\n initialValue: string | undefined,\n onChange: (value: string) => void\n): HTMLInputElement {\n const input = document.createElement('input');\n input.type = 'text';\n input.className = 'catalogue-control-input';\n input.name = propName;\n input.value = initialValue ?? spec.defaultValue ?? '';\n if (spec.placeholder) {\n input.placeholder = spec.placeholder;\n }\n\n input.addEventListener('input', () => {\n onChange(input.value);\n });\n\n return input;\n}\n\nfunction createNumberControl(\n propName: string,\n spec: { defaultValue?: number; min?: number; max?: number; step?: number },\n initialValue: number | undefined,\n onChange: (value: number) => void\n): HTMLInputElement {\n const input = document.createElement('input');\n input.type = 'number';\n input.className = 'catalogue-control-input';\n input.name = propName;\n input.value = String(initialValue ?? spec.defaultValue ?? 0);\n\n if (spec.min !== undefined) input.min = String(spec.min);\n if (spec.max !== undefined) input.max = String(spec.max);\n if (spec.step !== undefined) input.step = String(spec.step);\n\n input.addEventListener('input', () => {\n onChange(parseFloat(input.value) || 0);\n });\n\n return input;\n}\n\nfunction createBooleanControl(\n propName: string,\n spec: { defaultValue?: boolean },\n initialValue: boolean | undefined,\n onChange: (value: boolean) => void\n): HTMLDivElement {\n const wrapper = document.createElement('div');\n wrapper.className = 'catalogue-control-checkbox';\n\n const input = document.createElement('input');\n input.type = 'checkbox';\n input.className = 'catalogue-control-checkbox-input';\n input.name = propName;\n input.checked = initialValue ?? spec.defaultValue ?? false;\n\n input.addEventListener('change', () => {\n onChange(input.checked);\n });\n\n wrapper.appendChild(input);\n\n return wrapper;\n}\n\nfunction createSelectControl(\n propName: string,\n spec: {\n defaultValue?: string;\n options: Array<string | { label: string; value: string }>;\n },\n initialValue: string | undefined,\n onChange: (value: string) => void\n): HTMLSelectElement {\n const select = document.createElement('select');\n select.className = 'catalogue-control-select';\n select.name = propName;\n\n for (const option of spec.options) {\n const opt = document.createElement('option');\n if (typeof option === 'string') {\n opt.value = option;\n opt.textContent = option;\n } else {\n opt.value = option.value;\n opt.textContent = option.label;\n }\n select.appendChild(opt);\n }\n\n select.value = initialValue ?? spec.defaultValue ?? '';\n\n select.addEventListener('change', () => {\n onChange(select.value);\n });\n\n return select;\n}\n\nfunction createRadioControl(\n propName: string,\n spec: {\n defaultValue?: string;\n options: Array<string | { label: string; value: string }>;\n },\n initialValue: string | undefined,\n onChange: (value: string) => void\n): HTMLDivElement {\n const wrapper = document.createElement('div');\n wrapper.className = 'catalogue-control-radio-group';\n\n const currentValue = initialValue ?? spec.defaultValue;\n\n for (const option of spec.options) {\n const label = document.createElement('label');\n label.className = 'catalogue-control-radio';\n\n const input = document.createElement('input');\n input.type = 'radio';\n input.name = propName;\n\n const value = typeof option === 'string' ? option : option.value;\n const text = typeof option === 'string' ? option : option.label;\n\n input.value = value;\n input.checked = value === currentValue;\n\n input.addEventListener('change', () => {\n if (input.checked) {\n onChange(input.value);\n }\n });\n\n const span = document.createElement('span');\n span.textContent = text;\n\n label.appendChild(input);\n label.appendChild(span);\n wrapper.appendChild(label);\n }\n\n return wrapper;\n}\n\nfunction createColorControl(\n propName: string,\n spec: { defaultValue?: string },\n initialValue: string | undefined,\n onChange: (value: string) => void\n): HTMLInputElement {\n const input = document.createElement('input');\n input.type = 'color';\n input.className = 'catalogue-control-color';\n input.name = propName;\n input.value = initialValue ?? spec.defaultValue ?? '#000000';\n\n input.addEventListener('input', () => {\n onChange(input.value);\n });\n\n return input;\n}\n\nfunction createRangeControl(\n propName: string,\n spec: { defaultValue?: number; min: number; max: number; step?: number },\n initialValue: number | undefined,\n onChange: (value: number) => void\n): HTMLDivElement {\n const wrapper = document.createElement('div');\n wrapper.className = 'catalogue-control-range-wrapper';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.className = 'catalogue-control-range';\n input.name = propName;\n input.min = String(spec.min);\n input.max = String(spec.max);\n if (spec.step !== undefined) input.step = String(spec.step);\n input.value = String(initialValue ?? spec.defaultValue ?? spec.min);\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'catalogue-control-range-value';\n valueDisplay.textContent = input.value;\n\n input.addEventListener('input', () => {\n valueDisplay.textContent = input.value;\n onChange(parseFloat(input.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n\n return wrapper;\n}\n\nfunction createJsonControl(\n propName: string,\n spec: { defaultValue?: unknown },\n initialValue: unknown,\n onChange: (value: unknown) => void\n): HTMLTextAreaElement {\n const textarea = document.createElement('textarea');\n textarea.className = 'catalogue-control-json';\n textarea.name = propName;\n textarea.rows = 4;\n\n const value = initialValue ?? spec.defaultValue;\n textarea.value = value !== undefined ? JSON.stringify(value, null, 2) : '';\n\n textarea.addEventListener('input', () => {\n try {\n const parsed = JSON.parse(textarea.value);\n textarea.classList.remove('invalid');\n onChange(parsed);\n } catch {\n textarea.classList.add('invalid');\n }\n });\n\n return textarea;\n}\n","/**\n * Playground page - Live prop editing with controls.\n */\n\nimport type { Registry, RegistryComponent, RegistryScenario } from '../../registry/index.js';\nimport type { RenderNode, ControlSpec } from '../../schemas/index.js';\nimport { renderNode, updateElement } from '../../render/index.js';\nimport { createResizer, createBreakpointPresets } from '../../ui/resizer.js';\nimport { createThemeToggle, initTheme } from '../../ui/theme-toggle.js';\nimport { createCodePanel, updateCodePanel } from '../../ui/code-panel.js';\nimport { generateHtml } from '../../playground/codegen.js';\nimport { createControls } from '../../playground/controls.js';\nimport { createNavLink } from '../router.js';\n\nexport interface PlaygroundPageOptions {\n registry: Registry;\n componentId: string;\n onNavigate: (path: string) => void;\n}\n\nexport interface PlaygroundPageElements {\n root: HTMLDivElement;\n preview: HTMLDivElement;\n controls: HTMLDivElement;\n codePanel: HTMLDivElement;\n}\n\n/**\n * Create the playground page.\n */\nexport function createPlaygroundPage(options: PlaygroundPageOptions): PlaygroundPageElements | null {\n const { registry, componentId, onNavigate } = options;\n\n const component = registry.components.get(componentId);\n if (!component) {\n return null;\n }\n\n // Find the primary scenario\n const primaryScenario = component.scenarios.find(\n s => s.id === component.playground.primaryScenarioId\n );\n\n if (!primaryScenario) {\n return null;\n }\n\n // Initialize theme\n initTheme();\n\n const root = document.createElement('div');\n root.className = 'catalogue-playground';\n root.setAttribute('data-catalogue-root', '');\n\n // Header\n const header = document.createElement('header');\n header.className = 'catalogue-playground-header';\n\n // Breadcrumb\n const breadcrumb = document.createElement('nav');\n breadcrumb.className = 'catalogue-breadcrumb';\n\n const homeLink = createNavLink('/', 'Components');\n homeLink.addEventListener('click', (e) => {\n e.preventDefault();\n onNavigate('/');\n });\n breadcrumb.appendChild(homeLink);\n\n const sep1 = document.createElement('span');\n sep1.className = 'catalogue-breadcrumb-separator';\n sep1.textContent = '/';\n breadcrumb.appendChild(sep1);\n\n const componentLink = createNavLink(`/component/${component.id}`, component.title);\n componentLink.addEventListener('click', (e) => {\n e.preventDefault();\n onNavigate(`/component/${component.id}`);\n });\n breadcrumb.appendChild(componentLink);\n\n const sep2 = document.createElement('span');\n sep2.className = 'catalogue-breadcrumb-separator';\n sep2.textContent = '/';\n breadcrumb.appendChild(sep2);\n\n const current = document.createElement('span');\n current.className = 'catalogue-breadcrumb-current';\n current.textContent = 'Playground';\n breadcrumb.appendChild(current);\n\n header.appendChild(breadcrumb);\n\n // Title and theme toggle\n const titleRow = document.createElement('div');\n titleRow.className = 'catalogue-playground-title-row';\n\n const title = document.createElement('h1');\n title.textContent = `${component.title} Playground`;\n titleRow.appendChild(title);\n\n const themeToggle = createThemeToggle();\n titleRow.appendChild(themeToggle);\n\n header.appendChild(titleRow);\n root.appendChild(header);\n\n // Main content area\n const main = document.createElement('div');\n main.className = 'catalogue-playground-main';\n\n // Left side: Preview\n const previewSection = document.createElement('div');\n previewSection.className = 'catalogue-playground-preview-section';\n\n // Scenario selector (if multiple scenarios)\n if (component.scenarios.length > 1) {\n const scenarioSelector = document.createElement('div');\n scenarioSelector.className = 'catalogue-scenario-selector';\n\n const label = document.createElement('label');\n label.textContent = 'Scenario: ';\n\n const select = document.createElement('select');\n select.className = 'catalogue-scenario-select';\n\n for (const scenario of component.scenarios) {\n const option = document.createElement('option');\n option.value = scenario.id;\n option.textContent = scenario.title;\n if (scenario.id === primaryScenario.id) {\n option.selected = true;\n }\n select.appendChild(option);\n }\n\n label.appendChild(select);\n scenarioSelector.appendChild(label);\n previewSection.appendChild(scenarioSelector);\n\n // Handle scenario change\n select.addEventListener('change', () => {\n const selectedScenario = component.scenarios.find(s => s.id === select.value);\n if (selectedScenario) {\n currentRenderNode = structuredClone(selectedScenario.render);\n rerenderPreview();\n updateCode();\n }\n });\n }\n\n // Breakpoint presets\n const resizer = createResizer({\n initialWidth: '100%',\n initialHeight: '400px',\n onResize: (width, height) => {\n // Update dimension display is handled by resizer\n },\n onFullScreenChange: (isFullScreen) => {\n root.classList.toggle('catalogue-playground-fullscreen', isFullScreen);\n },\n });\n\n const presets = createBreakpointPresets(resizer);\n previewSection.appendChild(presets);\n previewSection.appendChild(resizer.wrapper);\n\n main.appendChild(previewSection);\n\n // Right side: Controls and code\n const sidebar = document.createElement('div');\n sidebar.className = 'catalogue-playground-sidebar';\n\n // Controls section\n const controlsSection = document.createElement('div');\n controlsSection.className = 'catalogue-playground-controls-section';\n\n const controlsTitle = document.createElement('h2');\n controlsTitle.textContent = 'Controls';\n controlsSection.appendChild(controlsTitle);\n\n const controlsContainer = document.createElement('div');\n controlsContainer.className = 'catalogue-controls-container';\n controlsSection.appendChild(controlsContainer);\n\n sidebar.appendChild(controlsSection);\n\n // Code panel\n const codeSection = document.createElement('div');\n codeSection.className = 'catalogue-playground-code-section';\n\n const codePanel = createCodePanel({\n code: generateHtml(primaryScenario.render),\n title: 'HTML',\n collapsible: true,\n collapsed: false,\n });\n codeSection.appendChild(codePanel.wrapper);\n\n sidebar.appendChild(codeSection);\n main.appendChild(sidebar);\n root.appendChild(main);\n\n // State\n let currentRenderNode: RenderNode = structuredClone(primaryScenario.render);\n let renderedElement: Element | null = null;\n\n // Render preview\n const rerenderPreview = () => {\n resizer.content.innerHTML = '';\n try {\n renderedElement = renderNode(currentRenderNode);\n resizer.content.appendChild(renderedElement);\n } catch (err) {\n const error = document.createElement('div');\n error.className = 'catalogue-render-error';\n error.textContent = `Error: ${err instanceof Error ? err.message : 'Unknown error'}`;\n resizer.content.appendChild(error);\n renderedElement = null;\n }\n };\n\n // Update code panel\n const updateCode = () => {\n const html = generateHtml(currentRenderNode);\n updateCodePanel(codePanel, html);\n };\n\n // Create controls\n const controls = createControls({\n component,\n values: getInitialControlValues(component, currentRenderNode),\n onChange: (propName, value) => {\n // Update the render node\n if (!currentRenderNode.attrs) {\n currentRenderNode.attrs = {};\n }\n\n const controlSpec = component.playground.controls[propName];\n if (controlSpec) {\n if (controlSpec.type === 'json') {\n // JSON values go to props\n if (!currentRenderNode.props) {\n currentRenderNode.props = {};\n }\n currentRenderNode.props[propName] = value;\n } else if (controlSpec.type === 'boolean') {\n // Boolean attributes\n if (value) {\n currentRenderNode.attrs[propName] = true;\n } else {\n delete currentRenderNode.attrs[propName];\n }\n } else {\n // String/number attributes\n currentRenderNode.attrs[propName] = value as string | number;\n }\n }\n\n // Update the rendered element or re-render\n if (renderedElement) {\n updateElement(renderedElement, currentRenderNode.attrs, currentRenderNode.props);\n } else {\n rerenderPreview();\n }\n\n updateCode();\n },\n });\n\n controlsContainer.appendChild(controls.container);\n\n // Initial render\n rerenderPreview();\n\n return {\n root,\n preview: resizer.content,\n controls: controlsContainer,\n codePanel: codeSection,\n };\n}\n\n/**\n * Get initial control values from a render node.\n */\nfunction getInitialControlValues(\n component: RegistryComponent,\n node: RenderNode\n): Record<string, unknown> {\n const values: Record<string, unknown> = {};\n\n for (const [propName, controlSpec] of Object.entries(component.playground.controls)) {\n // Check attrs first\n if (node.attrs && propName in node.attrs) {\n values[propName] = node.attrs[propName];\n }\n // Then props\n else if (node.props && propName in node.props) {\n values[propName] = node.props[propName];\n }\n // Fall back to control default\n else if ('defaultValue' in controlSpec) {\n values[propName] = controlSpec.defaultValue;\n }\n }\n\n return values;\n}\n\n/**\n * Render the playground page into a container.\n */\nexport function renderPlaygroundPage(\n container: HTMLElement,\n options: PlaygroundPageOptions\n): PlaygroundPageElements | null {\n container.innerHTML = '';\n\n const page = createPlaygroundPage(options);\n if (!page) {\n const notFound = document.createElement('div');\n notFound.className = 'catalogue-not-found';\n notFound.textContent = `Component \"${options.componentId}\" not found or missing primary scenario`;\n container.appendChild(notFound);\n return null;\n }\n\n container.appendChild(page.root);\n return page;\n}\n","/**\n * Harness page - Minimal view for Playwright visual testing.\n * Renders a single scenario with query param support for theme and dimensions.\n */\n\nimport type { Registry, RegistryScenario } from '../../registry/index.js';\nimport { render } from '../../render/index.js';\nimport { setTheme, type Theme } from '../../ui/theme-toggle.js';\n\nexport interface HarnessPageOptions {\n registry: Registry;\n scenarioId: string;\n query: URLSearchParams;\n}\n\nexport interface HarnessPageElements {\n root: HTMLDivElement;\n container: HTMLDivElement;\n}\n\n/**\n * Create the harness page.\n */\nexport function createHarnessPage(options: HarnessPageOptions): HarnessPageElements | null {\n const { registry, scenarioId, query } = options;\n\n const scenario = registry.scenarios.get(scenarioId);\n if (!scenario) {\n return null;\n }\n\n // Parse query params\n const theme = (query.get('theme') as Theme) || 'light';\n const width = query.get('w') ? parseInt(query.get('w')!, 10) : undefined;\n const height = query.get('h') ? parseInt(query.get('h')!, 10) : undefined;\n const background = query.get('bg') || scenario.background;\n\n // Apply theme\n setTheme(theme);\n\n // Create root - minimal chrome\n const root = document.createElement('div');\n root.className = 'catalogue-harness';\n root.setAttribute('data-catalogue-root', '');\n root.setAttribute('data-theme', theme);\n\n // Container for the component\n const container = document.createElement('div');\n container.className = 'catalogue-harness-container';\n container.setAttribute('data-catalogue-container', '');\n container.setAttribute('data-theme', theme);\n\n // Apply dimensions if specified\n if (width !== undefined) {\n container.style.width = `${width}px`;\n }\n if (height !== undefined) {\n container.style.height = `${height}px`;\n }\n if (background) {\n container.style.backgroundColor = background;\n }\n\n // Apply scenario viewport if specified and no query override\n if (!width && !height && scenario.viewport) {\n if (scenario.viewport.width) {\n container.style.width = `${scenario.viewport.width}px`;\n }\n if (scenario.viewport.height) {\n container.style.height = `${scenario.viewport.height}px`;\n }\n }\n\n // Render the scenario\n try {\n render(scenario.render, { container, clear: true });\n } catch (err) {\n const error = document.createElement('div');\n error.setAttribute('data-catalogue-error', '');\n error.style.cssText = 'color: red; padding: 1em; font-family: monospace;';\n error.textContent = `Render error: ${err instanceof Error ? err.message : 'Unknown error'}`;\n container.appendChild(error);\n }\n\n root.appendChild(container);\n\n return {\n root,\n container,\n };\n}\n\n/**\n * Render the harness page into a container.\n */\nexport function renderHarnessPage(\n container: HTMLElement,\n options: HarnessPageOptions\n): HarnessPageElements | null {\n container.innerHTML = '';\n\n // Apply minimal styles for harness\n document.body.classList.add('catalogue-harness-body');\n\n const page = createHarnessPage(options);\n if (!page) {\n const notFound = document.createElement('div');\n notFound.className = 'catalogue-not-found';\n notFound.setAttribute('data-catalogue-error', '');\n notFound.textContent = `Scenario \"${options.scenarioId}\" not found`;\n container.appendChild(notFound);\n return null;\n }\n\n container.appendChild(page.root);\n return page;\n}\n\n/**\n * Get harness URL for a scenario.\n */\nexport function getHarnessUrl(\n scenarioId: string,\n options?: {\n theme?: Theme;\n width?: number;\n height?: number;\n background?: string;\n }\n): string {\n const params = new URLSearchParams();\n\n if (options?.theme) {\n params.set('theme', options.theme);\n }\n if (options?.width !== undefined) {\n params.set('w', String(options.width));\n }\n if (options?.height !== undefined) {\n params.set('h', String(options.height));\n }\n if (options?.background) {\n params.set('bg', options.background);\n }\n\n const queryString = params.toString();\n return `/harness/${scenarioId}${queryString ? `?${queryString}` : ''}`;\n}\n\n/**\n * Generate all harness URLs for a registry (for Playwright test generation).\n */\nexport function getAllHarnessUrls(\n registry: Registry,\n breakpoints?: Array<{ width: number; height: number }>\n): Array<{\n scenarioId: string;\n componentId: string;\n url: string;\n theme: Theme;\n width?: number;\n height?: number;\n}> {\n const urls: Array<{\n scenarioId: string;\n componentId: string;\n url: string;\n theme: Theme;\n width?: number;\n height?: number;\n }> = [];\n\n const themes: Theme[] = ['light', 'dark'];\n const defaultBreakpoints = breakpoints || [\n { width: 375, height: 667 }, // Mobile\n { width: 1024, height: 768 }, // Desktop\n ];\n\n for (const [scenarioId, scenario] of registry.scenarios) {\n // Basic URLs (no specific dimensions)\n for (const theme of themes) {\n urls.push({\n scenarioId,\n componentId: scenario.componentId,\n url: getHarnessUrl(scenarioId, { theme }),\n theme,\n });\n }\n\n // Breakpoint URLs\n for (const bp of defaultBreakpoints) {\n for (const theme of themes) {\n urls.push({\n scenarioId,\n componentId: scenario.componentId,\n url: getHarnessUrl(scenarioId, {\n theme,\n width: bp.width,\n height: bp.height,\n }),\n theme,\n width: bp.width,\n height: bp.height,\n });\n }\n }\n }\n\n return urls;\n}\n","/**\n * Main catalogue application.\n * Sets up routing and renders pages based on URL.\n */\n\nimport type { Registry } from '../registry/index.js';\nimport { Router } from './router.js';\nimport { renderLandingPage } from './pages/landing.js';\nimport { renderComponentPage } from './pages/component.js';\nimport { renderPlaygroundPage } from './pages/playground.js';\nimport { renderHarnessPage } from './pages/harness.js';\nimport { initTheme, createThemeToggle } from '../ui/theme-toggle.js';\n\nexport interface CatalogueAppOptions {\n /** Container element to render into */\n container: HTMLElement;\n /** Registry data */\n registry: Registry;\n /** Optional base path for deployment */\n basePath?: string;\n}\n\nexport interface CatalogueApp {\n /** The router instance */\n router: Router;\n /** Start the application */\n start: () => void;\n /** Navigate to a path */\n navigate: (path: string) => void;\n /** Current registry */\n registry: Registry;\n}\n\n/**\n * Create and initialize the catalogue application.\n */\nexport function createCatalogueApp(options: CatalogueAppOptions): CatalogueApp {\n const { container, registry, basePath = '' } = options;\n\n // Initialize theme\n initTheme();\n\n // Set up router\n const router = new Router({\n basePath,\n root: container,\n onNotFound: (path) => {\n container.innerHTML = '';\n const notFound = document.createElement('div');\n notFound.className = 'catalogue-not-found';\n notFound.innerHTML = `\n <h1>Page Not Found</h1>\n <p>The page \"${path}\" does not exist.</p>\n <a href=\"#/\">Back to Components</a>\n `;\n container.appendChild(notFound);\n },\n });\n\n const navigate = (path: string) => {\n router.navigate(path);\n };\n\n // Landing page\n router.route('/', () => {\n renderLandingPage(container, { registry, onNavigate: navigate });\n addGlobalHeader(container, navigate);\n });\n\n // Component detail page\n router.route('/component/:componentId', (params) => {\n renderComponentPage(container, {\n registry,\n componentId: params.componentId,\n onNavigate: navigate,\n });\n addGlobalHeader(container, navigate);\n });\n\n // Playground page\n router.route('/playground/:componentId', (params) => {\n renderPlaygroundPage(container, {\n registry,\n componentId: params.componentId,\n onNavigate: navigate,\n });\n });\n\n // Harness page (minimal chrome for testing)\n router.route('/harness/:scenarioId', (params, query) => {\n renderHarnessPage(container, {\n registry,\n scenarioId: params.scenarioId,\n query,\n });\n });\n\n // Example page (same as harness but with different styling)\n router.route('/example/:exampleId', (params, query) => {\n // Examples use the same renderer as scenarios\n const example = registry.examples.get(params.exampleId);\n if (example) {\n renderHarnessPage(container, {\n registry: {\n ...registry,\n scenarios: new Map([[example.id, { ...example, filePath: example.filePath }]]),\n },\n scenarioId: params.exampleId,\n query,\n });\n } else {\n router.navigate('/');\n }\n });\n\n return {\n router,\n start: () => router.start(),\n navigate,\n registry,\n };\n}\n\n/**\n * Add global header with theme toggle to non-harness pages.\n */\nfunction addGlobalHeader(container: HTMLElement, navigate: (path: string) => void): void {\n // Check if we already have a global header\n const existingHeader = container.querySelector('.catalogue-global-header');\n if (existingHeader) {\n return;\n }\n\n const root = container.querySelector('[data-catalogue-root]');\n if (!root) {\n return;\n }\n\n const header = document.createElement('div');\n header.className = 'catalogue-global-header';\n\n const homeLink = document.createElement('a');\n homeLink.href = '#/';\n homeLink.className = 'catalogue-home-link';\n homeLink.textContent = 'Component Catalogue';\n homeLink.addEventListener('click', (e) => {\n e.preventDefault();\n navigate('/');\n });\n header.appendChild(homeLink);\n\n const themeToggle = createThemeToggle();\n header.appendChild(themeToggle);\n\n root.insertBefore(header, root.firstChild);\n}\n\n/**\n * Mount the catalogue app to the DOM.\n */\nexport function mountCatalogueApp(\n selector: string,\n registry: Registry,\n options?: Partial<CatalogueAppOptions>\n): CatalogueApp {\n const container = document.querySelector<HTMLElement>(selector);\n if (!container) {\n throw new Error(`Container element not found: ${selector}`);\n }\n\n const app = createCatalogueApp({\n container,\n registry,\n ...options,\n });\n\n app.start();\n return app;\n}\n"],"names":["BaseRenderNodeSchema","z","RenderNodeSchema","validateRenderNode","data","result","e","TextControlSchema","NumberControlSchema","BooleanControlSchema","SelectControlSchema","RadioControlSchema","ColorControlSchema","RangeControlSchema","JsonControlSchema","ControlSpecSchema","validateControlSpec","ComponentStatusSchema","ComponentKindSchema","ComponentExportsSchema","PlaygroundConfigSchema","ComponentSchema","validateComponent","formatComponentErrors","errors","filePath","prefix","ScenarioSchema","ExampleSchema","validateScenario","validateExample","formatScenarioErrors","loadRegistry","raw","components","scenarios","examples","docs","component","error","scenarioData","scenario","exampleData","categories","createEmptyRegistry","getStandaloneComponents","registry","c","getSubcomponents","parentId","searchComponents","query","filters","queryLower","matchesId","matchesTitle","matchesTags","_a","tag","matchesDescription","_b","_c","_d","_e","_f","getComponentsByCategory","standalone","categorised","uncategorised","cat","validateRegistry","warnings","allIds","id","example","files","primaryId","s","subId","sub","formatValidationErrors","lines","warning","renderNode","node","el","key","value","slotName","content","renderSlotContent","child","childEl","parent","span","render","options","element","err","errorEl","updateElement","attrs","props","attrNames","name","applyNodeToElement","THEME_KEY","getInitialTheme","stored","setTheme","theme","toggleTheme","next","initTheme","createThemeToggle","button","updateIcon","currentTheme","DEFAULT_BREAKPOINTS","TRANSITION_STYLE","createResizer","initialWidth","initialHeight","minWidth","minHeight","maxWidth","maxHeight","onResize","onFullScreenChange","animatePresets","isFullScreenMode","wrapper","container","handleRight","handleBottom","handleCorner","dimensionLabel","updateDimensionLabel","rect","setTransition","enabled","isResizing","startX","startY","startWidth","startHeight","resizeMode","onMouseDown","mode","onMouseMove","deltaX","deltaY","newWidth","newHeight","onMouseUp","width","height","animate","wasFullScreen","createBreakpointPresets","resizer","breakpoints","onSelect","presets","activeButton","bp","setResizerDimensions","createCodePanel","code","language","collapsible","collapsed","title","header","titleEl","copyButton","codeEl","updateCodePanel","panel","newCopyButton","formatHtml","html","indent","level","indentStr","line","trimmed","Router","__publicField","pattern","handler","regexPattern","path","hash","queryIndex","route","match","params","createNavLink","href","text","className","link","parseRouteParams","regex","createLandingPage","onNavigate","root","controls","searchInput","filterContainer","statusFilter","createFilterGroup","kindFilter","hasCategories","expandCollapseToggle","componentList","statusCheckboxes","kindCheckboxes","renderComponents","selectedStatuses","cb","selectedKinds","isFiltering","grouped","empty","group","section","createCategorySection","g","card","createComponentCard","isExpanded","d","uncategorisedLabel","details","summary","label","labelSpan","countSpan","labelEl","option","checkbox","input","badge","desc","tagsContainer","tagEl","meta","renderLandingPage","page","createComponentPage","componentId","breadcrumb","homeLink","separator","parentLink","sep2","current","titleRow","actions","playgroundLink","subcomponents","subsSection","subsTitle","subsList","subCard","subLink","subDesc","variantsSection","variantsTitle","variantsGrid","sortedScenarios","a","b","createScenarioCard","docsSection","docsTitle","docsContent","marked","isPrimary","preview","info","primaryBadge","links","harnessLink","renderComponentPage","notFound","generateHtml","includeScript","elementId","propsToSet","generateNodeHtml","selector","valueStr","currentIndent","indentStep","openTag","escapeAttr","escapeHtml","childIndent","nodeWithSlot","addSlotAttr","generateHtmlOnly","generatePropsScript","createControls","values","onChange","propName","spec","control","createControl","initialValue","createTextControl","createNumberControl","createBooleanControl","createSelectControl","createRadioControl","createColorControl","createRangeControl","createJsonControl","select","opt","currentValue","valueDisplay","textarea","parsed","createPlaygroundPage","primaryScenario","sep1","componentLink","themeToggle","main","previewSection","scenarioSelector","selectedScenario","currentRenderNode","rerenderPreview","updateCode","isFullScreen","sidebar","controlsSection","controlsTitle","controlsContainer","codeSection","codePanel","renderedElement","getInitialControlValues","controlSpec","renderPlaygroundPage","createHarnessPage","scenarioId","background","renderHarnessPage","getHarnessUrl","queryString","getAllHarnessUrls","urls","themes","defaultBreakpoints","createCatalogueApp","basePath","router","navigate","addGlobalHeader","mountCatalogueApp","app"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@adieyal/catalogue-core",
3
+ "version": "0.1.0",
4
+ "description": "Core runtime and UI for component catalogues",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/adieyal/component-catalogue.git",
9
+ "directory": "packages/catalogue-core"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "type": "module",
15
+ "main": "./dist/index.js",
16
+ "module": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js"
22
+ },
23
+ "./styles": "./dist/styles.css"
24
+ },
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "scripts": {
29
+ "dev": "vite build --watch",
30
+ "build": "vite build",
31
+ "test": "vitest run",
32
+ "test:watch": "vitest"
33
+ },
34
+ "dependencies": {
35
+ "marked": "^12.0.0",
36
+ "zod": "^3.22.4"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^20.11.0",
40
+ "typescript": "^5.3.3",
41
+ "vite": "^5.0.12",
42
+ "vite-plugin-dts": "^3.7.0",
43
+ "vitest": "^1.2.0"
44
+ },
45
+ "peerDependencies": {
46
+ "marked": "^12.0.0",
47
+ "zod": "^3.22.4"
48
+ }
49
+ }