@object-ui/components 3.3.0 → 3.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 (321) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +21 -1
  3. package/dist/index.css +6339 -2
  4. package/dist/index.js +17600 -17481
  5. package/dist/index.umd.cjs +36 -36
  6. package/dist/packages/components/src/custom/empty.d.ts +12 -1
  7. package/dist/packages/components/src/renderers/action/action-bar.d.ts +12 -1
  8. package/dist/packages/components/src/ui/chart.d.ts +10 -29
  9. package/package.json +65 -44
  10. package/.turbo/turbo-build.log +0 -84
  11. package/README_SHADCN_SYNC.md +0 -281
  12. package/TESTING.md +0 -335
  13. package/docs/FilterBuilder.md +0 -268
  14. package/metadata/Chart.component.yml +0 -30
  15. package/metadata/FilterBuilder.component.yml +0 -39
  16. package/metadata/GridLayout.component.yml +0 -27
  17. package/metadata/Menu.component.yml +0 -31
  18. package/metadata/ObjectForm.component.yml +0 -34
  19. package/metadata/ObjectGrid.component.yml +0 -72
  20. package/metadata/Page.component.yml +0 -24
  21. package/postcss.config.js +0 -14
  22. package/shadcn-components.json +0 -440
  23. package/src/SchemaRenderer.tsx +0 -28
  24. package/src/__tests__/PageRendererRegions.test.tsx +0 -668
  25. package/src/__tests__/README.md +0 -124
  26. package/src/__tests__/__snapshots__/snapshot-critical.test.tsx.snap +0 -811
  27. package/src/__tests__/__snapshots__/snapshot.test.tsx.snap +0 -327
  28. package/src/__tests__/accessibility.test.tsx +0 -137
  29. package/src/__tests__/action-bar.test.tsx +0 -206
  30. package/src/__tests__/api-consistency.test.tsx +0 -596
  31. package/src/__tests__/basic-renderers.test.tsx +0 -255
  32. package/src/__tests__/color-contrast.test.tsx +0 -212
  33. package/src/__tests__/complex-disclosure-renderers.test.tsx +0 -302
  34. package/src/__tests__/compliance.test.tsx +0 -72
  35. package/src/__tests__/config-field-renderer.test.tsx +0 -307
  36. package/src/__tests__/config-panel-renderer.test.tsx +0 -580
  37. package/src/__tests__/config-primitives.test.tsx +0 -106
  38. package/src/__tests__/edge-cases.test.tsx +0 -285
  39. package/src/__tests__/feedback-overlay-renderers.test.tsx +0 -349
  40. package/src/__tests__/filter-builder.test.tsx +0 -409
  41. package/src/__tests__/form-renderers.test.tsx +0 -364
  42. package/src/__tests__/layout-data-renderers.test.tsx +0 -340
  43. package/src/__tests__/mobile-accessibility.test.tsx +0 -120
  44. package/src/__tests__/navigation-overlay.test.tsx +0 -370
  45. package/src/__tests__/snapshot-critical.test.tsx +0 -317
  46. package/src/__tests__/snapshot.test.tsx +0 -205
  47. package/src/__tests__/test-utils.tsx +0 -190
  48. package/src/__tests__/use-config-draft.test.tsx +0 -295
  49. package/src/__tests__/view-compliance.test.tsx +0 -153
  50. package/src/__tests__/wcag-audit.test.tsx +0 -493
  51. package/src/custom/action-param-dialog.tsx +0 -264
  52. package/src/custom/button-group.tsx +0 -91
  53. package/src/custom/combobox.tsx +0 -104
  54. package/src/custom/config-field-renderer.tsx +0 -276
  55. package/src/custom/config-panel-renderer.tsx +0 -306
  56. package/src/custom/config-row.tsx +0 -50
  57. package/src/custom/date-picker.tsx +0 -61
  58. package/src/custom/empty.tsx +0 -112
  59. package/src/custom/field.tsx +0 -81
  60. package/src/custom/filter-builder.tsx +0 -418
  61. package/src/custom/index.ts +0 -21
  62. package/src/custom/input-group.tsx +0 -53
  63. package/src/custom/item.tsx +0 -201
  64. package/src/custom/kbd.tsx +0 -36
  65. package/src/custom/mobile-dialog-content.tsx +0 -67
  66. package/src/custom/native-select.tsx +0 -33
  67. package/src/custom/navigation-overlay.tsx +0 -334
  68. package/src/custom/section-header.tsx +0 -68
  69. package/src/custom/sort-builder.tsx +0 -129
  70. package/src/custom/spinner.tsx +0 -26
  71. package/src/custom/view-skeleton.tsx +0 -243
  72. package/src/custom/view-states.tsx +0 -153
  73. package/src/debug/DebugPanel.tsx +0 -313
  74. package/src/debug/__tests__/DebugPanel.test.tsx +0 -134
  75. package/src/debug/index.ts +0 -10
  76. package/src/hooks/use-config-draft.ts +0 -127
  77. package/src/hooks/use-mobile.tsx +0 -27
  78. package/src/index.css +0 -245
  79. package/src/index.ts +0 -47
  80. package/src/lib/use-sync-external-store-shim.ts +0 -10
  81. package/src/lib/use-sync-external-store-with-selector-shim.ts +0 -90
  82. package/src/lib/utils.tsx +0 -35
  83. package/src/new-components.test.ts +0 -73
  84. package/src/renderers/action/action-bar.tsx +0 -221
  85. package/src/renderers/action/action-button.tsx +0 -158
  86. package/src/renderers/action/action-group.tsx +0 -270
  87. package/src/renderers/action/action-icon.tsx +0 -150
  88. package/src/renderers/action/action-menu.tsx +0 -203
  89. package/src/renderers/action/index.ts +0 -19
  90. package/src/renderers/action/resolve-icon.ts +0 -35
  91. package/src/renderers/basic/button-group.tsx +0 -79
  92. package/src/renderers/basic/div.tsx +0 -60
  93. package/src/renderers/basic/html.tsx +0 -43
  94. package/src/renderers/basic/icon.tsx +0 -89
  95. package/src/renderers/basic/image.tsx +0 -49
  96. package/src/renderers/basic/index.ts +0 -18
  97. package/src/renderers/basic/navigation-menu.tsx +0 -81
  98. package/src/renderers/basic/pagination.tsx +0 -109
  99. package/src/renderers/basic/separator.tsx +0 -57
  100. package/src/renderers/basic/span.tsx +0 -63
  101. package/src/renderers/basic/text.tsx +0 -52
  102. package/src/renderers/complex/README-KANBAN.md +0 -208
  103. package/src/renderers/complex/TIMELINE.md +0 -353
  104. package/src/renderers/complex/__tests__/data-table-airtable-ux.test.tsx +0 -239
  105. package/src/renderers/complex/__tests__/data-table-batch-editing.test.tsx +0 -275
  106. package/src/renderers/complex/__tests__/data-table-cell-renderer.test.tsx +0 -120
  107. package/src/renderers/complex/__tests__/data-table-editing.test.tsx +0 -221
  108. package/src/renderers/complex/__tests__/data-table.test.ts +0 -76
  109. package/src/renderers/complex/carousel.tsx +0 -69
  110. package/src/renderers/complex/data-table.tsx +0 -1243
  111. package/src/renderers/complex/filter-builder.tsx +0 -77
  112. package/src/renderers/complex/index.ts +0 -16
  113. package/src/renderers/complex/resizable.tsx +0 -66
  114. package/src/renderers/complex/scroll-area.tsx +0 -58
  115. package/src/renderers/complex/table.tsx +0 -95
  116. package/src/renderers/data-display/alert.tsx +0 -46
  117. package/src/renderers/data-display/avatar.tsx +0 -38
  118. package/src/renderers/data-display/badge.tsx +0 -55
  119. package/src/renderers/data-display/breadcrumb.tsx +0 -61
  120. package/src/renderers/data-display/index.ts +0 -18
  121. package/src/renderers/data-display/kbd.tsx +0 -50
  122. package/src/renderers/data-display/list.tsx +0 -75
  123. package/src/renderers/data-display/statistic.tsx +0 -95
  124. package/src/renderers/data-display/table.tsx +0 -78
  125. package/src/renderers/data-display/tree-view.tsx +0 -176
  126. package/src/renderers/disclosure/accordion.tsx +0 -69
  127. package/src/renderers/disclosure/collapsible.tsx +0 -53
  128. package/src/renderers/disclosure/index.ts +0 -11
  129. package/src/renderers/disclosure/toggle-group.tsx +0 -79
  130. package/src/renderers/feedback/empty.tsx +0 -49
  131. package/src/renderers/feedback/index.ts +0 -16
  132. package/src/renderers/feedback/loading.tsx +0 -78
  133. package/src/renderers/feedback/progress.tsx +0 -29
  134. package/src/renderers/feedback/skeleton.tsx +0 -31
  135. package/src/renderers/feedback/sonner.tsx +0 -56
  136. package/src/renderers/feedback/spinner.tsx +0 -55
  137. package/src/renderers/feedback/toast.tsx +0 -59
  138. package/src/renderers/feedback/toaster.tsx +0 -23
  139. package/src/renderers/form/button.tsx +0 -103
  140. package/src/renderers/form/calendar.tsx +0 -34
  141. package/src/renderers/form/checkbox.tsx +0 -71
  142. package/src/renderers/form/combobox.tsx +0 -48
  143. package/src/renderers/form/command.tsx +0 -58
  144. package/src/renderers/form/date-picker.tsx +0 -84
  145. package/src/renderers/form/file-upload.tsx +0 -184
  146. package/src/renderers/form/form.tsx +0 -540
  147. package/src/renderers/form/index.ts +0 -26
  148. package/src/renderers/form/input-otp.tsx +0 -51
  149. package/src/renderers/form/input.tsx +0 -121
  150. package/src/renderers/form/label.tsx +0 -45
  151. package/src/renderers/form/radio-group.tsx +0 -63
  152. package/src/renderers/form/select.tsx +0 -94
  153. package/src/renderers/form/slider.tsx +0 -61
  154. package/src/renderers/form/switch.tsx +0 -48
  155. package/src/renderers/form/textarea.tsx +0 -76
  156. package/src/renderers/form/toggle.tsx +0 -42
  157. package/src/renderers/index.ts +0 -18
  158. package/src/renderers/layout/aspect-ratio.tsx +0 -51
  159. package/src/renderers/layout/card.tsx +0 -85
  160. package/src/renderers/layout/container.tsx +0 -122
  161. package/src/renderers/layout/flex.tsx +0 -132
  162. package/src/renderers/layout/grid.tsx +0 -178
  163. package/src/renderers/layout/index.ts +0 -19
  164. package/src/renderers/layout/page.tsx +0 -466
  165. package/src/renderers/layout/semantic.tsx +0 -48
  166. package/src/renderers/layout/stack.tsx +0 -132
  167. package/src/renderers/layout/tabs.tsx +0 -97
  168. package/src/renderers/navigation/header-bar.tsx +0 -118
  169. package/src/renderers/navigation/index.ts +0 -10
  170. package/src/renderers/navigation/sidebar.tsx +0 -208
  171. package/src/renderers/overlay/alert-dialog.tsx +0 -72
  172. package/src/renderers/overlay/context-menu.tsx +0 -100
  173. package/src/renderers/overlay/dialog.tsx +0 -77
  174. package/src/renderers/overlay/drawer.tsx +0 -77
  175. package/src/renderers/overlay/dropdown-menu.tsx +0 -99
  176. package/src/renderers/overlay/hover-card.tsx +0 -55
  177. package/src/renderers/overlay/index.ts +0 -18
  178. package/src/renderers/overlay/menubar.tsx +0 -76
  179. package/src/renderers/overlay/popover.tsx +0 -56
  180. package/src/renderers/overlay/sheet.tsx +0 -77
  181. package/src/renderers/overlay/tooltip.tsx +0 -67
  182. package/src/renderers/placeholders.tsx +0 -107
  183. package/src/stories/CRMApp.stories.tsx +0 -706
  184. package/src/stories/ConfigPanel.stories.tsx +0 -232
  185. package/src/stories/Guide.mdx +0 -55
  186. package/src/stories/MockedData.stories.tsx +0 -121
  187. package/src/stories/assets/accessibility.png +0 -0
  188. package/src/stories/assets/accessibility.svg +0 -1
  189. package/src/stories/assets/addon-library.png +0 -0
  190. package/src/stories/assets/assets.png +0 -0
  191. package/src/stories/assets/avif-test-image.avif +0 -0
  192. package/src/stories/assets/context.png +0 -0
  193. package/src/stories/assets/discord.svg +0 -1
  194. package/src/stories/assets/docs.png +0 -0
  195. package/src/stories/assets/figma-plugin.png +0 -0
  196. package/src/stories/assets/github.svg +0 -1
  197. package/src/stories/assets/share.png +0 -0
  198. package/src/stories/assets/styling.png +0 -0
  199. package/src/stories/assets/testing.png +0 -0
  200. package/src/stories/assets/theming.png +0 -0
  201. package/src/stories/assets/tutorials.svg +0 -1
  202. package/src/stories/assets/youtube.svg +0 -1
  203. package/src/stories/button.css +0 -30
  204. package/src/stories/header.css +0 -32
  205. package/src/stories/page.css +0 -68
  206. package/src/stories-json/Accessibility.mdx +0 -297
  207. package/src/stories-json/EdgeCases.stories.tsx +0 -160
  208. package/src/stories-json/GettingStarted.mdx +0 -89
  209. package/src/stories-json/Introduction.mdx +0 -127
  210. package/src/stories-json/accordion.stories.tsx +0 -43
  211. package/src/stories-json/aggrid.stories.tsx +0 -103
  212. package/src/stories-json/alert.stories.tsx +0 -39
  213. package/src/stories-json/aspect-ratio.stories.tsx +0 -34
  214. package/src/stories-json/avatar.stories.tsx +0 -38
  215. package/src/stories-json/badge.stories.tsx +0 -53
  216. package/src/stories-json/breadcrumb.stories.tsx +0 -30
  217. package/src/stories-json/button-group.stories.tsx +0 -43
  218. package/src/stories-json/button.stories.tsx +0 -73
  219. package/src/stories-json/calendar.stories.tsx +0 -85
  220. package/src/stories-json/card.stories.tsx +0 -48
  221. package/src/stories-json/carousel.stories.tsx +0 -33
  222. package/src/stories-json/charts.stories.tsx +0 -195
  223. package/src/stories-json/chatbot.stories.tsx +0 -349
  224. package/src/stories-json/code-editor.stories.tsx +0 -92
  225. package/src/stories-json/collapsible.stories.tsx +0 -40
  226. package/src/stories-json/controls.stories.tsx +0 -36
  227. package/src/stories-json/crm-live-data.stories.tsx +0 -154
  228. package/src/stories-json/dashboard.stories.tsx +0 -318
  229. package/src/stories-json/data-table.stories.tsx +0 -136
  230. package/src/stories-json/data_display_extras.stories.tsx +0 -102
  231. package/src/stories-json/date-picker.stories.tsx +0 -28
  232. package/src/stories-json/detail-view.stories.tsx +0 -258
  233. package/src/stories-json/dialog.stories.tsx +0 -43
  234. package/src/stories-json/feedback_extras.stories.tsx +0 -40
  235. package/src/stories-json/feedback_others.stories.tsx +0 -46
  236. package/src/stories-json/form-variants.stories.tsx +0 -210
  237. package/src/stories-json/form_advanced.stories.tsx +0 -117
  238. package/src/stories-json/form_extras.stories.tsx +0 -123
  239. package/src/stories-json/grid.stories.tsx +0 -56
  240. package/src/stories-json/icon.stories.tsx +0 -36
  241. package/src/stories-json/input.stories.tsx +0 -52
  242. package/src/stories-json/kanban.stories.tsx +0 -295
  243. package/src/stories-json/layout_extended.stories.tsx +0 -76
  244. package/src/stories-json/layout_flex.stories.tsx +0 -107
  245. package/src/stories-json/list-view.stories.tsx +0 -97
  246. package/src/stories-json/markdown.stories.tsx +0 -129
  247. package/src/stories-json/menus.stories.tsx +0 -63
  248. package/src/stories-json/metric-card.stories.tsx +0 -143
  249. package/src/stories-json/navigation-menu.stories.tsx +0 -37
  250. package/src/stories-json/object-aggrid-advanced.stories.tsx +0 -389
  251. package/src/stories-json/object-aggrid.stories.tsx +0 -252
  252. package/src/stories-json/object-form.stories.tsx +0 -130
  253. package/src/stories-json/object-gantt.stories.tsx +0 -114
  254. package/src/stories-json/object-grid.stories.tsx +0 -315
  255. package/src/stories-json/object-map.stories.tsx +0 -116
  256. package/src/stories-json/object-view.stories.tsx +0 -118
  257. package/src/stories-json/overlay_extras.stories.tsx +0 -113
  258. package/src/stories-json/overlay_others.stories.tsx +0 -76
  259. package/src/stories-json/page.stories.tsx +0 -55
  260. package/src/stories-json/reports.stories.tsx +0 -163
  261. package/src/stories-json/resizable.stories.tsx +0 -44
  262. package/src/stories-json/select.stories.tsx +0 -34
  263. package/src/stories-json/separator.stories.tsx +0 -41
  264. package/src/stories-json/sidebar.stories.tsx +0 -147
  265. package/src/stories-json/statistic.stories.tsx +0 -44
  266. package/src/stories-json/tabs.stories.tsx +0 -51
  267. package/src/stories-json/timeline.stories.tsx +0 -188
  268. package/src/stories-json/typography.stories.tsx +0 -45
  269. package/src/types/config-panel.ts +0 -101
  270. package/src/ui/accordion.tsx +0 -66
  271. package/src/ui/alert-dialog.tsx +0 -149
  272. package/src/ui/alert.tsx +0 -67
  273. package/src/ui/aspect-ratio.tsx +0 -15
  274. package/src/ui/avatar.tsx +0 -58
  275. package/src/ui/badge.tsx +0 -44
  276. package/src/ui/breadcrumb.tsx +0 -123
  277. package/src/ui/button.tsx +0 -64
  278. package/src/ui/calendar.tsx +0 -221
  279. package/src/ui/card.tsx +0 -87
  280. package/src/ui/carousel.tsx +0 -270
  281. package/src/ui/chart.tsx +0 -377
  282. package/src/ui/checkbox.tsx +0 -38
  283. package/src/ui/collapsible.tsx +0 -19
  284. package/src/ui/command.tsx +0 -161
  285. package/src/ui/context-menu.tsx +0 -208
  286. package/src/ui/dialog.tsx +0 -130
  287. package/src/ui/drawer.tsx +0 -126
  288. package/src/ui/dropdown-menu.tsx +0 -208
  289. package/src/ui/form.tsx +0 -186
  290. package/src/ui/hover-card.tsx +0 -37
  291. package/src/ui/index.ts +0 -56
  292. package/src/ui/input-otp.tsx +0 -79
  293. package/src/ui/input.tsx +0 -30
  294. package/src/ui/label.tsx +0 -34
  295. package/src/ui/menubar.tsx +0 -264
  296. package/src/ui/navigation-menu.tsx +0 -136
  297. package/src/ui/pagination.tsx +0 -125
  298. package/src/ui/popover.tsx +0 -39
  299. package/src/ui/progress.tsx +0 -36
  300. package/src/ui/radio-group.tsx +0 -52
  301. package/src/ui/resizable.tsx +0 -53
  302. package/src/ui/scroll-area.tsx +0 -56
  303. package/src/ui/select.tsx +0 -168
  304. package/src/ui/separator.tsx +0 -39
  305. package/src/ui/sheet.tsx +0 -150
  306. package/src/ui/sidebar.tsx +0 -781
  307. package/src/ui/skeleton.tsx +0 -23
  308. package/src/ui/slider.tsx +0 -39
  309. package/src/ui/sonner.tsx +0 -53
  310. package/src/ui/switch.tsx +0 -37
  311. package/src/ui/table.tsx +0 -125
  312. package/src/ui/tabs.tsx +0 -63
  313. package/src/ui/textarea.tsx +0 -30
  314. package/src/ui/toast.tsx +0 -137
  315. package/src/ui/toggle-group.tsx +0 -69
  316. package/src/ui/toggle.tsx +0 -53
  317. package/src/ui/tooltip.tsx +0 -38
  318. package/src/ui/typography.tsx +0 -85
  319. package/tsconfig.json +0 -19
  320. package/vite.config.ts +0 -71
  321. package/vitest.config.ts +0 -5
@@ -1,201 +0,0 @@
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 * as React from "react"
10
- import { Slot as SlotPrimitive } from "@radix-ui/react-slot"
11
- import { cva, type VariantProps } from "class-variance-authority"
12
-
13
- import { cn } from "../lib/utils"
14
- import { Separator } from "../ui/separator"
15
-
16
- function ItemGroup({ className, ...props }: React.ComponentProps<"div">) {
17
- return (
18
- <div
19
- role="list"
20
- data-slot="item-group"
21
- className={cn("group/item-group flex flex-col", className)}
22
- {...props}
23
- />
24
- )
25
- }
26
-
27
- function ItemSeparator({
28
- className,
29
- ...props
30
- }: React.ComponentProps<typeof Separator>) {
31
- return (
32
- <Separator
33
- data-slot="item-separator"
34
- orientation="horizontal"
35
- className={cn("my-0", className)}
36
- {...props}
37
- />
38
- )
39
- }
40
-
41
- const itemVariants = cva(
42
- "group/item flex items-center border border-transparent text-sm rounded-md transition-colors [a]:hover:bg-accent/50 [a]:transition-colors duration-100 flex-wrap outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
43
- {
44
- variants: {
45
- variant: {
46
- default: "bg-transparent",
47
- outline: "border-border",
48
- muted: "bg-muted/50",
49
- },
50
- size: {
51
- default: "p-4 gap-4 ",
52
- sm: "py-3 px-4 gap-2.5",
53
- },
54
- },
55
- defaultVariants: {
56
- variant: "default",
57
- size: "default",
58
- },
59
- }
60
- )
61
-
62
- function Item({
63
- className,
64
- variant = "default",
65
- size = "default",
66
- asChild = false,
67
- ...props
68
- }: React.ComponentProps<"div"> &
69
- VariantProps<typeof itemVariants> & { asChild?: boolean }) {
70
- const Comp = asChild ? SlotPrimitive : "div"
71
- return (
72
- <Comp
73
- data-slot="item"
74
- data-variant={variant}
75
- data-size={size}
76
- className={cn(itemVariants({ variant, size, className }))}
77
- {...props}
78
- />
79
- )
80
- }
81
-
82
- const itemMediaVariants = cva(
83
- "flex shrink-0 items-center justify-center gap-2 group-has-[[data-slot=item-description]]/item:self-start [&_svg]:pointer-events-none group-has-[[data-slot=item-description]]/item:translate-y-0.5",
84
- {
85
- variants: {
86
- variant: {
87
- default: "bg-transparent",
88
- icon: "size-8 border rounded-sm bg-muted [&_svg:not([class*='size-'])]:size-4",
89
- image:
90
- "size-10 rounded-sm overflow-hidden [&_img]:size-full [&_img]:object-cover",
91
- },
92
- },
93
- defaultVariants: {
94
- variant: "default",
95
- },
96
- }
97
- )
98
-
99
- function ItemMedia({
100
- className,
101
- variant = "default",
102
- ...props
103
- }: React.ComponentProps<"div"> & VariantProps<typeof itemMediaVariants>) {
104
- return (
105
- <div
106
- data-slot="item-media"
107
- data-variant={variant}
108
- className={cn(itemMediaVariants({ variant, className }))}
109
- {...props}
110
- />
111
- )
112
- }
113
-
114
- function ItemContent({ className, ...props }: React.ComponentProps<"div">) {
115
- return (
116
- <div
117
- data-slot="item-content"
118
- className={cn(
119
- "flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none",
120
- className
121
- )}
122
- {...props}
123
- />
124
- )
125
- }
126
-
127
- function ItemTitle({ className, ...props }: React.ComponentProps<"div">) {
128
- return (
129
- <div
130
- data-slot="item-title"
131
- className={cn(
132
- "flex w-fit items-center gap-2 text-sm leading-snug font-medium",
133
- className
134
- )}
135
- {...props}
136
- />
137
- )
138
- }
139
-
140
- function ItemDescription({ className, ...props }: React.ComponentProps<"p">) {
141
- return (
142
- <p
143
- data-slot="item-description"
144
- className={cn(
145
- "text-muted-foreground line-clamp-2 text-sm leading-normal font-normal text-balance",
146
- "[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
147
- className
148
- )}
149
- {...props}
150
- />
151
- )
152
- }
153
-
154
- function ItemActions({ className, ...props }: React.ComponentProps<"div">) {
155
- return (
156
- <div
157
- data-slot="item-actions"
158
- className={cn("flex items-center gap-2", className)}
159
- {...props}
160
- />
161
- )
162
- }
163
-
164
- function ItemHeader({ className, ...props }: React.ComponentProps<"div">) {
165
- return (
166
- <div
167
- data-slot="item-header"
168
- className={cn(
169
- "flex basis-full items-center justify-between gap-2",
170
- className
171
- )}
172
- {...props}
173
- />
174
- )
175
- }
176
-
177
- function ItemFooter({ className, ...props }: React.ComponentProps<"div">) {
178
- return (
179
- <div
180
- data-slot="item-footer"
181
- className={cn(
182
- "flex basis-full items-center justify-between gap-2",
183
- className
184
- )}
185
- {...props}
186
- />
187
- )
188
- }
189
-
190
- export {
191
- Item,
192
- ItemMedia,
193
- ItemContent,
194
- ItemActions,
195
- ItemGroup,
196
- ItemSeparator,
197
- ItemTitle,
198
- ItemDescription,
199
- ItemHeader,
200
- ItemFooter,
201
- }
@@ -1,36 +0,0 @@
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 { cn } from "../lib/utils"
10
-
11
- function Kbd({ className, ...props }: React.ComponentProps<"kbd">) {
12
- return (
13
- <kbd
14
- data-slot="kbd"
15
- className={cn(
16
- "bg-muted text-muted-foreground pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-sm px-1 font-sans text-xs font-medium select-none",
17
- "[&_svg:not([class*='size-'])]:size-3",
18
- "[[data-slot=tooltip-content]_&]:bg-background/20 [[data-slot=tooltip-content]_&]:text-background dark:[[data-slot=tooltip-content]_&]:bg-background/10",
19
- className
20
- )}
21
- {...props}
22
- />
23
- )
24
- }
25
-
26
- function KbdGroup({ className, ...props }: React.ComponentProps<"div">) {
27
- return (
28
- <kbd
29
- data-slot="kbd-group"
30
- className={cn("inline-flex items-center gap-1", className)}
31
- {...props}
32
- />
33
- )
34
- }
35
-
36
- export { Kbd, KbdGroup }
@@ -1,67 +0,0 @@
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
- /**
10
- * MobileDialogContent
11
- *
12
- * A mobile-optimized wrapper around the upstream Shadcn DialogContent.
13
- * On mobile (< sm breakpoint), the dialog is full-screen with a larger
14
- * close-button touch target (≥ 44×44px per WCAG 2.5.5).
15
- * On tablet+ (≥ sm), it falls back to the standard centered dialog.
16
- *
17
- * This lives in `custom/` to avoid modifying the Shadcn-synced `ui/dialog.tsx`.
18
- */
19
-
20
- import * as React from 'react';
21
- import * as DialogPrimitive from "@radix-ui/react-dialog";
22
- import { X } from 'lucide-react';
23
- import { cn } from '../lib/utils';
24
- import { DialogOverlay, DialogPortal } from '../ui/dialog';
25
-
26
- export const MobileDialogContent = React.forwardRef<
27
- React.ElementRef<typeof DialogPrimitive.Content>,
28
- React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
29
- >(({ className, children, ...props }, ref) => (
30
- <DialogPortal>
31
- <DialogOverlay />
32
- <DialogPrimitive.Content
33
- ref={ref}
34
- className={cn(
35
- // Mobile-first: full-screen
36
- 'fixed inset-0 z-50 w-full bg-background p-4 shadow-lg duration-200',
37
- 'h-[100dvh]',
38
- // Desktop (sm+): centered dialog with border + rounded corners
39
- 'sm:inset-auto sm:left-[50%] sm:top-[50%] sm:translate-x-[-50%] sm:translate-y-[-50%]',
40
- 'sm:max-w-lg sm:h-auto sm:max-h-[90vh] sm:rounded-lg sm:border sm:p-6',
41
- // Animations
42
- 'data-[state=open]:animate-in data-[state=closed]:animate-out',
43
- 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
44
- 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
45
- 'data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%]',
46
- 'data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]',
47
- className,
48
- )}
49
- {...props}
50
- >
51
- {children}
52
- <DialogPrimitive.Close
53
- className={cn(
54
- 'absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity',
55
- 'hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
56
- 'disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground',
57
- // Mobile touch target ≥ 44×44px (WCAG 2.5.5)
58
- 'min-h-[44px] min-w-[44px] sm:min-h-0 sm:min-w-0 flex items-center justify-center',
59
- )}
60
- >
61
- <X className="h-5 w-5 sm:h-4 sm:w-4" />
62
- <span className="sr-only">Close</span>
63
- </DialogPrimitive.Close>
64
- </DialogPrimitive.Content>
65
- </DialogPortal>
66
- ));
67
- MobileDialogContent.displayName = 'MobileDialogContent';
@@ -1,33 +0,0 @@
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 * as React from "react"
10
- import { cn } from "../lib/utils"
11
-
12
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type
13
- export interface NativeSelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {}
14
-
15
- const NativeSelect = React.forwardRef<HTMLSelectElement, NativeSelectProps>(
16
- ({ className, children, ...props }, ref) => {
17
- return (
18
- <select
19
- className={cn(
20
- "flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
21
- className
22
- )}
23
- ref={ref}
24
- {...props}
25
- >
26
- {children}
27
- </select>
28
- )
29
- }
30
- )
31
- NativeSelect.displayName = "NativeSelect"
32
-
33
- export { NativeSelect }
@@ -1,334 +0,0 @@
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
- /**
10
- * NavigationOverlay
11
- *
12
- * A reusable component that renders record detail overlays based on
13
- * ViewNavigationConfig mode. Supports drawer (Sheet), modal (Dialog),
14
- * split (ResizablePanelGroup), and popover modes.
15
- *
16
- * Works in conjunction with useNavigationOverlay hook from @object-ui/react —
17
- * the hook manages state while this component handles the visual presentation.
18
- *
19
- * @example
20
- * ```tsx
21
- * import { useNavigationOverlay } from '@object-ui/react';
22
- * import { NavigationOverlay } from '@object-ui/components';
23
- *
24
- * const nav = useNavigationOverlay({
25
- * navigation: schema.navigation,
26
- * objectName: schema.objectName,
27
- * });
28
- *
29
- * return (
30
- * <>
31
- * <DataTable onRowClick={nav.handleClick} />
32
- * <NavigationOverlay {...nav} title="Record Detail">
33
- * {(record) => <RecordDetail record={record} />}
34
- * </NavigationOverlay>
35
- * </>
36
- * );
37
- * ```
38
- */
39
-
40
- import React from 'react';
41
- import { cn } from '../lib/utils';
42
- import {
43
- Sheet,
44
- SheetContent,
45
- SheetHeader,
46
- SheetTitle,
47
- SheetDescription,
48
- } from '../ui/sheet';
49
- import {
50
- Dialog,
51
- DialogContent,
52
- DialogHeader,
53
- DialogTitle,
54
- DialogDescription,
55
- } from '../ui/dialog';
56
- import {
57
- Popover,
58
- PopoverContent,
59
- PopoverTrigger,
60
- } from '../ui/popover';
61
- import {
62
- ResizablePanelGroup,
63
- ResizablePanel,
64
- ResizableHandle,
65
- } from '../ui/resizable';
66
-
67
- /** Navigation mode type — matches ViewNavigationConfig.mode */
68
- export type NavigationOverlayMode =
69
- | 'page'
70
- | 'drawer'
71
- | 'modal'
72
- | 'split'
73
- | 'popover'
74
- | 'new_window'
75
- | 'none';
76
-
77
- export interface NavigationOverlayProps {
78
- /** Whether the overlay is open */
79
- isOpen: boolean;
80
- /** The selected record */
81
- selectedRecord: Record<string, unknown> | null;
82
- /** The navigation mode */
83
- mode: NavigationOverlayMode;
84
- /** Close the overlay */
85
- close: () => void;
86
- /** Set open state (for controlled Sheet/Dialog onOpenChange) */
87
- setIsOpen: (open: boolean) => void;
88
- /** Width for the overlay (drawer/modal/split) */
89
- width?: string | number;
90
- /** Whether navigation is an overlay mode */
91
- isOverlay: boolean;
92
- /** Target view/form name from NavigationConfig */
93
- view?: string;
94
- /** Title for the overlay header */
95
- title?: string;
96
- /** Description for the overlay header */
97
- description?: string;
98
- /** CSS class for the overlay container */
99
- className?: string;
100
- /**
101
- * Render function for the overlay content.
102
- * Receives the selected record.
103
- */
104
- children: (record: Record<string, unknown>) => React.ReactNode;
105
- /**
106
- * Optional render function for a specific view/form based on `view` prop.
107
- * When provided, this takes priority over `children` for rendering overlay content.
108
- * Receives the selected record and the view name.
109
- */
110
- renderView?: (record: Record<string, unknown>, viewName: string) => React.ReactNode;
111
- /**
112
- * The main content to wrap (for split mode only).
113
- * In split mode, the main content is rendered in the left panel.
114
- */
115
- mainContent?: React.ReactNode;
116
- /**
117
- * Popover trigger element (for popover mode).
118
- */
119
- popoverTrigger?: React.ReactNode;
120
- }
121
-
122
- /**
123
- * Resolve width to CSS-compatible value
124
- */
125
- function resolveWidth(width: string | number | undefined): string | undefined {
126
- if (width == null) return undefined;
127
- if (typeof width === 'number') return `${width}px`;
128
- return width;
129
- }
130
-
131
- /**
132
- * Compute CSS style from NavigationConfig width
133
- */
134
- function getWidthStyle(width: string | number | undefined): React.CSSProperties {
135
- const resolved = resolveWidth(width);
136
- if (!resolved) return {};
137
- return { maxWidth: resolved, width: '100%' };
138
- }
139
-
140
- /**
141
- * NavigationOverlay — renders record detail in the configured overlay mode.
142
- *
143
- * Supports:
144
- * - **drawer**: Right-side Sheet panel
145
- * - **modal**: Center Dialog overlay
146
- * - **split**: Side-by-side ResizablePanelGroup
147
- * - **popover**: Hoverable/clickable popover card
148
- * - **page / new_window / none**: No overlay rendered (handled by hook)
149
- */
150
- export const NavigationOverlay: React.FC<NavigationOverlayProps> = ({
151
- isOpen,
152
- selectedRecord,
153
- mode,
154
- close,
155
- setIsOpen,
156
- width,
157
- view,
158
- title,
159
- description,
160
- className,
161
- children,
162
- renderView,
163
- mainContent,
164
- popoverTrigger,
165
- }) => {
166
- // Non-overlay modes don't render anything
167
- if (mode === 'page' || mode === 'new_window' || mode === 'none') {
168
- return null;
169
- }
170
-
171
- if (!selectedRecord) {
172
- return null;
173
- }
174
-
175
- const widthStyle = getWidthStyle(width);
176
- const resolvedTitle = title || 'Record Detail';
177
-
178
- // Use renderView when both renderView and view are provided; otherwise fallback to children
179
- const renderContent = (record: Record<string, unknown>) => {
180
- if (renderView && view) {
181
- return renderView(record, view);
182
- }
183
- return children(record);
184
- };
185
-
186
- // --- Drawer Mode (Sheet) ---
187
- if (mode === 'drawer') {
188
- return (
189
- <Sheet open={isOpen} onOpenChange={setIsOpen}>
190
- <SheetContent
191
- side="right"
192
- className={cn('w-full sm:max-w-2xl overflow-y-auto', className)}
193
- style={widthStyle}
194
- >
195
- <SheetHeader>
196
- <SheetTitle>{resolvedTitle}</SheetTitle>
197
- {description && <SheetDescription>{description}</SheetDescription>}
198
- </SheetHeader>
199
- <div className="mt-4">
200
- {renderContent(selectedRecord)}
201
- </div>
202
- </SheetContent>
203
- </Sheet>
204
- );
205
- }
206
-
207
- // --- Modal Mode (Dialog) ---
208
- if (mode === 'modal') {
209
- return (
210
- <Dialog open={isOpen} onOpenChange={setIsOpen}>
211
- <DialogContent
212
- className={cn('max-w-2xl max-h-[90vh] overflow-y-auto', className)}
213
- style={widthStyle}
214
- >
215
- <DialogHeader>
216
- <DialogTitle>{resolvedTitle}</DialogTitle>
217
- {description && <DialogDescription>{description}</DialogDescription>}
218
- </DialogHeader>
219
- <div className="mt-4">
220
- {renderContent(selectedRecord)}
221
- </div>
222
- </DialogContent>
223
- </Dialog>
224
- );
225
- }
226
-
227
- // --- Split Mode (Resizable Panels) ---
228
- if (mode === 'split') {
229
- if (!isOpen || !mainContent) {
230
- return null;
231
- }
232
-
233
- // Calculate panel sizes based on width config
234
- const detailPercent = width
235
- ? typeof width === 'number'
236
- ? Math.min(70, Math.max(20, (width / 1200) * 100))
237
- : 40
238
- : 40;
239
- const mainPercent = 100 - detailPercent;
240
-
241
- // Cast needed: ResizablePanelGroup has correct runtime behavior but
242
- // vite-plugin-dts may not resolve the direction prop type correctly
243
- const PanelGroup = ResizablePanelGroup as React.FC<any>;
244
-
245
- return (
246
- <PanelGroup direction="horizontal" className={cn('h-full', className)}>
247
- <ResizablePanel defaultSize={mainPercent} minSize={30}>
248
- {mainContent}
249
- </ResizablePanel>
250
- <ResizableHandle withHandle />
251
- <ResizablePanel defaultSize={detailPercent} minSize={20}>
252
- <div className="h-full overflow-y-auto p-4">
253
- <div className="flex items-center justify-between mb-4">
254
- <h3 className="text-lg font-semibold">{resolvedTitle}</h3>
255
- <button
256
- onClick={close}
257
- className="rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"
258
- aria-label="Close panel"
259
- >
260
- <svg
261
- xmlns="http://www.w3.org/2000/svg"
262
- width="16"
263
- height="16"
264
- viewBox="0 0 24 24"
265
- fill="none"
266
- stroke="currentColor"
267
- strokeWidth="2"
268
- strokeLinecap="round"
269
- strokeLinejoin="round"
270
- >
271
- <line x1="18" y1="6" x2="6" y2="18" />
272
- <line x1="6" y1="6" x2="18" y2="18" />
273
- </svg>
274
- </button>
275
- </div>
276
- {description && (
277
- <p className="text-sm text-muted-foreground mb-4">{description}</p>
278
- )}
279
- {renderContent(selectedRecord)}
280
- </div>
281
- </ResizablePanel>
282
- </PanelGroup>
283
- );
284
- }
285
-
286
- // --- Popover Mode ---
287
- if (mode === 'popover') {
288
- if (!popoverTrigger) {
289
- // Fallback: render as a compact floating card when no trigger element is provided
290
- if (!isOpen) return null;
291
- return (
292
- <Dialog open={isOpen} onOpenChange={setIsOpen}>
293
- <DialogContent
294
- className={cn('w-96 max-h-[80vh] overflow-y-auto p-4', className)}
295
- style={widthStyle}
296
- >
297
- <DialogHeader>
298
- <DialogTitle className="text-sm">{resolvedTitle}</DialogTitle>
299
- {description && <DialogDescription className="text-xs">{description}</DialogDescription>}
300
- </DialogHeader>
301
- <div className="mt-2">
302
- {renderContent(selectedRecord)}
303
- </div>
304
- </DialogContent>
305
- </Dialog>
306
- );
307
- }
308
- return (
309
- <Popover open={isOpen} onOpenChange={setIsOpen}>
310
- {popoverTrigger && (
311
- <PopoverTrigger asChild>
312
- {popoverTrigger}
313
- </PopoverTrigger>
314
- )}
315
- <PopoverContent
316
- className={cn('w-96 max-h-[400px] overflow-y-auto p-4', className)}
317
- style={widthStyle}
318
- >
319
- <div className="space-y-2">
320
- <h4 className="text-sm font-semibold">{resolvedTitle}</h4>
321
- {description && (
322
- <p className="text-xs text-muted-foreground">{description}</p>
323
- )}
324
- {renderContent(selectedRecord)}
325
- </div>
326
- </PopoverContent>
327
- </Popover>
328
- );
329
- }
330
-
331
- return null;
332
- };
333
-
334
- NavigationOverlay.displayName = 'NavigationOverlay';