diff --git a/json-components-registry.json b/json-components-registry.json index 1e9d707..6f49ed3 100644 --- a/json-components-registry.json +++ b/json-components-registry.json @@ -2,7 +2,7 @@ "$schema": "./schemas/json-components-registry-schema.json", "version": "2.0.0", "description": "Registry of all components in the application", - "lastUpdated": "2026-01-18T12:20:47.049Z", + "lastUpdated": "2026-01-18T13:03:47Z", "categories": { "layout": "Layout and container components", "input": "Form inputs and interactive controls", @@ -1219,6 +1219,51 @@ "status": "supported", "source": "atoms" }, + { + "type": "TableHeader", + "name": "TableHeader", + "category": "data", + "canHaveChildren": true, + "description": "Table header wrapper", + "status": "supported", + "source": "ui" + }, + { + "type": "TableBody", + "name": "TableBody", + "category": "data", + "canHaveChildren": true, + "description": "Table body wrapper", + "status": "supported", + "source": "ui" + }, + { + "type": "TableRow", + "name": "TableRow", + "category": "data", + "canHaveChildren": true, + "description": "Table row container", + "status": "supported", + "source": "ui" + }, + { + "type": "TableCell", + "name": "TableCell", + "category": "data", + "canHaveChildren": true, + "description": "Table body cell", + "status": "supported", + "source": "ui" + }, + { + "type": "TableHead", + "name": "TableHead", + "category": "data", + "canHaveChildren": true, + "description": "Table header cell", + "status": "supported", + "source": "ui" + }, { "type": "Timeline", "name": "Timeline", @@ -1880,8 +1925,8 @@ } ], "statistics": { - "total": 217, - "supported": 204, + "total": 222, + "supported": 209, "planned": 0, "jsonCompatible": 13, "maybeJsonCompatible": 0, @@ -1891,14 +1936,14 @@ "display": 31, "navigation": 15, "feedback": 23, - "data": 20, + "data": 25, "custom": 69 }, "bySource": { "atoms": 117, "molecules": 40, "organisms": 15, - "ui": 45 + "ui": 50 } } } diff --git a/src/components/JSONUIShowcase.tsx b/src/components/JSONUIShowcase.tsx index d2ec68d..cf2ed96 100644 --- a/src/components/JSONUIShowcase.tsx +++ b/src/components/JSONUIShowcase.tsx @@ -3,8 +3,9 @@ import showcaseCopy from '@/config/ui-examples/showcase.json' import dashboardExample from '@/config/ui-examples/dashboard.json' import formExample from '@/config/ui-examples/form.json' import tableExample from '@/config/ui-examples/table.json' +import listTableTimelineExample from '@/config/ui-examples/list-table-timeline.json' import settingsExample from '@/config/ui-examples/settings.json' -import { FileCode, ChartBar, ListBullets, Table, Gear } from '@phosphor-icons/react' +import { FileCode, ChartBar, ListBullets, Table, Gear, Clock } from '@phosphor-icons/react' import { ShowcaseHeader } from '@/components/json-ui-showcase/ShowcaseHeader' import { ShowcaseTabs } from '@/components/json-ui-showcase/ShowcaseTabs' import { ShowcaseFooter } from '@/components/json-ui-showcase/ShowcaseFooter' @@ -14,6 +15,7 @@ const exampleConfigs = { dashboard: dashboardExample, form: formExample, table: tableExample, + 'list-table-timeline': listTableTimelineExample, settings: settingsExample, } @@ -21,6 +23,7 @@ const exampleIcons = { ChartBar, ListBullets, Table, + Clock, Gear, } diff --git a/src/config/ui-examples/README.md b/src/config/ui-examples/README.md index f476879..b2a9587 100644 --- a/src/config/ui-examples/README.md +++ b/src/config/ui-examples/README.md @@ -63,6 +63,17 @@ A comprehensive settings panel featuring: - Separator components for visual organization - Multiple independent data sources +### 5. List/Table/Timeline Bindings (`list-table-timeline.json`) +A binding-focused layout that highlights: +- **List loops**: ListItem rows rendered from a data source +- **Data table bindings**: Columns and rows bound to JSON data +- **Timeline bindings**: Timeline items pulled from a structured array + +**Key Features Demonstrated:** +- Loop contexts with `itemVar` and `indexVar` +- Property bindings for component props +- Shared data sources across multiple components + ## How to Use These Examples 1. **View in the UI**: Navigate to the "JSON UI" page in the application to see live previews diff --git a/src/config/ui-examples/list-table-timeline.json b/src/config/ui-examples/list-table-timeline.json new file mode 100644 index 0000000..24eff6b --- /dev/null +++ b/src/config/ui-examples/list-table-timeline.json @@ -0,0 +1,232 @@ +{ + "id": "list-table-timeline-bindings", + "title": "List, Table, Timeline Bindings", + "description": "Schema patterns for binding list, table, and timeline data sources.", + "layout": { + "type": "flex", + "direction": "column", + "gap": "6", + "padding": "6", + "className": "h-full bg-background", + "children": [ + { + "id": "bindings-header", + "type": "div", + "className": "space-y-2", + "children": [ + { + "id": "bindings-title", + "type": "h1", + "className": "text-3xl font-bold", + "children": "Data Binding Patterns" + }, + { + "id": "bindings-subtitle", + "type": "p", + "className": "text-muted-foreground", + "children": "List loops, table datasets, and timeline entries driven by JSON data sources." + } + ] + }, + { + "id": "bindings-grid", + "type": "Grid", + "props": { + "columns": 2, + "gap": 6 + }, + "children": [ + { + "id": "list-binding-card", + "type": "Card", + "children": [ + { + "id": "list-binding-header", + "type": "CardHeader", + "children": [ + { + "id": "list-binding-title", + "type": "CardTitle", + "children": "List bindings" + }, + { + "id": "list-binding-description", + "type": "CardDescription", + "children": "Loop over task data and bind fields into ListItem content." + } + ] + }, + { + "id": "list-binding-content", + "type": "CardContent", + "children": [ + { + "id": "task-loop", + "type": "div", + "className": "space-y-2", + "loop": { + "source": "tasks", + "itemVar": "task", + "indexVar": "idx" + }, + "children": [ + { + "id": "task-item", + "type": "ListItem", + "bindings": { + "active": "task.active" + }, + "children": [ + { + "id": "task-item-content", + "type": "div", + "className": "flex w-full items-center justify-between", + "children": [ + { + "id": "task-title", + "type": "span", + "className": "font-medium", + "dataBinding": "task.title" + }, + { + "id": "task-owner", + "type": "span", + "className": "text-xs text-muted-foreground", + "dataBinding": "task.owner" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "id": "timeline-binding-card", + "type": "Card", + "children": [ + { + "id": "timeline-binding-header", + "type": "CardHeader", + "children": [ + { + "id": "timeline-binding-title", + "type": "CardTitle", + "children": "Timeline bindings" + }, + { + "id": "timeline-binding-description", + "type": "CardDescription", + "children": "Bind timeline items from a structured data source." + } + ] + }, + { + "id": "timeline-binding-content", + "type": "CardContent", + "children": [ + { + "id": "timeline", + "type": "Timeline", + "bindings": { + "items": "timelineEvents" + } + } + ] + } + ] + }, + { + "id": "table-binding-card", + "type": "Card", + "className": "col-span-2", + "children": [ + { + "id": "table-binding-header", + "type": "CardHeader", + "children": [ + { + "id": "table-binding-title", + "type": "CardTitle", + "children": "Table bindings" + }, + { + "id": "table-binding-description", + "type": "CardDescription", + "children": "Columns and rows come from data sources to keep tables reusable." + } + ] + }, + { + "id": "table-binding-content", + "type": "CardContent", + "children": [ + { + "id": "data-table", + "type": "DataTable", + "bindings": { + "columns": "tableColumns", + "data": "tableRows" + } + } + ] + } + ] + } + ] + } + ] + }, + "dataSources": { + "tasks": { + "type": "static", + "config": [ + { "title": "Review PR", "owner": "Avery", "active": true }, + { "title": "Sync with design", "owner": "Jordan", "active": false }, + { "title": "Publish release notes", "owner": "Riley", "active": false } + ] + }, + "timelineEvents": { + "type": "static", + "config": [ + { + "title": "Planning", + "description": "Finalize milestones and goals", + "timestamp": "Mon 9:00 AM", + "status": "completed" + }, + { + "title": "Execution", + "description": "Kick off delivery work", + "timestamp": "Tue 11:00 AM", + "status": "current" + }, + { + "title": "Review", + "description": "Collect stakeholder feedback", + "timestamp": "Wed 3:00 PM", + "status": "pending" + } + ] + }, + "tableColumns": { + "type": "static", + "config": [ + { "key": "name", "header": "Workstream" }, + { "key": "owner", "header": "Owner" }, + { "key": "status", "header": "Status" } + ] + }, + "tableRows": { + "type": "static", + "config": [ + { "name": "Discovery", "owner": "Morgan", "status": "Complete" }, + { "name": "Implementation", "owner": "Taylor", "status": "In Progress" }, + { "name": "QA Review", "owner": "Casey", "status": "Pending" } + ] + } + } +} diff --git a/src/config/ui-examples/showcase.json b/src/config/ui-examples/showcase.json index e6c380f..f1b9898 100644 --- a/src/config/ui-examples/showcase.json +++ b/src/config/ui-examples/showcase.json @@ -32,6 +32,13 @@ "icon": "Table", "configKey": "table" }, + { + "key": "bindings", + "name": "Bindings", + "description": "List, table, and timeline bindings with shared data sources", + "icon": "Clock", + "configKey": "list-table-timeline" + }, { "key": "settings", "name": "Settings", diff --git a/src/lib/component-definitions.json b/src/lib/component-definitions.json index a7c74c5..2cbcf3c 100644 --- a/src/lib/component-definitions.json +++ b/src/lib/component-definitions.json @@ -409,6 +409,14 @@ "icon": "List", "defaultProps": { "items": [], "emptyMessage": "No items" } }, + { + "type": "ListItem", + "label": "List Item", + "category": "data", + "icon": "List", + "canHaveChildren": true, + "defaultProps": { "children": "List item" } + }, { "type": "DataList", "label": "Data List", @@ -427,6 +435,46 @@ "icon": "Table", "defaultProps": { "data": [], "columns": [] } }, + { + "type": "TableHeader", + "label": "Table Header", + "category": "data", + "icon": "Table", + "canHaveChildren": true, + "defaultProps": {} + }, + { + "type": "TableBody", + "label": "Table Body", + "category": "data", + "icon": "Table", + "canHaveChildren": true, + "defaultProps": {} + }, + { + "type": "TableRow", + "label": "Table Row", + "category": "data", + "icon": "Table", + "canHaveChildren": true, + "defaultProps": {} + }, + { + "type": "TableCell", + "label": "Table Cell", + "category": "data", + "icon": "Table", + "canHaveChildren": true, + "defaultProps": { "children": "Cell" } + }, + { + "type": "TableHead", + "label": "Table Head", + "category": "data", + "icon": "Table", + "canHaveChildren": true, + "defaultProps": { "children": "Header" } + }, { "type": "DataTable", "label": "Data Table", diff --git a/src/lib/json-ui/component-registry.ts b/src/lib/json-ui/component-registry.ts index 48f50fd..b7d0c7d 100644 --- a/src/lib/json-ui/component-registry.ts +++ b/src/lib/json-ui/component-registry.ts @@ -184,6 +184,7 @@ export const atomComponents: UIComponentRegistry = { ProgressBar, DataList: (AtomComponents as Record>).DataList, DataTable: (AtomComponents as Record>).DataTable, + ListItem: (AtomComponents as Record>).ListItem, MetricCard: (AtomComponents as Record>).MetricCard, Timeline: (AtomComponents as Record>).Timeline, } diff --git a/src/types/json-ui.ts b/src/types/json-ui.ts index f7420d4..160251d 100644 --- a/src/types/json-ui.ts +++ b/src/types/json-ui.ts @@ -3,12 +3,13 @@ export type ComponentType = | 'Button' | 'Card' | 'CardHeader' | 'CardTitle' | 'CardDescription' | 'CardContent' | 'CardFooter' | 'Input' | 'TextArea' | 'Textarea' | 'Select' | 'Checkbox' | 'Radio' | 'Switch' | 'Slider' | 'NumberInput' | 'DatePicker' | 'FileUpload' | 'Badge' | 'Progress' | 'Separator' | 'Tabs' | 'TabsContent' | 'TabsList' | 'TabsTrigger' | 'Dialog' - | 'Text' | 'Heading' | 'Label' | 'List' | 'Grid' | 'Stack' | 'Flex' | 'Container' + | 'Text' | 'Heading' | 'Label' | 'List' | 'ListItem' | 'Grid' | 'Stack' | 'Flex' | 'Container' | 'Link' | 'Breadcrumb' | 'Image' | 'Avatar' | 'Code' | 'Tag' | 'Spinner' | 'Skeleton' | 'CircularProgress' | 'Divider' | 'ProgressBar' | 'Alert' | 'InfoBox' | 'EmptyState' | 'StatusBadge' | 'ErrorBadge' | 'Notification' | 'StatusIcon' - | 'Table' | 'KeyValue' | 'StatCard' | 'DataCard' | 'SearchInput' | 'ActionBar' + | 'Table' | 'TableHeader' | 'TableBody' | 'TableRow' | 'TableCell' | 'TableHead' + | 'KeyValue' | 'StatCard' | 'DataCard' | 'SearchInput' | 'ActionBar' | 'DataList' | 'DataTable' | 'MetricCard' | 'Timeline' | 'LazyBarChart' | 'LazyLineChart' | 'LazyD3BarChart' | 'SeedDataManager' | 'SaveIndicator' | 'StorageSettings'