feat: migrate ConflictIndicator to JSON

This commit is contained in:
2026-01-21 05:02:38 +00:00
parent 3f2f698516
commit 61b64cb1df
33 changed files with 1803 additions and 25 deletions

View File

@@ -0,0 +1,26 @@
{
"id": "conditional-wrapper-container",
"type": "div",
"bindings": {
"className": {
"source": "className",
"transform": "data || ''"
},
"children": [
{
"id": "conditional-wrapper-content",
"type": "div",
"bindings": {
"children": {
"source": ["condition", "children", "fallback"],
"transform": "const condition = data[0]; const children = data[1]; const fallback = data[2]; return condition ? children : fallback"
},
"_if": {
"source": ["condition", "fallback"],
"transform": "const condition = data[0]; const fallback = data[1]; return condition || !!fallback"
}
}
}
]
}
}

View File

@@ -1,8 +1,114 @@
{
"id": "conflict-indicator",
"type": "div",
"props": {
"className": "conflict-indicator"
"id": "conflict-indicator-wrapper",
"type": "AnimatePresence",
"conditional": {
"if": "hasConflicts"
},
"children": []
"children": [
{
"id": "conflict-indicator-motion",
"type": "motion.div",
"props": {
"initial": { "opacity": 0, "x": -20 },
"animate": { "opacity": 1, "x": 0 },
"exit": { "opacity": 0, "x": -20 }
},
"children": [
{
"id": "conflict-indicator-badge-compact",
"type": "motion.button",
"conditional": {
"if": "variant === 'compact'"
},
"bindings": {
"onClick": {
"source": "onClick",
"transform": "data || (() => {})"
}
},
"props": {
"className": "relative",
"initial": { "scale": 0 },
"animate": { "scale": 1 },
"exit": { "scale": 0 }
},
"children": [
{
"id": "conflict-icon-compact",
"type": "Warning",
"props": {
"size": 20,
"weight": "fill",
"className": "text-destructive animate-pulse"
}
},
{
"id": "conflict-count-badge",
"type": "span",
"bindings": {
"children": {
"source": "stats.totalConflicts"
}
},
"props": {
"className": "absolute -top-1 -right-1 bg-destructive text-destructive-foreground text-[10px] font-bold rounded-full w-4 h-4 flex items-center justify-center"
}
}
]
},
{
"id": "conflict-indicator-badge-full",
"type": "Badge",
"conditional": {
"if": "variant !== 'compact'"
},
"bindings": {
"onClick": {
"source": "onClick",
"transform": "data || (() => {})"
}
},
"props": {
"variant": "destructive",
"className": "cursor-pointer hover:bg-destructive/90 transition-colors gap-1.5 animate-pulse"
},
"children": [
{
"id": "conflict-icon-full",
"type": "Warning",
"props": {
"size": 14,
"weight": "fill"
}
},
{
"id": "conflict-label",
"type": "span",
"conditional": {
"if": "showLabel"
},
"bindings": {
"children": {
"source": "stats.totalConflicts",
"transform": "data === 1 ? `${data} Conflict` : `${data} Conflicts`"
}
}
},
{
"id": "conflict-count-only",
"type": "span",
"conditional": {
"if": "!showLabel"
},
"bindings": {
"children": {
"source": "stats.totalConflicts"
}
}
}
]
}
]
}
]
}

View File

@@ -0,0 +1,82 @@
{
"id": "data-card-container",
"type": "Card",
"bindings": {
"className": {
"source": ["gradient", "className"],
"transform": "const gradient = data[0]; const className = data[1] || ''; const gradientClass = gradient ? `bg-gradient-to-br ${gradient} border-primary/20` : ''; return `${gradientClass} ${className}`.trim()"
}
},
"children": [
{
"id": "data-card-header",
"type": "CardHeader",
"children": [
{
"id": "data-card-title",
"type": "CardTitle",
"bindings": {
"className": {
"source": null,
"transform": "'flex items-center gap-2'"
},
"children": [
{
"id": "data-card-icon",
"type": "span",
"bindings": {
"className": {
"source": null,
"transform": "'text-primary'"
},
"children": {
"source": "icon",
"transform": "data"
},
"_if": {
"source": "icon",
"transform": "!!data"
}
}
},
{
"id": "data-card-title-text",
"type": "span",
"bindings": {
"children": {
"source": "title",
"transform": "data"
}
}
}
]
}
},
{
"id": "data-card-description",
"type": "CardDescription",
"bindings": {
"children": {
"source": "description",
"transform": "data"
},
"_if": {
"source": "description",
"transform": "!!data"
}
}
}
]
},
{
"id": "data-card-content",
"type": "CardContent",
"children": [
{
"type": "slot",
"source": "children"
}
]
}
]
}

View File

@@ -0,0 +1,16 @@
{
"id": "dynamic-text-container",
"type": "span",
"bindings": {
"className": "className"
},
"children": [
{
"id": "dynamic-text-value",
"type": "text",
"bindings": {
"content": "formattedValue"
}
}
]
}

View File

@@ -0,0 +1,66 @@
{
"id": "feature-toggle-settings",
"type": "div",
"className": "h-full p-6 bg-background",
"children": [
{
"id": "feature-toggle-header",
"type": "div",
"className": "mb-6",
"children": [
{
"id": "feature-toggle-title",
"type": "h2",
"className": "text-2xl font-bold mb-2",
"children": "Feature Toggles"
},
{
"id": "feature-toggle-description",
"type": "p",
"className": "text-muted-foreground",
"children": [
"Enable or disable features to customize your workspace. ",
{
"type": "span",
"bindings": {
"children": {
"source": "enabledCount",
"transform": "data"
}
}
},
" of ",
{
"type": "span",
"bindings": {
"children": {
"source": "totalCount",
"transform": "data"
}
}
},
" features enabled."
]
}
]
},
{
"id": "feature-toggle-scroll-area",
"type": "ScrollArea",
"className": "h-[calc(100vh-200px)]",
"children": [
{
"id": "feature-toggle-grid",
"type": "div",
"className": "grid grid-cols-1 lg:grid-cols-2 gap-4 pr-4",
"bindings": {
"children": {
"source": "items",
"transform": "data.map((item, index) => ({ id: `feature-${item.key}`, key: item.key, item: item, index: index }))"
}
}
}
]
}
]
}

View File

@@ -0,0 +1,14 @@
{
"id": "flex-layout",
"type": "div",
"bindings": {
"className": {
"source": ["direction", "align", "justify", "wrap", "gap", "className"],
"transform": "const [direction, align, justify, wrap, gap, customClass] = data; const directionClass = direction === 'column' ? 'flex-col' : 'flex-row'; const alignClasses = { start: 'items-start', center: 'items-center', end: 'items-end', stretch: 'items-stretch' }; const justifyClasses = { start: 'justify-start', center: 'justify-center', end: 'justify-end', between: 'justify-between', around: 'justify-around', evenly: 'justify-evenly' }; const gapClasses = { none: 'gap-0', xs: 'gap-1', sm: 'gap-2', md: 'gap-4', lg: 'gap-6', xl: 'gap-8' }; const wrapClass = wrap ? 'flex-wrap' : ''; const baseClasses = `flex ${directionClass} ${alignClasses[align || 'start']} ${justifyClasses[justify || 'start']} ${gapClasses[gap || 'md']} ${wrapClass} ${customClass || ''}`.trim(); return baseClasses.replace(/\\s+/g, ' ')"
},
"children": {
"source": "children",
"transform": "data"
}
}
}

View File

@@ -0,0 +1,14 @@
{
"id": "grid-layout",
"type": "div",
"bindings": {
"className": {
"source": ["cols", "gap", "className"],
"transform": "const [cols, gap, customClass] = data; const gapClasses = { none: 'gap-0', xs: 'gap-1', sm: 'gap-2', md: 'gap-4', lg: 'gap-6', xl: 'gap-8' }; const gridCols = []; const colsObj = cols || { base: 1 }; if (colsObj.base) gridCols.push(`grid-cols-${colsObj.base}`); if (colsObj.sm) gridCols.push(`sm:grid-cols-${colsObj.sm}`); if (colsObj.md) gridCols.push(`md:grid-cols-${colsObj.md}`); if (colsObj.lg) gridCols.push(`lg:grid-cols-${colsObj.lg}`); if (colsObj.xl) gridCols.push(`xl:grid-cols-${colsObj.xl}`); const baseClasses = `grid ${gapClasses[gap || 'md']} ${gridCols.join(' ')} ${customClass || ''}`.trim(); return baseClasses.replace(/\\s+/g, ' ')"
},
"children": {
"source": "children",
"transform": "data"
}
}
}

View File

@@ -0,0 +1,15 @@
{
"id": "icon-renderer-container",
"type": "span",
"children": [
{
"id": "icon-renderer-icon",
"type": "${name}",
"bindings": {
"size": "size",
"weight": "weight",
"className": "className"
}
}
]
}

View File

@@ -0,0 +1,112 @@
{
"id": "panel-card",
"type": "Card",
"bindings": {
"className": {
"source": "variant",
"transform": "const variantClasses = { default: 'border-border', bordered: 'border-2 border-primary/20', elevated: 'shadow-lg border-border' }; return variantClasses[data || 'default'] + (this.props.className ? ' ' + this.props.className : '')"
}
},
"children": [
{
"id": "panel-header",
"type": "div",
"bindings": {
"className": {
"source": ["title", "description", "actions"],
"transform": "const hasHeader = !!data[0] || !!data[1] || !!data[2]; return hasHeader ? 'flex items-start justify-between p-4 border-b' : ''"
},
"_if": {
"source": ["title", "description", "actions"],
"transform": "return !!data[0] || !!data[1] || !!data[2]"
}
},
"children": [
{
"id": "panel-header-content",
"type": "div",
"bindings": {
"className": {
"source": null,
"transform": "'space-y-1'"
}
},
"children": [
{
"id": "panel-title",
"type": "h3",
"bindings": {
"className": {
"source": null,
"transform": "'font-semibold text-lg'"
},
"children": {
"source": "title",
"transform": "data"
},
"_if": {
"source": "title",
"transform": "!!data"
}
}
},
{
"id": "panel-description",
"type": "p",
"bindings": {
"className": {
"source": null,
"transform": "'text-sm text-muted-foreground'"
},
"children": {
"source": "description",
"transform": "data"
},
"_if": {
"source": "description",
"transform": "!!data"
}
}
}
]
},
{
"id": "panel-actions",
"type": "div",
"bindings": {
"children": {
"source": "actions",
"transform": "data"
},
"_if": {
"source": "actions",
"transform": "!!data"
}
}
}
]
},
{
"id": "panel-content",
"type": "CardContent",
"bindings": {
"className": {
"source": null,
"transform": "'p-4'"
}
},
"children": [
{
"id": "panel-children",
"type": "div",
"bindings": {
"children": {
"source": "children",
"transform": "data"
}
}
}
]
}
]
}

View File

@@ -0,0 +1,48 @@
{
"id": "repeat-wrapper-container",
"type": "div",
"bindings": {
"className": {
"source": ["gap", "className"],
"transform": "const gap = data[0] || 'md'; const className = data[1] || ''; const gapClasses = { none: 'gap-0', xs: 'gap-1', sm: 'gap-2', md: 'gap-4', lg: 'gap-6', xl: 'gap-8' }; return `flex flex-col ${gapClasses[gap]} ${className}`.trim()"
}
},
"children": [
{
"id": "repeat-wrapper-empty",
"type": "div",
"bindings": {
"className": {
"source": null,
"transform": "'text-center text-muted-foreground text-sm p-4'"
},
"children": {
"source": "emptyMessage",
"transform": "data"
},
"_if": {
"source": ["items", "emptyMessage"],
"transform": "(!data[0] || data[0].length === 0) && data[1]"
}
}
},
{
"id": "repeat-wrapper-items",
"type": "RepeatLoop",
"bindings": {
"items": {
"source": "items",
"transform": "data"
},
"render": {
"source": "render",
"transform": "data"
}
},
"_if": {
"source": "items",
"transform": "data && data.length > 0"
}
}
]
}

View File

@@ -37,6 +37,8 @@ export * from './use-menu-state'
export * from './use-file-upload'
export * from './use-accordion'
export * from './use-binding-editor'
export * from './use-format-value'
export * from './use-repeat-wrapper'
export { useAppLayout } from './use-app-layout'
export { useAppRouterLayout } from './use-app-router-layout'
export { useNavigationMenu } from './use-navigation-menu'

View File

@@ -0,0 +1,49 @@
import { useMemo } from 'react'
export function useFormatValue(
value: any,
format: 'text' | 'number' | 'currency' | 'date' | 'time' | 'datetime' | 'boolean' = 'text',
currency: string = 'USD',
locale: string = 'en-US'
): string {
return useMemo(() => {
if (value === null || value === undefined) return ''
switch (format) {
case 'number':
return typeof value === 'number' ? value.toLocaleString(locale) : value
case 'currency':
return typeof value === 'number'
? new Intl.NumberFormat(locale, { style: 'currency', currency }).format(value)
: value
case 'date':
try {
return new Date(value).toLocaleDateString(locale)
} catch {
return value
}
case 'time':
try {
return new Date(value).toLocaleTimeString(locale)
} catch {
return value
}
case 'datetime':
try {
return new Date(value).toLocaleString(locale)
} catch {
return value
}
case 'boolean':
return value ? 'Yes' : 'No'
default:
return String(value)
}
}, [value, format, currency, locale])
}

View File

@@ -0,0 +1,26 @@
import { useMemo } from 'react'
interface UseRepeatWrapperArgs {
items: any[]
render: (item: any, index: number) => React.ReactNode
}
export function useRepeatWrapper({ items, render }: UseRepeatWrapperArgs) {
const rendered = useMemo(() => {
if (!items || items.length === 0) {
return []
}
return items.map((item, index) => ({
key: index,
item,
index,
element: render(item, index)
}))
}, [items, render])
return {
renderedItems: rendered,
itemCount: items?.length || 0,
isEmpty: !items || items.length === 0
}
}

View File

@@ -15,10 +15,13 @@ import { useMenuState } from '@/hooks/use-menu-state'
import { useFileUpload } from '@/hooks/use-file-upload'
import { useAccordion } from '@/hooks/use-accordion'
import { useBindingEditor } from '@/hooks/use-binding-editor'
import { useRepeatWrapper } from '@/hooks/use-repeat-wrapper'
import { useAppLayout } from '@/hooks/use-app-layout'
import { useAppRouterLayout } from '@/hooks/use-app-router-layout'
import { useNavigationMenu } from '@/hooks/use-navigation-menu'
import { useDataSourceManagerState } from '@/hooks/use-data-source-manager-state'
import { useFormatValue } from '@/hooks/use-format-value'
import { useConflictResolution } from '@/hooks/use-conflict-resolution'
export interface HookRegistry {
[key: string]: (...args: any[]) => any
@@ -41,10 +44,13 @@ export const hooksRegistry: HookRegistry = {
useFileUpload,
useAccordion,
useBindingEditor,
useRepeatWrapper,
useAppLayout,
useAppRouterLayout,
useNavigationMenu,
useDataSourceManagerState,
useFormatValue,
useConflictResolution,
// Add more hooks here as needed
}

View File

@@ -0,0 +1,6 @@
export interface ConditionalWrapperProps {
condition: boolean
children: React.ReactNode
fallback?: React.ReactNode
className?: string
}

View File

@@ -1,5 +1,5 @@
/**
* ConflictIndicatorProps - JSON definition interface
* Indicator for conflicts
*/
export interface ConflictIndicatorProps {}
export interface ConflictIndicatorProps {
onClick?: () => void
showLabel?: boolean
variant?: 'badge' | 'compact'
}

View File

@@ -0,0 +1,8 @@
export interface DataCardProps {
title: string
description?: string
icon?: string
gradient?: string
children: React.ReactNode
className?: string
}

View File

@@ -0,0 +1,7 @@
export interface DynamicTextProps {
value: any
format?: 'text' | 'number' | 'currency' | 'date' | 'time' | 'datetime' | 'boolean'
currency?: string
locale?: string
className?: string
}

View File

@@ -0,0 +1,6 @@
import type { FeatureToggles } from '@/types/project'
export interface FeatureToggleSettingsProps {
features: FeatureToggles
onFeaturesChange: (features: FeatureToggles) => void
}

View File

@@ -0,0 +1,9 @@
export interface FlexLayoutProps {
children: React.ReactNode
direction?: 'row' | 'column'
align?: 'start' | 'center' | 'end' | 'stretch'
justify?: 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly'
wrap?: boolean
gap?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl'
className?: string
}

View File

@@ -0,0 +1,12 @@
export interface GridLayoutProps {
children: React.ReactNode
cols?: {
base?: number
sm?: number
md?: number
lg?: number
xl?: number
}
gap?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl'
className?: string
}

View File

@@ -0,0 +1,6 @@
export interface IconRendererProps {
name: string
size?: number
weight?: 'thin' | 'light' | 'regular' | 'bold' | 'fill' | 'duotone'
className?: string
}

View File

@@ -34,6 +34,9 @@ export * from './menu'
export * from './file-upload'
export * from './accordion'
export * from './binding-editor'
export * from './icon-renderer'
export * from './dynamic-text'
export * from './repeat-wrapper'
export * from './tree-list-panel'
export * from './app-layout'
export * from './app-router-layout'
@@ -73,7 +76,9 @@ export * from './hover-card'
export * from './icon'
export * from './input-otp'
export * from './label'
export * from './conditional-wrapper'
export * from './pagination'
export * from './panel'
export * from './progress'
export * from './progress-bar'
export * from './pulse'
@@ -143,7 +148,9 @@ export * from './dot'
export * from './empty-state'
export * from './empty-state-icon'
export * from './flex'
export * from './flex-layout'
export * from './grid'
export * from './grid-layout'
export * from './icon-button'
export * from './icon-text'
export * from './icon-wrapper'
@@ -223,3 +230,4 @@ export * from './comprehensive-demo-page'
export * from './template-explorer'
export * from './project-manager'
export * from './storage-settings-panel'
export * from './feature-toggle-settings'

View File

@@ -0,0 +1,8 @@
export interface PanelProps {
title?: string
description?: string
actions?: React.ReactNode
children: React.ReactNode
className?: string
variant?: 'default' | 'bordered' | 'elevated'
}

View File

@@ -0,0 +1,7 @@
export interface RepeatWrapperProps {
items: any[]
render: (item: any, index: number) => React.ReactNode
emptyMessage?: string
className?: string
gap?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl'
}

View File

@@ -34,14 +34,19 @@ import type {
TreeCardProps,
FilterInputProps,
CopyButtonProps,
ConditionalWrapperProps,
InputProps,
PasswordInputProps,
ImageProps,
DataCardProps,
RepeatWrapperProps,
PopoverProps,
MenuProps,
FileUploadProps,
AccordionProps,
BindingEditorProps,
IconRendererProps,
DynamicTextProps,
AppLayoutProps,
AppRouterLayoutProps,
AppMainPanelProps,
@@ -88,6 +93,7 @@ import type {
InputOTPProps,
LabelProps,
PaginationProps,
PanelProps,
ProgressProps,
ProgressBarProps,
PulseProps,
@@ -149,6 +155,8 @@ import type {
DotProps,
EmptyStateProps,
EmptyStateIconProps,
FlexLayoutProps,
GridLayoutProps,
FlexProps,
GridProps,
IconButtonProps,
@@ -241,6 +249,7 @@ import type {
TemplateExplorerProps,
ProjectManagerProps,
StorageSettingsPanelProps,
FeatureToggleSettingsProps,
} from './interfaces'
// Import JSON definitions
@@ -270,14 +279,19 @@ import storageSettingsDef from '@/components/json-definitions/storage-settings.j
import treeCardDef from '@/components/json-definitions/tree-card.json'
import filterInputDef from '@/components/json-definitions/filter-input.json'
import copyButtonDef from '@/components/json-definitions/copy-button.json'
import conditionalWrapperDef from '@/components/json-definitions/conditional-wrapper.json'
import inputDef from '@/components/json-definitions/input.json'
import passwordInputDef from '@/components/json-definitions/password-input.json'
import imageDef from '@/components/json-definitions/image.json'
import dataCardDef from '@/components/json-definitions/data-card.json'
import repeatWrapperDef from '@/components/json-definitions/repeat-wrapper.json'
import popoverDef from '@/components/json-definitions/popover.json'
import menuDef from '@/components/json-definitions/menu.json'
import fileUploadDef from '@/components/json-definitions/file-upload.json'
import accordionDef from '@/components/json-definitions/accordion.json'
import bindingEditorDef from '@/components/json-definitions/binding-editor.json'
import iconRendererDef from '@/components/json-definitions/icon-renderer.json'
import dynamicTextDef from '@/components/json-definitions/dynamic-text.json'
import appLayoutDef from '@/components/json-definitions/app-layout.json'
import appRouterLayoutDef from '@/components/json-definitions/app-router-layout.json'
import appMainPanelDef from '@/components/json-definitions/app-main-panel.json'
@@ -318,6 +332,7 @@ import iconDef from '@/components/json-definitions/icon.json'
import inputOtpDef from '@/components/json-definitions/input-otp.json'
import labelDef from '@/components/json-definitions/label.json'
import paginationDef from '@/components/json-definitions/pagination.json'
import panelDef from '@/components/json-definitions/panel.json'
import progressDef from '@/components/json-definitions/progress.json'
import progressBarDef from '@/components/json-definitions/progress-bar.json'
import pulseDef from '@/components/json-definitions/pulse.json'
@@ -386,6 +401,8 @@ import dotDef from '@/components/json-definitions/dot.json'
import emptyStateDef from '@/components/json-definitions/empty-state.json'
import emptyStateIconDef from '@/components/json-definitions/empty-state-icon.json'
import flexDef from '@/components/json-definitions/flex.json'
import flexLayoutDef from '@/components/json-definitions/flex-layout.json'
import gridLayoutDef from '@/components/json-definitions/grid-layout.json'
import gridDef from '@/components/json-definitions/grid.json'
import iconButtonDef from '@/components/json-definitions/icon-button.json'
import iconTextDef from '@/components/json-definitions/icon-text.json'
@@ -479,6 +496,7 @@ import comprehensiveDemoPageDef from '@/components/json-definitions/comprehensiv
import templateExplorerDef from '@/components/json-definitions/template-explorer.json'
import projectManagerDef from '@/components/json-definitions/project-manager.json'
import storageSettingsPanelDef from '@/components/json-definitions/storage-settings-panel.json'
import featureToggleSettingsDef from '@/components/json-definitions/feature-toggle-settings.json'
// Create pure JSON components (no hooks)
export const BindingIndicator = createJsonComponent<BindingIndicatorProps>(bindingIndicatorDef)
@@ -486,6 +504,7 @@ export const ButtonGroup = createJsonComponent<ButtonGroupProps>(buttonGroupDef)
export const Chip = createJsonComponent<ChipProps>(chipDef)
export const CircularProgress = createJsonComponent<CircularProgressProps>(circularProgressDef)
export const Code = createJsonComponent<CodeProps>(codeDef)
export const ConditionalWrapper = createJsonComponent<ConditionalWrapperProps>(conditionalWrapperDef)
export const CommandPalette = createJsonComponent<CommandPaletteProps>(commandPaletteDef)
export const CompletionCard = createJsonComponent<CompletionCardProps>(completionCardDef)
export const ComponentPaletteItem = createJsonComponent<ComponentPaletteItemProps>(componentPaletteItemDef)
@@ -535,6 +554,7 @@ export const Icon = createJsonComponent<IconProps>(iconDef)
export const InputOTP = createJsonComponent<InputOTPProps>(inputOtpDef)
export const Label = createJsonComponent<LabelProps>(labelDef)
export const Pagination = createJsonComponent<PaginationProps>(paginationDef)
export const Panel = createJsonComponent<PanelProps>(panelDef)
export const Progress = createJsonComponent<ProgressProps>(progressDef)
export const ProgressBar = createJsonComponent<ProgressBarProps>(progressBarDef)
export const Pulse = createJsonComponent<PulseProps>(pulseDef)
@@ -669,6 +689,19 @@ export const Image = createJsonComponentWithHooks<ImageProps>(imageDef, {
}
}
})
export const DataCard = createJsonComponent<DataCardProps>(dataCardDef)
export const RepeatWrapper = createJsonComponentWithHooks<RepeatWrapperProps>(repeatWrapperDef, {
hooks: {
repeatData: {
hookName: "useRepeatWrapper",
args: (props) => [{
items: props.items,
render: props.render
}]
}
}
})
export const Popover = createJsonComponentWithHooks<PopoverProps>(popoverDef, {
hooks: {
@@ -715,6 +748,17 @@ export const BindingEditor = createJsonComponentWithHooks<BindingEditorProps>(bi
}
})
export const IconRenderer = createJsonComponent<IconRendererProps>(iconRendererDef)
export const DynamicText = createJsonComponentWithHooks<DynamicTextProps>(dynamicTextDef, {
hooks: {
formattedValue: {
hookName: 'useFormatValue',
args: (props) => [props.value, props.format, props.currency, props.locale]
}
}
})
export const AppLayout = createJsonComponentWithHooks<AppLayoutProps>(appLayoutDef, {
hooks: {
hookData: {
@@ -781,6 +825,8 @@ export const Dot = createJsonComponent<DotProps>(dotDef)
export const EmptyState = createJsonComponent<EmptyStateProps>(emptyStateDef)
export const EmptyStateIcon = createJsonComponent<EmptyStateIconProps>(emptyStateIconDef)
export const Flex = createJsonComponent<FlexProps>(flexDef)
export const FlexLayout = createJsonComponent<FlexLayoutProps>(flexLayoutDef)
export const GridLayout = createJsonComponent<GridLayoutProps>(gridLayoutDef)
export const Grid = createJsonComponent<GridProps>(gridDef)
export const IconButton = createJsonComponent<IconButtonProps>(iconButtonDef)
export const IconText = createJsonComponent<IconTextProps>(iconTextDef)
@@ -839,7 +885,23 @@ export const PWAStatusBar = createJsonComponent<PWAStatusBarProps>(pwaStatusBarD
export const PWAUpdatePrompt = createJsonComponent<PWAUpdatePromptProps>(pwaUpdatePromptDef)
export const PWAInstallPrompt = createJsonComponent<PWAInstallPromptProps>(pwaInstallPromptDef)
export const ConflictCard = createJsonComponent<ConflictCardProps>(conflictCardDef)
export const ConflictIndicator = createJsonComponent<ConflictIndicatorProps>(conflictIndicatorDef)
export const ConflictIndicator = createJsonComponentWithHooks<ConflictIndicatorProps>(
conflictIndicatorDef,
{
hooks: {
hasConflicts: {
hookName: 'useConflictResolution',
args: () => [],
selector: (result) => result.hasConflicts
},
stats: {
hookName: 'useConflictResolution',
args: () => [],
selector: (result) => result.stats
}
}
}
)
export const ErrorPanel = createJsonComponent<ErrorPanelProps>(errorPanelDef)
export const PreviewDialog = createJsonComponent<PreviewDialogProps>(previewDialogDef)
export const NotFoundPage = createJsonComponent<NotFoundPageProps>(notFoundPageDef)
@@ -862,5 +924,6 @@ export const ComprehensiveDemoPage = createJsonComponent<ComprehensiveDemoPagePr
export const TemplateExplorer = createJsonComponent<TemplateExplorerProps>(templateExplorerDef)
export const ProjectManager = createJsonComponent<ProjectManagerProps>(projectManagerDef)
export const StorageSettingsPanel = createJsonComponent<StorageSettingsPanelProps>(storageSettingsPanelDef)
export const FeatureToggleSettings = createJsonComponent<FeatureToggleSettingsProps>(featureToggleSettingsDef)
// All components converted to pure JSON! 🎉

View File

@@ -77,6 +77,7 @@ export const jsonUIComponentTypes = [
"ComponentTreeNode",
"ComponentTreeWrapper",
"ConfirmButton",
"ConditionalWrapper",
"ConflictResolutionPage",
"Container",
"ContextMenu",
@@ -97,6 +98,7 @@ export const jsonUIComponentTypes = [
"Dialog",
"Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,",
"Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle",
"DynamicText",
"Divider",
"DockerBuildDebugger",
"DocumentationView",
@@ -125,6 +127,7 @@ export const jsonUIComponentTypes = [
"Filter",
"FilterInput",
"Flex",
"FlexLayout",
"Form",
"Form as ShadcnForm,\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,",
"FormField",
@@ -132,6 +135,7 @@ export const jsonUIComponentTypes = [
"GitHubBuildStatusWrapper",
"GlowCard",
"Grid",
"GridLayout",
"Heading",
"Heart",
"HelpCircle",
@@ -140,6 +144,7 @@ export const jsonUIComponentTypes = [
"HoverCard",
"HoverCard as ShadcnHoverCard,\n HoverCardContent,\n HoverCardTrigger,",
"Icon",
"IconRenderer",
"IconButton",
"IconText",
"IconWrapper",
@@ -192,6 +197,7 @@ export const jsonUIComponentTypes = [
"PageHeader",
"PageHeaderContent",
"Pagination",
"Panel",
"PanelHeader",
"PasswordInput",
"PersistenceDashboard",
@@ -210,6 +216,7 @@ export const jsonUIComponentTypes = [
"RadioGroup",
"RangeSlider",
"Rating",
"RepeatWrapper",
"RefreshCw",
"Resizable",
"ResponsiveGrid",