diff --git a/schemas/package-schemas/INDEX.md b/schemas/package-schemas/INDEX.md index bb67a4144..2c3b7903f 100644 --- a/schemas/package-schemas/INDEX.md +++ b/schemas/package-schemas/INDEX.md @@ -105,6 +105,7 @@ import type { PackageMetadata, Entity } from '@metabuilder/schema-types'; | Forms | [forms_schema.json](forms_schema.json) | Dynamic forms | 1.0.0 | | Migrations | [migrations_schema.json](migrations_schema.json) | DB migrations | 1.0.0 | | Assets | [assets_schema.json](assets_schema.json) | Static assets | 1.0.0 | +| Storybook | [storybook_schema.json](storybook_schema.json) | Storybook config | 1.0.0 | ### Utility Schemas | Schema | File | Purpose | diff --git a/schemas/package-schemas/SCHEMAS_README.md b/schemas/package-schemas/SCHEMAS_README.md index 53d9cc65c..2639b8fc4 100644 --- a/schemas/package-schemas/SCHEMAS_README.md +++ b/schemas/package-schemas/SCHEMAS_README.md @@ -25,6 +25,7 @@ Complete JSON Schema collection for MetaBuilder packages, providing declarative 14. **migrations_schema.json** - Database migration definitions 15. **assets_schema.json** - Static assets (images, fonts, icons, files) 16. **index_schema.json** - Master schema index +17. **storybook_schema.json** - Storybook configuration for package preview ## 🚀 Quick Start @@ -57,8 +58,10 @@ my-package/ │ └── roles.json # permissions_schema.json ├── forms/ │ └── forms.json # forms_schema.json -└── migrations/ - └── versions.json # migrations_schema.json +├── migrations/ +│ └── versions.json # migrations_schema.json +└── storybook/ + └── config.json # storybook_schema.json ``` ## 📚 Schema Details @@ -553,6 +556,59 @@ my-package/ ## 🔧 Validation +### 16. Storybook Schema (NEW) +**Purpose**: Storybook configuration for package preview and documentation + +**Key Features**: +- Story definitions with render function references +- Interactive controls for function/component arguments +- Context variants for testing different user scenarios +- Package-level rendering configuration +- Storybook parameters (backgrounds, viewport, layout) +- Auto-discovery configuration +- Support for featured packages and renders + +**Example**: +```json +{ + "$schema": "https://metabuilder.dev/schemas/package-storybook.schema.json", + "featured": true, + "title": "Dashboard Components", + "description": "Dashboard layouts and stat cards", + "stories": [ + { + "name": "StatsCard", + "render": "stats", + "description": "Single stat card with trend indicator" + }, + { + "name": "DashboardLayout", + "render": "layout" + } + ], + "renders": { + "stats.card": { + "description": "Single stat card with trend indicator", + "featured": true + } + }, + "contextVariants": [ + { + "name": "Admin", + "context": { "user": { "level": 4 } } + }, + { + "name": "Guest", + "context": { "user": { "level": 1 } } + } + ], + "parameters": { + "layout": "fullscreen", + "backgrounds": { "default": "light" } + } +} +``` + All schemas are valid JSON Schema Draft-07. Validate your data: ```bash @@ -581,8 +637,11 @@ metadata_schema.json (root) │ └── entities_schema.json (resource definitions) ├── forms_schema.json (user input) │ └── validation_schema.json (form validation) -└── migrations_schema.json (schema evolution) - └── entities_schema.json (target schema) +├── migrations_schema.json (schema evolution) +│ └── entities_schema.json (target schema) +└── storybook_schema.json (preview/docs) + ├── components_schema.json (story components) + └── scripts_schema.json (render functions) ``` ## 📦 NPM Package Usage diff --git a/schemas/package-schemas/examples/README.md b/schemas/package-schemas/examples/README.md index 219b6d6f5..431554046 100644 --- a/schemas/package-schemas/examples/README.md +++ b/schemas/package-schemas/examples/README.md @@ -48,6 +48,7 @@ A production-ready example demonstrating all major features. - `jobs/tasks.json` - Background jobs - `migrations/versions.json` - Database migrations - `styles/tokens.json` - Design tokens +- `storybook/config.json` - Storybook configuration for preview and docs **Purpose:** Reference implementation, production patterns, best practices @@ -62,6 +63,7 @@ A production-ready example demonstrating all major features. - ✅ Event-driven architecture - ✅ Background job scheduling - ✅ Dynamic form generation +- ✅ Storybook integration with context variants and controls ## Advanced Features diff --git a/schemas/package-schemas/examples/complete-package/storybook/config.json b/schemas/package-schemas/examples/complete-package/storybook/config.json new file mode 100644 index 000000000..c52c68ea1 --- /dev/null +++ b/schemas/package-schemas/examples/complete-package/storybook/config.json @@ -0,0 +1,215 @@ +{ + "$schema": "https://metabuilder.dev/schemas/package-storybook.schema.json", + "featured": true, + "title": "Sample Package Stories", + "description": "Comprehensive storybook configuration demonstrating all features", + + "stories": [ + { + "name": "UserProfile", + "render": "profile", + "description": "Display a user profile card with avatar and details", + "args": { + "userId": "sample-user-123" + }, + "argTypes": { + "userId": { + "type": "string", + "description": "The user ID to display" + }, + "showEmail": { + "type": "boolean", + "defaultValue": true, + "description": "Whether to show the email address" + } + } + }, + { + "name": "UserList", + "render": "list", + "type": "function", + "description": "Paginated list of users with search", + "context": { + "user": { + "level": 4 + } + }, + "parameters": { + "layout": "fullscreen" + } + }, + { + "name": "LoginForm", + "type": "component", + "component": "LoginForm", + "description": "Authentication form with validation", + "props": { + "redirectUrl": "/dashboard" + }, + "propControls": { + "redirectUrl": { + "type": "string" + }, + "showForgotPassword": { + "type": "boolean", + "defaultValue": true + }, + "theme": { + "type": "select", + "options": ["light", "dark", "auto"], + "defaultValue": "auto" + } + }, + "tags": ["autodocs"] + } + ], + + "renders": { + "profile": { + "description": "User profile card component", + "featured": true, + "args": { + "userId": "demo-user" + } + }, + "list": { + "description": "Paginated user list with filters" + }, + "actions.edit": { + "description": "User edit action handler" + }, + "actions.delete": { + "description": "User delete confirmation dialog" + } + }, + + "defaultContext": { + "user": { + "id": "storybook-user", + "username": "demo_user", + "level": 2, + "email": "demo@example.com" + }, + "tenant": { + "id": "demo-tenant", + "name": "Demo Organization" + }, + "nerdMode": false, + "theme": "light" + }, + + "contextVariants": [ + { + "name": "Guest User", + "description": "Unauthenticated or minimal permission user", + "context": { + "user": { + "username": "guest", + "level": 1 + } + } + }, + { + "name": "Moderator", + "description": "User with moderation permissions", + "context": { + "user": { + "username": "mod_user", + "level": 2 + } + } + }, + { + "name": "Admin", + "description": "Full admin access", + "context": { + "user": { + "username": "admin", + "level": 4 + } + } + }, + { + "name": "Admin (Debug Mode)", + "description": "Admin with nerd mode enabled", + "context": { + "user": { + "username": "admin", + "level": 4 + }, + "nerdMode": true + } + }, + { + "name": "Dark Theme", + "description": "Standard user with dark theme", + "context": { + "theme": "dark" + } + } + ], + + "scripts": { + "renderFunctions": ["render", "main", "profile", "list", "form", "page"], + "ignoredScripts": ["test", "utils", "validate", "init", "helpers"] + }, + + "argTypes": { + "theme": { + "type": "select", + "options": ["light", "dark"], + "defaultValue": "light", + "description": "Color theme for components", + "table": { + "category": "Appearance" + } + }, + "locale": { + "type": "select", + "options": ["en-US", "en-GB", "es", "fr", "de", "ja"], + "defaultValue": "en-US", + "table": { + "category": "Localization" + } + } + }, + + "parameters": { + "layout": "padded", + "backgrounds": { + "default": "light", + "values": [ + { "name": "light", "value": "#ffffff" }, + { "name": "dark", "value": "#1a1a1a" }, + { "name": "gray", "value": "#f5f5f5" } + ] + }, + "viewport": { + "defaultViewport": "responsive", + "viewports": { + "mobile": { + "name": "Mobile", + "styles": { "width": "375px", "height": "667px" } + }, + "tablet": { + "name": "Tablet", + "styles": { "width": "768px", "height": "1024px" } + }, + "desktop": { + "name": "Desktop", + "styles": { "width": "1280px", "height": "800px" } + } + } + }, + "docs": { + "description": "Sample package demonstrating all storybook features", + "source": { + "type": "code", + "language": "lua" + } + }, + "actions": { + "argTypesRegex": "^on[A-Z].*" + } + } +} diff --git a/schemas/package-schemas/examples/minimal-package/storybook/config.json b/schemas/package-schemas/examples/minimal-package/storybook/config.json new file mode 100644 index 000000000..c54ba5d4e --- /dev/null +++ b/schemas/package-schemas/examples/minimal-package/storybook/config.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://metabuilder.dev/schemas/package-storybook.schema.json", + "stories": [ + { + "name": "MainView", + "render": "main" + } + ] +} diff --git a/schemas/package-schemas/metadata_schema.json b/schemas/package-schemas/metadata_schema.json index c070bcb6b..bb57f6d86 100644 --- a/schemas/package-schemas/metadata_schema.json +++ b/schemas/package-schemas/metadata_schema.json @@ -197,17 +197,7 @@ } }, "storybook": { - "type": "object", - "description": "Storybook configuration", - "properties": { - "stories": { - "type": "array", - "description": "Story definitions", - "items": { - "$ref": "#/definitions/story" - } - } - } + "$ref": "#/definitions/storybookConfig" }, "runtime": { "type": "object", @@ -276,9 +266,210 @@ } } }, + "storybookConfig": { + "type": "object", + "description": "Storybook configuration for package preview and documentation", + "properties": { + "featured": { + "type": "boolean", + "description": "Whether this package should be featured/highlighted in Storybook", + "default": false + }, + "excludeFromDiscovery": { + "type": "boolean", + "description": "Exclude this package from auto-discovery", + "default": false + }, + "category": { + "type": "string", + "description": "Override category for Storybook organization" + }, + "title": { + "type": "string", + "description": "Display title in Storybook (defaults to package name)" + }, + "description": { + "type": "string", + "description": "Extended description shown in Storybook docs" + }, + "stories": { + "type": "array", + "description": "Story definitions", + "items": { + "$ref": "#/definitions/story" + } + }, + "renders": { + "type": "object", + "description": "Map of render function names to their metadata", + "additionalProperties": { + "$ref": "#/definitions/renderMetadata" + } + }, + "defaultContext": { + "$ref": "#/definitions/storybookContext", + "description": "Default context for this package's stories" + }, + "contextVariants": { + "type": "array", + "description": "Package-specific context variants", + "items": { + "$ref": "#/definitions/contextVariant" + } + }, + "scripts": { + "type": "object", + "description": "Script rendering configuration", + "properties": { + "renderFunctions": { + "type": "array", + "description": "Function names that produce renderable output", + "items": { "type": "string" }, + "examples": [["render", "main", "layout", "form", "page", "view"]] + }, + "ignoredScripts": { + "type": "array", + "description": "Script names to exclude from Storybook", + "items": { "type": "string" }, + "examples": [["test", "utils", "init", "validate", "actions"]] + } + } + }, + "argTypes": { + "type": "object", + "description": "Global Storybook argTypes for all stories in package", + "additionalProperties": { + "$ref": "#/definitions/control" + } + }, + "parameters": { + "type": "object", + "description": "Storybook parameters (backgrounds, viewport, etc.)", + "properties": { + "backgrounds": { + "type": "object", + "properties": { + "default": { "type": "string" }, + "values": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "value": { "type": "string" } + } + } + } + } + }, + "viewport": { + "type": "object", + "properties": { + "defaultViewport": { "type": "string" } + } + }, + "layout": { + "type": "string", + "enum": ["centered", "fullscreen", "padded"], + "description": "Story layout mode" + }, + "docs": { + "type": "object", + "properties": { + "description": { "type": "string" }, + "source": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["code", "dynamic", "auto"] + }, + "language": { "type": "string" } + } + } + } + } + }, + "additionalProperties": true + } + } + }, + "renderMetadata": { + "type": "object", + "description": "Metadata for a render function in Storybook", + "properties": { + "description": { + "type": "string", + "description": "Human-readable description of what the render produces" + }, + "featured": { + "type": "boolean", + "description": "Highlight this render in the package's stories", + "default": false + }, + "args": { + "type": "object", + "description": "Default arguments for this render function", + "additionalProperties": true + }, + "argTypes": { + "type": "object", + "description": "Storybook controls for render function arguments", + "additionalProperties": { + "$ref": "#/definitions/control" + } + } + } + }, + "storybookContext": { + "type": "object", + "description": "Context passed to Lua render functions", + "properties": { + "user": { + "type": "object", + "properties": { + "id": { "type": "string" }, + "username": { "type": "string" }, + "level": { + "type": "integer", + "minimum": 0, + "maximum": 6 + }, + "email": { "type": "string" } + } + }, + "tenant": { + "type": "object", + "properties": { + "id": { "type": "string" }, + "name": { "type": "string" } + } + }, + "nerdMode": { "type": "boolean" }, + "theme": { + "type": "string", + "enum": ["light", "dark"] + } + }, + "additionalProperties": true + }, + "contextVariant": { + "type": "object", + "required": ["name", "context"], + "properties": { + "name": { + "type": "string", + "description": "Variant display name" + }, + "context": { + "$ref": "#/definitions/storybookContext", + "description": "Context overrides for this variant" + } + } + }, "story": { "type": "object", - "required": ["name", "type"], + "required": ["name"], "properties": { "name": { "type": "string", @@ -287,7 +478,11 @@ "type": { "type": "string", "description": "Story type", - "enum": ["function", "component"] + "enum": ["function", "component", "script", "render"] + }, + "render": { + "type": "string", + "description": "Render function or script name to execute" }, "function": { "type": "string", @@ -297,14 +492,34 @@ "type": "string", "description": "Component name (for component stories)" }, + "script": { + "type": "string", + "description": "Script file path (for script stories)" + }, + "description": { + "type": "string", + "description": "Story description for documentation" + }, "args": { - "type": "array", - "description": "Function arguments" + "oneOf": [ + { + "type": "array", + "description": "Ordered function arguments" + }, + { + "type": "object", + "description": "Named function arguments" + } + ] }, "props": { "type": "object", "description": "Component props" }, + "context": { + "$ref": "#/definitions/storybookContext", + "description": "Custom context for this story" + }, "argControls": { "type": "object", "description": "Storybook controls for arguments", @@ -318,35 +533,112 @@ "additionalProperties": { "$ref": "#/definitions/control" } + }, + "parameters": { + "type": "object", + "description": "Story-specific Storybook parameters", + "additionalProperties": true + }, + "decorators": { + "type": "array", + "description": "Decorator function references", + "items": { "type": "string" } } } }, "control": { "type": "object", "required": ["type"], + "description": "Storybook control definition for interactive args", "properties": { "type": { "type": "string", - "enum": ["number", "string", "boolean", "select", "object", "array", "color", "date"] + "enum": ["number", "range", "string", "text", "boolean", "select", "multi-select", "radio", "inline-radio", "check", "inline-check", "object", "array", "color", "date", "file"], + "description": "Control type determining the UI element" + }, + "name": { + "type": "string", + "description": "Display name for the control" + }, + "description": { + "type": "string", + "description": "Help text shown for this control" }, "default": { - "description": "Default value" + "description": "Default value for the control" }, "min": { "type": "number", - "description": "Minimum value (for number)" + "description": "Minimum value (for number/range)" }, "max": { "type": "number", - "description": "Maximum value (for number)" + "description": "Maximum value (for number/range)" }, "step": { "type": "number", - "description": "Step value (for number)" + "description": "Step increment (for number/range)" }, "options": { + "oneOf": [ + { + "type": "array", + "items": { "type": "string" }, + "description": "Simple string options" + }, + { + "type": "array", + "items": { + "type": "object", + "properties": { + "label": { "type": "string" }, + "value": {} + }, + "required": ["label", "value"] + }, + "description": "Labeled options with arbitrary values" + } + ], + "description": "Options (for select/radio/check controls)" + }, + "labels": { + "type": "object", + "description": "Custom labels for option values", + "additionalProperties": { "type": "string" } + }, + "accept": { + "type": "string", + "description": "Accepted file types (for file control)", + "examples": [".png,.jpg", "image/*", "application/json"] + }, + "presetColors": { "type": "array", - "description": "Options (for select)" + "items": { "type": "string" }, + "description": "Preset color swatches (for color control)" + }, + "if": { + "type": "object", + "description": "Conditional visibility based on other arg values", + "properties": { + "arg": { "type": "string" }, + "eq": {}, + "neq": {}, + "truthy": { "type": "boolean" }, + "exists": { "type": "boolean" } + } + }, + "mapping": { + "type": "object", + "description": "Map option values to different actual values", + "additionalProperties": true + }, + "table": { + "type": "object", + "description": "Table category grouping", + "properties": { + "category": { "type": "string" }, + "subcategory": { "type": "string" } + } } } } diff --git a/schemas/package-schemas/storybook_schema.json b/schemas/package-schemas/storybook_schema.json new file mode 100644 index 000000000..1bef67d5e --- /dev/null +++ b/schemas/package-schemas/storybook_schema.json @@ -0,0 +1,533 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://metabuilder.dev/schemas/package-storybook.schema.json", + "title": "Package Storybook Configuration", + "description": "Storybook configuration for MetaBuilder packages - defines stories, controls, and rendering options", + "type": "object", + "properties": { + "$schema": { + "type": "string", + "description": "JSON Schema reference" + }, + "featured": { + "type": "boolean", + "description": "Whether this package should be featured/highlighted in Storybook", + "default": false + }, + "excludeFromDiscovery": { + "type": "boolean", + "description": "Exclude this package from auto-discovery", + "default": false + }, + "category": { + "type": "string", + "description": "Override category for Storybook organization" + }, + "title": { + "type": "string", + "description": "Display title in Storybook (defaults to package name)" + }, + "description": { + "type": "string", + "description": "Extended description shown in Storybook docs" + }, + "stories": { + "type": "array", + "description": "Story definitions", + "items": { + "$ref": "#/definitions/story" + } + }, + "renders": { + "type": "object", + "description": "Map of render function names to their metadata", + "additionalProperties": { + "$ref": "#/definitions/renderMetadata" + } + }, + "defaultContext": { + "$ref": "#/definitions/storybookContext", + "description": "Default context for this package's stories" + }, + "contextVariants": { + "type": "array", + "description": "Package-specific context variants", + "items": { + "$ref": "#/definitions/contextVariant" + } + }, + "scripts": { + "type": "object", + "description": "Script rendering configuration", + "properties": { + "renderFunctions": { + "type": "array", + "description": "Function names that produce renderable output", + "items": { "type": "string" }, + "examples": [["render", "main", "layout", "form", "page", "view"]] + }, + "ignoredScripts": { + "type": "array", + "description": "Script names to exclude from Storybook", + "items": { "type": "string" }, + "examples": [["test", "utils", "init", "validate", "actions"]] + } + } + }, + "argTypes": { + "type": "object", + "description": "Global Storybook argTypes for all stories in package", + "additionalProperties": { + "$ref": "#/definitions/control" + } + }, + "parameters": { + "type": "object", + "description": "Storybook parameters (backgrounds, viewport, etc.)", + "properties": { + "backgrounds": { + "type": "object", + "properties": { + "default": { "type": "string" }, + "values": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "value": { "type": "string" } + }, + "required": ["name", "value"] + } + } + } + }, + "viewport": { + "type": "object", + "properties": { + "defaultViewport": { "type": "string" }, + "viewports": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "styles": { + "type": "object", + "properties": { + "width": { "type": "string" }, + "height": { "type": "string" } + } + } + } + } + } + } + }, + "layout": { + "type": "string", + "enum": ["centered", "fullscreen", "padded"], + "description": "Story layout mode" + }, + "docs": { + "type": "object", + "properties": { + "description": { + "type": "string", + "description": "Documentation description" + }, + "page": { + "type": "string", + "description": "Custom docs page reference" + }, + "source": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["code", "dynamic", "auto"] + }, + "language": { "type": "string" }, + "code": { "type": "string" } + } + }, + "canvas": { + "type": "object", + "properties": { + "sourceState": { + "type": "string", + "enum": ["shown", "hidden", "none"] + } + } + } + } + }, + "actions": { + "type": "object", + "properties": { + "argTypesRegex": { + "type": "string", + "description": "Regex pattern to auto-detect action handlers" + }, + "handles": { + "type": "array", + "items": { "type": "string" } + } + } + } + }, + "additionalProperties": true + } + }, + "definitions": { + "story": { + "type": "object", + "required": ["name"], + "description": "A single story definition", + "properties": { + "name": { + "type": "string", + "description": "Story display name" + }, + "type": { + "type": "string", + "description": "Story type", + "enum": ["function", "component", "script", "render"] + }, + "render": { + "type": "string", + "description": "Render function or script name to execute" + }, + "function": { + "type": "string", + "description": "Function name (for function stories)" + }, + "component": { + "type": "string", + "description": "Component name (for component stories)" + }, + "script": { + "type": "string", + "description": "Script file path (for script stories)" + }, + "description": { + "type": "string", + "description": "Story description for documentation" + }, + "args": { + "oneOf": [ + { + "type": "array", + "description": "Ordered function arguments" + }, + { + "type": "object", + "description": "Named function arguments" + } + ] + }, + "props": { + "type": "object", + "description": "Component props" + }, + "context": { + "$ref": "#/definitions/storybookContext", + "description": "Custom context for this story" + }, + "argTypes": { + "type": "object", + "description": "Storybook argTypes for this story", + "additionalProperties": { + "$ref": "#/definitions/control" + } + }, + "argControls": { + "type": "object", + "description": "Storybook controls for arguments (alias for argTypes)", + "additionalProperties": { + "$ref": "#/definitions/control" + } + }, + "propControls": { + "type": "object", + "description": "Storybook controls for props", + "additionalProperties": { + "$ref": "#/definitions/control" + } + }, + "parameters": { + "type": "object", + "description": "Story-specific Storybook parameters", + "additionalProperties": true + }, + "decorators": { + "type": "array", + "description": "Decorator function references", + "items": { "type": "string" } + }, + "tags": { + "type": "array", + "description": "Story tags for filtering (e.g., 'autodocs', 'skip-snapshot')", + "items": { "type": "string" } + }, + "play": { + "type": "string", + "description": "Reference to play function for interaction tests" + } + } + }, + "renderMetadata": { + "type": "object", + "description": "Metadata for a render function in Storybook", + "properties": { + "description": { + "type": "string", + "description": "Human-readable description of what the render produces" + }, + "featured": { + "type": "boolean", + "description": "Highlight this render in the package's stories", + "default": false + }, + "args": { + "type": "object", + "description": "Default arguments for this render function", + "additionalProperties": true + }, + "argTypes": { + "type": "object", + "description": "Storybook controls for render function arguments", + "additionalProperties": { + "$ref": "#/definitions/control" + } + }, + "context": { + "$ref": "#/definitions/storybookContext", + "description": "Default context for this render" + } + } + }, + "storybookContext": { + "type": "object", + "description": "Context passed to Lua render functions", + "properties": { + "user": { + "type": "object", + "properties": { + "id": { "type": "string" }, + "username": { "type": "string" }, + "level": { + "type": "integer", + "minimum": 0, + "maximum": 6, + "description": "Permission level (0=Public, 1=User, 2=Moderator, 3=Admin, 4=God, 5=Supergod)" + }, + "email": { "type": "string", "format": "email" } + } + }, + "tenant": { + "type": "object", + "properties": { + "id": { "type": "string" }, + "name": { "type": "string" } + } + }, + "nerdMode": { + "type": "boolean", + "description": "Enable developer/debug mode" + }, + "theme": { + "type": "string", + "enum": ["light", "dark"], + "description": "Current theme" + }, + "locale": { + "type": "string", + "description": "Locale/language code (e.g., 'en-US')" + } + }, + "additionalProperties": true + }, + "contextVariant": { + "type": "object", + "required": ["name", "context"], + "description": "A named context variant for testing different scenarios", + "properties": { + "name": { + "type": "string", + "description": "Variant display name" + }, + "description": { + "type": "string", + "description": "What this variant tests" + }, + "context": { + "$ref": "#/definitions/storybookContext", + "description": "Context overrides for this variant" + } + } + }, + "control": { + "type": "object", + "description": "Storybook control definition for interactive args", + "properties": { + "type": { + "type": "string", + "enum": ["number", "range", "string", "text", "boolean", "select", "multi-select", "radio", "inline-radio", "check", "inline-check", "object", "array", "color", "date", "file"], + "description": "Control type determining the UI element" + }, + "name": { + "type": "string", + "description": "Display name for the control" + }, + "description": { + "type": "string", + "description": "Help text shown for this control" + }, + "defaultValue": { + "description": "Default value for the control" + }, + "min": { + "type": "number", + "description": "Minimum value (for number/range)" + }, + "max": { + "type": "number", + "description": "Maximum value (for number/range)" + }, + "step": { + "type": "number", + "description": "Step increment (for number/range)" + }, + "options": { + "oneOf": [ + { + "type": "array", + "items": { "type": "string" }, + "description": "Simple string options" + }, + { + "type": "array", + "items": { + "type": "object", + "properties": { + "label": { "type": "string" }, + "value": {} + }, + "required": ["label", "value"] + }, + "description": "Labeled options with arbitrary values" + } + ], + "description": "Options (for select/radio/check controls)" + }, + "labels": { + "type": "object", + "description": "Custom labels for option values", + "additionalProperties": { "type": "string" } + }, + "accept": { + "type": "string", + "description": "Accepted file types (for file control)", + "examples": [".png,.jpg", "image/*", "application/json"] + }, + "presetColors": { + "type": "array", + "items": { "type": "string" }, + "description": "Preset color swatches (for color control)" + }, + "if": { + "type": "object", + "description": "Conditional visibility based on other arg values", + "properties": { + "arg": { "type": "string" }, + "eq": {}, + "neq": {}, + "truthy": { "type": "boolean" }, + "exists": { "type": "boolean" } + } + }, + "mapping": { + "type": "object", + "description": "Map option values to different actual values", + "additionalProperties": true + }, + "control": { + "oneOf": [ + { "type": "boolean", "const": false }, + { "type": "string" }, + { "type": "object" } + ], + "description": "Set to false to disable control, or override control type" + }, + "table": { + "type": "object", + "description": "Table category grouping for the Controls panel", + "properties": { + "category": { "type": "string" }, + "subcategory": { "type": "string" }, + "type": { + "type": "object", + "properties": { + "summary": { "type": "string" }, + "detail": { "type": "string" } + } + }, + "defaultValue": { + "type": "object", + "properties": { + "summary": { "type": "string" }, + "detail": { "type": "string" } + } + }, + "disable": { "type": "boolean" } + } + } + } + } + }, + "examples": [ + { + "featured": true, + "title": "Dashboard Components", + "description": "Dashboard layouts, stat cards, and widgets for displaying metrics", + "stories": [ + { + "name": "StatsCard", + "render": "stats", + "description": "Single stat card with trend indicator" + }, + { + "name": "DashboardLayout", + "render": "layout", + "description": "Full dashboard grid layout" + } + ], + "renders": { + "stats.card": { + "description": "Single stat card with trend indicator", + "featured": true + }, + "layout.standard": { + "description": "Standard dashboard layout" + } + }, + "contextVariants": [ + { + "name": "Admin View", + "context": { "user": { "level": 4 }, "nerdMode": false } + }, + { + "name": "Debug Mode", + "context": { "user": { "level": 4 }, "nerdMode": true } + } + ], + "parameters": { + "layout": "fullscreen", + "backgrounds": { + "default": "light" + } + } + } + ] +}