diff --git a/src/components/app/AppLayout.tsx b/src/components/app/AppLayout.tsx
index 1fb0ef0..ba9aab1 100644
--- a/src/components/app/AppLayout.tsx
+++ b/src/components/app/AppLayout.tsx
@@ -3,7 +3,7 @@ import { toast } from 'sonner'
import AppDialogs from '@/components/app/AppDialogs'
import AppMainPanel from '@/components/app/AppMainPanel'
-import { NavigationMenu } from '@/components/organisms/NavigationMenu'
+import { NavigationMenu } from '@/lib/json-ui/json-components'
import { SidebarInset, SidebarProvider } from '@/components/ui/sidebar'
import appStrings from '@/data/app-shortcuts.json'
import useAppNavigation from '@/hooks/use-app-navigation'
diff --git a/src/components/app/AppMainPanel.tsx b/src/components/app/AppMainPanel.tsx
index 18708d7..bed429d 100644
--- a/src/components/app/AppMainPanel.tsx
+++ b/src/components/app/AppMainPanel.tsx
@@ -1,6 +1,6 @@
import { Suspense } from 'react'
-import { AppHeader } from '@/components/organisms'
+import { AppHeader } from '@/lib/json-ui/json-components'
import { PWARegistry } from '@/lib/component-registry'
import { RouterProvider } from '@/router'
import type { FeatureToggles, Project } from '@/types/project'
diff --git a/src/components/organisms/AppHeader.tsx b/src/components/organisms/AppHeader.tsx
deleted file mode 100644
index 5e36bb1..0000000
--- a/src/components/organisms/AppHeader.tsx
+++ /dev/null
@@ -1,74 +0,0 @@
-import { AppBranding, Breadcrumb, SaveIndicator } from '@/components/molecules'
-import { SidebarTrigger } from '@/components/ui/sidebar'
-import { ToolbarActions } from '@/components/organisms/ToolbarActions'
-import { ProjectManager } from '@/components/ProjectManager'
-import { FeatureToggles, Project } from '@/types/project'
-import { Flex, Stack, Separator, Container } from '@/components/atoms'
-
-interface AppHeaderProps {
- activeTab: string
- onTabChange: (tab: string) => void
- featureToggles: FeatureToggles
- errorCount: number
- lastSaved: number | null
- currentProject: Project
- onProjectLoad: (project: Project) => void
- onSearch: () => void
- onShowShortcuts: () => void
- onGenerateAI: () => void
- onExport: () => void
- onPreview?: () => void
- onShowErrors: () => void
-}
-
-export function AppHeader({
- activeTab,
- onTabChange,
- featureToggles,
- errorCount,
- lastSaved,
- currentProject,
- onProjectLoad,
- onSearch,
- onShowShortcuts,
- onGenerateAI,
- onExport,
- onPreview,
- onShowErrors,
-}: AppHeaderProps) {
- return (
-
-
-
-
-
-
-
-
-
-
-
- 0}
- />
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/src/components/organisms/EmptyCanvasState.tsx b/src/components/organisms/EmptyCanvasState.tsx
deleted file mode 100644
index c80e4b0..0000000
--- a/src/components/organisms/EmptyCanvasState.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { Plus, Folder } from '@phosphor-icons/react'
-import { EmptyState, ActionButton, Stack } from '@/components/atoms'
-
-interface EmptyCanvasStateProps {
- onAddFirstComponent?: () => void
- onImportSchema?: () => void
-}
-
-export function EmptyCanvasState({ onAddFirstComponent, onImportSchema }: EmptyCanvasStateProps) {
- return (
-
-
}
- title="Empty Canvas"
- description="Start building your UI by dragging components from the left panel, or import an existing schema."
- >
-
- {onImportSchema && (
- }
- label="Import Schema"
- onClick={onImportSchema}
- variant="outline"
- />
- )}
- {onAddFirstComponent && (
- }
- label="Add Component"
- onClick={onAddFirstComponent}
- variant="default"
- />
- )}
-
-
-
- )
-}
diff --git a/src/components/organisms/NavigationMenu.tsx b/src/components/organisms/NavigationMenu.tsx
deleted file mode 100644
index b077790..0000000
--- a/src/components/organisms/NavigationMenu.tsx
+++ /dev/null
@@ -1,262 +0,0 @@
-import { useState } from 'react'
-import { Button } from '@/components/ui/button'
-import { Sidebar, SidebarContent, SidebarHeader } from '@/components/ui/sidebar'
-import { ScrollArea } from '@/components/ui/scroll-area'
-import { Collapsible, CollapsibleContent } from '@/components/ui/collapsible'
-import { CaretDoubleDown, CaretDoubleUp, CaretDown } from '@phosphor-icons/react'
-import { CollapsibleTrigger } from '@/components/ui/collapsible'
-import { Badge, Flex, Text, IconWrapper } from '@/components/atoms'
-import { navigationGroups, NavigationItemData } from '@/lib/navigation-config'
-import { FeatureToggles } from '@/types/project'
-import { useRoutePreload } from '@/hooks/use-route-preload'
-import navigationMenuCopy from '@/data/navigation-menu.json'
-
-interface NavigationMenuProps {
- activeTab: string
- onTabChange: (tab: string) => void
- featureToggles: FeatureToggles
- errorCount?: number
-}
-
-interface NavigationMenuControlsProps {
- onExpandAll: () => void
- onCollapseAll: () => void
-}
-
-interface NavigationMenuGroupListProps {
- activeTab: string
- expandedGroups: Set
- featureToggles: FeatureToggles
- errorCount: number
- onToggleGroup: (groupId: string) => void
- onItemClick: (value: string) => void
- onItemHover: (value: string) => void
- onItemLeave: (value: string) => void
-}
-
-function NavigationMenuControls({
- onExpandAll,
- onCollapseAll,
-}: NavigationMenuControlsProps) {
- return (
-
-
-
-
- )
-}
-
-function NavigationMenuHeader({
- onExpandAll,
- onCollapseAll,
-}: NavigationMenuControlsProps) {
- return (
-
- {navigationMenuCopy.labels.title}
-
-
- )
-}
-
-function NavigationMenuGroupList({
- activeTab,
- expandedGroups,
- featureToggles,
- errorCount,
- onToggleGroup,
- onItemClick,
- onItemHover,
- onItemLeave,
-}: NavigationMenuGroupListProps) {
- const isItemVisible = (item: NavigationItemData) => {
- if (!item.featureKey) return true
- return featureToggles[item.featureKey]
- }
-
- const getVisibleItemsCount = (groupId: string) => {
- const group = navigationGroups.find((g) => g.id === groupId)
- if (!group) return 0
- return group.items.filter(isItemVisible).length
- }
-
- const getItemBadge = (item: NavigationItemData) => {
- if (item.id === 'errors') return errorCount
- return item.badge
- }
-
- return (
-
- {navigationGroups.map((group) => {
- const visibleItemsCount = getVisibleItemsCount(group.id)
- if (visibleItemsCount === 0) return null
-
- const isExpanded = expandedGroups.has(group.id)
-
- return (
-
onToggleGroup(group.id)}
- >
- {/* NavigationGroupHeader - inlined */}
-
-
-
- {group.label}
-
- {visibleItemsCount}
-
-
-
- {group.items.map((item) => {
- if (!isItemVisible(item)) return null
-
- const isActive = activeTab === item.value
- const badge = getItemBadge(item)
-
- return (
-
onItemHover(item.value)}
- onMouseLeave={() => onItemLeave(item.value)}
- >
- {/* NavigationItem - inlined */}
-
-
- )
- })}
-
-
-
- )
- })}
-
- )
-}
-
-export function NavigationMenu({
- activeTab,
- onTabChange,
- featureToggles,
- errorCount = 0,
-}: NavigationMenuProps) {
- const [expandedGroups, setExpandedGroups] = useState>(
- new Set(['overview', 'development', 'automation', 'design', 'backend', 'testing', 'tools'])
- )
-
- const { preloadRoute, cancelPreload } = useRoutePreload({ delay: 100 })
-
- const handleItemClick = (value: string) => {
- onTabChange(value)
- }
-
- const handleItemHover = (value: string) => {
- console.log(`[NAV] 🖱️ Hover detected on: ${value}`)
- preloadRoute(value)
- }
-
- const handleItemLeave = (value: string) => {
- console.log(`[NAV] 👋 Hover left: ${value}`)
- cancelPreload(value)
- }
-
- const toggleGroup = (groupId: string) => {
- setExpandedGroups((prev) => {
- const newSet = new Set(prev)
- if (newSet.has(groupId)) {
- newSet.delete(groupId)
- } else {
- newSet.add(groupId)
- }
- return newSet
- })
- }
-
- const handleExpandAll = () => {
- const allGroupIds = navigationGroups
- .filter((group) =>
- group.items.some((item) => {
- if (!item.featureKey) return true
- return featureToggles[item.featureKey]
- })
- )
- .map((group) => group.id)
- setExpandedGroups(new Set(allGroupIds))
- }
-
- const handleCollapseAll = () => {
- setExpandedGroups(new Set())
- }
-
- return (
-
-
-
-
-
-
-
-
- )
-}
diff --git a/src/components/organisms/PageHeader.tsx b/src/components/organisms/PageHeader.tsx
deleted file mode 100644
index 19bd020..0000000
--- a/src/components/organisms/PageHeader.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import { Stack, Container } from '@/components/atoms'
-import { TabIcon } from '@/lib/json-ui/json-components'
-import { tabInfo } from '@/lib/navigation-config'
-
-interface PageHeaderProps {
- activeTab: string
-}
-
-export function PageHeader({ activeTab }: PageHeaderProps) {
- const info = tabInfo[activeTab]
-
- if (!info) return null
-
- return (
-
- {/* PageHeaderContent - inlined */}
-
-
-
-
{info.title}
- {info.description && (
-
- {info.description}
-
- )}
-
-
-
- )
-}
diff --git a/src/components/organisms/SchemaCodeViewer.tsx b/src/components/organisms/SchemaCodeViewer.tsx
deleted file mode 100644
index db138a5..0000000
--- a/src/components/organisms/SchemaCodeViewer.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
-import { ScrollArea } from '@/components/ui/scroll-area'
-import { Code, Eye } from '@phosphor-icons/react'
-import { UIComponent } from '@/types/json-ui'
-import { PanelHeader, Text, Code as CodeAtom, Stack, IconText } from '@/components/atoms'
-
-interface SchemaCodeViewerProps {
- components: UIComponent[]
- schema: any
-}
-
-export function SchemaCodeViewer({ components, schema }: SchemaCodeViewerProps) {
- const jsonString = JSON.stringify(schema, null, 2)
-
- return (
-
-
} />
-
-
-
- JSON
- Preview
-
-
-
-
-
- {jsonString}
-
-
-
-
-
-
-
- Live preview coming soon
-
-
-
-
-
- )
-}
diff --git a/src/components/organisms/ToolbarActions.tsx b/src/components/organisms/ToolbarActions.tsx
deleted file mode 100644
index 513a29c..0000000
--- a/src/components/organisms/ToolbarActions.tsx
+++ /dev/null
@@ -1,86 +0,0 @@
-import { ToolbarButton } from '@/components/molecules'
-import { ErrorBadge, Flex, Tooltip, Badge } from '@/components/atoms'
-import {
- MagnifyingGlass,
- Keyboard,
- Sparkle,
- Download,
- Wrench,
- Eye,
-} from '@phosphor-icons/react'
-
-interface ToolbarActionsProps {
- onSearch: () => void
- onShowShortcuts: () => void
- onGenerateAI: () => void
- onExport: () => void
- onPreview?: () => void
- onShowErrors?: () => void
- errorCount?: number
- showErrorButton?: boolean
-}
-
-export function ToolbarActions({
- onSearch,
- onShowShortcuts,
- onGenerateAI,
- onExport,
- onPreview,
- onShowErrors,
- errorCount = 0,
- showErrorButton = false,
-}: ToolbarActionsProps) {
- return (
-
- }
- label="Search (Ctrl+K)"
- onClick={onSearch}
- data-search-trigger
- />
-
- {showErrorButton && errorCount > 0 && onShowErrors && (
-
- }
- label={`${errorCount} ${errorCount === 1 ? 'Error' : 'Errors'}`}
- onClick={onShowErrors}
- variant="outline"
- className="border-destructive text-destructive hover:bg-destructive hover:text-destructive-foreground"
- />
-
-
- )}
-
- {onPreview && (
- }
- label="Preview (Ctrl+P)"
- onClick={onPreview}
- variant="outline"
- />
- )}
-
- }
- label="Keyboard Shortcuts (Ctrl+/)"
- onClick={onShowShortcuts}
- variant="ghost"
- className="hidden sm:flex"
- />
-
- }
- label="AI Generate (Ctrl+Shift+G)"
- onClick={onGenerateAI}
- />
-
- }
- label="Export Project (Ctrl+E)"
- onClick={onExport}
- variant="default"
- />
-
- )
-}
diff --git a/src/components/organisms/TreeListPanel.tsx b/src/components/organisms/TreeListPanel.tsx
deleted file mode 100644
index f5ca05d..0000000
--- a/src/components/organisms/TreeListPanel.tsx
+++ /dev/null
@@ -1,153 +0,0 @@
-import { ScrollArea } from '@/components/ui/scroll-area'
-import { EmptyState, Stack, Container, Card, Badge, ActionIcon, IconButton, Flex, Text, Heading, Button, TreeIcon } from '@/components/atoms'
-import { ComponentTree } from '@/types/project'
-import { FolderOpen } from '@phosphor-icons/react'
-
-interface TreeListPanelProps {
- trees: ComponentTree[]
- selectedTreeId: string | null
- onTreeSelect: (treeId: string) => void
- onTreeEdit: (tree: ComponentTree) => void
- onTreeDuplicate: (tree: ComponentTree) => void
- onTreeDelete: (treeId: string) => void
- onCreateNew: () => void
- onImportJson: () => void
- onExportJson: () => void
-}
-
-export function TreeListPanel({
- trees,
- selectedTreeId,
- onTreeSelect,
- onTreeEdit,
- onTreeDuplicate,
- onTreeDelete,
- onCreateNew,
- onImportJson,
- onExportJson,
-}: TreeListPanelProps) {
- return (
-
- {/* TreeListHeader - inlined */}
-
-
-
-
- Component Trees
-
- }
- size="sm"
- onClick={onCreateNew}
- />
-
-
-
- }
- >
- Import JSON
-
- }
- >
- Export JSON
-
-
-
-
- {trees.length === 0 ? (
-
- }
- title="No component trees yet"
- description="Create your first tree to get started"
- action={{
- label: 'Create First Tree',
- onClick: onCreateNew
- }}
- />
-
- ) : (
-
-
- {trees.map((tree) => {
- const isSelected = selectedTreeId === tree.id
- const disableDelete = trees.length === 1
-
- return (
- // TreeCard - inlined
- onTreeSelect(tree.id)}
- >
-
-
-
- {tree.name}
- {tree.description && (
-
- {tree.description}
-
- )}
-
-
- {tree.rootNodes.length} components
-
-
-
-
- e.stopPropagation()}>
-
- }
- variant="ghost"
- size="sm"
- onClick={() => onTreeEdit(tree)}
- title="Edit tree"
- />
- }
- variant="ghost"
- size="sm"
- onClick={() => onTreeDuplicate(tree)}
- title="Duplicate tree"
- />
- }
- variant="ghost"
- size="sm"
- onClick={() => onTreeDelete(tree.id)}
- disabled={disableDelete}
- title={disableDelete ? "Can't delete last tree" : "Delete tree"}
- />
-
-
-
-
- )
- })}
-
-
- )}
-
- )
-}
-
diff --git a/src/components/organisms/index.ts b/src/components/organisms/index.ts
index 7d6a368..c0115e5 100644
--- a/src/components/organisms/index.ts
+++ b/src/components/organisms/index.ts
@@ -1,6 +1,7 @@
-export { NavigationMenu } from './NavigationMenu'
-export { AppHeader } from './AppHeader'
-export { TreeListPanel } from './TreeListPanel'
export { SchemaEditorLayout } from './SchemaEditorLayout'
-export { SchemaCodeViewer } from './SchemaCodeViewer'
+export { SchemaEditorCanvas } from './SchemaEditorCanvas'
+export { SchemaEditorPropertiesPanel } from './SchemaEditorPropertiesPanel'
+export { SchemaEditorSidebar } from './SchemaEditorSidebar'
+export { SchemaEditorStatusBar } from './SchemaEditorStatusBar'
+export { SchemaEditorToolbar } from './SchemaEditorToolbar'
export { JSONUIShowcase } from '../JSONUIShowcase'