From 560a75cd69c7c02d6464bc2e915353a70c60b0e0 Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Sun, 18 Jan 2026 01:43:31 +0000 Subject: [PATCH] Expand schema component registry --- src/hooks/ui/use-component-registry.ts | 22 +++------------- src/lib/schema-renderer.tsx | 35 +++++++++++++++----------- 2 files changed, 23 insertions(+), 34 deletions(-) diff --git a/src/hooks/ui/use-component-registry.ts b/src/hooks/ui/use-component-registry.ts index 365f57f..c09b60f 100644 --- a/src/hooks/ui/use-component-registry.ts +++ b/src/hooks/ui/use-component-registry.ts @@ -1,11 +1,5 @@ import { useMemo } from 'react' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Button } from '@/components/ui/button' -import { Badge } from '@/components/ui/badge' -import { Input } from '@/components/ui/input' -import { Label } from '@/components/ui/label' -import { Separator } from '@/components/ui/separator' -import { Progress } from '@/components/ui/progress' +import { uiComponentRegistry, iconComponents } from '@/lib/json-ui/component-registry' import * as Icons from '@phosphor-icons/react' interface ComponentRegistryOptions { @@ -15,17 +9,7 @@ interface ComponentRegistryOptions { export function useComponentRegistry({ customComponents = {} }: ComponentRegistryOptions = {}) { const registry = useMemo( () => ({ - Card, - CardHeader, - CardTitle, - CardDescription, - CardContent, - Button, - Badge, - Input, - Label, - Separator, - Progress, + ...uiComponentRegistry, ...customComponents, }), [customComponents] @@ -36,7 +20,7 @@ export function useComponentRegistry({ customComponents = {} }: ComponentRegistr } const getIcon = (iconName: string, props?: any): React.ReactElement | null => { - const IconComponent = (Icons as any)[iconName] + const IconComponent = iconComponents[iconName as keyof typeof iconComponents] || (Icons as any)[iconName] if (!IconComponent) return null return IconComponent({ size: 24, weight: "duotone", ...props }) } diff --git a/src/lib/schema-renderer.tsx b/src/lib/schema-renderer.tsx index 46de07c..ce6bee5 100644 --- a/src/lib/schema-renderer.tsx +++ b/src/lib/schema-renderer.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react' +import type { ComponentType, ReactNode } from 'react' import { cn } from '@/lib/utils' import { Component as ComponentSchema, Layout } from '@/schemas/ui-schema' import { useDataBinding, useEventHandlers, useComponentRegistry } from '@/hooks/ui' @@ -7,6 +7,7 @@ interface SchemaRendererProps { schema: ComponentSchema data: Record functions?: Record any> + componentRegistry?: Record> } interface LayoutRendererProps { @@ -51,10 +52,10 @@ function LayoutRenderer({ layout, children }: LayoutRendererProps) { return
{children}
} -export function SchemaRenderer({ schema, data, functions = {} }: SchemaRendererProps) { +export function SchemaRenderer({ schema, data, functions = {}, componentRegistry }: SchemaRendererProps) { const { resolveCondition, resolveProps, resolveBinding } = useDataBinding({ data }) const { resolveEvents } = useEventHandlers({ functions }) - const { getComponent, getIcon } = useComponentRegistry() + const { getComponent, getIcon } = useComponentRegistry({ customComponents: componentRegistry }) if (schema.condition && !resolveCondition(schema.condition)) { return null @@ -76,6 +77,7 @@ export function SchemaRenderer({ schema, data, functions = {} }: SchemaRendererP schema={{ ...schema, repeat: undefined }} data={itemData} functions={functions} + componentRegistry={componentRegistry} /> ) })} @@ -83,6 +85,17 @@ export function SchemaRenderer({ schema, data, functions = {} }: SchemaRendererP ) } + const props = resolveProps(schema.props || {}) + const events = resolveEvents(schema.events) + const combinedProps = { ...props, ...events } + + if (schema.binding) { + const iconName = resolveBinding(schema.binding) + if (iconName && schema.type === 'Icon') { + return getIcon(iconName, combinedProps) + } + } + const Component = getComponent(schema.type) if (!Component) { @@ -96,23 +109,13 @@ export function SchemaRenderer({ schema, data, functions = {} }: SchemaRendererP ) } - const props = resolveProps(schema.props || {}) - const events = resolveEvents(schema.events) - const combinedProps = { ...props, ...events } - - if (schema.binding) { - const iconName = resolveBinding(schema.binding) - if (iconName && schema.type === 'Icon') { - return getIcon(iconName, props) - } - } - const children = schema.children?.map((child, index) => ( )) @@ -129,9 +132,10 @@ interface PageRendererProps { } data: Record functions?: Record any> + componentRegistry?: Record> } -export function PageRenderer({ schema, data, functions = {} }: PageRendererProps) { +export function PageRenderer({ schema, data, functions = {}, componentRegistry }: PageRendererProps) { return ( {schema.components.map((component) => ( @@ -140,6 +144,7 @@ export function PageRenderer({ schema, data, functions = {} }: PageRendererProps schema={component} data={data} functions={functions} + componentRegistry={componentRegistry} /> ))}