mirror of
https://github.com/johndoe6345789/low-code-react-app-b.git
synced 2026-04-25 22:25:01 +00:00
Compare commits
1 Commits
copilot/re
...
codex/inte
| Author | SHA1 | Date | |
|---|---|---|---|
| 5d007721cf |
@@ -2,7 +2,7 @@
|
|||||||
"$schema": "./schemas/json-components-registry-schema.json",
|
"$schema": "./schemas/json-components-registry-schema.json",
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"description": "Registry of all components in the application",
|
"description": "Registry of all components in the application",
|
||||||
"lastUpdated": "2026-01-17T22:10:22.582Z",
|
"lastUpdated": "2026-01-18T11:30:41.908Z",
|
||||||
"categories": {
|
"categories": {
|
||||||
"layout": "Layout and container components",
|
"layout": "Layout and container components",
|
||||||
"input": "Form inputs and interactive controls",
|
"input": "Form inputs and interactive controls",
|
||||||
@@ -322,7 +322,7 @@
|
|||||||
"category": "input",
|
"category": "input",
|
||||||
"canHaveChildren": false,
|
"canHaveChildren": false,
|
||||||
"description": "Date selection input",
|
"description": "Date selection input",
|
||||||
"status": "planned",
|
"status": "supported",
|
||||||
"source": "atoms"
|
"source": "atoms"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -331,7 +331,7 @@
|
|||||||
"category": "input",
|
"category": "input",
|
||||||
"canHaveChildren": false,
|
"canHaveChildren": false,
|
||||||
"description": "File upload control",
|
"description": "File upload control",
|
||||||
"status": "planned",
|
"status": "supported",
|
||||||
"source": "atoms"
|
"source": "atoms"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -2043,8 +2043,8 @@
|
|||||||
],
|
],
|
||||||
"statistics": {
|
"statistics": {
|
||||||
"total": 219,
|
"total": 219,
|
||||||
"supported": 150,
|
"supported": 152,
|
||||||
"planned": 14,
|
"planned": 12,
|
||||||
"jsonCompatible": 14,
|
"jsonCompatible": 14,
|
||||||
"maybeJsonCompatible": 41,
|
"maybeJsonCompatible": 41,
|
||||||
"byCategory": {
|
"byCategory": {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { PageRenderer } from '@/lib/json-ui/page-renderer'
|
|||||||
import { hydrateSchema } from '@/schemas/schema-loader'
|
import { hydrateSchema } from '@/schemas/schema-loader'
|
||||||
import todoListJson from '@/schemas/todo-list.json'
|
import todoListJson from '@/schemas/todo-list.json'
|
||||||
import newMoleculesShowcaseJson from '@/schemas/new-molecules-showcase.json'
|
import newMoleculesShowcaseJson from '@/schemas/new-molecules-showcase.json'
|
||||||
|
import { inputComponentsShowcaseSchema } from '@/schemas/page-schemas'
|
||||||
|
|
||||||
const todoListSchema = hydrateSchema(todoListJson)
|
const todoListSchema = hydrateSchema(todoListJson)
|
||||||
const newMoleculesShowcaseSchema = hydrateSchema(newMoleculesShowcaseJson)
|
const newMoleculesShowcaseSchema = hydrateSchema(newMoleculesShowcaseJson)
|
||||||
@@ -24,6 +25,7 @@ export function JSONUIShowcasePage() {
|
|||||||
</div>
|
</div>
|
||||||
<TabsList className="w-full justify-start">
|
<TabsList className="w-full justify-start">
|
||||||
<TabsTrigger value="atomic">Atomic Components</TabsTrigger>
|
<TabsTrigger value="atomic">Atomic Components</TabsTrigger>
|
||||||
|
<TabsTrigger value="inputs">JSON Inputs</TabsTrigger>
|
||||||
<TabsTrigger value="molecules">New Molecules</TabsTrigger>
|
<TabsTrigger value="molecules">New Molecules</TabsTrigger>
|
||||||
<TabsTrigger value="dashboard">JSON Dashboard</TabsTrigger>
|
<TabsTrigger value="dashboard">JSON Dashboard</TabsTrigger>
|
||||||
<TabsTrigger value="todos">JSON Todo List</TabsTrigger>
|
<TabsTrigger value="todos">JSON Todo List</TabsTrigger>
|
||||||
@@ -35,6 +37,10 @@ export function JSONUIShowcasePage() {
|
|||||||
<AtomicComponentDemo />
|
<AtomicComponentDemo />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
|
<TabsContent value="inputs" className="h-full m-0 data-[state=active]:block">
|
||||||
|
<PageRenderer schema={inputComponentsShowcaseSchema} />
|
||||||
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="molecules" className="h-full m-0 data-[state=active]:block">
|
<TabsContent value="molecules" className="h-full m-0 data-[state=active]:block">
|
||||||
<PageRenderer schema={newMoleculesShowcaseSchema} />
|
<PageRenderer schema={newMoleculesShowcaseSchema} />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { cn } from '@/lib/utils'
|
|||||||
|
|
||||||
interface DatePickerProps {
|
interface DatePickerProps {
|
||||||
value?: Date
|
value?: Date
|
||||||
onChange: (date: Date | undefined) => void
|
onChange?: (date: Date | undefined) => void
|
||||||
placeholder?: string
|
placeholder?: string
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
className?: string
|
className?: string
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ interface FileUploadProps {
|
|||||||
accept?: string
|
accept?: string
|
||||||
multiple?: boolean
|
multiple?: boolean
|
||||||
maxSize?: number
|
maxSize?: number
|
||||||
onFilesSelected: (files: File[]) => void
|
onFilesSelected?: (files: File[]) => void
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
className?: string
|
className?: string
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ export function FileUpload({
|
|||||||
})
|
})
|
||||||
|
|
||||||
setSelectedFiles(validFiles)
|
setSelectedFiles(validFiles)
|
||||||
onFilesSelected(validFiles)
|
onFilesSelected?.(validFiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDrop = (e: React.DragEvent) => {
|
const handleDrop = (e: React.DragEvent) => {
|
||||||
@@ -59,7 +59,7 @@ export function FileUpload({
|
|||||||
const removeFile = (index: number) => {
|
const removeFile = (index: number) => {
|
||||||
const newFiles = selectedFiles.filter((_, i) => i !== index)
|
const newFiles = selectedFiles.filter((_, i) => i !== index)
|
||||||
setSelectedFiles(newFiles)
|
setSelectedFiles(newFiles)
|
||||||
onFilesSelected(newFiles)
|
onFilesSelected?.(newFiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export interface ComponentDefinition {
|
|||||||
category: 'layout' | 'input' | 'display' | 'navigation' | 'feedback' | 'data' | 'custom'
|
category: 'layout' | 'input' | 'display' | 'navigation' | 'feedback' | 'data' | 'custom'
|
||||||
icon: string
|
icon: string
|
||||||
defaultProps?: Record<string, any>
|
defaultProps?: Record<string, any>
|
||||||
|
propSchema?: Record<string, { type: string; description?: string; required?: boolean }>
|
||||||
canHaveChildren?: boolean
|
canHaveChildren?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,6 +98,33 @@ export const componentDefinitions: ComponentDefinition[] = [
|
|||||||
icon: 'CaretDown',
|
icon: 'CaretDown',
|
||||||
defaultProps: { placeholder: 'Choose option...' }
|
defaultProps: { placeholder: 'Choose option...' }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'DatePicker',
|
||||||
|
label: 'Date Picker',
|
||||||
|
category: 'input',
|
||||||
|
icon: 'Calendar',
|
||||||
|
defaultProps: { placeholder: 'Pick a date' },
|
||||||
|
propSchema: {
|
||||||
|
value: { type: 'date', description: 'Selected date value' },
|
||||||
|
placeholder: { type: 'string', description: 'Placeholder when no date is selected' },
|
||||||
|
disabled: { type: 'boolean', description: 'Disable the date picker' },
|
||||||
|
onChange: { type: 'event', description: 'Fires when the date selection changes' }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'FileUpload',
|
||||||
|
label: 'File Upload',
|
||||||
|
category: 'input',
|
||||||
|
icon: 'Upload',
|
||||||
|
defaultProps: { accept: '', multiple: false },
|
||||||
|
propSchema: {
|
||||||
|
accept: { type: 'string', description: 'Accepted file types (comma-separated)' },
|
||||||
|
multiple: { type: 'boolean', description: 'Allow multiple file selections' },
|
||||||
|
maxSize: { type: 'number', description: 'Maximum file size in bytes' },
|
||||||
|
disabled: { type: 'boolean', description: 'Disable file uploads' },
|
||||||
|
onFilesSelected: { type: 'event', description: 'Fires when files are selected' }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'Checkbox',
|
type: 'Checkbox',
|
||||||
label: 'Checkbox',
|
label: 'Checkbox',
|
||||||
|
|||||||
@@ -136,10 +136,14 @@ export const shadcnComponents: UIComponentRegistry = {
|
|||||||
AvatarImage,
|
AvatarImage,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const atomComponents: UIComponentRegistry = buildRegistryFromNames(
|
export const atomComponents: UIComponentRegistry = {
|
||||||
atomRegistryNames,
|
...buildRegistryFromNames(
|
||||||
AtomComponents as Record<string, ComponentType<any>>
|
atomRegistryNames,
|
||||||
)
|
AtomComponents as Record<string, ComponentType<any>>
|
||||||
|
),
|
||||||
|
DatePicker: AtomComponents.DatePicker,
|
||||||
|
FileUpload: AtomComponents.FileUpload,
|
||||||
|
}
|
||||||
|
|
||||||
export const moleculeComponents: UIComponentRegistry = buildRegistryFromNames(
|
export const moleculeComponents: UIComponentRegistry = buildRegistryFromNames(
|
||||||
moleculeRegistryNames,
|
moleculeRegistryNames,
|
||||||
|
|||||||
@@ -73,3 +73,147 @@ export const stateBindingsDemoSchema: PageSchema = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const inputComponentsShowcaseSchema: PageSchema = {
|
||||||
|
id: 'input-components-showcase',
|
||||||
|
name: 'Input Components Showcase',
|
||||||
|
layout: {
|
||||||
|
type: 'single',
|
||||||
|
},
|
||||||
|
dataSources: [
|
||||||
|
{
|
||||||
|
id: 'selectedDate',
|
||||||
|
type: 'static',
|
||||||
|
defaultValue: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'uploadedFiles',
|
||||||
|
type: 'static',
|
||||||
|
defaultValue: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
components: [
|
||||||
|
{
|
||||||
|
id: 'input-showcase-root',
|
||||||
|
type: 'div',
|
||||||
|
props: {
|
||||||
|
className: 'space-y-6 rounded-lg border border-border bg-card p-6',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 'input-showcase-title',
|
||||||
|
type: 'Heading',
|
||||||
|
props: {
|
||||||
|
className: 'text-xl font-semibold',
|
||||||
|
children: 'Date Picker & File Upload',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'input-showcase-date-section',
|
||||||
|
type: 'div',
|
||||||
|
props: {
|
||||||
|
className: 'space-y-3',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 'input-showcase-date-label',
|
||||||
|
type: 'Text',
|
||||||
|
props: {
|
||||||
|
className: 'text-sm font-medium text-muted-foreground',
|
||||||
|
children: 'Pick a date',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'input-showcase-date-picker',
|
||||||
|
type: 'DatePicker',
|
||||||
|
props: {
|
||||||
|
placeholder: 'Select a date',
|
||||||
|
},
|
||||||
|
bindings: {
|
||||||
|
value: {
|
||||||
|
source: 'selectedDate',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
events: {
|
||||||
|
onChange: {
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
id: 'update-selected-date',
|
||||||
|
type: 'set-value',
|
||||||
|
target: 'selectedDate',
|
||||||
|
expression: 'event',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'input-showcase-date-value',
|
||||||
|
type: 'Text',
|
||||||
|
props: {
|
||||||
|
className: 'text-sm text-muted-foreground',
|
||||||
|
},
|
||||||
|
bindings: {
|
||||||
|
children: {
|
||||||
|
source: 'selectedDate',
|
||||||
|
transform: 'data ? `Selected: ${new Date(data).toLocaleDateString()}` : "Selected: none"',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'input-showcase-file-section',
|
||||||
|
type: 'div',
|
||||||
|
props: {
|
||||||
|
className: 'space-y-3',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 'input-showcase-file-label',
|
||||||
|
type: 'Text',
|
||||||
|
props: {
|
||||||
|
className: 'text-sm font-medium text-muted-foreground',
|
||||||
|
children: 'Upload files',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'input-showcase-file-upload',
|
||||||
|
type: 'FileUpload',
|
||||||
|
props: {
|
||||||
|
accept: '.pdf,.png,.jpg,.jpeg',
|
||||||
|
multiple: true,
|
||||||
|
maxSize: 5000000,
|
||||||
|
},
|
||||||
|
events: {
|
||||||
|
onFilesSelected: {
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
id: 'update-uploaded-files',
|
||||||
|
type: 'set-value',
|
||||||
|
target: 'uploadedFiles',
|
||||||
|
expression: 'event',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'input-showcase-file-value',
|
||||||
|
type: 'Text',
|
||||||
|
props: {
|
||||||
|
className: 'text-sm text-muted-foreground',
|
||||||
|
},
|
||||||
|
bindings: {
|
||||||
|
children: {
|
||||||
|
source: 'uploadedFiles',
|
||||||
|
transform: 'Array.isArray(data) && data.length ? `Selected: ${data.map((file) => file.name).join(", ")}` : "Selected: none"',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ export type ComponentType =
|
|||||||
| 'div' | 'section' | 'article' | 'header' | 'footer' | 'main'
|
| 'div' | 'section' | 'article' | 'header' | 'footer' | 'main'
|
||||||
| 'Button' | 'Card' | 'CardHeader' | 'CardTitle' | 'CardDescription' | 'CardContent' | 'CardFooter'
|
| 'Button' | 'Card' | 'CardHeader' | 'CardTitle' | 'CardDescription' | 'CardContent' | 'CardFooter'
|
||||||
| 'Input' | 'TextArea' | 'Textarea' | 'Select' | 'Checkbox' | 'Radio' | 'Switch' | 'Slider' | 'NumberInput'
|
| 'Input' | 'TextArea' | 'Textarea' | 'Select' | 'Checkbox' | 'Radio' | 'Switch' | 'Slider' | 'NumberInput'
|
||||||
|
| 'DatePicker' | 'FileUpload'
|
||||||
| 'Badge' | 'Progress' | 'Separator' | 'Tabs' | 'TabsContent' | 'TabsList' | 'TabsTrigger' | 'Dialog'
|
| 'Badge' | 'Progress' | 'Separator' | 'Tabs' | 'TabsContent' | 'TabsList' | 'TabsTrigger' | 'Dialog'
|
||||||
| 'Text' | 'Heading' | 'Label' | 'List' | 'Grid' | 'Stack' | 'Flex' | 'Container'
|
| 'Text' | 'Heading' | 'Label' | 'List' | 'Grid' | 'Stack' | 'Flex' | 'Container'
|
||||||
| 'Link' | 'Image' | 'Avatar' | 'Code' | 'Tag' | 'Spinner' | 'Skeleton'
|
| 'Link' | 'Image' | 'Avatar' | 'Code' | 'Tag' | 'Spinner' | 'Skeleton'
|
||||||
|
|||||||
Reference in New Issue
Block a user