From 0d82406e5f8ddb0d9b701574977c8c2e291de9d6 Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Sun, 18 Jan 2026 11:38:50 +0000 Subject: [PATCH] Add JSON UI support for feedback atoms --- json-components-registry.json | 6 +- src/components/JSONUIShowcasePage.tsx | 6 ++ src/lib/component-definitions.ts | 118 ++++++++++++++++++++++++++ src/schemas/page-schemas.ts | 114 +++++++++++++++++++++++++ src/types/json-ui.ts | 1 + 5 files changed, 242 insertions(+), 3 deletions(-) diff --git a/json-components-registry.json b/json-components-registry.json index bb68d7b..100f715 100644 --- a/json-components-registry.json +++ b/json-components-registry.json @@ -1088,7 +1088,7 @@ "category": "feedback", "canHaveChildren": false, "description": "Error state badge", - "status": "planned", + "status": "supported", "source": "atoms" }, { @@ -1164,7 +1164,7 @@ "category": "feedback", "canHaveChildren": true, "description": "Toast notification", - "status": "planned", + "status": "supported", "source": "atoms" }, { @@ -1201,7 +1201,7 @@ "category": "feedback", "canHaveChildren": false, "description": "Status indicator icon", - "status": "planned", + "status": "supported", "source": "atoms" }, { diff --git a/src/components/JSONUIShowcasePage.tsx b/src/components/JSONUIShowcasePage.tsx index 2b92f00..ad511da 100644 --- a/src/components/JSONUIShowcasePage.tsx +++ b/src/components/JSONUIShowcasePage.tsx @@ -3,6 +3,7 @@ import { AtomicComponentDemo } from '@/components/AtomicComponentDemo' import { DashboardDemoPage } from '@/components/DashboardDemoPage' import { PageRenderer } from '@/lib/json-ui/page-renderer' import { hydrateSchema } from '@/schemas/schema-loader' +import { feedbackAtomsDemoSchema } from '@/schemas/page-schemas' import todoListJson from '@/schemas/todo-list.json' import newMoleculesShowcaseJson from '@/schemas/new-molecules-showcase.json' @@ -24,6 +25,7 @@ export function JSONUIShowcasePage() { Atomic Components + Feedback Atoms New Molecules JSON Dashboard JSON Todo List @@ -34,6 +36,10 @@ export function JSONUIShowcasePage() { + + + + diff --git a/src/lib/component-definitions.ts b/src/lib/component-definitions.ts index 8093398..d9d8c71 100644 --- a/src/lib/component-definitions.ts +++ b/src/lib/component-definitions.ts @@ -7,6 +7,23 @@ export interface ComponentDefinition { icon: string defaultProps?: Record canHaveChildren?: boolean + props?: ComponentPropDefinition[] + events?: ComponentEventDefinition[] +} + +export interface ComponentPropDefinition { + name: string + type: string + description: string + required?: boolean + defaultValue?: string + options?: string[] + supportsBinding?: boolean +} + +export interface ComponentEventDefinition { + name: string + description: string } export const componentDefinitions: ComponentDefinition[] = [ @@ -256,6 +273,107 @@ export const componentDefinitions: ComponentDefinition[] = [ icon: 'Circle', defaultProps: { status: 'active', children: 'Active' } }, + { + type: 'ErrorBadge', + label: 'Error Badge', + category: 'feedback', + icon: 'WarningCircle', + defaultProps: { count: 3, variant: 'destructive', size: 'md' }, + props: [ + { + name: 'count', + type: 'number', + description: 'Number of errors to display. Hidden when set to 0.', + required: true, + supportsBinding: true, + }, + { + name: 'variant', + type: 'string', + description: 'Visual variant for the badge.', + defaultValue: 'destructive', + options: ['default', 'destructive'], + }, + { + name: 'size', + type: 'string', + description: 'Badge size.', + defaultValue: 'md', + options: ['sm', 'md'], + }, + ], + }, + { + type: 'Notification', + label: 'Notification', + category: 'feedback', + icon: 'Info', + defaultProps: { type: 'info', title: 'Notification', message: 'Details go here.' }, + props: [ + { + name: 'type', + type: 'string', + description: 'Notification style variant.', + required: true, + options: ['info', 'success', 'warning', 'error'], + }, + { + name: 'title', + type: 'string', + description: 'Primary notification title.', + required: true, + supportsBinding: true, + }, + { + name: 'message', + type: 'string', + description: 'Optional supporting message text.', + supportsBinding: true, + }, + { + name: 'className', + type: 'string', + description: 'Optional custom classes for spacing or layout tweaks.', + }, + ], + events: [ + { + name: 'onClose', + description: 'Fires when the close button is clicked. Bind to dismiss or trigger an action.', + }, + ], + }, + { + type: 'StatusIcon', + label: 'Status Icon', + category: 'feedback', + icon: 'CheckCircle', + defaultProps: { type: 'saved', size: 14, animate: false }, + props: [ + { + name: 'type', + type: 'string', + description: 'Status icon style.', + required: true, + supportsBinding: true, + options: ['saved', 'synced'], + }, + { + name: 'size', + type: 'number', + description: 'Icon size in pixels.', + defaultValue: '14', + supportsBinding: true, + }, + { + name: 'animate', + type: 'boolean', + description: 'Applies entry animation when true.', + defaultValue: 'false', + supportsBinding: true, + }, + ], + }, // Data Components { type: 'List', diff --git a/src/schemas/page-schemas.ts b/src/schemas/page-schemas.ts index 46ceb50..025fb26 100644 --- a/src/schemas/page-schemas.ts +++ b/src/schemas/page-schemas.ts @@ -73,3 +73,117 @@ export const stateBindingsDemoSchema: PageSchema = { }, ], } + +export const feedbackAtomsDemoSchema: PageSchema = { + id: 'feedback-atoms-demo', + name: 'Feedback Atoms Demo', + layout: { + type: 'single', + }, + dataSources: [ + { + id: 'errorCount', + type: 'static', + defaultValue: 3, + }, + { + id: 'showNotification', + type: 'static', + defaultValue: true, + }, + { + id: 'statusType', + type: 'static', + defaultValue: 'saved', + }, + ], + components: [ + { + id: 'feedback-atoms-root', + type: 'div', + props: { + className: 'space-y-6 rounded-lg border border-border bg-card p-6', + }, + children: [ + { + id: 'feedback-atoms-title', + type: 'Heading', + props: { + className: 'text-lg font-semibold', + children: 'Feedback Atoms', + }, + }, + { + id: 'feedback-atoms-row', + type: 'div', + props: { + className: 'flex flex-wrap items-center gap-6', + }, + children: [ + { + id: 'feedback-atoms-status-icon', + type: 'StatusIcon', + props: { + animate: true, + size: 18, + }, + bindings: { + type: { + source: 'statusType', + sourceType: 'data', + }, + }, + }, + { + id: 'feedback-atoms-badge-wrapper', + type: 'div', + props: { + className: 'relative h-10 w-10 rounded-full bg-muted', + }, + children: [ + { + id: 'feedback-atoms-error-badge', + type: 'ErrorBadge', + props: { + variant: 'destructive', + size: 'md', + }, + bindings: { + count: { + source: 'errorCount', + sourceType: 'data', + }, + }, + }, + ], + }, + ], + }, + { + id: 'feedback-atoms-notification', + type: 'Notification', + props: { + type: 'info', + title: 'Heads up!', + message: 'You have unsent changes ready to sync.', + }, + conditional: { + if: 'data.showNotification', + }, + events: { + onClose: { + actions: [ + { + id: 'dismiss-notification', + type: 'set-value', + target: 'showNotification', + value: false, + }, + ], + }, + }, + }, + ], + }, + ], +} diff --git a/src/types/json-ui.ts b/src/types/json-ui.ts index f3ce4c3..9b64f2e 100644 --- a/src/types/json-ui.ts +++ b/src/types/json-ui.ts @@ -6,6 +6,7 @@ export type ComponentType = | 'Text' | 'Heading' | 'Label' | 'List' | 'Grid' | 'Stack' | 'Flex' | 'Container' | 'Link' | 'Image' | 'Avatar' | 'Code' | 'Tag' | 'Spinner' | 'Skeleton' | 'Alert' | 'InfoBox' | 'EmptyState' | 'StatusBadge' + | 'ErrorBadge' | 'Notification' | 'StatusIcon' | 'Table' | 'KeyValue' | 'StatCard' | 'DataCard' | 'SearchInput' | 'ActionBar' | 'AppBranding' | 'LabelWithBadge' | 'EmptyEditorState' | 'LoadingFallback' | 'LoadingState' | 'NavigationGroupHeader'