diff --git a/src/lib/json-ui/component-renderer.tsx b/src/lib/json-ui/component-renderer.tsx index ebfbbc4..32b4965 100644 --- a/src/lib/json-ui/component-renderer.tsx +++ b/src/lib/json-ui/component-renderer.tsx @@ -4,18 +4,13 @@ import { getUIComponent } from './component-registry' import { transformData } from './utils' function resolveBinding(binding: Binding, data: Record): unknown { - let value: unknown = data[binding.source] + const sourceValue = binding.source.includes('.') + ? getNestedValue(data, binding.source) + : data[binding.source] + let value: unknown = sourceValue if (binding.path) { - const keys = binding.path.split('.') - for (const key of keys) { - if (value && typeof value === 'object') { - value = (value as Record)[key] - } else { - value = undefined - break - } - } + value = getNestedValue(value, binding.path) } if (binding.transform) { @@ -27,20 +22,21 @@ function resolveBinding(binding: Binding, data: Record): unknow return value } -export function ComponentRenderer({ component, data, onEvent }: ComponentRendererProps) { +export function ComponentRenderer({ component, data, context = {}, onEvent }: ComponentRendererProps) { + const mergedData = useMemo(() => ({ ...data, ...context }), [data, context]) const resolvedProps = useMemo(() => { const resolved: Record = { ...component.props } if (component.bindings) { Object.entries(component.bindings).forEach(([propName, binding]) => { - resolved[propName] = resolveBinding(binding, data) + resolved[propName] = resolveBinding(binding, mergedData) }) } if (component.events && onEvent) { component.events.forEach(handler => { resolved[`on${handler.event.charAt(0).toUpperCase()}${handler.event.slice(1)}`] = (e: unknown) => { - if (!handler.condition || handler.condition(data)) { + if (!handler.condition || handler.condition(mergedData as Record)) { onEvent(component.id, handler.event, e) } } @@ -48,7 +44,7 @@ export function ComponentRenderer({ component, data, onEvent }: ComponentRendere } return resolved - }, [component, data, onEvent]) + }, [component, mergedData, onEvent]) const Component = getUIComponent(component.type) @@ -58,7 +54,7 @@ export function ComponentRenderer({ component, data, onEvent }: ComponentRendere } if (component.condition) { - const conditionValue = resolveBinding(component.condition, data) + const conditionValue = resolveBinding(component.condition, mergedData) if (!conditionValue) { return null } @@ -69,6 +65,7 @@ export function ComponentRenderer({ component, data, onEvent }: ComponentRendere key={child.id || index} component={child} data={data} + context={context} onEvent={onEvent} /> )) diff --git a/src/types/json-ui.ts b/src/types/json-ui.ts index e2fbc3c..5884b36 100644 --- a/src/types/json-ui.ts +++ b/src/types/json-ui.ts @@ -98,6 +98,7 @@ export interface JSONUIContext { export interface ComponentRendererProps { component: UIComponent data: Record + context?: Record onEvent?: (componentId: string, event: string, eventData: unknown) => void }