@object-ui/components 0.3.0 → 0.3.1

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 (317) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/ISSUES_FOUND.md +128 -0
  3. package/README.md +19 -1
  4. package/README_SHADCN_SYNC.md +281 -0
  5. package/TESTING.md +335 -0
  6. package/dist/index.css +1 -1
  7. package/dist/index.js +30981 -30027
  8. package/dist/index.umd.cjs +30 -39
  9. package/dist/src/hooks/use-mobile.d.ts +7 -0
  10. package/dist/src/index.d.ts +4 -1
  11. package/dist/src/renderers/basic/button-group.d.ts +8 -0
  12. package/dist/src/renderers/basic/div.d.ts +7 -0
  13. package/dist/src/renderers/basic/html.d.ts +7 -0
  14. package/dist/src/renderers/basic/icon.d.ts +7 -0
  15. package/dist/src/renderers/basic/image.d.ts +7 -0
  16. package/dist/src/renderers/basic/navigation-menu.d.ts +8 -0
  17. package/dist/src/renderers/basic/pagination.d.ts +8 -0
  18. package/dist/src/renderers/basic/separator.d.ts +7 -0
  19. package/dist/src/renderers/basic/span.d.ts +7 -0
  20. package/dist/src/renderers/basic/text.d.ts +7 -0
  21. package/dist/src/renderers/complex/carousel.d.ts +7 -0
  22. package/dist/src/renderers/complex/data-table.d.ts +7 -0
  23. package/dist/src/renderers/complex/filter-builder.d.ts +7 -0
  24. package/dist/src/renderers/complex/resizable.d.ts +7 -0
  25. package/dist/src/renderers/complex/scroll-area.d.ts +7 -0
  26. package/dist/src/renderers/complex/table.d.ts +7 -0
  27. package/dist/src/renderers/data-display/alert.d.ts +7 -0
  28. package/dist/src/renderers/data-display/avatar.d.ts +7 -0
  29. package/dist/src/renderers/data-display/badge.d.ts +7 -0
  30. package/dist/src/renderers/data-display/breadcrumb.d.ts +8 -0
  31. package/dist/src/renderers/data-display/kbd.d.ts +8 -0
  32. package/dist/src/renderers/data-display/list.d.ts +7 -0
  33. package/dist/src/renderers/data-display/statistic.d.ts +7 -0
  34. package/dist/src/renderers/data-display/table.d.ts +8 -0
  35. package/dist/src/renderers/data-display/tree-view.d.ts +7 -0
  36. package/dist/src/renderers/disclosure/accordion.d.ts +7 -0
  37. package/dist/src/renderers/disclosure/collapsible.d.ts +7 -0
  38. package/dist/src/renderers/disclosure/toggle-group.d.ts +8 -0
  39. package/dist/src/renderers/feedback/empty.d.ts +8 -0
  40. package/dist/src/renderers/feedback/loading.d.ts +7 -0
  41. package/dist/src/renderers/feedback/progress.d.ts +7 -0
  42. package/dist/src/renderers/feedback/skeleton.d.ts +7 -0
  43. package/dist/src/renderers/feedback/sonner.d.ts +8 -0
  44. package/dist/src/renderers/feedback/spinner.d.ts +8 -0
  45. package/dist/src/renderers/feedback/toast.d.ts +8 -0
  46. package/dist/src/renderers/feedback/toaster.d.ts +7 -0
  47. package/dist/src/renderers/form/button.d.ts +7 -0
  48. package/dist/src/renderers/form/calendar.d.ts +7 -0
  49. package/dist/src/renderers/form/checkbox.d.ts +7 -0
  50. package/dist/src/renderers/form/combobox.d.ts +8 -0
  51. package/dist/src/renderers/form/command.d.ts +8 -0
  52. package/dist/src/renderers/form/date-picker.d.ts +7 -0
  53. package/dist/src/renderers/form/file-upload.d.ts +7 -0
  54. package/dist/src/renderers/form/form.d.ts +7 -0
  55. package/dist/src/renderers/form/input-otp.d.ts +7 -0
  56. package/dist/src/renderers/form/input.d.ts +7 -0
  57. package/dist/src/renderers/form/label.d.ts +7 -0
  58. package/dist/src/renderers/form/radio-group.d.ts +7 -0
  59. package/dist/src/renderers/form/select.d.ts +7 -0
  60. package/dist/src/renderers/form/slider.d.ts +7 -0
  61. package/dist/src/renderers/form/switch.d.ts +7 -0
  62. package/dist/src/renderers/form/textarea.d.ts +7 -0
  63. package/dist/src/renderers/form/toggle.d.ts +7 -0
  64. package/dist/src/renderers/layout/aspect-ratio.d.ts +8 -0
  65. package/dist/src/renderers/layout/card.d.ts +7 -0
  66. package/dist/src/renderers/layout/container.d.ts +7 -0
  67. package/dist/src/renderers/layout/flex.d.ts +7 -0
  68. package/dist/src/renderers/layout/grid.d.ts +7 -0
  69. package/dist/src/renderers/layout/semantic.d.ts +7 -0
  70. package/dist/src/renderers/layout/stack.d.ts +7 -0
  71. package/dist/src/renderers/layout/tabs.d.ts +7 -0
  72. package/dist/src/renderers/navigation/header-bar.d.ts +7 -0
  73. package/dist/src/renderers/navigation/sidebar.d.ts +7 -0
  74. package/dist/src/renderers/overlay/alert-dialog.d.ts +7 -0
  75. package/dist/src/renderers/overlay/context-menu.d.ts +7 -0
  76. package/dist/src/renderers/overlay/dialog.d.ts +7 -0
  77. package/dist/src/renderers/overlay/drawer.d.ts +7 -0
  78. package/dist/src/renderers/overlay/dropdown-menu.d.ts +7 -0
  79. package/dist/src/renderers/overlay/hover-card.d.ts +7 -0
  80. package/dist/src/renderers/overlay/menubar.d.ts +8 -0
  81. package/dist/src/renderers/overlay/popover.d.ts +7 -0
  82. package/dist/src/renderers/overlay/sheet.d.ts +7 -0
  83. package/dist/src/renderers/overlay/tooltip.d.ts +7 -0
  84. package/dist/src/renderers/placeholders.d.ts +9 -0
  85. package/dist/src/ui/accordion.d.ts +7 -0
  86. package/dist/src/ui/alert-dialog.d.ts +7 -0
  87. package/dist/src/ui/alert.d.ts +7 -0
  88. package/dist/src/ui/aspect-ratio.d.ts +7 -0
  89. package/dist/src/ui/avatar.d.ts +7 -0
  90. package/dist/src/ui/badge.d.ts +7 -0
  91. package/dist/src/ui/breadcrumb.d.ts +7 -0
  92. package/dist/src/ui/button.d.ts +10 -5
  93. package/dist/src/ui/calendar.d.ts +14 -7
  94. package/dist/src/ui/card.d.ts +7 -0
  95. package/dist/src/ui/carousel.d.ts +7 -0
  96. package/dist/src/ui/checkbox.d.ts +7 -0
  97. package/dist/src/ui/collapsible.d.ts +7 -0
  98. package/dist/src/ui/combobox.d.ts +22 -0
  99. package/dist/src/ui/command.d.ts +7 -0
  100. package/dist/src/ui/context-menu.d.ts +7 -0
  101. package/dist/src/ui/date-picker.d.ts +15 -0
  102. package/dist/src/ui/dialog.d.ts +7 -0
  103. package/dist/src/ui/drawer.d.ts +7 -0
  104. package/dist/src/ui/dropdown-menu.d.ts +7 -0
  105. package/dist/src/ui/filter-builder.d.ts +7 -0
  106. package/dist/src/ui/form.d.ts +7 -0
  107. package/dist/src/ui/hover-card.d.ts +7 -0
  108. package/dist/src/ui/index.d.ts +10 -5
  109. package/dist/src/ui/input-otp.d.ts +7 -0
  110. package/dist/src/ui/input.d.ts +7 -0
  111. package/dist/src/ui/item.d.ts +7 -0
  112. package/dist/src/ui/kbd.d.ts +7 -0
  113. package/dist/src/ui/label.d.ts +7 -0
  114. package/dist/src/ui/menubar.d.ts +7 -0
  115. package/dist/src/ui/navigation-menu.d.ts +7 -0
  116. package/dist/src/ui/pagination.d.ts +7 -0
  117. package/dist/src/ui/popover.d.ts +7 -0
  118. package/dist/src/ui/progress.d.ts +7 -0
  119. package/dist/src/ui/radio-group.d.ts +7 -0
  120. package/dist/src/ui/resizable.d.ts +7 -0
  121. package/dist/src/ui/scroll-area.d.ts +7 -0
  122. package/dist/src/ui/select.d.ts +9 -2
  123. package/dist/src/ui/separator.d.ts +7 -0
  124. package/dist/src/ui/sheet.d.ts +7 -0
  125. package/dist/src/ui/sidebar.d.ts +14 -9
  126. package/dist/src/ui/skeleton.d.ts +7 -0
  127. package/dist/src/ui/slider.d.ts +7 -0
  128. package/dist/src/ui/spinner.d.ts +7 -0
  129. package/dist/src/ui/switch.d.ts +7 -0
  130. package/dist/src/ui/table.d.ts +15 -8
  131. package/dist/src/ui/tabs.d.ts +7 -0
  132. package/dist/src/ui/textarea.d.ts +7 -0
  133. package/dist/src/ui/toggle-group.d.ts +8 -3
  134. package/dist/src/ui/toggle.d.ts +7 -0
  135. package/dist/src/ui/tooltip.d.ts +7 -0
  136. package/metadata/ObjectGrid.component.yml +72 -0
  137. package/package.json +23 -11
  138. package/postcss.config.js +9 -1
  139. package/shadcn-components.json +310 -0
  140. package/src/__tests__/README.md +124 -0
  141. package/src/__tests__/basic-renderers.test.tsx +255 -0
  142. package/src/__tests__/complex-disclosure-renderers.test.tsx +301 -0
  143. package/src/__tests__/feedback-overlay-renderers.test.tsx +349 -0
  144. package/src/__tests__/form-renderers.test.tsx +364 -0
  145. package/src/__tests__/layout-data-renderers.test.tsx +340 -0
  146. package/src/__tests__/test-utils.tsx +190 -0
  147. package/src/hooks/use-mobile.tsx +8 -0
  148. package/src/index.css +86 -54
  149. package/src/index.test.ts +8 -0
  150. package/src/index.ts +21 -1
  151. package/src/lib/utils.tsx +8 -0
  152. package/src/new-components.test.ts +8 -9
  153. package/src/renderers/basic/button-group.tsx +78 -0
  154. package/src/renderers/basic/div.tsx +9 -1
  155. package/src/renderers/basic/html.tsx +8 -0
  156. package/src/renderers/basic/icon.tsx +66 -3
  157. package/src/renderers/basic/image.tsx +12 -1
  158. package/src/renderers/basic/index.ts +11 -0
  159. package/src/renderers/basic/navigation-menu.tsx +80 -0
  160. package/src/renderers/basic/pagination.tsx +82 -0
  161. package/src/renderers/basic/separator.tsx +9 -1
  162. package/src/renderers/basic/span.tsx +9 -1
  163. package/src/renderers/basic/text.tsx +8 -0
  164. package/src/renderers/complex/__tests__/data-table.test.ts +8 -0
  165. package/src/renderers/complex/carousel.tsx +11 -3
  166. package/src/renderers/complex/data-table.tsx +19 -4
  167. package/src/renderers/complex/filter-builder.tsx +8 -0
  168. package/src/renderers/complex/index.ts +9 -3
  169. package/src/renderers/complex/resizable.tsx +8 -0
  170. package/src/renderers/complex/scroll-area.tsx +8 -0
  171. package/src/renderers/complex/table.tsx +10 -2
  172. package/src/renderers/data-display/alert.tsx +8 -0
  173. package/src/renderers/data-display/avatar.tsx +8 -0
  174. package/src/renderers/data-display/badge.tsx +8 -0
  175. package/src/renderers/data-display/breadcrumb.tsx +59 -0
  176. package/src/renderers/data-display/index.ts +12 -0
  177. package/src/renderers/data-display/kbd.tsx +49 -0
  178. package/src/renderers/data-display/list.tsx +8 -0
  179. package/src/renderers/data-display/statistic.tsx +24 -43
  180. package/src/renderers/data-display/table.tsx +68 -0
  181. package/src/renderers/data-display/tree-view.tsx +26 -37
  182. package/src/renderers/disclosure/accordion.tsx +8 -0
  183. package/src/renderers/disclosure/collapsible.tsx +8 -0
  184. package/src/renderers/disclosure/index.ts +9 -0
  185. package/src/renderers/disclosure/toggle-group.tsx +77 -0
  186. package/src/renderers/feedback/empty.tsx +48 -0
  187. package/src/renderers/feedback/index.ts +12 -0
  188. package/src/renderers/feedback/loading.tsx +8 -0
  189. package/src/renderers/feedback/progress.tsx +8 -0
  190. package/src/renderers/feedback/skeleton.tsx +8 -0
  191. package/src/renderers/feedback/sonner.tsx +55 -0
  192. package/src/renderers/feedback/spinner.tsx +54 -0
  193. package/src/renderers/feedback/toast.tsx +58 -0
  194. package/src/renderers/feedback/toaster.tsx +13 -17
  195. package/src/renderers/form/button.tsx +8 -0
  196. package/src/renderers/form/calendar.tsx +8 -0
  197. package/src/renderers/form/checkbox.tsx +8 -0
  198. package/src/renderers/form/combobox.tsx +47 -0
  199. package/src/renderers/form/command.tsx +57 -0
  200. package/src/renderers/form/date-picker.tsx +10 -2
  201. package/src/renderers/form/file-upload.tsx +10 -2
  202. package/src/renderers/form/form.tsx +12 -3
  203. package/src/renderers/form/index.ts +10 -0
  204. package/src/renderers/form/input-otp.tsx +34 -15
  205. package/src/renderers/form/input.tsx +89 -50
  206. package/src/renderers/form/label.tsx +8 -0
  207. package/src/renderers/form/radio-group.tsx +8 -0
  208. package/src/renderers/form/select.tsx +8 -0
  209. package/src/renderers/form/slider.tsx +16 -1
  210. package/src/renderers/form/switch.tsx +8 -0
  211. package/src/renderers/form/textarea.tsx +8 -0
  212. package/src/renderers/form/toggle.tsx +8 -0
  213. package/src/renderers/index.ts +8 -0
  214. package/src/renderers/layout/aspect-ratio.tsx +50 -0
  215. package/src/renderers/layout/card.tsx +8 -0
  216. package/src/renderers/layout/container.tsx +20 -12
  217. package/src/renderers/layout/flex.tsx +16 -8
  218. package/src/renderers/layout/grid.tsx +8 -0
  219. package/src/renderers/layout/index.ts +9 -0
  220. package/src/renderers/layout/page.tsx +9 -1
  221. package/src/renderers/layout/semantic.tsx +8 -0
  222. package/src/renderers/layout/stack.tsx +16 -8
  223. package/src/renderers/layout/tabs.tsx +8 -0
  224. package/src/renderers/navigation/header-bar.tsx +9 -1
  225. package/src/renderers/navigation/index.ts +8 -0
  226. package/src/renderers/navigation/sidebar.tsx +8 -0
  227. package/src/renderers/overlay/alert-dialog.tsx +8 -0
  228. package/src/renderers/overlay/context-menu.tsx +9 -1
  229. package/src/renderers/overlay/dialog.tsx +8 -0
  230. package/src/renderers/overlay/drawer.tsx +8 -0
  231. package/src/renderers/overlay/dropdown-menu.tsx +8 -0
  232. package/src/renderers/overlay/hover-card.tsx +8 -0
  233. package/src/renderers/overlay/index.ts +9 -0
  234. package/src/renderers/overlay/menubar.tsx +75 -0
  235. package/src/renderers/overlay/popover.tsx +8 -0
  236. package/src/renderers/overlay/sheet.tsx +8 -0
  237. package/src/renderers/overlay/tooltip.tsx +8 -0
  238. package/src/renderers/placeholders.tsx +107 -0
  239. package/src/ui/accordion.tsx +8 -0
  240. package/src/ui/alert-dialog.tsx +8 -0
  241. package/src/ui/alert.tsx +14 -24
  242. package/src/ui/aspect-ratio.tsx +8 -0
  243. package/src/ui/avatar.tsx +8 -0
  244. package/src/ui/badge.tsx +13 -6
  245. package/src/ui/breadcrumb.tsx +8 -0
  246. package/src/ui/button-group.tsx +8 -0
  247. package/src/ui/button.tsx +38 -36
  248. package/src/ui/calendar.tsx +57 -200
  249. package/src/ui/card.tsx +8 -0
  250. package/src/ui/carousel.tsx +8 -0
  251. package/src/ui/checkbox.tsx +8 -0
  252. package/src/ui/collapsible.tsx +8 -0
  253. package/src/ui/combobox.tsx +104 -0
  254. package/src/ui/command.tsx +8 -0
  255. package/src/ui/context-menu.tsx +8 -0
  256. package/src/ui/date-picker.tsx +61 -0
  257. package/src/ui/dialog.tsx +8 -0
  258. package/src/ui/drawer.tsx +8 -0
  259. package/src/ui/dropdown-menu.tsx +8 -0
  260. package/src/ui/empty.tsx +8 -0
  261. package/src/ui/filter-builder.tsx +8 -0
  262. package/src/ui/form.tsx +8 -0
  263. package/src/ui/hover-card.tsx +8 -0
  264. package/src/ui/index.ts +11 -5
  265. package/src/ui/input-otp.tsx +20 -12
  266. package/src/ui/input.tsx +8 -0
  267. package/src/ui/item.tsx +8 -0
  268. package/src/ui/kbd.tsx +8 -0
  269. package/src/ui/label.tsx +8 -0
  270. package/src/ui/menubar.tsx +8 -0
  271. package/src/ui/navigation-menu.tsx +8 -0
  272. package/src/ui/pagination.tsx +8 -0
  273. package/src/ui/popover.tsx +9 -1
  274. package/src/ui/progress.tsx +11 -15
  275. package/src/ui/radio-group.tsx +8 -0
  276. package/src/ui/resizable.tsx +8 -0
  277. package/src/ui/scroll-area.tsx +9 -1
  278. package/src/ui/select.tsx +17 -9
  279. package/src/ui/separator.tsx +8 -0
  280. package/src/ui/sheet.tsx +8 -0
  281. package/src/ui/sidebar.tsx +34 -15
  282. package/src/ui/skeleton.tsx +8 -0
  283. package/src/ui/slider.tsx +8 -0
  284. package/src/ui/sonner.tsx +12 -20
  285. package/src/ui/spinner.tsx +11 -23
  286. package/src/ui/switch.tsx +8 -0
  287. package/src/ui/table.tsx +102 -97
  288. package/src/ui/tabs.tsx +8 -0
  289. package/src/ui/textarea.tsx +8 -0
  290. package/src/ui/toggle-group.tsx +12 -21
  291. package/src/ui/toggle.tsx +15 -12
  292. package/src/ui/tooltip.tsx +8 -0
  293. package/tsconfig.json +2 -1
  294. package/vite.config.ts +11 -1
  295. package/dist/src/index.test.d.ts +0 -1
  296. package/dist/src/new-components.test.d.ts +0 -1
  297. package/dist/src/renderers/complex/__tests__/data-table.test.d.ts +0 -0
  298. package/dist/src/renderers/complex/calendar-view.d.ts +0 -1
  299. package/dist/src/renderers/complex/chatbot.d.ts +0 -1
  300. package/dist/src/renderers/complex/chatbot.test.d.ts +0 -1
  301. package/dist/src/renderers/complex/timeline.d.ts +0 -1
  302. package/dist/src/ui/calendar-view.d.ts +0 -21
  303. package/dist/src/ui/chatbot.d.ts +0 -36
  304. package/dist/src/ui/field.d.ts +0 -24
  305. package/dist/src/ui/input-group.d.ts +0 -16
  306. package/dist/src/ui/timeline.d.ts +0 -25
  307. package/metadata/ObjectTable.component.yml +0 -41
  308. package/src/renderers/complex/calendar-view.tsx +0 -219
  309. package/src/renderers/complex/chatbot.test.ts +0 -44
  310. package/src/renderers/complex/chatbot.tsx +0 -185
  311. package/src/renderers/complex/timeline.tsx +0 -466
  312. package/src/ui/calendar-view.tsx +0 -503
  313. package/src/ui/chatbot.tsx +0 -240
  314. package/src/ui/field.tsx +0 -246
  315. package/src/ui/input-group.tsx +0 -170
  316. package/src/ui/timeline.tsx +0 -266
  317. package/tailwind.config.js +0 -75
@@ -0,0 +1,301 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
9
+ import { describe, it, expect, beforeAll } from 'vitest';
10
+ import { ComponentRegistry } from '@object-ui/core';
11
+ import {
12
+ renderComponent,
13
+ validateComponentRegistration,
14
+ checkDOMStructure,
15
+ } from './test-utils';
16
+
17
+ // Import renderers to ensure registration
18
+ beforeAll(async () => {
19
+ await import('../renderers');
20
+ });
21
+
22
+ /**
23
+ * Comprehensive tests for disclosure renderer components
24
+ */
25
+ describe('Disclosure Renderers - Display Issue Detection', () => {
26
+ describe('Accordion Renderer', () => {
27
+ it('should be properly registered', () => {
28
+ const validation = validateComponentRegistration('accordion');
29
+ expect(validation.isRegistered).toBe(true);
30
+ });
31
+
32
+ it('should render accordion with items', () => {
33
+ const { container } = renderComponent({
34
+ type: 'accordion',
35
+ items: [
36
+ {
37
+ title: 'Section 1',
38
+ content: 'Content 1',
39
+ },
40
+ {
41
+ title: 'Section 2',
42
+ content: 'Content 2',
43
+ },
44
+ ],
45
+ });
46
+
47
+ expect(container.textContent).toContain('Section 1');
48
+ expect(container.textContent).toContain('Section 2');
49
+ });
50
+
51
+ it('should not have structural issues', () => {
52
+ const { container } = renderComponent({
53
+ type: 'accordion',
54
+ items: [{ title: 'Test', content: 'Content' }],
55
+ });
56
+
57
+ const domCheck = checkDOMStructure(container);
58
+ expect(domCheck.hasContent).toBe(true);
59
+ });
60
+ });
61
+
62
+ describe('Collapsible Renderer', () => {
63
+ it('should be properly registered', () => {
64
+ const validation = validateComponentRegistration('collapsible');
65
+ expect(validation.isRegistered).toBe(true);
66
+ });
67
+
68
+ it('should render collapsible component', () => {
69
+ const { container } = renderComponent({
70
+ type: 'collapsible',
71
+ trigger: { type: 'button', label: 'Toggle' },
72
+ body: [{ type: 'text', content: 'Hidden content' }],
73
+ });
74
+
75
+ expect(container.textContent).toContain('Toggle');
76
+ });
77
+ });
78
+
79
+ describe('Toggle Group Renderer', () => {
80
+ it('should be properly registered', () => {
81
+ const validation = validateComponentRegistration('toggle-group');
82
+ expect(validation.isRegistered).toBe(true);
83
+ });
84
+
85
+ it('should render toggle group with items', () => {
86
+ const { container } = renderComponent({
87
+ type: 'toggle-group',
88
+ selectionType: 'single',
89
+ items: [
90
+ { value: 'bold', label: 'Bold' },
91
+ { value: 'italic', label: 'Italic' },
92
+ ],
93
+ });
94
+
95
+ expect(container).toBeDefined();
96
+ });
97
+ });
98
+ });
99
+
100
+ /**
101
+ * Comprehensive tests for complex renderer components
102
+ */
103
+ describe('Complex Renderers - Display Issue Detection', () => {
104
+ describe('Data Table Renderer', () => {
105
+ it('should be properly registered', () => {
106
+ const validation = validateComponentRegistration('data-table');
107
+ expect(validation.isRegistered).toBe(true);
108
+ expect(validation.hasDefaultProps).toBe(true);
109
+ });
110
+
111
+ it('should render table with data', () => {
112
+ const { container } = renderComponent({
113
+ type: 'data-table',
114
+ columns: [
115
+ { id: 'name', header: 'Name' },
116
+ { id: 'age', header: 'Age' },
117
+ ],
118
+ data: [
119
+ { name: 'John', age: 30 },
120
+ { name: 'Jane', age: 25 },
121
+ ],
122
+ });
123
+
124
+ expect(container.textContent).toContain('Name');
125
+ expect(container.textContent).toContain('Age');
126
+ });
127
+
128
+ it('should use table semantics', () => {
129
+ const { container } = renderComponent({
130
+ type: 'data-table',
131
+ columns: [{ id: 'col1', header: 'Column 1' }],
132
+ data: [{ col1: 'Data' }],
133
+ });
134
+
135
+ const table = container.querySelector('table');
136
+ expect(table || container.querySelector('[role="table"]')).toBeTruthy();
137
+ });
138
+
139
+ it('should not have excessive nesting', () => {
140
+ const { container } = renderComponent({
141
+ type: 'data-table',
142
+ columns: [{ id: 'col1', header: 'Test' }],
143
+ data: [{ col1: 'Value' }],
144
+ });
145
+
146
+ const domCheck = checkDOMStructure(container);
147
+ // Tables can be nested but not excessively
148
+ expect(domCheck.nestedDepth).toBeLessThan(25);
149
+ });
150
+ });
151
+
152
+ describe('Carousel Renderer', () => {
153
+ it('should be properly registered', () => {
154
+ const validation = validateComponentRegistration('carousel');
155
+ expect(validation.isRegistered).toBe(true);
156
+ });
157
+
158
+ it('should render carousel with items', () => {
159
+ const { container } = renderComponent({
160
+ type: 'carousel',
161
+ items: [
162
+ { type: 'div', body: [{ type: 'text', content: 'Slide 1' }] },
163
+ { type: 'div', body: [{ type: 'text', content: 'Slide 2' }] },
164
+ ],
165
+ });
166
+
167
+ // Carousel should render
168
+ expect(container).toBeDefined();
169
+ });
170
+ });
171
+
172
+ describe('Scroll Area Renderer', () => {
173
+ it('should be properly registered', () => {
174
+ const validation = validateComponentRegistration('scroll-area');
175
+ expect(validation.isRegistered).toBe(true);
176
+ });
177
+
178
+ it('should render scrollable area', () => {
179
+ const { container } = renderComponent({
180
+ type: 'scroll-area',
181
+ content: [{ type: 'text', content: 'Scrollable content' }],
182
+ });
183
+
184
+ // ScrollArea renders content
185
+ expect(container.textContent).toContain('Scrollable content');
186
+ });
187
+ });
188
+
189
+ describe('Resizable Renderer', () => {
190
+ it('should be properly registered', () => {
191
+ const validation = validateComponentRegistration('resizable');
192
+ expect(validation.isRegistered).toBe(true);
193
+ });
194
+
195
+ it('should render resizable panels', () => {
196
+ const { container } = renderComponent({
197
+ type: 'resizable',
198
+ panels: [
199
+ { content: { type: 'text', content: 'Panel 1' } },
200
+ { content: { type: 'text', content: 'Panel 2' } },
201
+ ],
202
+ });
203
+
204
+ expect(container).toBeDefined();
205
+ });
206
+ });
207
+
208
+ describe('Filter Builder Renderer', () => {
209
+ it('should be properly registered', () => {
210
+ const validation = validateComponentRegistration('filter-builder');
211
+ expect(validation.isRegistered).toBe(true);
212
+ });
213
+
214
+ it('should render filter builder', () => {
215
+ const { container } = renderComponent({
216
+ type: 'filter-builder',
217
+ fields: [
218
+ { name: 'name', label: 'Name', type: 'text' },
219
+ { name: 'age', label: 'Age', type: 'number' },
220
+ ],
221
+ });
222
+
223
+ expect(container).toBeDefined();
224
+ });
225
+ });
226
+
227
+ describe('Table Renderer', () => {
228
+ it('should be properly registered', () => {
229
+ const validation = validateComponentRegistration('table');
230
+ expect(validation.isRegistered).toBe(true);
231
+ });
232
+
233
+ it('should render basic table', () => {
234
+ const { container } = renderComponent({
235
+ type: 'table',
236
+ head: {
237
+ rows: [
238
+ {
239
+ cells: [
240
+ { type: 'text', content: 'Header 1' },
241
+ { type: 'text', content: 'Header 2' },
242
+ ],
243
+ },
244
+ ],
245
+ },
246
+ body: {
247
+ rows: [
248
+ {
249
+ cells: [
250
+ { type: 'text', content: 'Cell 1' },
251
+ { type: 'text', content: 'Cell 2' },
252
+ ],
253
+ },
254
+ ],
255
+ },
256
+ });
257
+
258
+ const table = container.querySelector('table');
259
+ expect(table).toBeTruthy();
260
+ });
261
+ });
262
+ });
263
+
264
+ /**
265
+ * Cross-cutting concerns: Tests that apply to all components
266
+ */
267
+ describe('All Renderers - Cross-Cutting Concerns', () => {
268
+ it('should not render components with excessive DOM nesting', () => {
269
+ const components = ['div', 'container', 'flex', 'grid'];
270
+
271
+ components.forEach(type => {
272
+ if (ComponentRegistry.has(type)) {
273
+ const { container } = renderComponent({
274
+ type,
275
+ body: [{ type: 'text', content: 'Test' }],
276
+ });
277
+
278
+ const domCheck = checkDOMStructure(container);
279
+ expect(domCheck.nestedDepth).toBeLessThan(20);
280
+ }
281
+ });
282
+ });
283
+
284
+ it('should handle className prop for custom styling', () => {
285
+ const components = ['button', 'input', 'div', 'text'];
286
+
287
+ components.forEach(type => {
288
+ if (ComponentRegistry.has(type)) {
289
+ const { container } = renderComponent({
290
+ type,
291
+ className: 'custom-class',
292
+ label: 'Test',
293
+ content: 'Test',
294
+ });
295
+
296
+ // Should render without errors
297
+ expect(container).toBeDefined();
298
+ }
299
+ });
300
+ });
301
+ });
@@ -0,0 +1,349 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
9
+ import { describe, it, expect, beforeAll } from 'vitest';
10
+ import {
11
+ renderComponent,
12
+ validateComponentRegistration,
13
+ checkDOMStructure,
14
+ } from './test-utils';
15
+
16
+ // Import renderers to ensure registration
17
+ beforeAll(async () => {
18
+ await import('../renderers');
19
+ });
20
+
21
+ /**
22
+ * Comprehensive tests for feedback renderer components
23
+ */
24
+ describe('Feedback Renderers - Display Issue Detection', () => {
25
+ describe('Loading Renderer', () => {
26
+ it('should be properly registered', () => {
27
+ const validation = validateComponentRegistration('loading');
28
+ expect(validation.isRegistered).toBe(true);
29
+ });
30
+
31
+ it('should render loading indicator', () => {
32
+ const { container } = renderComponent({
33
+ type: 'loading',
34
+ });
35
+
36
+ const domCheck = checkDOMStructure(container);
37
+ expect(domCheck.hasChildren || domCheck.hasContent).toBe(true);
38
+ });
39
+
40
+ it('should support loading message', () => {
41
+ const { container } = renderComponent({
42
+ type: 'loading',
43
+ text: 'Loading data...',
44
+ });
45
+
46
+ expect(container.textContent).toContain('Loading');
47
+ });
48
+ });
49
+
50
+ describe('Spinner Renderer', () => {
51
+ it('should be properly registered', () => {
52
+ const validation = validateComponentRegistration('spinner');
53
+ expect(validation.isRegistered).toBe(true);
54
+ });
55
+
56
+ it('should render spinner element', () => {
57
+ const { container } = renderComponent({
58
+ type: 'spinner',
59
+ });
60
+
61
+ // Spinner should render some content
62
+ expect(container.firstChild).toBeTruthy();
63
+ });
64
+ });
65
+
66
+ describe('Progress Renderer', () => {
67
+ it('should be properly registered', () => {
68
+ const validation = validateComponentRegistration('progress');
69
+ expect(validation.isRegistered).toBe(true);
70
+ });
71
+
72
+ it('should render progress bar', () => {
73
+ const { container } = renderComponent({
74
+ type: 'progress',
75
+ value: 50,
76
+ });
77
+
78
+ const progress = container.querySelector('[role="progressbar"], progress');
79
+ expect(progress || container.firstChild).toBeTruthy();
80
+ });
81
+
82
+ it('should support different values', () => {
83
+ const values = [0, 25, 50, 75, 100];
84
+
85
+ values.forEach(value => {
86
+ const { container } = renderComponent({
87
+ type: 'progress',
88
+ value,
89
+ });
90
+
91
+ expect(container.firstChild).toBeTruthy();
92
+ });
93
+ });
94
+ });
95
+
96
+ describe('Skeleton Renderer', () => {
97
+ it('should be properly registered', () => {
98
+ const validation = validateComponentRegistration('skeleton');
99
+ expect(validation.isRegistered).toBe(true);
100
+ });
101
+
102
+ it('should render skeleton placeholder', () => {
103
+ const { container } = renderComponent({
104
+ type: 'skeleton',
105
+ });
106
+
107
+ expect(container.firstChild).toBeTruthy();
108
+ });
109
+
110
+ it('should support different shapes', () => {
111
+ const { container: rect } = renderComponent({
112
+ type: 'skeleton',
113
+ className: 'h-12',
114
+ });
115
+
116
+ const { container: circle } = renderComponent({
117
+ type: 'skeleton',
118
+ className: 'h-12 w-12 rounded-full',
119
+ });
120
+
121
+ expect(rect.firstChild).toBeTruthy();
122
+ expect(circle.firstChild).toBeTruthy();
123
+ });
124
+ });
125
+
126
+ describe('Empty Renderer', () => {
127
+ it('should be properly registered', () => {
128
+ const validation = validateComponentRegistration('empty');
129
+ expect(validation.isRegistered).toBe(true);
130
+ });
131
+
132
+ it('should render empty state message', () => {
133
+ const { container } = renderComponent({
134
+ type: 'empty',
135
+ description: 'No data available',
136
+ });
137
+
138
+ expect(container.textContent).toContain('No data');
139
+ });
140
+ });
141
+
142
+ describe('Toast Renderer', () => {
143
+ it('should be properly registered', () => {
144
+ const validation = validateComponentRegistration('toast');
145
+ expect(validation.isRegistered).toBe(true);
146
+ });
147
+
148
+ it('should render toast notification', () => {
149
+ const { container } = renderComponent({
150
+ type: 'toast',
151
+ title: 'Success',
152
+ description: 'Operation completed',
153
+ });
154
+
155
+ // Toast might be rendered in a portal, so just check it doesn't error
156
+ expect(container).toBeDefined();
157
+ });
158
+ });
159
+ });
160
+
161
+ /**
162
+ * Comprehensive tests for overlay renderer components
163
+ */
164
+ describe('Overlay Renderers - Display Issue Detection', () => {
165
+ describe('Dialog Renderer', () => {
166
+ it('should be properly registered', () => {
167
+ const validation = validateComponentRegistration('dialog');
168
+ expect(validation.isRegistered).toBe(true);
169
+ });
170
+
171
+ it('should render dialog structure', () => {
172
+ const { container } = renderComponent({
173
+ type: 'dialog',
174
+ title: 'Dialog Title',
175
+ open: true,
176
+ body: [
177
+ { type: 'text', content: 'Dialog content' },
178
+ ],
179
+ });
180
+
181
+ // Dialog might render in a portal
182
+ expect(container).toBeDefined();
183
+ });
184
+ });
185
+
186
+ describe('Alert Dialog Renderer', () => {
187
+ it('should be properly registered', () => {
188
+ const validation = validateComponentRegistration('alert-dialog');
189
+ expect(validation.isRegistered).toBe(true);
190
+ });
191
+
192
+ it('should render alert dialog', () => {
193
+ const { container } = renderComponent({
194
+ type: 'alert-dialog',
195
+ title: 'Confirm',
196
+ description: 'Are you sure?',
197
+ open: true,
198
+ });
199
+
200
+ expect(container).toBeDefined();
201
+ });
202
+ });
203
+
204
+ describe('Sheet Renderer', () => {
205
+ it('should be properly registered', () => {
206
+ const validation = validateComponentRegistration('sheet');
207
+ expect(validation.isRegistered).toBe(true);
208
+ });
209
+
210
+ it('should render sheet component', () => {
211
+ const { container } = renderComponent({
212
+ type: 'sheet',
213
+ title: 'Sheet',
214
+ open: true,
215
+ });
216
+
217
+ expect(container).toBeDefined();
218
+ });
219
+ });
220
+
221
+ describe('Drawer Renderer', () => {
222
+ it('should be properly registered', () => {
223
+ const validation = validateComponentRegistration('drawer');
224
+ expect(validation.isRegistered).toBe(true);
225
+ });
226
+
227
+ it('should render drawer component', () => {
228
+ const { container } = renderComponent({
229
+ type: 'drawer',
230
+ title: 'Drawer',
231
+ open: true,
232
+ });
233
+
234
+ expect(container).toBeDefined();
235
+ });
236
+ });
237
+
238
+ describe('Popover Renderer', () => {
239
+ it('should be properly registered', () => {
240
+ const validation = validateComponentRegistration('popover');
241
+ expect(validation.isRegistered).toBe(true);
242
+ });
243
+
244
+ it('should render popover structure', () => {
245
+ const { container } = renderComponent({
246
+ type: 'popover',
247
+ trigger: { type: 'button', label: 'Open' },
248
+ content: { type: 'text', content: 'Popover content' },
249
+ });
250
+
251
+ expect(container).toBeDefined();
252
+ });
253
+ });
254
+
255
+ describe('Tooltip Renderer', () => {
256
+ it('should be properly registered', () => {
257
+ const validation = validateComponentRegistration('tooltip');
258
+ expect(validation.isRegistered).toBe(true);
259
+ });
260
+
261
+ it('should render tooltip with trigger', () => {
262
+ const { container } = renderComponent({
263
+ type: 'tooltip',
264
+ content: 'Helpful tip',
265
+ trigger: [{ type: 'button', label: 'Hover me' }],
266
+ });
267
+
268
+ // Tooltip renders with trigger
269
+ expect(container.textContent).toContain('Hover me');
270
+ });
271
+ });
272
+
273
+ describe('Dropdown Menu Renderer', () => {
274
+ it('should be properly registered', () => {
275
+ const validation = validateComponentRegistration('dropdown-menu');
276
+ expect(validation.isRegistered).toBe(true);
277
+ });
278
+
279
+ it('should render dropdown with items', () => {
280
+ const { container } = renderComponent({
281
+ type: 'dropdown-menu',
282
+ trigger: { type: 'button', label: 'Menu' },
283
+ items: [
284
+ { label: 'Item 1' },
285
+ { label: 'Item 2' },
286
+ ],
287
+ });
288
+
289
+ expect(container).toBeDefined();
290
+ });
291
+ });
292
+
293
+ describe('Context Menu Renderer', () => {
294
+ it('should be properly registered', () => {
295
+ const validation = validateComponentRegistration('context-menu');
296
+ expect(validation.isRegistered).toBe(true);
297
+ });
298
+
299
+ it('should render context menu', () => {
300
+ const { container } = renderComponent({
301
+ type: 'context-menu',
302
+ items: [
303
+ { label: 'Action 1' },
304
+ { label: 'Action 2' },
305
+ ],
306
+ });
307
+
308
+ expect(container).toBeDefined();
309
+ });
310
+ });
311
+
312
+ describe('Hover Card Renderer', () => {
313
+ it('should be properly registered', () => {
314
+ const validation = validateComponentRegistration('hover-card');
315
+ expect(validation.isRegistered).toBe(true);
316
+ });
317
+
318
+ it('should render hover card', () => {
319
+ const { container } = renderComponent({
320
+ type: 'hover-card',
321
+ trigger: { type: 'text', content: 'Hover' },
322
+ content: { type: 'text', content: 'Card content' },
323
+ });
324
+
325
+ expect(container).toBeDefined();
326
+ });
327
+ });
328
+
329
+ describe('Menubar Renderer', () => {
330
+ it('should be properly registered', () => {
331
+ const validation = validateComponentRegistration('menubar');
332
+ expect(validation.isRegistered).toBe(true);
333
+ });
334
+
335
+ it('should render menubar', () => {
336
+ const { container } = renderComponent({
337
+ type: 'menubar',
338
+ menus: [
339
+ {
340
+ label: 'File',
341
+ items: [{ label: 'New' }, { label: 'Open' }],
342
+ },
343
+ ],
344
+ });
345
+
346
+ expect(container).toBeDefined();
347
+ });
348
+ });
349
+ });