Merge branch 'main' into codex/identify-components-for-hooks-and-context

This commit is contained in:
2026-01-18 13:05:37 +00:00
committed by GitHub
31 changed files with 2691 additions and 373 deletions

View File

@@ -1,6 +1,9 @@
export { AppBranding } from './AppBranding'
export { Breadcrumb } from './Breadcrumb'
export { CanvasRenderer } from './CanvasRenderer'
export { CodeExplanationDialog } from './CodeExplanationDialog'
export { ComponentPalette } from './ComponentPalette'
export { ComponentTree } from './ComponentTree'
export { EditorActions } from './EditorActions'
export { EditorToolbar } from './EditorToolbar'
export { EmptyEditorState } from './EmptyEditorState'
@@ -18,8 +21,11 @@ export { MonacoEditorPanel } from './MonacoEditorPanel'
export { NavigationGroupHeader } from './NavigationGroupHeader'
export { NavigationItem } from './NavigationItem'
export { PageHeaderContent } from './PageHeaderContent'
export { PropertyEditor } from './PropertyEditor'
export { SaveIndicator } from './SaveIndicator'
export { SeedDataManager } from './SeedDataManager'
export { SearchBar } from './SearchBar'
export { StatCard } from './StatCard'
export { ToolbarButton } from './ToolbarButton'
export { TreeCard } from './TreeCard'
export { TreeFormDialog } from './TreeFormDialog'
@@ -31,4 +37,3 @@ export { DataSourceCard } from './DataSourceCard'
export { BindingEditor } from './BindingEditor'
export { DataSourceEditorDialog } from './DataSourceEditorDialog'
export { ComponentBindingDialog } from './ComponentBindingDialog'

View File

@@ -2,6 +2,7 @@ export { NavigationMenu } from './NavigationMenu'
export { PageHeader } from './PageHeader'
export { ToolbarActions } from './ToolbarActions'
export { AppHeader } from './AppHeader'
export { DataSourceManager } from './DataSourceManager'
export { TreeListPanel } from './TreeListPanel'
export { SchemaEditorToolbar } from './SchemaEditorToolbar'
export { SchemaEditorSidebar } from './SchemaEditorSidebar'
@@ -11,3 +12,4 @@ export { SchemaEditorLayout } from './SchemaEditorLayout'
export { EmptyCanvasState } from './EmptyCanvasState'
export { SchemaEditorStatusBar } from './SchemaEditorStatusBar'
export { SchemaCodeViewer } from './SchemaCodeViewer'
export { JSONUIShowcase } from './JSONUIShowcase'

View File

@@ -185,14 +185,20 @@
"label": "Progress Bar",
"category": "display",
"icon": "ChartBar",
"defaultProps": { "value": 65, "size": "md", "variant": "default", "showLabel": false }
"defaultProps": {
"value": 65,
"max": 100,
"size": "md",
"variant": "default",
"showLabel": false
}
},
{
"type": "CircularProgress",
"label": "Circular Progress",
"category": "display",
"icon": "CircleNotch",
"defaultProps": { "value": 65, "size": "md", "showLabel": true }
"defaultProps": { "value": 65, "max": 100, "size": "md", "showLabel": true }
},
{
"type": "Spinner",
@@ -220,7 +226,7 @@
"label": "Divider",
"category": "display",
"icon": "Minus",
"defaultProps": { "orientation": "horizontal", "decorative": true }
"defaultProps": { "orientation": "horizontal", "decorative": true, "className": "" }
},
{
"type": "Link",
@@ -574,5 +580,480 @@
"isExporting": false,
"isImporting": false
}
},
{
"type": "CodeExplanationDialog",
"label": "Code Explanation Dialog",
"category": "layout",
"icon": "Info",
"defaultProps": {
"open": false,
"fileName": "example.ts",
"explanation": "Explain this code...",
"isLoading": false
}
},
{
"type": "ComponentBindingDialog",
"label": "Component Binding Dialog",
"category": "layout",
"icon": "Link",
"defaultProps": {
"open": false,
"component": null,
"dataSources": []
}
},
{
"type": "DataSourceCard",
"label": "Data Source Card",
"category": "layout",
"icon": "Database",
"defaultProps": {
"dataSource": {
"id": "source",
"type": "static",
"defaultValue": ""
},
"dependents": []
}
},
{
"type": "DataSourceEditorDialog",
"label": "Data Source Editor Dialog",
"category": "layout",
"icon": "Database",
"defaultProps": {
"open": false,
"dataSource": null,
"allDataSources": []
}
},
{
"type": "TreeCard",
"label": "Tree Card",
"category": "layout",
"icon": "Tree",
"defaultProps": {
"tree": {
"id": "tree-1",
"name": "Main Tree",
"description": "Primary UI tree",
"rootNodes": [],
"createdAt": 0,
"updatedAt": 0
},
"isSelected": false,
"disableDelete": false
}
},
{
"type": "TreeFormDialog",
"label": "Tree Form Dialog",
"category": "layout",
"icon": "Tree",
"defaultProps": {
"open": false,
"title": "Create Tree",
"description": "Add a new component tree.",
"name": "",
"treeDescription": "",
"submitLabel": "Save"
}
},
{
"type": "ToolbarButton",
"label": "Toolbar Button",
"category": "input",
"icon": "Button",
"defaultProps": {
"label": "Action",
"variant": "outline",
"disabled": false
}
},
{
"type": "SchemaCodeViewer",
"label": "Schema Code Viewer",
"category": "display",
"icon": "Code",
"defaultProps": {
"components": [],
"schema": {}
}
},
{
"type": "FileTabs",
"label": "File Tabs",
"category": "navigation",
"icon": "Tabs",
"defaultProps": {
"files": [],
"activeFileId": null
}
},
{
"type": "NavigationItem",
"label": "Navigation Item",
"category": "navigation",
"icon": "List",
"defaultProps": {
"label": "Overview",
"isActive": false,
"badge": 0
}
},
{
"type": "NavigationMenu",
"label": "Navigation Menu",
"category": "navigation",
"icon": "Sidebar",
"defaultProps": {
"activeTab": "overview",
"featureToggles": {
"codeEditor": false,
"models": false,
"components": false,
"componentTrees": false,
"workflows": false,
"lambdas": false,
"styling": false,
"flaskApi": false,
"playwright": false,
"storybook": false,
"unitTests": false,
"errorRepair": false,
"documentation": false,
"sassStyles": false,
"faviconDesigner": false,
"ideaCloud": false,
"schemaEditor": false,
"dataBinding": false
},
"errorCount": 0
}
},
{
"type": "EmptyCanvasState",
"label": "Empty Canvas State",
"category": "feedback",
"icon": "FolderOpen",
"defaultProps": {}
},
{
"type": "SchemaEditorStatusBar",
"label": "Schema Editor Status Bar",
"category": "feedback",
"icon": "Info",
"defaultProps": {
"componentCount": 0,
"selectedComponentType": "",
"hasUnsavedChanges": false
}
},
{
"type": "DataSourceManager",
"label": "Data Source Manager",
"category": "data",
"icon": "Database",
"defaultProps": {
"dataSources": []
}
},
{
"type": "TreeListHeader",
"label": "Tree List Header",
"category": "data",
"icon": "Tree",
"defaultProps": {
"hasSelectedTree": false
}
},
{
"type": "TreeListPanel",
"label": "Tree List Panel",
"category": "data",
"icon": "Tree",
"defaultProps": {
"trees": [],
"selectedTreeId": null
}
},
{
"type": "AppHeader",
"label": "App Header",
"category": "custom",
"icon": "Layout",
"defaultProps": {
"activeTab": "overview",
"featureToggles": {
"codeEditor": false,
"models": false,
"components": false,
"componentTrees": false,
"workflows": false,
"lambdas": false,
"styling": false,
"flaskApi": false,
"playwright": false,
"storybook": false,
"unitTests": false,
"errorRepair": false,
"documentation": false,
"sassStyles": false,
"faviconDesigner": false,
"ideaCloud": false,
"schemaEditor": false,
"dataBinding": false
},
"errorCount": 0,
"lastSaved": null,
"currentProject": {
"name": "Demo Project",
"files": [],
"models": [],
"components": [],
"componentTrees": [],
"workflows": [],
"lambdas": [],
"theme": {
"variants": [
{
"id": "default",
"name": "Default",
"colors": {
"primary": "#4f46e5",
"secondary": "#64748b",
"accent": "#0ea5e9",
"muted": "#f1f5f9",
"background": "#ffffff",
"surface": "#ffffff",
"text": "#0f172a",
"textSecondary": "#475569",
"border": "#e2e8f0",
"customColors": {}
}
}
],
"activeVariantId": "default",
"fontFamily": "Inter",
"fontSize": {
"small": 12,
"medium": 14,
"large": 18
},
"spacing": 4,
"borderRadius": 8
}
}
}
},
{
"type": "BindingEditor",
"label": "Binding Editor",
"category": "custom",
"icon": "Link",
"defaultProps": {
"bindings": {},
"dataSources": [],
"availableProps": ["children", "value"]
}
},
{
"type": "CanvasRenderer",
"label": "Canvas Renderer",
"category": "custom",
"icon": "Layout",
"defaultProps": {
"components": [],
"selectedId": null,
"hoveredId": null,
"draggedOverId": null,
"dropPosition": null
}
},
{
"type": "ComponentPalette",
"label": "Component Palette",
"category": "custom",
"icon": "GridFour",
"defaultProps": {}
},
{
"type": "ComponentTree",
"label": "Component Tree",
"category": "custom",
"icon": "Tree",
"defaultProps": {
"components": [],
"selectedId": null,
"hoveredId": null,
"draggedOverId": null,
"dropPosition": null
}
},
{
"type": "EditorActions",
"label": "Editor Actions",
"category": "custom",
"icon": "Sparkle",
"defaultProps": {}
},
{
"type": "EditorToolbar",
"label": "Editor Toolbar",
"category": "custom",
"icon": "Toolbox",
"defaultProps": {
"openFiles": [],
"activeFileId": null,
"activeFile": null
}
},
{
"type": "JSONUIShowcase",
"label": "JSON UI Showcase",
"category": "custom",
"icon": "Code",
"defaultProps": {
"files": [],
"models": [],
"components": []
}
},
{
"type": "LazyInlineMonacoEditor",
"label": "Inline Monaco Editor",
"category": "custom",
"icon": "Code",
"defaultProps": {
"height": "300px",
"language": "typescript",
"value": "// Start typing..."
}
},
{
"type": "LazyMonacoEditor",
"label": "Monaco Editor",
"category": "custom",
"icon": "Code",
"defaultProps": {
"file": {
"id": "file-1",
"name": "App.tsx",
"path": "/App.tsx",
"content": "// Start typing...",
"language": "typescript"
}
}
},
{
"type": "MonacoEditorPanel",
"label": "Monaco Editor Panel",
"category": "custom",
"icon": "Code",
"defaultProps": {
"file": {
"id": "file-1",
"name": "App.tsx",
"path": "/App.tsx",
"content": "// Start typing...",
"language": "typescript"
}
}
},
{
"type": "PageHeaderContent",
"label": "Page Header Content",
"category": "custom",
"icon": "Heading",
"defaultProps": {
"title": "Page Title",
"description": "Page description"
}
},
{
"type": "PropertyEditor",
"label": "Property Editor",
"category": "custom",
"icon": "SlidersHorizontal",
"defaultProps": {
"component": null
}
},
{
"type": "SchemaEditorCanvas",
"label": "Schema Editor Canvas",
"category": "custom",
"icon": "Layout",
"defaultProps": {
"components": [],
"selectedId": null,
"hoveredId": null,
"draggedOverId": null,
"dropPosition": null
}
},
{
"type": "SchemaEditorLayout",
"label": "Schema Editor Layout",
"category": "custom",
"icon": "Layout",
"defaultProps": {
"components": [],
"selectedId": null,
"hoveredId": null,
"draggedOverId": null,
"dropPosition": null,
"selectedComponent": null
}
},
{
"type": "SchemaEditorPropertiesPanel",
"label": "Schema Editor Properties Panel",
"category": "custom",
"icon": "SlidersHorizontal",
"defaultProps": {
"components": [],
"selectedId": null,
"hoveredId": null,
"draggedOverId": null,
"dropPosition": null,
"selectedComponent": null
}
},
{
"type": "SchemaEditorSidebar",
"label": "Schema Editor Sidebar",
"category": "custom",
"icon": "Sidebar",
"defaultProps": {}
},
{
"type": "SchemaEditorToolbar",
"label": "Schema Editor Toolbar",
"category": "custom",
"icon": "Toolbox",
"defaultProps": {}
},
{
"type": "SearchBar",
"label": "Search Bar",
"category": "custom",
"icon": "MagnifyingGlass",
"defaultProps": {
"value": "",
"placeholder": "Search..."
}
},
{
"type": "ToolbarActions",
"label": "Toolbar Actions",
"category": "custom",
"icon": "Toolbox",
"defaultProps": {
"errorCount": 0,
"showErrorButton": false
}
}
]

View File

@@ -17,9 +17,19 @@ import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, D
import { Skeleton as ShadcnSkeleton } from '@/components/ui/skeleton'
import { Progress } from '@/components/ui/progress'
import { Avatar as ShadcnAvatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { CircularProgress, Divider, ProgressBar } from '@/components/atoms'
import * as AtomComponents from '@/components/atoms'
import * as MoleculeComponents from '@/components/molecules'
import * as WrapperComponents from '@/lib/json-ui/wrappers'
import * as OrganismComponents from '@/components/organisms'
import {
BreadcrumbWrapper,
LazyBarChartWrapper,
LazyD3BarChartWrapper,
LazyLineChartWrapper,
SaveIndicatorWrapper,
SeedDataManagerWrapper,
StorageSettingsWrapper,
} from '@/lib/json-ui/wrappers'
import jsonComponentsRegistry from '../../../json-components-registry.json'
import {
ArrowLeft, ArrowRight, Check, X, Plus, Minus, MagnifyingGlass,
@@ -39,14 +49,19 @@ interface JsonRegistryEntry {
type?: string
export?: string
source?: string
wrapperRequired?: boolean
wrapperComponent?: string
status?: string
deprecated?: DeprecatedComponentInfo
}
interface JsonComponentRegistry {
components?: JsonRegistryEntry[]
}
export interface DeprecatedComponentInfo {
replacedBy?: string
message?: string
}
const jsonRegistry = jsonComponentsRegistry as JsonComponentRegistry
const buildRegistryFromNames = (
@@ -63,6 +78,19 @@ const buildRegistryFromNames = (
}
const jsonRegistryEntries = jsonRegistry.components ?? []
const deprecatedComponentInfo = jsonRegistryEntries.reduce<Record<string, DeprecatedComponentInfo>>(
(acc, entry) => {
const entryName = entry.export ?? entry.name ?? entry.type
if (!entryName) {
return acc
}
if (entry.status === 'deprecated' || entry.deprecated) {
acc[entryName] = entry.deprecated ?? {}
}
return acc
},
{}
)
const atomRegistryNames = jsonRegistryEntries
.filter((entry) => entry.source === 'atoms')
.map((entry) => entry.export ?? entry.name ?? entry.type)
@@ -71,20 +99,11 @@ const moleculeRegistryNames = jsonRegistryEntries
.filter((entry) => entry.source === 'molecules')
.map((entry) => entry.export ?? entry.name ?? entry.type)
.filter((name): name is string => Boolean(name))
const wrapperRegistryNames = jsonRegistryEntries
.filter((entry) => entry.source === 'wrappers')
const organismRegistryNames = jsonRegistryEntries
.filter((entry) => entry.source === 'organisms')
.map((entry) => entry.export ?? entry.name ?? entry.type)
.filter((name): name is string => Boolean(name))
const registryEntryByType = new Map<string, JsonRegistryEntry>(
jsonRegistryEntries
.map((entry) => {
const key = entry.type ?? entry.name ?? entry.export
return key ? [key, entry] : null
})
.filter((entry): entry is [string, JsonRegistryEntry] => Boolean(entry))
)
export const primitiveComponents: UIComponentRegistry = {
div: 'div' as any,
span: 'span' as any,
@@ -157,6 +176,9 @@ export const atomComponents: UIComponentRegistry = {
atomRegistryNames,
AtomComponents as Record<string, ComponentType<any>>
),
CircularProgress,
Divider,
ProgressBar,
DataList: (AtomComponents as Record<string, ComponentType<any>>).DataList,
DataTable: (AtomComponents as Record<string, ComponentType<any>>).DataTable,
MetricCard: (AtomComponents as Record<string, ComponentType<any>>).MetricCard,
@@ -173,11 +195,21 @@ export const moleculeComponents: UIComponentRegistry = buildRegistryFromNames(
MoleculeComponents as Record<string, ComponentType<any>>
)
export const jsonWrapperComponents: UIComponentRegistry = buildRegistryFromNames(
wrapperRegistryNames,
WrapperComponents as Record<string, ComponentType<any>>
export const organismComponents: UIComponentRegistry = buildRegistryFromNames(
organismRegistryNames,
OrganismComponents as Record<string, ComponentType<any>>
)
export const jsonWrapperComponents: UIComponentRegistry = {
Breadcrumb: BreadcrumbWrapper,
SaveIndicator: SaveIndicatorWrapper,
LazyBarChart: LazyBarChartWrapper,
LazyLineChart: LazyLineChartWrapper,
LazyD3BarChart: LazyD3BarChartWrapper,
SeedDataManager: SeedDataManagerWrapper,
StorageSettings: StorageSettingsWrapper,
}
export const iconComponents: UIComponentRegistry = {
ArrowLeft,
ArrowRight,
@@ -224,6 +256,7 @@ export const uiComponentRegistry: UIComponentRegistry = {
...shadcnComponents,
...atomComponents,
...moleculeComponents,
...organismComponents,
...jsonWrapperComponents,
...iconComponents,
}
@@ -247,3 +280,7 @@ export function getUIComponent(type: string): ComponentType<any> | string | null
export function hasComponent(type: string): boolean {
return Boolean(resolveWrapperComponent(type) ?? uiComponentRegistry[type])
}
export function getDeprecatedComponentInfo(type: string): DeprecatedComponentInfo | null {
return deprecatedComponentInfo[type] ?? null
}

View File

@@ -2,6 +2,7 @@ import { createElement, type ComponentType, type ReactNode } from 'react'
import { cn } from '@/lib/utils'
import { Component as ComponentSchema, Layout } from '@/schemas/ui-schema'
import { useDataBinding, useEventHandlers, useComponentRegistry } from '@/hooks/ui'
import { getDeprecatedComponentInfo } from '@/lib/json-ui/component-registry'
interface SchemaRendererProps {
schema: ComponentSchema
@@ -15,6 +16,26 @@ interface LayoutRendererProps {
children: ReactNode
}
const warnedDeprecatedComponents = new Set<string>()
const warnDeprecatedComponent = (schema: ComponentSchema) => {
const deprecatedInfo = getDeprecatedComponentInfo(schema.type)
if (!deprecatedInfo || warnedDeprecatedComponents.has(schema.type)) {
return
}
const idSuffix = schema.id ? ` (id: ${schema.id})` : ''
const replacementHint = deprecatedInfo.replacedBy
? ` Replace with "${deprecatedInfo.replacedBy}".`
: ''
const extraMessage = deprecatedInfo.message ? ` ${deprecatedInfo.message}` : ''
console.warn(
`[SchemaRenderer] Deprecated component "${schema.type}" detected in schema${idSuffix}.${replacementHint}${extraMessage}`
)
warnedDeprecatedComponents.add(schema.type)
}
function LayoutRenderer({ layout, children }: LayoutRendererProps) {
const getLayoutClasses = () => {
const classes: string[] = []
@@ -85,6 +106,8 @@ export function SchemaRenderer({ schema, data, functions = {}, componentRegistry
)
}
warnDeprecatedComponent(schema)
const props = resolveProps(schema.props || {})
const events = resolveEvents(schema.events)
const combinedProps = { ...props, ...events }

View File

@@ -181,29 +181,28 @@
]
},
{
"id": "loading-states-card",
"id": "loading-fallback-card",
"type": "Card",
"children": [
{
"id": "loading-states-header",
"id": "loading-fallback-header",
"type": "CardHeader",
"children": [
{
"id": "loading-states-title",
"id": "loading-fallback-title",
"type": "CardTitle",
"props": { "children": "Loading States" }
"props": { "children": "LoadingFallback" }
},
{
"id": "loading-states-description",
"id": "loading-fallback-description",
"type": "CardDescription",
"props": { "children": "LoadingFallback and LoadingState components" }
"props": { "children": "Inline loading message with spinner" }
}
]
},
{
"id": "loading-states-content",
"id": "loading-fallback-content",
"type": "CardContent",
"props": { "className": "space-y-4" },
"children": [
{
"id": "loading-fallback-wrapper",
@@ -218,7 +217,36 @@
}
}
]
}
]
}
]
},
{
"id": "loading-state-card",
"type": "Card",
"children": [
{
"id": "loading-state-header",
"type": "CardHeader",
"children": [
{
"id": "loading-state-title",
"type": "CardTitle",
"props": { "children": "LoadingState" }
},
{
"id": "loading-state-description",
"type": "CardDescription",
"props": { "children": "Standalone loading state with size variants" }
}
]
},
{
"id": "loading-state-content",
"type": "CardContent",
"props": { "className": "space-y-3" },
"children": [
{
"id": "loading-state-demo",
"type": "LoadingState",
@@ -226,6 +254,14 @@
"message": "Processing request...",
"size": "sm"
}
},
{
"id": "loading-state-demo-lg",
"type": "LoadingState",
"props": {
"message": "Syncing workspace...",
"size": "lg"
}
}
]
}

View File

@@ -208,5 +208,81 @@
]
}
]
},
"progressComponentsDemoSchema": {
"id": "progress-components-demo",
"name": "Progress Components Demo",
"layout": {
"type": "single"
},
"dataSources": [
{
"id": "progressValues",
"type": "static",
"defaultValue": {
"linear": 72,
"circular": 48,
"max": 100
}
}
],
"components": [
{
"id": "progress-components-root",
"type": "div",
"props": {
"className": "space-y-6 rounded-lg border border-border bg-card p-6"
},
"children": [
{
"id": "progress-components-title",
"type": "Heading",
"props": {
"className": "text-xl font-semibold",
"children": "Progress Indicators"
}
},
{
"id": "progress-components-divider-top",
"type": "Divider",
"props": {
"orientation": "horizontal"
}
},
{
"id": "progress-components-linear",
"type": "ProgressBar",
"props": {
"size": "md",
"variant": "accent",
"showLabel": true
},
"bindings": {
"value": { "source": "progressValues", "sourceType": "data", "path": "linear" },
"max": { "source": "progressValues", "sourceType": "data", "path": "max" }
}
},
{
"id": "progress-components-divider-middle",
"type": "Divider",
"props": {
"orientation": "horizontal"
}
},
{
"id": "progress-components-circular",
"type": "CircularProgress",
"props": {
"size": "md",
"showLabel": true
},
"bindings": {
"value": { "source": "progressValues", "sourceType": "data", "path": "circular" },
"max": { "source": "progressValues", "sourceType": "data", "path": "max" }
}
}
]
}
]
}
}

View File

@@ -14,6 +14,16 @@ export type ComponentType =
| 'LazyBarChart' | 'LazyLineChart' | 'LazyD3BarChart' | 'SeedDataManager'
| 'SaveIndicator' | 'StorageSettings'
| 'AppBranding' | 'LabelWithBadge' | 'EmptyEditorState' | 'LoadingFallback' | 'LoadingState' | 'NavigationGroupHeader'
| 'CodeExplanationDialog' | 'ComponentBindingDialog' | 'DataSourceCard' | 'DataSourceEditorDialog' | 'TreeCard' | 'TreeFormDialog'
| 'ToolbarButton'
| 'SchemaCodeViewer'
| 'FileTabs' | 'NavigationItem' | 'NavigationMenu'
| 'EmptyCanvasState' | 'SchemaEditorStatusBar'
| 'DataSourceManager' | 'TreeListHeader' | 'TreeListPanel'
| 'AppHeader' | 'BindingEditor' | 'CanvasRenderer' | 'ComponentPalette' | 'ComponentTree' | 'EditorActions'
| 'EditorToolbar' | 'JSONUIShowcase' | 'LazyInlineMonacoEditor' | 'LazyMonacoEditor' | 'MonacoEditorPanel'
| 'PageHeaderContent' | 'PropertyEditor' | 'SchemaEditorCanvas' | 'SchemaEditorLayout'
| 'SchemaEditorPropertiesPanel' | 'SchemaEditorSidebar' | 'SchemaEditorToolbar' | 'SearchBar' | 'ToolbarActions'
export type ActionType =
| 'create' | 'update' | 'delete' | 'navigate'