Merge pull request #121 from johndoe6345789/codex/change-component-definitions.ts-to-json-file

Convert component definitions to JSON with typed helpers
This commit is contained in:
2026-01-18 11:53:39 +00:00
committed by GitHub
12 changed files with 525 additions and 527 deletions

View File

@@ -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'

View File

@@ -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'

View File

@@ -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'

View File

@@ -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'

View File

@@ -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'

View File

@@ -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'

View File

@@ -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

View File

@@ -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'

View File

@@ -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<string, any>
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
}

View File

@@ -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)
}

View File

@@ -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": [] }
}
]

View File

@@ -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<string, any>
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)
}