@questpie/admin 2.0.0 → 3.0.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 (1087) hide show
  1. package/README.md +173 -143
  2. package/dist/augmentation.d.mts +110 -11
  3. package/dist/client/blocks/block-renderer.d.mts +5 -12
  4. package/dist/client/blocks/block-renderer.mjs +89 -55
  5. package/dist/client/blocks/index.d.mts +2 -4
  6. package/dist/client/blocks/types.d.mts +3 -4
  7. package/dist/client/blocks/types.mjs +1 -2
  8. package/dist/client/builder/admin-types.d.mts +11 -44
  9. package/dist/client/builder/admin.d.mts +34 -45
  10. package/dist/client/builder/admin.mjs +35 -44
  11. package/dist/client/builder/field/field.d.mts +27 -205
  12. package/dist/client/builder/field/field.mjs +22 -68
  13. package/dist/client/builder/index.d.mts +23 -28
  14. package/dist/client/builder/page/page.d.mts +15 -27
  15. package/dist/client/builder/page/page.mjs +21 -17
  16. package/dist/client/builder/registry.d.mts +14 -34
  17. package/dist/client/builder/types/action-registry.mjs +148 -14
  18. package/dist/client/builder/types/action-types.d.mts +8 -35
  19. package/dist/client/builder/types/collection-types.mjs +1 -2
  20. package/dist/client/builder/types/common.d.mts +6 -20
  21. package/dist/client/builder/types/field-types.d.mts +4 -5
  22. package/dist/client/builder/types/field-types.mjs +1 -2
  23. package/dist/client/builder/types/ui-config.d.mts +3 -5
  24. package/dist/client/builder/types/widget-types.d.mts +19 -20
  25. package/dist/client/builder/validation.d.mts +33 -3
  26. package/dist/client/builder/validation.mjs +169 -150
  27. package/dist/client/builder/view/view.d.mts +26 -106
  28. package/dist/client/builder/view/view.mjs +14 -96
  29. package/dist/client/builder/widget/widget.d.mts +16 -22
  30. package/dist/client/builder/widget/widget.mjs +11 -16
  31. package/dist/client/components/actions/action-button.mjs +207 -97
  32. package/dist/client/components/actions/action-dialog.mjs +471 -176
  33. package/dist/client/components/actions/confirmation-dialog.mjs +166 -47
  34. package/dist/client/components/actions/header-actions.mjs +164 -71
  35. package/dist/client/components/admin-link.d.mts +8 -9
  36. package/dist/client/components/admin-link.mjs +127 -48
  37. package/dist/client/components/auth/auth-guard.d.mts +6 -7
  38. package/dist/client/components/auth/auth-guard.mjs +9 -9
  39. package/dist/client/components/auth/auth-loading.d.mts +3 -4
  40. package/dist/client/components/auth/auth-loading.mjs +38 -10
  41. package/dist/client/components/blocks/block-canvas.mjs +111 -42
  42. package/dist/client/components/blocks/block-editor-context.mjs +90 -23
  43. package/dist/client/components/blocks/block-editor-layout.mjs +176 -59
  44. package/dist/client/components/blocks/block-editor-provider.mjs +219 -139
  45. package/dist/client/components/blocks/block-fields-renderer.mjs +212 -42
  46. package/dist/client/components/blocks/block-insert-button.mjs +168 -51
  47. package/dist/client/components/blocks/block-item-menu.mjs +312 -110
  48. package/dist/client/components/blocks/block-item.mjs +372 -125
  49. package/dist/client/components/blocks/block-library-sidebar.mjs +209 -114
  50. package/dist/client/components/blocks/block-tree.mjs +73 -15
  51. package/dist/client/components/blocks/block-type-icon.mjs +65 -20
  52. package/dist/client/components/blocks/utils/tree-utils.mjs +1 -2
  53. package/dist/client/components/component-renderer.d.mts +11 -22
  54. package/dist/client/components/component-renderer.mjs +151 -38
  55. package/dist/client/components/error-boundary.mjs +77 -25
  56. package/dist/client/components/fields/array-field.mjs +474 -199
  57. package/dist/client/components/fields/asset-preview-field.mjs +143 -44
  58. package/dist/client/components/fields/blocks-field/blocks-field.mjs +143 -35
  59. package/dist/client/components/fields/boolean-field.mjs +62 -32
  60. package/dist/client/components/fields/date-field.mjs +46 -12
  61. package/dist/client/components/fields/datetime-field.mjs +42 -11
  62. package/dist/client/components/fields/email-field.mjs +57 -28
  63. package/dist/client/components/fields/field-utils.mjs +1 -2
  64. package/dist/client/components/fields/field-wrapper.mjs +107 -32
  65. package/dist/client/components/fields/json-field.mjs +323 -110
  66. package/dist/client/components/fields/locale-badge.mjs +16 -8
  67. package/dist/client/components/fields/number-field.mjs +63 -30
  68. package/dist/client/components/fields/object-array-field.mjs +666 -272
  69. package/dist/client/components/fields/object-field.mjs +656 -98
  70. package/dist/client/components/fields/relation/displays/cards-display.mjs +225 -111
  71. package/dist/client/components/fields/relation/displays/chips-display.mjs +150 -77
  72. package/dist/client/components/fields/relation/displays/grid-display.mjs +186 -91
  73. package/dist/client/components/fields/relation/displays/list-display.mjs +230 -111
  74. package/dist/client/components/fields/relation/displays/table-display.mjs +241 -66
  75. package/dist/client/components/fields/relation/displays/types.mjs +2 -3
  76. package/dist/client/components/fields/relation/relation-items-display.mjs +131 -35
  77. package/dist/client/components/fields/relation-field.mjs +70 -15
  78. package/dist/client/components/fields/relation-picker.mjs +93 -98
  79. package/dist/client/components/fields/relation-select.mjs +42 -29
  80. package/dist/client/components/fields/rich-text-editor/bubble-menu.mjs +90 -41
  81. package/dist/client/components/fields/rich-text-editor/extensions.mjs +33 -7
  82. package/dist/client/components/fields/rich-text-editor/image-popover.mjs +48 -23
  83. package/dist/client/components/fields/rich-text-editor/index.mjs +491 -158
  84. package/dist/client/components/fields/rich-text-editor/link-popover.mjs +13 -14
  85. package/dist/client/components/fields/rich-text-editor/presets.mjs +1 -2
  86. package/dist/client/components/fields/rich-text-editor/slash-commands.mjs +96 -53
  87. package/dist/client/components/fields/rich-text-editor/table-controls.mjs +416 -107
  88. package/dist/client/components/fields/rich-text-editor/toolbar.mjs +476 -215
  89. package/dist/client/components/fields/rich-text-editor/types.mjs +1 -2
  90. package/dist/client/components/fields/rich-text-editor/utils.mjs +1 -2
  91. package/dist/client/components/fields/rich-text-field.mjs +55 -17
  92. package/dist/client/components/fields/select-field.mjs +79 -44
  93. package/dist/client/components/fields/text-field.mjs +62 -29
  94. package/dist/client/components/fields/textarea-field.mjs +61 -29
  95. package/dist/client/components/fields/time-field.mjs +39 -11
  96. package/dist/client/components/fields/upload-field.mjs +253 -129
  97. package/dist/client/components/filter-builder/columns-tab.mjs +287 -93
  98. package/dist/client/components/filter-builder/filter-builder-sheet.mjs +437 -138
  99. package/dist/client/components/filter-builder/filters-tab.mjs +409 -126
  100. package/dist/client/components/filter-builder/saved-views-tab.mjs +259 -106
  101. package/dist/client/components/history-sidebar.mjs +496 -0
  102. package/dist/client/components/layout/field-layout-renderer.mjs +301 -0
  103. package/dist/client/components/locale-switcher.mjs +231 -108
  104. package/dist/client/components/media/media-grid.mjs +259 -84
  105. package/dist/client/components/media/media-picker-dialog.mjs +500 -192
  106. package/dist/client/components/preview/live-preview-mode.mjs +416 -124
  107. package/dist/client/components/preview/preview-pane.mjs +353 -144
  108. package/dist/client/components/primitives/asset-preview.mjs +665 -257
  109. package/dist/client/components/primitives/checkbox-input.mjs +37 -11
  110. package/dist/client/components/primitives/date-input.mjs +392 -149
  111. package/dist/client/components/primitives/dropzone.mjs +314 -185
  112. package/dist/client/components/primitives/number-input.mjs +14 -10
  113. package/dist/client/components/primitives/select-multi.mjs +519 -185
  114. package/dist/client/components/primitives/select-single.mjs +416 -126
  115. package/dist/client/components/primitives/text-input.mjs +10 -5
  116. package/dist/client/components/primitives/textarea-input.mjs +10 -5
  117. package/dist/client/components/primitives/time-input.mjs +118 -45
  118. package/dist/client/components/primitives/toggle-input.mjs +31 -11
  119. package/dist/client/components/primitives/types.mjs +1 -2
  120. package/dist/client/components/sheets/resource-sheet.mjs +72 -64
  121. package/dist/client/components/ui/accordion.mjs +156 -37
  122. package/dist/client/components/ui/alert.mjs +70 -17
  123. package/dist/client/components/ui/badge.mjs +57 -16
  124. package/dist/client/components/ui/button.mjs +49 -14
  125. package/dist/client/components/ui/card.mjs +194 -39
  126. package/dist/client/components/ui/checkbox.mjs +71 -16
  127. package/dist/client/components/ui/command.mjs +220 -50
  128. package/dist/client/components/ui/dialog.mjs +265 -52
  129. package/dist/client/components/ui/drawer.mjs +260 -57
  130. package/dist/client/components/ui/dropdown-menu.mjs +293 -67
  131. package/dist/client/components/ui/empty-state.mjs +72 -26
  132. package/dist/client/components/ui/field.mjs +332 -56
  133. package/dist/client/components/ui/input-group.mjs +174 -41
  134. package/dist/client/components/ui/input.mjs +38 -9
  135. package/dist/client/components/ui/kbd.mjs +37 -8
  136. package/dist/client/components/ui/label.mjs +38 -8
  137. package/dist/client/components/ui/popover.mjs +162 -35
  138. package/dist/client/components/ui/responsive-dialog.mjs +277 -71
  139. package/dist/client/components/ui/search-input.mjs +101 -36
  140. package/dist/client/components/ui/select.mjs +297 -57
  141. package/dist/client/components/ui/separator.mjs +39 -9
  142. package/dist/client/components/ui/sheet.mjs +253 -51
  143. package/dist/client/components/ui/sidebar.mjs +700 -182
  144. package/dist/client/components/ui/skeleton.mjs +33 -8
  145. package/dist/client/components/ui/sonner.d.mts +2 -3
  146. package/dist/client/components/ui/sonner.mjs +45 -15
  147. package/dist/client/components/ui/spinner.mjs +44 -10
  148. package/dist/client/components/ui/switch.mjs +47 -12
  149. package/dist/client/components/ui/table.mjs +260 -50
  150. package/dist/client/components/ui/tabs.mjs +140 -29
  151. package/dist/client/components/ui/textarea.mjs +33 -8
  152. package/dist/client/components/ui/toolbar.mjs +105 -23
  153. package/dist/client/components/ui/tooltip.mjs +130 -29
  154. package/dist/client/components/widgets/chart-widget.mjs +456 -156
  155. package/dist/client/components/widgets/progress-widget.mjs +150 -60
  156. package/dist/client/components/widgets/quick-actions-widget.mjs +175 -87
  157. package/dist/client/components/widgets/recent-items-widget.mjs +157 -62
  158. package/dist/client/components/widgets/stats-widget.mjs +153 -42
  159. package/dist/client/components/widgets/table-widget.mjs +198 -64
  160. package/dist/client/components/widgets/timeline-widget.mjs +193 -82
  161. package/dist/client/components/widgets/value-widget.mjs +257 -56
  162. package/dist/client/components/widgets/widget-skeletons.mjs +390 -108
  163. package/dist/client/contexts/breadcrumb-context.mjs +44 -16
  164. package/dist/client/{context → contexts}/focus-context.d.mts +6 -7
  165. package/dist/client/{context → contexts}/focus-context.mjs +134 -62
  166. package/dist/client/hooks/typed-hooks.d.mts +38 -12
  167. package/dist/client/hooks/typed-hooks.mjs +758 -142
  168. package/dist/client/hooks/use-action.mjs +197 -69
  169. package/dist/client/hooks/use-admin-config.mjs +39 -10
  170. package/dist/client/hooks/use-admin-preferences.mjs +118 -15
  171. package/dist/client/hooks/use-admin-routes.mjs +60 -27
  172. package/dist/client/hooks/use-audit-history.mjs +157 -0
  173. package/dist/client/hooks/use-auth.d.mts +14 -15
  174. package/dist/client/hooks/use-auth.mjs +8 -9
  175. package/dist/client/hooks/use-collection-fields.mjs +58 -19
  176. package/dist/client/hooks/use-collection-meta.mjs +45 -13
  177. package/dist/client/hooks/use-collection-schema.mjs +34 -11
  178. package/dist/client/hooks/use-collection-validation.mjs +39 -25
  179. package/dist/client/hooks/use-collection.d.mts +18 -8
  180. package/dist/client/hooks/use-collection.mjs +560 -101
  181. package/dist/client/hooks/use-current-user.d.mts +6 -3
  182. package/dist/client/hooks/use-current-user.mjs +2 -2
  183. package/dist/client/hooks/use-field-hooks.mjs +73 -65
  184. package/dist/client/hooks/use-field-options.d.mts +1 -34
  185. package/dist/client/hooks/use-field-options.mjs +233 -148
  186. package/dist/client/hooks/use-global-fields.mjs +47 -16
  187. package/dist/client/hooks/use-global-meta.mjs +57 -11
  188. package/dist/client/hooks/use-global-schema.mjs +31 -11
  189. package/dist/client/hooks/use-global.d.mts +13 -2
  190. package/dist/client/hooks/use-global.mjs +244 -34
  191. package/dist/client/hooks/use-locks.mjs +331 -124
  192. package/dist/client/hooks/use-media-query.d.mts +1 -2
  193. package/dist/client/hooks/use-media-query.mjs +38 -19
  194. package/dist/client/hooks/use-prefill-params.mjs +2 -2
  195. package/dist/client/hooks/use-questpie-query-options.mjs +33 -11
  196. package/dist/client/hooks/use-reactive-fields.d.mts +6 -3
  197. package/dist/client/hooks/use-reactive-fields.mjs +130 -93
  198. package/dist/client/hooks/use-realtime-highlight.mjs +115 -53
  199. package/dist/client/hooks/use-saved-views.mjs +109 -34
  200. package/dist/client/hooks/use-search-param-toggle.d.mts +12 -0
  201. package/dist/client/hooks/use-search-param-toggle.mjs +115 -0
  202. package/dist/client/hooks/use-search.mjs +147 -36
  203. package/dist/client/hooks/use-server-actions.mjs +191 -0
  204. package/dist/client/hooks/use-server-validation.mjs +164 -72
  205. package/dist/client/hooks/use-server-widget-data.d.mts +2 -3
  206. package/dist/client/hooks/use-server-widget-data.mjs +36 -11
  207. package/dist/client/hooks/use-setup-status.d.mts +3 -4
  208. package/dist/client/hooks/use-setup-status.mjs +28 -16
  209. package/dist/client/hooks/use-sidebar-search-param.d.mts +9 -0
  210. package/dist/client/hooks/use-sidebar-search-param.mjs +104 -0
  211. package/dist/client/hooks/use-transition-stage.mjs +125 -0
  212. package/dist/client/hooks/use-upload-collection.mjs +1 -2
  213. package/dist/client/hooks/use-upload.mjs +189 -125
  214. package/dist/client/hooks/use-validation-error-map.mjs +10 -6
  215. package/dist/client/hooks/use-view-state.mjs +380 -162
  216. package/dist/client/i18n/hooks.mjs +191 -67
  217. package/dist/client/i18n/intl-cache.mjs +1 -2
  218. package/dist/client/i18n/messages.mjs +1 -2
  219. package/dist/client/i18n/simple.d.mts +1 -2
  220. package/dist/client/i18n/simple.mjs +1 -2
  221. package/dist/client/i18n/types.d.mts +1 -2
  222. package/dist/client/lib/cookies.mjs +9 -0
  223. package/dist/client/lib/events.mjs +5 -0
  224. package/dist/client/lib/render-profiler.mjs +51 -0
  225. package/dist/client/lib/utils.mjs +1 -6
  226. package/dist/client/preview/block-scope-context.d.mts +5 -6
  227. package/dist/client/preview/block-scope-context.mjs +50 -27
  228. package/dist/client/preview/index.d.mts +2 -2
  229. package/dist/client/preview/preview-banner.d.mts +3 -4
  230. package/dist/client/preview/preview-banner.mjs +74 -35
  231. package/dist/client/preview/preview-field.d.mts +9 -10
  232. package/dist/client/preview/preview-field.mjs +163 -61
  233. package/dist/client/preview/types.d.mts +1 -2
  234. package/dist/client/preview/types.mjs +1 -2
  235. package/dist/client/preview/use-collection-preview.d.mts +1 -2
  236. package/dist/client/preview/use-collection-preview.mjs +105 -56
  237. package/dist/client/runtime/content-locales-provider.mjs +87 -36
  238. package/dist/client/runtime/index.d.mts +1 -3
  239. package/dist/client/runtime/index.mjs +1 -3
  240. package/dist/client/runtime/locale-scope.mjs +69 -29
  241. package/dist/client/runtime/provider.d.mts +18 -9922
  242. package/dist/client/runtime/provider.mjs +250 -86
  243. package/dist/client/runtime/routes.d.mts +7 -7
  244. package/dist/client/runtime/routes.mjs +4 -20
  245. package/dist/client/runtime/translations-provider.mjs +114 -53
  246. package/dist/client/scope/picker.d.mts +3 -4
  247. package/dist/client/scope/picker.mjs +324 -90
  248. package/dist/client/scope/provider.d.mts +4 -5
  249. package/dist/client/scope/provider.mjs +30 -22
  250. package/dist/client/scope/types.d.mts +1 -2
  251. package/dist/client/styles/index.css +301 -225
  252. package/dist/client/utils/auto-expand-fields.mjs +23 -5
  253. package/dist/client/utils/build-field-definitions-from-schema.mjs +10 -7
  254. package/dist/client/utils/dependency-tracker.mjs +61 -0
  255. package/dist/client/utils/detect-relations.mjs +1 -2
  256. package/dist/client/utils/locale-to-flag.d.mts +8 -7
  257. package/dist/client/utils/locale-to-flag.mjs +1 -2
  258. package/dist/client/utils/routes.mjs +1 -2
  259. package/dist/client/views/auth/accept-invite-form.d.mts +3 -4
  260. package/dist/client/views/auth/accept-invite-form.mjs +414 -121
  261. package/dist/client/views/auth/auth-layout.d.mts +5 -6
  262. package/dist/client/views/auth/auth-layout.mjs +93 -30
  263. package/dist/client/views/auth/forgot-password-form.d.mts +4 -5
  264. package/dist/client/views/auth/forgot-password-form.mjs +332 -100
  265. package/dist/client/views/auth/invite-form.mjs +447 -105
  266. package/dist/client/views/auth/login-form.d.mts +4 -5
  267. package/dist/client/views/auth/login-form.mjs +340 -120
  268. package/dist/client/views/auth/reset-password-form.d.mts +4 -5
  269. package/dist/client/views/auth/reset-password-form.mjs +458 -131
  270. package/dist/client/views/auth/setup-form.d.mts +2 -3
  271. package/dist/client/views/auth/setup-form.mjs +481 -141
  272. package/dist/client/views/collection/auto-form-fields.mjs +686 -266
  273. package/dist/client/views/collection/bulk-action-toolbar.mjs +392 -203
  274. package/dist/client/views/collection/cells/complex-cells.mjs +635 -216
  275. package/dist/client/views/collection/cells/primitive-cells.mjs +332 -102
  276. package/dist/client/views/collection/cells/relation-cells.mjs +227 -72
  277. package/dist/client/views/collection/cells/shared/asset-thumbnail.mjs +456 -136
  278. package/dist/client/views/collection/cells/shared/cell-helpers.mjs +49 -2
  279. package/dist/client/views/collection/cells/shared/relation-chip.mjs +109 -25
  280. package/dist/client/views/collection/cells/upload-cells.mjs +16 -8
  281. package/dist/client/views/collection/columns/build-columns.mjs +51 -12
  282. package/dist/client/views/collection/columns/column-defaults.mjs +17 -2
  283. package/dist/client/views/collection/field-context.mjs +10 -11
  284. package/dist/client/views/collection/field-renderer.mjs +237 -40
  285. package/dist/client/views/collection/form-view.mjs +1108 -445
  286. package/dist/client/views/collection/table-view.mjs +300 -163
  287. package/dist/client/views/collection/view-skeletons.mjs +181 -87
  288. package/dist/client/views/common/global-search.mjs +557 -233
  289. package/dist/client/views/dashboard/dashboard-grid.mjs +707 -211
  290. package/dist/client/views/dashboard/dashboard-widget.mjs +145 -58
  291. package/dist/client/views/dashboard/widget-card.mjs +315 -102
  292. package/dist/client/views/globals/global-form-view.mjs +1256 -131
  293. package/dist/client/views/layout/admin-layout-provider.d.mts +18 -21
  294. package/dist/client/views/layout/admin-layout-provider.mjs +135 -32
  295. package/dist/client/views/layout/admin-layout.d.mts +14 -32
  296. package/dist/client/views/layout/admin-layout.mjs +254 -96
  297. package/dist/client/views/layout/admin-router.d.mts +10 -42
  298. package/dist/client/views/layout/admin-router.mjs +1086 -426
  299. package/dist/client/views/layout/admin-sidebar.d.mts +10 -16
  300. package/dist/client/views/layout/admin-sidebar.mjs +1211 -382
  301. package/dist/client/views/layout/admin-topbar.mjs +220 -112
  302. package/dist/client/views/pages/accept-invite-page.d.mts +5 -6
  303. package/dist/client/views/pages/accept-invite-page.mjs +302 -96
  304. package/dist/client/views/pages/dashboard-page.d.mts +7 -16
  305. package/dist/client/views/pages/dashboard-page.mjs +62 -23
  306. package/dist/client/views/pages/forgot-password-page.d.mts +7 -10
  307. package/dist/client/views/pages/forgot-password-page.mjs +112 -40
  308. package/dist/client/views/pages/invite-page.d.mts +6 -7
  309. package/dist/client/views/pages/invite-page.mjs +121 -46
  310. package/dist/client/views/pages/login-page.d.mts +8 -15
  311. package/dist/client/views/pages/login-page.mjs +152 -57
  312. package/dist/client/views/pages/reset-password-page.d.mts +7 -10
  313. package/dist/client/views/pages/reset-password-page.mjs +209 -57
  314. package/dist/client/views/pages/setup-page.d.mts +7 -10
  315. package/dist/client/views/pages/setup-page.mjs +108 -43
  316. package/dist/client-module.d.mts +3 -0
  317. package/dist/client-module.mjs +3 -0
  318. package/dist/client.d.mts +55 -48
  319. package/dist/client.mjs +26 -28
  320. package/dist/components/rich-text/rich-text-renderer.d.mts +3 -4
  321. package/dist/components/rich-text/rich-text-renderer.mjs +97 -70
  322. package/dist/index.d.mts +36 -39
  323. package/dist/index.mjs +26 -28
  324. package/dist/plugin.d.mts +2 -0
  325. package/dist/plugin.mjs +3 -0
  326. package/dist/server/adapters/nextjs.d.mts +13 -14
  327. package/dist/server/adapters/nextjs.mjs +12 -13
  328. package/dist/server/adapters/tanstack.d.mts +10 -11
  329. package/dist/server/adapters/tanstack.mjs +11 -12
  330. package/dist/server/augmentation/actions.d.mts +279 -0
  331. package/dist/server/augmentation/common.d.mts +76 -0
  332. package/dist/server/augmentation/dashboard.d.mts +547 -0
  333. package/dist/server/augmentation/form-layout.d.mts +303 -0
  334. package/dist/server/augmentation/index.d.mts +44 -0
  335. package/dist/server/augmentation/index.mjs +10 -0
  336. package/dist/server/augmentation/sidebar.d.mts +181 -0
  337. package/dist/server/augmentation/views.d.mts +237 -0
  338. package/dist/server/augmentation.d.mts +7 -1523
  339. package/dist/server/block/index.d.mts +4 -3
  340. package/dist/server/codegen/admin-client-template.mjs +93 -0
  341. package/dist/server/codegen/projection-validator.mjs +67 -0
  342. package/dist/server/fields/blocks.d.mts +10 -78
  343. package/dist/server/fields/blocks.mjs +74 -115
  344. package/dist/server/fields/index.d.mts +6 -39
  345. package/dist/server/fields/index.mjs +6 -7
  346. package/dist/server/fields/rich-text.d.mts +10 -77
  347. package/dist/server/fields/rich-text.mjs +59 -100
  348. package/dist/server/i18n/index.mjs +8 -9
  349. package/dist/server/i18n/messages/cs.mjs +3 -3
  350. package/dist/server/i18n/messages/de.mjs +3 -3
  351. package/dist/server/i18n/messages/en.mjs +217 -3
  352. package/dist/server/i18n/messages/es.mjs +3 -3
  353. package/dist/server/i18n/messages/fr.mjs +3 -3
  354. package/dist/server/i18n/messages/index.mjs +1 -2
  355. package/dist/server/i18n/messages/pl.mjs +3 -3
  356. package/dist/server/i18n/messages/pt.mjs +3 -3
  357. package/dist/server/i18n/messages/sk.mjs +202 -3
  358. package/dist/server/modules/admin/.generated/module.d.mts +52 -0
  359. package/dist/server/modules/admin/.generated/module.mjs +78 -0
  360. package/dist/server/modules/admin/.generated/registries.d.mts +22 -0
  361. package/dist/server/{auth-helpers.d.mts → modules/admin/auth-helpers.d.mts} +13 -14
  362. package/dist/server/{auth-helpers.mjs → modules/admin/auth-helpers.mjs} +15 -16
  363. package/dist/server/{block → modules/admin/block}/block-builder.d.mts +96 -32
  364. package/dist/server/{block → modules/admin/block}/block-builder.mjs +113 -15
  365. package/dist/server/modules/admin/block/index.d.mts +3 -0
  366. package/dist/server/{block → modules/admin/block}/introspection.d.mts +10 -5
  367. package/dist/server/{block → modules/admin/block}/introspection.mjs +18 -7
  368. package/dist/server/{block → modules/admin/block}/prefetch.d.mts +21 -17
  369. package/dist/server/{block → modules/admin/block}/prefetch.mjs +17 -16
  370. package/dist/server/modules/admin/client/.generated/module.d.mts +94 -0
  371. package/dist/server/modules/admin/client/.generated/module.mjs +91 -0
  372. package/dist/server/modules/admin/client/components/badge.d.mts +1 -0
  373. package/dist/server/modules/admin/client/components/icon.d.mts +1 -0
  374. package/dist/server/modules/admin/client/fields/array.d.mts +6 -0
  375. package/dist/server/modules/admin/client/fields/array.mjs +12 -0
  376. package/dist/server/modules/admin/client/fields/assetPreview.d.mts +6 -0
  377. package/dist/server/modules/admin/client/fields/assetPreview.mjs +18 -0
  378. package/dist/server/modules/admin/client/fields/blocks.d.mts +6 -0
  379. package/dist/server/modules/admin/client/fields/blocks.mjs +12 -0
  380. package/dist/server/modules/admin/client/fields/boolean.d.mts +6 -0
  381. package/dist/server/modules/admin/client/fields/boolean.mjs +12 -0
  382. package/dist/server/modules/admin/client/fields/date.d.mts +6 -0
  383. package/dist/server/modules/admin/client/fields/date.mjs +12 -0
  384. package/dist/server/modules/admin/client/fields/datetime.d.mts +6 -0
  385. package/dist/server/modules/admin/client/fields/datetime.mjs +12 -0
  386. package/dist/server/modules/admin/client/fields/email.d.mts +6 -0
  387. package/dist/server/modules/admin/client/fields/email.mjs +12 -0
  388. package/dist/server/modules/admin/client/fields/json.d.mts +6 -0
  389. package/dist/server/modules/admin/client/fields/json.mjs +11 -0
  390. package/dist/server/modules/admin/client/fields/number.d.mts +6 -0
  391. package/dist/server/modules/admin/client/fields/number.mjs +12 -0
  392. package/dist/server/modules/admin/client/fields/object.d.mts +6 -0
  393. package/dist/server/modules/admin/client/fields/object.mjs +12 -0
  394. package/dist/server/modules/admin/client/fields/relation.d.mts +6 -0
  395. package/dist/server/modules/admin/client/fields/relation.mjs +12 -0
  396. package/dist/server/modules/admin/client/fields/richText.d.mts +6 -0
  397. package/dist/server/modules/admin/client/fields/richText.mjs +11 -0
  398. package/dist/server/modules/admin/client/fields/select.d.mts +6 -0
  399. package/dist/server/modules/admin/client/fields/select.mjs +12 -0
  400. package/dist/server/modules/admin/client/fields/text.d.mts +6 -0
  401. package/dist/server/modules/admin/client/fields/text.mjs +12 -0
  402. package/dist/server/modules/admin/client/fields/textarea.d.mts +6 -0
  403. package/dist/server/modules/admin/client/fields/textarea.mjs +12 -0
  404. package/dist/server/modules/admin/client/fields/time.d.mts +6 -0
  405. package/dist/server/modules/admin/client/fields/time.mjs +12 -0
  406. package/dist/server/modules/admin/client/fields/upload.d.mts +6 -0
  407. package/dist/server/modules/admin/client/fields/upload.mjs +12 -0
  408. package/dist/server/modules/admin/client/fields/url.d.mts +6 -0
  409. package/dist/server/modules/admin/client/fields/url.mjs +12 -0
  410. package/dist/server/modules/admin/client/index.d.mts +1 -0
  411. package/dist/server/modules/admin/client/pages/dashboard.d.mts +6 -0
  412. package/dist/server/modules/admin/client/pages/dashboard.mjs +11 -0
  413. package/dist/server/modules/admin/client/pages/forgotPassword.d.mts +6 -0
  414. package/dist/server/modules/admin/client/pages/forgotPassword.mjs +11 -0
  415. package/dist/server/modules/admin/client/pages/login.d.mts +6 -0
  416. package/dist/server/modules/admin/client/pages/login.mjs +11 -0
  417. package/dist/server/modules/admin/client/pages/resetPassword.d.mts +6 -0
  418. package/dist/server/modules/admin/client/pages/resetPassword.mjs +11 -0
  419. package/dist/server/modules/admin/client/pages/setup.d.mts +6 -0
  420. package/dist/server/modules/admin/client/pages/setup.mjs +11 -0
  421. package/dist/server/modules/admin/client/views/collection-form.mjs +10 -0
  422. package/dist/server/modules/admin/client/views/collection-table.mjs +10 -0
  423. package/dist/server/modules/admin/client/views/global-form.mjs +10 -0
  424. package/dist/server/modules/admin/client/widgets/chart.d.mts +6 -0
  425. package/dist/server/modules/admin/client/widgets/chart.mjs +7 -0
  426. package/dist/server/modules/admin/client/widgets/progress.d.mts +6 -0
  427. package/dist/server/modules/admin/client/widgets/progress.mjs +7 -0
  428. package/dist/server/modules/admin/client/widgets/quickActions.d.mts +6 -0
  429. package/dist/server/modules/admin/client/widgets/quickActions.mjs +7 -0
  430. package/dist/server/modules/admin/client/widgets/recentItems.d.mts +6 -0
  431. package/dist/server/modules/admin/client/widgets/recentItems.mjs +7 -0
  432. package/dist/server/modules/admin/client/widgets/stats.d.mts +6 -0
  433. package/dist/server/modules/admin/client/widgets/stats.mjs +7 -0
  434. package/dist/server/modules/admin/client/widgets/table.d.mts +6 -0
  435. package/dist/server/modules/admin/client/widgets/table.mjs +7 -0
  436. package/dist/server/modules/admin/client/widgets/timeline.d.mts +6 -0
  437. package/dist/server/modules/admin/client/widgets/timeline.mjs +7 -0
  438. package/dist/server/modules/admin/client/widgets/value.d.mts +6 -0
  439. package/dist/server/modules/admin/client/widgets/value.mjs +7 -0
  440. package/dist/server/modules/admin/collections/account.d.mts +77 -0
  441. package/dist/server/modules/admin/collections/account.mjs +23 -0
  442. package/dist/server/modules/admin/collections/admin-locks.d.mts +90 -0
  443. package/dist/server/modules/admin/collections/admin-locks.mjs +16 -0
  444. package/dist/server/modules/admin/collections/admin-preferences.d.mts +69 -0
  445. package/dist/server/modules/admin/collections/admin-preferences.mjs +16 -0
  446. package/dist/server/modules/admin/collections/admin-saved-views.d.mts +83 -0
  447. package/dist/server/modules/admin/collections/admin-saved-views.mjs +16 -0
  448. package/dist/server/modules/admin/collections/apikey.d.mts +99 -0
  449. package/dist/server/modules/admin/collections/apikey.mjs +15 -0
  450. package/dist/server/modules/admin/collections/assets.d.mts +72 -0
  451. package/dist/server/modules/admin/collections/assets.mjs +71 -0
  452. package/dist/server/modules/admin/collections/session.d.mts +69 -0
  453. package/dist/server/modules/admin/collections/session.mjs +15 -0
  454. package/dist/server/modules/admin/collections/user.d.mts +85 -0
  455. package/dist/server/modules/admin/collections/user.mjs +204 -0
  456. package/dist/server/modules/admin/collections/verification.d.mts +63 -0
  457. package/dist/server/modules/admin/collections/verification.mjs +15 -0
  458. package/dist/server/modules/admin/components/badge.d.mts +10 -0
  459. package/dist/server/modules/admin/components/badge.mjs +10 -0
  460. package/dist/server/modules/admin/components/icon.d.mts +9 -0
  461. package/dist/server/modules/admin/components/icon.mjs +11 -0
  462. package/dist/server/modules/admin/config/admin.mjs +34 -0
  463. package/dist/server/modules/admin/dto/admin-config.dto.mjs +102 -0
  464. package/dist/server/modules/admin/factories.mjs +172 -0
  465. package/dist/server/modules/admin/index.d.mts +1060 -16846
  466. package/dist/server/modules/admin/index.mjs +17 -240
  467. package/dist/server/modules/admin/modules.mjs +11 -0
  468. package/dist/server/modules/admin/plugin.mjs +13 -0
  469. package/dist/server/modules/admin/routes/admin-config.d.mts +28 -0
  470. package/dist/server/modules/admin/routes/admin-config.mjs +552 -0
  471. package/dist/server/modules/admin/{functions → routes}/execute-action.d.mts +17 -32
  472. package/dist/server/modules/admin/{functions → routes}/execute-action.mjs +146 -44
  473. package/dist/server/modules/admin/routes/locales.d.mts +18 -0
  474. package/dist/server/modules/admin/routes/locales.mjs +69 -0
  475. package/dist/server/modules/admin/{functions → routes}/preview.d.mts +25 -15
  476. package/dist/server/modules/admin/{functions → routes}/preview.mjs +84 -97
  477. package/dist/server/modules/admin/{functions → routes}/reactive.d.mts +19 -44
  478. package/dist/server/modules/admin/{functions → routes}/reactive.mjs +89 -117
  479. package/dist/server/modules/admin/routes/route-helpers.d.mts +23 -0
  480. package/dist/server/modules/admin/routes/route-helpers.mjs +76 -0
  481. package/dist/server/modules/admin/{functions → routes}/setup.d.mts +11 -32
  482. package/dist/server/modules/admin/routes/setup.mjs +114 -0
  483. package/dist/server/modules/admin/routes/translations.d.mts +26 -0
  484. package/dist/server/modules/admin/routes/translations.mjs +114 -0
  485. package/dist/server/modules/admin/routes/widget-data.d.mts +32 -0
  486. package/dist/server/modules/admin/routes/widget-data.mjs +62 -0
  487. package/dist/server/modules/admin/views/form.d.mts +8 -0
  488. package/dist/server/modules/admin/views/form.mjs +7 -0
  489. package/dist/server/modules/admin/views/global-form.d.mts +8 -0
  490. package/dist/server/modules/admin/views/global-form.mjs +7 -0
  491. package/dist/server/modules/admin/views/table.d.mts +8 -0
  492. package/dist/server/modules/admin/views/table.mjs +7 -0
  493. package/dist/server/modules/admin-preferences/collections/{admin-preferences.collection.mjs → admin-preferences.mjs} +13 -24
  494. package/dist/server/modules/admin-preferences/collections/locks.collection.mjs +18 -42
  495. package/dist/server/modules/admin-preferences/collections/saved-views.d.mts +99 -0
  496. package/dist/server/modules/admin-preferences/collections/saved-views.mjs +38 -0
  497. package/dist/server/modules/audit/.generated/module.d.mts +60 -0
  498. package/dist/server/modules/audit/.generated/module.mjs +30 -0
  499. package/dist/server/modules/audit/collections/audit-log.d.mts +214 -0
  500. package/dist/server/modules/audit/collections/audit-log.mjs +107 -0
  501. package/dist/server/modules/audit/config/admin.mjs +21 -0
  502. package/dist/server/modules/audit/config/app.mjs +262 -0
  503. package/dist/server/modules/audit/index.d.mts +2 -0
  504. package/dist/server/modules/audit/jobs/audit-cleanup.d.mts +13 -0
  505. package/dist/server/modules/audit/jobs/audit-cleanup.mjs +28 -0
  506. package/dist/server/plugin.d.mts +26 -0
  507. package/dist/server/plugin.mjs +385 -0
  508. package/dist/server/proxy-factories.d.mts +85 -0
  509. package/dist/server/proxy-factories.mjs +302 -0
  510. package/dist/server/registry-helpers.d.mts +83 -0
  511. package/dist/server/registry-helpers.mjs +104 -0
  512. package/dist/server.d.mts +30 -18
  513. package/dist/server.mjs +19 -16
  514. package/dist/shared/preview-utils.d.mts +2 -3
  515. package/dist/shared/preview-utils.mjs +2 -3
  516. package/dist/shared/types/saved-views.types.d.mts +2 -2
  517. package/package.json +51 -40
  518. package/dist/_virtual/rolldown_runtime.mjs +0 -18
  519. package/dist/augmentation.d.mts.map +0 -1
  520. package/dist/client/blocks/block-registry.d.mts +0 -199
  521. package/dist/client/blocks/block-registry.d.mts.map +0 -1
  522. package/dist/client/blocks/block-registry.mjs +0 -88
  523. package/dist/client/blocks/block-registry.mjs.map +0 -1
  524. package/dist/client/blocks/block-renderer.d.mts.map +0 -1
  525. package/dist/client/blocks/block-renderer.mjs.map +0 -1
  526. package/dist/client/blocks/prefetch.d.mts +0 -45
  527. package/dist/client/blocks/prefetch.d.mts.map +0 -1
  528. package/dist/client/blocks/prefetch.mjs +0 -26
  529. package/dist/client/blocks/prefetch.mjs.map +0 -1
  530. package/dist/client/blocks/types.d.mts.map +0 -1
  531. package/dist/client/blocks/types.mjs.map +0 -1
  532. package/dist/client/builder/admin-builder.d.mts +0 -112
  533. package/dist/client/builder/admin-builder.d.mts.map +0 -1
  534. package/dist/client/builder/admin-builder.mjs +0 -185
  535. package/dist/client/builder/admin-builder.mjs.map +0 -1
  536. package/dist/client/builder/admin-types.d.mts.map +0 -1
  537. package/dist/client/builder/admin.d.mts.map +0 -1
  538. package/dist/client/builder/admin.mjs.map +0 -1
  539. package/dist/client/builder/defaults/components.mjs +0 -20
  540. package/dist/client/builder/defaults/components.mjs.map +0 -1
  541. package/dist/client/builder/defaults/core.d.mts +0 -354
  542. package/dist/client/builder/defaults/core.d.mts.map +0 -1
  543. package/dist/client/builder/defaults/core.mjs +0 -49
  544. package/dist/client/builder/defaults/core.mjs.map +0 -1
  545. package/dist/client/builder/defaults/fields.mjs +0 -328
  546. package/dist/client/builder/defaults/fields.mjs.map +0 -1
  547. package/dist/client/builder/defaults/pages.mjs +0 -58
  548. package/dist/client/builder/defaults/pages.mjs.map +0 -1
  549. package/dist/client/builder/defaults/starter.d.mts +0 -351
  550. package/dist/client/builder/defaults/starter.d.mts.map +0 -1
  551. package/dist/client/builder/defaults/starter.mjs +0 -28
  552. package/dist/client/builder/defaults/starter.mjs.map +0 -1
  553. package/dist/client/builder/defaults/views.mjs +0 -27
  554. package/dist/client/builder/defaults/views.mjs.map +0 -1
  555. package/dist/client/builder/defaults/widgets.mjs +0 -31
  556. package/dist/client/builder/defaults/widgets.mjs.map +0 -1
  557. package/dist/client/builder/field/field.d.mts.map +0 -1
  558. package/dist/client/builder/field/field.mjs.map +0 -1
  559. package/dist/client/builder/index.d.mts.map +0 -1
  560. package/dist/client/builder/page/page.d.mts.map +0 -1
  561. package/dist/client/builder/page/page.mjs.map +0 -1
  562. package/dist/client/builder/proxies.d.mts +0 -2
  563. package/dist/client/builder/proxies.mjs +0 -24
  564. package/dist/client/builder/proxies.mjs.map +0 -1
  565. package/dist/client/builder/qa.d.mts +0 -50
  566. package/dist/client/builder/qa.d.mts.map +0 -1
  567. package/dist/client/builder/qa.mjs +0 -42
  568. package/dist/client/builder/qa.mjs.map +0 -1
  569. package/dist/client/builder/registry.d.mts.map +0 -1
  570. package/dist/client/builder/types/action-registry.d.mts +0 -2
  571. package/dist/client/builder/types/action-registry.mjs.map +0 -1
  572. package/dist/client/builder/types/action-types.d.mts.map +0 -1
  573. package/dist/client/builder/types/collection-types.d.mts +0 -199
  574. package/dist/client/builder/types/collection-types.d.mts.map +0 -1
  575. package/dist/client/builder/types/collection-types.mjs.map +0 -1
  576. package/dist/client/builder/types/common.d.mts.map +0 -1
  577. package/dist/client/builder/types/field-types.d.mts.map +0 -1
  578. package/dist/client/builder/types/field-types.mjs.map +0 -1
  579. package/dist/client/builder/types/global-types.d.mts +0 -22
  580. package/dist/client/builder/types/global-types.d.mts.map +0 -1
  581. package/dist/client/builder/types/ui-config.d.mts.map +0 -1
  582. package/dist/client/builder/types/views.d.mts +0 -89
  583. package/dist/client/builder/types/views.d.mts.map +0 -1
  584. package/dist/client/builder/types/widget-types.d.mts.map +0 -1
  585. package/dist/client/builder/validation.mjs.map +0 -1
  586. package/dist/client/builder/view/view.d.mts.map +0 -1
  587. package/dist/client/builder/view/view.mjs.map +0 -1
  588. package/dist/client/builder/widget/widget.d.mts.map +0 -1
  589. package/dist/client/builder/widget/widget.mjs.map +0 -1
  590. package/dist/client/components/actions/action-button.d.mts +0 -2
  591. package/dist/client/components/actions/action-button.mjs.map +0 -1
  592. package/dist/client/components/actions/action-dialog.d.mts +0 -2
  593. package/dist/client/components/actions/action-dialog.mjs.map +0 -1
  594. package/dist/client/components/actions/confirmation-dialog.d.mts +0 -2
  595. package/dist/client/components/actions/confirmation-dialog.mjs.map +0 -1
  596. package/dist/client/components/actions/header-actions.d.mts +0 -2
  597. package/dist/client/components/actions/header-actions.mjs.map +0 -1
  598. package/dist/client/components/actions/index.d.mts +0 -4
  599. package/dist/client/components/admin-link.d.mts.map +0 -1
  600. package/dist/client/components/admin-link.mjs.map +0 -1
  601. package/dist/client/components/auth/auth-guard.d.mts.map +0 -1
  602. package/dist/client/components/auth/auth-guard.mjs.map +0 -1
  603. package/dist/client/components/auth/auth-loading.d.mts.map +0 -1
  604. package/dist/client/components/auth/auth-loading.mjs.map +0 -1
  605. package/dist/client/components/auth/index.d.mts +0 -2
  606. package/dist/client/components/blocks/block-canvas.mjs.map +0 -1
  607. package/dist/client/components/blocks/block-editor-context.mjs.map +0 -1
  608. package/dist/client/components/blocks/block-editor-layout.mjs.map +0 -1
  609. package/dist/client/components/blocks/block-editor-provider.mjs.map +0 -1
  610. package/dist/client/components/blocks/block-fields-renderer.mjs.map +0 -1
  611. package/dist/client/components/blocks/block-insert-button.mjs.map +0 -1
  612. package/dist/client/components/blocks/block-item-menu.mjs.map +0 -1
  613. package/dist/client/components/blocks/block-item.mjs.map +0 -1
  614. package/dist/client/components/blocks/block-library-sidebar.mjs.map +0 -1
  615. package/dist/client/components/blocks/block-tree.mjs.map +0 -1
  616. package/dist/client/components/blocks/block-type-icon.mjs.map +0 -1
  617. package/dist/client/components/blocks/utils/tree-utils.mjs.map +0 -1
  618. package/dist/client/components/component-renderer.d.mts.map +0 -1
  619. package/dist/client/components/component-renderer.mjs.map +0 -1
  620. package/dist/client/components/error-boundary.mjs.map +0 -1
  621. package/dist/client/components/fields/array-field.d.mts +0 -44
  622. package/dist/client/components/fields/array-field.d.mts.map +0 -1
  623. package/dist/client/components/fields/array-field.mjs.map +0 -1
  624. package/dist/client/components/fields/asset-preview-field.d.mts +0 -52
  625. package/dist/client/components/fields/asset-preview-field.d.mts.map +0 -1
  626. package/dist/client/components/fields/asset-preview-field.mjs.map +0 -1
  627. package/dist/client/components/fields/blocks-field/blocks-field.d.mts +0 -41
  628. package/dist/client/components/fields/blocks-field/blocks-field.d.mts.map +0 -1
  629. package/dist/client/components/fields/blocks-field/blocks-field.mjs.map +0 -1
  630. package/dist/client/components/fields/blocks-field/index.d.mts +0 -1
  631. package/dist/client/components/fields/boolean-field.d.mts +0 -30
  632. package/dist/client/components/fields/boolean-field.d.mts.map +0 -1
  633. package/dist/client/components/fields/boolean-field.mjs.map +0 -1
  634. package/dist/client/components/fields/custom-field.d.mts +0 -3
  635. package/dist/client/components/fields/date-field.d.mts +0 -22
  636. package/dist/client/components/fields/date-field.d.mts.map +0 -1
  637. package/dist/client/components/fields/date-field.mjs.map +0 -1
  638. package/dist/client/components/fields/datetime-field.d.mts +0 -23
  639. package/dist/client/components/fields/datetime-field.d.mts.map +0 -1
  640. package/dist/client/components/fields/datetime-field.mjs.map +0 -1
  641. package/dist/client/components/fields/email-field.d.mts +0 -19
  642. package/dist/client/components/fields/email-field.d.mts.map +0 -1
  643. package/dist/client/components/fields/email-field.mjs.map +0 -1
  644. package/dist/client/components/fields/embedded-collection.d.mts +0 -3
  645. package/dist/client/components/fields/field-types.d.mts +0 -571
  646. package/dist/client/components/fields/field-types.d.mts.map +0 -1
  647. package/dist/client/components/fields/field-utils.d.mts +0 -1
  648. package/dist/client/components/fields/field-utils.mjs.map +0 -1
  649. package/dist/client/components/fields/field-wrapper.d.mts +0 -3
  650. package/dist/client/components/fields/field-wrapper.mjs.map +0 -1
  651. package/dist/client/components/fields/index.d.mts +0 -33
  652. package/dist/client/components/fields/json-field.d.mts +0 -84
  653. package/dist/client/components/fields/json-field.d.mts.map +0 -1
  654. package/dist/client/components/fields/json-field.mjs.map +0 -1
  655. package/dist/client/components/fields/locale-badge.d.mts +0 -1
  656. package/dist/client/components/fields/locale-badge.mjs.map +0 -1
  657. package/dist/client/components/fields/number-field.d.mts +0 -23
  658. package/dist/client/components/fields/number-field.d.mts.map +0 -1
  659. package/dist/client/components/fields/number-field.mjs.map +0 -1
  660. package/dist/client/components/fields/object-array-field.d.mts +0 -2
  661. package/dist/client/components/fields/object-array-field.mjs.map +0 -1
  662. package/dist/client/components/fields/object-field.d.mts +0 -32
  663. package/dist/client/components/fields/object-field.d.mts.map +0 -1
  664. package/dist/client/components/fields/object-field.mjs.map +0 -1
  665. package/dist/client/components/fields/relation/displays/cards-display.d.mts +0 -2
  666. package/dist/client/components/fields/relation/displays/cards-display.mjs.map +0 -1
  667. package/dist/client/components/fields/relation/displays/chips-display.d.mts +0 -2
  668. package/dist/client/components/fields/relation/displays/chips-display.mjs.map +0 -1
  669. package/dist/client/components/fields/relation/displays/grid-display.d.mts +0 -2
  670. package/dist/client/components/fields/relation/displays/grid-display.mjs.map +0 -1
  671. package/dist/client/components/fields/relation/displays/index.d.mts +0 -6
  672. package/dist/client/components/fields/relation/displays/list-display.d.mts +0 -2
  673. package/dist/client/components/fields/relation/displays/list-display.mjs.map +0 -1
  674. package/dist/client/components/fields/relation/displays/table-display.d.mts +0 -2
  675. package/dist/client/components/fields/relation/displays/table-display.mjs.map +0 -1
  676. package/dist/client/components/fields/relation/displays/types.d.mts +0 -22
  677. package/dist/client/components/fields/relation/displays/types.d.mts.map +0 -1
  678. package/dist/client/components/fields/relation/displays/types.mjs.map +0 -1
  679. package/dist/client/components/fields/relation/index.d.mts +0 -3
  680. package/dist/client/components/fields/relation/relation-items-display.d.mts +0 -5
  681. package/dist/client/components/fields/relation/relation-items-display.mjs.map +0 -1
  682. package/dist/client/components/fields/relation-field.d.mts +0 -134
  683. package/dist/client/components/fields/relation-field.d.mts.map +0 -1
  684. package/dist/client/components/fields/relation-field.mjs.map +0 -1
  685. package/dist/client/components/fields/relation-picker.d.mts +0 -4
  686. package/dist/client/components/fields/relation-picker.mjs.map +0 -1
  687. package/dist/client/components/fields/relation-select.d.mts +0 -3
  688. package/dist/client/components/fields/relation-select.mjs.map +0 -1
  689. package/dist/client/components/fields/reverse-relation-field.d.mts +0 -2
  690. package/dist/client/components/fields/rich-text-editor/bubble-menu.mjs.map +0 -1
  691. package/dist/client/components/fields/rich-text-editor/extensions.mjs.map +0 -1
  692. package/dist/client/components/fields/rich-text-editor/image-popover.mjs.map +0 -1
  693. package/dist/client/components/fields/rich-text-editor/index.d.mts +0 -4
  694. package/dist/client/components/fields/rich-text-editor/index.mjs.map +0 -1
  695. package/dist/client/components/fields/rich-text-editor/link-popover.mjs.map +0 -1
  696. package/dist/client/components/fields/rich-text-editor/presets.d.mts +0 -11
  697. package/dist/client/components/fields/rich-text-editor/presets.d.mts.map +0 -1
  698. package/dist/client/components/fields/rich-text-editor/presets.mjs.map +0 -1
  699. package/dist/client/components/fields/rich-text-editor/slash-commands.mjs.map +0 -1
  700. package/dist/client/components/fields/rich-text-editor/table-controls.mjs.map +0 -1
  701. package/dist/client/components/fields/rich-text-editor/toolbar.mjs.map +0 -1
  702. package/dist/client/components/fields/rich-text-editor/types.d.mts +0 -78
  703. package/dist/client/components/fields/rich-text-editor/types.d.mts.map +0 -1
  704. package/dist/client/components/fields/rich-text-editor/types.mjs.map +0 -1
  705. package/dist/client/components/fields/rich-text-editor/utils.mjs.map +0 -1
  706. package/dist/client/components/fields/rich-text-editor/variants.d.mts +0 -2
  707. package/dist/client/components/fields/rich-text-field.d.mts +0 -14
  708. package/dist/client/components/fields/rich-text-field.d.mts.map +0 -1
  709. package/dist/client/components/fields/rich-text-field.mjs.map +0 -1
  710. package/dist/client/components/fields/select-field.d.mts +0 -25
  711. package/dist/client/components/fields/select-field.d.mts.map +0 -1
  712. package/dist/client/components/fields/select-field.mjs.map +0 -1
  713. package/dist/client/components/fields/status-field.d.mts +0 -2
  714. package/dist/client/components/fields/text-field.d.mts +0 -22
  715. package/dist/client/components/fields/text-field.d.mts.map +0 -1
  716. package/dist/client/components/fields/text-field.mjs.map +0 -1
  717. package/dist/client/components/fields/textarea-field.d.mts +0 -22
  718. package/dist/client/components/fields/textarea-field.d.mts.map +0 -1
  719. package/dist/client/components/fields/textarea-field.mjs.map +0 -1
  720. package/dist/client/components/fields/time-field.d.mts +0 -20
  721. package/dist/client/components/fields/time-field.d.mts.map +0 -1
  722. package/dist/client/components/fields/time-field.mjs.map +0 -1
  723. package/dist/client/components/fields/upload-field.d.mts +0 -97
  724. package/dist/client/components/fields/upload-field.d.mts.map +0 -1
  725. package/dist/client/components/fields/upload-field.mjs.map +0 -1
  726. package/dist/client/components/filter-builder/columns-tab.d.mts +0 -1
  727. package/dist/client/components/filter-builder/columns-tab.mjs.map +0 -1
  728. package/dist/client/components/filter-builder/filter-builder-sheet.d.mts +0 -1
  729. package/dist/client/components/filter-builder/filter-builder-sheet.mjs.map +0 -1
  730. package/dist/client/components/filter-builder/filters-tab.d.mts +0 -1
  731. package/dist/client/components/filter-builder/filters-tab.mjs.map +0 -1
  732. package/dist/client/components/filter-builder/index.d.mts +0 -5
  733. package/dist/client/components/filter-builder/saved-views-tab.d.mts +0 -1
  734. package/dist/client/components/filter-builder/saved-views-tab.mjs.map +0 -1
  735. package/dist/client/components/index.d.mts +0 -80
  736. package/dist/client/components/locale-switcher.d.mts +0 -2
  737. package/dist/client/components/locale-switcher.mjs.map +0 -1
  738. package/dist/client/components/media/media-grid.mjs.map +0 -1
  739. package/dist/client/components/media/media-picker-dialog.mjs.map +0 -1
  740. package/dist/client/components/preview/live-preview-mode.mjs.map +0 -1
  741. package/dist/client/components/preview/preview-pane.mjs.map +0 -1
  742. package/dist/client/components/primitives/asset-preview.mjs.map +0 -1
  743. package/dist/client/components/primitives/checkbox-input.mjs.map +0 -1
  744. package/dist/client/components/primitives/date-input.mjs.map +0 -1
  745. package/dist/client/components/primitives/dropzone.mjs.map +0 -1
  746. package/dist/client/components/primitives/number-input.mjs.map +0 -1
  747. package/dist/client/components/primitives/select-multi.mjs.map +0 -1
  748. package/dist/client/components/primitives/select-single.mjs.map +0 -1
  749. package/dist/client/components/primitives/text-input.mjs.map +0 -1
  750. package/dist/client/components/primitives/textarea-input.mjs.map +0 -1
  751. package/dist/client/components/primitives/time-input.mjs.map +0 -1
  752. package/dist/client/components/primitives/toggle-input.mjs.map +0 -1
  753. package/dist/client/components/primitives/types.d.mts +0 -14
  754. package/dist/client/components/primitives/types.d.mts.map +0 -1
  755. package/dist/client/components/primitives/types.mjs.map +0 -1
  756. package/dist/client/components/sheets/index.d.mts +0 -1
  757. package/dist/client/components/sheets/resource-sheet.d.mts +0 -1
  758. package/dist/client/components/sheets/resource-sheet.mjs.map +0 -1
  759. package/dist/client/components/ui/accordion.d.mts +0 -2
  760. package/dist/client/components/ui/accordion.mjs.map +0 -1
  761. package/dist/client/components/ui/alert.mjs.map +0 -1
  762. package/dist/client/components/ui/avatar.d.mts +0 -3
  763. package/dist/client/components/ui/badge.d.mts +0 -3
  764. package/dist/client/components/ui/badge.mjs.map +0 -1
  765. package/dist/client/components/ui/button.d.mts +0 -3
  766. package/dist/client/components/ui/button.mjs.map +0 -1
  767. package/dist/client/components/ui/card.d.mts +0 -2
  768. package/dist/client/components/ui/card.mjs.map +0 -1
  769. package/dist/client/components/ui/checkbox.d.mts +0 -2
  770. package/dist/client/components/ui/checkbox.mjs.map +0 -1
  771. package/dist/client/components/ui/combobox.d.mts +0 -3
  772. package/dist/client/components/ui/command.mjs.map +0 -1
  773. package/dist/client/components/ui/dialog.d.mts +0 -3
  774. package/dist/client/components/ui/dialog.mjs.map +0 -1
  775. package/dist/client/components/ui/drawer.mjs.map +0 -1
  776. package/dist/client/components/ui/dropdown-menu.d.mts +0 -3
  777. package/dist/client/components/ui/dropdown-menu.mjs.map +0 -1
  778. package/dist/client/components/ui/empty-state.mjs.map +0 -1
  779. package/dist/client/components/ui/field.d.mts +0 -3
  780. package/dist/client/components/ui/field.mjs.map +0 -1
  781. package/dist/client/components/ui/input-group.d.mts +0 -4
  782. package/dist/client/components/ui/input-group.mjs.map +0 -1
  783. package/dist/client/components/ui/input.d.mts +0 -2
  784. package/dist/client/components/ui/input.mjs.map +0 -1
  785. package/dist/client/components/ui/kbd.mjs.map +0 -1
  786. package/dist/client/components/ui/label.d.mts +0 -2
  787. package/dist/client/components/ui/label.mjs.map +0 -1
  788. package/dist/client/components/ui/popover.d.mts +0 -3
  789. package/dist/client/components/ui/popover.mjs.map +0 -1
  790. package/dist/client/components/ui/responsive-dialog.mjs.map +0 -1
  791. package/dist/client/components/ui/scroll-area.d.mts +0 -2
  792. package/dist/client/components/ui/search-input.mjs.map +0 -1
  793. package/dist/client/components/ui/select.d.mts +0 -3
  794. package/dist/client/components/ui/select.mjs.map +0 -1
  795. package/dist/client/components/ui/separator.d.mts +0 -2
  796. package/dist/client/components/ui/separator.mjs.map +0 -1
  797. package/dist/client/components/ui/sheet.d.mts +0 -3
  798. package/dist/client/components/ui/sheet.mjs.map +0 -1
  799. package/dist/client/components/ui/sidebar.d.mts +0 -8
  800. package/dist/client/components/ui/sidebar.mjs.map +0 -1
  801. package/dist/client/components/ui/skeleton.d.mts +0 -1
  802. package/dist/client/components/ui/skeleton.mjs.map +0 -1
  803. package/dist/client/components/ui/sonner.d.mts.map +0 -1
  804. package/dist/client/components/ui/sonner.mjs.map +0 -1
  805. package/dist/client/components/ui/spinner.d.mts +0 -1
  806. package/dist/client/components/ui/spinner.mjs.map +0 -1
  807. package/dist/client/components/ui/switch.d.mts +0 -2
  808. package/dist/client/components/ui/switch.mjs.map +0 -1
  809. package/dist/client/components/ui/table.d.mts +0 -2
  810. package/dist/client/components/ui/table.mjs.map +0 -1
  811. package/dist/client/components/ui/tabs.d.mts +0 -3
  812. package/dist/client/components/ui/tabs.mjs.map +0 -1
  813. package/dist/client/components/ui/textarea.d.mts +0 -2
  814. package/dist/client/components/ui/textarea.mjs.map +0 -1
  815. package/dist/client/components/ui/toolbar.mjs.map +0 -1
  816. package/dist/client/components/ui/tooltip.d.mts +0 -2
  817. package/dist/client/components/ui/tooltip.mjs.map +0 -1
  818. package/dist/client/components/widgets/chart-widget.d.mts +0 -57
  819. package/dist/client/components/widgets/chart-widget.d.mts.map +0 -1
  820. package/dist/client/components/widgets/chart-widget.mjs.map +0 -1
  821. package/dist/client/components/widgets/progress-widget.d.mts +0 -41
  822. package/dist/client/components/widgets/progress-widget.d.mts.map +0 -1
  823. package/dist/client/components/widgets/progress-widget.mjs.map +0 -1
  824. package/dist/client/components/widgets/quick-actions-widget.d.mts +0 -29
  825. package/dist/client/components/widgets/quick-actions-widget.d.mts.map +0 -1
  826. package/dist/client/components/widgets/quick-actions-widget.mjs.map +0 -1
  827. package/dist/client/components/widgets/recent-items-widget.d.mts +0 -51
  828. package/dist/client/components/widgets/recent-items-widget.d.mts.map +0 -1
  829. package/dist/client/components/widgets/recent-items-widget.mjs.map +0 -1
  830. package/dist/client/components/widgets/stats-widget.d.mts +0 -55
  831. package/dist/client/components/widgets/stats-widget.d.mts.map +0 -1
  832. package/dist/client/components/widgets/stats-widget.mjs.map +0 -1
  833. package/dist/client/components/widgets/table-widget.d.mts +0 -31
  834. package/dist/client/components/widgets/table-widget.d.mts.map +0 -1
  835. package/dist/client/components/widgets/table-widget.mjs.map +0 -1
  836. package/dist/client/components/widgets/timeline-widget.d.mts +0 -51
  837. package/dist/client/components/widgets/timeline-widget.d.mts.map +0 -1
  838. package/dist/client/components/widgets/timeline-widget.mjs.map +0 -1
  839. package/dist/client/components/widgets/value-widget.d.mts +0 -39
  840. package/dist/client/components/widgets/value-widget.d.mts.map +0 -1
  841. package/dist/client/components/widgets/value-widget.mjs.map +0 -1
  842. package/dist/client/components/widgets/widget-skeletons.mjs.map +0 -1
  843. package/dist/client/context/focus-context.d.mts.map +0 -1
  844. package/dist/client/context/focus-context.mjs.map +0 -1
  845. package/dist/client/contexts/breadcrumb-context.mjs.map +0 -1
  846. package/dist/client/hooks/typed-hooks.d.mts.map +0 -1
  847. package/dist/client/hooks/typed-hooks.mjs.map +0 -1
  848. package/dist/client/hooks/use-action.mjs.map +0 -1
  849. package/dist/client/hooks/use-admin-config.mjs.map +0 -1
  850. package/dist/client/hooks/use-admin-preferences.mjs.map +0 -1
  851. package/dist/client/hooks/use-admin-routes.mjs.map +0 -1
  852. package/dist/client/hooks/use-auth.d.mts.map +0 -1
  853. package/dist/client/hooks/use-auth.mjs.map +0 -1
  854. package/dist/client/hooks/use-collection-fields.mjs.map +0 -1
  855. package/dist/client/hooks/use-collection-meta.mjs.map +0 -1
  856. package/dist/client/hooks/use-collection-schema.mjs.map +0 -1
  857. package/dist/client/hooks/use-collection-validation.mjs.map +0 -1
  858. package/dist/client/hooks/use-collection.d.mts.map +0 -1
  859. package/dist/client/hooks/use-collection.mjs.map +0 -1
  860. package/dist/client/hooks/use-current-user.d.mts.map +0 -1
  861. package/dist/client/hooks/use-current-user.mjs.map +0 -1
  862. package/dist/client/hooks/use-field-hooks.mjs.map +0 -1
  863. package/dist/client/hooks/use-field-options.d.mts.map +0 -1
  864. package/dist/client/hooks/use-field-options.mjs.map +0 -1
  865. package/dist/client/hooks/use-global-fields.mjs.map +0 -1
  866. package/dist/client/hooks/use-global-meta.mjs.map +0 -1
  867. package/dist/client/hooks/use-global-schema.mjs.map +0 -1
  868. package/dist/client/hooks/use-global.d.mts.map +0 -1
  869. package/dist/client/hooks/use-global.mjs.map +0 -1
  870. package/dist/client/hooks/use-locks.mjs.map +0 -1
  871. package/dist/client/hooks/use-media-query.d.mts.map +0 -1
  872. package/dist/client/hooks/use-media-query.mjs.map +0 -1
  873. package/dist/client/hooks/use-prefill-params.mjs.map +0 -1
  874. package/dist/client/hooks/use-questpie-query-options.mjs.map +0 -1
  875. package/dist/client/hooks/use-reactive-fields.d.mts.map +0 -1
  876. package/dist/client/hooks/use-reactive-fields.mjs.map +0 -1
  877. package/dist/client/hooks/use-realtime-highlight.mjs.map +0 -1
  878. package/dist/client/hooks/use-saved-views.mjs.map +0 -1
  879. package/dist/client/hooks/use-search.mjs.map +0 -1
  880. package/dist/client/hooks/use-server-validation.mjs.map +0 -1
  881. package/dist/client/hooks/use-server-widget-data.d.mts.map +0 -1
  882. package/dist/client/hooks/use-server-widget-data.mjs.map +0 -1
  883. package/dist/client/hooks/use-setup-status.d.mts.map +0 -1
  884. package/dist/client/hooks/use-setup-status.mjs.map +0 -1
  885. package/dist/client/hooks/use-upload-collection.mjs.map +0 -1
  886. package/dist/client/hooks/use-upload.d.mts +0 -23
  887. package/dist/client/hooks/use-upload.d.mts.map +0 -1
  888. package/dist/client/hooks/use-upload.mjs.map +0 -1
  889. package/dist/client/hooks/use-validation-error-map.mjs.map +0 -1
  890. package/dist/client/hooks/use-view-state.mjs.map +0 -1
  891. package/dist/client/i18n/hooks.mjs.map +0 -1
  892. package/dist/client/i18n/intl-cache.mjs.map +0 -1
  893. package/dist/client/i18n/messages.mjs.map +0 -1
  894. package/dist/client/i18n/simple.d.mts.map +0 -1
  895. package/dist/client/i18n/simple.mjs.map +0 -1
  896. package/dist/client/i18n/types.d.mts.map +0 -1
  897. package/dist/client/lib/utils.d.mts +0 -1
  898. package/dist/client/lib/utils.mjs.map +0 -1
  899. package/dist/client/preview/block-scope-context.d.mts.map +0 -1
  900. package/dist/client/preview/block-scope-context.mjs.map +0 -1
  901. package/dist/client/preview/preview-banner.d.mts.map +0 -1
  902. package/dist/client/preview/preview-banner.mjs.map +0 -1
  903. package/dist/client/preview/preview-field.d.mts.map +0 -1
  904. package/dist/client/preview/preview-field.mjs.map +0 -1
  905. package/dist/client/preview/types.d.mts.map +0 -1
  906. package/dist/client/preview/types.mjs.map +0 -1
  907. package/dist/client/preview/use-collection-preview.d.mts.map +0 -1
  908. package/dist/client/preview/use-collection-preview.mjs.map +0 -1
  909. package/dist/client/runtime/content-locales-provider.mjs.map +0 -1
  910. package/dist/client/runtime/locale-scope.mjs.map +0 -1
  911. package/dist/client/runtime/provider.d.mts.map +0 -1
  912. package/dist/client/runtime/provider.mjs.map +0 -1
  913. package/dist/client/runtime/routes.d.mts.map +0 -1
  914. package/dist/client/runtime/routes.mjs.map +0 -1
  915. package/dist/client/runtime/translations-provider.d.mts +0 -2
  916. package/dist/client/runtime/translations-provider.mjs.map +0 -1
  917. package/dist/client/scope/picker.d.mts.map +0 -1
  918. package/dist/client/scope/picker.mjs.map +0 -1
  919. package/dist/client/scope/provider.d.mts.map +0 -1
  920. package/dist/client/scope/provider.mjs.map +0 -1
  921. package/dist/client/scope/types.d.mts.map +0 -1
  922. package/dist/client/utils/auto-expand-fields.mjs.map +0 -1
  923. package/dist/client/utils/build-field-definitions-from-schema.mjs.map +0 -1
  924. package/dist/client/utils/detect-relations.mjs.map +0 -1
  925. package/dist/client/utils/locale-to-flag.d.mts.map +0 -1
  926. package/dist/client/utils/locale-to-flag.mjs.map +0 -1
  927. package/dist/client/utils/routes.mjs.map +0 -1
  928. package/dist/client/views/auth/accept-invite-form.d.mts.map +0 -1
  929. package/dist/client/views/auth/accept-invite-form.mjs.map +0 -1
  930. package/dist/client/views/auth/auth-layout.d.mts.map +0 -1
  931. package/dist/client/views/auth/auth-layout.mjs.map +0 -1
  932. package/dist/client/views/auth/forgot-password-form.d.mts.map +0 -1
  933. package/dist/client/views/auth/forgot-password-form.mjs.map +0 -1
  934. package/dist/client/views/auth/index.d.mts +0 -7
  935. package/dist/client/views/auth/invite-form.d.mts +0 -1
  936. package/dist/client/views/auth/invite-form.mjs.map +0 -1
  937. package/dist/client/views/auth/login-form.d.mts.map +0 -1
  938. package/dist/client/views/auth/login-form.mjs.map +0 -1
  939. package/dist/client/views/auth/reset-password-form.d.mts.map +0 -1
  940. package/dist/client/views/auth/reset-password-form.mjs.map +0 -1
  941. package/dist/client/views/auth/setup-form.d.mts.map +0 -1
  942. package/dist/client/views/auth/setup-form.mjs.map +0 -1
  943. package/dist/client/views/collection/auto-form-fields.d.mts +0 -4
  944. package/dist/client/views/collection/auto-form-fields.mjs.map +0 -1
  945. package/dist/client/views/collection/bulk-action-toolbar.mjs.map +0 -1
  946. package/dist/client/views/collection/cells/complex-cells.d.mts +0 -46
  947. package/dist/client/views/collection/cells/complex-cells.d.mts.map +0 -1
  948. package/dist/client/views/collection/cells/complex-cells.mjs.map +0 -1
  949. package/dist/client/views/collection/cells/index.d.mts +0 -7
  950. package/dist/client/views/collection/cells/primitive-cells.d.mts +0 -76
  951. package/dist/client/views/collection/cells/primitive-cells.d.mts.map +0 -1
  952. package/dist/client/views/collection/cells/primitive-cells.mjs.map +0 -1
  953. package/dist/client/views/collection/cells/relation-cells.d.mts +0 -21
  954. package/dist/client/views/collection/cells/relation-cells.d.mts.map +0 -1
  955. package/dist/client/views/collection/cells/relation-cells.mjs.map +0 -1
  956. package/dist/client/views/collection/cells/shared/asset-thumbnail.d.mts +0 -1
  957. package/dist/client/views/collection/cells/shared/asset-thumbnail.mjs.map +0 -1
  958. package/dist/client/views/collection/cells/shared/cell-helpers.d.mts +0 -2
  959. package/dist/client/views/collection/cells/shared/cell-helpers.mjs.map +0 -1
  960. package/dist/client/views/collection/cells/shared/relation-chip.d.mts +0 -1
  961. package/dist/client/views/collection/cells/shared/relation-chip.mjs.map +0 -1
  962. package/dist/client/views/collection/cells/upload-cells.d.mts +0 -25
  963. package/dist/client/views/collection/cells/upload-cells.d.mts.map +0 -1
  964. package/dist/client/views/collection/cells/upload-cells.mjs.map +0 -1
  965. package/dist/client/views/collection/columns/build-columns.d.mts +0 -2
  966. package/dist/client/views/collection/columns/build-columns.mjs.map +0 -1
  967. package/dist/client/views/collection/columns/column-defaults.d.mts +0 -2
  968. package/dist/client/views/collection/columns/column-defaults.mjs.map +0 -1
  969. package/dist/client/views/collection/columns/index.d.mts +0 -3
  970. package/dist/client/views/collection/columns/types.d.mts +0 -2
  971. package/dist/client/views/collection/field-context.mjs.map +0 -1
  972. package/dist/client/views/collection/field-renderer.mjs.map +0 -1
  973. package/dist/client/views/collection/form-view.d.mts +0 -112
  974. package/dist/client/views/collection/form-view.d.mts.map +0 -1
  975. package/dist/client/views/collection/form-view.mjs.map +0 -1
  976. package/dist/client/views/collection/index.d.mts +0 -9
  977. package/dist/client/views/collection/table-view.d.mts +0 -102
  978. package/dist/client/views/collection/table-view.d.mts.map +0 -1
  979. package/dist/client/views/collection/table-view.mjs.map +0 -1
  980. package/dist/client/views/collection/view-skeletons.mjs.map +0 -1
  981. package/dist/client/views/common/global-search.d.mts +0 -1
  982. package/dist/client/views/common/global-search.mjs.map +0 -1
  983. package/dist/client/views/common/index.d.mts +0 -1
  984. package/dist/client/views/dashboard/dashboard-grid.mjs.map +0 -1
  985. package/dist/client/views/dashboard/dashboard-widget.mjs.map +0 -1
  986. package/dist/client/views/dashboard/widget-card.mjs.map +0 -1
  987. package/dist/client/views/globals/global-form-view.d.mts +0 -74
  988. package/dist/client/views/globals/global-form-view.d.mts.map +0 -1
  989. package/dist/client/views/globals/global-form-view.mjs.map +0 -1
  990. package/dist/client/views/index.d.mts +0 -28
  991. package/dist/client/views/layout/admin-layout-provider.d.mts.map +0 -1
  992. package/dist/client/views/layout/admin-layout-provider.mjs.map +0 -1
  993. package/dist/client/views/layout/admin-layout.d.mts.map +0 -1
  994. package/dist/client/views/layout/admin-layout.mjs.map +0 -1
  995. package/dist/client/views/layout/admin-root.d.mts +0 -7
  996. package/dist/client/views/layout/admin-router.d.mts.map +0 -1
  997. package/dist/client/views/layout/admin-router.mjs.map +0 -1
  998. package/dist/client/views/layout/admin-sidebar.d.mts.map +0 -1
  999. package/dist/client/views/layout/admin-sidebar.mjs.map +0 -1
  1000. package/dist/client/views/layout/admin-topbar.mjs.map +0 -1
  1001. package/dist/client/views/layout/index.d.mts +0 -5
  1002. package/dist/client/views/pages/accept-invite-page.d.mts.map +0 -1
  1003. package/dist/client/views/pages/accept-invite-page.mjs.map +0 -1
  1004. package/dist/client/views/pages/dashboard-page.d.mts.map +0 -1
  1005. package/dist/client/views/pages/dashboard-page.mjs.map +0 -1
  1006. package/dist/client/views/pages/forgot-password-page.d.mts.map +0 -1
  1007. package/dist/client/views/pages/forgot-password-page.mjs.map +0 -1
  1008. package/dist/client/views/pages/index.d.mts +0 -7
  1009. package/dist/client/views/pages/invite-page.d.mts.map +0 -1
  1010. package/dist/client/views/pages/invite-page.mjs.map +0 -1
  1011. package/dist/client/views/pages/login-page.d.mts.map +0 -1
  1012. package/dist/client/views/pages/login-page.mjs.map +0 -1
  1013. package/dist/client/views/pages/reset-password-page.d.mts.map +0 -1
  1014. package/dist/client/views/pages/reset-password-page.mjs.map +0 -1
  1015. package/dist/client/views/pages/setup-page.d.mts.map +0 -1
  1016. package/dist/client/views/pages/setup-page.mjs.map +0 -1
  1017. package/dist/client.d.mts.map +0 -1
  1018. package/dist/components/rich-text/rich-text-renderer.d.mts.map +0 -1
  1019. package/dist/components/rich-text/rich-text-renderer.mjs.map +0 -1
  1020. package/dist/server/adapters/nextjs.d.mts.map +0 -1
  1021. package/dist/server/adapters/nextjs.mjs.map +0 -1
  1022. package/dist/server/adapters/tanstack.d.mts.map +0 -1
  1023. package/dist/server/adapters/tanstack.mjs.map +0 -1
  1024. package/dist/server/augmentation.d.mts.map +0 -1
  1025. package/dist/server/auth-helpers.d.mts.map +0 -1
  1026. package/dist/server/auth-helpers.mjs.map +0 -1
  1027. package/dist/server/block/block-builder.d.mts.map +0 -1
  1028. package/dist/server/block/block-builder.mjs.map +0 -1
  1029. package/dist/server/block/introspection.d.mts.map +0 -1
  1030. package/dist/server/block/introspection.mjs.map +0 -1
  1031. package/dist/server/block/prefetch.d.mts.map +0 -1
  1032. package/dist/server/block/prefetch.mjs.map +0 -1
  1033. package/dist/server/fields/blocks.d.mts.map +0 -1
  1034. package/dist/server/fields/blocks.mjs.map +0 -1
  1035. package/dist/server/fields/index.d.mts.map +0 -1
  1036. package/dist/server/fields/index.mjs.map +0 -1
  1037. package/dist/server/fields/rich-text.d.mts.map +0 -1
  1038. package/dist/server/fields/rich-text.mjs.map +0 -1
  1039. package/dist/server/i18n/index.d.mts +0 -16
  1040. package/dist/server/i18n/index.d.mts.map +0 -1
  1041. package/dist/server/i18n/index.mjs.map +0 -1
  1042. package/dist/server/i18n/messages/cs.mjs.map +0 -1
  1043. package/dist/server/i18n/messages/de.mjs.map +0 -1
  1044. package/dist/server/i18n/messages/en.mjs.map +0 -1
  1045. package/dist/server/i18n/messages/es.mjs.map +0 -1
  1046. package/dist/server/i18n/messages/fr.mjs.map +0 -1
  1047. package/dist/server/i18n/messages/index.mjs.map +0 -1
  1048. package/dist/server/i18n/messages/pl.mjs.map +0 -1
  1049. package/dist/server/i18n/messages/pt.mjs.map +0 -1
  1050. package/dist/server/i18n/messages/sk.mjs.map +0 -1
  1051. package/dist/server/index.d.mts +0 -20
  1052. package/dist/server/modules/admin/functions/admin-config.mjs +0 -348
  1053. package/dist/server/modules/admin/functions/admin-config.mjs.map +0 -1
  1054. package/dist/server/modules/admin/functions/execute-action.d.mts.map +0 -1
  1055. package/dist/server/modules/admin/functions/execute-action.mjs.map +0 -1
  1056. package/dist/server/modules/admin/functions/locales.mjs +0 -80
  1057. package/dist/server/modules/admin/functions/locales.mjs.map +0 -1
  1058. package/dist/server/modules/admin/functions/preview.d.mts.map +0 -1
  1059. package/dist/server/modules/admin/functions/preview.mjs.map +0 -1
  1060. package/dist/server/modules/admin/functions/reactive.d.mts.map +0 -1
  1061. package/dist/server/modules/admin/functions/reactive.mjs.map +0 -1
  1062. package/dist/server/modules/admin/functions/setup.d.mts.map +0 -1
  1063. package/dist/server/modules/admin/functions/setup.mjs +0 -131
  1064. package/dist/server/modules/admin/functions/setup.mjs.map +0 -1
  1065. package/dist/server/modules/admin/functions/translations.mjs +0 -125
  1066. package/dist/server/modules/admin/functions/translations.mjs.map +0 -1
  1067. package/dist/server/modules/admin/functions/widget-data.d.mts +0 -33
  1068. package/dist/server/modules/admin/functions/widget-data.d.mts.map +0 -1
  1069. package/dist/server/modules/admin/functions/widget-data.mjs +0 -70
  1070. package/dist/server/modules/admin/functions/widget-data.mjs.map +0 -1
  1071. package/dist/server/modules/admin/index.d.mts.map +0 -1
  1072. package/dist/server/modules/admin/index.mjs.map +0 -1
  1073. package/dist/server/modules/admin-preferences/collections/admin-preferences.collection.d.mts +0 -3
  1074. package/dist/server/modules/admin-preferences/collections/admin-preferences.collection.mjs.map +0 -1
  1075. package/dist/server/modules/admin-preferences/collections/locks.collection.d.mts +0 -3
  1076. package/dist/server/modules/admin-preferences/collections/locks.collection.mjs.map +0 -1
  1077. package/dist/server/modules/admin-preferences/collections/saved-views.collection.d.mts +0 -1490
  1078. package/dist/server/modules/admin-preferences/collections/saved-views.collection.d.mts.map +0 -1
  1079. package/dist/server/modules/admin-preferences/collections/saved-views.collection.mjs +0 -57
  1080. package/dist/server/modules/admin-preferences/collections/saved-views.collection.mjs.map +0 -1
  1081. package/dist/server/patch.d.mts +0 -100
  1082. package/dist/server/patch.d.mts.map +0 -1
  1083. package/dist/server/patch.mjs +0 -1062
  1084. package/dist/server/patch.mjs.map +0 -1
  1085. package/dist/shared/preview-utils.d.mts.map +0 -1
  1086. package/dist/shared/preview-utils.mjs.map +0 -1
  1087. package/dist/shared/types/saved-views.types.d.mts.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"locale-switcher.mjs","names":["mapping: Record<string, string>"],"sources":["../../../src/client/components/locale-switcher.tsx"],"sourcesContent":["import { Icon } from \"@iconify/react\";\nimport type * as React from \"react\";\nimport { useMemo, useState } from \"react\";\nimport { useResolveText } from \"../i18n/hooks\";\nimport type { I18nText } from \"../i18n/types\";\nimport { cn } from \"../lib/utils\";\nimport { getFlagUrl } from \"../utils/locale-to-flag\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"./ui/dropdown-menu\";\n\nexport type LocaleOption = {\n code: string;\n label?: I18nText;\n flagCountryCode?: string;\n};\n\nexport type LocaleSwitcherLabelMode = \"code\" | \"name\" | \"both\" | \"none\";\n\nexport interface LocaleSwitcherProps {\n locales: LocaleOption[];\n value?: string;\n onChange?: (locale: string) => void;\n showFlag?: boolean;\n labelMode?: LocaleSwitcherLabelMode;\n className?: string;\n}\n\nconst DROPDOWN_THRESHOLD = 4;\n\nexport function LocaleSwitcher({\n locales,\n value,\n onChange,\n showFlag = true,\n labelMode = \"code\",\n className,\n}: LocaleSwitcherProps): React.ReactElement | null {\n const resolveText = useResolveText();\n const [imgError, setImgError] = useState(false);\n const resolvedValue = value ?? locales[0]?.code ?? \"\";\n const hasResolvedValue = resolvedValue.length > 0;\n const localeOptions = locales.length\n ? locales\n : hasResolvedValue\n ? [{ code: resolvedValue } satisfies LocaleOption]\n : [];\n const currentLocale =\n localeOptions.find((locale) => locale.code === resolvedValue) ??\n ({ code: resolvedValue } satisfies LocaleOption);\n const canSwitch = !!onChange && localeOptions.length > 1;\n const useDropdown = localeOptions.length >= DROPDOWN_THRESHOLD;\n\n const flagMapping = useMemo(() => {\n const mapping: Record<string, string> = {};\n for (const locale of localeOptions) {\n if (locale.flagCountryCode) {\n mapping[locale.code.toLowerCase()] = locale.flagCountryCode;\n }\n }\n return mapping;\n }, [localeOptions]);\n const hasCustomMapping = Object.keys(flagMapping).length > 0;\n\n const getLocaleFlagUrl = (code: string, size = 24) =>\n getFlagUrl(code, size, hasCustomMapping ? flagMapping : undefined);\n\n if (!hasResolvedValue) return null;\n\n const codeLabel = currentLocale.code.toUpperCase();\n const nameLabel = currentLocale.label\n ? resolveText(currentLocale.label)\n : codeLabel;\n const renderLabel = () => {\n switch (labelMode) {\n case \"none\":\n return null;\n case \"name\":\n return <span className=\"font-medium\">{nameLabel}</span>;\n case \"both\":\n return (\n <span className=\"flex items-center gap-1\">\n <span className=\"uppercase tracking-wide\">{codeLabel}</span>\n {currentLocale.label && (\n <span className=\"font-normal text-muted-foreground\">\n {resolveText(currentLocale.label)}\n </span>\n )}\n </span>\n );\n case \"code\":\n default:\n return <span className=\"uppercase tracking-wide\">{codeLabel}</span>;\n }\n };\n\n const baseClassName = cn(\n \"inline-flex items-center gap-1 rounded bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground\",\n className,\n );\n const interactiveClassName = cn(\n baseClassName,\n \"cursor-pointer transition-colors hover:bg-muted/80 focus:outline-none focus:ring-1 focus:ring-ring\",\n );\n const ariaLabel = `Switch locale (current: ${nameLabel})`;\n\n const content = (\n <>\n {showFlag && !imgError && (\n <img\n src={getLocaleFlagUrl(resolvedValue)}\n alt={resolvedValue}\n className=\"h-2.5 w-3.5 rounded-[1px] object-cover\"\n onError={() => setImgError(true)}\n />\n )}\n {renderLabel()}\n </>\n );\n\n if (!canSwitch) {\n return <span className={baseClassName}>{content}</span>;\n }\n\n if (!useDropdown) {\n const handleCycle = (e: React.MouseEvent) => {\n e.stopPropagation();\n const currentIndex = localeOptions.findIndex(\n (locale) => locale.code === resolvedValue,\n );\n const nextIndex = (currentIndex + 1) % localeOptions.length;\n const nextLocale = localeOptions[nextIndex]?.code;\n if (nextLocale) onChange(nextLocale);\n };\n\n return (\n <button\n type=\"button\"\n onClick={handleCycle}\n className={interactiveClassName}\n aria-label={ariaLabel}\n title={ariaLabel}\n >\n {content}\n </button>\n );\n }\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger\n className={interactiveClassName}\n aria-label={ariaLabel}\n title={ariaLabel}\n onClick={(e) => e.stopPropagation()}\n >\n {content}\n <Icon icon=\"ph:caret-down\" className=\"size-2.5\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"min-w-[140px]\">\n {localeOptions.map((locale) => (\n <DropdownMenuItem\n key={locale.code}\n onClick={(e) => {\n e.stopPropagation();\n onChange(locale.code);\n }}\n className=\"gap-2 text-xs\"\n >\n {showFlag && (\n <img\n src={getLocaleFlagUrl(locale.code)}\n alt={locale.code}\n className=\"h-2.5 w-3.5 rounded-[1px] object-cover\"\n onError={(event) => {\n event.currentTarget.style.display = \"none\";\n }}\n />\n )}\n <span className=\"uppercase font-medium\">{locale.code}</span>\n {locale.label && (\n <span className=\"text-muted-foreground\">\n {resolveText(locale.label)}\n </span>\n )}\n {locale.code === resolvedValue && (\n <Icon icon=\"ph:check\" className=\"ml-auto size-3\" />\n )}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"media-grid.mjs","names":["React"],"sources":["../../../../src/client/components/media/media-grid.tsx"],"sourcesContent":["/**\n * MediaGrid Component\n *\n * Reusable grid display for assets with selection support.\n * Used in MediaPickerDialog and potentially in assets table view.\n *\n * Features:\n * - Responsive columns (2-5)\n * - Single/multiple/no selection modes\n * - Loading skeleton\n * - Click handling\n *\n * @example\n * ```tsx\n * <MediaGrid\n * assets={assets}\n * selectedIds={selectedIds}\n * onSelectionChange={setSelectedIds}\n * selectionMode=\"multiple\"\n * />\n * ```\n */\n\nimport { Icon } from \"@iconify/react\";\nimport * as React from \"react\";\nimport type { Asset } from \"../../hooks/use-upload\";\nimport { cn } from \"../../lib/utils\";\nimport { Skeleton } from \"../ui/skeleton\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface MediaGridProps {\n\t/**\n\t * Assets to display\n\t */\n\tassets: Asset[];\n\n\t/**\n\t * Currently selected asset IDs\n\t */\n\tselectedIds?: Set<string>;\n\n\t/**\n\t * Called when selection changes\n\t */\n\tonSelectionChange?: (ids: Set<string>) => void;\n\n\t/**\n\t * Selection mode\n\t * @default \"none\"\n\t */\n\tselectionMode?: \"single\" | \"multiple\" | \"none\";\n\n\t/**\n\t * Loading state (shows skeleton)\n\t */\n\tloading?: boolean;\n\n\t/**\n\t * Called when an asset is clicked\n\t */\n\tonAssetClick?: (asset: Asset) => void;\n\n\t/**\n\t * Number of columns\n\t * @default 4\n\t */\n\tcolumns?: 2 | 3 | 4 | 5;\n\n\t/**\n\t * Additional className\n\t */\n\tclassName?: string;\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Get file icon color based on MIME type\n */\nfunction getAssetTypeColor(mimeType?: string): string {\n\tif (!mimeType) return \"bg-muted\";\n\n\tconst type = mimeType.toLowerCase();\n\n\tif (type.startsWith(\"image/\")) return \"bg-info/10\";\n\tif (type.startsWith(\"video/\")) return \"bg-primary/10\";\n\tif (type.startsWith(\"audio/\")) return \"bg-success/10\";\n\tif (type === \"application/pdf\") return \"bg-destructive/10\";\n\n\treturn \"bg-muted\";\n}\n\n/**\n * Check if MIME type is an image\n */\nfunction isImage(mimeType?: string): boolean {\n\treturn !!mimeType?.toLowerCase().startsWith(\"image/\");\n}\n\n// ============================================================================\n// Skeleton Component\n// ============================================================================\n\nfunction MediaGridSkeleton({ columns = 4 }: { columns?: 2 | 3 | 4 | 5 }) {\n\tconst count = columns * 3; // Show 3 rows\n\tconst skeletonKeys = React.useMemo(\n\t\t() => Array.from({ length: count }, () => crypto.randomUUID()),\n\t\t[count],\n\t);\n\tconst gridClass =\n\t\tcolumns === 2\n\t\t\t? \"grid-cols-2\"\n\t\t\t: columns === 3\n\t\t\t\t? \"grid-cols-2 sm:grid-cols-3\"\n\t\t\t\t: columns === 5\n\t\t\t\t\t? \"grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5\"\n\t\t\t\t\t: \"grid-cols-2 sm:grid-cols-3 lg:grid-cols-4\";\n\n\treturn (\n\t\t<div className={cn(\"grid gap-3\", gridClass)}>\n\t\t\t{skeletonKeys.map((key) => (\n\t\t\t\t<div key={key} className=\"space-y-2\">\n\t\t\t\t\t<Skeleton className=\"aspect-square w-full rounded-lg\" />\n\t\t\t\t\t<Skeleton className=\"h-4 w-3/4\" />\n\t\t\t\t</div>\n\t\t\t))}\n\t\t</div>\n\t);\n}\n\n// ============================================================================\n// Asset Item Component\n// ============================================================================\n\ninterface AssetItemProps {\n\tasset: Asset;\n\tselected: boolean;\n\tselectionMode: \"single\" | \"multiple\" | \"none\";\n\tonToggle: () => void;\n\tonClick?: () => void;\n}\n\nfunction AssetItem({\n\tasset,\n\tselected,\n\tselectionMode,\n\tonToggle,\n\tonClick,\n}: AssetItemProps) {\n\tconst [imageError, setImageError] = React.useState(false);\n\tconst thumbnailUrl = asset.url;\n\tconst isImageType = isImage(asset.mimeType);\n\tconst showCheckbox = selectionMode !== \"none\";\n\n\tconst handleClick = () => {\n\t\tif (selectionMode !== \"none\") {\n\t\t\tonToggle();\n\t\t}\n\t\tonClick?.();\n\t};\n\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tonClick={handleClick}\n\t\t\tclassName={cn(\n\t\t\t\t\"group relative aspect-square w-full overflow-hidden rounded-lg border\",\n\t\t\t\t\"transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n\t\t\t\tselected\n\t\t\t\t\t? \"ring-primary border-primary ring-2\"\n\t\t\t\t\t: \"border-border/60 hover:border-border\",\n\t\t\t\t\"bg-muted/30\",\n\t\t\t)}\n\t\t>\n\t\t\t{/* Thumbnail or icon */}\n\t\t\t{thumbnailUrl && isImageType && !imageError ? (\n\t\t\t\t<img\n\t\t\t\t\tsrc={thumbnailUrl}\n\t\t\t\t\talt={asset.alt || asset.filename || \"Asset\"}\n\t\t\t\t\tclassName=\"h-full w-full object-cover\"\n\t\t\t\t\tonError={() => setImageError(true)}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"flex h-full w-full items-center justify-center\",\n\t\t\t\t\t\tgetAssetTypeColor(asset.mimeType),\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t<span className=\"text-muted-foreground text-xs font-medium uppercase\">\n\t\t\t\t\t\t{asset.mimeType?.split(\"/\")[1]?.slice(0, 4) || \"FILE\"}\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{/* Selection checkbox */}\n\t\t\t{showCheckbox && (\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"absolute right-2 top-2 flex size-5 items-center justify-center rounded-full border-2 transition-all\",\n\t\t\t\t\t\tselected\n\t\t\t\t\t\t\t? \"bg-primary border-primary\"\n\t\t\t\t\t\t\t: \"border-white bg-black/20 backdrop-blur-sm group-hover:bg-black/40\",\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t{selected && (\n\t\t\t\t\t\t<Icon icon=\"ph:check-bold\" className=\"size-3 text-white\" />\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{/* Filename overlay (on hover) */}\n\t\t\t{asset.filename && (\n\t\t\t\t<div className=\"absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/60 to-transparent p-2 opacity-0 transition-opacity group-hover:opacity-100\">\n\t\t\t\t\t<p className=\"truncate text-xs text-white\" title={asset.filename}>\n\t\t\t\t\t\t{asset.filename}\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</button>\n\t);\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\nexport function MediaGrid({\n\tassets,\n\tselectedIds = new Set(),\n\tonSelectionChange,\n\tselectionMode = \"none\",\n\tloading = false,\n\tonAssetClick,\n\tcolumns = 4,\n\tclassName,\n}: MediaGridProps) {\n\t// Handle toggle selection\n\tconst handleToggle = (assetId: string) => {\n\t\tif (!onSelectionChange) return;\n\n\t\tconst newSelection = new Set(selectedIds);\n\n\t\tif (selectionMode === \"single\") {\n\t\t\t// Single mode: clear all and select only this one\n\t\t\tnewSelection.clear();\n\t\t\tnewSelection.add(assetId);\n\t\t} else {\n\t\t\t// Multiple mode: toggle this one\n\t\t\tif (newSelection.has(assetId)) {\n\t\t\t\tnewSelection.delete(assetId);\n\t\t\t} else {\n\t\t\t\tnewSelection.add(assetId);\n\t\t\t}\n\t\t}\n\n\t\tonSelectionChange(newSelection);\n\t};\n\n\t// Show loading skeleton\n\tif (loading) {\n\t\treturn (\n\t\t\t<div className={className}>\n\t\t\t\t<MediaGridSkeleton columns={columns} />\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Empty state\n\tif (assets.length === 0) {\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"flex flex-col items-center justify-center rounded-lg border border-dashed p-12\",\n\t\t\t\t\t\"bg-muted/30 text-muted-foreground\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t<p className=\"text-sm\">No assets found</p>\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Grid columns class\n\tconst gridClass =\n\t\tcolumns === 2\n\t\t\t? \"grid-cols-2\"\n\t\t\t: columns === 3\n\t\t\t\t? \"grid-cols-2 sm:grid-cols-3\"\n\t\t\t\t: columns === 5\n\t\t\t\t\t? \"grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5\"\n\t\t\t\t\t: \"grid-cols-2 sm:grid-cols-3 lg:grid-cols-4\";\n\n\treturn (\n\t\t<div className={cn(\"grid gap-3\", gridClass, className)}>\n\t\t\t{assets.map((asset) => (\n\t\t\t\t<AssetItem\n\t\t\t\t\tkey={asset.id}\n\t\t\t\t\tasset={asset}\n\t\t\t\t\tselected={selectedIds.has(asset.id)}\n\t\t\t\t\tselectionMode={selectionMode}\n\t\t\t\t\tonToggle={() => handleToggle(asset.id)}\n\t\t\t\t\tonClick={onAssetClick ? () => onAssetClick(asset) : undefined}\n\t\t\t\t/>\n\t\t\t))}\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"media-picker-dialog.mjs","names":["React","andConditions: any[]"],"sources":["../../../../src/client/components/media/media-picker-dialog.tsx"],"sourcesContent":["/**\n * MediaPickerDialog Component\n *\n * Dialog for searching and selecting existing assets from the media library.\n * Used in UploadField and UploadManyField to allow browsing existing files.\n *\n * Features:\n * - Search by filename\n * - MIME type filtering\n * - Responsive grid display\n * - Single/multiple selection modes\n * - Pagination support\n *\n * @example\n * ```tsx\n * <MediaPickerDialog\n * open={isOpen}\n * onOpenChange={setIsOpen}\n * mode=\"single\"\n * onSelect={(id) => field.onChange(id)}\n * />\n * ```\n */\n\nimport { Icon } from \"@iconify/react\";\nimport * as React from \"react\";\nimport { toast } from \"sonner\";\nimport { useCollectionList } from \"../../hooks/use-collection\";\nimport type { Asset } from \"../../hooks/use-upload\";\nimport { useUploadCollection } from \"../../hooks/use-upload-collection\";\nimport { AssetPreview } from \"../primitives/asset-preview\";\nimport { Button } from \"../ui/button\";\nimport { Input } from \"../ui/input\";\nimport {\n\tSelect,\n\tSelectContent,\n\tSelectItem,\n\tSelectTrigger,\n\tSelectValue,\n} from \"../ui/select\";\nimport {\n\tSheet,\n\tSheetContent,\n\tSheetDescription,\n\tSheetFooter,\n\tSheetHeader,\n\tSheetTitle,\n} from \"../ui/sheet\";\nimport { MediaGrid } from \"./media-grid\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface MediaPickerDialogProps {\n\t/**\n\t * Dialog open state\n\t */\n\topen: boolean;\n\n\t/**\n\t * Called when dialog open state changes\n\t */\n\tonOpenChange: (open: boolean) => void;\n\n\t/**\n\t * Selection mode\n\t * @default \"single\"\n\t */\n\tmode?: \"single\" | \"multiple\";\n\n\t/**\n\t * Accepted MIME types filter\n\t * @example [\"image/*\", \"video/*\"]\n\t */\n\taccept?: string[];\n\n\t/**\n\t * Called when assets are selected\n\t */\n\tonSelect: (ids: string | string[]) => void;\n\n\t/**\n\t * Maximum number of items (for multiple mode)\n\t */\n\tmaxItems?: number;\n\n\t/**\n\t * Target collection\n\t */\n\tcollection?: string;\n}\n\n// ============================================================================\n// MIME Type Filters\n// ============================================================================\n\nconst MIME_TYPE_FILTERS = [\n\t{ value: \"all\", label: \"All Files\", mimePattern: undefined },\n\t{ value: \"images\", label: \"Images\", mimePattern: \"image/\" },\n\t{ value: \"videos\", label: \"Videos\", mimePattern: \"video/\" },\n\t{ value: \"audio\", label: \"Audio\", mimePattern: \"audio/\" },\n\t{ value: \"documents\", label: \"Documents\", mimePattern: \"application/pdf\" },\n];\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function MediaPickerDialog({\n\topen,\n\tonOpenChange,\n\tmode = \"single\",\n\taccept,\n\tonSelect,\n\tmaxItems,\n\tcollection,\n}: MediaPickerDialogProps) {\n\tconst {\n\t\tcollection: resolvedCollection,\n\t\tcollections: availableUploadCollections,\n\t} = useUploadCollection(collection);\n\n\t// State\n\tconst [selectedIds, setSelectedIds] = React.useState<Set<string>>(new Set());\n\tconst [searchQuery, setSearchQuery] = React.useState(\"\");\n\tconst [mimeFilter, setMimeFilter] = React.useState(\"all\");\n\tconst [previewAssetId, setPreviewAssetId] = React.useState<string | null>(\n\t\tnull,\n\t);\n\n\t// Build where clause for query\n\tconst where = React.useMemo(() => {\n\t\tconst andConditions: any[] = [];\n\n\t\t// MIME type filter\n\t\tconst selectedFilter = MIME_TYPE_FILTERS.find(\n\t\t\t(f) => f.value === mimeFilter,\n\t\t);\n\t\tif (selectedFilter?.mimePattern) {\n\t\t\tandConditions.push({\n\t\t\t\tmimeType: { startsWith: selectedFilter.mimePattern },\n\t\t\t});\n\t\t}\n\n\t\t// Accept prop filter\n\t\tif (accept && accept.length > 0) {\n\t\t\tconst acceptPatterns = accept.map((pattern) => {\n\t\t\t\tif (pattern.startsWith(\".\")) {\n\t\t\t\t\treturn { filename: { endsWith: pattern } };\n\t\t\t\t}\n\t\t\t\tif (pattern.endsWith(\"/*\")) {\n\t\t\t\t\t// e.g., \"image/*\" -> \"image/\"\n\t\t\t\t\treturn { mimeType: { startsWith: pattern.slice(0, -1) } };\n\t\t\t\t}\n\t\t\t\t// Exact match\n\t\t\t\treturn { mimeType: pattern };\n\t\t\t});\n\n\t\t\tif (acceptPatterns.length === 1) {\n\t\t\t\tandConditions.push(acceptPatterns[0]);\n\t\t\t} else {\n\t\t\t\tandConditions.push({ OR: acceptPatterns });\n\t\t\t}\n\t\t}\n\n\t\tif (andConditions.length === 0) return undefined;\n\t\tif (andConditions.length === 1) return andConditions[0];\n\t\treturn { AND: andConditions };\n\t}, [mimeFilter, accept]);\n\n\tconst trimmedSearch = searchQuery.trim();\n\n\t// Fetch assets\n\tconst { data, isLoading } = useCollectionList(\n\t\tresolvedCollection || \"\",\n\t\t{\n\t\t\twhere,\n\t\t\tsearch: trimmedSearch || undefined,\n\t\t\tlimit: 50,\n\t\t\torderBy: { createdAt: \"desc\" },\n\t\t},\n\t\t{\n\t\t\tenabled: open && !!resolvedCollection,\n\t\t},\n\t);\n\n\tconst assets = React.useMemo(\n\t\t() => (data?.docs || []) as Asset[],\n\t\t[data?.docs],\n\t);\n\tconst previewAsset = React.useMemo(\n\t\t() => assets.find((asset) => asset.id === previewAssetId) ?? null,\n\t\t[assets, previewAssetId],\n\t);\n\n\t// Reset state when dialog closes\n\tReact.useEffect(() => {\n\t\tif (!open) {\n\t\t\tsetSelectedIds(new Set());\n\t\t\tsetSearchQuery(\"\");\n\t\t\tsetMimeFilter(\"all\");\n\t\t\tsetPreviewAssetId(null);\n\t\t\treturn;\n\t\t}\n\t}, [open]);\n\n\t// Auto-select first asset for preview\n\tReact.useEffect(() => {\n\t\tif (!open || assets.length === 0) return;\n\n\t\tif (!previewAssetId) {\n\t\t\tsetPreviewAssetId(assets[0].id);\n\t\t\treturn;\n\t\t}\n\n\t\tconst stillExists = assets.some((asset) => asset.id === previewAssetId);\n\t\tif (!stillExists) {\n\t\t\tsetPreviewAssetId(assets[0].id);\n\t\t}\n\t}, [open, assets, previewAssetId]);\n\n\t// Handle selection change\n\tconst handleSelectionChange = (ids: Set<string>) => {\n\t\t// Check maxItems for multiple mode\n\t\tif (mode === \"multiple\" && maxItems && ids.size > maxItems) {\n\t\t\ttoast.warning(`Maximum ${maxItems} items allowed`);\n\t\t\treturn;\n\t\t}\n\n\t\tsetSelectedIds(ids);\n\t};\n\n\t// Handle select button click\n\tconst handleSelect = () => {\n\t\tif (!resolvedCollection) {\n\t\t\ttoast.error(\n\t\t\t\tavailableUploadCollections.length > 1\n\t\t\t\t\t? `Multiple upload collections are available (${availableUploadCollections.join(\", \")}). Specify the collection for MediaPickerDialog.`\n\t\t\t\t\t: \"No upload collection is configured for media library.\",\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tif (selectedIds.size === 0) {\n\t\t\ttoast.error(\"Please select at least one asset\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (mode === \"single\") {\n\t\t\tconst [id] = Array.from(selectedIds);\n\t\t\tonSelect(id);\n\t\t} else {\n\t\t\tonSelect(Array.from(selectedIds));\n\t\t}\n\n\t\tonOpenChange(false);\n\t};\n\n\t// Handle cancel\n\tconst handleCancel = () => {\n\t\tonOpenChange(false);\n\t};\n\n\treturn (\n\t\t<Sheet open={open} onOpenChange={onOpenChange}>\n\t\t\t<SheetContent\n\t\t\t\tside=\"right\"\n\t\t\t\tclassName=\"data-[side=right]:sm:max-w-6xl w-full p-0\"\n\t\t\t>\n\t\t\t\t<SheetHeader className=\"px-6 pt-6\">\n\t\t\t\t\t<SheetTitle>Browse Media Library</SheetTitle>\n\t\t\t\t\t<SheetDescription>\n\t\t\t\t\t\t{mode === \"single\"\n\t\t\t\t\t\t\t? \"Select an asset from your library\"\n\t\t\t\t\t\t\t: `Select up to ${maxItems || \"multiple\"} assets`}\n\t\t\t\t\t</SheetDescription>\n\t\t\t\t</SheetHeader>\n\n\t\t\t\t<div className=\"flex flex-1 flex-col gap-4 overflow-hidden px-6 pb-6\">\n\t\t\t\t\t{!resolvedCollection && (\n\t\t\t\t\t\t<div className=\"rounded-lg border border-warning/40 bg-warning/5 p-3 text-sm text-warning\">\n\t\t\t\t\t\t\t{availableUploadCollections.length > 1\n\t\t\t\t\t\t\t\t? `Multiple upload collections are available (${availableUploadCollections.join(\", \")}). Pass the collection prop to choose one.`\n\t\t\t\t\t\t\t\t: \"No upload collection is configured for media library.\"}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{/* Filters */}\n\t\t\t\t\t<div className=\"flex flex-col gap-3 border-b pb-4 sm:flex-row\">\n\t\t\t\t\t\t{/* Search input */}\n\t\t\t\t\t\t<div className=\"relative flex-1\">\n\t\t\t\t\t\t\t<Icon\n\t\t\t\t\t\t\t\ticon=\"ph:magnifying-glass-bold\"\n\t\t\t\t\t\t\t\tclassName=\"text-muted-foreground absolute left-3 top-1/2 size-4 -translate-y-1/2\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\tplaceholder=\"Search by filename...\"\n\t\t\t\t\t\t\t\tvalue={searchQuery}\n\t\t\t\t\t\t\t\tonChange={(e) => setSearchQuery(e.target.value)}\n\t\t\t\t\t\t\t\tclassName=\"pl-9\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{/* MIME type filter */}\n\t\t\t\t\t\t{!accept && (\n\t\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\t\tvalue={mimeFilter}\n\t\t\t\t\t\t\t\tonValueChange={(value) => setMimeFilter(value || \"all\")}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<SelectTrigger className=\"w-full sm:w-[180px]\">\n\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t<Icon icon=\"ph:funnel-simple-bold\" className=\"size-4\" />\n\t\t\t\t\t\t\t\t\t\t<SelectValue />\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t\t{MIME_TYPE_FILTERS.map((filter) => (\n\t\t\t\t\t\t\t\t\t\t<SelectItem key={filter.value} value={filter.value}>\n\t\t\t\t\t\t\t\t\t\t\t{filter.label}\n\t\t\t\t\t\t\t\t\t\t</SelectItem>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t\t</Select>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t{/* Assets + Preview */}\n\t\t\t\t\t<div className=\"flex flex-1 gap-4 overflow-hidden\">\n\t\t\t\t\t\t<div className=\"flex-1 overflow-y-auto pr-1\">\n\t\t\t\t\t\t\t<MediaGrid\n\t\t\t\t\t\t\t\tassets={assets}\n\t\t\t\t\t\t\t\tselectedIds={selectedIds}\n\t\t\t\t\t\t\t\tonSelectionChange={handleSelectionChange}\n\t\t\t\t\t\t\t\tselectionMode={mode}\n\t\t\t\t\t\t\t\tloading={isLoading}\n\t\t\t\t\t\t\t\tcolumns={5}\n\t\t\t\t\t\t\t\tclassName=\"gap-2\"\n\t\t\t\t\t\t\t\tonAssetClick={(asset) => setPreviewAssetId(asset.id)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"hidden lg:flex w-80 xl:w-96 shrink-0 flex-col gap-3 border-l pl-4\">\n\t\t\t\t\t\t\t<p className=\"text-muted-foreground text-xs uppercase tracking-wide\">\n\t\t\t\t\t\t\t\tPreview\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t{previewAsset ? (\n\t\t\t\t\t\t\t\t<AssetPreview asset={previewAsset} variant=\"card\" />\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<div className=\"flex items-center justify-center rounded-lg border border-dashed p-6 text-xs text-muted-foreground\">\n\t\t\t\t\t\t\t\t\tSelect an asset to preview\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div className=\"lg:hidden border-t pt-4\">\n\t\t\t\t\t\t{previewAsset ? (\n\t\t\t\t\t\t\t<AssetPreview asset={previewAsset} variant=\"compact\" />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<div className=\"flex items-center justify-center rounded-lg border border-dashed p-4 text-xs text-muted-foreground\">\n\t\t\t\t\t\t\t\tSelect an asset to preview\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<SheetFooter className=\"border-t px-6 py-4\">\n\t\t\t\t\t<div className=\"flex w-full justify-end gap-2\">\n\t\t\t\t\t\t<Button variant=\"outline\" onClick={handleCancel}>\n\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tonClick={handleSelect}\n\t\t\t\t\t\t\tdisabled={selectedIds.size === 0 || isLoading}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tSelect {selectedIds.size > 0 && `(${selectedIds.size})`}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t</SheetFooter>\n\t\t\t</SheetContent>\n\t\t</Sheet>\n\t);\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"live-preview-mode.mjs","names":["React"],"sources":["../../../../src/client/components/preview/live-preview-mode.tsx"],"sourcesContent":["/**\n * LivePreviewMode Component\n *\n * Fullscreen overlay for live preview editing.\n * Left side: Form panel (inline, not portal)\n * Right side: Preview iframe\n * Mobile: Tabs to switch between form and preview\n */\n\n\"use client\";\n\nimport { Icon } from \"@iconify/react\";\nimport * as React from \"react\";\nimport type { CollectionBuilderState } from \"../../builder/types/collection-types.js\";\nimport type { ComponentRegistry } from \"../../builder/types/field-types.js\";\nimport {\n FocusProvider,\n type FocusState,\n parsePreviewFieldPath,\n scrollFieldIntoView,\n useFocus,\n} from \"../../context/focus-context.js\";\nimport { useIsMobile } from \"../../hooks/use-media-query.js\";\nimport { useTranslation } from \"../../i18n/hooks.js\";\nimport { cn } from \"../../lib/utils.js\";\nimport {\n LocaleScopeProvider,\n selectBasePath,\n selectNavigate,\n useAdminStore,\n} from \"../../runtime/index.js\";\nimport FormView from \"../../views/collection/form-view.js\";\nimport { Button } from \"../ui/button.js\";\nimport { Tabs, TabsList, TabsTrigger } from \"../ui/tabs.js\";\nimport { PreviewPane, type PreviewPaneRef } from \"./preview-pane.js\";\n\n// ============================================================================\n// Context\n// ============================================================================\n\ntype LivePreviewContextValue = {\n triggerPreviewRefresh: () => void;\n};\n\nconst LivePreviewContext = React.createContext<LivePreviewContextValue | null>(\n null,\n);\n\nexport function useLivePreviewContext() {\n return React.useContext(LivePreviewContext);\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface LivePreviewModeProps {\n /** Whether preview mode is open */\n open: boolean;\n /** Callback to close preview mode */\n onClose: () => void;\n /** Collection name */\n collection: string;\n /** Item ID (for edit mode) */\n itemId?: string;\n /** Collection config */\n config?: any;\n /** All collections config (for embedded) */\n allCollectionsConfig?: Record<string, any>;\n /** Component registry */\n registry?: ComponentRegistry;\n /** Preview URL */\n previewUrl: string;\n /** Callback after successful save */\n onSuccess?: (data: any) => void;\n}\n\n// ============================================================================\n// Inner Component (with FocusContext access)\n// ============================================================================\n\ntype LivePreviewContentProps = LivePreviewModeProps & {\n previewRef: React.RefObject<PreviewPaneRef | null>;\n};\n\nfunction LivePreviewContent({\n onClose,\n collection,\n itemId,\n config,\n allCollectionsConfig,\n registry,\n previewUrl,\n onSuccess,\n previewRef,\n}: LivePreviewContentProps) {\n const { t } = useTranslation();\n const isMobile = useIsMobile();\n const navigate = useAdminStore(selectNavigate);\n const basePath = useAdminStore(selectBasePath);\n const [activeTab, setActiveTab] = React.useState<\"form\" | \"preview\">(\"form\");\n\n // Access FocusContext\n const focusContext = useFocus();\n const focusState = focusContext.state; // Extract for effect dependency\n\n // Handle exit preview (clear draft mode cookie)\n const handleExitPreview = React.useCallback(() => {\n // Redirect to exit preview endpoint\n window.location.href = \"/api/preview?disable=true\";\n }, []);\n\n // Sync focus changes to preview iframe\n React.useEffect(() => {\n if (!previewRef.current) return;\n\n if (focusState.type === \"field\") {\n previewRef.current.sendFocusToPreview(focusState.fieldPath);\n } else if (focusState.type === \"block\") {\n // Send full block field path\n if (focusState.fieldPath) {\n const fullPath = `content._values.${focusState.blockId}.${focusState.fieldPath}`;\n previewRef.current.sendFocusToPreview(fullPath);\n } else {\n // Just the block itself\n const fullPath = `content._values.${focusState.blockId}`;\n previewRef.current.sendFocusToPreview(fullPath);\n }\n }\n }, [focusState, previewRef]);\n\n // Preview click handlers - update FocusContext state\n const handlePreviewFieldClick = React.useCallback(\n (fieldPath: string, context?: any) => {\n const state = parsePreviewFieldPath(fieldPath, context);\n\n if (state.type === \"field\") {\n focusContext.focusField(state.fieldPath);\n } else if (state.type === \"block\") {\n focusContext.focusBlock(state.blockId, state.fieldPath);\n } else if (state.type === \"relation\") {\n focusContext.focusRelation(state.fieldPath, state.targetCollection);\n }\n },\n [focusContext],\n );\n\n const handlePreviewBlockClick = React.useCallback(\n (blockId: string) => {\n focusContext.focusBlock(blockId);\n },\n [focusContext],\n );\n\n // Use provided config or undefined (schema-driven)\n const resolvedConfig = config;\n const resolvedAllCollections = allCollectionsConfig;\n\n return (\n <div className=\"fixed inset-0 z-50 bg-background flex flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between border-b px-4 py-2 shrink-0\">\n <div className=\"flex items-center gap-2\">\n <Icon icon=\"ph:eye\" className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"font-medium\">{t(\"preview.livePreview\")}</span>\n </div>\n\n {/* Mobile tabs in header */}\n {isMobile && (\n <Tabs\n value={activeTab}\n onValueChange={(v) => setActiveTab(v as \"form\" | \"preview\")}\n className=\"mx-4\"\n >\n <TabsList className=\"h-8\">\n <TabsTrigger value=\"form\" className=\"text-xs px-3\">\n {t(\"common.form\")}\n </TabsTrigger>\n <TabsTrigger value=\"preview\" className=\"text-xs px-3\">\n {t(\"preview.title\")}\n </TabsTrigger>\n </TabsList>\n </Tabs>\n )}\n\n <div className=\"flex items-center gap-1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleExitPreview}\n className=\"gap-1.5\"\n title=\"Exit preview mode and clear draft cookie\"\n >\n <Icon icon=\"ph:sign-out\" className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">Exit Preview</span>\n </Button>\n <Button variant=\"ghost\" size=\"icon\" onClick={onClose}>\n <Icon icon=\"ph:x\" className=\"h-4 w-4\" />\n <span className=\"sr-only\">{t(\"common.close\")}</span>\n </Button>\n </div>\n </div>\n\n {/* Content */}\n {isMobile ? (\n /* Mobile: Tabs content */\n <div className=\"flex-1 min-h-0\">\n {activeTab === \"form\" ? (\n <div className=\"h-full overflow-y-auto p-6\" data-preview-form-scope>\n <LocaleScopeProvider>\n <FormView\n collection={collection}\n id={itemId}\n config={resolvedConfig}\n allCollectionsConfig={resolvedAllCollections}\n registry={registry}\n navigate={navigate}\n basePath={basePath}\n onSuccess={onSuccess}\n showMeta={false}\n />\n </LocaleScopeProvider>\n </div>\n ) : (\n <div className=\"h-full\">\n <PreviewPane\n ref={previewRef}\n url={previewUrl}\n onFieldClick={handlePreviewFieldClick}\n onBlockClick={handlePreviewBlockClick}\n />\n </div>\n )}\n </div>\n ) : (\n /* Desktop: Side by side */\n <div className=\"flex-1 flex min-h-0\">\n {/* Form panel - fixed width like sheet */}\n <div\n data-preview-form-scope\n className={cn(\n \"h-full border-r bg-background shrink-0\",\n \"w-full sm:max-w-2xl\",\n \"overflow-y-auto p-6\",\n )}\n >\n <LocaleScopeProvider>\n <FormView\n collection={collection}\n id={itemId}\n config={resolvedConfig}\n allCollectionsConfig={resolvedAllCollections}\n registry={registry}\n navigate={navigate}\n basePath={basePath}\n onSuccess={onSuccess}\n showMeta={false}\n />\n </LocaleScopeProvider>\n </div>\n\n {/* Preview panel - fills remaining space */}\n <div className=\"flex-1 min-w-0 bg-muted/30\">\n <PreviewPane\n ref={previewRef}\n url={previewUrl}\n onFieldClick={handlePreviewFieldClick}\n onBlockClick={handlePreviewBlockClick}\n />\n </div>\n </div>\n )}\n </div>\n );\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\nexport function LivePreviewMode({\n open,\n onClose,\n collection,\n itemId,\n config,\n allCollectionsConfig,\n registry,\n previewUrl,\n onSuccess,\n}: LivePreviewModeProps) {\n // Create ref for PreviewPane\n const previewRef = React.useRef<PreviewPaneRef>(null);\n\n // Create context value with refresh callback\n const contextValue = React.useMemo(\n () => ({\n triggerPreviewRefresh: () => {\n previewRef.current?.triggerRefresh();\n },\n }),\n [],\n );\n\n // Handle focus changes from FocusContext - scroll to and focus the field\n const handleFocusChange = React.useCallback((state: FocusState) => {\n if (state.type === \"field\") {\n scrollFieldIntoView(state.fieldPath);\n } else if (state.type === \"block\") {\n // Wait for block form to render before scrolling\n setTimeout(() => {\n const fullPath = state.fieldPath\n ? `content._values.${state.blockId}.${state.fieldPath}`\n : `content._values.${state.blockId}`;\n scrollFieldIntoView(fullPath);\n }, 150);\n }\n }, []);\n\n if (!open) return null;\n\n return (\n <LivePreviewContext.Provider value={contextValue}>\n <FocusProvider onFocusChange={handleFocusChange}>\n <LivePreviewContent\n open={open}\n onClose={onClose}\n collection={collection}\n itemId={itemId}\n config={config}\n allCollectionsConfig={allCollectionsConfig}\n registry={registry}\n previewUrl={previewUrl}\n onSuccess={onSuccess}\n previewRef={previewRef}\n />\n </FocusProvider>\n </LivePreviewContext.Provider>\n );\n}\n\n// ============================================================================\n// Trigger Button Component\n// ============================================================================\n\nexport interface LivePreviewButtonProps {\n onClick: () => void;\n disabled?: boolean;\n}\n\nexport function LivePreviewButton({\n onClick,\n disabled,\n}: LivePreviewButtonProps) {\n return (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n className=\"size-9\"\n onClick={onClick}\n disabled={disabled}\n title=\"Live Preview\"\n >\n <Icon icon=\"ph:eye\" className=\"size-4\" />\n <span className=\"sr-only\">Live Preview</span>\n </Button>\n );\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"preview-pane.mjs","names":["React"],"sources":["../../../../src/client/components/preview/preview-pane.tsx"],"sourcesContent":["/**\n * Preview Pane\n *\n * Admin-side component that renders the preview iframe\n * and handles postMessage communication with the preview page.\n */\n\n\"use client\";\n\nimport { Icon } from \"@iconify/react\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\nimport type {\n AdminToPreviewMessage,\n PreviewToAdminMessage,\n} from \"../../preview/types.js\";\nimport { isPreviewToAdminMessage } from \"../../preview/types.js\";\nimport { selectClient, useAdminStore } from \"../../runtime/index.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type PreviewPaneRef = {\n triggerRefresh: () => void;\n sendFocusToPreview: (fieldPath: string) => void;\n};\n\nexport type PreviewPaneProps = {\n /** Preview URL */\n url: string;\n /** Selected block ID (for block editor integration) */\n selectedBlockId?: string | null;\n /** Field click handler */\n onFieldClick?: (\n fieldPath: string,\n context?: {\n blockId?: string;\n fieldType?: \"regular\" | \"block\" | \"relation\";\n },\n ) => void;\n /** Block click handler */\n onBlockClick?: (blockId: string) => void;\n /** Custom class name */\n className?: string;\n /** Allowed preview origins (for security) */\n allowedOrigins?: string[];\n};\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * Preview pane component for admin.\n *\n * Renders an iframe with the preview page and handles\n * bidirectional communication via postMessage.\n */\nexport const PreviewPane = React.forwardRef<PreviewPaneRef, PreviewPaneProps>(\n (\n {\n url,\n selectedBlockId,\n onFieldClick,\n onBlockClick,\n className,\n allowedOrigins,\n },\n ref,\n ) => {\n const client = useAdminStore(selectClient);\n const iframeRef = React.useRef<HTMLIFrameElement>(null);\n const [isReady, setIsReady] = React.useState(false);\n const [isLoading, setIsLoading] = React.useState(true);\n const [isRefreshing, setIsRefreshing] = React.useState(false);\n const [previewUrl, setPreviewUrl] = React.useState<string | null>(null);\n const [tokenError, setTokenError] = React.useState<string | null>(null);\n\n // Mint preview token when URL changes\n React.useEffect(() => {\n const mintToken = async () => {\n if (!url) {\n setPreviewUrl(null);\n return;\n }\n\n setIsLoading(true);\n setTokenError(null);\n\n try {\n // Use type assertion since the client type may not include mintPreviewToken\n // depending on which modules are used\n const result = await (client as any).rpc.mintPreviewToken({\n path: url,\n ttlMs: 60 * 60 * 1000, // 1 hour\n });\n setPreviewUrl(`/api/preview?token=${result.token}`);\n } catch (error) {\n console.error(\"Failed to mint preview token:\", error);\n setTokenError(\n error instanceof Error\n ? error.message\n : \"Failed to generate preview token\",\n );\n setPreviewUrl(null);\n setIsLoading(false);\n }\n };\n\n mintToken();\n }, [url, client]);\n\n // Validate origin for security\n const isValidOrigin = React.useCallback(\n (origin: string): boolean => {\n if (!allowedOrigins || allowedOrigins.length === 0) {\n // If no origins specified, allow same origin and preview URL origin\n try {\n const previewOrigin = new URL(url).origin;\n return (\n origin === window.location.origin || origin === previewOrigin\n );\n } catch {\n return origin === window.location.origin;\n }\n }\n return allowedOrigins.includes(origin);\n },\n [url, allowedOrigins],\n );\n\n // Send message to preview iframe\n const sendToPreview = React.useCallback(\n (message: AdminToPreviewMessage) => {\n const iframe = iframeRef.current;\n if (!iframe?.contentWindow) return;\n\n try {\n const targetOrigin = new URL(url).origin;\n iframe.contentWindow.postMessage(message, targetOrigin);\n } catch {\n // If URL parsing fails, use wildcard (less secure)\n iframe.contentWindow.postMessage(message, \"*\");\n }\n },\n [url],\n );\n\n // Expose refresh and focus methods via imperative handle\n React.useImperativeHandle(\n ref,\n () => ({\n triggerRefresh: () => {\n if (isReady) {\n setIsRefreshing(true);\n sendToPreview({ type: \"PREVIEW_REFRESH\" });\n }\n },\n sendFocusToPreview: (fieldPath: string) => {\n if (isReady) {\n sendToPreview({ type: \"FOCUS_FIELD\", fieldPath });\n }\n },\n }),\n [isReady, sendToPreview],\n );\n\n // Listen for messages from preview\n React.useEffect(() => {\n const handleMessage = (event: MessageEvent<PreviewToAdminMessage>) => {\n // Validate origin\n if (!isValidOrigin(event.origin)) {\n return;\n }\n\n // Validate message structure\n if (!isPreviewToAdminMessage(event.data)) {\n return;\n }\n\n switch (event.data.type) {\n case \"PREVIEW_READY\":\n setIsReady(true);\n setIsLoading(false);\n break;\n\n case \"REFRESH_COMPLETE\":\n setIsRefreshing(false);\n break;\n\n case \"FIELD_CLICKED\":\n onFieldClick?.(event.data.fieldPath, {\n blockId: event.data.blockId,\n fieldType: event.data.fieldType,\n });\n break;\n\n case \"BLOCK_CLICKED\":\n onBlockClick?.(event.data.blockId);\n break;\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n return () => window.removeEventListener(\"message\", handleMessage);\n }, [isValidOrigin, onFieldClick, onBlockClick]);\n\n // Send selected block updates\n React.useEffect(() => {\n if (isReady && selectedBlockId) {\n sendToPreview({ type: \"SELECT_BLOCK\", blockId: selectedBlockId });\n }\n }, [isReady, selectedBlockId, sendToPreview]);\n\n // Handle iframe load\n const handleLoad = () => {\n // Preview should signal PREVIEW_READY, but set a fallback timeout\n setTimeout(() => {\n if (!isReady) {\n setIsLoading(false);\n }\n }, 3000);\n };\n\n return (\n <div className={cn(\"relative h-full w-full\", className)}>\n {/* Loading overlay */}\n {isLoading && (\n <div className=\"absolute inset-0 z-10 flex items-center justify-center bg-muted/80\">\n <Icon\n icon=\"ph:spinner\"\n className=\"h-6 w-6 animate-spin text-muted-foreground\"\n />\n <span className=\"ml-2 text-sm text-muted-foreground\">\n Loading preview...\n </span>\n </div>\n )}\n\n {/* Error overlay */}\n {tokenError && (\n <div className=\"absolute inset-0 z-10 flex items-center justify-center bg-muted/80\">\n <div className=\"rounded-md bg-destructive/10 border border-destructive px-4 py-3 text-sm text-destructive\">\n <p className=\"font-medium\">Preview Error</p>\n <p>{tokenError}</p>\n </div>\n </div>\n )}\n\n {/* Refreshing indicator */}\n {isRefreshing && !isLoading && (\n <div className=\"absolute top-4 right-4 z-10 flex items-center gap-2 rounded-md bg-background px-3 py-2 shadow-md border\">\n <Icon\n icon=\"ph:spinner\"\n className=\"h-4 w-4 animate-spin text-muted-foreground\"\n />\n <span className=\"text-sm text-muted-foreground\">Refreshing...</span>\n </div>\n )}\n\n {/* Preview iframe */}\n {previewUrl && (\n <iframe\n ref={iframeRef}\n src={previewUrl}\n className=\"h-full w-full border-0\"\n title=\"Preview\"\n onLoad={handleLoad}\n sandbox=\"allow-scripts allow-same-origin allow-forms\"\n />\n )}\n </div>\n );\n },\n);\n\nPreviewPane.displayName = \"PreviewPane\";\n\n// ============================================================================\n// Preview Toggle Button\n// ============================================================================\n\nexport type PreviewToggleButtonProps = {\n /** Whether preview is currently visible */\n isPreviewVisible: boolean;\n /** Toggle handler */\n onToggle: () => void;\n /** Custom class name */\n className?: string;\n};\n\n/**\n * Button to toggle preview pane visibility.\n */\nexport function PreviewToggleButton({\n isPreviewVisible,\n onToggle,\n className,\n}: PreviewToggleButtonProps) {\n return (\n <button\n type=\"button\"\n onClick={onToggle}\n className={cn(\n \"inline-flex items-center gap-2 rounded-md px-3 py-1.5 text-sm\",\n \"border transition-colors\",\n isPreviewVisible\n ? \"border-primary bg-primary/10 text-primary\"\n : \"border-border hover:bg-muted\",\n className,\n )}\n >\n {isPreviewVisible ? \"Hide Preview\" : \"Show Preview\"}\n </button>\n );\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"asset-preview.mjs","names":["React"],"sources":["../../../../src/client/components/primitives/asset-preview.tsx"],"sourcesContent":["/**\n * AssetPreview Primitive\n *\n * Displays an uploaded asset with thumbnail/icon, metadata, and actions.\n * Supports images, videos, PDFs, and other file types.\n *\n * @example\n * ```tsx\n * <AssetPreview\n * asset={asset}\n * onRemove={() => handleRemove(asset.id)}\n * onEdit={() => openEditDialog(asset)}\n * />\n * ```\n */\n\nimport { Icon } from \"@iconify/react\";\nimport * as React from \"react\";\nimport type { Asset } from \"../../hooks/use-upload\";\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../ui/button\";\nimport { Skeleton } from \"../ui/skeleton\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface AssetPreviewProps {\n\t/**\n\t * Asset data (from upload or existing record)\n\t */\n\tasset: Partial<Asset> & {\n\t\tid?: string;\n\t\tfilename?: string;\n\t\tmimeType?: string;\n\t\tsize?: number;\n\t\turl?: string;\n\t\talt?: string | null;\n\t};\n\n\t/**\n\t * Pending file object (for displaying local preview before upload)\n\t */\n\tpendingFile?: File;\n\n\t/**\n\t * Called when remove button is clicked\n\t */\n\tonRemove?: () => void;\n\n\t/**\n\t * Called when edit button is clicked\n\t */\n\tonEdit?: () => void;\n\n\t/**\n\t * Show loading state\n\t */\n\tloading?: boolean;\n\n\t/**\n\t * Upload progress (0-100)\n\t */\n\tprogress?: number;\n\n\t/**\n\t * Whether the preview is disabled\n\t */\n\tdisabled?: boolean;\n\n\t/**\n\t * Whether to show the drag handle (for sortable lists)\n\t */\n\tshowDragHandle?: boolean;\n\n\t/**\n\t * Drag handle props (from dnd-kit)\n\t */\n\tdragHandleProps?: React.HTMLAttributes<HTMLButtonElement>;\n\n\t/**\n\t * Display variant\n\t * @default \"card\"\n\t */\n\tvariant?: \"card\" | \"compact\" | \"thumbnail\";\n\n\t/**\n\t * Link to asset detail page (makes the preview clickable)\n\t */\n\thref?: string;\n\n\t/**\n\t * Called when the preview is clicked\n\t */\n\tonClick?: (id: string) => void;\n\n\t/**\n\t * Additional className\n\t */\n\tclassName?: string;\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Get icon name based on MIME type\n */\nfunction getFileIconName(mimeType?: string): string {\n\tif (!mimeType) return \"ph:file\";\n\n\tconst type = mimeType.toLowerCase();\n\n\tif (type.startsWith(\"image/\")) return \"ph:file-image\";\n\tif (type.startsWith(\"video/\")) return \"ph:file-video\";\n\tif (type.startsWith(\"audio/\")) return \"ph:file-audio\";\n\tif (type === \"application/pdf\") return \"ph:file-pdf\";\n\tif (\n\t\ttype.includes(\"zip\") ||\n\t\ttype.includes(\"compressed\") ||\n\t\ttype.includes(\"archive\")\n\t)\n\t\treturn \"ph:file-zip\";\n\tif (type.includes(\"csv\") || type.includes(\"spreadsheet\"))\n\t\treturn \"ph:file-csv\";\n\tif (\n\t\ttype.includes(\"word\") ||\n\t\ttype.includes(\"document\") ||\n\t\ttype === \"application/rtf\"\n\t)\n\t\treturn \"ph:file-doc\";\n\tif (\n\t\ttype.includes(\"json\") ||\n\t\ttype.includes(\"javascript\") ||\n\t\ttype.includes(\"typescript\") ||\n\t\ttype.includes(\"xml\") ||\n\t\ttype.includes(\"html\")\n\t)\n\t\treturn \"ph:file-code\";\n\n\treturn \"ph:file\";\n}\n\n/**\n * Check if MIME type is an image\n */\nfunction isImage(mimeType?: string): boolean {\n\treturn !!mimeType?.toLowerCase().startsWith(\"image/\");\n}\n\n/**\n * Format file size for display\n */\nfunction formatFileSize(bytes?: number): string {\n\tif (!bytes) return \"\";\n\tif (bytes < 1024) return `${bytes} B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\n/**\n * Get file extension from filename or MIME type\n */\nfunction getExtension(filename?: string, mimeType?: string): string {\n\tif (filename) {\n\t\tconst parts = filename.split(\".\");\n\t\tif (parts.length > 1) {\n\t\t\treturn parts[parts.length - 1].toUpperCase();\n\t\t}\n\t}\n\tif (mimeType) {\n\t\tconst parts = mimeType.split(\"/\");\n\t\treturn parts[parts.length - 1].toUpperCase();\n\t}\n\treturn \"\";\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function AssetPreview({\n\tasset,\n\tpendingFile,\n\tonRemove,\n\tonEdit,\n\tloading = false,\n\tprogress,\n\tdisabled = false,\n\tshowDragHandle = false,\n\tdragHandleProps,\n\tvariant = \"card\",\n\thref,\n\tonClick,\n\tclassName,\n}: AssetPreviewProps) {\n\tconst [imageError, setImageError] = React.useState(false);\n\n\t// Check if we have actual asset data or just an ID (loading state)\n\tconst hasAssetData = !!(asset.filename || asset.url || pendingFile);\n\tconst isLoadingAsset = loading && !hasAssetData;\n\n\t// Get display values\n\tconst filename = asset.filename || pendingFile?.name || \"Unknown file\";\n\tconst mimeType = asset.mimeType || pendingFile?.type;\n\tconst size = asset.size || pendingFile?.size;\n\tconst isImageType = isImage(mimeType);\n\tconst fileIconName = getFileIconName(mimeType);\n\tconst extension = getExtension(filename, mimeType);\n\n\t// Build thumbnail URL\n\tconst thumbnailUrl = React.useMemo(() => {\n\t\t// If we have a pending file, create object URL\n\t\tif (pendingFile && isImageType) {\n\t\t\treturn URL.createObjectURL(pendingFile);\n\t\t}\n\t\t// If we have an asset URL and it's an image\n\t\tif (asset.url && isImageType) {\n\t\t\treturn asset.url;\n\t\t}\n\t\treturn null;\n\t}, [pendingFile, asset.url, isImageType]);\n\n\t// Clean up object URL on unmount\n\tReact.useEffect(() => {\n\t\treturn () => {\n\t\t\tif (pendingFile && thumbnailUrl) {\n\t\t\t\tURL.revokeObjectURL(thumbnailUrl);\n\t\t\t}\n\t\t};\n\t}, [pendingFile, thumbnailUrl]);\n\n\t// Thumbnail variant\n\tif (variant === \"thumbnail\") {\n\t\t// Show skeleton when loading and no actual asset data\n\t\tif (isLoadingAsset) {\n\t\t\treturn (\n\t\t\t\t<Skeleton\n\t\t\t\t\tclassName={cn(\"aspect-square w-full rounded-lg\", className)}\n\t\t\t\t/>\n\t\t\t);\n\t\t}\n\n\t\tconst content = (\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"group relative aspect-square overflow-hidden rounded-lg border\",\n\t\t\t\t\t\"bg-muted/30 border-border/60\",\n\t\t\t\t\tdisabled && \"opacity-60\",\n\t\t\t\t\tonClick && !disabled && \"cursor-pointer hover:border-border\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tonClick={\n\t\t\t\t\tonClick && !disabled && asset.id\n\t\t\t\t\t\t? () => onClick(asset.id!)\n\t\t\t\t\t\t: undefined\n\t\t\t\t}\n\t\t\t>\n\t\t\t\t{/* Thumbnail or icon */}\n\t\t\t\t{thumbnailUrl && !imageError ? (\n\t\t\t\t\t<img\n\t\t\t\t\t\tsrc={thumbnailUrl}\n\t\t\t\t\t\talt={asset.alt || filename}\n\t\t\t\t\t\tclassName=\"h-full w-full object-cover\"\n\t\t\t\t\t\tonError={() => setImageError(true)}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<div className=\"flex h-full w-full items-center justify-center\">\n\t\t\t\t\t\t<Icon\n\t\t\t\t\t\t\ticon={fileIconName}\n\t\t\t\t\t\t\tclassName=\"text-muted-foreground size-8\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Loading overlay */}\n\t\t\t\t{loading && (\n\t\t\t\t\t<div className=\"bg-background/80 absolute inset-0 flex items-center justify-center\">\n\t\t\t\t\t\t<div className=\"relative\">\n\t\t\t\t\t\t\t<Icon\n\t\t\t\t\t\t\t\ticon=\"ph:spinner-gap\"\n\t\t\t\t\t\t\t\tclassName=\"text-muted-foreground size-6 animate-spin\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t{typeof progress === \"number\" && (\n\t\t\t\t\t\t\t\t<span className=\"text-muted-foreground absolute inset-0 flex items-center justify-center text-[10px] font-medium\">\n\t\t\t\t\t\t\t\t\t{progress}%\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Action buttons (visible on hover) */}\n\t\t\t\t{!loading && !disabled && (onRemove || onEdit || href) && (\n\t\t\t\t\t<div className=\"absolute inset-0 flex items-center justify-center gap-1 bg-black/50 opacity-0 transition-opacity group-hover:opacity-100\">\n\t\t\t\t\t\t{href && (\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\t\t\tsize=\"icon-xs\"\n\t\t\t\t\t\t\t\tnativeButton={false}\n\t\t\t\t\t\t\t\trender={<a href={href} onClick={(e) => e.stopPropagation()} />}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon icon=\"ph:arrow-square-out-bold\" />\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{onEdit && (\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\t\t\tsize=\"icon-xs\"\n\t\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\tonEdit();\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon icon=\"ph:pencil-bold\" />\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{onRemove && (\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tvariant=\"destructive\"\n\t\t\t\t\t\t\t\tsize=\"icon-xs\"\n\t\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\tonRemove();\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon icon=\"ph:trash-bold\" />\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t);\n\n\t\treturn content;\n\t}\n\n\t// Compact variant\n\tif (variant === \"compact\") {\n\t\t// Show skeleton when loading and no actual asset data\n\t\tif (isLoadingAsset) {\n\t\t\treturn (\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"flex items-center gap-2 rounded-md border p-2\",\n\t\t\t\t\t\t\"bg-muted/30 border-border/60\",\n\t\t\t\t\t\tclassName,\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t{showDragHandle && <Skeleton className=\"size-4 -ml-1 rounded\" />}\n\t\t\t\t\t<Skeleton className=\"size-8 shrink-0 rounded\" />\n\t\t\t\t\t<div className=\"min-w-0 flex-1 space-y-1.5\">\n\t\t\t\t\t\t<Skeleton className=\"h-4 w-32 rounded\" />\n\t\t\t\t\t\t<Skeleton className=\"h-3 w-16 rounded\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"group flex items-center gap-2 rounded-md border p-2\",\n\t\t\t\t\t\"bg-muted/30 border-border/60\",\n\t\t\t\t\tdisabled && \"opacity-60\",\n\t\t\t\t\tonClick && !disabled && \"cursor-pointer hover:border-border\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tonClick={\n\t\t\t\t\tonClick && !disabled && asset.id\n\t\t\t\t\t\t? () => onClick(asset.id!)\n\t\t\t\t\t\t: undefined\n\t\t\t\t}\n\t\t\t>\n\t\t\t\t{/* Drag handle */}\n\t\t\t\t{showDragHandle && (\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"text-muted-foreground hover:text-foreground -ml-1 cursor-grab touch-none active:cursor-grabbing\"\n\t\t\t\t\t\t{...dragHandleProps}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Icon icon=\"ph:dots-six-vertical-bold\" className=\"size-4\" />\n\t\t\t\t\t</button>\n\t\t\t\t)}\n\n\t\t\t\t{/* Icon or thumbnail */}\n\t\t\t\t<div className=\"bg-muted flex size-8 shrink-0 items-center justify-center overflow-hidden rounded\">\n\t\t\t\t\t{thumbnailUrl && !imageError ? (\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tsrc={thumbnailUrl}\n\t\t\t\t\t\t\talt={asset.alt || filename}\n\t\t\t\t\t\t\tclassName=\"h-full w-full object-cover\"\n\t\t\t\t\t\t\tonError={() => setImageError(true)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Icon\n\t\t\t\t\t\t\ticon={fileIconName}\n\t\t\t\t\t\t\tclassName=\"text-muted-foreground size-4\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\n\t\t\t\t{/* File info */}\n\t\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t\t<p className=\"truncate text-sm font-medium\">{filename}</p>\n\t\t\t\t\t{size && (\n\t\t\t\t\t\t<p className=\"text-muted-foreground text-xs\">\n\t\t\t\t\t\t\t{formatFileSize(size)}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\n\t\t\t\t{/* Loading indicator */}\n\t\t\t\t{loading && (\n\t\t\t\t\t<Icon\n\t\t\t\t\t\ticon=\"ph:spinner-gap\"\n\t\t\t\t\t\tclassName=\"text-muted-foreground size-4 shrink-0 animate-spin\"\n\t\t\t\t\t/>\n\t\t\t\t)}\n\n\t\t\t\t{/* Action buttons */}\n\t\t\t\t{!loading && !disabled && (href || onEdit || onRemove) && (\n\t\t\t\t\t<div className=\"flex shrink-0 items-center gap-1\">\n\t\t\t\t\t\t{href && (\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\tsize=\"icon-xs\"\n\t\t\t\t\t\t\t\tnativeButton={false}\n\t\t\t\t\t\t\t\trender={<a href={href} onClick={(e) => e.stopPropagation()} />}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon icon=\"ph:arrow-square-out-bold\" />\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{onEdit && (\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\tsize=\"icon-xs\"\n\t\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\tonEdit();\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon icon=\"ph:pencil-bold\" />\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{onRemove && (\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\tsize=\"icon-xs\"\n\t\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\tonRemove();\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tclassName=\"text-destructive hover:text-destructive\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon icon=\"ph:x-bold\" />\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Card variant (default)\n\t// Show skeleton when loading and no actual asset data\n\tif (isLoadingAsset) {\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"overflow-hidden rounded-lg border\",\n\t\t\t\t\t\"bg-muted/30 border-border/60\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t<Skeleton className=\"aspect-video w-full\" />\n\t\t\t\t<div className=\"space-y-1.5 p-3\">\n\t\t\t\t\t<Skeleton className=\"h-4 w-3/4 rounded\" />\n\t\t\t\t\t<Skeleton className=\"h-3 w-1/2 rounded\" />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"group relative overflow-hidden rounded-lg border\",\n\t\t\t\t\"bg-muted/30 border-border/60\",\n\t\t\t\tdisabled && \"opacity-60\",\n\t\t\t\tonClick && !disabled && \"cursor-pointer hover:border-border\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tonClick={\n\t\t\t\tonClick && !disabled && asset.id ? () => onClick(asset.id!) : undefined\n\t\t\t}\n\t\t>\n\t\t\t{/* Drag handle */}\n\t\t\t{showDragHandle && (\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"text-muted-foreground hover:text-foreground absolute left-2 top-2 z-10 cursor-grab touch-none rounded p-1 active:cursor-grabbing\"\n\t\t\t\t\t{...dragHandleProps}\n\t\t\t\t>\n\t\t\t\t\t<Icon icon=\"ph:dots-six-vertical-bold\" className=\"size-4\" />\n\t\t\t\t</button>\n\t\t\t)}\n\n\t\t\t{/* Thumbnail area */}\n\t\t\t<div className=\"bg-muted/50 relative aspect-video w-full\">\n\t\t\t\t{thumbnailUrl && !imageError ? (\n\t\t\t\t\t<img\n\t\t\t\t\t\tsrc={thumbnailUrl}\n\t\t\t\t\t\talt={asset.alt || filename}\n\t\t\t\t\t\tclassName=\"h-full w-full object-contain\"\n\t\t\t\t\t\tonError={() => setImageError(true)}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<div className=\"flex h-full w-full flex-col items-center justify-center gap-2\">\n\t\t\t\t\t\t<Icon\n\t\t\t\t\t\t\ticon={fileIconName}\n\t\t\t\t\t\t\tclassName=\"text-muted-foreground size-12\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{extension && (\n\t\t\t\t\t\t\t<span className=\"bg-muted text-muted-foreground rounded px-2 py-0.5 text-xs font-medium\">\n\t\t\t\t\t\t\t\t{extension}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Loading overlay */}\n\t\t\t\t{loading && (\n\t\t\t\t\t<div className=\"bg-background/80 absolute inset-0 flex flex-col items-center justify-center gap-2\">\n\t\t\t\t\t\t<Icon\n\t\t\t\t\t\t\ticon=\"ph:spinner-gap\"\n\t\t\t\t\t\t\tclassName=\"text-muted-foreground size-8 animate-spin\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{typeof progress === \"number\" && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<span className=\"text-muted-foreground text-sm font-medium\">\n\t\t\t\t\t\t\t\t\t{progress}%\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<div className=\"bg-muted h-1.5 w-24 overflow-hidden rounded-full\">\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tclassName=\"bg-primary h-full rounded-full transition-all duration-300\"\n\t\t\t\t\t\t\t\t\t\tstyle={{ width: `${progress}%` }}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Remove button (top right) */}\n\t\t\t\t{!loading && !disabled && onRemove && (\n\t\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\tsize=\"icon-xs\"\n\t\t\t\t\t\tclassName=\"absolute right-2 top-2 opacity-0 transition-opacity group-hover:opacity-100\"\n\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\tonRemove();\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Icon icon=\"ph:x-bold\" />\n\t\t\t\t\t</Button>\n\t\t\t\t)}\n\t\t\t</div>\n\n\t\t\t{/* File info footer */}\n\t\t\t<div className=\"flex items-center gap-2 border-t p-2\">\n\t\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t\t<p className=\"truncate text-sm font-medium\" title={filename}>\n\t\t\t\t\t\t{filename}\n\t\t\t\t\t</p>\n\t\t\t\t\t<p className=\"text-muted-foreground text-xs\">\n\t\t\t\t\t\t{formatFileSize(size)}\n\t\t\t\t\t\t{mimeType && ` • ${mimeType.split(\"/\")[1]?.toUpperCase()}`}\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\n\t\t\t\t{/* Action buttons */}\n\t\t\t\t{!loading && !disabled && (href || onEdit) && (\n\t\t\t\t\t<div className=\"flex items-center gap-1\">\n\t\t\t\t\t\t{href && (\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\tsize=\"icon-sm\"\n\t\t\t\t\t\t\t\tnativeButton={false}\n\t\t\t\t\t\t\t\trender={\n\t\t\t\t\t\t\t\t\t// biome-ignore lint/a11y/useAnchorContent: TODO: improve accessibility\n\t\t\t\t\t\t\t\t\t<a href={href} onClick={(e) => e.stopPropagation()} />\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon icon=\"ph:arrow-square-out-bold\" />\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{onEdit && (\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\tsize=\"icon-sm\"\n\t\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\tonEdit();\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon icon=\"ph:pencil-bold\" />\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"checkbox-input.mjs","names":[],"sources":["../../../../src/client/components/primitives/checkbox-input.tsx"],"sourcesContent":["\"use client\";\n\nimport { useResolveText } from \"../../i18n/hooks\";\nimport { cn } from \"../../lib/utils\";\nimport { Checkbox } from \"../ui/checkbox\";\nimport type {\n CheckboxGroupProps,\n CheckboxInputProps,\n RadioGroupProps,\n} from \"./types\";\n\n/**\n * Checkbox Input Primitive\n *\n * A single checkbox with value/onChange pattern.\n *\n * @example\n * ```tsx\n * <CheckboxInput\n * value={isAccepted}\n * onChange={setIsAccepted}\n * />\n * ```\n */\nexport function CheckboxInput({\n value,\n onChange,\n disabled,\n className,\n id,\n \"aria-invalid\": ariaInvalid,\n}: CheckboxInputProps) {\n return (\n <Checkbox\n id={id}\n checked={value}\n onCheckedChange={(checked) => onChange(checked === true)}\n disabled={disabled}\n aria-invalid={ariaInvalid}\n className={className}\n />\n );\n}\n\n/**\n * Checkbox Group Primitive\n *\n * A group of checkboxes for multi-selection.\n * Returns an array of selected values.\n *\n * @example\n * ```tsx\n * <CheckboxGroup\n * value={selectedCategories}\n * onChange={setSelectedCategories}\n * options={[\n * { value: \"news\", label: \"News\" },\n * { value: \"blog\", label: \"Blog\" },\n * { value: \"tutorial\", label: \"Tutorial\" },\n * ]}\n * orientation=\"vertical\"\n * />\n * ```\n */\nexport function CheckboxGroup<TValue extends string = string>({\n value,\n onChange,\n options,\n orientation = \"vertical\",\n disabled,\n className,\n id,\n \"aria-invalid\": ariaInvalid,\n}: CheckboxGroupProps<TValue>) {\n const resolveText = useResolveText();\n const handleChange = (optionValue: TValue, checked: boolean) => {\n if (checked) {\n onChange([...value, optionValue]);\n } else {\n onChange(value.filter((v) => v !== optionValue));\n }\n };\n\n return (\n <div\n id={id}\n role=\"group\"\n aria-invalid={ariaInvalid}\n className={cn(\n \"flex gap-3\",\n orientation === \"vertical\" ? \"flex-col\" : \"flex-row flex-wrap\",\n className,\n )}\n >\n {options.map((option) => {\n const optionId = `${id}-${String(option.value)}`;\n return (\n <div\n key={String(option.value)}\n className={cn(\n \"flex items-center gap-2\",\n option.disabled || disabled\n ? \"opacity-50 cursor-not-allowed\"\n : \"cursor-pointer\",\n )}\n >\n <CheckboxInput\n id={optionId}\n value={value.includes(option.value)}\n onChange={(checked) => handleChange(option.value, checked)}\n disabled={option.disabled || disabled}\n />\n <label htmlFor={optionId} className=\"text-sm cursor-pointer\">\n {resolveText(option.label)}\n </label>\n </div>\n );\n })}\n </div>\n );\n}\n\n/**\n * Radio Group Primitive\n *\n * A group of radio buttons for single selection.\n * Returns the selected value or null.\n *\n * @example\n * ```tsx\n * <RadioGroup\n * value={selectedPriority}\n * onChange={setSelectedPriority}\n * options={[\n * { value: \"low\", label: \"Low\" },\n * { value: \"medium\", label: \"Medium\" },\n * { value: \"high\", label: \"High\" },\n * ]}\n * />\n * ```\n */\nexport function RadioGroup<TValue extends string = string>({\n value,\n onChange,\n options,\n orientation = \"vertical\",\n disabled,\n className,\n id,\n \"aria-invalid\": ariaInvalid,\n}: RadioGroupProps<TValue>) {\n const resolveText = useResolveText();\n return (\n <div\n id={id}\n role=\"radiogroup\"\n aria-invalid={ariaInvalid}\n className={cn(\n \"flex gap-3\",\n orientation === \"vertical\" ? \"flex-col\" : \"flex-row flex-wrap\",\n className,\n )}\n >\n {options.map((option) => {\n const optionId = `${id}-${String(option.value)}`;\n return (\n <div\n key={String(option.value)}\n className={cn(\n \"flex items-center gap-2\",\n option.disabled || disabled\n ? \"opacity-50 cursor-not-allowed\"\n : \"cursor-pointer\",\n )}\n >\n <input\n type=\"radio\"\n id={optionId}\n name={id}\n checked={value === option.value}\n onChange={() => onChange(option.value)}\n disabled={option.disabled || disabled}\n className={cn(\n \"size-4 shrink-0 accent-primary\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n )}\n />\n <label htmlFor={optionId} className=\"text-sm cursor-pointer\">\n {resolveText(option.label)}\n </label>\n </div>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAwBA,SAAgB,cAAc,EAC5B,OACA,UACA,UACA,WACA,IACA,gBAAgB,eACK;AACrB,QACE,oBAAC;EACK;EACJ,SAAS;EACT,kBAAkB,YAAY,SAAS,YAAY,KAAK;EAC9C;EACV,gBAAc;EACH;GACX"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"date-input.mjs","names":[],"sources":["../../../../src/client/components/primitives/date-input.tsx"],"sourcesContent":["\"use client\";\n\nimport { Icon } from \"@iconify/react\";\nimport { format } from \"date-fns\";\nimport { useState } from \"react\";\nimport { DayPicker } from \"react-day-picker\";\nimport { useResolveText } from \"../../i18n/hooks\";\nimport { cn } from \"../../lib/utils\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../ui/popover\";\nimport type {\n DateInputProps,\n DateRangeInputProps,\n DateTimeInputProps,\n} from \"./types\";\n\n/**\n * Date Input Primitive\n *\n * A date picker with popover calendar.\n * Uses react-day-picker under the hood.\n *\n * @example\n * ```tsx\n * <DateInput\n * value={selectedDate}\n * onChange={setSelectedDate}\n * placeholder=\"Select date\"\n * />\n * ```\n */\nexport function DateInput({\n value,\n onChange,\n minDate,\n maxDate,\n format: dateFormat = \"PP\",\n placeholder = \"Select date\",\n disabled,\n className,\n id,\n \"aria-invalid\": ariaInvalid,\n}: DateInputProps) {\n const resolveText = useResolveText();\n const [open, setOpen] = useState(false);\n\n const handleSelect = (date: Date | undefined) => {\n onChange(date ?? null);\n setOpen(false);\n };\n\n const handleClear = (e: React.MouseEvent) => {\n e.stopPropagation();\n onChange(null);\n };\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger\n id={id}\n disabled={disabled}\n aria-invalid={ariaInvalid}\n className={cn(\n \"flex h-9 w-full items-center justify-start gap-2 border border-input/80 bg-input/20 backdrop-blur-sm px-3 py-2 text-sm\",\n \"hover:bg-accent hover:text-accent-foreground\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n !value && \"text-muted-foreground\",\n className,\n )}\n >\n <Icon icon=\"ph:calendar-blank\" className=\"size-4\" />\n <span className=\"flex-1 text-left\">\n {value ? format(value, dateFormat) : resolveText(placeholder)}\n </span>\n {value && !disabled && (\n <Icon\n icon=\"ph:x\"\n className=\"size-4 opacity-50 hover:opacity-100\"\n onClick={handleClear}\n />\n )}\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <DayPicker\n mode=\"single\"\n selected={value ?? undefined}\n onSelect={handleSelect}\n disabled={(date) => {\n if (minDate && date < minDate) return true;\n if (maxDate && date > maxDate) return true;\n return false;\n }}\n className=\"p-3\"\n classNames={{\n months: \"flex flex-col sm:flex-row gap-2\",\n month: \"flex flex-col gap-4\",\n month_caption: \"flex justify-center pt-1 relative items-center h-9\",\n caption_label: \"text-sm font-medium\",\n nav: \"absolute inset-x-0 top-0 flex items-center justify-between px-1\",\n button_previous: cn(\n \"size-8 flex items-center justify-center rounded-md\",\n \"bg-transparent p-0 opacity-50 hover:opacity-100 hover:bg-accent\",\n ),\n button_next: cn(\n \"size-8 flex items-center justify-center rounded-md\",\n \"bg-transparent p-0 opacity-50 hover:opacity-100 hover:bg-accent\",\n ),\n month_grid: \"w-full border-collapse\",\n weekdays: \"flex\",\n weekday:\n \"text-muted-foreground w-9 font-normal text-[0.8rem] text-center\",\n week: \"flex w-full mt-2\",\n day: \"relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50\",\n day_button: cn(\n \"size-9 p-0 font-normal rounded-md\",\n \"hover:bg-accent hover:text-accent-foreground\",\n \"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n ),\n selected:\n \"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground rounded-md\",\n today: \"bg-accent text-accent-foreground\",\n outside: \"text-muted-foreground opacity-50\",\n disabled: \"text-muted-foreground opacity-50\",\n hidden: \"invisible\",\n }}\n />\n </PopoverContent>\n </Popover>\n );\n}\n\n/**\n * DateTime Input Primitive\n *\n * A date and time picker.\n *\n * @example\n * ```tsx\n * <DateTimeInput\n * value={scheduledAt}\n * onChange={setScheduledAt}\n * precision=\"minute\"\n * />\n * ```\n */\nexport function DateTimeInput({\n value,\n onChange,\n minDate,\n maxDate,\n format: dateFormat = \"PPp\",\n precision = \"minute\",\n placeholder = \"Select date and time\",\n disabled,\n className,\n id,\n \"aria-invalid\": ariaInvalid,\n}: DateTimeInputProps) {\n const resolveText = useResolveText();\n const [open, setOpen] = useState(false);\n const [timeValue, setTimeValue] = useState(() => {\n if (!value) return \"\";\n return precision === \"second\"\n ? format(value, \"HH:mm:ss\")\n : format(value, \"HH:mm\");\n });\n\n const handleDateSelect = (date: Date | undefined) => {\n if (!date) {\n onChange(null);\n return;\n }\n\n // Preserve existing time if available\n if (timeValue) {\n const [hours, minutes, seconds] = timeValue.split(\":\").map(Number);\n date.setHours(hours || 0, minutes || 0, seconds || 0);\n }\n onChange(date);\n };\n\n const handleTimeChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const time = e.target.value;\n setTimeValue(time);\n\n if (value && time) {\n const [hours, minutes, seconds] = time.split(\":\").map(Number);\n const newDate = new Date(value);\n newDate.setHours(hours || 0, minutes || 0, seconds || 0);\n onChange(newDate);\n }\n };\n\n const handleClear = (e: React.MouseEvent) => {\n e.stopPropagation();\n onChange(null);\n setTimeValue(\"\");\n };\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger\n id={id}\n disabled={disabled}\n aria-invalid={ariaInvalid}\n className={cn(\n \"flex h-9 w-full items-center justify-start gap-2 border border-input/80 bg-input/20 backdrop-blur-sm px-3 py-2 text-sm\",\n \"hover:bg-accent hover:text-accent-foreground\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n !value && \"text-muted-foreground\",\n className,\n )}\n >\n <Icon icon=\"ph:calendar-blank\" className=\"size-4\" />\n <span className=\"flex-1 text-left\">\n {value ? format(value, dateFormat) : resolveText(placeholder)}\n </span>\n {value && !disabled && (\n <Icon\n icon=\"ph:x\"\n className=\"size-4 opacity-50 hover:opacity-100\"\n onClick={handleClear}\n />\n )}\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <DayPicker\n mode=\"single\"\n selected={value ?? undefined}\n onSelect={handleDateSelect}\n disabled={(date) => {\n if (minDate && date < minDate) return true;\n if (maxDate && date > maxDate) return true;\n return false;\n }}\n className=\"p-3\"\n classNames={{\n months: \"flex flex-col sm:flex-row gap-2\",\n month: \"flex flex-col gap-4\",\n month_caption: \"flex justify-center pt-1 relative items-center h-9\",\n caption_label: \"text-sm font-medium\",\n nav: \"absolute inset-x-0 top-0 flex items-center justify-between px-1\",\n button_previous: cn(\n \"size-8 flex items-center justify-center rounded-md\",\n \"bg-transparent p-0 opacity-50 hover:opacity-100 hover:bg-accent\",\n ),\n button_next: cn(\n \"size-8 flex items-center justify-center rounded-md\",\n \"bg-transparent p-0 opacity-50 hover:opacity-100 hover:bg-accent\",\n ),\n month_grid: \"w-full border-collapse\",\n weekdays: \"flex\",\n weekday:\n \"text-muted-foreground w-9 font-normal text-[0.8rem] text-center\",\n week: \"flex w-full mt-2\",\n day: \"relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50\",\n day_button: cn(\n \"size-9 p-0 font-normal rounded-md\",\n \"hover:bg-accent hover:text-accent-foreground\",\n \"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n ),\n selected:\n \"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground rounded-md\",\n today: \"bg-accent text-accent-foreground\",\n outside: \"text-muted-foreground opacity-50\",\n disabled: \"text-muted-foreground opacity-50\",\n hidden: \"invisible\",\n }}\n />\n <div className=\"border-t border-border p-3\">\n <input\n type=\"time\"\n step={precision === \"second\" ? 1 : 60}\n value={timeValue}\n onChange={handleTimeChange}\n className={cn(\n \"flex h-9 w-full border border-input/80 bg-input/20 backdrop-blur-sm px-3 py-2 text-sm\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n )}\n />\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\n/**\n * Date Range Input Primitive\n *\n * A date range picker for selecting start and end dates.\n *\n * @example\n * ```tsx\n * <DateRangeInput\n * value={{ start: startDate, end: endDate }}\n * onChange={setDateRange}\n * />\n * ```\n */\nexport function DateRangeInput({\n value,\n onChange,\n minDate,\n maxDate,\n placeholder = \"Select date range\",\n disabled,\n className,\n id,\n \"aria-invalid\": ariaInvalid,\n}: DateRangeInputProps) {\n const resolveText = useResolveText();\n const [open, setOpen] = useState(false);\n\n const handleSelect = (range: { from?: Date; to?: Date } | undefined) => {\n onChange({\n start: range?.from ?? null,\n end: range?.to ?? null,\n });\n };\n\n const handleClear = (e: React.MouseEvent) => {\n e.stopPropagation();\n onChange({ start: null, end: null });\n };\n\n const displayValue = () => {\n if (!value.start && !value.end) return resolveText(placeholder);\n if (value.start && value.end) {\n return `${format(value.start, \"PP\")} - ${format(value.end, \"PP\")}`;\n }\n if (value.start) return `${format(value.start, \"PP\")} - ...`;\n return resolveText(placeholder);\n };\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger\n id={id}\n disabled={disabled}\n aria-invalid={ariaInvalid}\n className={cn(\n \"flex h-9 w-full items-center justify-start gap-2 border border-input/80 bg-input/20 backdrop-blur-sm px-3 py-2 text-sm\",\n \"hover:bg-accent hover:text-accent-foreground\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n !value.start && !value.end && \"text-muted-foreground\",\n className,\n )}\n >\n <Icon icon=\"ph:calendar-blank\" className=\"size-4\" />\n <span className=\"flex-1 text-left\">{displayValue()}</span>\n {(value.start || value.end) && !disabled && (\n <Icon\n icon=\"ph:x\"\n className=\"size-4 opacity-50 hover:opacity-100\"\n onClick={handleClear}\n />\n )}\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <DayPicker\n mode=\"range\"\n selected={\n value.start || value.end\n ? { from: value.start ?? undefined, to: value.end ?? undefined }\n : undefined\n }\n onSelect={handleSelect}\n numberOfMonths={2}\n disabled={(date) => {\n if (minDate && date < minDate) return true;\n if (maxDate && date > maxDate) return true;\n return false;\n }}\n className=\"p-3\"\n classNames={{\n months: \"flex flex-col sm:flex-row gap-4\",\n month: \"flex flex-col gap-4\",\n month_caption: \"flex justify-center pt-1 relative items-center h-9\",\n caption_label: \"text-sm font-medium\",\n nav: \"absolute inset-x-0 top-0 flex items-center justify-between px-1\",\n button_previous: cn(\n \"size-8 flex items-center justify-center rounded-md\",\n \"bg-transparent p-0 opacity-50 hover:opacity-100 hover:bg-accent\",\n ),\n button_next: cn(\n \"size-8 flex items-center justify-center rounded-md\",\n \"bg-transparent p-0 opacity-50 hover:opacity-100 hover:bg-accent\",\n ),\n month_grid: \"w-full border-collapse\",\n weekdays: \"flex\",\n weekday:\n \"text-muted-foreground w-9 font-normal text-[0.8rem] text-center\",\n week: \"flex w-full mt-2\",\n day: \"relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50\",\n day_button: cn(\n \"size-9 p-0 font-normal rounded-md\",\n \"hover:bg-accent hover:text-accent-foreground\",\n \"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n ),\n selected:\n \"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground rounded-md\",\n range_start: \"rounded-l-md\",\n range_end: \"rounded-r-md\",\n range_middle: \"bg-accent\",\n today: \"bg-accent text-accent-foreground\",\n outside: \"text-muted-foreground opacity-50\",\n disabled: \"text-muted-foreground opacity-50\",\n hidden: \"invisible\",\n }}\n />\n </PopoverContent>\n </Popover>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,SAAgB,UAAU,EACxB,OACA,UACA,SACA,SACA,QAAQ,aAAa,MACrB,cAAc,eACd,UACA,WACA,IACA,gBAAgB,eACC;CACjB,MAAM,cAAc,gBAAgB;CACpC,MAAM,CAAC,MAAM,WAAW,SAAS,MAAM;CAEvC,MAAM,gBAAgB,SAA2B;AAC/C,WAAS,QAAQ,KAAK;AACtB,UAAQ,MAAM;;CAGhB,MAAM,eAAe,MAAwB;AAC3C,IAAE,iBAAiB;AACnB,WAAS,KAAK;;AAGhB,QACE,qBAAC;EAAc;EAAM,cAAc;aACjC,qBAAC;GACK;GACM;GACV,gBAAc;GACd,WAAW,GACT,0HACA,gDACA,uGACA,mDACA,CAAC,SAAS,yBACV,UACD;;IAED,oBAAC;KAAK,MAAK;KAAoB,WAAU;MAAW;IACpD,oBAAC;KAAK,WAAU;eACb,QAAQ,OAAO,OAAO,WAAW,GAAG,YAAY,YAAY;MACxD;IACN,SAAS,CAAC,YACT,oBAAC;KACC,MAAK;KACL,WAAU;KACV,SAAS;MACT;;IAEW,EACjB,oBAAC;GAAe,WAAU;GAAa,OAAM;aAC3C,oBAAC;IACC,MAAK;IACL,UAAU,SAAS;IACnB,UAAU;IACV,WAAW,SAAS;AAClB,SAAI,WAAW,OAAO,QAAS,QAAO;AACtC,SAAI,WAAW,OAAO,QAAS,QAAO;AACtC,YAAO;;IAET,WAAU;IACV,YAAY;KACV,QAAQ;KACR,OAAO;KACP,eAAe;KACf,eAAe;KACf,KAAK;KACL,iBAAiB,GACf,sDACA,kEACD;KACD,aAAa,GACX,sDACA,kEACD;KACD,YAAY;KACZ,UAAU;KACV,SACE;KACF,MAAM;KACN,KAAK;KACL,YAAY,GACV,qCACA,gDACA,2EACD;KACD,UACE;KACF,OAAO;KACP,SAAS;KACT,UAAU;KACV,QAAQ;KACT;KACD;IACa;GACT;;;;;;;;;;;;;;;;AAkBd,SAAgB,cAAc,EAC5B,OACA,UACA,SACA,SACA,QAAQ,aAAa,OACrB,YAAY,UACZ,cAAc,wBACd,UACA,WACA,IACA,gBAAgB,eACK;CACrB,MAAM,cAAc,gBAAgB;CACpC,MAAM,CAAC,MAAM,WAAW,SAAS,MAAM;CACvC,MAAM,CAAC,WAAW,gBAAgB,eAAe;AAC/C,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,cAAc,WACjB,OAAO,OAAO,WAAW,GACzB,OAAO,OAAO,QAAQ;GAC1B;CAEF,MAAM,oBAAoB,SAA2B;AACnD,MAAI,CAAC,MAAM;AACT,YAAS,KAAK;AACd;;AAIF,MAAI,WAAW;GACb,MAAM,CAAC,OAAO,SAAS,WAAW,UAAU,MAAM,IAAI,CAAC,IAAI,OAAO;AAClE,QAAK,SAAS,SAAS,GAAG,WAAW,GAAG,WAAW,EAAE;;AAEvD,WAAS,KAAK;;CAGhB,MAAM,oBAAoB,MAA2C;EACnE,MAAM,OAAO,EAAE,OAAO;AACtB,eAAa,KAAK;AAElB,MAAI,SAAS,MAAM;GACjB,MAAM,CAAC,OAAO,SAAS,WAAW,KAAK,MAAM,IAAI,CAAC,IAAI,OAAO;GAC7D,MAAM,UAAU,IAAI,KAAK,MAAM;AAC/B,WAAQ,SAAS,SAAS,GAAG,WAAW,GAAG,WAAW,EAAE;AACxD,YAAS,QAAQ;;;CAIrB,MAAM,eAAe,MAAwB;AAC3C,IAAE,iBAAiB;AACnB,WAAS,KAAK;AACd,eAAa,GAAG;;AAGlB,QACE,qBAAC;EAAc;EAAM,cAAc;aACjC,qBAAC;GACK;GACM;GACV,gBAAc;GACd,WAAW,GACT,0HACA,gDACA,uGACA,mDACA,CAAC,SAAS,yBACV,UACD;;IAED,oBAAC;KAAK,MAAK;KAAoB,WAAU;MAAW;IACpD,oBAAC;KAAK,WAAU;eACb,QAAQ,OAAO,OAAO,WAAW,GAAG,YAAY,YAAY;MACxD;IACN,SAAS,CAAC,YACT,oBAAC;KACC,MAAK;KACL,WAAU;KACV,SAAS;MACT;;IAEW,EACjB,qBAAC;GAAe,WAAU;GAAa,OAAM;cAC3C,oBAAC;IACC,MAAK;IACL,UAAU,SAAS;IACnB,UAAU;IACV,WAAW,SAAS;AAClB,SAAI,WAAW,OAAO,QAAS,QAAO;AACtC,SAAI,WAAW,OAAO,QAAS,QAAO;AACtC,YAAO;;IAET,WAAU;IACV,YAAY;KACV,QAAQ;KACR,OAAO;KACP,eAAe;KACf,eAAe;KACf,KAAK;KACL,iBAAiB,GACf,sDACA,kEACD;KACD,aAAa,GACX,sDACA,kEACD;KACD,YAAY;KACZ,UAAU;KACV,SACE;KACF,MAAM;KACN,KAAK;KACL,YAAY,GACV,qCACA,gDACA,2EACD;KACD,UACE;KACF,OAAO;KACP,SAAS;KACT,UAAU;KACV,QAAQ;KACT;KACD,EACF,oBAAC;IAAI,WAAU;cACb,oBAAC;KACC,MAAK;KACL,MAAM,cAAc,WAAW,IAAI;KACnC,OAAO;KACP,UAAU;KACV,WAAW,GACT,yFACA,sGACD;MACD;KACE;IACS;GACT"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"dropzone.mjs","names":["React","valid: File[]","errors: ValidationError[]","parts: string[]"],"sources":["../../../../src/client/components/primitives/dropzone.tsx"],"sourcesContent":["/**\n * Dropzone Primitive\n *\n * A reusable drag-and-drop area for file uploads.\n * Supports file type filtering, size validation, and visual feedback.\n *\n * @example\n * ```tsx\n * <Dropzone\n * onDrop={(files) => handleUpload(files)}\n * accept={[\"image/*\", \"application/pdf\"]}\n * maxSize={5_000_000}\n * />\n * ```\n */\n\nimport * as React from \"react\";\nimport { Icon } from \"@iconify/react\";\nimport { cn } from \"../../lib/utils\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DropzoneProps {\n /**\n * Called when files are dropped or selected\n */\n onDrop: (files: File[]) => void;\n\n /**\n * Accepted file types (MIME types or extensions)\n * @example [\"image/*\", \"application/pdf\", \".doc\"]\n */\n accept?: string[];\n\n /**\n * Maximum file size in bytes\n */\n maxSize?: number;\n\n /**\n * Whether multiple files can be selected\n * @default false\n */\n multiple?: boolean;\n\n /**\n * Disable the dropzone\n */\n disabled?: boolean;\n\n /**\n * Show loading state (e.g., during upload)\n */\n loading?: boolean;\n\n /**\n * Current upload progress (0-100)\n */\n progress?: number;\n\n /**\n * Custom label text\n * @default \"Drop files here or click to browse\"\n */\n label?: string;\n\n /**\n * Helper text shown below the label\n */\n hint?: string;\n\n /**\n * Error message to display\n */\n error?: string;\n\n /**\n * Additional className\n */\n className?: string;\n\n /**\n * Children to render inside the dropzone (custom content)\n */\n children?: React.ReactNode;\n\n /**\n * Callback when validation fails\n */\n onValidationError?: (errors: ValidationError[]) => void;\n}\n\nexport interface ValidationError {\n file: File;\n type: \"type\" | \"size\";\n message: string;\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Check if a file matches accepted types\n */\nfunction matchesAccept(file: File, accept?: string[]): boolean {\n if (!accept || accept.length === 0) return true;\n\n const mimeType = file.type.toLowerCase();\n const fileName = file.name.toLowerCase();\n\n return accept.some((pattern) => {\n const normalizedPattern = pattern.toLowerCase();\n\n // Handle wildcard MIME types like \"image/*\"\n if (normalizedPattern.endsWith(\"/*\")) {\n const baseType = normalizedPattern.slice(0, -2);\n return mimeType.startsWith(`${baseType}/`);\n }\n\n // Handle extensions like \".pdf\"\n if (normalizedPattern.startsWith(\".\")) {\n return fileName.endsWith(normalizedPattern);\n }\n\n // Handle exact MIME types\n return mimeType === normalizedPattern;\n });\n}\n\n/**\n * Format file size for display\n */\nfunction formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function Dropzone({\n onDrop,\n accept,\n maxSize,\n multiple = false,\n disabled = false,\n loading = false,\n progress,\n label = \"Drop files here or click to browse\",\n hint,\n error,\n className,\n children,\n onValidationError,\n}: DropzoneProps) {\n const [isDragging, setIsDragging] = React.useState(false);\n const inputRef = React.useRef<HTMLInputElement>(null);\n const dragCounterRef = React.useRef(0);\n\n /**\n * Validate files and return valid ones + errors\n */\n const validateFiles = React.useCallback(\n (files: File[]): { valid: File[]; errors: ValidationError[] } => {\n const valid: File[] = [];\n const errors: ValidationError[] = [];\n\n for (const file of files) {\n // Check type\n if (!matchesAccept(file, accept)) {\n errors.push({\n file,\n type: \"type\",\n message: `\"${file.name}\" is not an accepted file type`,\n });\n continue;\n }\n\n // Check size\n if (maxSize && file.size > maxSize) {\n errors.push({\n file,\n type: \"size\",\n message: `\"${file.name}\" exceeds maximum size of ${formatFileSize(maxSize)}`,\n });\n continue;\n }\n\n valid.push(file);\n }\n\n return { valid, errors };\n },\n [accept, maxSize],\n );\n\n /**\n * Handle file selection\n */\n const handleFiles = React.useCallback(\n (files: FileList | File[]) => {\n if (disabled || loading) return;\n\n const fileArray = Array.from(files);\n const filesToProcess = multiple ? fileArray : fileArray.slice(0, 1);\n\n const { valid, errors } = validateFiles(filesToProcess);\n\n if (errors.length > 0) {\n onValidationError?.(errors);\n }\n\n if (valid.length > 0) {\n onDrop(valid);\n }\n },\n [disabled, loading, multiple, validateFiles, onDrop, onValidationError],\n );\n\n /**\n * Handle drag events\n */\n const handleDragEnter = React.useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n dragCounterRef.current += 1;\n if (e.dataTransfer.items.length > 0 && !disabled && !loading) {\n setIsDragging(true);\n }\n },\n [disabled, loading],\n );\n\n const handleDragLeave = React.useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n dragCounterRef.current -= 1;\n if (dragCounterRef.current === 0) {\n setIsDragging(false);\n }\n }, []);\n\n const handleDragOver = React.useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n }, []);\n\n const handleDrop = React.useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n dragCounterRef.current = 0;\n setIsDragging(false);\n\n if (e.dataTransfer.files.length > 0) {\n handleFiles(e.dataTransfer.files);\n }\n },\n [handleFiles],\n );\n\n /**\n * Handle click to open file dialog\n */\n const handleClick = React.useCallback(() => {\n if (disabled || loading) return;\n inputRef.current?.click();\n }, [disabled, loading]);\n\n /**\n * Handle file input change\n */\n const handleInputChange = React.useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n if (e.target.files && e.target.files.length > 0) {\n handleFiles(e.target.files);\n }\n // Reset input so same file can be selected again\n e.target.value = \"\";\n },\n [handleFiles],\n );\n\n /**\n * Build accept string for input\n */\n const acceptString = accept?.join(\",\") || undefined;\n\n /**\n * Build hint text\n */\n const hintText = React.useMemo(() => {\n if (hint) return hint;\n\n const parts: string[] = [];\n\n if (accept && accept.length > 0) {\n // Simplify accept types for display\n const types = accept\n .map((t) => {\n if (t.startsWith(\"image/\")) return \"Images\";\n if (t.startsWith(\"video/\")) return \"Videos\";\n if (t.startsWith(\"audio/\")) return \"Audio\";\n if (t === \"application/pdf\") return \"PDF\";\n if (t.startsWith(\".\")) return t.toUpperCase();\n return t;\n })\n .filter((v, i, a) => a.indexOf(v) === i); // unique\n parts.push(types.join(\", \"));\n }\n\n if (maxSize) {\n parts.push(`Max ${formatFileSize(maxSize)}`);\n }\n\n return parts.length > 0 ? parts.join(\" • \") : undefined;\n }, [hint, accept, maxSize]);\n\n return (\n <div\n role=\"button\"\n tabIndex={disabled || loading ? -1 : 0}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n handleClick();\n }\n }}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n className={cn(\n \"relative flex min-h-[120px] cursor-pointer flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed p-6 text-center transition-colors\",\n \"border-border/60 bg-muted/30 hover:border-border hover:bg-muted/50\",\n isDragging && \"border-primary bg-primary/5\",\n error && \"border-destructive/50 bg-destructive/5\",\n (disabled || loading) && \"pointer-events-none opacity-60\",\n className,\n )}\n aria-disabled={disabled || loading}\n data-dragging={isDragging || undefined}\n >\n {/* Hidden file input */}\n <input\n ref={inputRef}\n type=\"file\"\n accept={acceptString}\n multiple={multiple}\n onChange={handleInputChange}\n className=\"sr-only\"\n disabled={disabled || loading}\n tabIndex={-1}\n />\n\n {/* Custom children or default content */}\n {children || (\n <>\n {/* Icon / Loading */}\n <div className=\"flex items-center justify-center\">\n {loading ? (\n <div className=\"relative\">\n <Icon\n icon=\"ph:spinner-gap\"\n className=\"text-muted-foreground size-10 animate-spin\"\n />\n {typeof progress === \"number\" && (\n <span className=\"text-muted-foreground absolute inset-0 flex items-center justify-center text-xs font-medium\">\n {progress}%\n </span>\n )}\n </div>\n ) : (\n <Icon\n icon=\"ph:cloud-arrow-up\"\n className={cn(\n \"size-10 transition-colors\",\n isDragging ? \"text-primary\" : \"text-muted-foreground\",\n )}\n />\n )}\n </div>\n\n {/* Label */}\n <div className=\"space-y-1\">\n <p\n className={cn(\n \"text-sm font-medium\",\n isDragging ? \"text-primary\" : \"text-foreground\",\n )}\n >\n {loading ? \"Uploading...\" : label}\n </p>\n\n {/* Hint */}\n {hintText && !loading && (\n <p className=\"text-muted-foreground text-xs\">{hintText}</p>\n )}\n\n {/* Progress bar */}\n {loading && typeof progress === \"number\" && (\n <div className=\"bg-muted mx-auto mt-2 h-1.5 w-32 overflow-hidden rounded-full\">\n <div\n className=\"bg-primary h-full rounded-full transition-all duration-300\"\n style={{ width: `${progress}%` }}\n />\n </div>\n )}\n </div>\n </>\n )}\n\n {/* Error message */}\n {error && (\n <p className=\"text-destructive absolute bottom-2 left-0 right-0 text-center text-xs\">\n {error}\n </p>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"number-input.mjs","names":[],"sources":["../../../../src/client/components/primitives/number-input.tsx"],"sourcesContent":["import { Icon } from \"@iconify/react\";\nimport { useResolveText } from \"../../i18n/hooks\";\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../ui/button\";\nimport { Input } from \"../ui/input\";\nimport type { NumberInputProps } from \"./types\";\n\n/**\n * Number Input Primitive\n *\n * A number input with optional increment/decrement buttons.\n *\n * @example\n * ```tsx\n * <NumberInput\n * value={count}\n * onChange={setCount}\n * min={0}\n * max={100}\n * step={1}\n * showButtons\n * />\n * ```\n */\nexport function NumberInput({\n value,\n onChange,\n min,\n max,\n step = 1,\n showButtons = false,\n placeholder,\n disabled,\n readOnly,\n className,\n id,\n \"aria-invalid\": ariaInvalid,\n}: NumberInputProps) {\n const resolveText = useResolveText();\n\n const handleChange = (newValue: number | null) => {\n if (newValue === null) {\n onChange(null);\n return;\n }\n\n let clampedValue = newValue;\n if (min !== undefined && clampedValue < min) clampedValue = min;\n if (max !== undefined && clampedValue > max) clampedValue = max;\n\n onChange(clampedValue);\n };\n\n const increment = () => {\n const current = value ?? 0;\n handleChange(current + step);\n };\n\n const decrement = () => {\n const current = value ?? 0;\n handleChange(current - step);\n };\n\n if (showButtons) {\n return (\n <div className={cn(\"flex items-center gap-1\", className)}>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon-sm\"\n onClick={decrement}\n disabled={disabled || (min !== undefined && (value ?? 0) <= min)}\n tabIndex={-1}\n >\n <Icon icon=\"ph:minus\" className=\"size-3\" />\n </Button>\n <Input\n id={id}\n type=\"number\"\n value={value ?? \"\"}\n onChange={(e) => {\n const val = e.target.value;\n if (val === \"\") {\n handleChange(null);\n } else {\n handleChange(Number(val));\n }\n }}\n placeholder={resolveText(placeholder)}\n disabled={disabled}\n readOnly={readOnly}\n min={min}\n max={max}\n step={step}\n aria-invalid={ariaInvalid}\n className=\"text-center [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none\"\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon-sm\"\n onClick={increment}\n disabled={disabled || (max !== undefined && (value ?? 0) >= max)}\n tabIndex={-1}\n >\n <Icon icon=\"ph:plus\" className=\"size-3\" />\n </Button>\n </div>\n );\n }\n\n return (\n <Input\n id={id}\n type=\"number\"\n value={value ?? \"\"}\n onChange={(e) => {\n const val = e.target.value;\n if (val === \"\") {\n handleChange(null);\n } else {\n handleChange(Number(val));\n }\n }}\n placeholder={resolveText(placeholder)}\n disabled={disabled}\n readOnly={readOnly}\n min={min}\n max={max}\n step={step}\n aria-invalid={ariaInvalid}\n className={className}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAAgB,YAAY,EAC1B,OACA,UACA,KACA,KACA,OAAO,GACP,cAAc,OACd,aACA,UACA,UACA,WACA,IACA,gBAAgB,eACG;CACnB,MAAM,cAAc,gBAAgB;CAEpC,MAAM,gBAAgB,aAA4B;AAChD,MAAI,aAAa,MAAM;AACrB,YAAS,KAAK;AACd;;EAGF,IAAI,eAAe;AACnB,MAAI,QAAQ,UAAa,eAAe,IAAK,gBAAe;AAC5D,MAAI,QAAQ,UAAa,eAAe,IAAK,gBAAe;AAE5D,WAAS,aAAa;;CAGxB,MAAM,kBAAkB;AAEtB,gBADgB,SAAS,KACF,KAAK;;CAG9B,MAAM,kBAAkB;AAEtB,gBADgB,SAAS,KACF,KAAK;;AAG9B,KAAI,YACF,QACE,qBAAC;EAAI,WAAW,GAAG,2BAA2B,UAAU;;GACtD,oBAAC;IACC,MAAK;IACL,SAAQ;IACR,MAAK;IACL,SAAS;IACT,UAAU,YAAa,QAAQ,WAAc,SAAS,MAAM;IAC5D,UAAU;cAEV,oBAAC;KAAK,MAAK;KAAW,WAAU;MAAW;KACpC;GACT,oBAAC;IACK;IACJ,MAAK;IACL,OAAO,SAAS;IAChB,WAAW,MAAM;KACf,MAAM,MAAM,EAAE,OAAO;AACrB,SAAI,QAAQ,GACV,cAAa,KAAK;SAElB,cAAa,OAAO,IAAI,CAAC;;IAG7B,aAAa,YAAY,YAAY;IAC3B;IACA;IACL;IACA;IACC;IACN,gBAAc;IACd,WAAU;KACV;GACF,oBAAC;IACC,MAAK;IACL,SAAQ;IACR,MAAK;IACL,SAAS;IACT,UAAU,YAAa,QAAQ,WAAc,SAAS,MAAM;IAC5D,UAAU;cAEV,oBAAC;KAAK,MAAK;KAAU,WAAU;MAAW;KACnC;;GACL;AAIV,QACE,oBAAC;EACK;EACJ,MAAK;EACL,OAAO,SAAS;EAChB,WAAW,MAAM;GACf,MAAM,MAAM,EAAE,OAAO;AACrB,OAAI,QAAQ,GACV,cAAa,KAAK;OAElB,cAAa,OAAO,IAAI,CAAC;;EAG7B,aAAa,YAAY,YAAY;EAC3B;EACA;EACL;EACA;EACC;EACN,gBAAc;EACH;GACX"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"select-multi.mjs","names":[],"sources":["../../../../src/client/components/primitives/select-multi.tsx"],"sourcesContent":["\"use client\";\n\nimport { Icon } from \"@iconify/react\";\nimport type * as React from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useIsMobile } from \"../../hooks/use-media-query\";\nimport { useResolveText } from \"../../i18n/hooks\";\nimport { cn } from \"../../lib/utils\";\nimport { Badge } from \"../ui/badge\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"../ui/command\";\nimport {\n Drawer,\n DrawerContent,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"../ui/drawer\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../ui/popover\";\nimport type { BasePrimitiveProps, SelectOption, SelectOptions } from \"./types\";\nimport { flattenOptions } from \"./types\";\n\nexport interface SelectMultiProps<\n TValue extends string = string,\n> extends BasePrimitiveProps {\n /** Selected values */\n value: TValue[];\n /** Change handler */\n onChange: (value: TValue[]) => void;\n /** Static options */\n options?: SelectOptions<TValue>;\n /** Dynamic options loader */\n loadOptions?: (search: string) => Promise<SelectOption<TValue>[]>;\n /** Max selections */\n maxSelections?: number;\n /** Debounce delay for loadOptions (ms) */\n debounceMs?: number;\n /** External loading state */\n loading?: boolean;\n /** Empty state message */\n emptyMessage?: string;\n /** Title for mobile drawer */\n drawerTitle?: string;\n /** Max visible chips before collapsing */\n maxVisibleChips?: number;\n}\n\n/**\n * SelectMulti - Multi-select component with chips\n *\n * Features:\n * - Always searchable\n * - Responsive: Popover on desktop, Drawer on mobile\n * - Chip display with remove buttons\n * - Supports static and async options\n * - Keyboard navigation\n *\n * @example\n * ```tsx\n * <SelectMulti\n * value={selectedTags}\n * onChange={setSelectedTags}\n * options={[\n * { value: \"react\", label: \"React\" },\n * { value: \"vue\", label: \"Vue\" },\n * { value: \"angular\", label: \"Angular\" },\n * ]}\n * />\n * ```\n */\nexport function SelectMulti<TValue extends string = string>({\n value = [],\n onChange,\n options: staticOptions = [],\n loadOptions,\n maxSelections,\n debounceMs = 300,\n loading: externalLoading = false,\n emptyMessage = \"No options found\",\n placeholder = \"Select...\",\n disabled,\n className,\n id,\n \"aria-invalid\": ariaInvalid,\n drawerTitle = \"Select options\",\n maxVisibleChips = 3,\n}: SelectMultiProps<TValue>) {\n const resolveText = useResolveText();\n const resolvedPlaceholder = resolveText(placeholder);\n const resolvedEmptyMessage = resolveText(emptyMessage);\n const resolvedDrawerTitle = resolveText(drawerTitle);\n const [open, setOpen] = useState(false);\n const [search, setSearch] = useState(\"\");\n const [dynamicOptions, setDynamicOptions] = useState<SelectOption<TValue>[]>(\n [],\n );\n const [isLoading, setIsLoading] = useState(false);\n const debounceRef = useRef<ReturnType<typeof setTimeout>>(null);\n const isMobile = useIsMobile();\n\n // Flatten static options\n const flatStaticOptions = useMemo(\n () => flattenOptions(staticOptions),\n [staticOptions],\n );\n\n // Merge static and dynamic options\n const allOptions = useMemo(() => {\n if (loadOptions) {\n return dynamicOptions;\n }\n return flatStaticOptions;\n }, [loadOptions, dynamicOptions, flatStaticOptions]);\n\n // Filter options by search (for static options)\n const filteredOptions = useMemo(() => {\n if (loadOptions) {\n return allOptions;\n }\n if (!search) {\n return allOptions;\n }\n return allOptions.filter((opt) =>\n resolveText(opt.label).toLowerCase().includes(search.toLowerCase()),\n );\n }, [allOptions, search, loadOptions, resolveText]);\n\n // Load dynamic options\n useEffect(() => {\n if (!loadOptions) return;\n\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n\n debounceRef.current = setTimeout(async () => {\n setIsLoading(true);\n try {\n const results = await loadOptions(search);\n setDynamicOptions(results);\n } catch (error) {\n console.error(\"Failed to load options:\", error);\n setDynamicOptions([]);\n } finally {\n setIsLoading(false);\n }\n }, debounceMs);\n\n return () => {\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n };\n }, [search, loadOptions, debounceMs]);\n\n // Get label for a value\n const getLabel = useCallback(\n (val: TValue): string => {\n const option = allOptions.find((opt) => opt.value === val);\n return option?.label ? resolveText(option.label) : String(val);\n },\n [allOptions, resolveText],\n );\n\n const handleToggle = useCallback(\n (selectedValue: string) => {\n const typedValue = selectedValue as TValue;\n const isSelected = value.includes(typedValue);\n\n if (isSelected) {\n onChange(value.filter((v) => v !== typedValue));\n } else {\n if (maxSelections && value.length >= maxSelections) return;\n onChange([...value, typedValue]);\n }\n },\n [value, onChange, maxSelections],\n );\n\n const handleRemove = useCallback(\n (removedValue: TValue, e?: React.MouseEvent) => {\n e?.stopPropagation();\n onChange(value.filter((v) => v !== removedValue));\n },\n [value, onChange],\n );\n\n const handleClearAll = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onChange([]);\n },\n [onChange],\n );\n\n const showLoading = isLoading || externalLoading;\n const canAddMore = !maxSelections || value.length < maxSelections;\n\n // Visible and hidden chips\n const visibleChips = value.slice(0, maxVisibleChips);\n const hiddenCount = value.length - maxVisibleChips;\n\n const TriggerContent = (\n <div\n id={id}\n role=\"combobox\"\n aria-controls=\"select-multi-list\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-invalid={ariaInvalid}\n tabIndex={0}\n className={cn(\n \"flex min-h-9 w-full flex-wrap items-center gap-1 rounded-md border border-input/80 bg-input/20 backdrop-blur-sm px-3 py-1.5 text-sm transition-colors\",\n \"focus-within:ring-2 focus-within:ring-ring focus-within:border-ring\",\n disabled && \"cursor-not-allowed opacity-50\",\n ariaInvalid && \"border-destructive ring-destructive/20\",\n className,\n )}\n >\n {value.length === 0 ? (\n <span className=\"text-muted-foreground text-xs\">\n {resolvedPlaceholder}\n </span>\n ) : (\n <>\n {visibleChips.map((val) => (\n <Badge key={String(val)} variant=\"secondary\" className=\"gap-1 pr-1\">\n <span className=\"truncate max-w-24\">{getLabel(val)}</span>\n {!disabled && (\n <button\n type=\"button\"\n onClick={(e) => handleRemove(val, e)}\n className=\"rounded-full hover:bg-muted-foreground/20 p-0.5\"\n >\n <Icon icon=\"ph:x\" className=\"size-2.5\" />\n </button>\n )}\n </Badge>\n ))}\n {hiddenCount > 0 && (\n <Badge variant=\"outline\" className=\"text-muted-foreground\">\n +{hiddenCount} more\n </Badge>\n )}\n </>\n )}\n <div className=\"ml-auto flex items-center gap-1 shrink-0\">\n {value.length > 0 && !disabled && (\n <button\n type=\"button\"\n onClick={handleClearAll}\n className=\"rounded-sm opacity-50 hover:opacity-100 hover:bg-muted p-0.5\"\n >\n <Icon icon=\"ph:x\" className=\"size-3\" />\n </button>\n )}\n <Icon icon=\"ph:plus\" className=\"size-3.5 opacity-50\" />\n </div>\n </div>\n );\n\n const CommandContent = (\n <Command shouldFilter={!loadOptions}>\n <CommandInput\n placeholder=\"Search...\"\n value={search}\n onValueChange={setSearch}\n />\n <CommandList>\n {showLoading && (\n <div className=\"flex items-center justify-center py-6\">\n <Icon\n icon=\"ph:circle-notch\"\n className=\"size-4 animate-spin text-muted-foreground\"\n />\n </div>\n )}\n <CommandEmpty>{resolvedEmptyMessage}</CommandEmpty>\n <CommandGroup>\n {filteredOptions.map((option) => {\n const isSelected = value.includes(option.value);\n const isDisabled = option.disabled || (!isSelected && !canAddMore);\n\n return (\n <CommandItem\n key={String(option.value)}\n value={String(option.value)}\n onSelect={handleToggle}\n disabled={isDisabled}\n >\n <div\n className={cn(\n \"flex size-4 items-center justify-center rounded-sm border\",\n isSelected\n ? \"bg-primary border-primary text-primary-foreground\"\n : \"border-muted-foreground/30\",\n )}\n >\n {isSelected && <Icon icon=\"ph:check\" className=\"size-3\" />}\n </div>\n {option.icon}\n <span className=\"truncate\">{resolveText(option.label)}</span>\n </CommandItem>\n );\n })}\n </CommandGroup>\n </CommandList>\n {maxSelections && (\n <div className=\"border-t p-2 text-center text-xs text-muted-foreground\">\n {value.length} / {maxSelections} selected\n </div>\n )}\n </Command>\n );\n\n // Mobile: Drawer\n if (isMobile) {\n return (\n <Drawer open={open} onOpenChange={setOpen}>\n <DrawerTrigger asChild>\n <button\n type=\"button\"\n disabled={disabled}\n className=\"w-full text-left\"\n >\n {TriggerContent}\n </button>\n </DrawerTrigger>\n <DrawerContent>\n <DrawerHeader>\n <DrawerTitle>{resolvedDrawerTitle}</DrawerTitle>\n </DrawerHeader>\n <div className=\"px-4 pb-6\">{CommandContent}</div>\n </DrawerContent>\n </Drawer>\n );\n }\n\n // Desktop: Popover\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger\n render={\n <button\n type=\"button\"\n disabled={disabled}\n className=\"w-full text-left\"\n >\n {TriggerContent}\n </button>\n }\n />\n <PopoverContent className=\"w-(--anchor-width) p-0\" align=\"start\">\n {CommandContent}\n </PopoverContent>\n </Popover>\n );\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"select-single.mjs","names":[],"sources":["../../../../src/client/components/primitives/select-single.tsx"],"sourcesContent":["\"use client\";\n\nimport { Icon } from \"@iconify/react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type * as React from \"react\";\nimport { useCallback, useDeferredValue, useId, useMemo, useState } from \"react\";\nimport { useIsMobile } from \"../../hooks/use-media-query\";\nimport { useResolveText } from \"../../i18n/hooks\";\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../ui/button\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"../ui/command\";\nimport {\n Drawer,\n DrawerContent,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"../ui/drawer\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../ui/popover\";\nimport type { BasePrimitiveProps, SelectOption, SelectOptions } from \"./types\";\nimport { flattenOptions } from \"./types\";\n\nexport interface SelectSingleProps<\n TValue extends string = string,\n> extends BasePrimitiveProps {\n /** Selected value */\n value: TValue | null;\n /** Change handler */\n onChange: (value: TValue | null) => void;\n /** Static options */\n options?: SelectOptions<TValue>;\n /** Dynamic options loader */\n loadOptions?: (search: string) => Promise<SelectOption<TValue>[]>;\n /** Query key builder for loadOptions */\n queryKey?: (search: string) => readonly unknown[];\n /** Prefetch options on mount */\n prefetchOnMount?: boolean;\n\n /** Allow clearing selection */\n clearable?: boolean;\n /** Debounce delay for loadOptions (ms) */\n debounceMs?: number;\n /** External loading state */\n loading?: boolean;\n /** Empty state message */\n emptyMessage?: string;\n /** Title for mobile drawer */\n drawerTitle?: string;\n}\n\n/**\n * SelectSingle - Single select component with search\n *\n * Features:\n * - Always searchable\n * - Responsive: Popover on desktop, Drawer on mobile\n * - Supports static and async options\n * - Keyboard navigation\n *\n * @example\n * ```tsx\n * <SelectSingle\n * value={status}\n * onChange={setStatus}\n * options={[\n * { value: \"active\", label: \"Active\" },\n * { value: \"inactive\", label: \"Inactive\" },\n * ]}\n * />\n * ```\n */\nexport function SelectSingle<TValue extends string = string>({\n value,\n onChange,\n options: staticOptions = [],\n loadOptions,\n queryKey,\n prefetchOnMount = false,\n clearable = true,\n loading: externalLoading = false,\n emptyMessage = \"No options found\",\n placeholder = \"Select...\",\n disabled,\n className,\n id,\n \"aria-invalid\": ariaInvalid,\n drawerTitle = \"Select option\",\n}: SelectSingleProps<TValue>) {\n const resolveText = useResolveText();\n const resolvedPlaceholder = resolveText(placeholder);\n const resolvedEmptyMessage = resolveText(emptyMessage);\n const resolvedDrawerTitle = resolveText(drawerTitle);\n const [open, setOpen] = useState(false);\n const [search, setSearch] = useState(\"\");\n const instanceId = useId();\n const deferredSearch = useDeferredValue(search);\n const isMobile = useIsMobile();\n\n // Flatten static options\n const flatStaticOptions = useMemo(\n () => flattenOptions(staticOptions),\n [staticOptions],\n );\n\n const loadOptionsKey = useMemo(\n () =>\n queryKey\n ? queryKey(deferredSearch)\n : [\"select-single\", instanceId, deferredSearch],\n [queryKey, deferredSearch, instanceId],\n );\n\n const { data: dynamicOptions = [], isFetching } = useQuery({\n queryKey: loadOptionsKey,\n queryFn: () => loadOptions?.(deferredSearch) ?? Promise.resolve([]),\n enabled: !!loadOptions && (open || prefetchOnMount),\n staleTime: 30_000,\n gcTime: 5 * 60_000,\n });\n\n // Merge static and dynamic options (immutable pattern for React Compiler)\n const allOptions = useMemo(() => {\n if (!loadOptions) {\n return flatStaticOptions;\n }\n if (flatStaticOptions.length === 0) {\n return dynamicOptions;\n }\n // Use reduce to build Map immutably - dynamic options override static\n const mergedMap = [...flatStaticOptions, ...dynamicOptions].reduce(\n (map, opt) => new Map(map).set(opt.value, opt),\n new Map<TValue, SelectOption<TValue>>(),\n );\n return Array.from(mergedMap.values());\n }, [loadOptions, dynamicOptions, flatStaticOptions]);\n\n // Filter options by search (for static options)\n const filteredOptions = useMemo(() => {\n if (loadOptions) {\n return allOptions; // Dynamic options are already filtered by server\n }\n if (!search) {\n return allOptions;\n }\n return allOptions.filter((opt: SelectOption<TValue>) =>\n resolveText(opt.label).toLowerCase().includes(search.toLowerCase()),\n );\n }, [allOptions, search, loadOptions, resolveText]);\n\n // Get label for a value\n const getLabel = useCallback(\n (val: TValue): string => {\n const option = allOptions.find(\n (opt: SelectOption<TValue>) => opt.value === val,\n );\n return option?.label ? resolveText(option.label) : String(val);\n },\n [allOptions, resolveText],\n );\n\n const handleSelect = useCallback(\n (selectedValue: string) => {\n onChange(selectedValue as TValue);\n setOpen(false);\n setSearch(\"\");\n },\n [onChange],\n );\n\n const handleClear = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onChange(null);\n },\n [onChange],\n );\n\n const showLoading = isFetching || externalLoading;\n\n const TriggerButton = (\n <Button\n id={id}\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n aria-invalid={ariaInvalid}\n disabled={disabled}\n className={cn(\n \"w-full justify-between font-normal\",\n !value && \"text-muted-foreground\",\n className,\n )}\n >\n <span className=\"truncate\">\n {value ? getLabel(value) : resolvedPlaceholder}\n </span>\n <div className=\"flex items-center gap-1 shrink-0\">\n {clearable && value && !disabled && (\n <span\n role=\"button\"\n tabIndex={-1}\n onClick={handleClear}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n handleClear(event as unknown as React.MouseEvent);\n }\n }}\n className=\"rounded-sm opacity-50 hover:opacity-100 hover:bg-muted p-0.5 -mr-1\"\n >\n <Icon icon=\"ph:x\" className=\"size-3\" />\n </span>\n )}\n <Icon icon=\"ph:caret-up-down\" className=\"size-3.5 opacity-50\" />\n </div>\n </Button>\n );\n\n const CommandContent = (\n <Command shouldFilter={!loadOptions}>\n <CommandInput\n placeholder=\"Search...\"\n value={search}\n onValueChange={setSearch}\n />\n <CommandList>\n {showLoading && (\n <div className=\"flex items-center justify-center py-6\">\n <Icon\n icon=\"ph:circle-notch\"\n className=\"size-4 animate-spin text-muted-foreground\"\n />\n </div>\n )}\n <CommandEmpty>{resolvedEmptyMessage}</CommandEmpty>\n <CommandGroup>\n {filteredOptions.map((option) => (\n <CommandItem\n key={String(option.value)}\n value={String(option.value)}\n onSelect={handleSelect}\n disabled={option.disabled}\n data-checked={value === option.value}\n >\n {option.icon}\n <span className=\"truncate\">{resolveText(option.label)}</span>\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n );\n\n // Mobile: Drawer\n if (isMobile) {\n return (\n <Drawer open={open} onOpenChange={setOpen}>\n <DrawerTrigger asChild>{TriggerButton}</DrawerTrigger>\n <DrawerContent>\n <DrawerHeader>\n <DrawerTitle>{resolvedDrawerTitle}</DrawerTitle>\n </DrawerHeader>\n <div className=\"px-4 pb-6\">{CommandContent}</div>\n </DrawerContent>\n </Drawer>\n );\n }\n\n // Desktop: Popover\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger render={TriggerButton} />\n <PopoverContent className=\"w-(--anchor-width) p-0\" align=\"start\">\n {CommandContent}\n </PopoverContent>\n </Popover>\n );\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"text-input.mjs","names":[],"sources":["../../../../src/client/components/primitives/text-input.tsx"],"sourcesContent":["import { useResolveText } from \"../../i18n/hooks\";\nimport { Input } from \"../ui/input\";\nimport type { TextInputProps } from \"./types\";\n\n/**\n * Text Input Primitive\n *\n * A basic text input with value/onChange pattern.\n * Supports different input types: text, email, password, url, tel, search.\n *\n * @example\n * ```tsx\n * <TextInput\n * value={email}\n * onChange={setEmail}\n * type=\"email\"\n * placeholder=\"Enter email\"\n * />\n * ```\n */\nexport function TextInput({\n value,\n onChange,\n type = \"text\",\n placeholder,\n disabled,\n readOnly,\n maxLength,\n autoComplete,\n className,\n id,\n \"aria-invalid\": ariaInvalid,\n}: TextInputProps) {\n const resolveText = useResolveText();\n\n return (\n <Input\n id={id}\n type={type}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n placeholder={resolveText(placeholder)}\n disabled={disabled}\n readOnly={readOnly}\n maxLength={maxLength}\n autoComplete={autoComplete}\n aria-invalid={ariaInvalid}\n className={className}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,UAAU,EACxB,OACA,UACA,OAAO,QACP,aACA,UACA,UACA,WACA,cACA,WACA,IACA,gBAAgB,eACC;AAGjB,QACE,oBAAC;EACK;EACE;EACC;EACP,WAAW,MAAM,SAAS,EAAE,OAAO,MAAM;EACzC,aARgB,gBAAgB,CAQP,YAAY;EAC3B;EACA;EACC;EACG;EACd,gBAAc;EACH;GACX"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"textarea-input.mjs","names":[],"sources":["../../../../src/client/components/primitives/textarea-input.tsx"],"sourcesContent":["import { useResolveText } from \"../../i18n/hooks\";\nimport { Textarea } from \"../ui/textarea\";\nimport type { TextareaInputProps } from \"./types\";\n\n/**\n * Textarea Input Primitive\n *\n * A multi-line text input.\n *\n * @example\n * ```tsx\n * <TextareaInput\n * value={description}\n * onChange={setDescription}\n * rows={4}\n * placeholder=\"Enter description...\"\n * />\n * ```\n */\nexport function TextareaInput({\n value,\n onChange,\n rows = 3,\n maxLength,\n placeholder,\n disabled,\n readOnly,\n className,\n id,\n \"aria-invalid\": ariaInvalid,\n}: TextareaInputProps) {\n const resolveText = useResolveText();\n\n return (\n <Textarea\n id={id}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n rows={rows}\n maxLength={maxLength}\n placeholder={resolveText(placeholder)}\n disabled={disabled}\n readOnly={readOnly}\n aria-invalid={ariaInvalid}\n className={className}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,cAAc,EAC5B,OACA,UACA,OAAO,GACP,WACA,aACA,UACA,UACA,WACA,IACA,gBAAgB,eACK;AAGrB,QACE,oBAAC;EACK;EACG;EACP,WAAW,MAAM,SAAS,EAAE,OAAO,MAAM;EACnC;EACK;EACX,aATgB,gBAAgB,CASP,YAAY;EAC3B;EACA;EACV,gBAAc;EACH;GACX"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"time-input.mjs","names":[],"sources":["../../../../src/client/components/primitives/time-input.tsx"],"sourcesContent":["\"use client\";\n\nimport { Icon } from \"@iconify/react\";\nimport { useResolveText } from \"../../i18n/hooks\";\nimport { cn } from \"../../lib/utils\";\nimport type { TimeInputProps } from \"./types\";\n\n/**\n * Time Input Primitive\n *\n * A time-only input using the native HTML time picker.\n * Returns time as string in \"HH:mm\" or \"HH:mm:ss\" format.\n *\n * @example\n * ```tsx\n * <TimeInput\n * value={selectedTime}\n * onChange={setSelectedTime}\n * placeholder=\"Select time\"\n * />\n * ```\n */\nexport function TimeInput({\n value,\n onChange,\n precision = \"minute\",\n placeholder = \"Select time\",\n disabled,\n className,\n id,\n \"aria-invalid\": ariaInvalid,\n}: TimeInputProps) {\n const resolveText = useResolveText();\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const timeValue = e.target.value;\n onChange(timeValue || null);\n };\n\n const handleClear = (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n onChange(null);\n };\n\n return (\n <div className=\"relative\">\n <div\n className={cn(\n \"flex h-9 w-full items-center gap-2 border border-input/80 bg-input/20 backdrop-blur-sm px-3 py-2 text-sm\",\n \"focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2\",\n disabled && \"cursor-not-allowed opacity-50\",\n ariaInvalid && \"border-destructive\",\n className,\n )}\n >\n <Icon icon=\"ph:clock\" className=\"size-4 text-muted-foreground\" />\n <input\n type=\"time\"\n id={id}\n value={value ?? \"\"}\n onChange={handleChange}\n step={precision === \"second\" ? 1 : 60}\n disabled={disabled}\n aria-invalid={ariaInvalid}\n placeholder={resolveText(placeholder)}\n className={cn(\n \"flex-1 bg-transparent outline-none\",\n \"placeholder:text-muted-foreground\",\n \"disabled:cursor-not-allowed\",\n // Hide the native clock icon in some browsers\n \"[&::-webkit-calendar-picker-indicator]:hidden\",\n )}\n />\n {value && !disabled && (\n <button\n type=\"button\"\n onClick={handleClear}\n className=\"text-muted-foreground hover:text-foreground\"\n tabIndex={-1}\n >\n <Icon icon=\"ph:x\" className=\"size-4\" />\n </button>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,UAAU,EACxB,OACA,UACA,YAAY,UACZ,cAAc,eACd,UACA,WACA,IACA,gBAAgB,eACC;CACjB,MAAM,cAAc,gBAAgB;CAEpC,MAAM,gBAAgB,MAA2C;EAC/D,MAAM,YAAY,EAAE,OAAO;AAC3B,WAAS,aAAa,KAAK;;CAG7B,MAAM,eAAe,MAAwB;AAC3C,IAAE,gBAAgB;AAClB,IAAE,iBAAiB;AACnB,WAAS,KAAK;;AAGhB,QACE,oBAAC;EAAI,WAAU;YACb,qBAAC;GACC,WAAW,GACT,4GACA,yEACA,YAAY,iCACZ,eAAe,sBACf,UACD;;IAED,oBAAC;KAAK,MAAK;KAAW,WAAU;MAAiC;IACjE,oBAAC;KACC,MAAK;KACD;KACJ,OAAO,SAAS;KAChB,UAAU;KACV,MAAM,cAAc,WAAW,IAAI;KACzB;KACV,gBAAc;KACd,aAAa,YAAY,YAAY;KACrC,WAAW,GACT,sCACA,qCACA,+BAEA,gDACD;MACD;IACD,SAAS,CAAC,YACT,oBAAC;KACC,MAAK;KACL,SAAS;KACT,WAAU;KACV,UAAU;eAEV,oBAAC;MAAK,MAAK;MAAO,WAAU;OAAW;MAChC;;IAEP;GACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"toggle-input.mjs","names":[],"sources":["../../../../src/client/components/primitives/toggle-input.tsx"],"sourcesContent":["import { Switch } from \"../ui/switch\";\nimport type { ToggleInputProps } from \"./types\";\n\n/**\n * Toggle Input Primitive\n *\n * A switch/toggle for boolean values.\n *\n * @example\n * ```tsx\n * <ToggleInput\n * value={isActive}\n * onChange={setIsActive}\n * />\n * ```\n */\nexport function ToggleInput({\n value,\n onChange,\n disabled,\n className,\n id,\n \"aria-invalid\": ariaInvalid,\n}: ToggleInputProps) {\n return (\n <Switch\n id={id}\n checked={value}\n onCheckedChange={onChange}\n disabled={disabled}\n aria-invalid={ariaInvalid}\n className={className}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAgBA,SAAgB,YAAY,EAC1B,OACA,UACA,UACA,WACA,IACA,gBAAgB,eACG;AACnB,QACE,oBAAC;EACK;EACJ,SAAS;EACT,iBAAiB;EACP;EACV,gBAAc;EACH;GACX"}
@@ -1,14 +0,0 @@
1
- import { I18nText } from "../../i18n/types.mjs";
2
- import { ReactNode } from "react";
3
-
4
- //#region src/client/components/primitives/types.d.ts
5
-
6
- interface SelectOption<TValue = string> {
7
- value: TValue;
8
- label: I18nText;
9
- disabled?: boolean;
10
- icon?: ReactNode;
11
- }
12
- //#endregion
13
- export { SelectOption };
14
- //# sourceMappingURL=types.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.mts","names":[],"sources":["../../../../src/client/components/primitives/types.ts"],"sourcesContent":[],"mappings":";;;;;UAwDiB;SACR;SACA;;SAEA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.mjs","names":[],"sources":["../../../../src/client/components/primitives/types.ts"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { I18nText } from \"../../i18n/types\";\n\n// =============================================================================\n// Base Props (shared by all primitives)\n// =============================================================================\n\nexport interface BasePrimitiveProps {\n /** Unique identifier */\n id?: string;\n /** Placeholder text */\n placeholder?: I18nText;\n /** Disabled state */\n disabled?: boolean;\n /** Read-only state */\n readOnly?: boolean;\n /** Additional class names */\n className?: string;\n /** aria-invalid for error state */\n \"aria-invalid\"?: boolean;\n}\n\n// =============================================================================\n// Text Inputs\n// =============================================================================\n\nexport interface TextInputProps extends BasePrimitiveProps {\n value: string;\n onChange: (value: string) => void;\n type?: \"text\" | \"email\" | \"password\" | \"url\" | \"tel\" | \"search\";\n maxLength?: number;\n autoComplete?: string;\n}\n\nexport interface NumberInputProps extends BasePrimitiveProps {\n value: number | null;\n onChange: (value: number | null) => void;\n min?: number;\n max?: number;\n step?: number;\n /** Show increment/decrement buttons */\n showButtons?: boolean;\n}\n\nexport interface TextareaInputProps extends BasePrimitiveProps {\n value: string;\n onChange: (value: string) => void;\n rows?: number;\n maxLength?: number;\n autoResize?: boolean;\n}\n\n// =============================================================================\n// Select / Multi-Select\n// =============================================================================\n\nexport interface SelectOption<TValue = string> {\n value: TValue;\n label: I18nText;\n disabled?: boolean;\n icon?: ReactNode;\n}\n\nexport interface SelectOptionGroup<TValue = string> {\n label: I18nText;\n options: SelectOption<TValue>[];\n}\n\nexport type SelectOptions<TValue = string> =\n | SelectOption<TValue>[]\n | SelectOptionGroup<TValue>[];\n\n// =============================================================================\n// Boolean Inputs\n// =============================================================================\n// Boolean Inputs\n// =============================================================================\n\nexport interface ToggleInputProps extends BasePrimitiveProps {\n value: boolean;\n onChange: (value: boolean) => void;\n /** Size variant */\n size?: \"sm\" | \"default\" | \"lg\";\n}\n\nexport interface CheckboxInputProps extends BasePrimitiveProps {\n value: boolean;\n onChange: (value: boolean) => void;\n /** Indeterminate state */\n indeterminate?: boolean;\n}\n\nexport interface CheckboxGroupProps<\n TValue = string,\n> extends BasePrimitiveProps {\n value: TValue[];\n onChange: (value: TValue[]) => void;\n options: SelectOption<TValue>[];\n /** Layout direction */\n orientation?: \"horizontal\" | \"vertical\";\n}\n\nexport interface RadioGroupProps<TValue = string> extends BasePrimitiveProps {\n value: TValue | null;\n onChange: (value: TValue) => void;\n options: SelectOption<TValue>[];\n orientation?: \"horizontal\" | \"vertical\";\n}\n\n// =============================================================================\n// Date/Time Inputs\n// =============================================================================\n\nexport interface DateInputProps extends BasePrimitiveProps {\n value: Date | null;\n onChange: (value: Date | null) => void;\n /** Minimum date */\n minDate?: Date;\n /** Maximum date */\n maxDate?: Date;\n /** Date format display */\n format?: string;\n}\n\nexport interface DateTimeInputProps extends DateInputProps {\n /** Time precision */\n precision?: \"minute\" | \"second\";\n}\n\nexport interface TimeInputProps extends BasePrimitiveProps {\n value: string | null; // \"HH:mm\" or \"HH:mm:ss\"\n onChange: (value: string | null) => void;\n precision?: \"minute\" | \"second\";\n}\n\nexport interface DateRangeInputProps extends BasePrimitiveProps {\n value: { start: Date | null; end: Date | null };\n onChange: (value: { start: Date | null; end: Date | null }) => void;\n minDate?: Date;\n maxDate?: Date;\n}\n\n// =============================================================================\n// Special Inputs\n// =============================================================================\n\nexport interface TagInputProps extends BasePrimitiveProps {\n value: string[];\n onChange: (value: string[]) => void;\n /** Suggestions for autocomplete */\n suggestions?: string[];\n /** Max tags */\n maxTags?: number;\n /** Allow duplicates */\n allowDuplicates?: boolean;\n /** Validation pattern */\n pattern?: RegExp;\n}\n\nexport interface ColorInputProps extends BasePrimitiveProps {\n value: string; // hex color\n onChange: (value: string) => void;\n /** Preset colors */\n presets?: string[];\n /** Allow alpha */\n alpha?: boolean;\n}\n\nexport interface SliderInputProps extends BasePrimitiveProps {\n value: number | [number, number];\n onChange: (value: number | [number, number]) => void;\n min: number;\n max: number;\n step?: number;\n /** Show value label */\n showValue?: boolean;\n}\n\nexport interface JsonEditorProps extends BasePrimitiveProps {\n value: unknown;\n onChange: (value: unknown) => void;\n /** Max height */\n maxHeight?: string;\n /** Line numbers */\n showLineNumbers?: boolean;\n /** Schema for validation */\n schema?: unknown;\n}\n\n// =============================================================================\n// Utility Types\n// =============================================================================\n\n/** Check if options are grouped */\nexport function isOptionGroup<T>(\n option: SelectOption<T> | SelectOptionGroup<T>,\n): option is SelectOptionGroup<T> {\n return \"options\" in option;\n}\n\n/** Flatten grouped options */\nexport function flattenOptions<T>(\n options: SelectOptions<T>,\n): SelectOption<T>[] {\n return options.flatMap((opt) => (isOptionGroup(opt) ? opt.options : [opt]));\n}\n"],"mappings":";;AAkMA,SAAgB,cACd,QACgC;AAChC,QAAO,aAAa;;;AAItB,SAAgB,eACd,SACmB;AACnB,QAAO,QAAQ,SAAS,QAAS,cAAc,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,CAAE"}
@@ -1 +0,0 @@
1
- import "./resource-sheet.mjs";
@@ -1 +0,0 @@
1
- import "react/jsx-runtime";
@@ -1 +0,0 @@
1
- {"version":3,"file":"resource-sheet.mjs","names":["React"],"sources":["../../../../src/client/components/sheets/resource-sheet.tsx"],"sourcesContent":["/**\n * ResourceSheet Component\n *\n * Universal sheet component for viewing/editing collections and globals.\n * Uses FormView/GlobalFormView internally for consistent UI and behavior.\n * Container queries provide automatic responsive layout.\n *\n * @example\n * ```tsx\n * // Collection usage\n * <ResourceSheet\n * type=\"collection\"\n * collection=\"posts\"\n * itemId=\"123\"\n * open={isOpen}\n * onOpenChange={setIsOpen}\n * onSave={(data) => console.log('Saved:', data)}\n * />\n *\n * // Global usage\n * <ResourceSheet\n * type=\"global\"\n * global=\"siteSettings\"\n * open={isOpen}\n * onOpenChange={setIsOpen}\n * onSave={(data) => console.log('Saved:', data)}\n * />\n * ```\n */\n\nimport * as React from \"react\";\nimport {\n LocaleScopeProvider,\n selectBasePath,\n selectNavigate,\n useAdminStore,\n} from \"../../runtime\";\nimport FormView from \"../../views/collection/form-view\";\nimport GlobalFormView from \"../../views/globals/global-form-view\";\nimport { Sheet, SheetContent } from \"../ui/sheet\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Base props shared between collection and global sheets\n */\ninterface ResourceSheetBaseProps {\n /**\n * Is sheet open\n */\n open: boolean;\n\n /**\n * Callback when sheet open state changes\n */\n onOpenChange: (open: boolean) => void;\n\n /**\n * Callback after successful save\n * Receives the saved data\n */\n onSave?: (data: any) => void;\n\n /**\n * Side of the screen where sheet appears\n * @default \"right\"\n */\n side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n}\n\n/**\n * Props for collection resource type\n */\ninterface CollectionSheetProps extends ResourceSheetBaseProps {\n type: \"collection\";\n\n /**\n * Collection name\n */\n collection: string;\n\n /**\n * Item ID (undefined for create, string for edit)\n */\n itemId?: string;\n\n /**\n * Default values for create mode (prefill)\n * Useful for pre-populating relation fields when creating from a parent context\n */\n defaultValues?: Record<string, any>;\n}\n\n/**\n * Props for global resource type\n */\ninterface GlobalSheetProps extends ResourceSheetBaseProps {\n type: \"global\";\n\n /**\n * Global name\n */\n global: string;\n}\n\n/**\n * Discriminated union of all resource sheet props\n */\nexport type ResourceSheetProps = CollectionSheetProps | GlobalSheetProps;\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function ResourceSheet(props: ResourceSheetProps) {\n const { open, onOpenChange, onSave, side = \"right\" } = props;\n const navigate = useAdminStore(selectNavigate);\n const basePath = useAdminStore(selectBasePath);\n\n const handleSuccess = React.useCallback(\n (data: any) => {\n onSave?.(data);\n onOpenChange(false);\n },\n [onSave, onOpenChange],\n );\n\n return (\n <Sheet open={open} onOpenChange={onOpenChange}>\n <SheetContent side={side} className=\"overflow-y-auto p-6 pt-12\">\n {/* LocaleScopeProvider isolates locale changes in nested forms */}\n <LocaleScopeProvider>\n {props.type === \"collection\" ? (\n <FormView\n collection={props.collection}\n id={props.itemId}\n defaultValues={props.defaultValues}\n config={undefined}\n allCollectionsConfig={undefined}\n navigate={navigate}\n basePath={basePath}\n onSuccess={handleSuccess}\n showMeta={false}\n />\n ) : (\n <GlobalFormView\n global={props.global}\n config={undefined}\n allGlobalsConfig={undefined}\n navigate={navigate}\n basePath={basePath}\n onSuccess={handleSuccess}\n showMeta={false}\n />\n )}\n </LocaleScopeProvider>\n </SheetContent>\n </Sheet>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoHA,SAAgB,cAAc,OAA2B;CACvD,MAAM,EAAE,MAAM,cAAc,QAAQ,OAAO,YAAY;CACvD,MAAM,WAAW,cAAc,eAAe;CAC9C,MAAM,WAAW,cAAc,eAAe;CAE9C,MAAM,gBAAgBA,QAAM,aACzB,SAAc;AACb,WAAS,KAAK;AACd,eAAa,MAAM;IAErB,CAAC,QAAQ,aAAa,CACvB;AAED,QACE,oBAAC;EAAY;EAAoB;YAC/B,oBAAC;GAAmB;GAAM,WAAU;aAElC,oBAAC,iCACE,MAAM,SAAS,eACd,oBAAC;IACC,YAAY,MAAM;IAClB,IAAI,MAAM;IACV,eAAe,MAAM;IACrB,QAAQ;IACR,sBAAsB;IACZ;IACA;IACV,WAAW;IACX,UAAU;KACV,GAEF,oBAAC;IACC,QAAQ,MAAM;IACd,QAAQ;IACR,kBAAkB;IACR;IACA;IACV,WAAW;IACX,UAAU;KACV,GAEgB;IACT;GACT"}
@@ -1,2 +0,0 @@
1
- import "react/jsx-runtime";
2
- import { Accordion } from "@base-ui/react/accordion";
@@ -1 +0,0 @@
1
- {"version":3,"file":"accordion.mjs","names":["Accordion","AccordionPrimitive"],"sources":["../../../../src/client/components/ui/accordion.tsx"],"sourcesContent":["import { Accordion as AccordionPrimitive } from \"@base-ui/react/accordion\";\nimport { Icon } from \"@iconify/react\";\nimport { cn } from \"../../lib/utils\";\n\nfunction Accordion({ className, ...props }: AccordionPrimitive.Root.Props) {\n return (\n <AccordionPrimitive.Root\n data-slot=\"accordion\"\n className={cn(\n \"overflow-hidden border border-border/60 bg-card/30 backdrop-blur-md flex w-full flex-col\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AccordionItem({ className, ...props }: AccordionPrimitive.Item.Props) {\n return (\n <AccordionPrimitive.Item\n data-slot=\"accordion-item\"\n className={cn(\n \"data-open:bg-muted/30 data-open:backdrop-blur-sm not-last:border-b border-border/40 transition-colors\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AccordionTrigger({\n className,\n children,\n ...props\n}: AccordionPrimitive.Trigger.Props) {\n return (\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger\n data-slot=\"accordion-trigger\"\n className={cn(\n \"**:data-[slot=accordion-trigger-icon]:text-muted-foreground gap-4 px-4 py-3 text-left text-sm font-medium hover:bg-muted/20 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 group/accordion-trigger relative flex flex-1 items-center justify-between transition-all outline-none disabled:pointer-events-none disabled:opacity-50\",\n className,\n )}\n {...props}\n >\n {children}\n <Icon\n icon=\"ph:caret-down\"\n data-slot=\"accordion-trigger-icon\"\n className=\"pointer-events-none shrink-0 transition-transform duration-200 group-aria-expanded/accordion-trigger:rotate-180\"\n />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n );\n}\n\nfunction AccordionContent({\n className,\n children,\n ...props\n}: AccordionPrimitive.Panel.Props) {\n return (\n <AccordionPrimitive.Panel\n data-slot=\"accordion-content\"\n className=\"data-open:animate-accordion-down data-closed:animate-accordion-up overflow-hidden\"\n {...props}\n >\n <div\n className={cn(\n \"px-4 pt-0 pb-4 text-sm [&_a]:hover:text-foreground h-(--accordion-panel-height) data-ending-style:h-0 data-starting-style:h-0 [&_a]:underline [&_a]:underline-offset-3 [&_p:not(:last-child)]:mb-4\",\n className,\n )}\n >\n {children}\n </div>\n </AccordionPrimitive.Panel>\n );\n}\n\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent };\n"],"mappings":";;;;;;AAIA,SAASA,YAAU,EAAE,WAAW,GAAG,SAAwC;AACzE,QACE,oBAACC,UAAmB;EAClB,aAAU;EACV,WAAW,GACT,4FACA,UACD;EACD,GAAI;GACJ;;AAIN,SAAS,cAAc,EAAE,WAAW,GAAG,SAAwC;AAC7E,QACE,oBAACA,UAAmB;EAClB,aAAU;EACV,WAAW,GACT,yGACA,UACD;EACD,GAAI;GACJ;;AAIN,SAAS,iBAAiB,EACxB,WACA,UACA,GAAG,SACgC;AACnC,QACE,oBAACA,UAAmB;EAAO,WAAU;YACnC,qBAACA,UAAmB;GAClB,aAAU;GACV,WAAW,GACT,iXACA,UACD;GACD,GAAI;cAEH,UACD,oBAAC;IACC,MAAK;IACL,aAAU;IACV,WAAU;KACV;IACyB;GACH;;AAIhC,SAAS,iBAAiB,EACxB,WACA,UACA,GAAG,SAC8B;AACjC,QACE,oBAACA,UAAmB;EAClB,aAAU;EACV,WAAU;EACV,GAAI;YAEJ,oBAAC;GACC,WAAW,GACT,sMACA,UACD;GAEA;IACG;GACmB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"alert.mjs","names":[],"sources":["../../../../src/client/components/ui/alert.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"#questpie/admin/client/lib/utils\";\n\nconst alertVariants = cva(\n \"grid gap-0.5 border px-2 py-1.5 text-left text-xs/relaxed has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-1.5 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-3.5 w-full relative group/alert\",\n {\n variants: {\n variant: {\n default: \"bg-card text-card-foreground\",\n destructive:\n \"text-destructive bg-card *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n },\n);\n\nfunction Alert({\n className,\n variant,\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof alertVariants>) {\n return (\n <div\n data-slot=\"alert\"\n role=\"alert\"\n className={cn(alertVariants({ variant }), className)}\n {...props}\n />\n );\n}\n\nfunction AlertTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-title\"\n className={cn(\n \"font-medium group-has-[>svg]/alert:col-start-2 [&_a]:hover:text-foreground [&_a]:underline [&_a]:underline-offset-3\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDescription({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-description\"\n className={cn(\n \"text-muted-foreground text-xs/relaxed text-balance md:text-pretty [&_p:not(:last-child)]:mb-4 [&_a]:hover:text-foreground [&_a]:underline [&_a]:underline-offset-3\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-action\"\n className={cn(\"absolute top-1.5 right-2\", className)}\n {...props}\n />\n );\n}\n\nexport { Alert, AlertTitle, AlertDescription, AlertAction };\n"],"mappings":";;;;;;AAKA,MAAM,gBAAgB,IACpB,8TACA;CACE,UAAU,EACR,SAAS;EACP,SAAS;EACT,aACE;EACH,EACF;CACD,iBAAiB,EACf,SAAS,WACV;CACF,CACF;AAED,SAAS,MAAM,EACb,WACA,SACA,GAAG,SACgE;AACnE,QACE,oBAAC;EACC,aAAU;EACV,MAAK;EACL,WAAW,GAAG,cAAc,EAAE,SAAS,CAAC,EAAE,UAAU;EACpD,GAAI;GACJ;;AAiBN,SAAS,iBAAiB,EACxB,WACA,GAAG,SAC2B;AAC9B,QACE,oBAAC;EACC,aAAU;EACV,WAAW,GACT,sKACA,UACD;EACD,GAAI;GACJ"}
@@ -1,3 +0,0 @@
1
- import "react";
2
- import "react/jsx-runtime";
3
- import "@base-ui/react/avatar";
@@ -1,3 +0,0 @@
1
- import "react";
2
- import "class-variance-authority";
3
- import { useRender } from "@base-ui/react/use-render";
@@ -1 +0,0 @@
1
- {"version":3,"file":"badge.mjs","names":[],"sources":["../../../../src/client/components/ui/badge.tsx"],"sourcesContent":["import { mergeProps } from \"@base-ui/react/merge-props\";\nimport { useRender } from \"@base-ui/react/use-render\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst badgeVariants = cva(\n \"h-5 gap-1 rounded-none border border-transparent px-2 py-0.5 text-[0.625rem] font-medium transition-all has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:size-2.5! inline-flex items-center justify-center w-fit whitespace-nowrap shrink-0 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-colors overflow-hidden group/badge\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary/10 text-primary border-primary border backdrop-blur-sm [a]:hover:bg-primary/80\",\n secondary:\n \"bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80\",\n destructive:\n \"bg-destructive/10 [a]:hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive dark:bg-destructive/20\",\n outline:\n \"border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground bg-input/20 \",\n ghost:\n \"hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n },\n);\n\nfunction Badge({\n className,\n variant = \"default\",\n render,\n ...props\n}: useRender.ComponentProps<\"span\"> & VariantProps<typeof badgeVariants>) {\n return useRender({\n defaultTagName: \"span\",\n props: mergeProps<\"span\">(\n {\n className: cn(badgeVariants({ className, variant })),\n },\n props,\n ),\n render,\n state: {\n slot: \"badge\",\n variant,\n },\n });\n}\n\nexport { Badge, badgeVariants };\n"],"mappings":";;;;;;AAMA,MAAM,gBAAgB,IACpB,2gBACA;CACE,UAAU,EACR,SAAS;EACP,SACE;EACF,WACE;EACF,aACE;EACF,SACE;EACF,OACE;EACF,MAAM;EACP,EACF;CACD,iBAAiB,EACf,SAAS,WACV;CACF,CACF;AAED,SAAS,MAAM,EACb,WACA,UAAU,WACV,QACA,GAAG,SACqE;AACxE,QAAO,UAAU;EACf,gBAAgB;EAChB,OAAO,WACL,EACE,WAAW,GAAG,cAAc;GAAE;GAAW;GAAS,CAAC,CAAC,EACrD,EACD,MACD;EACD;EACA,OAAO;GACL,MAAM;GACN;GACD;EACF,CAAC"}
@@ -1,3 +0,0 @@
1
- import "react/jsx-runtime";
2
- import { Button } from "@base-ui/react/button";
3
- import "class-variance-authority";