- Introduced `menu.json` for menu component structure with bindings for trigger and content. - Created `password-input.json` for password input handling visibility and value changes. - Added `popover.json` for popover component with trigger and content bindings. feat: Implement custom hooks for UI interactions - Added `useAccordion` for managing accordion state with single/multiple item support. - Created `useBindingEditor` for managing bindings in a dynamic editor. - Implemented `useCopyState` for clipboard copy functionality with feedback. - Developed `useFileUpload` for handling file uploads with drag-and-drop support. - Introduced `useFocusState` for managing focus state in components. - Created `useImageState` for handling image loading and error states. - Added `useMenuState` for managing menu interactions and item clicks. - Implemented `usePasswordVisibility` for toggling password visibility. - Developed `usePopoverState` for managing popover visibility and interactions. feat: Add constants and interfaces for JSON UI components - Introduced constants for sizes, placements, styles, and object-fit handling. - Created interfaces for various components including Accordion, Binding Editor, Copy Button, Data Source Editor, File Upload, and more. - Added type definitions for menu items, popover props, and other UI elements to enhance type safety and maintainability.
12 KiB
Claude Code Documentation
Architecture Overview
This is a low-code React application builder that is migrating from TypeScript/TSX components to a JSON-driven architecture.
Current State (Jan 2026)
- ~420 TSX files in
src/components/(legacy - being phased out) - 338 JSON definitions in
src/config/pages/(target architecture) - 342 entries in
json-components-registry.json - 19 complete JSON implementations in
src/components/json-definitions/ - 141 duplicate TSX files deleted (had JSON equivalents)
- 5 atoms remaining to convert: Accordion, FileUpload, Image, Menu, Popover
- 1 molecule remaining: BindingEditor
- 3 organisms remaining: DataSourceManager, NavigationMenu, TreeListPanel
Migration Strategy
Core Principle
ALL components can be converted to JSON except the application entrypoint, because custom hooks can handle any stateful/complex logic.
Directory Structure
src/
├── components/ # 🔴 LEGACY - Phase out
│ ├── atoms/ # Basic UI components (6 TSX remaining)
│ │ ├── json-ui/ # JSON-specific atoms
│ │ ├── Accordion.tsx
│ │ ├── FileUpload.tsx
│ │ ├── Image.tsx
│ │ ├── Menu.tsx
│ │ └── Popover.tsx
│ ├── molecules/ # Composite components (1 TSX remaining)
│ │ └── BindingEditor.tsx
│ ├── organisms/ # Complex feature components (3 TSX remaining)
│ │ ├── DataSourceManager.tsx
│ │ ├── NavigationMenu.tsx
│ │ └── TreeListPanel.tsx
│ └── json-definitions/ # ✅ JSON implementations (19 files)
│ ├── loading-fallback.json
│ ├── navigation-item.json
│ ├── page-header-content.json
│ ├── component-binding-dialog.json
│ ├── data-source-editor-dialog.json
│ ├── github-build-status.json
│ ├── save-indicator.json
│ ├── component-tree.json
│ ├── seed-data-manager.json
│ ├── lazy-d3-bar-chart.json
│ ├── storage-settings.json
│ ├── tree-card.json
│ ├── filter-input.json
│ ├── copy-button.json
│ ├── input.json
│ └── password-input.json
│
├── config/
│ ├── pages/ # ✅ TARGET - JSON definitions (338 files)
│ │ ├── atoms/ # JSON schema for atoms
│ │ ├── molecules/ # JSON schema for molecules
│ │ ├── organisms/ # JSON schema for organisms
│ │ ├── templates/ # Page templates
│ │ └── *.json # Page definitions
│ └── pages.json # Central routing manifest
│
├── hooks/ # ✅ Custom hooks for JSON components
│ ├── use-save-indicator.ts
│ ├── use-component-tree.ts
│ ├── use-storage-backend-info.ts
│ ├── use-d3-bar-chart.ts
│ ├── use-focus-state.ts # NEW: For FilterInput
│ ├── use-copy-state.ts # NEW: For CopyButton
│ ├── use-password-visibility.ts # NEW: For PasswordInput
│ └── index.ts
│
├── lib/
│ └── json-ui/
│ ├── component-registry.ts # Component resolver
│ ├── component-renderer.tsx # JSON → React renderer
│ ├── json-components.ts # JSON component exports (27 components)
│ ├── create-json-component.tsx # Pure JSON component factory
│ ├── create-json-component-with-hooks.tsx # JSON + hooks factory
│ ├── hooks.ts # Data source/action hooks
│ ├── hooks-registry.ts # Hook registration (12 hooks registered)
│ ├── constants/ # Shared constants for JSON transforms
│ │ ├── sizes.ts # Button sizes, icon sizes, dimensions
│ │ ├── placements.ts # Popover/tooltip positioning
│ │ ├── styles.ts # Common CSS classes (transitions, animations, etc.)
│ │ ├── object-fit.ts # Image object-fit classes
│ │ └── index.ts
│ └── interfaces/ # TypeScript interfaces (1 per file)
│ ├── loading-fallback.ts
│ ├── navigation-item.ts
│ ├── page-header-content.ts
│ ├── save-indicator.ts
│ ├── lazy-bar-chart.ts
│ ├── lazy-line-chart.ts
│ ├── lazy-d3-bar-chart.ts
│ ├── seed-data-manager.ts
│ ├── storage-settings.ts
│ ├── github-build-status.ts
│ ├── component-binding-dialog.ts
│ ├── data-source-editor-dialog.ts
│ ├── component-tree.ts
│ ├── tree-card.ts
│ ├── filter-input.ts
│ ├── copy-button.ts
│ ├── input.ts
│ ├── password-input.ts
│ ├── image.ts
│ ├── popover.ts
│ ├── menu.ts
│ ├── file-upload.ts
│ ├── accordion.ts
│ └── index.ts
│
├── scripts/ # Migration and audit tools
│ ├── audit-json-components.ts
│ ├── analyze-duplicates.ts
│ ├── cleanup-registry.ts
│ └── fix-index-files.ts
│
└── json-components-registry.json # Master component registry
How It Works
1. Routing Flow
pages.json → json-components-registry.json → Component Implementation
Example:
// pages.json
{
"id": "dashboard",
"component": "ProjectDashboard"
}
// json-components-registry.json
{
"type": "ProjectDashboard",
"source": "organisms",
"load": {
"path": "@/components/ProjectDashboard",
"export": "ProjectDashboard"
}
}
2. Component Types
Pure JSON Components (No Hooks)
Simple stateless components defined entirely in JSON:
// src/components/json-definitions/tree-card.json
{
"id": "tree-card-container",
"type": "Card",
"bindings": {
"className": {
"source": "isSelected",
"transform": "data ? 'ring-2 ring-primary' : 'hover:bg-accent/50'"
}
},
"children": [...]
}
Exported from src/lib/json-ui/json-components.ts:
import treeCardDef from '@/components/json-definitions/tree-card.json'
export const TreeCard = createJsonComponent<TreeCardProps>(treeCardDef)
JSON Components with Hooks
Stateful components using custom hooks (NO WRAPPER FILES NEEDED):
// src/lib/json-ui/json-components.ts
export const ComponentTree = createJsonComponentWithHooks<ComponentTreeProps>(
componentTreeDef,
{
hooks: {
treeData: {
hookName: 'useComponentTree',
args: (props) => [props.components || [], props.selectedId || null]
}
}
}
)
The custom hook is defined in src/hooks/use-component-tree.ts (or other hook files) and registered in src/lib/json-ui/hooks-registry.ts.
TSX Components (Legacy)
Currently imported directly - these need migration:
// ❌ OLD: Direct TSX import
import { AppBranding } from '@/components/molecules/AppBranding'
// ✅ NEW: JSON-based import
import { AppBranding } from '@/lib/json-ui/json-components'
3. Registry System
The json-components-registry.json defines how components are loaded:
{
"type": "SaveIndicator",
"source": "molecules",
"jsonCompatible": true
}
- jsonCompatible: Whether component can be expressed as JSON
- load.path: Explicit path to component file (for TSX legacy components)
- source: Where the component comes from (atoms, molecules, organisms, ui)
Note: wrapperRequired and wrapperComponent fields in the registry are obsolete and should be removed. All stateful logic is handled via createJsonComponentWithHooks.
Current Issues (Jan 2026)
Audit Results
Run npm run audit:json to see current status:
-
❌ Errors
- 6 orphaned JSON files (no registry entry)
- 7 broken load paths
-
⚠️ 153 warnings
- 153 duplicate implementations (TSX + JSON)
Critical Tasks
-
Phase Out
src/components/- 153 components have both TSX and JSON definitions
- TSX versions should be deleted and routed through JSON
-
Clean Up Registry
- Remove
wrapperRequiredandwrapperComponentfields (obsolete) - All stateful logic is handled via
createJsonComponentWithHooks - Custom hooks defined in
src/lib/json-ui/hooks.ts
- Remove
-
Fix Registry Issues
- Add missing registry entries for orphaned JSON
- Fix broken load paths
- Verify all source mappings
Migration Checklist
For each component:
- Create JSON definition in
src/components/json-definitions/ - Add TypeScript interface in
src/lib/json-ui/interfaces/(one file per interface) - If stateful: Define custom hook in
src/hooks/use-[component-name].ts - If stateful: Register hook in
src/lib/json-ui/hooks-registry.ts - If stateful: Export hook from
src/hooks/index.ts - Export from
src/lib/json-ui/json-components.ts:- Use
createJsonComponentfor pure/stateless - Use
createJsonComponentWithHooksfor stateful
- Use
- Update registry in
json-components-registry.json - Update all imports to use
@/lib/json-ui/json-components - Delete legacy TSX file from
src/components/ - Run tests and build to verify
Useful Commands
# Run audit to check migration status
npm run audit:json
# Generate component types
npm run components:generate-types
# Build (will fail if components missing)
npm run build
Key Files
json-components-registry.json- Master registry of all componentssrc/config/pages.json- Page routing configurationsrc/lib/json-ui/component-registry.ts- Component resolver logicsrc/lib/json-ui/json-components.ts- JSON component exportssrc/lib/json-ui/hooks.ts- Custom hooks for stateful componentssrc/lib/json-ui/hooks-registry.ts- Hook registrationscripts/audit-json-components.ts- Audit tool
Notes
- Never create new TSX components - use JSON instead
- All components can be JSON except the app entrypoint
- Use custom hooks for stateful logic (via
createJsonComponentWithHooks) - NO wrapper files needed - hooks are defined in
hooks.tsand registered inhooks-registry.ts - One interface per file in
src/lib/json-ui/interfaces/ - Meta JSON files in
src/config/pages/are routing schemas - Full JSON definitions live in
src/components/json-definitions/
Recent Changes (Jan 2026)
Phase 1: Setup & Cleanup
- ✅ Fixed e2e build failures (TreeCard, TreeListHeader routing)
- ✅ Removed 8 initial duplicate TSX files with JSON equivalents
- ✅ Split wrapper-interfaces.ts into individual interface files
- ✅ Created audit script to track migration progress
- ✅ Updated imports to use
@/lib/json-ui/json-components - ✅ Clarified: NO wrapper system - use JSON + custom hooks
Phase 2: Mass Cleanup
- ✅ Cleaned registry - removed 107 obsolete
wrapperRequired/wrapperComponentfields - ✅ Analyzed 153 duplicates, categorized safe deletions
- ✅ Deleted 141 duplicate TSX files (had complete JSON implementations)
- ✅ Created fix-index-files.ts script to auto-update exports
Phase 3: Active Conversions (In Progress)
- ✅ Converted FilterInput to JSON with useFocusState hook
- ✅ Converted CopyButton to JSON with useCopyState hook
- ✅ Converted Input to JSON (pure component with forwardRef support)
- ✅ Converted PasswordInput to JSON with usePasswordVisibility hook
- ✅ Moved custom hooks from
lib/json-ui/hooks.tstosrc/hooks/directory - ✅ Created use-focus-state.ts, use-copy-state.ts, and use-password-visibility.ts
- ✅ Updated hooks-registry.ts to include 7 registered hooks
Remaining Work
- 🔄 5 atoms left: Accordion, FileUpload, Image, Menu, Popover
- 🔄 1 molecule left: BindingEditor
- 🔄 3 organisms left: DataSourceManager, NavigationMenu, TreeListPanel
- ✅ 20 JSON components complete (up from 12)
Next Steps
- Clean up registry - remove
wrapperRequiredandwrapperComponentfields - Convert the 153 duplicate TSX components to JSON-only
- Fix 6 orphaned JSON files (add registry entries)
- Fix 7 broken load paths in registry
- Complete full migration of
src/components/to JSON