@object-ui/components 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (295) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/LICENSE +21 -0
  3. package/README.md +170 -0
  4. package/dist/index.css +1 -0
  5. package/dist/index.d.ts +2 -0
  6. package/dist/index.js +46186 -0
  7. package/dist/index.umd.cjs +92 -0
  8. package/dist/src/hooks/use-mobile.d.ts +1 -0
  9. package/dist/src/index.d.ts +2 -0
  10. package/dist/src/index.test.d.ts +1 -0
  11. package/dist/src/lib/utils.d.ts +4 -0
  12. package/dist/src/new-components.test.d.ts +1 -0
  13. package/dist/src/renderers/basic/div.d.ts +1 -0
  14. package/dist/src/renderers/basic/html.d.ts +1 -0
  15. package/dist/src/renderers/basic/icon.d.ts +1 -0
  16. package/dist/src/renderers/basic/image.d.ts +1 -0
  17. package/dist/src/renderers/basic/index.d.ts +0 -0
  18. package/dist/src/renderers/basic/separator.d.ts +1 -0
  19. package/dist/src/renderers/basic/span.d.ts +1 -0
  20. package/dist/src/renderers/basic/text.d.ts +1 -0
  21. package/dist/src/renderers/complex/__tests__/data-table.test.d.ts +0 -0
  22. package/dist/src/renderers/complex/calendar-view.d.ts +1 -0
  23. package/dist/src/renderers/complex/carousel.d.ts +1 -0
  24. package/dist/src/renderers/complex/chatbot.d.ts +1 -0
  25. package/dist/src/renderers/complex/chatbot.test.d.ts +1 -0
  26. package/dist/src/renderers/complex/data-table.d.ts +1 -0
  27. package/dist/src/renderers/complex/filter-builder.d.ts +1 -0
  28. package/dist/src/renderers/complex/index.d.ts +0 -0
  29. package/dist/src/renderers/complex/resizable.d.ts +1 -0
  30. package/dist/src/renderers/complex/scroll-area.d.ts +1 -0
  31. package/dist/src/renderers/complex/table.d.ts +1 -0
  32. package/dist/src/renderers/complex/timeline.d.ts +1 -0
  33. package/dist/src/renderers/data-display/alert.d.ts +1 -0
  34. package/dist/src/renderers/data-display/avatar.d.ts +1 -0
  35. package/dist/src/renderers/data-display/badge.d.ts +1 -0
  36. package/dist/src/renderers/data-display/index.d.ts +0 -0
  37. package/dist/src/renderers/data-display/list.d.ts +1 -0
  38. package/dist/src/renderers/data-display/statistic.d.ts +1 -0
  39. package/dist/src/renderers/data-display/tree-view.d.ts +1 -0
  40. package/dist/src/renderers/disclosure/accordion.d.ts +1 -0
  41. package/dist/src/renderers/disclosure/collapsible.d.ts +1 -0
  42. package/dist/src/renderers/disclosure/index.d.ts +0 -0
  43. package/dist/src/renderers/feedback/index.d.ts +0 -0
  44. package/dist/src/renderers/feedback/loading.d.ts +1 -0
  45. package/dist/src/renderers/feedback/progress.d.ts +1 -0
  46. package/dist/src/renderers/feedback/skeleton.d.ts +1 -0
  47. package/dist/src/renderers/feedback/toaster.d.ts +1 -0
  48. package/dist/src/renderers/form/button.d.ts +1 -0
  49. package/dist/src/renderers/form/calendar.d.ts +1 -0
  50. package/dist/src/renderers/form/checkbox.d.ts +1 -0
  51. package/dist/src/renderers/form/date-picker.d.ts +1 -0
  52. package/dist/src/renderers/form/file-upload.d.ts +1 -0
  53. package/dist/src/renderers/form/form.d.ts +1 -0
  54. package/dist/src/renderers/form/index.d.ts +0 -0
  55. package/dist/src/renderers/form/input-otp.d.ts +1 -0
  56. package/dist/src/renderers/form/input.d.ts +1 -0
  57. package/dist/src/renderers/form/label.d.ts +1 -0
  58. package/dist/src/renderers/form/radio-group.d.ts +1 -0
  59. package/dist/src/renderers/form/select.d.ts +1 -0
  60. package/dist/src/renderers/form/slider.d.ts +1 -0
  61. package/dist/src/renderers/form/switch.d.ts +1 -0
  62. package/dist/src/renderers/form/textarea.d.ts +1 -0
  63. package/dist/src/renderers/form/toggle.d.ts +1 -0
  64. package/dist/src/renderers/index.d.ts +0 -0
  65. package/dist/src/renderers/layout/card.d.ts +1 -0
  66. package/dist/src/renderers/layout/container.d.ts +1 -0
  67. package/dist/src/renderers/layout/flex.d.ts +1 -0
  68. package/dist/src/renderers/layout/grid.d.ts +1 -0
  69. package/dist/src/renderers/layout/index.d.ts +0 -0
  70. package/dist/src/renderers/layout/page.d.ts +7 -0
  71. package/dist/src/renderers/layout/semantic.d.ts +1 -0
  72. package/dist/src/renderers/layout/stack.d.ts +1 -0
  73. package/dist/src/renderers/layout/tabs.d.ts +1 -0
  74. package/dist/src/renderers/navigation/header-bar.d.ts +1 -0
  75. package/dist/src/renderers/navigation/index.d.ts +0 -0
  76. package/dist/src/renderers/navigation/sidebar.d.ts +1 -0
  77. package/dist/src/renderers/overlay/alert-dialog.d.ts +1 -0
  78. package/dist/src/renderers/overlay/context-menu.d.ts +1 -0
  79. package/dist/src/renderers/overlay/dialog.d.ts +1 -0
  80. package/dist/src/renderers/overlay/drawer.d.ts +1 -0
  81. package/dist/src/renderers/overlay/dropdown-menu.d.ts +1 -0
  82. package/dist/src/renderers/overlay/hover-card.d.ts +1 -0
  83. package/dist/src/renderers/overlay/index.d.ts +0 -0
  84. package/dist/src/renderers/overlay/popover.d.ts +1 -0
  85. package/dist/src/renderers/overlay/sheet.d.ts +1 -0
  86. package/dist/src/renderers/overlay/tooltip.d.ts +1 -0
  87. package/dist/src/ui/accordion.d.ts +7 -0
  88. package/dist/src/ui/alert-dialog.d.ts +14 -0
  89. package/dist/src/ui/alert.d.ts +9 -0
  90. package/dist/src/ui/aspect-ratio.d.ts +3 -0
  91. package/dist/src/ui/avatar.d.ts +6 -0
  92. package/dist/src/ui/badge.d.ts +9 -0
  93. package/dist/src/ui/breadcrumb.d.ts +11 -0
  94. package/dist/src/ui/button-group.d.ts +11 -0
  95. package/dist/src/ui/button.d.ts +13 -0
  96. package/dist/src/ui/calendar-view.d.ts +21 -0
  97. package/dist/src/ui/calendar.d.ts +8 -0
  98. package/dist/src/ui/card.d.ts +9 -0
  99. package/dist/src/ui/carousel.d.ts +19 -0
  100. package/dist/src/ui/chatbot.d.ts +36 -0
  101. package/dist/src/ui/checkbox.d.ts +4 -0
  102. package/dist/src/ui/collapsible.d.ts +5 -0
  103. package/dist/src/ui/command.d.ts +18 -0
  104. package/dist/src/ui/context-menu.d.ts +25 -0
  105. package/dist/src/ui/dialog.d.ts +15 -0
  106. package/dist/src/ui/drawer.d.ts +13 -0
  107. package/dist/src/ui/dropdown-menu.d.ts +25 -0
  108. package/dist/src/ui/empty.d.ts +11 -0
  109. package/dist/src/ui/field.d.ts +24 -0
  110. package/dist/src/ui/filter-builder.d.ts +31 -0
  111. package/dist/src/ui/form.d.ts +24 -0
  112. package/dist/src/ui/hover-card.d.ts +6 -0
  113. package/dist/src/ui/index.d.ts +56 -0
  114. package/dist/src/ui/input-group.d.ts +16 -0
  115. package/dist/src/ui/input-otp.d.ts +11 -0
  116. package/dist/src/ui/input.d.ts +3 -0
  117. package/dist/src/ui/item.d.ts +23 -0
  118. package/dist/src/ui/kbd.d.ts +3 -0
  119. package/dist/src/ui/label.d.ts +4 -0
  120. package/dist/src/ui/menubar.d.ts +26 -0
  121. package/dist/src/ui/navigation-menu.d.ts +14 -0
  122. package/dist/src/ui/pagination.d.ts +13 -0
  123. package/dist/src/ui/popover.d.ts +7 -0
  124. package/dist/src/ui/progress.d.ts +4 -0
  125. package/dist/src/ui/radio-group.d.ts +5 -0
  126. package/dist/src/ui/resizable.d.ts +10 -0
  127. package/dist/src/ui/scroll-area.d.ts +5 -0
  128. package/dist/src/ui/select.d.ts +15 -0
  129. package/dist/src/ui/separator.d.ts +4 -0
  130. package/dist/src/ui/sheet.d.ts +13 -0
  131. package/dist/src/ui/sidebar.d.ts +69 -0
  132. package/dist/src/ui/skeleton.d.ts +2 -0
  133. package/dist/src/ui/slider.d.ts +4 -0
  134. package/dist/src/ui/sonner.d.ts +3 -0
  135. package/dist/src/ui/spinner.d.ts +3 -0
  136. package/dist/src/ui/switch.d.ts +4 -0
  137. package/dist/src/ui/table.d.ts +10 -0
  138. package/dist/src/ui/tabs.d.ts +7 -0
  139. package/dist/src/ui/textarea.d.ts +3 -0
  140. package/dist/src/ui/timeline.d.ts +25 -0
  141. package/dist/src/ui/toggle-group.d.ts +9 -0
  142. package/dist/src/ui/toggle.d.ts +9 -0
  143. package/dist/src/ui/tooltip.d.ts +7 -0
  144. package/docs/FilterBuilder.md +268 -0
  145. package/metadata/Chart.component.yml +30 -0
  146. package/metadata/FilterBuilder.component.yml +39 -0
  147. package/metadata/GridLayout.component.yml +27 -0
  148. package/metadata/Menu.component.yml +31 -0
  149. package/metadata/ObjectForm.component.yml +34 -0
  150. package/metadata/ObjectTable.component.yml +41 -0
  151. package/metadata/Page.component.yml +24 -0
  152. package/package.json +87 -0
  153. package/postcss.config.js +6 -0
  154. package/src/hooks/use-mobile.tsx +19 -0
  155. package/src/index.css +76 -0
  156. package/src/index.test.ts +7 -0
  157. package/src/index.ts +10 -0
  158. package/src/lib/utils.tsx +27 -0
  159. package/src/new-components.test.ts +74 -0
  160. package/src/renderers/basic/div.tsx +41 -0
  161. package/src/renderers/basic/html.tsx +34 -0
  162. package/src/renderers/basic/icon.tsx +25 -0
  163. package/src/renderers/basic/image.tsx +37 -0
  164. package/src/renderers/basic/index.ts +7 -0
  165. package/src/renderers/basic/separator.tsx +48 -0
  166. package/src/renderers/basic/span.tsx +44 -0
  167. package/src/renderers/basic/text.tsx +42 -0
  168. package/src/renderers/complex/README-KANBAN.md +208 -0
  169. package/src/renderers/complex/TIMELINE.md +353 -0
  170. package/src/renderers/complex/__tests__/data-table.test.ts +52 -0
  171. package/src/renderers/complex/calendar-view.tsx +219 -0
  172. package/src/renderers/complex/carousel.tsx +60 -0
  173. package/src/renderers/complex/chatbot.test.ts +44 -0
  174. package/src/renderers/complex/chatbot.tsx +185 -0
  175. package/src/renderers/complex/data-table.tsx +650 -0
  176. package/src/renderers/complex/filter-builder.tsx +68 -0
  177. package/src/renderers/complex/index.ts +10 -0
  178. package/src/renderers/complex/resizable.tsx +54 -0
  179. package/src/renderers/complex/scroll-area.tsx +32 -0
  180. package/src/renderers/complex/table.tsx +86 -0
  181. package/src/renderers/complex/timeline.tsx +466 -0
  182. package/src/renderers/data-display/alert.tsx +37 -0
  183. package/src/renderers/data-display/avatar.tsx +29 -0
  184. package/src/renderers/data-display/badge.tsx +46 -0
  185. package/src/renderers/data-display/index.ts +6 -0
  186. package/src/renderers/data-display/list.tsx +95 -0
  187. package/src/renderers/data-display/statistic.tsx +98 -0
  188. package/src/renderers/data-display/tree-view.tsx +180 -0
  189. package/src/renderers/disclosure/accordion.tsx +60 -0
  190. package/src/renderers/disclosure/collapsible.tsx +44 -0
  191. package/src/renderers/disclosure/index.ts +2 -0
  192. package/src/renderers/feedback/index.ts +4 -0
  193. package/src/renderers/feedback/loading.tsx +69 -0
  194. package/src/renderers/feedback/progress.tsx +20 -0
  195. package/src/renderers/feedback/skeleton.tsx +22 -0
  196. package/src/renderers/feedback/toaster.tsx +26 -0
  197. package/src/renderers/form/button.tsx +61 -0
  198. package/src/renderers/form/calendar.tsx +25 -0
  199. package/src/renderers/form/checkbox.tsx +41 -0
  200. package/src/renderers/form/date-picker.tsx +75 -0
  201. package/src/renderers/form/file-upload.tsx +175 -0
  202. package/src/renderers/form/form.tsx +417 -0
  203. package/src/renderers/form/index.ts +16 -0
  204. package/src/renderers/form/input-otp.tsx +31 -0
  205. package/src/renderers/form/input.tsx +79 -0
  206. package/src/renderers/form/label.tsx +36 -0
  207. package/src/renderers/form/radio-group.tsx +54 -0
  208. package/src/renderers/form/select.tsx +66 -0
  209. package/src/renderers/form/slider.tsx +45 -0
  210. package/src/renderers/form/switch.tsx +39 -0
  211. package/src/renderers/form/textarea.tsx +45 -0
  212. package/src/renderers/form/toggle.tsx +76 -0
  213. package/src/renderers/index.ts +9 -0
  214. package/src/renderers/layout/card.tsx +69 -0
  215. package/src/renderers/layout/container.tsx +113 -0
  216. package/src/renderers/layout/flex.tsx +123 -0
  217. package/src/renderers/layout/grid.tsx +155 -0
  218. package/src/renderers/layout/index.ts +10 -0
  219. package/src/renderers/layout/page.tsx +82 -0
  220. package/src/renderers/layout/semantic.tsx +39 -0
  221. package/src/renderers/layout/stack.tsx +123 -0
  222. package/src/renderers/layout/tabs.tsx +63 -0
  223. package/src/renderers/navigation/header-bar.tsx +50 -0
  224. package/src/renderers/navigation/index.ts +2 -0
  225. package/src/renderers/navigation/sidebar.tsx +189 -0
  226. package/src/renderers/overlay/alert-dialog.tsx +63 -0
  227. package/src/renderers/overlay/context-menu.tsx +91 -0
  228. package/src/renderers/overlay/dialog.tsx +68 -0
  229. package/src/renderers/overlay/drawer.tsx +68 -0
  230. package/src/renderers/overlay/dropdown-menu.tsx +90 -0
  231. package/src/renderers/overlay/hover-card.tsx +46 -0
  232. package/src/renderers/overlay/index.ts +9 -0
  233. package/src/renderers/overlay/popover.tsx +47 -0
  234. package/src/renderers/overlay/sheet.tsx +68 -0
  235. package/src/renderers/overlay/tooltip.tsx +58 -0
  236. package/src/ui/accordion.tsx +64 -0
  237. package/src/ui/alert-dialog.tsx +155 -0
  238. package/src/ui/alert.tsx +78 -0
  239. package/src/ui/aspect-ratio.tsx +11 -0
  240. package/src/ui/avatar.tsx +51 -0
  241. package/src/ui/badge.tsx +46 -0
  242. package/src/ui/breadcrumb.tsx +109 -0
  243. package/src/ui/button-group.tsx +83 -0
  244. package/src/ui/button.tsx +65 -0
  245. package/src/ui/calendar-view.tsx +503 -0
  246. package/src/ui/calendar.tsx +237 -0
  247. package/src/ui/card.tsx +138 -0
  248. package/src/ui/carousel.tsx +239 -0
  249. package/src/ui/chatbot.tsx +240 -0
  250. package/src/ui/checkbox.tsx +32 -0
  251. package/src/ui/collapsible.tsx +31 -0
  252. package/src/ui/command.tsx +182 -0
  253. package/src/ui/context-menu.tsx +247 -0
  254. package/src/ui/dialog.tsx +141 -0
  255. package/src/ui/drawer.tsx +135 -0
  256. package/src/ui/dropdown-menu.tsx +254 -0
  257. package/src/ui/empty.tsx +104 -0
  258. package/src/ui/field.tsx +246 -0
  259. package/src/ui/filter-builder.tsx +359 -0
  260. package/src/ui/form.tsx +167 -0
  261. package/src/ui/hover-card.tsx +44 -0
  262. package/src/ui/index.ts +56 -0
  263. package/src/ui/input-group.tsx +170 -0
  264. package/src/ui/input-otp.tsx +81 -0
  265. package/src/ui/input.tsx +24 -0
  266. package/src/ui/item.tsx +193 -0
  267. package/src/ui/kbd.tsx +28 -0
  268. package/src/ui/label.tsx +24 -0
  269. package/src/ui/menubar.tsx +274 -0
  270. package/src/ui/navigation-menu.tsx +168 -0
  271. package/src/ui/pagination.tsx +127 -0
  272. package/src/ui/popover.tsx +48 -0
  273. package/src/ui/progress.tsx +41 -0
  274. package/src/ui/radio-group.tsx +45 -0
  275. package/src/ui/resizable.tsx +55 -0
  276. package/src/ui/scroll-area.tsx +58 -0
  277. package/src/ui/select.tsx +188 -0
  278. package/src/ui/separator.tsx +31 -0
  279. package/src/ui/sheet.tsx +137 -0
  280. package/src/ui/sidebar.tsx +726 -0
  281. package/src/ui/skeleton.tsx +20 -0
  282. package/src/ui/slider.tsx +63 -0
  283. package/src/ui/sonner.tsx +43 -0
  284. package/src/ui/spinner.tsx +38 -0
  285. package/src/ui/switch.tsx +31 -0
  286. package/src/ui/table.tsx +120 -0
  287. package/src/ui/tabs.tsx +86 -0
  288. package/src/ui/textarea.tsx +18 -0
  289. package/src/ui/timeline.tsx +266 -0
  290. package/src/ui/toggle-group.tsx +87 -0
  291. package/src/ui/toggle.tsx +50 -0
  292. package/src/ui/tooltip.tsx +61 -0
  293. package/tailwind.config.js +75 -0
  294. package/tsconfig.json +18 -0
  295. package/vite.config.ts +44 -0
@@ -0,0 +1,466 @@
1
+ import { ComponentRegistry } from '@object-ui/core';
2
+ import type { TimelineSchema } from '@object-ui/types';
3
+ import {
4
+ Timeline,
5
+ TimelineItem,
6
+ TimelineMarker,
7
+ TimelineContent,
8
+ TimelineTitle,
9
+ TimelineTime,
10
+ TimelineDescription,
11
+ TimelineHorizontal,
12
+ TimelineHorizontalItem,
13
+ TimelineGantt,
14
+ TimelineGanttHeader,
15
+ TimelineGanttRowLabels,
16
+ TimelineGanttGrid,
17
+ TimelineGanttRow,
18
+ TimelineGanttLabel,
19
+ TimelineGanttBar,
20
+ TimelineGanttBarContent,
21
+ } from '../../ui';
22
+ import { renderChildren } from '../../lib/utils';
23
+
24
+ // Constants
25
+ const MILLISECONDS_PER_WEEK = 7 * 24 * 60 * 60 * 1000;
26
+
27
+ // Helper function to calculate date range from items
28
+ function calculateDateRange(items: any[]): { minDate: string; maxDate: string } {
29
+ const allDates = items.flatMap((row: any) =>
30
+ (row.items || []).flatMap((item: any) => [item.startDate, item.endDate])
31
+ );
32
+
33
+ const minTimestamp = Math.min(...allDates.map((d: string) => new Date(d).getTime()));
34
+ const maxTimestamp = Math.max(...allDates.map((d: string) => new Date(d).getTime()));
35
+
36
+ return {
37
+ minDate: new Date(minTimestamp).toISOString().split('T')[0],
38
+ maxDate: new Date(maxTimestamp).toISOString().split('T')[0],
39
+ };
40
+ }
41
+
42
+ // Helper function to calculate bar position and width based on dates
43
+ function calculateBarDimensions(
44
+ startDate: string,
45
+ endDate: string,
46
+ minDate: string,
47
+ maxDate: string
48
+ ): { start: number; width: number } {
49
+ const start = new Date(startDate).getTime();
50
+ const end = new Date(endDate).getTime();
51
+ const min = new Date(minDate).getTime();
52
+ const max = new Date(maxDate).getTime();
53
+
54
+ const totalDuration = max - min;
55
+ const startOffset = start - min;
56
+ const duration = end - start;
57
+
58
+ return {
59
+ start: (startOffset / totalDuration) * 100,
60
+ width: (duration / totalDuration) * 100,
61
+ };
62
+ }
63
+
64
+ // Helper function to format date
65
+ function formatDate(dateString: string, format?: string): string {
66
+ const date = new Date(dateString);
67
+ if (format === 'short') {
68
+ return date.toLocaleDateString();
69
+ }
70
+ if (format === 'long') {
71
+ return date.toLocaleDateString('en-US', {
72
+ year: 'numeric',
73
+ month: 'long',
74
+ day: 'numeric',
75
+ });
76
+ }
77
+ return date.toISOString().split('T')[0];
78
+ }
79
+
80
+ ComponentRegistry.register(
81
+ 'timeline',
82
+ ({ schema, className, ...props }: { schema: TimelineSchema; className?: string; [key: string]: any }) => {
83
+ const {
84
+ variant = 'vertical',
85
+ items = [],
86
+ dateFormat = 'short',
87
+ onItemClick,
88
+ } = schema;
89
+
90
+ // Vertical Timeline
91
+ if (variant === 'vertical') {
92
+ return (
93
+ <Timeline className={className} {...props}>
94
+ {items.map((item: any, index: number) => (
95
+ <TimelineItem key={index} className={item.className}>
96
+ <TimelineMarker variant={item.variant || 'default'}>
97
+ {item.icon && <span className="text-xs">{item.icon}</span>}
98
+ </TimelineMarker>
99
+ <TimelineContent>
100
+ {item.time && (
101
+ <TimelineTime dateTime={item.time}>
102
+ {formatDate(item.time, dateFormat)}
103
+ </TimelineTime>
104
+ )}
105
+ {item.title && <TimelineTitle>{item.title}</TimelineTitle>}
106
+ {item.description && (
107
+ <TimelineDescription>{item.description}</TimelineDescription>
108
+ )}
109
+ {item.content && renderChildren(item.content)}
110
+ </TimelineContent>
111
+ </TimelineItem>
112
+ ))}
113
+ </Timeline>
114
+ );
115
+ }
116
+
117
+ // Horizontal Timeline
118
+ if (variant === 'horizontal') {
119
+ return (
120
+ <TimelineHorizontal className={className} {...props}>
121
+ {items.map((item: any, index: number) => (
122
+ <TimelineHorizontalItem key={index} className={item.className}>
123
+ <div className="flex flex-col items-center">
124
+ <TimelineMarker variant={item.variant || 'default'}>
125
+ {item.icon && <span className="text-xs">{item.icon}</span>}
126
+ </TimelineMarker>
127
+ <div className="mt-4 text-center">
128
+ {item.time && (
129
+ <TimelineTime dateTime={item.time}>
130
+ {formatDate(item.time, dateFormat)}
131
+ </TimelineTime>
132
+ )}
133
+ {item.title && <TimelineTitle>{item.title}</TimelineTitle>}
134
+ {item.description && (
135
+ <TimelineDescription className="text-center">
136
+ {item.description}
137
+ </TimelineDescription>
138
+ )}
139
+ {item.content && renderChildren(item.content)}
140
+ </div>
141
+ </div>
142
+ {index < items.length - 1 && (
143
+ <div className="absolute left-full w-16 border-t-2 border-gray-200 top-3" />
144
+ )}
145
+ </TimelineHorizontalItem>
146
+ ))}
147
+ </TimelineHorizontal>
148
+ );
149
+ }
150
+
151
+ // Gantt/Airtable-style Timeline
152
+ if (variant === 'gantt') {
153
+ // Calculate date range from all items
154
+ const dateRange = calculateDateRange(items);
155
+ const minDate = schema.minDate || dateRange.minDate;
156
+ const maxDate = schema.maxDate || dateRange.maxDate;
157
+
158
+ // Generate time scale headers (months, weeks, etc.)
159
+ const timeScale = schema.timeScale || 'month';
160
+ const generateTimeHeaders = () => {
161
+ const headers: string[] = [];
162
+ const start = new Date(minDate);
163
+ const end = new Date(maxDate);
164
+
165
+ if (timeScale === 'month') {
166
+ const current = new Date(start);
167
+ while (current <= end) {
168
+ headers.push(
169
+ current.toLocaleDateString('en-US', {
170
+ month: 'short',
171
+ year: 'numeric',
172
+ })
173
+ );
174
+ current.setMonth(current.getMonth() + 1);
175
+ }
176
+ } else if (timeScale === 'week') {
177
+ const current = new Date(start);
178
+ while (current <= end) {
179
+ headers.push(
180
+ `Week ${Math.ceil(
181
+ (current.getTime() - start.getTime()) / MILLISECONDS_PER_WEEK
182
+ ) + 1}`
183
+ );
184
+ current.setDate(current.getDate() + 7);
185
+ }
186
+ } else if (timeScale === 'day') {
187
+ const current = new Date(start);
188
+ while (current <= end) {
189
+ headers.push(
190
+ current.toLocaleDateString('en-US', {
191
+ month: 'short',
192
+ day: 'numeric',
193
+ })
194
+ );
195
+ current.setDate(current.getDate() + 1);
196
+ }
197
+ }
198
+
199
+ return headers;
200
+ };
201
+
202
+ const timeHeaders = generateTimeHeaders();
203
+
204
+ return (
205
+ <TimelineGantt className={className} {...props}>
206
+ {/* Header */}
207
+ <TimelineGanttHeader>
208
+ <TimelineGanttRowLabels className="flex items-center px-4 py-3">
209
+ <span className="font-semibold text-sm">
210
+ {schema.rowLabel || 'Items'}
211
+ </span>
212
+ </TimelineGanttRowLabels>
213
+ <TimelineGanttGrid>
214
+ <div className="flex h-full">
215
+ {timeHeaders.map((header, index) => (
216
+ <div
217
+ key={index}
218
+ className="flex-1 px-2 py-3 border-r text-xs font-medium text-center"
219
+ >
220
+ {header}
221
+ </div>
222
+ ))}
223
+ </div>
224
+ </TimelineGanttGrid>
225
+ </TimelineGanttHeader>
226
+
227
+ {/* Rows */}
228
+ <div>
229
+ <div className="flex">
230
+ <TimelineGanttRowLabels>
231
+ {items.map((row: any, rowIndex: number) => (
232
+ <TimelineGanttRow key={rowIndex}>
233
+ <TimelineGanttLabel title={row.label}>
234
+ {row.label}
235
+ </TimelineGanttLabel>
236
+ </TimelineGanttRow>
237
+ ))}
238
+ </TimelineGanttRowLabels>
239
+ <TimelineGanttGrid className="relative">
240
+ {items.map((row: any, rowIndex: number) => (
241
+ <TimelineGanttRow key={rowIndex} className="relative">
242
+ {(row.items || []).map((item: any, itemIndex: number) => {
243
+ const dimensions = calculateBarDimensions(
244
+ item.startDate,
245
+ item.endDate,
246
+ minDate,
247
+ maxDate
248
+ );
249
+
250
+ return (
251
+ <TimelineGanttBar
252
+ key={itemIndex}
253
+ start={dimensions.start}
254
+ width={dimensions.width}
255
+ variant={item.variant || 'default'}
256
+ onClick={() => onItemClick?.(item, row, rowIndex, itemIndex)}
257
+ title={`${item.title || ''}\n${formatDate(item.startDate, dateFormat)} - ${formatDate(item.endDate, dateFormat)}`}
258
+ >
259
+ <TimelineGanttBarContent>
260
+ {item.title}
261
+ </TimelineGanttBarContent>
262
+ </TimelineGanttBar>
263
+ );
264
+ })}
265
+ </TimelineGanttRow>
266
+ ))}
267
+ </TimelineGanttGrid>
268
+ </div>
269
+ </div>
270
+ </TimelineGantt>
271
+ );
272
+ }
273
+
274
+ return null;
275
+ },
276
+ {
277
+ label: 'Timeline',
278
+ category: 'data-display',
279
+ inputs: [
280
+ {
281
+ name: 'variant',
282
+ type: 'enum',
283
+ enum: ['vertical', 'horizontal', 'gantt'],
284
+ label: 'Timeline Variant',
285
+ defaultValue: 'vertical',
286
+ },
287
+ {
288
+ name: 'items',
289
+ type: 'array',
290
+ label: 'Timeline Items',
291
+ description:
292
+ 'For vertical/horizontal: Array of { time, title, description, variant, icon, content }. For gantt: Array of { label, items: [{ title, startDate, endDate, variant }] }',
293
+ },
294
+ {
295
+ name: 'dateFormat',
296
+ type: 'enum',
297
+ enum: ['short', 'long', 'iso'],
298
+ label: 'Date Format',
299
+ defaultValue: 'short',
300
+ },
301
+ {
302
+ name: 'timeScale',
303
+ type: 'enum',
304
+ enum: ['day', 'week', 'month'],
305
+ label: 'Time Scale (Gantt only)',
306
+ defaultValue: 'month',
307
+ },
308
+ {
309
+ name: 'rowLabel',
310
+ type: 'string',
311
+ label: 'Row Label (Gantt only)',
312
+ defaultValue: 'Items',
313
+ },
314
+ {
315
+ name: 'minDate',
316
+ type: 'string',
317
+ label: 'Min Date (Gantt only)',
318
+ description: 'Override auto-calculated min date (YYYY-MM-DD)',
319
+ },
320
+ {
321
+ name: 'maxDate',
322
+ type: 'string',
323
+ label: 'Max Date (Gantt only)',
324
+ description: 'Override auto-calculated max date (YYYY-MM-DD)',
325
+ },
326
+ { name: 'className', type: 'string', label: 'CSS Class' },
327
+ ],
328
+ defaultProps: {
329
+ variant: 'vertical',
330
+ dateFormat: 'short',
331
+ items: [
332
+ {
333
+ time: '2024-01-15',
334
+ title: 'Project Started',
335
+ description: 'Kickoff meeting and initial planning',
336
+ variant: 'success',
337
+ icon: '🚀',
338
+ },
339
+ {
340
+ time: '2024-02-01',
341
+ title: 'First Milestone',
342
+ description: 'Completed initial design phase',
343
+ variant: 'info',
344
+ icon: '🎨',
345
+ },
346
+ {
347
+ time: '2024-03-15',
348
+ title: 'Beta Release',
349
+ description: 'Released beta version to testers',
350
+ variant: 'warning',
351
+ icon: '⚡',
352
+ },
353
+ {
354
+ time: '2024-04-01',
355
+ title: 'Launch',
356
+ description: 'Official product launch',
357
+ variant: 'success',
358
+ icon: '🎉',
359
+ },
360
+ ],
361
+ },
362
+ examples: {
363
+ vertical: {
364
+ variant: 'vertical',
365
+ dateFormat: 'long',
366
+ items: [
367
+ {
368
+ time: '2024-01-15',
369
+ title: 'Project Started',
370
+ description: 'Kickoff meeting and initial planning',
371
+ variant: 'success',
372
+ },
373
+ {
374
+ time: '2024-02-01',
375
+ title: 'First Milestone',
376
+ description: 'Completed initial design phase',
377
+ variant: 'info',
378
+ },
379
+ ],
380
+ },
381
+ horizontal: {
382
+ variant: 'horizontal',
383
+ dateFormat: 'short',
384
+ items: [
385
+ {
386
+ time: '2024-01-01',
387
+ title: 'Q1',
388
+ description: 'First quarter',
389
+ variant: 'default',
390
+ },
391
+ {
392
+ time: '2024-04-01',
393
+ title: 'Q2',
394
+ description: 'Second quarter',
395
+ variant: 'info',
396
+ },
397
+ {
398
+ time: '2024-07-01',
399
+ title: 'Q3',
400
+ description: 'Third quarter',
401
+ variant: 'warning',
402
+ },
403
+ {
404
+ time: '2024-10-01',
405
+ title: 'Q4',
406
+ description: 'Fourth quarter',
407
+ variant: 'success',
408
+ },
409
+ ],
410
+ },
411
+ gantt: {
412
+ variant: 'gantt',
413
+ dateFormat: 'short',
414
+ timeScale: 'month',
415
+ rowLabel: 'Projects',
416
+ items: [
417
+ {
418
+ label: 'Backend Development',
419
+ items: [
420
+ {
421
+ title: 'API Design',
422
+ startDate: '2024-01-01',
423
+ endDate: '2024-01-31',
424
+ variant: 'success',
425
+ },
426
+ {
427
+ title: 'Implementation',
428
+ startDate: '2024-02-01',
429
+ endDate: '2024-03-31',
430
+ variant: 'info',
431
+ },
432
+ ],
433
+ },
434
+ {
435
+ label: 'Frontend Development',
436
+ items: [
437
+ {
438
+ title: 'UI Design',
439
+ startDate: '2024-01-15',
440
+ endDate: '2024-02-15',
441
+ variant: 'warning',
442
+ },
443
+ {
444
+ title: 'Component Dev',
445
+ startDate: '2024-02-15',
446
+ endDate: '2024-04-15',
447
+ variant: 'default',
448
+ },
449
+ ],
450
+ },
451
+ {
452
+ label: 'Testing',
453
+ items: [
454
+ {
455
+ title: 'QA Phase',
456
+ startDate: '2024-03-01',
457
+ endDate: '2024-04-30',
458
+ variant: 'danger',
459
+ },
460
+ ],
461
+ },
462
+ ],
463
+ },
464
+ },
465
+ }
466
+ );
@@ -0,0 +1,37 @@
1
+ import { ComponentRegistry } from '@object-ui/core';
2
+ import type { AlertSchema } from '@object-ui/types';
3
+ import { renderChildren } from '../../lib/utils';
4
+ import {
5
+ Alert,
6
+ AlertTitle,
7
+ AlertDescription
8
+ } from '../../ui';
9
+
10
+ ComponentRegistry.register('alert',
11
+ ({ schema, className, ...props }: { schema: AlertSchema; className?: string; [key: string]: any }) => (
12
+ <Alert variant={schema.variant} className={className} {...props}>
13
+ <AlertTitle>{schema.title}</AlertTitle>
14
+ <AlertDescription>{schema.description || renderChildren(schema.body)}</AlertDescription>
15
+ </Alert>
16
+ ),
17
+ {
18
+ label: 'Alert',
19
+ inputs: [
20
+ { name: 'title', type: 'string', label: 'Title', required: true },
21
+ { name: 'description', type: 'string', label: 'Description' },
22
+ {
23
+ name: 'variant',
24
+ type: 'enum',
25
+ enum: ['default', 'destructive'],
26
+ defaultValue: 'default',
27
+ label: 'Variant'
28
+ },
29
+ { name: 'className', type: 'string', label: 'CSS Class' }
30
+ ],
31
+ defaultProps: {
32
+ title: 'Alert Title',
33
+ description: 'This is an alert message.',
34
+ variant: 'default'
35
+ }
36
+ }
37
+ );
@@ -0,0 +1,29 @@
1
+ import { ComponentRegistry } from '@object-ui/core';
2
+ import type { AvatarSchema } from '@object-ui/types';
3
+ import {
4
+ Avatar,
5
+ AvatarImage,
6
+ AvatarFallback
7
+ } from '../../ui';
8
+
9
+ ComponentRegistry.register('avatar',
10
+ ({ schema, className, ...props }: { schema: AvatarSchema; className?: string; [key: string]: any }) => (
11
+ <Avatar className={className} {...props}>
12
+ <AvatarImage src={schema.src} alt={schema.alt} />
13
+ <AvatarFallback>{schema.fallback}</AvatarFallback>
14
+ </Avatar>
15
+ ),
16
+ {
17
+ label: 'Avatar',
18
+ inputs: [
19
+ { name: 'src', type: 'string', label: 'Image URL' },
20
+ { name: 'alt', type: 'string', label: 'Alt Text' },
21
+ { name: 'fallback', type: 'string', label: 'Fallback Initials', defaultValue: 'CN' },
22
+ { name: 'className', type: 'string', label: 'CSS Class' }
23
+ ],
24
+ defaultProps: {
25
+ fallback: 'CN',
26
+ alt: 'Avatar'
27
+ }
28
+ }
29
+ );
@@ -0,0 +1,46 @@
1
+ import { ComponentRegistry } from '@object-ui/core';
2
+ import type { BadgeSchema } from '@object-ui/types';
3
+ import { Badge } from '../../ui';
4
+ import { renderChildren } from '../../lib/utils';
5
+
6
+ ComponentRegistry.register('badge',
7
+ ({ schema, ...props }: { schema: BadgeSchema; [key: string]: any }) => {
8
+ // Extract designer-related props
9
+ const {
10
+ 'data-obj-id': dataObjId,
11
+ 'data-obj-type': dataObjType,
12
+ style,
13
+ ...badgeProps
14
+ } = props;
15
+
16
+ return (
17
+ <Badge
18
+ variant={schema.variant}
19
+ className={schema.className}
20
+ {...badgeProps}
21
+ // Apply designer props
22
+ {...{ 'data-obj-id': dataObjId, 'data-obj-type': dataObjType, style }}
23
+ >
24
+ {schema.label || renderChildren(schema.body)}
25
+ </Badge>
26
+ );
27
+ },
28
+ {
29
+ label: 'Badge',
30
+ inputs: [
31
+ { name: 'label', type: 'string', label: 'Label' },
32
+ {
33
+ name: 'variant',
34
+ type: 'enum',
35
+ enum: ['default', 'secondary', 'destructive', 'outline'],
36
+ defaultValue: 'default',
37
+ label: 'Variant'
38
+ },
39
+ { name: 'className', type: 'string', label: 'CSS Class' }
40
+ ],
41
+ defaultProps: {
42
+ label: 'Badge',
43
+ variant: 'default'
44
+ }
45
+ }
46
+ );
@@ -0,0 +1,6 @@
1
+ import './badge';
2
+ import './avatar';
3
+ import './alert';
4
+ import './list';
5
+ import './tree-view';
6
+ import './statistic';
@@ -0,0 +1,95 @@
1
+ import { ComponentRegistry } from '@object-ui/core';
2
+ import type { ListSchema } from '@object-ui/types';
3
+ import { renderChildren } from '../../lib/utils';
4
+ import { cn } from '../../lib/utils';
5
+ import { ChevronRight, Hexagon, Terminal } from 'lucide-react';
6
+
7
+ ComponentRegistry.register('list',
8
+ ({ schema, className, ...props }: { schema: ListSchema; className?: string; [key: string]: any }) => {
9
+ // We use 'ul' for both to control semantics manually with visuals
10
+ const ListTag = 'ul';
11
+
12
+ return (
13
+ <div className={cn("relative p-4 rounded-lg bg-slate-950/30 border border-slate-800/50 backdrop-blur-sm", schema.wrapperClass)}>
14
+ {/* Decorative corner accents for container */}
15
+ <div className="absolute top-0 left-0 w-2 h-2 border-l-2 border-t-2 border-cyan-500/50 rounded-tl-sm" />
16
+ <div className="absolute top-0 right-0 w-2 h-2 border-r-2 border-t-2 border-cyan-500/50 rounded-tr-sm" />
17
+ <div className="absolute bottom-0 left-0 w-2 h-2 border-l-2 border-b-2 border-cyan-500/50 rounded-bl-sm" />
18
+ <div className="absolute bottom-0 right-0 w-2 h-2 border-r-2 border-b-2 border-cyan-500/50 rounded-br-sm" />
19
+
20
+ {schema.title && (
21
+ <div className="flex items-center gap-2 mb-4 pb-2 border-b border-cyan-900/30">
22
+ <Terminal className="w-4 h-4 text-cyan-500" />
23
+ <h3 className="text-sm font-bold uppercase tracking-widest text-cyan-400 drop-shadow-[0_0_5px_rgba(6,182,212,0.5)]">
24
+ {schema.title}
25
+ </h3>
26
+ </div>
27
+ )}
28
+
29
+ <ListTag
30
+ className={cn(
31
+ "space-y-1",
32
+ className
33
+ )}
34
+ {...props}
35
+ >
36
+ {schema.items?.map((item: any, index: number) => (
37
+ <li
38
+ key={index}
39
+ className={cn(
40
+ "group flex items-start gap-3 p-2 rounded-sm transition-all duration-300",
41
+ "hover:bg-cyan-950/20 hover:pl-3",
42
+ typeof item === 'object' && item.className
43
+ )}
44
+ >
45
+ {/* Marker Area */}
46
+ <div className="flex-shrink-0 mt-0.5">
47
+ {schema.ordered ? (
48
+ <span className="flex items-center justify-center w-5 h-5 text-[10px] font-mono font-bold text-slate-950 bg-cyan-600 rounded-sm shadow-[0_0_8px_cyan] group-hover:bg-cyan-400 group-hover:scale-110 transition-all">
49
+ {String(index + 1).padStart(2, '0')}
50
+ </span>
51
+ ) : (
52
+ <div className="relative flex items-center justify-center w-5 h-5">
53
+ <Hexagon className="w-3 h-3 text-cyan-600 group-hover:text-cyan-400 group-hover:rotate-90 transition-transform duration-500" />
54
+ <div className="absolute inset-0 bg-cyan-500/20 blur-[2px] rounded-full opacity-0 group-hover:opacity-100 transition-opacity" />
55
+ </div>
56
+ )}
57
+ </div>
58
+
59
+ {/* Content Area */}
60
+ <div className="flex-1 text-sm text-slate-400 group-hover:text-cyan-100 font-medium font-sans leading-tight transition-colors">
61
+ {typeof item === 'string' ? item : item.content || renderChildren(item.body)}
62
+ </div>
63
+
64
+ {/* Hover Indicator */}
65
+ <ChevronRight className="w-4 h-4 text-cyan-500/0 -translate-x-2 group-hover:text-cyan-500 group-hover:translate-x-0 transition-all duration-300 opacity-0 group-hover:opacity-100" />
66
+ </li>
67
+ ))}
68
+ </ListTag>
69
+ </div>
70
+ );
71
+ },
72
+ {
73
+ label: 'List',
74
+ inputs: [
75
+ { name: 'title', type: 'string', label: 'Title' },
76
+ { name: 'ordered', type: 'boolean', label: 'Ordered List (numbered)', defaultValue: false },
77
+ {
78
+ name: 'items',
79
+ type: 'array',
80
+ label: 'List Items',
81
+ description: 'Array of strings or objects with content/body'
82
+ },
83
+ { name: 'className', type: 'string', label: 'CSS Class' }
84
+ ],
85
+ defaultProps: {
86
+ ordered: false,
87
+ items: [
88
+ 'First item',
89
+ 'Second item',
90
+ 'Third item'
91
+ ],
92
+ className: 'text-sm'
93
+ }
94
+ }
95
+ );