Consolidate JSON UI component registry

This commit is contained in:
2026-01-18 01:42:41 +00:00
parent e033b032a1
commit 320e8a4c2c
3 changed files with 68 additions and 169 deletions

View File

@@ -6,25 +6,51 @@ import { Label } from '@/components/ui/label'
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Separator } from '@/components/ui/separator'
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
import { Alert as ShadcnAlert, AlertDescription, AlertTitle } from '@/components/ui/alert'
import { Switch } from '@/components/ui/switch'
import { Checkbox } from '@/components/ui/checkbox'
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
import { Table as ShadcnTable, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import { Skeleton } from '@/components/ui/skeleton'
import { Skeleton as ShadcnSkeleton } from '@/components/ui/skeleton'
import { Progress } from '@/components/ui/progress'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Avatar as ShadcnAvatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Heading } from '@/components/atoms/Heading'
import { Text } from '@/components/atoms/Text'
import { TextArea } from '@/components/atoms/TextArea'
import { List as ListComponent } from '@/components/atoms/List'
import { Grid } from '@/components/atoms/Grid'
import { Stack } from '@/components/atoms/Stack'
import { Flex } from '@/components/atoms/Flex'
import { Container } from '@/components/atoms/Container'
import { Link } from '@/components/atoms/Link'
import { Image } from '@/components/atoms/Image'
import { Avatar as AtomAvatar } from '@/components/atoms/Avatar'
import { Code } from '@/components/atoms/Code'
import { Tag } from '@/components/atoms/Tag'
import { Spinner } from '@/components/atoms/Spinner'
import { Skeleton as AtomSkeleton } from '@/components/atoms/Skeleton'
import { Slider } from '@/components/atoms/Slider'
import { NumberInput } from '@/components/atoms/NumberInput'
import { Radio } from '@/components/atoms/Radio'
import { Alert as AtomAlert } from '@/components/atoms/Alert'
import { InfoBox } from '@/components/atoms/InfoBox'
import { EmptyState } from '@/components/atoms/EmptyState'
import { Table as AtomTable } from '@/components/atoms/Table'
import { KeyValue } from '@/components/atoms/KeyValue'
import { StatCard } from '@/components/atoms/StatCard'
import { StatusBadge } from '@/components/atoms/StatusBadge'
import { DataCard } from '@/components/molecules/DataCard'
import { SearchInput } from '@/components/molecules/SearchInput'
import { ActionBar } from '@/components/molecules/ActionBar'
import { AppBranding } from '@/components/molecules/AppBranding'
import { LabelWithBadge } from '@/components/molecules/LabelWithBadge'
import { EmptyEditorState } from '@/components/molecules/EmptyEditorState'
import { LoadingFallback } from '@/components/molecules/LoadingFallback'
import { LoadingState } from '@/components/molecules/LoadingState'
import { NavigationGroupHeader } from '@/components/molecules/NavigationGroupHeader'
import {
ArrowLeft, ArrowRight, Check, X, Plus, Minus, MagnifyingGlass,
Funnel, Download, Upload, PencilSimple, Trash, Eye, EyeClosed,
@@ -70,7 +96,7 @@ export const shadcnComponents: UIComponentRegistry = {
CardFooter,
Badge,
Separator,
Alert,
Alert: ShadcnAlert,
AlertDescription,
AlertTitle,
Switch,
@@ -82,7 +108,7 @@ export const shadcnComponents: UIComponentRegistry = {
SelectItem,
SelectTrigger,
SelectValue,
Table,
Table: ShadcnTable,
TableBody,
TableCell,
TableHead,
@@ -98,22 +124,51 @@ export const shadcnComponents: UIComponentRegistry = {
DialogFooter,
DialogHeader,
DialogTitle,
Skeleton,
Skeleton: ShadcnSkeleton,
Progress,
Avatar,
Avatar: ShadcnAvatar,
AvatarFallback,
AvatarImage,
}
export const customComponents: UIComponentRegistry = {
export const atomComponents: UIComponentRegistry = {
Heading,
Text,
TextArea,
List: ListComponent,
Grid,
Stack,
Flex,
Container,
Link,
Image,
Avatar: AtomAvatar,
Code,
Tag,
Spinner,
Skeleton: AtomSkeleton,
Slider,
NumberInput,
Radio,
Alert: AtomAlert,
InfoBox,
EmptyState,
Table: AtomTable,
KeyValue,
StatCard,
StatusBadge,
}
export const moleculeComponents: UIComponentRegistry = {
DataCard,
SearchInput,
ActionBar,
AppBranding,
LabelWithBadge,
EmptyEditorState,
LoadingFallback,
LoadingState,
NavigationGroupHeader,
}
export const iconComponents: UIComponentRegistry = {
@@ -160,7 +215,8 @@ export const iconComponents: UIComponentRegistry = {
export const uiComponentRegistry: UIComponentRegistry = {
...primitiveComponents,
...shadcnComponents,
...customComponents,
...atomComponents,
...moleculeComponents,
...iconComponents,
}

View File

@@ -1,157 +0,0 @@
import { ComponentType } from '@/types/json-ui'
import { Button } from '@/components/ui/button'
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Select } from '@/components/ui/select'
import { Checkbox } from '@/components/ui/checkbox'
import { Switch } from '@/components/ui/switch'
import { Badge } from '@/components/ui/badge'
import { Progress } from '@/components/ui/progress'
import { Separator } from '@/components/ui/separator'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { Heading } from '@/components/atoms/Heading'
import { Text } from '@/components/atoms/Text'
import { TextArea } from '@/components/atoms/TextArea'
import { List } from '@/components/atoms/List'
import { Grid } from '@/components/atoms/Grid'
import { Stack } from '@/components/atoms/Stack'
import { Flex } from '@/components/atoms/Flex'
import { Container } from '@/components/atoms/Container'
import { Link } from '@/components/atoms/Link'
import { Image } from '@/components/atoms/Image'
import { Avatar } from '@/components/atoms/Avatar'
import { Code } from '@/components/atoms/Code'
import { Tag } from '@/components/atoms/Tag'
import { Spinner } from '@/components/atoms/Spinner'
import { Skeleton } from '@/components/atoms/Skeleton'
import { Slider } from '@/components/atoms/Slider'
import { NumberInput } from '@/components/atoms/NumberInput'
import { Radio } from '@/components/atoms/Radio'
import { Alert } from '@/components/atoms/Alert'
import { InfoBox } from '@/components/atoms/InfoBox'
import { EmptyState } from '@/components/atoms/EmptyState'
import { Table } from '@/components/atoms/Table'
import { KeyValue } from '@/components/atoms/KeyValue'
import { StatCard } from '@/components/atoms/StatCard'
import { StatusBadge } from '@/components/atoms/StatusBadge'
import { DataCard } from '@/components/molecules/DataCard'
import { SearchInput } from '@/components/molecules/SearchInput'
import { ActionBar } from '@/components/molecules/ActionBar'
import { AppBranding } from '@/components/molecules/AppBranding'
import { LabelWithBadge } from '@/components/molecules/LabelWithBadge'
import { EmptyEditorState } from '@/components/molecules/EmptyEditorState'
import { LoadingFallback } from '@/components/molecules/LoadingFallback'
import { LoadingState } from '@/components/molecules/LoadingState'
import { NavigationGroupHeader } from '@/components/molecules/NavigationGroupHeader'
export const componentRegistry: Record<ComponentType, any> = {
'div': 'div',
'section': 'section',
'article': 'article',
'header': 'header',
'footer': 'footer',
'main': 'main',
'Button': Button,
'Card': Card,
'Input': Input,
'TextArea': TextArea,
'Select': Select,
'Checkbox': Checkbox,
'Radio': Radio,
'Switch': Switch,
'Slider': Slider,
'NumberInput': NumberInput,
'Badge': Badge,
'Tag': Tag,
'Progress': Progress,
'Separator': Separator,
'Tabs': Tabs,
'Dialog': 'div',
'Text': Text,
'Heading': Heading,
'Label': Label,
'Link': Link,
'Image': Image,
'Avatar': Avatar,
'Code': Code,
'Spinner': Spinner,
'Skeleton': Skeleton,
'List': List,
'Grid': Grid,
'Stack': Stack,
'Flex': Flex,
'Container': Container,
'Alert': Alert,
'InfoBox': InfoBox,
'EmptyState': EmptyState,
'StatusBadge': StatusBadge,
'Table': Table,
'KeyValue': KeyValue,
'StatCard': StatCard,
'DataCard': DataCard,
'SearchInput': SearchInput,
'ActionBar': ActionBar,
'AppBranding': AppBranding,
'LabelWithBadge': LabelWithBadge,
'EmptyEditorState': EmptyEditorState,
'LoadingFallback': LoadingFallback,
'LoadingState': LoadingState,
'NavigationGroupHeader': NavigationGroupHeader,
}
export const cardSubComponents = {
'CardHeader': CardHeader,
'CardTitle': CardTitle,
'CardDescription': CardDescription,
'CardContent': CardContent,
'CardFooter': CardFooter,
}
export const tabsSubComponents = {
'TabsContent': TabsContent,
'TabsList': TabsList,
'TabsTrigger': TabsTrigger,
}
export const customComponents = {
'StatusBadge': StatusBadge,
'DataCard': DataCard,
'SearchInput': SearchInput,
'ActionBar': ActionBar,
'StatCard': StatCard,
'KeyValue': KeyValue,
'Table': Table,
'Alert': Alert,
'InfoBox': InfoBox,
'EmptyState': EmptyState,
'AppBranding': AppBranding,
'LabelWithBadge': LabelWithBadge,
'EmptyEditorState': EmptyEditorState,
'LoadingFallback': LoadingFallback,
'LoadingState': LoadingState,
'NavigationGroupHeader': NavigationGroupHeader,
}
export function getComponent(type: ComponentType | string): any {
if (type in componentRegistry) {
return componentRegistry[type as ComponentType]
}
if (type in cardSubComponents) {
return cardSubComponents[type as keyof typeof cardSubComponents]
}
if (type in tabsSubComponents) {
return tabsSubComponents[type as keyof typeof tabsSubComponents]
}
if (type in customComponents) {
return customComponents[type as keyof typeof customComponents]
}
return 'div'
}
export const getUIComponent = getComponent

View File

@@ -3,8 +3,8 @@ import { ReactNode } from 'react'
export type ComponentType =
| 'div' | 'section' | 'article' | 'header' | 'footer' | 'main'
| 'Button' | 'Card' | 'CardHeader' | 'CardTitle' | 'CardDescription' | 'CardContent' | 'CardFooter'
| 'Input' | 'TextArea' | 'Select' | 'Checkbox' | 'Radio' | 'Switch' | 'Slider' | 'NumberInput'
| 'Badge' | 'Progress' | 'Separator' | 'Tabs' | 'Dialog'
| 'Input' | 'TextArea' | 'Textarea' | 'Select' | 'Checkbox' | 'Radio' | 'Switch' | 'Slider' | 'NumberInput'
| 'Badge' | 'Progress' | 'Separator' | 'Tabs' | 'TabsContent' | 'TabsList' | 'TabsTrigger' | 'Dialog'
| 'Text' | 'Heading' | 'Label' | 'List' | 'Grid' | 'Stack' | 'Flex' | 'Container'
| 'Link' | 'Image' | 'Avatar' | 'Code' | 'Tag' | 'Spinner' | 'Skeleton'
| 'Alert' | 'InfoBox' | 'EmptyState' | 'StatusBadge'