diff --git a/src/components/atoms/ComponentPaletteItem.tsx b/src/components/atoms/ComponentPaletteItem.tsx index 99c2b48..5bc47e1 100644 --- a/src/components/atoms/ComponentPaletteItem.tsx +++ b/src/components/atoms/ComponentPaletteItem.tsx @@ -1,4 +1,4 @@ -import { ComponentDefinition } from '@/lib/component-definitions' +import { ComponentDefinition } from '@/lib/component-definition-types' import { Card } from '@/components/ui/card' import * as Icons from '@phosphor-icons/react' import { cn } from '@/lib/utils' diff --git a/src/components/atoms/ComponentTreeNode.tsx b/src/components/atoms/ComponentTreeNode.tsx index 8b42047..1655ea2 100644 --- a/src/components/atoms/ComponentTreeNode.tsx +++ b/src/components/atoms/ComponentTreeNode.tsx @@ -1,5 +1,5 @@ import { UIComponent } from '@/types/json-ui' -import { getComponentDef } from '@/lib/component-definitions' +import { getComponentDef } from '@/lib/component-definition-utils' import { cn } from '@/lib/utils' import * as Icons from '@phosphor-icons/react' diff --git a/src/components/molecules/CanvasRenderer.tsx b/src/components/molecules/CanvasRenderer.tsx index 10eecbf..e31ca54 100644 --- a/src/components/molecules/CanvasRenderer.tsx +++ b/src/components/molecules/CanvasRenderer.tsx @@ -1,6 +1,6 @@ import { UIComponent } from '@/types/json-ui' import { getUIComponent } from '@/lib/json-ui/component-registry' -import { getComponentDef } from '@/lib/component-definitions' +import { getComponentDef } from '@/lib/component-definition-utils' import { cn } from '@/lib/utils' import { createElement, ReactNode } from 'react' diff --git a/src/components/molecules/ComponentPalette.tsx b/src/components/molecules/ComponentPalette.tsx index fb60e05..1571f47 100644 --- a/src/components/molecules/ComponentPalette.tsx +++ b/src/components/molecules/ComponentPalette.tsx @@ -1,4 +1,5 @@ -import { ComponentDefinition, getCategoryComponents } from '@/lib/component-definitions' +import { ComponentDefinition } from '@/lib/component-definition-types' +import { getCategoryComponents } from '@/lib/component-definition-utils' import { ComponentPaletteItem } from '@/components/atoms/ComponentPaletteItem' import { PanelHeader, Stack } from '@/components/atoms' import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' diff --git a/src/components/molecules/PropertyEditor.tsx b/src/components/molecules/PropertyEditor.tsx index 0cbd56b..cdbe172 100644 --- a/src/components/molecules/PropertyEditor.tsx +++ b/src/components/molecules/PropertyEditor.tsx @@ -1,7 +1,7 @@ import { UIComponent } from '@/types/json-ui' import { ScrollArea } from '@/components/ui/scroll-area' import { Separator } from '@/components/ui/separator' -import { getComponentDef } from '@/lib/component-definitions' +import { getComponentDef } from '@/lib/component-definition-utils' import { PropertyEditorEmptyState } from '@/components/molecules/property-editor/PropertyEditorEmptyState' import { propertyEditorConfig } from '@/components/molecules/property-editor/propertyEditorConfig' import { PropertyEditorHeader } from '@/components/molecules/property-editor/PropertyEditorHeader' diff --git a/src/components/organisms/SchemaEditorLayout.tsx b/src/components/organisms/SchemaEditorLayout.tsx index 78a9d9f..aea9be3 100644 --- a/src/components/organisms/SchemaEditorLayout.tsx +++ b/src/components/organisms/SchemaEditorLayout.tsx @@ -1,5 +1,5 @@ import { UIComponent, PageSchema } from '@/types/json-ui' -import { ComponentDefinition } from '@/lib/component-definitions' +import { ComponentDefinition } from '@/lib/component-definition-types' import { SchemaEditorToolbar } from './SchemaEditorToolbar' import { SchemaEditorSidebar } from './SchemaEditorSidebar' import { SchemaEditorCanvas } from './SchemaEditorCanvas' diff --git a/src/components/organisms/SchemaEditorSidebar.tsx b/src/components/organisms/SchemaEditorSidebar.tsx index 1ffb087..dfba600 100644 --- a/src/components/organisms/SchemaEditorSidebar.tsx +++ b/src/components/organisms/SchemaEditorSidebar.tsx @@ -1,5 +1,5 @@ import { ComponentPalette } from '@/components/molecules/ComponentPalette' -import { ComponentDefinition } from '@/lib/component-definitions' +import { ComponentDefinition } from '@/lib/component-definition-types' interface SchemaEditorSidebarProps { onDragStart: (component: ComponentDefinition, e: React.DragEvent) => void diff --git a/src/components/schema-editor/SchemaEditorWorkspace.tsx b/src/components/schema-editor/SchemaEditorWorkspace.tsx index 119ba50..c64d9a1 100644 --- a/src/components/schema-editor/SchemaEditorWorkspace.tsx +++ b/src/components/schema-editor/SchemaEditorWorkspace.tsx @@ -2,7 +2,7 @@ import { useSchemaEditor } from '@/hooks/ui/use-schema-editor' import { useDragDrop } from '@/hooks/ui/use-drag-drop' import { useJsonExport } from '@/hooks/ui/use-json-export' import { SchemaEditorLayout } from '@/components/organisms' -import { ComponentDefinition } from '@/lib/component-definitions' +import { ComponentDefinition } from '@/lib/component-definition-types' import { UIComponent, PageSchema } from '@/types/json-ui' import { toast } from 'sonner' import { schemaEditorConfig } from '@/components/schema-editor/schemaEditorConfig' diff --git a/src/lib/component-definition-types.ts b/src/lib/component-definition-types.ts new file mode 100644 index 0000000..ead5aea --- /dev/null +++ b/src/lib/component-definition-types.ts @@ -0,0 +1,27 @@ +import { ComponentType } from '@/types/json-ui' + +export interface ComponentDefinition { + type: ComponentType + label: string + category: 'layout' | 'input' | 'display' | 'navigation' | 'feedback' | 'data' | 'custom' + icon: string + defaultProps?: Record + canHaveChildren?: boolean + props?: ComponentPropDefinition[] + events?: ComponentEventDefinition[] +} + +export interface ComponentPropDefinition { + name: string + type: string + description: string + required?: boolean + defaultValue?: string + options?: string[] + supportsBinding?: boolean +} + +export interface ComponentEventDefinition { + name: string + description: string +} diff --git a/src/lib/component-definition-utils.ts b/src/lib/component-definition-utils.ts new file mode 100644 index 0000000..9796af7 --- /dev/null +++ b/src/lib/component-definition-utils.ts @@ -0,0 +1,13 @@ +import componentDefinitionsData from '@/lib/component-definitions.json' +import { ComponentDefinition } from '@/lib/component-definition-types' +import { ComponentType } from '@/types/json-ui' + +export const componentDefinitions = componentDefinitionsData as ComponentDefinition[] + +export function getCategoryComponents(category: string): ComponentDefinition[] { + return componentDefinitions.filter(c => c.category === category) +} + +export function getComponentDef(type: ComponentType): ComponentDefinition | undefined { + return componentDefinitions.find(c => c.type === type) +} diff --git a/src/lib/component-definitions.json b/src/lib/component-definitions.json new file mode 100644 index 0000000..a0ad390 --- /dev/null +++ b/src/lib/component-definitions.json @@ -0,0 +1,476 @@ +[ + { + "type": "div", + "label": "Container", + "category": "layout", + "icon": "Square", + "canHaveChildren": true, + "defaultProps": { "className": "p-4 space-y-2" } + }, + { + "type": "section", + "label": "Section", + "category": "layout", + "icon": "SquaresFour", + "canHaveChildren": true, + "defaultProps": { "className": "space-y-4" } + }, + { + "type": "Grid", + "label": "Grid", + "category": "layout", + "icon": "GridFour", + "canHaveChildren": true, + "defaultProps": { "columns": 2, "gap": 4 } + }, + { + "type": "Stack", + "label": "Stack", + "category": "layout", + "icon": "Stack", + "canHaveChildren": true, + "defaultProps": { "direction": "vertical", "gap": 2 } + }, + { + "type": "Flex", + "label": "Flex", + "category": "layout", + "icon": "ArrowsOutLineHorizontal", + "canHaveChildren": true, + "defaultProps": { "direction": "row", "gap": 2 } + }, + { + "type": "Container", + "label": "Container", + "category": "layout", + "icon": "Rectangle", + "canHaveChildren": true, + "defaultProps": { "maxWidth": "lg" } + }, + { + "type": "Card", + "label": "Card", + "category": "layout", + "icon": "Rectangle", + "canHaveChildren": true, + "defaultProps": { "className": "p-4" } + }, + { + "type": "Button", + "label": "Button", + "category": "input", + "icon": "Circle", + "canHaveChildren": true, + "defaultProps": { "children": "Click me", "variant": "default" } + }, + { + "type": "Input", + "label": "Input", + "category": "input", + "icon": "TextT", + "defaultProps": { "placeholder": "Enter text..." } + }, + { + "type": "TextArea", + "label": "TextArea", + "category": "input", + "icon": "TextAlignLeft", + "defaultProps": { "placeholder": "Enter text...", "rows": 4 } + }, + { + "type": "Select", + "label": "Select", + "category": "input", + "icon": "CaretDown", + "defaultProps": { "placeholder": "Choose option..." } + }, + { + "type": "Checkbox", + "label": "Checkbox", + "category": "input", + "icon": "CheckSquare", + "defaultProps": {} + }, + { + "type": "Radio", + "label": "Radio", + "category": "input", + "icon": "Circle", + "defaultProps": {} + }, + { + "type": "Switch", + "label": "Switch", + "category": "input", + "icon": "ToggleLeft", + "defaultProps": {} + }, + { + "type": "Slider", + "label": "Slider", + "category": "input", + "icon": "SlidersHorizontal", + "defaultProps": { "min": 0, "max": 100, "value": 50 } + }, + { + "type": "NumberInput", + "label": "Number Input", + "category": "input", + "icon": "NumberCircleOne", + "defaultProps": { "placeholder": "0", "min": 0 } + }, + { + "type": "Heading", + "label": "Heading", + "category": "display", + "icon": "TextHOne", + "canHaveChildren": true, + "defaultProps": { "level": 1, "children": "Heading" } + }, + { + "type": "Text", + "label": "Text", + "category": "display", + "icon": "Paragraph", + "canHaveChildren": true, + "defaultProps": { "children": "Text content" } + }, + { + "type": "Badge", + "label": "Badge", + "category": "display", + "icon": "Tag", + "canHaveChildren": true, + "defaultProps": { "children": "Badge", "variant": "default" } + }, + { + "type": "Tag", + "label": "Tag", + "category": "display", + "icon": "Tag", + "canHaveChildren": true, + "defaultProps": { "children": "Tag" } + }, + { + "type": "Code", + "label": "Code", + "category": "display", + "icon": "Code", + "canHaveChildren": true, + "defaultProps": { "children": "code" } + }, + { + "type": "Image", + "label": "Image", + "category": "display", + "icon": "Image", + "defaultProps": { "src": "", "alt": "Image" } + }, + { + "type": "Avatar", + "label": "Avatar", + "category": "display", + "icon": "UserCircle", + "defaultProps": { "src": "", "alt": "Avatar" } + }, + { + "type": "Progress", + "label": "Progress", + "category": "display", + "icon": "CircleNotch", + "defaultProps": { "value": 50 } + }, + { + "type": "Spinner", + "label": "Spinner", + "category": "display", + "icon": "CircleNotch", + "defaultProps": { "size": "md" } + }, + { + "type": "Skeleton", + "label": "Skeleton", + "category": "display", + "icon": "Rectangle", + "defaultProps": { "className": "h-4 w-full" } + }, + { + "type": "Separator", + "label": "Separator", + "category": "display", + "icon": "Minus", + "defaultProps": {} + }, + { + "type": "Link", + "label": "Link", + "category": "navigation", + "icon": "Link", + "canHaveChildren": true, + "defaultProps": { "href": "#", "children": "Link" } + }, + { + "type": "Breadcrumb", + "label": "Breadcrumb", + "category": "navigation", + "icon": "CaretRight", + "canHaveChildren": false, + "defaultProps": { + "items": [ + { "label": "Home", "href": "/" }, + { "label": "Current" } + ] + } + }, + { + "type": "Alert", + "label": "Alert", + "category": "feedback", + "icon": "Info", + "canHaveChildren": true, + "defaultProps": { "variant": "info", "children": "Alert message" } + }, + { + "type": "InfoBox", + "label": "Info Box", + "category": "feedback", + "icon": "Info", + "canHaveChildren": true, + "defaultProps": { "type": "info", "children": "Information" } + }, + { + "type": "EmptyState", + "label": "Empty State", + "category": "feedback", + "icon": "FolderOpen", + "canHaveChildren": true, + "defaultProps": { "message": "No items found" } + }, + { + "type": "StatusBadge", + "label": "Status Badge", + "category": "feedback", + "icon": "Circle", + "defaultProps": { "status": "active", "children": "Active" } + }, + { + "type": "ErrorBadge", + "label": "Error Badge", + "category": "feedback", + "icon": "WarningCircle", + "defaultProps": { "count": 3, "variant": "destructive", "size": "md" }, + "props": [ + { + "name": "count", + "type": "number", + "description": "Number of errors to display. Hidden when set to 0.", + "required": true, + "supportsBinding": true + }, + { + "name": "variant", + "type": "string", + "description": "Visual variant for the badge.", + "defaultValue": "destructive", + "options": ["default", "destructive"] + }, + { + "name": "size", + "type": "string", + "description": "Badge size.", + "defaultValue": "md", + "options": ["sm", "md"] + } + ] + }, + { + "type": "Notification", + "label": "Notification", + "category": "feedback", + "icon": "Info", + "defaultProps": { "type": "info", "title": "Notification", "message": "Details go here." }, + "props": [ + { + "name": "type", + "type": "string", + "description": "Notification style variant.", + "required": true, + "options": ["info", "success", "warning", "error"] + }, + { + "name": "title", + "type": "string", + "description": "Primary notification title.", + "required": true, + "supportsBinding": true + }, + { + "name": "message", + "type": "string", + "description": "Optional supporting message text.", + "supportsBinding": true + }, + { + "name": "className", + "type": "string", + "description": "Optional custom classes for spacing or layout tweaks." + } + ], + "events": [ + { + "name": "onClose", + "description": "Fires when the close button is clicked. Bind to dismiss or trigger an action." + } + ] + }, + { + "type": "StatusIcon", + "label": "Status Icon", + "category": "feedback", + "icon": "CheckCircle", + "defaultProps": { "type": "saved", "size": 14, "animate": false }, + "props": [ + { + "name": "type", + "type": "string", + "description": "Status icon style.", + "required": true, + "supportsBinding": true, + "options": ["saved", "synced"] + }, + { + "name": "size", + "type": "number", + "description": "Icon size in pixels.", + "defaultValue": "14", + "supportsBinding": true + }, + { + "name": "animate", + "type": "boolean", + "description": "Applies entry animation when true.", + "defaultValue": "false", + "supportsBinding": true + } + ] + }, + { + "type": "List", + "label": "List", + "category": "data", + "icon": "List", + "defaultProps": { "items": [], "emptyMessage": "No items" } + }, + { + "type": "DataList", + "label": "Data List", + "category": "data", + "icon": "List", + "defaultProps": { + "items": ["Daily summary", "New signups", "Pending approvals"], + "emptyMessage": "No updates", + "itemClassName": "rounded-md border border-border bg-card/50 px-4 py-2" + } + }, + { + "type": "Table", + "label": "Table", + "category": "data", + "icon": "Table", + "defaultProps": { "data": [], "columns": [] } + }, + { + "type": "DataTable", + "label": "Data Table", + "category": "data", + "icon": "Table", + "defaultProps": { + "columns": [ + { "key": "name", "header": "Name" }, + { "key": "status", "header": "Status" }, + { "key": "owner", "header": "Owner" } + ], + "data": [ + { "name": "Launch Plan", "status": "In Progress", "owner": "Avery" }, + { "name": "Design Review", "status": "Scheduled", "owner": "Jordan" }, + { "name": "QA Checklist", "status": "Done", "owner": "Riley" } + ], + "emptyMessage": "No records available" + } + }, + { + "type": "KeyValue", + "label": "Key Value", + "category": "data", + "icon": "Equals", + "defaultProps": { "label": "Key", "value": "Value" } + }, + { + "type": "StatCard", + "label": "Stat Card", + "category": "data", + "icon": "ChartBar", + "defaultProps": { "title": "Metric", "value": "0" } + }, + { + "type": "MetricCard", + "label": "Metric Card", + "category": "data", + "icon": "ChartBar", + "defaultProps": { + "label": "Active Users", + "value": "1,248", + "trend": { "value": 12.4, "direction": "up" } + } + }, + { + "type": "Timeline", + "label": "Timeline", + "category": "data", + "icon": "Clock", + "defaultProps": { + "items": [ + { + "title": "Planning", + "description": "Finalize milestones", + "timestamp": "Mon 9:00 AM", + "status": "completed" + }, + { + "title": "Execution", + "description": "Kick off delivery", + "timestamp": "Tue 11:00 AM", + "status": "current" + }, + { + "title": "Review", + "description": "Collect feedback", + "timestamp": "Wed 3:00 PM", + "status": "pending" + } + ] + } + }, + { + "type": "DataCard", + "label": "Data Card", + "category": "custom", + "icon": "ChartBar", + "defaultProps": { "title": "Metric", "value": "100", "icon": "TrendUp" } + }, + { + "type": "SearchInput", + "label": "Search Input", + "category": "custom", + "icon": "MagnifyingGlass", + "defaultProps": { "placeholder": "Search..." } + }, + { + "type": "ActionBar", + "label": "Action Bar", + "category": "custom", + "icon": "Toolbox", + "canHaveChildren": true, + "defaultProps": { "actions": [] } + } +] diff --git a/src/lib/component-definitions.ts b/src/lib/component-definitions.ts deleted file mode 100644 index c607634..0000000 --- a/src/lib/component-definitions.ts +++ /dev/null @@ -1,519 +0,0 @@ -import { ComponentType } from '@/types/json-ui' - -export interface ComponentDefinition { - type: ComponentType - label: string - category: 'layout' | 'input' | 'display' | 'navigation' | 'feedback' | 'data' | 'custom' - icon: string - defaultProps?: Record - canHaveChildren?: boolean - props?: ComponentPropDefinition[] - events?: ComponentEventDefinition[] -} - -export interface ComponentPropDefinition { - name: string - type: string - description: string - required?: boolean - defaultValue?: string - options?: string[] - supportsBinding?: boolean -} - -export interface ComponentEventDefinition { - name: string - description: string -} - -export const componentDefinitions: ComponentDefinition[] = [ - // Layout Components - { - type: 'div', - label: 'Container', - category: 'layout', - icon: 'Square', - canHaveChildren: true, - defaultProps: { className: 'p-4 space-y-2' } - }, - { - type: 'section', - label: 'Section', - category: 'layout', - icon: 'SquaresFour', - canHaveChildren: true, - defaultProps: { className: 'space-y-4' } - }, - { - type: 'Grid', - label: 'Grid', - category: 'layout', - icon: 'GridFour', - canHaveChildren: true, - defaultProps: { columns: 2, gap: 4 } - }, - { - type: 'Stack', - label: 'Stack', - category: 'layout', - icon: 'Stack', - canHaveChildren: true, - defaultProps: { direction: 'vertical', gap: 2 } - }, - { - type: 'Flex', - label: 'Flex', - category: 'layout', - icon: 'ArrowsOutLineHorizontal', - canHaveChildren: true, - defaultProps: { direction: 'row', gap: 2 } - }, - { - type: 'Container', - label: 'Container', - category: 'layout', - icon: 'Rectangle', - canHaveChildren: true, - defaultProps: { maxWidth: 'lg' } - }, - { - type: 'Card', - label: 'Card', - category: 'layout', - icon: 'Rectangle', - canHaveChildren: true, - defaultProps: { className: 'p-4' } - }, - // Input Components - { - type: 'Button', - label: 'Button', - category: 'input', - icon: 'Circle', - canHaveChildren: true, - defaultProps: { children: 'Click me', variant: 'default' } - }, - { - type: 'Input', - label: 'Input', - category: 'input', - icon: 'TextT', - defaultProps: { placeholder: 'Enter text...' } - }, - { - type: 'TextArea', - label: 'TextArea', - category: 'input', - icon: 'TextAlignLeft', - defaultProps: { placeholder: 'Enter text...', rows: 4 } - }, - { - type: 'Select', - label: 'Select', - category: 'input', - icon: 'CaretDown', - defaultProps: { placeholder: 'Choose option...' } - }, - { - type: 'Checkbox', - label: 'Checkbox', - category: 'input', - icon: 'CheckSquare', - defaultProps: {} - }, - { - type: 'Radio', - label: 'Radio', - category: 'input', - icon: 'Circle', - defaultProps: {} - }, - { - type: 'Switch', - label: 'Switch', - category: 'input', - icon: 'ToggleLeft', - defaultProps: {} - }, - { - type: 'Slider', - label: 'Slider', - category: 'input', - icon: 'SlidersHorizontal', - defaultProps: { min: 0, max: 100, value: 50 } - }, - { - type: 'NumberInput', - label: 'Number Input', - category: 'input', - icon: 'NumberCircleOne', - defaultProps: { placeholder: '0', min: 0 } - }, - // Display Components - { - type: 'Heading', - label: 'Heading', - category: 'display', - icon: 'TextHOne', - canHaveChildren: true, - defaultProps: { level: 1, children: 'Heading' } - }, - { - type: 'Text', - label: 'Text', - category: 'display', - icon: 'Paragraph', - canHaveChildren: true, - defaultProps: { children: 'Text content' } - }, - { - type: 'Badge', - label: 'Badge', - category: 'display', - icon: 'Tag', - canHaveChildren: true, - defaultProps: { children: 'Badge', variant: 'default' } - }, - { - type: 'Tag', - label: 'Tag', - category: 'display', - icon: 'Tag', - canHaveChildren: true, - defaultProps: { children: 'Tag' } - }, - { - type: 'Code', - label: 'Code', - category: 'display', - icon: 'Code', - canHaveChildren: true, - defaultProps: { children: 'code' } - }, - { - type: 'Image', - label: 'Image', - category: 'display', - icon: 'Image', - defaultProps: { src: '', alt: 'Image' } - }, - { - type: 'Avatar', - label: 'Avatar', - category: 'display', - icon: 'UserCircle', - defaultProps: { src: '', alt: 'Avatar' } - }, - { - type: 'Progress', - label: 'Progress', - category: 'display', - icon: 'CircleNotch', - defaultProps: { value: 50 } - }, - { - type: 'Spinner', - label: 'Spinner', - category: 'display', - icon: 'CircleNotch', - defaultProps: { size: 'md' } - }, - { - type: 'Skeleton', - label: 'Skeleton', - category: 'display', - icon: 'Rectangle', - defaultProps: { className: 'h-4 w-full' } - }, - { - type: 'Separator', - label: 'Separator', - category: 'display', - icon: 'Minus', - defaultProps: {} - }, - // Navigation Components - { - type: 'Link', - label: 'Link', - category: 'navigation', - icon: 'Link', - canHaveChildren: true, - defaultProps: { href: '#', children: 'Link' } - }, - { - type: 'Breadcrumb', - label: 'Breadcrumb', - category: 'navigation', - icon: 'CaretRight', - canHaveChildren: false, - defaultProps: { - items: [ - { label: 'Home', href: '/' }, - { label: 'Current' } - ] - } - }, - // Feedback Components - { - type: 'Alert', - label: 'Alert', - category: 'feedback', - icon: 'Info', - canHaveChildren: true, - defaultProps: { variant: 'info', children: 'Alert message' } - }, - { - type: 'InfoBox', - label: 'Info Box', - category: 'feedback', - icon: 'Info', - canHaveChildren: true, - defaultProps: { type: 'info', children: 'Information' } - }, - { - type: 'EmptyState', - label: 'Empty State', - category: 'feedback', - icon: 'FolderOpen', - canHaveChildren: true, - defaultProps: { message: 'No items found' } - }, - { - type: 'StatusBadge', - label: 'Status Badge', - category: 'feedback', - icon: 'Circle', - defaultProps: { status: 'active', children: 'Active' } - }, - { - type: 'ErrorBadge', - label: 'Error Badge', - category: 'feedback', - icon: 'WarningCircle', - defaultProps: { count: 3, variant: 'destructive', size: 'md' }, - props: [ - { - name: 'count', - type: 'number', - description: 'Number of errors to display. Hidden when set to 0.', - required: true, - supportsBinding: true, - }, - { - name: 'variant', - type: 'string', - description: 'Visual variant for the badge.', - defaultValue: 'destructive', - options: ['default', 'destructive'], - }, - { - name: 'size', - type: 'string', - description: 'Badge size.', - defaultValue: 'md', - options: ['sm', 'md'], - }, - ], - }, - { - type: 'Notification', - label: 'Notification', - category: 'feedback', - icon: 'Info', - defaultProps: { type: 'info', title: 'Notification', message: 'Details go here.' }, - props: [ - { - name: 'type', - type: 'string', - description: 'Notification style variant.', - required: true, - options: ['info', 'success', 'warning', 'error'], - }, - { - name: 'title', - type: 'string', - description: 'Primary notification title.', - required: true, - supportsBinding: true, - }, - { - name: 'message', - type: 'string', - description: 'Optional supporting message text.', - supportsBinding: true, - }, - { - name: 'className', - type: 'string', - description: 'Optional custom classes for spacing or layout tweaks.', - }, - ], - events: [ - { - name: 'onClose', - description: 'Fires when the close button is clicked. Bind to dismiss or trigger an action.', - }, - ], - }, - { - type: 'StatusIcon', - label: 'Status Icon', - category: 'feedback', - icon: 'CheckCircle', - defaultProps: { type: 'saved', size: 14, animate: false }, - props: [ - { - name: 'type', - type: 'string', - description: 'Status icon style.', - required: true, - supportsBinding: true, - options: ['saved', 'synced'], - }, - { - name: 'size', - type: 'number', - description: 'Icon size in pixels.', - defaultValue: '14', - supportsBinding: true, - }, - { - name: 'animate', - type: 'boolean', - description: 'Applies entry animation when true.', - defaultValue: 'false', - supportsBinding: true, - }, - ], - }, - // Data Components - { - type: 'List', - label: 'List', - category: 'data', - icon: 'List', - defaultProps: { items: [], emptyMessage: 'No items' } - }, - { - type: 'DataList', - label: 'Data List', - category: 'data', - icon: 'List', - defaultProps: { - items: ['Daily summary', 'New signups', 'Pending approvals'], - emptyMessage: 'No updates', - itemClassName: 'rounded-md border border-border bg-card/50 px-4 py-2' - } - }, - { - type: 'Table', - label: 'Table', - category: 'data', - icon: 'Table', - defaultProps: { data: [], columns: [] } - }, - { - type: 'DataTable', - label: 'Data Table', - category: 'data', - icon: 'Table', - defaultProps: { - columns: [ - { key: 'name', header: 'Name' }, - { key: 'status', header: 'Status' }, - { key: 'owner', header: 'Owner' }, - ], - data: [ - { name: 'Launch Plan', status: 'In Progress', owner: 'Avery' }, - { name: 'Design Review', status: 'Scheduled', owner: 'Jordan' }, - { name: 'QA Checklist', status: 'Done', owner: 'Riley' }, - ], - emptyMessage: 'No records available', - } - }, - { - type: 'KeyValue', - label: 'Key Value', - category: 'data', - icon: 'Equals', - defaultProps: { label: 'Key', value: 'Value' } - }, - { - type: 'StatCard', - label: 'Stat Card', - category: 'data', - icon: 'ChartBar', - defaultProps: { title: 'Metric', value: '0' } - }, - { - type: 'MetricCard', - label: 'Metric Card', - category: 'data', - icon: 'ChartBar', - defaultProps: { - label: 'Active Users', - value: '1,248', - trend: { value: 12.4, direction: 'up' }, - } - }, - { - type: 'Timeline', - label: 'Timeline', - category: 'data', - icon: 'Clock', - defaultProps: { - items: [ - { - title: 'Planning', - description: 'Finalize milestones', - timestamp: 'Mon 9:00 AM', - status: 'completed', - }, - { - title: 'Execution', - description: 'Kick off delivery', - timestamp: 'Tue 11:00 AM', - status: 'current', - }, - { - title: 'Review', - description: 'Collect feedback', - timestamp: 'Wed 3:00 PM', - status: 'pending', - }, - ], - } - }, - // Custom Components - { - type: 'DataCard', - label: 'Data Card', - category: 'custom', - icon: 'ChartBar', - defaultProps: { title: 'Metric', value: '100', icon: 'TrendUp' } - }, - { - type: 'SearchInput', - label: 'Search Input', - category: 'custom', - icon: 'MagnifyingGlass', - defaultProps: { placeholder: 'Search...' } - }, - { - type: 'ActionBar', - label: 'Action Bar', - category: 'custom', - icon: 'Toolbox', - canHaveChildren: true, - defaultProps: { actions: [] } - }, -] - -export function getCategoryComponents(category: string): ComponentDefinition[] { - return componentDefinitions.filter(c => c.category === category) -} - -export function getComponentDef(type: ComponentType): ComponentDefinition | undefined { - return componentDefinitions.find(c => c.type === type) -}