8.2 KiB
Component Conversion Analysis
Analysis of 68 React Components
After analyzing all 68 organism and molecule components, here's what can be converted to JSON:
Categories
✅ Fully Convertible to JSON (48 components)
These are presentational components with props, conditional rendering, and simple event handlers:
Molecules (35):
LabelWithBadge- ✅ ConvertedLoadingState- ✅ ConvertedSaveIndicator- ✅ Converted (computed sources replace hook)SearchInput- ✅ ConvertedAppBranding- Props + conditionalsActionBar- Layout + buttonsBreadcrumb- ✅ Already convertedDataCard- ✅ Already convertedEmptyState- ✅ Already convertedEmptyEditorState- ✅ Already convertedFileTabs- ✅ Already convertedNavigationGroupHeader- Collapse trigger + stateNavigationItem- Button with active statePageHeaderContent- Layout compositionToolbarButton- Tooltip + IconButtonTreeListHeader- Buttons with eventsComponentTreeEmptyState- Config + icon lookupComponentTreeHeader- Counts + expand/collapsePropertyEditorEmptyState- Config + icon lookupPropertyEditorHeader- Title + countPropertyEditorSection- Collapsible sectionDataSourceIdField- Input with validation displayKvSourceFields- Form fieldsStaticSourceFields- Form fieldsComputedSourceFields- Form fieldsGitHubBuildStatus- Status display + pollingLoadingFallback- Spinner + messageMonacoEditorPanel- Layout wrapper (not editor itself)SearchBar- SearchInput wrapperSeedDataManager- Form + buttons (logic in parent)StorageSettings- Form fieldsTreeCard- Card + tree displayTreeFormDialog- Dialog with form (validation in parent)EditorActions- Button groupEditorToolbar- Toolbar layout
Organisms (13):
AppHeader- ✅ Already convertedEmptyCanvasState- ✅ Already convertedNavigationMenu- ✅ Already convertedPageHeader- ✅ Already convertedSchemaEditorLayout- ✅ Already convertedSchemaEditorSidebar- ✅ Already convertedSchemaEditorCanvas- ✅ Already convertedSchemaEditorPropertiesPanel- ✅ Already convertedSchemaEditorStatusBar- Status displaySchemaEditorToolbar- Toolbar with actionsToolbarActions- Action buttonsSchemaCodeViewer- Tabs + code displayTreeListPanel- List display
⚠️ Needs Wrapper (Complex Hooks) (12 components)
These use hooks but the hook logic can be extracted to data sources or remain in a thin wrapper:
Molecules (10):
BindingEditor- Form withuseFormhook → Extract to form stateComponentBindingDialog- Dialog withuseForm→ Extract to form stateDataSourceEditorDialog- Complex form + validation → Wrapper + JSON formPropertyEditor- Dynamic form generation → Computed source for fieldsComponentPalette- Search + filter → Computed sourceCanvasRenderer- Recursive rendering → Could be JSON with loop supportComponentTree- Tree state + drag/drop → State machine in JSONComponentTreeNodes- Recursive nodes → Loop constructCodeExplanationDialog- Dialog + API call → Dialog JSON + API actionDataSourceCard- Card with actions + state → Separate state, JSON layout
Organisms (2):
DataSourceManager- Complex CRUD + hook → ExtractuseDataSourceManagerlogicJSONUIShowcase- Examples display → Convert examples to JSON schema
❌ Must Stay React (8 components)
These have imperative APIs, complex recursion, or third-party integration:
Molecules (6):
LazyMonacoEditor- Monaco integration (refs, imperative API)LazyInlineMonacoEditor- Monaco integrationMonacoEditorPanel- Monaco wrapperLazyBarChart- Recharts integrationLazyLineChart- Recharts integrationLazyD3BarChart- D3.js integration (imperative DOM manipulation)
Organisms (2):
SchemaEditor- Complex editor with drag-drop, undo/redo state machineDataBindingDesigner- Visual flow editor with canvas manipulation
Conversion Statistics
| Category | Count | Percentage |
|---|---|---|
| ✅ Fully Convertible | 48 | 71% |
| ⚠️ Needs Wrapper | 12 | 18% |
| ❌ Must Stay React | 8 | 11% |
| Total | 68 | 100% |
Key Insights
1. Most Components Are Presentational
71% of components are pure presentation + simple logic that JSON can handle with:
- Data binding
- Computed sources
- Conditional rendering
- Event actions
- Loops (for lists)
2. Hooks Aren't a Blocker
Even components with hooks like useSaveIndicator can be converted:
- Time-based logic → Computed sources with polling
- Form state → Form data sources
- Local UI state → Page-level state
3. True Blockers
Only 8 components (11%) genuinely need React:
- Third-party library integrations (Monaco, D3, Recharts)
- Complex state machines (drag-drop, undo/redo)
- Imperative DOM manipulation
- Recursive algorithms (though loops might handle some)
4. Wrapper Pattern
The 12 "needs wrapper" components can have thin React wrappers that:
- Extract hooks to data source utilities
- Convert to JSON-configurable components
- Keep complex logic centralized
Example:
// Thin wrapper
export function FormDialogWrapper({ schema, onSubmit }) {
const form = useForm()
return <JSONDialog schema={schema} formState={form} onSubmit={onSubmit} />
}
// JSON configures it
{
"type": "FormDialogWrapper",
"props": {
"schema": { "$ref": "./schemas/user-form.json" }
}
}
Recommended Conversion Priority
Phase 1: Low-Hanging Fruit (35 molecules)
Convert all presentational molecules that are just composition:
- AppBranding, ActionBar, ToolbarButton, etc.
- Impact: Eliminate 51% of React components
Phase 2: Organisms (13)
Convert layout organisms:
- TreeListPanel, SchemaCodeViewer, etc.
- Impact: Eliminate 70% of React components
Phase 3: Extract Hooks (10 molecules)
Create data source utilities and convert:
- BindingEditor, ComponentPalette, etc.
- Impact: Eliminate 85% of React components
Phase 4: Wrappers (2 organisms)
Create thin wrappers for complex components:
- DataSourceManager, JSONUIShowcase
- Impact: 89% conversion
Final State
- 8 React components (third-party integrations + complex editors)
- 60 JSON components (89% of current React code)
- 100% JSON page definitions (already achieved)
Implementation Patterns
Pattern 1: Simple Conversion
// React
export function LabelWithBadge({ label, badge }) {
return (
<Flex>
<Text>{label}</Text>
{badge && <Badge>{badge}</Badge>}
</Flex>
)
}
// JSON
{
"type": "div",
"className": "flex gap-2",
"children": [
{ "type": "Text", "dataBinding": { "children": { "source": "label" } } },
{
"type": "Badge",
"conditional": { "source": "badge", "operator": "truthy" },
"dataBinding": { "children": { "source": "badge" } }
}
]
}
Pattern 2: Hook Extraction
// React (before)
export function SaveIndicator({ lastSaved }) {
const { timeAgo, isRecent } = useSaveIndicator(lastSaved)
return <div>{isRecent ? 'Saved' : timeAgo}</div>
}
// JSON (after) - hook logic → computed source
{
"dataSources": [
{
"id": "isRecent",
"type": "computed",
"compute": "(data) => Date.now() - data.lastSaved < 3000"
}
],
"type": "div",
"dataBinding": {
"children": {
"source": "isRecent",
"transform": "(isRecent, data) => isRecent ? 'Saved' : data.timeAgo"
}
}
}
Pattern 3: Wrapper for Complex Logic
// Thin React wrapper
export function DataSourceManagerWrapper(props) {
const manager = useDataSourceManager(props.dataSources)
return <JSONComponent schema={schema} data={manager} />
}
Next Steps
- ✅ Convert 35 simple molecules to JSON
- ✅ Convert 13 layout organisms to JSON
- ⚠️ Extract hooks to utilities for 10 components
- ⚠️ Create wrappers for 2 complex organisms
- ❌ Keep 8 third-party integrations as React
Target: 60/68 components in JSON (89% conversion)