mirror of
https://github.com/johndoe6345789/low-code-react-app-b.git
synced 2026-04-24 13:44:54 +00:00
Expand schema component registry
This commit is contained in:
@@ -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 })
|
||||
}
|
||||
|
||||
@@ -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<string, any>
|
||||
functions?: Record<string, (...args: any[]) => any>
|
||||
componentRegistry?: Record<string, ComponentType<any>>
|
||||
}
|
||||
|
||||
interface LayoutRendererProps {
|
||||
@@ -51,10 +52,10 @@ function LayoutRenderer({ layout, children }: LayoutRendererProps) {
|
||||
return <div className={getLayoutClasses()}>{children}</div>
|
||||
}
|
||||
|
||||
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) => (
|
||||
<SchemaRenderer
|
||||
key={child.id || index}
|
||||
schema={child}
|
||||
data={data}
|
||||
functions={functions}
|
||||
componentRegistry={componentRegistry}
|
||||
/>
|
||||
))
|
||||
|
||||
@@ -129,9 +132,10 @@ interface PageRendererProps {
|
||||
}
|
||||
data: Record<string, any>
|
||||
functions?: Record<string, (...args: any[]) => any>
|
||||
componentRegistry?: Record<string, ComponentType<any>>
|
||||
}
|
||||
|
||||
export function PageRenderer({ schema, data, functions = {} }: PageRendererProps) {
|
||||
export function PageRenderer({ schema, data, functions = {}, componentRegistry }: PageRendererProps) {
|
||||
return (
|
||||
<LayoutRenderer layout={schema.layout}>
|
||||
{schema.components.map((component) => (
|
||||
@@ -140,6 +144,7 @@ export function PageRenderer({ schema, data, functions = {} }: PageRendererProps
|
||||
schema={component}
|
||||
data={data}
|
||||
functions={functions}
|
||||
componentRegistry={componentRegistry}
|
||||
/>
|
||||
))}
|
||||
</LayoutRenderer>
|
||||
|
||||
Reference in New Issue
Block a user