@lattice-php/lattice 0.30.0 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. package/dist/action/components/action-form.js +26 -25
  2. package/dist/action/components/action-form.js.map +1 -1
  3. package/dist/action/components/action-group.js.map +1 -1
  4. package/dist/action/components/action-trigger-provider.js.map +1 -1
  5. package/dist/action/components/action.js.map +1 -1
  6. package/dist/action/lib/run-action.js +2 -1
  7. package/dist/action/lib/run-action.js.map +1 -1
  8. package/dist/appearance/index.js.map +1 -1
  9. package/dist/chat/components/chat-box.js +4 -2
  10. package/dist/chat/components/chat-box.js.map +1 -1
  11. package/dist/chat/components/message-list.js.map +1 -1
  12. package/dist/chat/components/message.js.map +1 -1
  13. package/dist/chat/components/prompt-input.js.map +1 -1
  14. package/dist/chat/hooks/use-chat.js +2 -1
  15. package/dist/chat/hooks/use-chat.js.map +1 -1
  16. package/dist/chat/lib/transport.js.map +1 -1
  17. package/dist/chat/parts/text.js.map +1 -1
  18. package/dist/chat/parts/tool-call.js.map +1 -1
  19. package/dist/core/api.js.map +1 -1
  20. package/dist/core/event-names.d.ts +1 -0
  21. package/dist/core/event-names.js +1 -0
  22. package/dist/core/event-names.js.map +1 -1
  23. package/dist/core/hooks/column-sizing.js.map +1 -1
  24. package/dist/core/hooks/use-column-resizing.js.map +1 -1
  25. package/dist/core/materialize.js.map +1 -1
  26. package/dist/core/registry-context.js.map +1 -1
  27. package/dist/core/renderer.js +2 -1
  28. package/dist/core/renderer.js.map +1 -1
  29. package/dist/core/test-id.js.map +1 -1
  30. package/dist/core/upload.js.map +1 -1
  31. package/dist/create-app.js +1 -1
  32. package/dist/create-app.js.map +1 -1
  33. package/dist/effects/registry.js +2 -1
  34. package/dist/effects/registry.js.map +1 -1
  35. package/dist/form/components/base/field.js.map +1 -1
  36. package/dist/form/components/base/submit-button.js.map +1 -1
  37. package/dist/form/components/fields/add-row-menu.js.map +1 -1
  38. package/dist/form/components/fields/builder.js +2 -1
  39. package/dist/form/components/fields/builder.js.map +1 -1
  40. package/dist/form/components/fields/checkbox.js.map +1 -1
  41. package/dist/form/components/fields/choice.js.map +1 -1
  42. package/dist/form/components/fields/color-picker-field.js.map +1 -1
  43. package/dist/form/components/fields/date-input.js.map +1 -1
  44. package/dist/form/components/fields/date-picker-field.js.map +1 -1
  45. package/dist/form/components/fields/date-picker-value.js.map +1 -1
  46. package/dist/form/components/fields/date-picker.js.map +1 -1
  47. package/dist/form/components/fields/date-time-input.js.map +1 -1
  48. package/dist/form/components/fields/file-upload.js +3 -2
  49. package/dist/form/components/fields/file-upload.js.map +1 -1
  50. package/dist/form/components/fields/number-input.js.map +1 -1
  51. package/dist/form/components/fields/otp-input.js.map +1 -1
  52. package/dist/form/components/fields/password-input.js.map +1 -1
  53. package/dist/form/components/fields/repeater.js +2 -1
  54. package/dist/form/components/fields/repeater.js.map +1 -1
  55. package/dist/form/components/fields/rich-editor-field.js +6 -5
  56. package/dist/form/components/fields/rich-editor-field.js.map +1 -1
  57. package/dist/form/components/fields/rich-editor.js.map +1 -1
  58. package/dist/form/components/fields/row-action-menu.js.map +1 -1
  59. package/dist/form/components/fields/row-actions.js.map +1 -1
  60. package/dist/form/components/fields/row-item.js.map +1 -1
  61. package/dist/form/components/fields/row-templates.js.map +1 -1
  62. package/dist/form/components/fields/select.js.map +1 -1
  63. package/dist/form/components/fields/simple-field.js.map +1 -1
  64. package/dist/form/components/fields/table-rows.js.map +1 -1
  65. package/dist/form/components/fields/text-input.js.map +1 -1
  66. package/dist/form/components/fields/textarea.js.map +1 -1
  67. package/dist/form/components/fields/time-input.js.map +1 -1
  68. package/dist/form/components/fields/time-picker-columns.js.map +1 -1
  69. package/dist/form/components/fields/time-picker.js +0 -1
  70. package/dist/form/components/fields/time-picker.js.map +1 -1
  71. package/dist/form/components/fields/toggle.js.map +1 -1
  72. package/dist/form/components/fields/use-flip-reorder.js.map +1 -1
  73. package/dist/form/components/form.js +7 -5
  74. package/dist/form/components/form.js.map +1 -1
  75. package/dist/form/components/wizard.js +1 -1
  76. package/dist/form/components/wizard.js.map +1 -1
  77. package/dist/form/hooks/resolved-nodes.js.map +1 -1
  78. package/dist/form/hooks/use-dependent-field.js +2 -1
  79. package/dist/form/hooks/use-dependent-field.js.map +1 -1
  80. package/dist/form/hooks/use-form-resolver.js +2 -1
  81. package/dist/form/hooks/use-form-resolver.js.map +1 -1
  82. package/dist/form/hooks/values.js +2 -1
  83. package/dist/form/hooks/values.js.map +1 -1
  84. package/dist/form/lib/conditions.js +1 -1
  85. package/dist/form/lib/conditions.js.map +1 -1
  86. package/dist/form/lib/field-dom-name.js.map +1 -1
  87. package/dist/form/lib/field-props.js +1 -1
  88. package/dist/form/lib/field-props.js.map +1 -1
  89. package/dist/form/lib/form-path.js.map +1 -1
  90. package/dist/form/lib/form-transport.js.map +1 -1
  91. package/dist/form/lib/prefill-targets.js.map +1 -1
  92. package/dist/form/lib/wizard-steps.js.map +1 -1
  93. package/dist/form/rich-editor/builtins.js.map +1 -1
  94. package/dist/format/date-time.d.ts +1 -0
  95. package/dist/format/date-time.js +5 -1
  96. package/dist/format/date-time.js.map +1 -1
  97. package/dist/format/number.js.map +1 -1
  98. package/dist/i18n/config.js.map +1 -1
  99. package/dist/i18n/date-time-formatter.d.ts +13 -0
  100. package/dist/i18n/date-time-formatter.js +28 -0
  101. package/dist/i18n/date-time-formatter.js.map +1 -0
  102. package/dist/i18n/date-time.js +1 -1
  103. package/dist/i18n/date-time.js.map +1 -1
  104. package/dist/i18n/index.js +1 -1
  105. package/dist/i18n/instance.js +2 -0
  106. package/dist/i18n/instance.js.map +1 -1
  107. package/dist/i18n/locale.js +1 -1
  108. package/dist/i18n/locale.js.map +1 -1
  109. package/dist/i18n/timezone.js.map +1 -1
  110. package/dist/i18n/translatable.js.map +1 -1
  111. package/dist/icons/icon-renderer.js.map +1 -1
  112. package/dist/icons/sprite.js.map +1 -1
  113. package/dist/layout/components/breadcrumbs.js.map +1 -1
  114. package/dist/layout/components/callouts.d.ts +2 -1
  115. package/dist/layout/components/callouts.js +6 -2
  116. package/dist/layout/components/callouts.js.map +1 -1
  117. package/dist/layout/components/dropdown.js.map +1 -1
  118. package/dist/layout/components/menu-item.js.map +1 -1
  119. package/dist/layout/components/menu.js.map +1 -1
  120. package/dist/layout/components/popover.js.map +1 -1
  121. package/dist/layout/components/schema-layout.js.map +1 -1
  122. package/dist/layout/components/sidebar.js.map +1 -1
  123. package/dist/lib/color.js +1 -1
  124. package/dist/lib/color.js.map +1 -1
  125. package/dist/lib/use-media-query.js.map +1 -1
  126. package/dist/notifications/components/empty-state.js.map +1 -1
  127. package/dist/notifications/components/notification-item.js.map +1 -1
  128. package/dist/notifications/components/notification-list.js.map +1 -1
  129. package/dist/notifications/components/notifications.js.map +1 -1
  130. package/dist/notifications/store.js.map +1 -1
  131. package/dist/page.js.map +1 -1
  132. package/dist/provider-base.js.map +1 -1
  133. package/dist/realtime/listeners.js.map +1 -1
  134. package/dist/remote/components/data-list.js.map +1 -1
  135. package/dist/table/components/bulk-bar.js.map +1 -1
  136. package/dist/table/components/cells/badge-cell.js.map +1 -1
  137. package/dist/table/components/cells/boolean-cell.js.map +1 -1
  138. package/dist/table/components/cells/icon-cell.js.map +1 -1
  139. package/dist/table/components/cells/numeric-cell.js.map +1 -1
  140. package/dist/table/components/cells/stack-cell.js.map +1 -1
  141. package/dist/table/components/cells/text-cell.js.map +1 -1
  142. package/dist/table/components/column-filter-control.js.map +1 -1
  143. package/dist/table/components/column-header.js.map +1 -1
  144. package/dist/table/components/column-visibility-menu.js +2 -1
  145. package/dist/table/components/column-visibility-menu.js.map +1 -1
  146. package/dist/table/components/filter-bar.js +2 -1
  147. package/dist/table/components/filter-bar.js.map +1 -1
  148. package/dist/table/components/filter-controls.js +6 -5
  149. package/dist/table/components/filter-controls.js.map +1 -1
  150. package/dist/table/components/filter-value-input.js.map +1 -1
  151. package/dist/table/components/pagination.d.ts +5 -1
  152. package/dist/table/components/pagination.js +25 -6
  153. package/dist/table/components/pagination.js.map +1 -1
  154. package/dist/table/components/sort-bar.js.map +1 -1
  155. package/dist/table/components/table-cell.js +2 -1
  156. package/dist/table/components/table-cell.js.map +1 -1
  157. package/dist/table/components/table-search.js.map +1 -1
  158. package/dist/table/components/table.js +6 -2
  159. package/dist/table/components/table.js.map +1 -1
  160. package/dist/table/hooks/use-column-visibility.js.map +1 -1
  161. package/dist/table/hooks/use-table-selection.js +2 -1
  162. package/dist/table/hooks/use-table-selection.js.map +1 -1
  163. package/dist/table/hooks/use-table.d.ts +2 -0
  164. package/dist/table/hooks/use-table.js +12 -0
  165. package/dist/table/hooks/use-table.js.map +1 -1
  166. package/dist/table/lib/bulk.js.map +1 -1
  167. package/dist/table/lib/filter-values.js.map +1 -1
  168. package/dist/table/lib/format.js.map +1 -1
  169. package/dist/table/lib/payload.d.ts +2 -0
  170. package/dist/table/lib/payload.js +18 -3
  171. package/dist/table/lib/payload.js.map +1 -1
  172. package/dist/table/lib/query.js +2 -1
  173. package/dist/table/lib/query.js.map +1 -1
  174. package/dist/toast/callout.d.ts +1 -0
  175. package/dist/toast/callout.js +9 -1
  176. package/dist/toast/callout.js.map +1 -1
  177. package/dist/toast/index.d.ts +1 -1
  178. package/dist/toast/index.js +2 -2
  179. package/dist/toast/toaster.js.map +1 -1
  180. package/dist/types/generated.d.ts +9 -1
  181. package/dist/ui/affix-group.js.map +1 -1
  182. package/dist/ui/avatar.js.map +1 -1
  183. package/dist/ui/badge.js.map +1 -1
  184. package/dist/ui/button.js.map +1 -1
  185. package/dist/ui/card.js.map +1 -1
  186. package/dist/ui/chart-view.js.map +1 -1
  187. package/dist/ui/chart.js.map +1 -1
  188. package/dist/ui/checkbox.js.map +1 -1
  189. package/dist/ui/collapsible.js.map +1 -1
  190. package/dist/ui/color-picker.js.map +1 -1
  191. package/dist/ui/combobox.js.map +1 -1
  192. package/dist/ui/confirm-dialog.js.map +1 -1
  193. package/dist/ui/copyable-text.js.map +1 -1
  194. package/dist/ui/dialog.js.map +1 -1
  195. package/dist/ui/dropdown-menu.js.map +1 -1
  196. package/dist/ui/floating-panel.js.map +1 -1
  197. package/dist/ui/fragment.js +2 -1
  198. package/dist/ui/fragment.js.map +1 -1
  199. package/dist/ui/heading.js.map +1 -1
  200. package/dist/ui/icon-button.js.map +1 -1
  201. package/dist/ui/icon.js.map +1 -1
  202. package/dist/ui/image-preview.js.map +1 -1
  203. package/dist/ui/info-tooltip.js.map +1 -1
  204. package/dist/ui/input-error.js.map +1 -1
  205. package/dist/ui/input-otp.js.map +1 -1
  206. package/dist/ui/link.js.map +1 -1
  207. package/dist/ui/modal.js.map +1 -1
  208. package/dist/ui/password-input.js.map +1 -1
  209. package/dist/ui/progress.js.map +1 -1
  210. package/dist/ui/section.js +4 -2
  211. package/dist/ui/section.js.map +1 -1
  212. package/dist/ui/segmented-control.js.map +1 -1
  213. package/dist/ui/segmented-pills.js.map +1 -1
  214. package/dist/ui/tabs.js.map +1 -1
  215. package/dist/ui/text.js.map +1 -1
  216. package/dist/ui/tooltip.js.map +1 -1
  217. package/dist/vite-typescript-refresh.js.map +1 -1
  218. package/dist/vite.js.map +1 -1
  219. package/dist-standalone/chunks/chart-view-ZCTbih8A.js +59 -0
  220. package/dist-standalone/chunks/date-picker-field-CCnkf4SC.js +1 -0
  221. package/dist-standalone/chunks/dist-CK9gk4iB.js +1 -0
  222. package/dist-standalone/chunks/dist-DqlcM-vw.js +2 -0
  223. package/dist-standalone/chunks/icon-button-DcP25cn4.js +41 -0
  224. package/dist-standalone/chunks/instance-t58Awajh.js +1 -0
  225. package/dist-standalone/chunks/jsx-runtime-CN5ucv1d.js +1 -0
  226. package/dist-standalone/chunks/locale-CgtcxthU.js +1 -0
  227. package/dist-standalone/chunks/materialize-CWqnSEHR.js +1 -0
  228. package/dist-standalone/chunks/{notifications-echo-DsfNc4Ge.js → notifications-echo-uU87iJAV.js} +1 -1
  229. package/dist-standalone/chunks/number-BvVKQqOG.js +1 -0
  230. package/dist-standalone/chunks/page-props-B4GewgLI.js +1 -0
  231. package/dist-standalone/chunks/react-SIfiwpqq.js +1 -0
  232. package/dist-standalone/chunks/rich-editor-field-BtbU5XFS.js +158 -0
  233. package/dist-standalone/chunks/shared-props-B_wT1GcG.js +1 -0
  234. package/dist-standalone/chunks/subscriptions-BdHDnVA3.js +1 -0
  235. package/dist-standalone/chunks/time-picker-DSs9fDWe.js +1 -0
  236. package/dist-standalone/chunks/timezone-BukvzD0d.js +1 -0
  237. package/dist-standalone/chunks/translatable-DLw4h3x8.js +1 -0
  238. package/dist-standalone/chunks/use-effect-dispatcher-CiWYRvsF.js +97 -0
  239. package/dist-standalone/chunks/{with-selector-BwDoCrJJ.js → with-selector-zFUY-tQj.js} +1 -1
  240. package/dist-standalone/lattice.css +2 -2
  241. package/dist-standalone/lattice.js +4 -48
  242. package/dist-standalone/manifest.json +24 -15
  243. package/dist-standalone/sprite.svg +1 -1
  244. package/package.json +6 -6
  245. package/resources/icons/align-center.svg +1 -1
  246. package/resources/icons/align-justify.svg +1 -1
  247. package/resources/icons/align-left.svg +1 -1
  248. package/resources/icons/align-right.svg +1 -1
  249. package/resources/icons/arrow-down.svg +1 -1
  250. package/resources/icons/arrow-up.svg +1 -1
  251. package/resources/icons/bell.svg +1 -1
  252. package/resources/icons/bold.svg +1 -1
  253. package/resources/icons/calendar.svg +5 -5
  254. package/resources/icons/check.svg +1 -1
  255. package/resources/icons/chevron-down.svg +1 -1
  256. package/resources/icons/chevron-left.svg +1 -1
  257. package/resources/icons/chevron-right.svg +1 -1
  258. package/resources/icons/chevrons-up-down.svg +1 -1
  259. package/resources/icons/circle-alert.svg +1 -1
  260. package/resources/icons/circle-check.svg +1 -1
  261. package/resources/icons/circle-help.svg +1 -1
  262. package/resources/icons/circle-x.svg +1 -1
  263. package/resources/icons/clock.svg +1 -1
  264. package/resources/icons/code-xml.svg +1 -1
  265. package/resources/icons/code.svg +1 -1
  266. package/resources/icons/columns-3.svg +1 -1
  267. package/resources/icons/copy.svg +1 -1
  268. package/resources/icons/external-link.svg +1 -1
  269. package/resources/icons/eye-off.svg +1 -1
  270. package/resources/icons/eye.svg +1 -1
  271. package/resources/icons/filter.svg +1 -1
  272. package/resources/icons/heading-1.svg +1 -1
  273. package/resources/icons/heading-2.svg +1 -1
  274. package/resources/icons/heading-3.svg +1 -1
  275. package/resources/icons/heading.svg +1 -1
  276. package/resources/icons/highlighter.svg +1 -1
  277. package/resources/icons/info.svg +1 -1
  278. package/resources/icons/italic.svg +1 -1
  279. package/resources/icons/layout-dashboard.svg +1 -1
  280. package/resources/icons/link.svg +1 -1
  281. package/resources/icons/list-ordered.svg +1 -1
  282. package/resources/icons/list.svg +1 -1
  283. package/resources/icons/loader-2.svg +1 -1
  284. package/resources/icons/minus.svg +1 -1
  285. package/resources/icons/more-horizontal.svg +1 -1
  286. package/resources/icons/panel-left.svg +1 -1
  287. package/resources/icons/pencil-line.svg +1 -1
  288. package/resources/icons/pencil.svg +1 -1
  289. package/resources/icons/plus.svg +1 -1
  290. package/resources/icons/quote.svg +1 -1
  291. package/resources/icons/rotate-ccw.svg +1 -1
  292. package/resources/icons/rows-3.svg +1 -1
  293. package/resources/icons/search.svg +1 -1
  294. package/resources/icons/send.svg +1 -1
  295. package/resources/icons/settings.svg +1 -1
  296. package/resources/icons/smile.svg +1 -1
  297. package/resources/icons/strikethrough.svg +1 -1
  298. package/resources/icons/table.svg +1 -1
  299. package/resources/icons/trash-2.svg +1 -1
  300. package/resources/icons/underline.svg +1 -1
  301. package/resources/icons/x.svg +1 -1
  302. package/dist-standalone/chunks/chart-view-CpYsLvzR.js +0 -36
  303. package/dist-standalone/chunks/date-picker-field-lX8N40Ii.js +0 -1
  304. package/dist-standalone/chunks/dist-PaT1gYi_.js +0 -2
  305. package/dist-standalone/chunks/jsx-runtime-Drll_-DD.js +0 -1
  306. package/dist-standalone/chunks/locale-CXqr7LPR.js +0 -1
  307. package/dist-standalone/chunks/page-props-ClpVjpOc.js +0 -1
  308. package/dist-standalone/chunks/react-B8IZ02wI.js +0 -1
  309. package/dist-standalone/chunks/rich-editor-field-C71csVJv.js +0 -154
  310. package/dist-standalone/chunks/subscriptions-B1STcwPE.js +0 -1
  311. package/dist-standalone/chunks/use-effect-dispatcher-I8So0l_I.js +0 -97
@@ -1 +1 @@
1
- {"version":3,"file":"use-column-resizing.js","names":[],"sources":["../../../resources/js/core/hooks/use-column-resizing.ts"],"sourcesContent":["import type { HTMLAttributes, KeyboardEvent, PointerEvent } from \"react\";\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport {\n buildColumnGridTemplate,\n defaultColumnWidthPx,\n maxColumnWidthPx,\n minColumnWidthPx,\n type SizableColumn,\n} from \"./column-sizing\";\n\ntype DragState = {\n key: string;\n maxWidth: number;\n overrides: Record<string, number | undefined> | null;\n startWidth: number;\n startX: number;\n};\n\ntype ResizeHandleProps = HTMLAttributes<HTMLDivElement> & {\n \"aria-label\": string;\n \"aria-orientation\": \"vertical\";\n \"aria-valuemax\": number;\n \"aria-valuemin\": number;\n \"aria-valuenow\": number;\n role: \"separator\";\n tabIndex: number;\n};\n\ntype StoredColumnWidths = {\n columns: string[];\n overrides: Record<string, number>;\n};\n\nconst emptyTracks: string[] = [];\n\nexport function useColumnResizing({\n columnGapPx = 0,\n columns,\n enabled,\n leadingTracks = emptyTracks,\n showIndicator = false,\n storageKey,\n trailingTracks = emptyTracks,\n}: {\n columnGapPx?: number;\n columns: SizableColumn[];\n enabled: boolean;\n leadingTracks?: string[];\n showIndicator?: boolean;\n storageKey?: string;\n trailingTracks?: string[];\n}) {\n const columnKeys = useMemo(() => columns.map((column) => column.key), [columns]);\n const [overrides, setOverrides] = useState<Record<string, number | undefined>>(() =>\n readStoredOverrides(storageKey, columns),\n );\n const overridesRef = useRef(overrides);\n const drag = useRef<DragState | null>(null);\n const resizeRootRef = useRef<HTMLDivElement | null>(null);\n\n const templateForOverrides = useCallback(\n (nextOverrides: Record<string, number | undefined>): string =>\n buildColumnGridTemplate({\n columns,\n leadingTracks,\n trailingTracks,\n overrides: enabled ? nextOverrides : {},\n }),\n [columns, enabled, leadingTracks, trailingTracks],\n );\n\n const gridTemplateColumns = useMemo(\n () => templateForOverrides(overrides),\n [overrides, templateForOverrides],\n );\n\n const applyTemplate = useCallback((template: string): void => {\n const root = resizeRootRef.current;\n\n if (!root) {\n return;\n }\n\n root.style.gridTemplateColumns = template;\n root.style.setProperty(\"--lattice-table-columns\", template);\n }, []);\n\n const commitOverrides = useCallback(\n (next: Record<string, number | undefined>) => {\n overridesRef.current = next;\n setOverrides(next);\n writeStoredOverrides(storageKey, columnKeys, next);\n applyTemplate(templateForOverrides(next));\n },\n [applyTemplate, columnKeys, storageKey, templateForOverrides],\n );\n\n const overridesWithColumnWidth = useCallback(\n (\n current: Record<string, number | undefined>,\n column: SizableColumn,\n width: number,\n maxWidth?: number,\n ): Record<string, number | undefined> => ({\n ...current,\n [column.key]: Math.min(\n maxWidth ?? maxColumnWidthPx(column),\n Math.max(minColumnWidthPx(column), width),\n ),\n }),\n [],\n );\n\n const setColumnWidth = useCallback(\n (column: SizableColumn, width: number, maxWidth?: number) => {\n commitOverrides(overridesWithColumnWidth(overridesRef.current, column, width, maxWidth));\n },\n [commitOverrides, overridesWithColumnWidth],\n );\n\n const resetColumnWidth = useCallback(\n (column: SizableColumn) => {\n const next = { ...overridesRef.current };\n delete next[column.key];\n\n commitOverrides(next);\n },\n [commitOverrides],\n );\n\n const resetColumns = useCallback(() => {\n commitOverrides({});\n }, [commitOverrides]);\n\n const hasOverrides =\n enabled && Object.values(overrides).some((width) => typeof width === \"number\");\n\n const currentColumnWidth = useCallback(\n (column: SizableColumn): number =>\n overridesRef.current[column.key] ?? defaultColumnWidthPx(column),\n [],\n );\n\n const getResizeHandleProps = useCallback(\n (column: SizableColumn): ResizeHandleProps => {\n const max = maxColumnWidthPx(column);\n const min = minColumnWidthPx(column);\n const current = currentColumnWidth(column);\n const label = column.label ?? column.key;\n const indicatorClass = showIndicator ? \"after:bg-lt-border\" : \"after:bg-transparent\";\n\n const maxWidthForHandle = (handle: HTMLDivElement): number =>\n maxColumnWidthForGrid({\n column,\n columnGapPx,\n columns,\n grid: resizeRootRef.current ?? handle.parentElement?.parentElement,\n leadingTracks,\n trailingTracks,\n });\n\n const resizeBy = (handle: HTMLDivElement, delta: number): void =>\n setColumnWidth(column, current + delta, maxWidthForHandle(handle));\n\n const finishDrag = (event: PointerEvent<HTMLDivElement>, releaseCapture: boolean): void => {\n const active = drag.current;\n\n if (active?.key !== column.key) {\n return;\n }\n\n drag.current = null;\n if (active.overrides !== null) {\n commitOverrides(active.overrides);\n }\n\n if (releaseCapture) {\n event.currentTarget.releasePointerCapture?.(event.pointerId);\n }\n };\n\n return {\n \"aria-label\": `Resize ${label}`,\n \"aria-orientation\": \"vertical\",\n \"aria-valuemax\": max,\n \"aria-valuemin\": min,\n \"aria-valuenow\": current,\n className: `absolute inset-y-0 right-0 hidden w-2 cursor-col-resize touch-none items-stretch justify-center md:flex after:my-1 after:w-px ${indicatorClass} hover:after:bg-lt-border focus-visible:outline-none focus-visible:after:bg-lt-ring`,\n onDoubleClick: () => resetColumnWidth(column),\n onKeyDown: (event: KeyboardEvent<HTMLDivElement>) => {\n if (!enabled) {\n return;\n }\n\n const step = event.shiftKey ? 32 : 8;\n\n if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n resizeBy(event.currentTarget, -step);\n }\n\n if (event.key === \"ArrowRight\") {\n event.preventDefault();\n resizeBy(event.currentTarget, step);\n }\n\n if (event.key === \"Home\") {\n event.preventDefault();\n setColumnWidth(column, min);\n }\n\n if (event.key === \"End\") {\n event.preventDefault();\n const handleMax = maxWidthForHandle(event.currentTarget);\n setColumnWidth(column, handleMax, handleMax);\n }\n\n if (event.key === \"Enter\" || event.key === \"Escape\") {\n event.preventDefault();\n resetColumnWidth(column);\n }\n },\n onPointerDown: (event: PointerEvent<HTMLDivElement>) => {\n if (!enabled) {\n return;\n }\n\n const parentWidth = event.currentTarget.parentElement?.getBoundingClientRect().width ?? 0;\n drag.current = {\n key: column.key,\n maxWidth: maxWidthForHandle(event.currentTarget),\n overrides: null,\n startWidth: parentWidth > 0 ? parentWidth : current,\n startX: event.clientX,\n };\n event.currentTarget.setPointerCapture?.(event.pointerId);\n event.preventDefault();\n },\n onPointerMove: (event: PointerEvent<HTMLDivElement>) => {\n const active = drag.current;\n\n if (!enabled || active?.key !== column.key) {\n return;\n }\n\n const next = overridesWithColumnWidth(\n overridesRef.current,\n column,\n active.startWidth + event.clientX - active.startX,\n active.maxWidth,\n );\n\n active.overrides = next;\n overridesRef.current = next;\n applyTemplate(templateForOverrides(next));\n },\n onPointerUp: (event: PointerEvent<HTMLDivElement>) => {\n finishDrag(event, true);\n },\n onPointerCancel: (event: PointerEvent<HTMLDivElement>) => {\n finishDrag(event, true);\n },\n onLostPointerCapture: (event: PointerEvent<HTMLDivElement>) => {\n finishDrag(event, false);\n },\n role: \"separator\",\n tabIndex: 0,\n };\n },\n [\n columnGapPx,\n columns,\n currentColumnWidth,\n enabled,\n leadingTracks,\n applyTemplate,\n commitOverrides,\n overridesWithColumnWidth,\n resetColumnWidth,\n setColumnWidth,\n showIndicator,\n templateForOverrides,\n trailingTracks,\n ],\n );\n\n return {\n getResizeHandleProps,\n gridTemplateColumns,\n hasOverrides,\n resizeRootRef,\n resetColumns,\n resetColumnWidth,\n };\n}\n\nfunction maxColumnWidthForGrid({\n column,\n columnGapPx,\n columns,\n grid,\n leadingTracks,\n trailingTracks,\n}: {\n column: SizableColumn;\n columnGapPx: number;\n columns: SizableColumn[];\n grid: Element | null | undefined;\n leadingTracks: string[];\n trailingTracks: string[];\n}): number {\n const gridWidth = grid?.getBoundingClientRect().width ?? 0;\n\n if (gridWidth <= 0) {\n return maxColumnWidthPx(column);\n }\n\n const utilityWidth = [...leadingTracks, ...trailingTracks].reduce(\n (sum, track) => sum + fixedTrackWidthPx(track),\n 0,\n );\n const siblingMinWidth = columns.reduce(\n (sum, sibling) => (sibling.key === column.key ? sum : sum + minColumnWidthPx(sibling)),\n 0,\n );\n const trackCount = columns.length + leadingTracks.length + trailingTracks.length;\n const gapWidth = Math.max(0, trackCount - 1) * columnGapPx;\n const available = gridWidth - utilityWidth - siblingMinWidth - gapWidth;\n\n return Math.min(maxColumnWidthPx(column), Math.max(minColumnWidthPx(column), available));\n}\n\nfunction readStoredOverrides(\n storageKey: string | undefined,\n columns: SizableColumn[],\n): Record<string, number | undefined> {\n if (!storageKey || typeof window === \"undefined\") {\n return {};\n }\n\n try {\n const raw = window.localStorage.getItem(storageKey);\n\n if (raw === null) {\n return {};\n }\n\n const stored = JSON.parse(raw) as unknown;\n\n if (!isStoredColumnWidths(stored)) {\n removeStoredOverrides(storageKey);\n\n return {};\n }\n\n const overrides = sanitizeOverrides(stored.overrides, columns);\n\n if (Object.keys(overrides).length === 0) {\n removeStoredOverrides(storageKey);\n }\n\n return overrides;\n } catch {\n removeStoredOverrides(storageKey);\n\n return {};\n }\n}\n\nfunction writeStoredOverrides(\n storageKey: string | undefined,\n columnKeys: string[],\n overrides: Record<string, number | undefined>,\n): void {\n if (!storageKey || typeof window === \"undefined\") {\n return;\n }\n\n const stored: Record<string, number> = {};\n const knownKeys = new Set(columnKeys);\n\n for (const [key, value] of Object.entries(overrides)) {\n if (knownKeys.has(key) && typeof value === \"number\" && Number.isFinite(value)) {\n stored[key] = value;\n }\n }\n\n if (Object.keys(stored).length === 0) {\n removeStoredOverrides(storageKey);\n\n return;\n }\n\n try {\n window.localStorage.setItem(\n storageKey,\n JSON.stringify({\n columns: columnKeys,\n overrides: stored,\n }),\n );\n } catch {\n return;\n }\n}\n\nfunction removeStoredOverrides(storageKey: string): void {\n if (typeof window === \"undefined\") {\n return;\n }\n\n try {\n window.localStorage.removeItem(storageKey);\n } catch {\n return;\n }\n}\n\nfunction isStoredColumnWidths(value: unknown): value is StoredColumnWidths {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n const record = value as Record<string, unknown>;\n\n return (\n Array.isArray(record.columns) &&\n record.columns.every((column) => typeof column === \"string\") &&\n typeof record.overrides === \"object\" &&\n record.overrides !== null &&\n !Array.isArray(record.overrides)\n );\n}\n\nfunction sanitizeOverrides(\n overrides: Record<string, unknown>,\n columns: SizableColumn[],\n): Record<string, number | undefined> {\n const next: Record<string, number | undefined> = {};\n\n for (const column of columns) {\n const value = overrides[column.key];\n\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n continue;\n }\n\n next[column.key] = Math.min(\n maxColumnWidthPx(column),\n Math.max(minColumnWidthPx(column), value),\n );\n }\n\n return next;\n}\n\nfunction fixedTrackWidthPx(track: string): number {\n const value = track.trim();\n const px = value.match(/^([0-9.]+)px$/);\n\n if (px) {\n return Number.parseFloat(px[1]);\n }\n\n const rem = value.match(/^([0-9.]+)rem$/);\n\n if (rem) {\n return Number.parseFloat(rem[1]) * rootFontSizePx();\n }\n\n return 0;\n}\n\nfunction rootFontSizePx(): number {\n if (typeof window === \"undefined\") {\n return 16;\n }\n\n const parsed = Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize);\n\n return Number.isFinite(parsed) && parsed > 0 ? parsed : 16;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-column-resizing.js","names":[],"sources":["../../../resources/js/core/hooks/use-column-resizing.ts"],"sourcesContent":["import type { HTMLAttributes, KeyboardEvent, PointerEvent } from \"react\";\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport {\n buildColumnGridTemplate,\n defaultColumnWidthPx,\n maxColumnWidthPx,\n minColumnWidthPx,\n type SizableColumn,\n} from \"./column-sizing\";\n\ntype DragState = {\n key: string;\n maxWidth: number;\n overrides: Record<string, number | undefined> | null;\n startWidth: number;\n startX: number;\n};\n\ntype ResizeHandleProps = HTMLAttributes<HTMLDivElement> & {\n \"aria-label\": string;\n \"aria-orientation\": \"vertical\";\n \"aria-valuemax\": number;\n \"aria-valuemin\": number;\n \"aria-valuenow\": number;\n role: \"separator\";\n tabIndex: number;\n};\n\ntype StoredColumnWidths = {\n columns: string[];\n overrides: Record<string, number>;\n};\n\nconst emptyTracks: string[] = [];\n\nexport function useColumnResizing({\n columnGapPx = 0,\n columns,\n enabled,\n leadingTracks = emptyTracks,\n showIndicator = false,\n storageKey,\n trailingTracks = emptyTracks,\n}: {\n columnGapPx?: number;\n columns: SizableColumn[];\n enabled: boolean;\n leadingTracks?: string[];\n showIndicator?: boolean;\n storageKey?: string;\n trailingTracks?: string[];\n}) {\n const columnKeys = useMemo(() => columns.map((column) => column.key), [columns]);\n const [overrides, setOverrides] = useState<Record<string, number | undefined>>(() =>\n readStoredOverrides(storageKey, columns),\n );\n const overridesRef = useRef(overrides);\n const drag = useRef<DragState | null>(null);\n const resizeRootRef = useRef<HTMLDivElement | null>(null);\n\n const templateForOverrides = useCallback(\n (nextOverrides: Record<string, number | undefined>): string =>\n buildColumnGridTemplate({\n columns,\n leadingTracks,\n trailingTracks,\n overrides: enabled ? nextOverrides : {},\n }),\n [columns, enabled, leadingTracks, trailingTracks],\n );\n\n const gridTemplateColumns = useMemo(\n () => templateForOverrides(overrides),\n [overrides, templateForOverrides],\n );\n\n const applyTemplate = useCallback((template: string): void => {\n const root = resizeRootRef.current;\n\n if (!root) {\n return;\n }\n\n root.style.gridTemplateColumns = template;\n root.style.setProperty(\"--lattice-table-columns\", template);\n }, []);\n\n const commitOverrides = useCallback(\n (next: Record<string, number | undefined>) => {\n overridesRef.current = next;\n setOverrides(next);\n writeStoredOverrides(storageKey, columnKeys, next);\n applyTemplate(templateForOverrides(next));\n },\n [applyTemplate, columnKeys, storageKey, templateForOverrides],\n );\n\n const overridesWithColumnWidth = useCallback(\n (\n current: Record<string, number | undefined>,\n column: SizableColumn,\n width: number,\n maxWidth?: number,\n ): Record<string, number | undefined> => ({\n ...current,\n [column.key]: Math.min(\n maxWidth ?? maxColumnWidthPx(column),\n Math.max(minColumnWidthPx(column), width),\n ),\n }),\n [],\n );\n\n const setColumnWidth = useCallback(\n (column: SizableColumn, width: number, maxWidth?: number) => {\n commitOverrides(overridesWithColumnWidth(overridesRef.current, column, width, maxWidth));\n },\n [commitOverrides, overridesWithColumnWidth],\n );\n\n const resetColumnWidth = useCallback(\n (column: SizableColumn) => {\n const next = { ...overridesRef.current };\n delete next[column.key];\n\n commitOverrides(next);\n },\n [commitOverrides],\n );\n\n const resetColumns = useCallback(() => {\n commitOverrides({});\n }, [commitOverrides]);\n\n const hasOverrides =\n enabled && Object.values(overrides).some((width) => typeof width === \"number\");\n\n const currentColumnWidth = useCallback(\n (column: SizableColumn): number =>\n overridesRef.current[column.key] ?? defaultColumnWidthPx(column),\n [],\n );\n\n const getResizeHandleProps = useCallback(\n (column: SizableColumn): ResizeHandleProps => {\n const max = maxColumnWidthPx(column);\n const min = minColumnWidthPx(column);\n const current = currentColumnWidth(column);\n const label = column.label ?? column.key;\n const indicatorClass = showIndicator ? \"after:bg-lt-border\" : \"after:bg-transparent\";\n\n const maxWidthForHandle = (handle: HTMLDivElement): number =>\n maxColumnWidthForGrid({\n column,\n columnGapPx,\n columns,\n grid: resizeRootRef.current ?? handle.parentElement?.parentElement,\n leadingTracks,\n trailingTracks,\n });\n\n const resizeBy = (handle: HTMLDivElement, delta: number): void =>\n setColumnWidth(column, current + delta, maxWidthForHandle(handle));\n\n const finishDrag = (event: PointerEvent<HTMLDivElement>, releaseCapture: boolean): void => {\n const active = drag.current;\n\n if (active?.key !== column.key) {\n return;\n }\n\n drag.current = null;\n if (active.overrides !== null) {\n commitOverrides(active.overrides);\n }\n\n if (releaseCapture) {\n event.currentTarget.releasePointerCapture?.(event.pointerId);\n }\n };\n\n return {\n \"aria-label\": `Resize ${label}`,\n \"aria-orientation\": \"vertical\",\n \"aria-valuemax\": max,\n \"aria-valuemin\": min,\n \"aria-valuenow\": current,\n className: `absolute inset-y-0 right-0 hidden w-2 cursor-col-resize touch-none items-stretch justify-center md:flex after:my-1 after:w-px ${indicatorClass} hover:after:bg-lt-border focus-visible:outline-none focus-visible:after:bg-lt-ring`,\n onDoubleClick: () => resetColumnWidth(column),\n onKeyDown: (event: KeyboardEvent<HTMLDivElement>) => {\n if (!enabled) {\n return;\n }\n\n const step = event.shiftKey ? 32 : 8;\n\n if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n resizeBy(event.currentTarget, -step);\n }\n\n if (event.key === \"ArrowRight\") {\n event.preventDefault();\n resizeBy(event.currentTarget, step);\n }\n\n if (event.key === \"Home\") {\n event.preventDefault();\n setColumnWidth(column, min);\n }\n\n if (event.key === \"End\") {\n event.preventDefault();\n const handleMax = maxWidthForHandle(event.currentTarget);\n setColumnWidth(column, handleMax, handleMax);\n }\n\n if (event.key === \"Enter\" || event.key === \"Escape\") {\n event.preventDefault();\n resetColumnWidth(column);\n }\n },\n onPointerDown: (event: PointerEvent<HTMLDivElement>) => {\n if (!enabled) {\n return;\n }\n\n const parentWidth = event.currentTarget.parentElement?.getBoundingClientRect().width ?? 0;\n drag.current = {\n key: column.key,\n maxWidth: maxWidthForHandle(event.currentTarget),\n overrides: null,\n startWidth: parentWidth > 0 ? parentWidth : current,\n startX: event.clientX,\n };\n event.currentTarget.setPointerCapture?.(event.pointerId);\n event.preventDefault();\n },\n onPointerMove: (event: PointerEvent<HTMLDivElement>) => {\n const active = drag.current;\n\n if (!enabled || active?.key !== column.key) {\n return;\n }\n\n const next = overridesWithColumnWidth(\n overridesRef.current,\n column,\n active.startWidth + event.clientX - active.startX,\n active.maxWidth,\n );\n\n active.overrides = next;\n overridesRef.current = next;\n applyTemplate(templateForOverrides(next));\n },\n onPointerUp: (event: PointerEvent<HTMLDivElement>) => {\n finishDrag(event, true);\n },\n onPointerCancel: (event: PointerEvent<HTMLDivElement>) => {\n finishDrag(event, true);\n },\n onLostPointerCapture: (event: PointerEvent<HTMLDivElement>) => {\n finishDrag(event, false);\n },\n role: \"separator\",\n tabIndex: 0,\n };\n },\n [\n columnGapPx,\n columns,\n currentColumnWidth,\n enabled,\n leadingTracks,\n applyTemplate,\n commitOverrides,\n overridesWithColumnWidth,\n resetColumnWidth,\n setColumnWidth,\n showIndicator,\n templateForOverrides,\n trailingTracks,\n ],\n );\n\n return {\n getResizeHandleProps,\n gridTemplateColumns,\n hasOverrides,\n resizeRootRef,\n resetColumns,\n resetColumnWidth,\n };\n}\n\nfunction maxColumnWidthForGrid({\n column,\n columnGapPx,\n columns,\n grid,\n leadingTracks,\n trailingTracks,\n}: {\n column: SizableColumn;\n columnGapPx: number;\n columns: SizableColumn[];\n grid: Element | null | undefined;\n leadingTracks: string[];\n trailingTracks: string[];\n}): number {\n const gridWidth = grid?.getBoundingClientRect().width ?? 0;\n\n if (gridWidth <= 0) {\n return maxColumnWidthPx(column);\n }\n\n const utilityWidth = [...leadingTracks, ...trailingTracks].reduce(\n (sum, track) => sum + fixedTrackWidthPx(track),\n 0,\n );\n const siblingMinWidth = columns.reduce(\n (sum, sibling) => (sibling.key === column.key ? sum : sum + minColumnWidthPx(sibling)),\n 0,\n );\n const trackCount = columns.length + leadingTracks.length + trailingTracks.length;\n const gapWidth = Math.max(0, trackCount - 1) * columnGapPx;\n const available = gridWidth - utilityWidth - siblingMinWidth - gapWidth;\n\n return Math.min(maxColumnWidthPx(column), Math.max(minColumnWidthPx(column), available));\n}\n\nfunction readStoredOverrides(\n storageKey: string | undefined,\n columns: SizableColumn[],\n): Record<string, number | undefined> {\n if (!storageKey || typeof window === \"undefined\") {\n return {};\n }\n\n try {\n const raw = window.localStorage.getItem(storageKey);\n\n if (raw === null) {\n return {};\n }\n\n const stored = JSON.parse(raw) as unknown;\n\n if (!isStoredColumnWidths(stored)) {\n removeStoredOverrides(storageKey);\n\n return {};\n }\n\n const overrides = sanitizeOverrides(stored.overrides, columns);\n\n if (Object.keys(overrides).length === 0) {\n removeStoredOverrides(storageKey);\n }\n\n return overrides;\n } catch {\n removeStoredOverrides(storageKey);\n\n return {};\n }\n}\n\nfunction writeStoredOverrides(\n storageKey: string | undefined,\n columnKeys: string[],\n overrides: Record<string, number | undefined>,\n): void {\n if (!storageKey || typeof window === \"undefined\") {\n return;\n }\n\n const stored: Record<string, number> = {};\n const knownKeys = new Set(columnKeys);\n\n for (const [key, value] of Object.entries(overrides)) {\n if (knownKeys.has(key) && typeof value === \"number\" && Number.isFinite(value)) {\n stored[key] = value;\n }\n }\n\n if (Object.keys(stored).length === 0) {\n removeStoredOverrides(storageKey);\n\n return;\n }\n\n try {\n window.localStorage.setItem(\n storageKey,\n JSON.stringify({\n columns: columnKeys,\n overrides: stored,\n }),\n );\n } catch {\n return;\n }\n}\n\nfunction removeStoredOverrides(storageKey: string): void {\n if (typeof window === \"undefined\") {\n return;\n }\n\n try {\n window.localStorage.removeItem(storageKey);\n } catch {\n return;\n }\n}\n\nfunction isStoredColumnWidths(value: unknown): value is StoredColumnWidths {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n const record = value as Record<string, unknown>;\n\n return (\n Array.isArray(record.columns) &&\n record.columns.every((column) => typeof column === \"string\") &&\n typeof record.overrides === \"object\" &&\n record.overrides !== null &&\n !Array.isArray(record.overrides)\n );\n}\n\nfunction sanitizeOverrides(\n overrides: Record<string, unknown>,\n columns: SizableColumn[],\n): Record<string, number | undefined> {\n const next: Record<string, number | undefined> = {};\n\n for (const column of columns) {\n const value = overrides[column.key];\n\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n continue;\n }\n\n next[column.key] = Math.min(\n maxColumnWidthPx(column),\n Math.max(minColumnWidthPx(column), value),\n );\n }\n\n return next;\n}\n\nfunction fixedTrackWidthPx(track: string): number {\n const value = track.trim();\n const px = value.match(/^([0-9.]+)px$/);\n\n if (px) {\n return Number.parseFloat(px[1]);\n }\n\n const rem = value.match(/^([0-9.]+)rem$/);\n\n if (rem) {\n return Number.parseFloat(rem[1]) * rootFontSizePx();\n }\n\n return 0;\n}\n\nfunction rootFontSizePx(): number {\n if (typeof window === \"undefined\") {\n return 16;\n }\n\n const parsed = Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize);\n\n return Number.isFinite(parsed) && parsed > 0 ? parsed : 16;\n}\n"],"mappings":";;;AAiCA,IAAM,cAAwB,CAAC;AAE/B,SAAgB,kBAAkB,EAChC,cAAc,GACd,SACA,SACA,gBAAgB,aAChB,gBAAgB,OAChB,YACA,iBAAiB,eAShB;CACD,MAAM,aAAa,cAAc,QAAQ,KAAK,WAAW,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;CAC/E,MAAM,CAAC,WAAW,gBAAgB,eAChC,oBAAoB,YAAY,OAAO,CACzC;CACA,MAAM,eAAe,OAAO,SAAS;CACrC,MAAM,OAAO,OAAyB,IAAI;CAC1C,MAAM,gBAAgB,OAA8B,IAAI;CAExD,MAAM,uBAAuB,aAC1B,kBACC,wBAAwB;EACtB;EACA;EACA;EACA,WAAW,UAAU,gBAAgB,CAAC;CACxC,CAAC,GACH;EAAC;EAAS;EAAS;EAAe;CAAc,CAClD;CAEA,MAAM,sBAAsB,cACpB,qBAAqB,SAAS,GACpC,CAAC,WAAW,oBAAoB,CAClC;CAEA,MAAM,gBAAgB,aAAa,aAA2B;EAC5D,MAAM,OAAO,cAAc;EAE3B,IAAI,CAAC,MACH;EAGF,KAAK,MAAM,sBAAsB;EACjC,KAAK,MAAM,YAAY,2BAA2B,QAAQ;CAC5D,GAAG,CAAC,CAAC;CAEL,MAAM,kBAAkB,aACrB,SAA6C;EAC5C,aAAa,UAAU;EACvB,aAAa,IAAI;EACjB,qBAAqB,YAAY,YAAY,IAAI;EACjD,cAAc,qBAAqB,IAAI,CAAC;CAC1C,GACA;EAAC;EAAe;EAAY;EAAY;CAAoB,CAC9D;CAEA,MAAM,2BAA2B,aAE7B,SACA,QACA,OACA,cACwC;EACxC,GAAG;GACF,OAAO,MAAM,KAAK,IACjB,YAAY,iBAAiB,MAAM,GACnC,KAAK,IAAI,iBAAiB,MAAM,GAAG,KAAK,CAC1C;CACF,IACA,CAAC,CACH;CAEA,MAAM,iBAAiB,aACpB,QAAuB,OAAe,aAAsB;EAC3D,gBAAgB,yBAAyB,aAAa,SAAS,QAAQ,OAAO,QAAQ,CAAC;CACzF,GACA,CAAC,iBAAiB,wBAAwB,CAC5C;CAEA,MAAM,mBAAmB,aACtB,WAA0B;EACzB,MAAM,OAAO,EAAE,GAAG,aAAa,QAAQ;EACvC,OAAO,KAAK,OAAO;EAEnB,gBAAgB,IAAI;CACtB,GACA,CAAC,eAAe,CAClB;CAEA,MAAM,eAAe,kBAAkB;EACrC,gBAAgB,CAAC,CAAC;CACpB,GAAG,CAAC,eAAe,CAAC;CAEpB,MAAM,eACJ,WAAW,OAAO,OAAO,SAAS,CAAC,CAAC,MAAM,UAAU,OAAO,UAAU,QAAQ;CAE/E,MAAM,qBAAqB,aACxB,WACC,aAAa,QAAQ,OAAO,QAAQ,qBAAqB,MAAM,GACjE,CAAC,CACH;CAiJA,OAAO;EACL,sBAhJ2B,aAC1B,WAA6C;GAC5C,MAAM,MAAM,iBAAiB,MAAM;GACnC,MAAM,MAAM,iBAAiB,MAAM;GACnC,MAAM,UAAU,mBAAmB,MAAM;GACzC,MAAM,QAAQ,OAAO,SAAS,OAAO;GACrC,MAAM,iBAAiB,gBAAgB,uBAAuB;GAE9D,MAAM,qBAAqB,WACzB,sBAAsB;IACpB;IACA;IACA;IACA,MAAM,cAAc,WAAW,OAAO,eAAe;IACrD;IACA;GACF,CAAC;GAEH,MAAM,YAAY,QAAwB,UACxC,eAAe,QAAQ,UAAU,OAAO,kBAAkB,MAAM,CAAC;GAEnE,MAAM,cAAc,OAAqC,mBAAkC;IACzF,MAAM,SAAS,KAAK;IAEpB,IAAI,QAAQ,QAAQ,OAAO,KACzB;IAGF,KAAK,UAAU;IACf,IAAI,OAAO,cAAc,MACvB,gBAAgB,OAAO,SAAS;IAGlC,IAAI,gBACF,MAAM,cAAc,wBAAwB,MAAM,SAAS;GAE/D;GAEA,OAAO;IACL,cAAc,UAAU;IACxB,oBAAoB;IACpB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,WAAW,iIAAiI,eAAe;IAC3J,qBAAqB,iBAAiB,MAAM;IAC5C,YAAY,UAAyC;KACnD,IAAI,CAAC,SACH;KAGF,MAAM,OAAO,MAAM,WAAW,KAAK;KAEnC,IAAI,MAAM,QAAQ,aAAa;MAC7B,MAAM,eAAe;MACrB,SAAS,MAAM,eAAe,CAAC,IAAI;KACrC;KAEA,IAAI,MAAM,QAAQ,cAAc;MAC9B,MAAM,eAAe;MACrB,SAAS,MAAM,eAAe,IAAI;KACpC;KAEA,IAAI,MAAM,QAAQ,QAAQ;MACxB,MAAM,eAAe;MACrB,eAAe,QAAQ,GAAG;KAC5B;KAEA,IAAI,MAAM,QAAQ,OAAO;MACvB,MAAM,eAAe;MACrB,MAAM,YAAY,kBAAkB,MAAM,aAAa;MACvD,eAAe,QAAQ,WAAW,SAAS;KAC7C;KAEA,IAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,UAAU;MACnD,MAAM,eAAe;MACrB,iBAAiB,MAAM;KACzB;IACF;IACA,gBAAgB,UAAwC;KACtD,IAAI,CAAC,SACH;KAGF,MAAM,cAAc,MAAM,cAAc,eAAe,sBAAsB,CAAC,CAAC,SAAS;KACxF,KAAK,UAAU;MACb,KAAK,OAAO;MACZ,UAAU,kBAAkB,MAAM,aAAa;MAC/C,WAAW;MACX,YAAY,cAAc,IAAI,cAAc;MAC5C,QAAQ,MAAM;KAChB;KACA,MAAM,cAAc,oBAAoB,MAAM,SAAS;KACvD,MAAM,eAAe;IACvB;IACA,gBAAgB,UAAwC;KACtD,MAAM,SAAS,KAAK;KAEpB,IAAI,CAAC,WAAW,QAAQ,QAAQ,OAAO,KACrC;KAGF,MAAM,OAAO,yBACX,aAAa,SACb,QACA,OAAO,aAAa,MAAM,UAAU,OAAO,QAC3C,OAAO,QACT;KAEA,OAAO,YAAY;KACnB,aAAa,UAAU;KACvB,cAAc,qBAAqB,IAAI,CAAC;IAC1C;IACA,cAAc,UAAwC;KACpD,WAAW,OAAO,IAAI;IACxB;IACA,kBAAkB,UAAwC;KACxD,WAAW,OAAO,IAAI;IACxB;IACA,uBAAuB,UAAwC;KAC7D,WAAW,OAAO,KAAK;IACzB;IACA,MAAM;IACN,UAAU;GACZ;EACF,GACA;GACE;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF,CAIA;EACA;EACA;EACA;EACA;EACA;CACF;AACF;AAEA,SAAS,sBAAsB,EAC7B,QACA,aACA,SACA,MACA,eACA,kBAQS;CACT,MAAM,YAAY,MAAM,sBAAsB,CAAC,CAAC,SAAS;CAEzD,IAAI,aAAa,GACf,OAAO,iBAAiB,MAAM;CAGhC,MAAM,eAAe,CAAC,GAAG,eAAe,GAAG,cAAc,CAAC,CAAC,QACxD,KAAK,UAAU,MAAM,kBAAkB,KAAK,GAC7C,CACF;CACA,MAAM,kBAAkB,QAAQ,QAC7B,KAAK,YAAa,QAAQ,QAAQ,OAAO,MAAM,MAAM,MAAM,iBAAiB,OAAO,GACpF,CACF;CACA,MAAM,aAAa,QAAQ,SAAS,cAAc,SAAS,eAAe;CAC1E,MAAM,WAAW,KAAK,IAAI,GAAG,aAAa,CAAC,IAAI;CAC/C,MAAM,YAAY,YAAY,eAAe,kBAAkB;CAE/D,OAAO,KAAK,IAAI,iBAAiB,MAAM,GAAG,KAAK,IAAI,iBAAiB,MAAM,GAAG,SAAS,CAAC;AACzF;AAEA,SAAS,oBACP,YACA,SACoC;CACpC,IAAI,CAAC,cAAc,OAAO,WAAW,aACnC,OAAO,CAAC;CAGV,IAAI;EACF,MAAM,MAAM,OAAO,aAAa,QAAQ,UAAU;EAElD,IAAI,QAAQ,MACV,OAAO,CAAC;EAGV,MAAM,SAAS,KAAK,MAAM,GAAG;EAE7B,IAAI,CAAC,qBAAqB,MAAM,GAAG;GACjC,sBAAsB,UAAU;GAEhC,OAAO,CAAC;EACV;EAEA,MAAM,YAAY,kBAAkB,OAAO,WAAW,OAAO;EAE7D,IAAI,OAAO,KAAK,SAAS,CAAC,CAAC,WAAW,GACpC,sBAAsB,UAAU;EAGlC,OAAO;CACT,QAAQ;EACN,sBAAsB,UAAU;EAEhC,OAAO,CAAC;CACV;AACF;AAEA,SAAS,qBACP,YACA,YACA,WACM;CACN,IAAI,CAAC,cAAc,OAAO,WAAW,aACnC;CAGF,MAAM,SAAiC,CAAC;CACxC,MAAM,YAAY,IAAI,IAAI,UAAU;CAEpC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,SAAS,GACjD,IAAI,UAAU,IAAI,GAAG,KAAK,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,GAC1E,OAAO,OAAO;CAIlB,IAAI,OAAO,KAAK,MAAM,CAAC,CAAC,WAAW,GAAG;EACpC,sBAAsB,UAAU;EAEhC;CACF;CAEA,IAAI;EACF,OAAO,aAAa,QAClB,YACA,KAAK,UAAU;GACb,SAAS;GACT,WAAW;EACb,CAAC,CACH;CACF,QAAQ;EACN;CACF;AACF;AAEA,SAAS,sBAAsB,YAA0B;CACvD,IAAI,OAAO,WAAW,aACpB;CAGF,IAAI;EACF,OAAO,aAAa,WAAW,UAAU;CAC3C,QAAQ;EACN;CACF;AACF;AAEA,SAAS,qBAAqB,OAA6C;CACzE,IAAI,OAAO,UAAU,YAAY,UAAU,MACzC,OAAO;CAGT,MAAM,SAAS;CAEf,OACE,MAAM,QAAQ,OAAO,OAAO,KAC5B,OAAO,QAAQ,OAAO,WAAW,OAAO,WAAW,QAAQ,KAC3D,OAAO,OAAO,cAAc,YAC5B,OAAO,cAAc,QACrB,CAAC,MAAM,QAAQ,OAAO,SAAS;AAEnC;AAEA,SAAS,kBACP,WACA,SACoC;CACpC,MAAM,OAA2C,CAAC;CAElD,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,QAAQ,UAAU,OAAO;EAE/B,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GACrD;EAGF,KAAK,OAAO,OAAO,KAAK,IACtB,iBAAiB,MAAM,GACvB,KAAK,IAAI,iBAAiB,MAAM,GAAG,KAAK,CAC1C;CACF;CAEA,OAAO;AACT;AAEA,SAAS,kBAAkB,OAAuB;CAChD,MAAM,QAAQ,MAAM,KAAK;CACzB,MAAM,KAAK,MAAM,MAAM,eAAe;CAEtC,IAAI,IACF,OAAO,OAAO,WAAW,GAAG,EAAE;CAGhC,MAAM,MAAM,MAAM,MAAM,gBAAgB;CAExC,IAAI,KACF,OAAO,OAAO,WAAW,IAAI,EAAE,IAAI,eAAe;CAGpD,OAAO;AACT;AAEA,SAAS,iBAAyB;CAChC,IAAI,OAAO,WAAW,aACpB,OAAO;CAGT,MAAM,SAAS,OAAO,WAAW,OAAO,iBAAiB,SAAS,eAAe,CAAC,CAAC,QAAQ;CAE3F,OAAO,OAAO,SAAS,MAAM,KAAK,SAAS,IAAI,SAAS;AAC1D"}
@@ -1 +1 @@
1
- {"version":3,"file":"materialize.js","names":[],"sources":["../../resources/js/core/materialize.ts"],"sourcesContent":["import type { Node, NodeProps, Schema } from \"./types\";\n\nexport type RemoteRow = Record<string, unknown>;\n\nexport type DataBindings = Record<string, string>;\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function dataBindings(value: unknown): DataBindings {\n if (!isRecord(value)) {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(value).filter((entry): entry is [string, string] => {\n return typeof entry[1] === \"string\";\n }),\n );\n}\n\nexport function rowValue(row: RemoteRow, key: string): unknown {\n if (key in row) {\n return row[key];\n }\n\n return key.split(\".\").reduce<unknown>((value, segment) => {\n return isRecord(value) ? value[segment] : undefined;\n }, row);\n}\n\nexport function materializeProps(props: unknown, row: RemoteRow): NodeProps {\n if (!isRecord(props)) {\n return {};\n }\n\n const { dataBindings: bindings, ...materialized } = props;\n\n for (const [prop, key] of Object.entries(dataBindings(bindings))) {\n const value = rowValue(row, key);\n\n if (value !== undefined) {\n materialized[prop] = value;\n }\n }\n\n return materialized;\n}\n\nexport function materializeNode(node: Node, row: RemoteRow): Node {\n return {\n ...node,\n props: materializeProps(node.props, row),\n schema: node.schema?.map((child) => materializeNode(child, row)),\n } as Node;\n}\n\nexport function materializeSchema(schema: Schema | undefined, row: RemoteRow): Schema {\n return schema?.map((node) => materializeNode(node, row)) ?? [];\n}\n"],"mappings":";AAMA,SAAgB,SAAS,OAAkD;CACzE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAgB,aAAa,OAA8B;CACzD,IAAI,CAAC,SAAS,KAAK,GACjB,OAAO,CAAC;CAGV,OAAO,OAAO,YACZ,OAAO,QAAQ,KAAK,EAAE,QAAQ,UAAqC;EACjE,OAAO,OAAO,MAAM,OAAO;CAC7B,CAAC,CACH;AACF;AAEA,SAAgB,SAAS,KAAgB,KAAsB;CAC7D,IAAI,OAAO,KACT,OAAO,IAAI;CAGb,OAAO,IAAI,MAAM,GAAG,EAAE,QAAiB,OAAO,YAAY;EACxD,OAAO,SAAS,KAAK,IAAI,MAAM,WAAW,KAAA;CAC5C,GAAG,GAAG;AACR;AAEA,SAAgB,iBAAiB,OAAgB,KAA2B;CAC1E,IAAI,CAAC,SAAS,KAAK,GACjB,OAAO,CAAC;CAGV,MAAM,EAAE,cAAc,UAAU,GAAG,iBAAiB;CAEpD,KAAK,MAAM,CAAC,MAAM,QAAQ,OAAO,QAAQ,aAAa,QAAQ,CAAC,GAAG;EAChE,MAAM,QAAQ,SAAS,KAAK,GAAG;EAE/B,IAAI,UAAU,KAAA,GACZ,aAAa,QAAQ;CAEzB;CAEA,OAAO;AACT;AAEA,SAAgB,gBAAgB,MAAY,KAAsB;CAChE,OAAO;EACL,GAAG;EACH,OAAO,iBAAiB,KAAK,OAAO,GAAG;EACvC,QAAQ,KAAK,QAAQ,KAAK,UAAU,gBAAgB,OAAO,GAAG,CAAC;CACjE;AACF;AAEA,SAAgB,kBAAkB,QAA4B,KAAwB;CACpF,OAAO,QAAQ,KAAK,SAAS,gBAAgB,MAAM,GAAG,CAAC,KAAK,CAAC;AAC/D"}
1
+ {"version":3,"file":"materialize.js","names":[],"sources":["../../resources/js/core/materialize.ts"],"sourcesContent":["import type { Node, NodeProps, Schema } from \"./types\";\n\nexport type RemoteRow = Record<string, unknown>;\n\nexport type DataBindings = Record<string, string>;\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function dataBindings(value: unknown): DataBindings {\n if (!isRecord(value)) {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(value).filter((entry): entry is [string, string] => {\n return typeof entry[1] === \"string\";\n }),\n );\n}\n\nexport function rowValue(row: RemoteRow, key: string): unknown {\n if (key in row) {\n return row[key];\n }\n\n return key.split(\".\").reduce<unknown>((value, segment) => {\n return isRecord(value) ? value[segment] : undefined;\n }, row);\n}\n\nexport function materializeProps(props: unknown, row: RemoteRow): NodeProps {\n if (!isRecord(props)) {\n return {};\n }\n\n const { dataBindings: bindings, ...materialized } = props;\n\n for (const [prop, key] of Object.entries(dataBindings(bindings))) {\n const value = rowValue(row, key);\n\n if (value !== undefined) {\n materialized[prop] = value;\n }\n }\n\n return materialized;\n}\n\nexport function materializeNode(node: Node, row: RemoteRow): Node {\n return {\n ...node,\n props: materializeProps(node.props, row),\n schema: node.schema?.map((child) => materializeNode(child, row)),\n } as Node;\n}\n\nexport function materializeSchema(schema: Schema | undefined, row: RemoteRow): Schema {\n return schema?.map((node) => materializeNode(node, row)) ?? [];\n}\n"],"mappings":";AAMA,SAAgB,SAAS,OAAkD;CACzE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAgB,aAAa,OAA8B;CACzD,IAAI,CAAC,SAAS,KAAK,GACjB,OAAO,CAAC;CAGV,OAAO,OAAO,YACZ,OAAO,QAAQ,KAAK,CAAC,CAAC,QAAQ,UAAqC;EACjE,OAAO,OAAO,MAAM,OAAO;CAC7B,CAAC,CACH;AACF;AAEA,SAAgB,SAAS,KAAgB,KAAsB;CAC7D,IAAI,OAAO,KACT,OAAO,IAAI;CAGb,OAAO,IAAI,MAAM,GAAG,CAAC,CAAC,QAAiB,OAAO,YAAY;EACxD,OAAO,SAAS,KAAK,IAAI,MAAM,WAAW,KAAA;CAC5C,GAAG,GAAG;AACR;AAEA,SAAgB,iBAAiB,OAAgB,KAA2B;CAC1E,IAAI,CAAC,SAAS,KAAK,GACjB,OAAO,CAAC;CAGV,MAAM,EAAE,cAAc,UAAU,GAAG,iBAAiB;CAEpD,KAAK,MAAM,CAAC,MAAM,QAAQ,OAAO,QAAQ,aAAa,QAAQ,CAAC,GAAG;EAChE,MAAM,QAAQ,SAAS,KAAK,GAAG;EAE/B,IAAI,UAAU,KAAA,GACZ,aAAa,QAAQ;CAEzB;CAEA,OAAO;AACT;AAEA,SAAgB,gBAAgB,MAAY,KAAsB;CAChE,OAAO;EACL,GAAG;EACH,OAAO,iBAAiB,KAAK,OAAO,GAAG;EACvC,QAAQ,KAAK,QAAQ,KAAK,UAAU,gBAAgB,OAAO,GAAG,CAAC;CACjE;AACF;AAEA,SAAgB,kBAAkB,QAA4B,KAAwB;CACpF,OAAO,QAAQ,KAAK,SAAS,gBAAgB,MAAM,GAAG,CAAC,KAAK,CAAC;AAC/D"}
@@ -1 +1 @@
1
- {"version":3,"file":"registry-context.js","names":[],"sources":["../../resources/js/core/registry-context.tsx"],"sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { ComponentRegistry, Registry } from \"./registry\";\nimport type { EffectHandlerRegistry } from \"@lattice-php/lattice/effects/registry\";\nimport type { ColumnRegistry } from \"@lattice-php/lattice/table/registry\";\n\n/**\n * Holds the active Registry for the current Provider subtree. Extracted into\n * its own module to break the circular reference between provider.tsx (which\n * imports the default registry instance) and use-effect-dispatcher.ts (which\n * imports the context selector). Neither file imports from the other; both\n * import from here.\n *\n * The context default is null. Selectors fall back to `_defaultRegistry`,\n * which provider.tsx sets at module evaluation time (after registry.ts has\n * finished loading). This avoids a synchronous evaluation cycle while\n * preserving the pre-existing behaviour that components work without a\n * surrounding <Provider>.\n */\nexport const RegistryContext = createContext<Registry | null>(null);\n\n/**\n * Called by provider.tsx at module-evaluation time, after registry.ts finishes\n * loading. The constraint is on CALLING this setter, not on importing this\n * module: do not call setDefaultRegistry from any module that evaluates before\n * registry.ts completes. (use-effect-dispatcher.ts safely imports the selectors\n * below — that import is exactly why this module was extracted.)\n */\nlet _defaultRegistry: Registry | null = null;\n\nexport function setDefaultRegistry(registry: Registry): void {\n _defaultRegistry = registry;\n}\n\nexport function useComponentRegistry(): ComponentRegistry {\n const registry = useContext(RegistryContext) ?? _defaultRegistry;\n return registry?.components ?? {};\n}\n\nexport function useColumnRegistry(): ColumnRegistry {\n const registry = useContext(RegistryContext) ?? _defaultRegistry;\n return registry?.columns ?? {};\n}\n\nexport function useEffectHandlerRegistry(): EffectHandlerRegistry {\n const registry = useContext(RegistryContext) ?? _defaultRegistry;\n return registry?.effects ?? {};\n}\n"],"mappings":";;;;;;;;;;;;;;;AAkBA,IAAa,kBAAkB,cAA+B,IAAI;;;;;;;;AASlE,IAAI,mBAAoC;AAExC,SAAgB,mBAAmB,UAA0B;CAC3D,mBAAmB;AACrB;AAEA,SAAgB,uBAA0C;CAExD,QADiB,WAAW,eAAe,KAAK,mBAC/B,cAAc,CAAC;AAClC;AAEA,SAAgB,oBAAoC;CAElD,QADiB,WAAW,eAAe,KAAK,mBAC/B,WAAW,CAAC;AAC/B;AAEA,SAAgB,2BAAkD;CAEhE,QADiB,WAAW,eAAe,KAAK,mBAC/B,WAAW,CAAC;AAC/B"}
1
+ {"version":3,"file":"registry-context.js","names":[],"sources":["../../resources/js/core/registry-context.tsx"],"sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { ComponentRegistry, Registry } from \"./registry\";\nimport type { EffectHandlerRegistry } from \"@lattice-php/lattice/effects/registry\";\nimport type { ColumnRegistry } from \"@lattice-php/lattice/table/registry\";\n\n/**\n * Holds the active Registry for the current Provider subtree. Extracted into\n * its own module to break the circular reference between provider.tsx (which\n * imports the default registry instance) and use-effect-dispatcher.ts (which\n * imports the context selector). Neither file imports from the other; both\n * import from here.\n *\n * The context default is null. Selectors fall back to `_defaultRegistry`,\n * which provider.tsx sets at module evaluation time (after registry.ts has\n * finished loading). This avoids a synchronous evaluation cycle while\n * preserving the pre-existing behaviour that components work without a\n * surrounding <Provider>.\n */\nexport const RegistryContext = createContext<Registry | null>(null);\n\n/**\n * Called by provider.tsx at module-evaluation time, after registry.ts finishes\n * loading. The constraint is on CALLING this setter, not on importing this\n * module: do not call setDefaultRegistry from any module that evaluates before\n * registry.ts completes. (use-effect-dispatcher.ts safely imports the selectors\n * below — that import is exactly why this module was extracted.)\n */\nlet _defaultRegistry: Registry | null = null;\n\nexport function setDefaultRegistry(registry: Registry): void {\n _defaultRegistry = registry;\n}\n\nexport function useComponentRegistry(): ComponentRegistry {\n const registry = useContext(RegistryContext) ?? _defaultRegistry;\n return registry?.components ?? {};\n}\n\nexport function useColumnRegistry(): ColumnRegistry {\n const registry = useContext(RegistryContext) ?? _defaultRegistry;\n return registry?.columns ?? {};\n}\n\nexport function useEffectHandlerRegistry(): EffectHandlerRegistry {\n const registry = useContext(RegistryContext) ?? _defaultRegistry;\n return registry?.effects ?? {};\n}\n"],"mappings":";;;;;;;;;;;;;;;AAkBA,IAAa,kBAAkB,cAA+B,IAAI;;;;;;;;AASlE,IAAI,mBAAoC;AAExC,SAAgB,mBAAmB,UAA0B;CAC3D,mBAAmB;AACrB;AAEA,SAAgB,uBAA0C;CAExD,QADiB,WAAW,eAAe,KAAK,iBAAA,EAC/B,cAAc,CAAC;AAClC;AAEA,SAAgB,oBAAoC;CAElD,QADiB,WAAW,eAAe,KAAK,iBAAA,EAC/B,WAAW,CAAC;AAC/B;AAEA,SAAgB,2BAAkD;CAEhE,QADiB,WAAW,eAAe,KAAK,iBAAA,EAC/B,WAAW,CAAC;AAC/B"}
@@ -59,9 +59,10 @@ var NodeRenderer = memo(function NodeRenderer({ node }) {
59
59
  if (collapsed && node.props?.hideWhenCollapsed === true) return null;
60
60
  if (!registration) return /* @__PURE__ */ jsx(MissingComponent, { node });
61
61
  const Component = registration.component;
62
+ const children = node.schema?.length ? /* @__PURE__ */ jsx(Renderer, { nodes: node.schema }) : null;
62
63
  const renderedComponent = /* @__PURE__ */ jsx(Component, {
63
64
  node,
64
- children: node.schema?.length ? /* @__PURE__ */ jsx(Renderer, { nodes: node.schema }) : null
65
+ children
65
66
  });
66
67
  if (registration.mode === "lazy") {
67
68
  const FallbackComponent = registration.fallback;
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.js","names":[],"sources":["../../resources/js/core/renderer.tsx"],"sourcesContent":["import { memo, Suspense } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type { Node } from \"./types\";\nimport { nodeKey } from \"./nodes\";\nimport { useCollapsed } from \"./collapsed-context\";\nimport { useComponentRegistry } from \"./registry-context\";\n\nconst warnedMissingTypes = new Set<string>();\n\nfunction warnMissingComponent(type: string): void {\n if (!import.meta.env.DEV || warnedMissingTypes.has(type)) {\n return;\n }\n\n warnedMissingTypes.add(type);\n console.warn(\n `[lattice] No component registered for node type \"${type}\" — Lattice rendered a fallback ` +\n \"placeholder. Likely causes: your app registry was not passed to \" +\n \"createLatticeApp({ registry }), or the registry key does not match the PHP \" +\n \"#[AsComponent]/AsField type.\",\n );\n}\n\nfunction MissingComponentIcon() {\n return (\n <svg\n aria-hidden=\"true\"\n className=\"size-lt-icon-md shrink-0\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n >\n <rect height=\"18\" rx=\"2\" strokeDasharray=\"4 3\" width=\"18\" x=\"3\" y=\"3\" />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n </svg>\n );\n}\n\n/**\n * Fallback for a node whose type has no registered renderer. Always renders a\n * visible, muted marker — icon-only survives tight spots like table cells — so\n * the gap is never invisible. Shows the type inline in development; keeps it\n * screen-reader-only (plus a hover tooltip) in production.\n */\nfunction MissingComponent({ node }: { node: Node }) {\n warnMissingComponent(node.type);\n\n const label = `Missing component: ${node.type}`;\n\n return (\n <span\n className=\"inline-flex items-center gap-1.5 align-middle text-lt-muted-fg\"\n data-lattice-missing-component={node.type}\n title={label}\n >\n <MissingComponentIcon />\n <span className={import.meta.env.DEV ? \"text-sm\" : \"sr-only\"}>{label}</span>\n </span>\n );\n}\n\nexport function Renderer({ nodes }: { nodes: Node[] }): ReactNode {\n return nodes.map((node, index) => <NodeRenderer key={nodeKey(node, index)} node={node} />);\n}\n\nexport function RenderNode({ node }: { node: Node }): ReactNode {\n return <NodeRenderer node={node} />;\n}\n\nconst NodeRenderer = memo(function NodeRenderer({ node }: { node: Node }) {\n const collapsed = useCollapsed();\n const registry = useComponentRegistry();\n const registration = registry[node.type];\n\n if (collapsed && node.props?.hideWhenCollapsed === true) {\n return null;\n }\n\n if (!registration) {\n return <MissingComponent node={node} />;\n }\n\n const Component = registration.component;\n const children = node.schema?.length ? <Renderer nodes={node.schema} /> : null;\n const renderedComponent = <Component node={node}>{children}</Component>;\n\n if (registration.mode === \"lazy\") {\n const FallbackComponent = registration.fallback;\n const fallback = FallbackComponent ? (\n <FallbackComponent node={node}>{null}</FallbackComponent>\n ) : null;\n\n return <Suspense fallback={fallback}>{renderedComponent}</Suspense>;\n }\n\n return renderedComponent;\n});\n"],"mappings":";;;;;;AAuBA,SAAS,uBAAuB;CAC9B,OACE,qBAAC,OAAD;EACE,eAAY;EACZ,WAAU;EACV,MAAK;EACL,QAAO;EACP,eAAc;EACd,gBAAe;EACf,aAAY;EACZ,SAAQ;YARV;GAUE,oBAAC,QAAD;IAAM,QAAO;IAAK,IAAG;IAAI,iBAAgB;IAAM,OAAM;IAAK,GAAE;IAAI,GAAE;GAAK,CAAA;GACvE,oBAAC,QAAD,EAAM,GAAE,UAAW,CAAA;GACnB,oBAAC,QAAD,EAAM,GAAE,aAAc,CAAA;EACnB;;AAET;;;;;;;AAQA,SAAS,iBAAiB,EAAE,QAAwB;CAClD,KAA0B;CAE1B,MAAM,QAAQ,sBAAsB,KAAK;CAEzC,OACE,qBAAC,QAAD;EACE,WAAU;EACV,kCAAgC,KAAK;EACrC,OAAO;YAHT,CAKE,oBAAC,sBAAD,CAAuB,CAAA,GACvB,oBAAC,QAAD;GAAM,WAA6C;aAAY;EAAY,CAAA,CACvE;;AAEV;AAEA,SAAgB,SAAS,EAAE,SAAuC;CAChE,OAAO,MAAM,KAAK,MAAM,UAAU,oBAAC,cAAD,EAA+C,KAAO,GAAnC,QAAQ,MAAM,KAAK,CAAgB,CAAC;AAC3F;AAEA,SAAgB,WAAW,EAAE,QAAmC;CAC9D,OAAO,oBAAC,cAAD,EAAoB,KAAO,CAAA;AACpC;AAEA,IAAM,eAAe,KAAK,SAAS,aAAa,EAAE,QAAwB;CACxE,MAAM,YAAY,aAAa;CAE/B,MAAM,eADW,qBACI,EAAS,KAAK;CAEnC,IAAI,aAAa,KAAK,OAAO,sBAAsB,MACjD,OAAO;CAGT,IAAI,CAAC,cACH,OAAO,oBAAC,kBAAD,EAAwB,KAAO,CAAA;CAGxC,MAAM,YAAY,aAAa;CAE/B,MAAM,oBAAoB,oBAAC,WAAD;EAAiB;EAAO,UADjC,KAAK,QAAQ,SAAS,oBAAC,UAAD,EAAU,OAAO,KAAK,OAAS,CAAA,IAAI;CACJ,CAAA;CAEtE,IAAI,aAAa,SAAS,QAAQ;EAChC,MAAM,oBAAoB,aAAa;EAKvC,OAAO,oBAAC,UAAD;GAAoB,UAJV,oBACf,oBAAC,mBAAD;IAAyB;cAAO;GAAwB,CAAA,IACtD;aAEkC;EAA4B,CAAA;CACpE;CAEA,OAAO;AACT,CAAC"}
1
+ {"version":3,"file":"renderer.js","names":[],"sources":["../../resources/js/core/renderer.tsx"],"sourcesContent":["import { memo, Suspense } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type { Node } from \"./types\";\nimport { nodeKey } from \"./nodes\";\nimport { useCollapsed } from \"./collapsed-context\";\nimport { useComponentRegistry } from \"./registry-context\";\n\nconst warnedMissingTypes = new Set<string>();\n\nfunction warnMissingComponent(type: string): void {\n if (!import.meta.env.DEV || warnedMissingTypes.has(type)) {\n return;\n }\n\n warnedMissingTypes.add(type);\n console.warn(\n `[lattice] No component registered for node type \"${type}\" — Lattice rendered a fallback ` +\n \"placeholder. Likely causes: your app registry was not passed to \" +\n \"createLatticeApp({ registry }), or the registry key does not match the PHP \" +\n \"#[AsComponent]/AsField type.\",\n );\n}\n\nfunction MissingComponentIcon() {\n return (\n <svg\n aria-hidden=\"true\"\n className=\"size-lt-icon-md shrink-0\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n >\n <rect height=\"18\" rx=\"2\" strokeDasharray=\"4 3\" width=\"18\" x=\"3\" y=\"3\" />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n </svg>\n );\n}\n\n/**\n * Fallback for a node whose type has no registered renderer. Always renders a\n * visible, muted marker — icon-only survives tight spots like table cells — so\n * the gap is never invisible. Shows the type inline in development; keeps it\n * screen-reader-only (plus a hover tooltip) in production.\n */\nfunction MissingComponent({ node }: { node: Node }) {\n warnMissingComponent(node.type);\n\n const label = `Missing component: ${node.type}`;\n\n return (\n <span\n className=\"inline-flex items-center gap-1.5 align-middle text-lt-muted-fg\"\n data-lattice-missing-component={node.type}\n title={label}\n >\n <MissingComponentIcon />\n <span className={import.meta.env.DEV ? \"text-sm\" : \"sr-only\"}>{label}</span>\n </span>\n );\n}\n\nexport function Renderer({ nodes }: { nodes: Node[] }): ReactNode {\n return nodes.map((node, index) => <NodeRenderer key={nodeKey(node, index)} node={node} />);\n}\n\nexport function RenderNode({ node }: { node: Node }): ReactNode {\n return <NodeRenderer node={node} />;\n}\n\nconst NodeRenderer = memo(function NodeRenderer({ node }: { node: Node }) {\n const collapsed = useCollapsed();\n const registry = useComponentRegistry();\n const registration = registry[node.type];\n\n if (collapsed && node.props?.hideWhenCollapsed === true) {\n return null;\n }\n\n if (!registration) {\n return <MissingComponent node={node} />;\n }\n\n const Component = registration.component;\n const children = node.schema?.length ? <Renderer nodes={node.schema} /> : null;\n const renderedComponent = <Component node={node}>{children}</Component>;\n\n if (registration.mode === \"lazy\") {\n const FallbackComponent = registration.fallback;\n const fallback = FallbackComponent ? (\n <FallbackComponent node={node}>{null}</FallbackComponent>\n ) : null;\n\n return <Suspense fallback={fallback}>{renderedComponent}</Suspense>;\n }\n\n return renderedComponent;\n});\n"],"mappings":";;;;;;AAuBA,SAAS,uBAAuB;CAC9B,OACE,qBAAC,OAAD;EACE,eAAY;EACZ,WAAU;EACV,MAAK;EACL,QAAO;EACP,eAAc;EACd,gBAAe;EACf,aAAY;EACZ,SAAQ;EARV,UAAA;GAUE,oBAAC,QAAD;IAAM,QAAO;IAAK,IAAG;IAAI,iBAAgB;IAAM,OAAM;IAAK,GAAE;IAAI,GAAE;GAAK,CAAA;GACvE,oBAAC,QAAD,EAAM,GAAE,UAAW,CAAA;GACnB,oBAAC,QAAD,EAAM,GAAE,aAAc,CAAA;EACnB;;AAET;;;;;;;AAQA,SAAS,iBAAiB,EAAE,QAAwB;CAClD,KAA0B;CAE1B,MAAM,QAAQ,sBAAsB,KAAK;CAEzC,OACE,qBAAC,QAAD;EACE,WAAU;EACV,kCAAgC,KAAK;EACrC,OAAO;EAHT,UAAA,CAKE,oBAAC,sBAAD,CAAuB,CAAA,GACvB,oBAAC,QAAD;GAAM,WAA6C;GAAY,UAAA;EAAY,CAAA,CACvE;;AAEV;AAEA,SAAgB,SAAS,EAAE,SAAuC;CAChE,OAAO,MAAM,KAAK,MAAM,UAAU,oBAAC,cAAD,EAA+C,KAAO,GAAnC,QAAQ,MAAM,KAAK,CAAgB,CAAC;AAC3F;AAEA,SAAgB,WAAW,EAAE,QAAmC;CAC9D,OAAO,oBAAC,cAAD,EAAoB,KAAO,CAAA;AACpC;AAEA,IAAM,eAAe,KAAK,SAAS,aAAa,EAAE,QAAwB;CACxE,MAAM,YAAY,aAAa;CAE/B,MAAM,eADW,qBACI,CAAA,CAAS,KAAK;CAEnC,IAAI,aAAa,KAAK,OAAO,sBAAsB,MACjD,OAAO;CAGT,IAAI,CAAC,cACH,OAAO,oBAAC,kBAAD,EAAwB,KAAO,CAAA;CAGxC,MAAM,YAAY,aAAa;CAC/B,MAAM,WAAW,KAAK,QAAQ,SAAS,oBAAC,UAAD,EAAU,OAAO,KAAK,OAAS,CAAA,IAAI;CAC1E,MAAM,oBAAoB,oBAAC,WAAD;EAAiB;EAAO;CAAoB,CAAA;CAEtE,IAAI,aAAa,SAAS,QAAQ;EAChC,MAAM,oBAAoB,aAAa;EAKvC,OAAO,oBAAC,UAAD;GAAoB,UAJV,oBACf,oBAAC,mBAAD;IAAyB;IAAO,UAAA;GAAwB,CAAA,IACtD;GAEkC,UAAA;EAA4B,CAAA;CACpE;CAEA,OAAO;AACT,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"test-id.js","names":[],"sources":["../../resources/js/core/test-id.ts"],"sourcesContent":["import type { Node } from \"./types\";\n\ntype IdentifiedNode = Pick<Node, \"id\" | \"key\">;\n\nexport function testIdentity(value: string | null | undefined): string | undefined {\n return value === undefined || value === null || value === \"\" ? undefined : value;\n}\n\nexport function nodeIdentity(node: IdentifiedNode): string | undefined {\n return testIdentity(node.key) ?? testIdentity(node.id);\n}\n\nexport function leafTestIdentity(value: string | null | undefined): string | undefined {\n return testIdentity(value)?.split(\".\").at(-1);\n}\n\nexport function prefixedTestId(\n prefix: string,\n value: string | null | undefined,\n): string | undefined {\n const identity = leafTestIdentity(value);\n\n return identity ? `${prefix}-${identity}` : undefined;\n}\n\nexport function prefixedNodeTestId(prefix: string, node: IdentifiedNode): string | undefined {\n return prefixedTestId(prefix, nodeIdentity(node));\n}\n"],"mappings":";AAIA,SAAgB,aAAa,OAAsD;CACjF,OAAO,UAAU,KAAA,KAAa,UAAU,QAAQ,UAAU,KAAK,KAAA,IAAY;AAC7E;AAEA,SAAgB,aAAa,MAA0C;CACrE,OAAO,aAAa,KAAK,GAAG,KAAK,aAAa,KAAK,EAAE;AACvD;AAEA,SAAgB,iBAAiB,OAAsD;CACrF,OAAO,aAAa,KAAK,GAAG,MAAM,GAAG,EAAE,GAAG,EAAE;AAC9C;AAEA,SAAgB,eACd,QACA,OACoB;CACpB,MAAM,WAAW,iBAAiB,KAAK;CAEvC,OAAO,WAAW,GAAG,OAAO,GAAG,aAAa,KAAA;AAC9C;AAEA,SAAgB,mBAAmB,QAAgB,MAA0C;CAC3F,OAAO,eAAe,QAAQ,aAAa,IAAI,CAAC;AAClD"}
1
+ {"version":3,"file":"test-id.js","names":[],"sources":["../../resources/js/core/test-id.ts"],"sourcesContent":["import type { Node } from \"./types\";\n\ntype IdentifiedNode = Pick<Node, \"id\" | \"key\">;\n\nexport function testIdentity(value: string | null | undefined): string | undefined {\n return value === undefined || value === null || value === \"\" ? undefined : value;\n}\n\nexport function nodeIdentity(node: IdentifiedNode): string | undefined {\n return testIdentity(node.key) ?? testIdentity(node.id);\n}\n\nexport function leafTestIdentity(value: string | null | undefined): string | undefined {\n return testIdentity(value)?.split(\".\").at(-1);\n}\n\nexport function prefixedTestId(\n prefix: string,\n value: string | null | undefined,\n): string | undefined {\n const identity = leafTestIdentity(value);\n\n return identity ? `${prefix}-${identity}` : undefined;\n}\n\nexport function prefixedNodeTestId(prefix: string, node: IdentifiedNode): string | undefined {\n return prefixedTestId(prefix, nodeIdentity(node));\n}\n"],"mappings":";AAIA,SAAgB,aAAa,OAAsD;CACjF,OAAO,UAAU,KAAA,KAAa,UAAU,QAAQ,UAAU,KAAK,KAAA,IAAY;AAC7E;AAEA,SAAgB,aAAa,MAA0C;CACrE,OAAO,aAAa,KAAK,GAAG,KAAK,aAAa,KAAK,EAAE;AACvD;AAEA,SAAgB,iBAAiB,OAAsD;CACrF,OAAO,aAAa,KAAK,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE;AAC9C;AAEA,SAAgB,eACd,QACA,OACoB;CACpB,MAAM,WAAW,iBAAiB,KAAK;CAEvC,OAAO,WAAW,GAAG,OAAO,GAAG,aAAa,KAAA;AAC9C;AAEA,SAAgB,mBAAmB,QAAgB,MAA0C;CAC3F,OAAO,eAAe,QAAQ,aAAa,IAAI,CAAC;AAClD"}
@@ -1 +1 @@
1
- {"version":3,"file":"upload.js","names":[],"sources":["../../resources/js/core/upload.ts"],"sourcesContent":["import { apiFetch } from \"./api\";\n\nexport type Transfer = {\n url: string;\n method: string;\n body: FormData | File | Blob;\n headers: Record<string, unknown>;\n onProgress?: (percent: number) => void;\n};\n\nexport type SignedUploadRequest = {\n ref: string;\n target: string;\n filename: string;\n contentType: string;\n values?: Record<string, unknown>;\n};\n\n/**\n * XHR rather than fetch because only XHR reports upload progress. A transport\n * failure leaves `status` at 0, which `new Response` rejects as out of range, so\n * it is mapped to 500 — otherwise the promise never settles and the upload hangs.\n */\nexport function xhrTransfer({\n url,\n method,\n body,\n headers,\n onProgress,\n}: Transfer): Promise<Response> {\n return new Promise((resolve, reject) => {\n const request = new XMLHttpRequest();\n\n request.open(method, url, true);\n Object.entries(headers).forEach(([key, value]) => request.setRequestHeader(key, String(value)));\n request.upload.onprogress = (event) => {\n if (event.lengthComputable) {\n onProgress?.(Math.round((event.loaded / event.total) * 100));\n }\n };\n request.onload = () => {\n try {\n resolve(new Response(request.responseText || null, { status: request.status || 500 }));\n } catch {\n reject(new Error(`Upload to ${url} returned an unusable response`));\n }\n };\n request.onerror = () => reject(new Error(`Upload to ${url} failed`));\n request.send(body);\n });\n}\n\n/**\n * Asks the component for a signed upload. Form fields spread their live values\n * in so the server-side schema walk can find the field inside repeater rows.\n */\nexport function requestSignedUpload(\n endpoint: string,\n { ref, target, filename, contentType, values }: SignedUploadRequest,\n): Promise<Response> {\n return apiFetch(endpoint, {\n method: \"POST\",\n ref,\n body: JSON.stringify({\n ...values,\n _sub: \"upload\",\n _target: target,\n filename,\n contentType,\n }),\n throwOnError: false,\n });\n}\n"],"mappings":";;;;;;;AAuBA,SAAgB,YAAY,EAC1B,KACA,QACA,MACA,SACA,cAC8B;CAC9B,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,UAAU,IAAI,eAAe;EAEnC,QAAQ,KAAK,QAAQ,KAAK,IAAI;EAC9B,OAAO,QAAQ,OAAO,EAAE,SAAS,CAAC,KAAK,WAAW,QAAQ,iBAAiB,KAAK,OAAO,KAAK,CAAC,CAAC;EAC9F,QAAQ,OAAO,cAAc,UAAU;GACrC,IAAI,MAAM,kBACR,aAAa,KAAK,MAAO,MAAM,SAAS,MAAM,QAAS,GAAG,CAAC;EAE/D;EACA,QAAQ,eAAe;GACrB,IAAI;IACF,QAAQ,IAAI,SAAS,QAAQ,gBAAgB,MAAM,EAAE,QAAQ,QAAQ,UAAU,IAAI,CAAC,CAAC;GACvF,QAAQ;IACN,uBAAO,IAAI,MAAM,aAAa,IAAI,+BAA+B,CAAC;GACpE;EACF;EACA,QAAQ,gBAAgB,uBAAO,IAAI,MAAM,aAAa,IAAI,QAAQ,CAAC;EACnE,QAAQ,KAAK,IAAI;CACnB,CAAC;AACH;;;;;AAMA,SAAgB,oBACd,UACA,EAAE,KAAK,QAAQ,UAAU,aAAa,UACnB;CACnB,OAAO,SAAS,UAAU;EACxB,QAAQ;EACR;EACA,MAAM,KAAK,UAAU;GACnB,GAAG;GACH,MAAM;GACN,SAAS;GACT;GACA;EACF,CAAC;EACD,cAAc;CAChB,CAAC;AACH"}
1
+ {"version":3,"file":"upload.js","names":[],"sources":["../../resources/js/core/upload.ts"],"sourcesContent":["import { apiFetch } from \"./api\";\n\nexport type Transfer = {\n url: string;\n method: string;\n body: FormData | File | Blob;\n headers: Record<string, unknown>;\n onProgress?: (percent: number) => void;\n};\n\nexport type SignedUploadRequest = {\n ref: string;\n target: string;\n filename: string;\n contentType: string;\n values?: Record<string, unknown>;\n};\n\n/**\n * XHR rather than fetch because only XHR reports upload progress. A transport\n * failure leaves `status` at 0, which `new Response` rejects as out of range, so\n * it is mapped to 500 — otherwise the promise never settles and the upload hangs.\n */\nexport function xhrTransfer({\n url,\n method,\n body,\n headers,\n onProgress,\n}: Transfer): Promise<Response> {\n return new Promise((resolve, reject) => {\n const request = new XMLHttpRequest();\n\n request.open(method, url, true);\n Object.entries(headers).forEach(([key, value]) => request.setRequestHeader(key, String(value)));\n request.upload.onprogress = (event) => {\n if (event.lengthComputable) {\n onProgress?.(Math.round((event.loaded / event.total) * 100));\n }\n };\n request.onload = () => {\n try {\n resolve(new Response(request.responseText || null, { status: request.status || 500 }));\n } catch {\n reject(new Error(`Upload to ${url} returned an unusable response`));\n }\n };\n request.onerror = () => reject(new Error(`Upload to ${url} failed`));\n request.send(body);\n });\n}\n\n/**\n * Asks the component for a signed upload. Form fields spread their live values\n * in so the server-side schema walk can find the field inside repeater rows.\n */\nexport function requestSignedUpload(\n endpoint: string,\n { ref, target, filename, contentType, values }: SignedUploadRequest,\n): Promise<Response> {\n return apiFetch(endpoint, {\n method: \"POST\",\n ref,\n body: JSON.stringify({\n ...values,\n _sub: \"upload\",\n _target: target,\n filename,\n contentType,\n }),\n throwOnError: false,\n });\n}\n"],"mappings":";;;;;;;AAuBA,SAAgB,YAAY,EAC1B,KACA,QACA,MACA,SACA,cAC8B;CAC9B,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,UAAU,IAAI,eAAe;EAEnC,QAAQ,KAAK,QAAQ,KAAK,IAAI;EAC9B,OAAO,QAAQ,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,WAAW,QAAQ,iBAAiB,KAAK,OAAO,KAAK,CAAC,CAAC;EAC9F,QAAQ,OAAO,cAAc,UAAU;GACrC,IAAI,MAAM,kBACR,aAAa,KAAK,MAAO,MAAM,SAAS,MAAM,QAAS,GAAG,CAAC;EAE/D;EACA,QAAQ,eAAe;GACrB,IAAI;IACF,QAAQ,IAAI,SAAS,QAAQ,gBAAgB,MAAM,EAAE,QAAQ,QAAQ,UAAU,IAAI,CAAC,CAAC;GACvF,QAAQ;IACN,uBAAO,IAAI,MAAM,aAAa,IAAI,+BAA+B,CAAC;GACpE;EACF;EACA,QAAQ,gBAAgB,uBAAO,IAAI,MAAM,aAAa,IAAI,QAAQ,CAAC;EACnE,QAAQ,KAAK,IAAI;CACnB,CAAC;AACH;;;;;AAMA,SAAgB,oBACd,UACA,EAAE,KAAK,QAAQ,UAAU,aAAa,UACnB;CACnB,OAAO,SAAS,UAAU;EACxB,QAAQ;EACR;EACA,MAAM,KAAK,UAAU;GACnB,GAAG;GACH,MAAM;GACN,SAAS;GACT;GACA;EACF,CAAC;EACD,cAAc;CAChB,CAAC;AACH"}
@@ -15,7 +15,7 @@ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
15
15
  //#region resources/js/create-app.tsx
16
16
  function withPluginNamespaces(options, entries) {
17
17
  if (entries.length === 0) return options;
18
- const namespaces = new Set([...options.namespaces ?? ["lattice"], ...entries.map((entry) => entry.namespace)]);
18
+ const namespaces = /* @__PURE__ */ new Set([...options.namespaces ?? ["lattice"], ...entries.map((entry) => entry.namespace)]);
19
19
  return {
20
20
  ...options,
21
21
  namespaces: [...namespaces]
@@ -1 +1 @@
1
- {"version":3,"file":"create-app.js","names":[],"sources":["../resources/js/create-app.tsx"],"sourcesContent":["import type { Page as InertiaPage, VisitOptions } from \"@inertiajs/core\";\nimport { createInertiaApp } from \"@inertiajs/react\";\nimport { useEffect, useState, type ReactElement, type ReactNode } from \"react\";\nimport { initializeAppearance } from \"./appearance\";\nimport { setRefRefreshEndpoint } from \"./core/api\";\nimport { isRecord } from \"./core/materialize\";\nimport { extendRegistry, type Plugin, type PluginI18n, type Registry } from \"./core/registry\";\nimport { setDefaultRegistry } from \"./core/registry-context\";\nimport type { SpriteValue } from \"./icons/sprite\";\nimport { DEFAULT_NAMESPACE } from \"./i18n/instance\";\nimport { LocaleReload } from \"./i18n/locale-reload\";\nimport { i18nConfigFromPageProps } from \"./i18n/shared-props\";\nimport {\n createLayoutResolver,\n createPageResolver,\n registerRefRenewal,\n withVisitHeaders,\n type CreateLayoutResolverOptions,\n type PageModules,\n} from \"./inertia\";\nimport { ProviderBase } from \"./provider-base\";\nimport { registry as defaultRegistry } from \"./registry\";\n\ntype InertiaAppOptions = NonNullable<Parameters<typeof createInertiaApp>[0]>;\n\nexport type CreateLatticeAppI18nOptions = {\n /**\n * i18next namespaces to load, e.g. `[\"lattice\", \"app\"]`. Defaults to the\n * package's own. Namespaces declared by plugins are merged in on top.\n */\n namespaces?: string[];\n};\n\nexport type CreateLatticeAppOptions = Omit<\n InertiaAppOptions,\n \"resolve\" | \"layout\" | \"setup\" | \"withApp\" | \"pages\"\n> & {\n registry?: Registry;\n /**\n * Component-package plugins to merge onto the registry — pass the\n * Composer-discovered `virtual:lattice/plugins` here to register vendor\n * components with no manual `extendRegistry` call. A plugin's declared\n * i18n namespace joins the i18n bootstrap automatically.\n */\n plugins?: Plugin[];\n sprite?: SpriteValue;\n /** Normal Inertia page modules, e.g. `import.meta.glob('./pages/**\\/*.tsx')`. */\n pages?: PageModules;\n defaultLayout?: CreateLayoutResolverOptions[\"defaultLayout\"];\n /**\n * Lattice's i18n bootstrap, on by default: when the backend shares the\n * `lattice.i18n` prop, the first render waits for the translation setup (no\n * flash of untranslated fallbacks), `LocaleReload` re-fetches the page after\n * a locale switch, and every visit carries the locale/timezone headers. The\n * i18next chunk only loads when the backend actually shares the prop. Pass\n * `false` to opt out entirely.\n */\n i18n?: CreateLatticeAppI18nOptions | false;\n /**\n * App bootstrap that needs the initial page — e.g. `configureEcho` from a\n * shared connection prop. Runs on the client before the first render; a\n * returned promise delays that render until it resolves.\n */\n boot?: (context: { page: InertiaPage }) => void | Promise<void>;\n /**\n * Compose providers or siblings around the app. Applied inside the Lattice\n * Provider, so the registry, sprite, and toaster contexts are available.\n */\n wrap?: (app: ReactElement) => ReactElement;\n};\n\nfunction withPluginNamespaces(\n options: CreateLatticeAppI18nOptions,\n entries: PluginI18n[],\n): CreateLatticeAppI18nOptions {\n if (entries.length === 0) {\n return options;\n }\n\n const namespaces = new Set([\n ...(options.namespaces ?? [DEFAULT_NAMESPACE]),\n ...entries.map((entry) => entry.namespace),\n ]);\n\n return { ...options, namespaces: [...namespaces] };\n}\n\n// Fail-open: a failed bootstrap renders the app anyway (with fallback strings)\n// rather than a blank page.\nfunction AwaitReady({ ready, children }: { ready: Promise<unknown>; children: ReactNode }) {\n const [isReady, setReady] = useState(false);\n\n useEffect(() => {\n let active = true;\n const reveal = (): void => {\n if (active) {\n setReady(true);\n }\n };\n\n void ready.then(reveal, reveal);\n\n return () => {\n active = false;\n };\n }, [ready]);\n\n return isReady ? children : null;\n}\n\n/**\n * Bootstrap an Inertia app with the Lattice shell: the page/layout resolvers\n * (server-driven Lattice pages and normal Inertia pages alike), the Provider —\n * registry, sprite, flash toasts via Lattice's own Toaster — theme\n * initialization, and the i18n bootstrap. Forwards any other createInertiaApp\n * option.\n */\nexport function createLatticeApp({\n registry,\n plugins,\n sprite,\n pages = {},\n defaultLayout,\n strictMode = true,\n i18n,\n boot,\n wrap,\n ...inertiaOptions\n}: CreateLatticeAppOptions = {}) {\n const baseRegistry = registry ?? defaultRegistry;\n const activeRegistry =\n plugins && plugins.length > 0 ? extendRegistry(baseRegistry, ...plugins) : baseRegistry;\n\n setDefaultRegistry(activeRegistry);\n registerRefRenewal();\n\n const i18nEnabled = i18n !== false;\n const pluginI18n = plugins?.flatMap((plugin) => (plugin.i18n ? [plugin.i18n] : [])) ?? [];\n const i18nOptions = i18nEnabled ? withPluginNamespaces(i18n ?? {}, pluginI18n) : {};\n const userVisitOptions = inertiaOptions.defaults?.visitOptions;\n const defaults = i18nEnabled\n ? {\n ...inertiaOptions.defaults,\n visitOptions: (href: string, options: VisitOptions): VisitOptions =>\n withVisitHeaders(href, userVisitOptions?.(href, options) ?? options),\n }\n : inertiaOptions.defaults;\n\n const app = createInertiaApp({\n ...inertiaOptions,\n defaults,\n strictMode,\n resolve: createPageResolver(pages),\n layout: createLayoutResolver({ defaultLayout }),\n withApp: (node: ReactElement, { ssr, page }: { ssr: boolean; page: InertiaPage }) => {\n const pending: Promise<unknown>[] = [];\n\n if (!ssr) {\n const shared = page.props.lattice;\n\n if (\n isRecord(shared) &&\n isRecord(shared.urls) &&\n typeof shared.urls.refreshRef === \"string\"\n ) {\n setRefRefreshEndpoint(shared.urls.refreshRef);\n }\n\n // Loaded on demand so apps without the shared i18n prop never ship the\n // i18next backend; the disabled-config call still stores the timezone.\n if (i18nEnabled && i18nConfigFromPageProps(page.props) !== undefined) {\n pending.push(\n import(\"./i18n/page-props\").then((module) =>\n module.configureI18nFromPageProps(page.props, i18nOptions),\n ),\n );\n }\n\n const booted = boot?.({ page });\n\n if (booted) {\n pending.push(booted);\n }\n }\n\n const inner = (\n <>\n {node}\n {i18nEnabled ? <LocaleReload /> : null}\n </>\n );\n\n // The whole shell waits, not just the page: anything rendering a\n // translated string (the Toaster included) would otherwise initialize\n // i18next before the backend can register — init runs exactly once,\n // first caller wins.\n const shell = (\n <ProviderBase registry={activeRegistry} sprite={sprite}>\n {wrap ? wrap(inner) : inner}\n </ProviderBase>\n );\n\n return pending.length > 0 ? (\n <AwaitReady ready={Promise.all(pending)}>{shell}</AwaitReady>\n ) : (\n shell\n );\n },\n });\n\n initializeAppearance();\n\n return app;\n}\n"],"mappings":";;;;;;;;;;;;;;;AAuEA,SAAS,qBACP,SACA,SAC6B;CAC7B,IAAI,QAAQ,WAAW,GACrB,OAAO;CAGT,MAAM,aAAa,IAAI,IAAI,CACzB,GAAI,QAAQ,cAAc,CAAA,SAAkB,GAC5C,GAAG,QAAQ,KAAK,UAAU,MAAM,SAAS,CAC3C,CAAC;CAED,OAAO;EAAE,GAAG;EAAS,YAAY,CAAC,GAAG,UAAU;CAAE;AACnD;AAIA,SAAS,WAAW,EAAE,OAAO,YAA8D;CACzF,MAAM,CAAC,SAAS,YAAY,SAAS,KAAK;CAE1C,gBAAgB;EACd,IAAI,SAAS;EACb,MAAM,eAAqB;GACzB,IAAI,QACF,SAAS,IAAI;EAEjB;EAEA,MAAW,KAAK,QAAQ,MAAM;EAE9B,aAAa;GACX,SAAS;EACX;CACF,GAAG,CAAC,KAAK,CAAC;CAEV,OAAO,UAAU,WAAW;AAC9B;;;;;;;;AASA,SAAgB,iBAAiB,EAC/B,UAAA,YACA,SACA,QACA,QAAQ,CAAC,GACT,eACA,aAAa,MACb,MACA,MACA,MACA,GAAG,mBACwB,CAAC,GAAG;CAC/B,MAAM,eAAe,cAAY;CACjC,MAAM,iBACJ,WAAW,QAAQ,SAAS,IAAI,eAAe,cAAc,GAAG,OAAO,IAAI;CAE7E,mBAAmB,cAAc;CACjC,mBAAmB;CAEnB,MAAM,cAAc,SAAS;CAC7B,MAAM,aAAa,SAAS,SAAS,WAAY,OAAO,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,CAAE,KAAK,CAAC;CACxF,MAAM,cAAc,cAAc,qBAAqB,QAAQ,CAAC,GAAG,UAAU,IAAI,CAAC;CAClF,MAAM,mBAAmB,eAAe,UAAU;CAClD,MAAM,WAAW,cACb;EACE,GAAG,eAAe;EAClB,eAAe,MAAc,YAC3B,iBAAiB,MAAM,mBAAmB,MAAM,OAAO,KAAK,OAAO;CACvE,IACA,eAAe;CAEnB,MAAM,MAAM,iBAAiB;EAC3B,GAAG;EACH;EACA;EACA,SAAS,mBAAmB,KAAK;EACjC,QAAQ,qBAAqB,EAAE,cAAc,CAAC;EAC9C,UAAU,MAAoB,EAAE,KAAK,WAAgD;GACnF,MAAM,UAA8B,CAAC;GAErC,IAAI,CAAC,KAAK;IACR,MAAM,SAAS,KAAK,MAAM;IAE1B,IACE,SAAS,MAAM,KACf,SAAS,OAAO,IAAI,KACpB,OAAO,OAAO,KAAK,eAAe,UAElC,sBAAsB,OAAO,KAAK,UAAU;IAK9C,IAAI,eAAe,wBAAwB,KAAK,KAAK,MAAM,KAAA,GACzD,QAAQ,KACN,OAAO,wBAAqB,MAAM,WAChC,OAAO,2BAA2B,KAAK,OAAO,WAAW,CAC3D,CACF;IAGF,MAAM,SAAS,OAAO,EAAE,KAAK,CAAC;IAE9B,IAAI,QACF,QAAQ,KAAK,MAAM;GAEvB;GAEA,MAAM,QACJ,qBAAA,YAAA,EAAA,UAAA,CACG,MACA,cAAc,oBAAC,cAAD,CAAe,CAAA,IAAI,IAClC,EAAA,CAAA;GAOJ,MAAM,QACJ,oBAAC,cAAD;IAAc,UAAU;IAAwB;cAC7C,OAAO,KAAK,KAAK,IAAI;GACV,CAAA;GAGhB,OAAO,QAAQ,SAAS,IACtB,oBAAC,YAAD;IAAY,OAAO,QAAQ,IAAI,OAAO;cAAI;GAAkB,CAAA,IAE5D;EAEJ;CACF,CAAC;CAED,qBAAqB;CAErB,OAAO;AACT"}
1
+ {"version":3,"file":"create-app.js","names":[],"sources":["../resources/js/create-app.tsx"],"sourcesContent":["import type { Page as InertiaPage, VisitOptions } from \"@inertiajs/core\";\nimport { createInertiaApp } from \"@inertiajs/react\";\nimport { useEffect, useState, type ReactElement, type ReactNode } from \"react\";\nimport { initializeAppearance } from \"./appearance\";\nimport { setRefRefreshEndpoint } from \"./core/api\";\nimport { isRecord } from \"./core/materialize\";\nimport { extendRegistry, type Plugin, type PluginI18n, type Registry } from \"./core/registry\";\nimport { setDefaultRegistry } from \"./core/registry-context\";\nimport type { SpriteValue } from \"./icons/sprite\";\nimport { DEFAULT_NAMESPACE } from \"./i18n/instance\";\nimport { LocaleReload } from \"./i18n/locale-reload\";\nimport { i18nConfigFromPageProps } from \"./i18n/shared-props\";\nimport {\n createLayoutResolver,\n createPageResolver,\n registerRefRenewal,\n withVisitHeaders,\n type CreateLayoutResolverOptions,\n type PageModules,\n} from \"./inertia\";\nimport { ProviderBase } from \"./provider-base\";\nimport { registry as defaultRegistry } from \"./registry\";\n\ntype InertiaAppOptions = NonNullable<Parameters<typeof createInertiaApp>[0]>;\n\nexport type CreateLatticeAppI18nOptions = {\n /**\n * i18next namespaces to load, e.g. `[\"lattice\", \"app\"]`. Defaults to the\n * package's own. Namespaces declared by plugins are merged in on top.\n */\n namespaces?: string[];\n};\n\nexport type CreateLatticeAppOptions = Omit<\n InertiaAppOptions,\n \"resolve\" | \"layout\" | \"setup\" | \"withApp\" | \"pages\"\n> & {\n registry?: Registry;\n /**\n * Component-package plugins to merge onto the registry — pass the\n * Composer-discovered `virtual:lattice/plugins` here to register vendor\n * components with no manual `extendRegistry` call. A plugin's declared\n * i18n namespace joins the i18n bootstrap automatically.\n */\n plugins?: Plugin[];\n sprite?: SpriteValue;\n /** Normal Inertia page modules, e.g. `import.meta.glob('./pages/**\\/*.tsx')`. */\n pages?: PageModules;\n defaultLayout?: CreateLayoutResolverOptions[\"defaultLayout\"];\n /**\n * Lattice's i18n bootstrap, on by default: when the backend shares the\n * `lattice.i18n` prop, the first render waits for the translation setup (no\n * flash of untranslated fallbacks), `LocaleReload` re-fetches the page after\n * a locale switch, and every visit carries the locale/timezone headers. The\n * i18next chunk only loads when the backend actually shares the prop. Pass\n * `false` to opt out entirely.\n */\n i18n?: CreateLatticeAppI18nOptions | false;\n /**\n * App bootstrap that needs the initial page — e.g. `configureEcho` from a\n * shared connection prop. Runs on the client before the first render; a\n * returned promise delays that render until it resolves.\n */\n boot?: (context: { page: InertiaPage }) => void | Promise<void>;\n /**\n * Compose providers or siblings around the app. Applied inside the Lattice\n * Provider, so the registry, sprite, and toaster contexts are available.\n */\n wrap?: (app: ReactElement) => ReactElement;\n};\n\nfunction withPluginNamespaces(\n options: CreateLatticeAppI18nOptions,\n entries: PluginI18n[],\n): CreateLatticeAppI18nOptions {\n if (entries.length === 0) {\n return options;\n }\n\n const namespaces = new Set([\n ...(options.namespaces ?? [DEFAULT_NAMESPACE]),\n ...entries.map((entry) => entry.namespace),\n ]);\n\n return { ...options, namespaces: [...namespaces] };\n}\n\n// Fail-open: a failed bootstrap renders the app anyway (with fallback strings)\n// rather than a blank page.\nfunction AwaitReady({ ready, children }: { ready: Promise<unknown>; children: ReactNode }) {\n const [isReady, setReady] = useState(false);\n\n useEffect(() => {\n let active = true;\n const reveal = (): void => {\n if (active) {\n setReady(true);\n }\n };\n\n void ready.then(reveal, reveal);\n\n return () => {\n active = false;\n };\n }, [ready]);\n\n return isReady ? children : null;\n}\n\n/**\n * Bootstrap an Inertia app with the Lattice shell: the page/layout resolvers\n * (server-driven Lattice pages and normal Inertia pages alike), the Provider —\n * registry, sprite, flash toasts via Lattice's own Toaster — theme\n * initialization, and the i18n bootstrap. Forwards any other createInertiaApp\n * option.\n */\nexport function createLatticeApp({\n registry,\n plugins,\n sprite,\n pages = {},\n defaultLayout,\n strictMode = true,\n i18n,\n boot,\n wrap,\n ...inertiaOptions\n}: CreateLatticeAppOptions = {}) {\n const baseRegistry = registry ?? defaultRegistry;\n const activeRegistry =\n plugins && plugins.length > 0 ? extendRegistry(baseRegistry, ...plugins) : baseRegistry;\n\n setDefaultRegistry(activeRegistry);\n registerRefRenewal();\n\n const i18nEnabled = i18n !== false;\n const pluginI18n = plugins?.flatMap((plugin) => (plugin.i18n ? [plugin.i18n] : [])) ?? [];\n const i18nOptions = i18nEnabled ? withPluginNamespaces(i18n ?? {}, pluginI18n) : {};\n const userVisitOptions = inertiaOptions.defaults?.visitOptions;\n const defaults = i18nEnabled\n ? {\n ...inertiaOptions.defaults,\n visitOptions: (href: string, options: VisitOptions): VisitOptions =>\n withVisitHeaders(href, userVisitOptions?.(href, options) ?? options),\n }\n : inertiaOptions.defaults;\n\n const app = createInertiaApp({\n ...inertiaOptions,\n defaults,\n strictMode,\n resolve: createPageResolver(pages),\n layout: createLayoutResolver({ defaultLayout }),\n withApp: (node: ReactElement, { ssr, page }: { ssr: boolean; page: InertiaPage }) => {\n const pending: Promise<unknown>[] = [];\n\n if (!ssr) {\n const shared = page.props.lattice;\n\n if (\n isRecord(shared) &&\n isRecord(shared.urls) &&\n typeof shared.urls.refreshRef === \"string\"\n ) {\n setRefRefreshEndpoint(shared.urls.refreshRef);\n }\n\n // Loaded on demand so apps without the shared i18n prop never ship the\n // i18next backend; the disabled-config call still stores the timezone.\n if (i18nEnabled && i18nConfigFromPageProps(page.props) !== undefined) {\n pending.push(\n import(\"./i18n/page-props\").then((module) =>\n module.configureI18nFromPageProps(page.props, i18nOptions),\n ),\n );\n }\n\n const booted = boot?.({ page });\n\n if (booted) {\n pending.push(booted);\n }\n }\n\n const inner = (\n <>\n {node}\n {i18nEnabled ? <LocaleReload /> : null}\n </>\n );\n\n // The whole shell waits, not just the page: anything rendering a\n // translated string (the Toaster included) would otherwise initialize\n // i18next before the backend can register — init runs exactly once,\n // first caller wins.\n const shell = (\n <ProviderBase registry={activeRegistry} sprite={sprite}>\n {wrap ? wrap(inner) : inner}\n </ProviderBase>\n );\n\n return pending.length > 0 ? (\n <AwaitReady ready={Promise.all(pending)}>{shell}</AwaitReady>\n ) : (\n shell\n );\n },\n });\n\n initializeAppearance();\n\n return app;\n}\n"],"mappings":";;;;;;;;;;;;;;;AAuEA,SAAS,qBACP,SACA,SAC6B;CAC7B,IAAI,QAAQ,WAAW,GACrB,OAAO;CAGT,MAAM,6BAAa,IAAI,IAAI,CACzB,GAAI,QAAQ,cAAc,CAAA,SAAkB,GAC5C,GAAG,QAAQ,KAAK,UAAU,MAAM,SAAS,CAC3C,CAAC;CAED,OAAO;EAAE,GAAG;EAAS,YAAY,CAAC,GAAG,UAAU;CAAE;AACnD;AAIA,SAAS,WAAW,EAAE,OAAO,YAA8D;CACzF,MAAM,CAAC,SAAS,YAAY,SAAS,KAAK;CAE1C,gBAAgB;EACd,IAAI,SAAS;EACb,MAAM,eAAqB;GACzB,IAAI,QACF,SAAS,IAAI;EAEjB;EAEA,MAAW,KAAK,QAAQ,MAAM;EAE9B,aAAa;GACX,SAAS;EACX;CACF,GAAG,CAAC,KAAK,CAAC;CAEV,OAAO,UAAU,WAAW;AAC9B;;;;;;;;AASA,SAAgB,iBAAiB,EAC/B,UAAA,YACA,SACA,QACA,QAAQ,CAAC,GACT,eACA,aAAa,MACb,MACA,MACA,MACA,GAAG,mBACwB,CAAC,GAAG;CAC/B,MAAM,eAAe,cAAY;CACjC,MAAM,iBACJ,WAAW,QAAQ,SAAS,IAAI,eAAe,cAAc,GAAG,OAAO,IAAI;CAE7E,mBAAmB,cAAc;CACjC,mBAAmB;CAEnB,MAAM,cAAc,SAAS;CAC7B,MAAM,aAAa,SAAS,SAAS,WAAY,OAAO,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,CAAE,KAAK,CAAC;CACxF,MAAM,cAAc,cAAc,qBAAqB,QAAQ,CAAC,GAAG,UAAU,IAAI,CAAC;CAClF,MAAM,mBAAmB,eAAe,UAAU;CAClD,MAAM,WAAW,cACb;EACE,GAAG,eAAe;EAClB,eAAe,MAAc,YAC3B,iBAAiB,MAAM,mBAAmB,MAAM,OAAO,KAAK,OAAO;CACvE,IACA,eAAe;CAEnB,MAAM,MAAM,iBAAiB;EAC3B,GAAG;EACH;EACA;EACA,SAAS,mBAAmB,KAAK;EACjC,QAAQ,qBAAqB,EAAE,cAAc,CAAC;EAC9C,UAAU,MAAoB,EAAE,KAAK,WAAgD;GACnF,MAAM,UAA8B,CAAC;GAErC,IAAI,CAAC,KAAK;IACR,MAAM,SAAS,KAAK,MAAM;IAE1B,IACE,SAAS,MAAM,KACf,SAAS,OAAO,IAAI,KACpB,OAAO,OAAO,KAAK,eAAe,UAElC,sBAAsB,OAAO,KAAK,UAAU;IAK9C,IAAI,eAAe,wBAAwB,KAAK,KAAK,MAAM,KAAA,GACzD,QAAQ,KACN,OAAO,uBAAoB,CAAC,MAAM,WAChC,OAAO,2BAA2B,KAAK,OAAO,WAAW,CAC3D,CACF;IAGF,MAAM,SAAS,OAAO,EAAE,KAAK,CAAC;IAE9B,IAAI,QACF,QAAQ,KAAK,MAAM;GAEvB;GAEA,MAAM,QACJ,qBAAA,YAAA,EAAA,UAAA,CACG,MACA,cAAc,oBAAC,cAAD,CAAe,CAAA,IAAI,IAClC,EAAA,CAAA;GAOJ,MAAM,QACJ,oBAAC,cAAD;IAAc,UAAU;IAAwB;IAC7C,UAAA,OAAO,KAAK,KAAK,IAAI;GACV,CAAA;GAGhB,OAAO,QAAQ,SAAS,IACtB,oBAAC,YAAD;IAAY,OAAO,QAAQ,IAAI,OAAO;IAAI,UAAA;GAAkB,CAAA,IAE5D;EAEJ;CACF,CAAC;CAED,qBAAqB;CAErB,OAAO;AACT"}
@@ -21,12 +21,13 @@ function bridge(event) {
21
21
  return (effect) => window.dispatchEvent(new CustomEvent(event, { detail: effect.props }));
22
22
  }
23
23
  var builtinEffectHandlers = {
24
- "reload-page": () => router.reload(),
24
+ "reload-page": (effect) => effect.props.full ? window.location.reload() : router.reload(),
25
25
  redirect: (effect) => router.visit(effect.props.url),
26
26
  download: (effect) => triggerDownload(effect.props.url),
27
27
  "locale-change": (effect) => setLocale(effect.props.locale),
28
28
  toast: bridge(LATTICE_EVENT.toast),
29
29
  callout: bridge(LATTICE_EVENT.callout),
30
+ "retract-callout": bridge(LATTICE_EVENT.retractCallout),
30
31
  "reload-component": bridge(LATTICE_EVENT.reloadComponent),
31
32
  "open-modal": bridge(LATTICE_EVENT.openModal),
32
33
  "close-modal": bridge(LATTICE_EVENT.closeModal),
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","names":[],"sources":["../../resources/js/effects/registry.ts"],"sourcesContent":["import { router } from \"@inertiajs/react\";\nimport type {\n EffectOf,\n EffectProps,\n EffectPropsMap,\n EffectPropsOf,\n} from \"@lattice-php/lattice/types/generated\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/core/event-names\";\nimport { setLocale } from \"@lattice-php/lattice/i18n/locale\";\n\nexport type { EffectOf, EffectProps, EffectPropsOf };\n\nexport type EffectHandler<TType extends string = string> = (effect: EffectOf<TType>) => void;\n\nexport type EffectHandlerRegistry = Record<string, EffectHandler>;\n\nexport type EffectHandlerRegistryFor<TTypes extends keyof EffectPropsMap & string> = Record<\n TTypes,\n EffectHandler\n>;\n\n/**\n * Author a handler against `EffectHandler<\"my.type\">` for a typed payload, then\n * register it through this — it erases the type parameter for the loose registry.\n */\nexport function effectHandler<TType extends string>(\n _type: TType,\n fn: EffectHandler<TType>,\n): EffectHandler {\n return fn as unknown as EffectHandler;\n}\n\nfunction triggerDownload(url: string): void {\n const link = document.createElement(\"a\");\n link.href = url;\n link.rel = \"noopener\";\n document.body.appendChild(link);\n link.click();\n link.remove();\n}\n\nfunction bridge<TType extends keyof EffectPropsMap & string>(event: string): EffectHandler<TType> {\n return (effect) => window.dispatchEvent(new CustomEvent(event, { detail: effect.props }));\n}\n\n/**\n * Imperative effects act directly; the rest bridge to the `lattice:*` DOM events\n * that toast/callout/modal/fragment/form subscribe to. The export cast erases\n * the mapped type to the loose registry shape — the same variance erasure\n * effectHandler performs.\n */\nconst typedBuiltinHandlers: { [K in keyof EffectPropsMap]: EffectHandler<K> } = {\n \"reload-page\": () => router.reload(),\n redirect: (effect) => router.visit(effect.props.url),\n download: (effect) => triggerDownload(effect.props.url),\n \"locale-change\": (effect) => setLocale(effect.props.locale),\n toast: bridge<\"toast\">(LATTICE_EVENT.toast),\n callout: bridge<\"callout\">(LATTICE_EVENT.callout),\n \"reload-component\": bridge<\"reload-component\">(LATTICE_EVENT.reloadComponent),\n \"open-modal\": bridge<\"open-modal\">(LATTICE_EVENT.openModal),\n \"close-modal\": bridge<\"close-modal\">(LATTICE_EVENT.closeModal),\n \"reset-form\": bridge<\"reset-form\">(LATTICE_EVENT.resetForm),\n \"toggle-sidebar\": bridge<\"toggle-sidebar\">(LATTICE_EVENT.toggleSidebar),\n};\n\nexport const builtinEffectHandlers: EffectHandlerRegistryFor<keyof EffectPropsMap & string> =\n typedBuiltinHandlers as EffectHandlerRegistryFor<keyof EffectPropsMap & string>;\n\nexport function mergeEffectHandlers(\n ...registries: Array<EffectHandlerRegistry | undefined>\n): EffectHandlerRegistry {\n return registries.reduce<EffectHandlerRegistry>(\n (merged, registry) => ({ ...merged, ...registry }),\n {},\n );\n}\n"],"mappings":";;;;;;;;AAyBA,SAAgB,cACd,OACA,IACe;CACf,OAAO;AACT;AAEA,SAAS,gBAAgB,KAAmB;CAC1C,MAAM,OAAO,SAAS,cAAc,GAAG;CACvC,KAAK,OAAO;CACZ,KAAK,MAAM;CACX,SAAS,KAAK,YAAY,IAAI;CAC9B,KAAK,MAAM;CACX,KAAK,OAAO;AACd;AAEA,SAAS,OAAoD,OAAqC;CAChG,QAAQ,WAAW,OAAO,cAAc,IAAI,YAAY,OAAO,EAAE,QAAQ,OAAO,MAAM,CAAC,CAAC;AAC1F;AAsBA,IAAa,wBACX;CAdA,qBAAqB,OAAO,OAAO;CACnC,WAAW,WAAW,OAAO,MAAM,OAAO,MAAM,GAAG;CACnD,WAAW,WAAW,gBAAgB,OAAO,MAAM,GAAG;CACtD,kBAAkB,WAAW,UAAU,OAAO,MAAM,MAAM;CAC1D,OAAO,OAAgB,cAAc,KAAK;CAC1C,SAAS,OAAkB,cAAc,OAAO;CAChD,oBAAoB,OAA2B,cAAc,eAAe;CAC5E,cAAc,OAAqB,cAAc,SAAS;CAC1D,eAAe,OAAsB,cAAc,UAAU;CAC7D,cAAc,OAAqB,cAAc,SAAS;CAC1D,kBAAkB,OAAyB,cAAc,aAAa;AAItE;AAEF,SAAgB,oBACd,GAAG,YACoB;CACvB,OAAO,WAAW,QACf,QAAQ,cAAc;EAAE,GAAG;EAAQ,GAAG;CAAS,IAChD,CAAC,CACH;AACF"}
1
+ {"version":3,"file":"registry.js","names":[],"sources":["../../resources/js/effects/registry.ts"],"sourcesContent":["import { router } from \"@inertiajs/react\";\nimport type {\n EffectOf,\n EffectProps,\n EffectPropsMap,\n EffectPropsOf,\n} from \"@lattice-php/lattice/types/generated\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/core/event-names\";\nimport { setLocale } from \"@lattice-php/lattice/i18n/locale\";\n\nexport type { EffectOf, EffectProps, EffectPropsOf };\n\nexport type EffectHandler<TType extends string = string> = (effect: EffectOf<TType>) => void;\n\nexport type EffectHandlerRegistry = Record<string, EffectHandler>;\n\nexport type EffectHandlerRegistryFor<TTypes extends keyof EffectPropsMap & string> = Record<\n TTypes,\n EffectHandler\n>;\n\n/**\n * Author a handler against `EffectHandler<\"my.type\">` for a typed payload, then\n * register it through this — it erases the type parameter for the loose registry.\n */\nexport function effectHandler<TType extends string>(\n _type: TType,\n fn: EffectHandler<TType>,\n): EffectHandler {\n return fn as unknown as EffectHandler;\n}\n\nfunction triggerDownload(url: string): void {\n const link = document.createElement(\"a\");\n link.href = url;\n link.rel = \"noopener\";\n document.body.appendChild(link);\n link.click();\n link.remove();\n}\n\nfunction bridge<TType extends keyof EffectPropsMap & string>(event: string): EffectHandler<TType> {\n return (effect) => window.dispatchEvent(new CustomEvent(event, { detail: effect.props }));\n}\n\n/**\n * Imperative effects act directly; the rest bridge to the `lattice:*` DOM events\n * that toast/callout/modal/fragment/form subscribe to. The export cast erases\n * the mapped type to the loose registry shape — the same variance erasure\n * effectHandler performs.\n */\nconst typedBuiltinHandlers: { [K in keyof EffectPropsMap]: EffectHandler<K> } = {\n \"reload-page\": (effect) => (effect.props.full ? window.location.reload() : router.reload()),\n redirect: (effect) => router.visit(effect.props.url),\n download: (effect) => triggerDownload(effect.props.url),\n \"locale-change\": (effect) => setLocale(effect.props.locale),\n toast: bridge<\"toast\">(LATTICE_EVENT.toast),\n callout: bridge<\"callout\">(LATTICE_EVENT.callout),\n \"retract-callout\": bridge<\"retract-callout\">(LATTICE_EVENT.retractCallout),\n \"reload-component\": bridge<\"reload-component\">(LATTICE_EVENT.reloadComponent),\n \"open-modal\": bridge<\"open-modal\">(LATTICE_EVENT.openModal),\n \"close-modal\": bridge<\"close-modal\">(LATTICE_EVENT.closeModal),\n \"reset-form\": bridge<\"reset-form\">(LATTICE_EVENT.resetForm),\n \"toggle-sidebar\": bridge<\"toggle-sidebar\">(LATTICE_EVENT.toggleSidebar),\n};\n\nexport const builtinEffectHandlers: EffectHandlerRegistryFor<keyof EffectPropsMap & string> =\n typedBuiltinHandlers as EffectHandlerRegistryFor<keyof EffectPropsMap & string>;\n\nexport function mergeEffectHandlers(\n ...registries: Array<EffectHandlerRegistry | undefined>\n): EffectHandlerRegistry {\n return registries.reduce<EffectHandlerRegistry>(\n (merged, registry) => ({ ...merged, ...registry }),\n {},\n );\n}\n"],"mappings":";;;;;;;;AAyBA,SAAgB,cACd,OACA,IACe;CACf,OAAO;AACT;AAEA,SAAS,gBAAgB,KAAmB;CAC1C,MAAM,OAAO,SAAS,cAAc,GAAG;CACvC,KAAK,OAAO;CACZ,KAAK,MAAM;CACX,SAAS,KAAK,YAAY,IAAI;CAC9B,KAAK,MAAM;CACX,KAAK,OAAO;AACd;AAEA,SAAS,OAAoD,OAAqC;CAChG,QAAQ,WAAW,OAAO,cAAc,IAAI,YAAY,OAAO,EAAE,QAAQ,OAAO,MAAM,CAAC,CAAC;AAC1F;AAuBA,IAAa,wBACX;CAfA,gBAAgB,WAAY,OAAO,MAAM,OAAO,OAAO,SAAS,OAAO,IAAI,OAAO,OAAO;CACzF,WAAW,WAAW,OAAO,MAAM,OAAO,MAAM,GAAG;CACnD,WAAW,WAAW,gBAAgB,OAAO,MAAM,GAAG;CACtD,kBAAkB,WAAW,UAAU,OAAO,MAAM,MAAM;CAC1D,OAAO,OAAgB,cAAc,KAAK;CAC1C,SAAS,OAAkB,cAAc,OAAO;CAChD,mBAAmB,OAA0B,cAAc,cAAc;CACzE,oBAAoB,OAA2B,cAAc,eAAe;CAC5E,cAAc,OAAqB,cAAc,SAAS;CAC1D,eAAe,OAAsB,cAAc,UAAU;CAC7D,cAAc,OAAqB,cAAc,SAAS;CAC1D,kBAAkB,OAAyB,cAAc,aAAa;AAItE;AAEF,SAAgB,oBACd,GAAG,YACoB;CACvB,OAAO,WAAW,QACf,QAAQ,cAAc;EAAE,GAAG;EAAQ,GAAG;CAAS,IAChD,CAAC,CACH;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"field.js","names":[],"sources":["../../../../resources/js/form/components/base/field.tsx"],"sourcesContent":["import InputError from \"@lattice-php/lattice/ui/input-error\";\nimport { InfoTooltip } from \"@lattice-php/lattice/ui/info-tooltip\";\nimport { TextLink } from \"@lattice-php/lattice/ui/link\";\nimport { Label } from \"@lattice-php/lattice/ui/label\";\nimport { useInTableCell } from \"@lattice-php/lattice/form/hooks/row-layout-context\";\nimport type { LabelAction } from \"@lattice-php/lattice/form/types\";\n\nexport function FormFieldFrame({\n children,\n error,\n helperText,\n label,\n labelAction,\n name,\n required,\n tooltip,\n}: {\n children: React.ReactNode;\n error?: string;\n helperText?: string;\n label: string;\n labelAction?: LabelAction;\n name: string;\n required?: boolean;\n tooltip?: string;\n}) {\n const bare = useInTableCell();\n\n if (bare) {\n return (\n <div className=\"grid gap-1\">\n <Label htmlFor={name} className=\"sr-only\">\n {label}\n </Label>\n {children}\n <InputError message={error} />\n </div>\n );\n }\n\n return (\n <div className=\"grid gap-2\">\n <div className=\"flex min-h-5 items-center\">\n <Label htmlFor={name}>{label}</Label>\n {required && (\n <span aria-hidden=\"true\" className=\"ml-0.5 text-lt-danger\">\n *\n </span>\n )}\n <InfoTooltip content={tooltip} />\n {labelAction && (\n <TextLink\n href={labelAction.href}\n tabIndex={labelAction.tabIndex ?? undefined}\n className=\"ml-auto text-sm\"\n >\n {labelAction.label}\n </TextLink>\n )}\n </div>\n\n {children}\n\n {helperText && <p className=\"text-sm text-lt-muted-fg\">{helperText}</p>}\n\n <InputError message={error} />\n </div>\n );\n}\n"],"mappings":";;;;;;;AAOA,SAAgB,eAAe,EAC7B,UACA,OACA,YACA,OACA,aACA,MACA,UACA,WAUC;CAGD,IAFa,eAET,GACF,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf;GACE,oBAAC,OAAD;IAAO,SAAS;IAAM,WAAU;cAC7B;GACI,CAAA;GACN;GACD,oBAAC,YAAD,EAAY,SAAS,MAAQ,CAAA;EAC1B;;CAIT,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf;GACE,qBAAC,OAAD;IAAK,WAAU;cAAf;KACE,oBAAC,OAAD;MAAO,SAAS;gBAAO;KAAa,CAAA;KACnC,YACC,oBAAC,QAAD;MAAM,eAAY;MAAO,WAAU;gBAAwB;KAErD,CAAA;KAER,oBAAC,aAAD,EAAa,SAAS,QAAU,CAAA;KAC/B,eACC,oBAAC,UAAD;MACE,MAAM,YAAY;MAClB,UAAU,YAAY,YAAY,KAAA;MAClC,WAAU;gBAET,YAAY;KACL,CAAA;IAET;;GAEJ;GAEA,cAAc,oBAAC,KAAD;IAAG,WAAU;cAA4B;GAAc,CAAA;GAEtE,oBAAC,YAAD,EAAY,SAAS,MAAQ,CAAA;EAC1B;;AAET"}
1
+ {"version":3,"file":"field.js","names":[],"sources":["../../../../resources/js/form/components/base/field.tsx"],"sourcesContent":["import InputError from \"@lattice-php/lattice/ui/input-error\";\nimport { InfoTooltip } from \"@lattice-php/lattice/ui/info-tooltip\";\nimport { TextLink } from \"@lattice-php/lattice/ui/link\";\nimport { Label } from \"@lattice-php/lattice/ui/label\";\nimport { useInTableCell } from \"@lattice-php/lattice/form/hooks/row-layout-context\";\nimport type { LabelAction } from \"@lattice-php/lattice/form/types\";\n\nexport function FormFieldFrame({\n children,\n error,\n helperText,\n label,\n labelAction,\n name,\n required,\n tooltip,\n}: {\n children: React.ReactNode;\n error?: string;\n helperText?: string;\n label: string;\n labelAction?: LabelAction;\n name: string;\n required?: boolean;\n tooltip?: string;\n}) {\n const bare = useInTableCell();\n\n if (bare) {\n return (\n <div className=\"grid gap-1\">\n <Label htmlFor={name} className=\"sr-only\">\n {label}\n </Label>\n {children}\n <InputError message={error} />\n </div>\n );\n }\n\n return (\n <div className=\"grid gap-2\">\n <div className=\"flex min-h-5 items-center\">\n <Label htmlFor={name}>{label}</Label>\n {required && (\n <span aria-hidden=\"true\" className=\"ml-0.5 text-lt-danger\">\n *\n </span>\n )}\n <InfoTooltip content={tooltip} />\n {labelAction && (\n <TextLink\n href={labelAction.href}\n tabIndex={labelAction.tabIndex ?? undefined}\n className=\"ml-auto text-sm\"\n >\n {labelAction.label}\n </TextLink>\n )}\n </div>\n\n {children}\n\n {helperText && <p className=\"text-sm text-lt-muted-fg\">{helperText}</p>}\n\n <InputError message={error} />\n </div>\n );\n}\n"],"mappings":";;;;;;;AAOA,SAAgB,eAAe,EAC7B,UACA,OACA,YACA,OACA,aACA,MACA,UACA,WAUC;CAGD,IAFa,eAET,GACF,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,oBAAC,OAAD;IAAO,SAAS;IAAM,WAAU;IAC7B,UAAA;GACI,CAAA;GACN;GACD,oBAAC,YAAD,EAAY,SAAS,MAAQ,CAAA;EAC1B;;CAIT,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,oBAAC,OAAD;MAAO,SAAS;MAAO,UAAA;KAAa,CAAA;KACnC,YACC,oBAAC,QAAD;MAAM,eAAY;MAAO,WAAU;MAAwB,UAAA;KAErD,CAAA;KAER,oBAAC,aAAD,EAAa,SAAS,QAAU,CAAA;KAC/B,eACC,oBAAC,UAAD;MACE,MAAM,YAAY;MAClB,UAAU,YAAY,YAAY,KAAA;MAClC,WAAU;MAET,UAAA,YAAY;KACL,CAAA;IAET;;GAEJ;GAEA,cAAc,oBAAC,KAAD;IAAG,WAAU;IAA4B,UAAA;GAAc,CAAA;GAEtE,oBAAC,YAAD,EAAY,SAAS,MAAQ,CAAA;EAC1B;;AAET"}
@@ -1 +1 @@
1
- {"version":3,"file":"submit-button.js","names":[],"sources":["../../../../resources/js/form/components/base/submit-button.tsx"],"sourcesContent":["import { Button } from \"@lattice-php/lattice/ui/button\";\nimport { Spinner } from \"@lattice-php/lattice/ui/spinner\";\nimport type { Emphasis, Variant } from \"@lattice-php/lattice/types/generated\";\nimport { useFormContext } from \"@lattice-php/lattice/form/hooks/context\";\n\nexport function FormSubmitButton({\n label,\n summaryLabel,\n variant,\n emphasis,\n}: {\n label: string;\n summaryLabel: string;\n variant?: Variant | null;\n emphasis?: Emphasis | null;\n}) {\n const { componentId, errors, fieldLabels, processing } = useFormContext();\n\n const invalidFields = Object.entries(errors)\n .filter(([, message]) => Boolean(message))\n .map(([name, message]) => ({ label: fieldLabels[name] ?? name, message: message as string }));\n const hasErrors = invalidFields.length > 0;\n\n return (\n <span className=\"group relative inline-flex flex-col\">\n <Button\n data-lattice-form={componentId}\n data-test=\"form-submit\"\n disabled={processing || hasErrors}\n emphasis={emphasis}\n type=\"submit\"\n variant={variant}\n >\n {processing && <Spinner />}\n {label}\n </Button>\n\n {hasErrors && (\n <div\n className=\"pointer-events-none absolute bottom-full left-1/2 z-lt-popover mb-2 w-max max-w-xs -translate-x-1/2 rounded-lt border border-lt-border bg-lt-surface p-3 text-left text-sm opacity-0 shadow-lt-md transition-opacity group-hover:opacity-100\"\n role=\"tooltip\"\n >\n <p className=\"mb-1 font-medium text-lt-fg\">{summaryLabel}</p>\n <ul className=\"space-y-1\">\n {invalidFields.map((field) => (\n <li className=\"text-lt-muted-fg\" key={field.label}>\n <span className=\"font-medium text-lt-fg\">{field.label}</span> — {field.message}\n </li>\n ))}\n </ul>\n </div>\n )}\n </span>\n );\n}\n"],"mappings":";;;;;AAKA,SAAgB,iBAAiB,EAC/B,OACA,cACA,SACA,YAMC;CACD,MAAM,EAAE,aAAa,QAAQ,aAAa,eAAe,eAAe;CAExE,MAAM,gBAAgB,OAAO,QAAQ,MAAM,EACxC,QAAQ,GAAG,aAAa,QAAQ,OAAO,CAAC,EACxC,KAAK,CAAC,MAAM,cAAc;EAAE,OAAO,YAAY,SAAS;EAAe;CAAkB,EAAE;CAC9F,MAAM,YAAY,cAAc,SAAS;CAEzC,OACE,qBAAC,QAAD;EAAM,WAAU;YAAhB,CACE,qBAAC,QAAD;GACE,qBAAmB;GACnB,aAAU;GACV,UAAU,cAAc;GACd;GACV,MAAK;GACI;aANX,CAQG,cAAc,oBAAC,SAAD,CAAU,CAAA,GACxB,KACK;MAEP,aACC,qBAAC,OAAD;GACE,WAAU;GACV,MAAK;aAFP,CAIE,oBAAC,KAAD;IAAG,WAAU;cAA+B;GAAgB,CAAA,GAC5D,oBAAC,MAAD;IAAI,WAAU;cACX,cAAc,KAAK,UAClB,qBAAC,MAAD;KAAI,WAAU;eAAd;MACE,oBAAC,QAAD;OAAM,WAAU;iBAA0B,MAAM;MAAY,CAAA;MAAC;MAAI,MAAM;KACrE;OAFkC,MAAM,KAExC,CACL;GACC,CAAA,CACD;IAEH;;AAEV"}
1
+ {"version":3,"file":"submit-button.js","names":[],"sources":["../../../../resources/js/form/components/base/submit-button.tsx"],"sourcesContent":["import { Button } from \"@lattice-php/lattice/ui/button\";\nimport { Spinner } from \"@lattice-php/lattice/ui/spinner\";\nimport type { Emphasis, Variant } from \"@lattice-php/lattice/types/generated\";\nimport { useFormContext } from \"@lattice-php/lattice/form/hooks/context\";\n\nexport function FormSubmitButton({\n label,\n summaryLabel,\n variant,\n emphasis,\n}: {\n label: string;\n summaryLabel: string;\n variant?: Variant | null;\n emphasis?: Emphasis | null;\n}) {\n const { componentId, errors, fieldLabels, processing } = useFormContext();\n\n const invalidFields = Object.entries(errors)\n .filter(([, message]) => Boolean(message))\n .map(([name, message]) => ({ label: fieldLabels[name] ?? name, message: message as string }));\n const hasErrors = invalidFields.length > 0;\n\n return (\n <span className=\"group relative inline-flex flex-col\">\n <Button\n data-lattice-form={componentId}\n data-test=\"form-submit\"\n disabled={processing || hasErrors}\n emphasis={emphasis}\n type=\"submit\"\n variant={variant}\n >\n {processing && <Spinner />}\n {label}\n </Button>\n\n {hasErrors && (\n <div\n className=\"pointer-events-none absolute bottom-full left-1/2 z-lt-popover mb-2 w-max max-w-xs -translate-x-1/2 rounded-lt border border-lt-border bg-lt-surface p-3 text-left text-sm opacity-0 shadow-lt-md transition-opacity group-hover:opacity-100\"\n role=\"tooltip\"\n >\n <p className=\"mb-1 font-medium text-lt-fg\">{summaryLabel}</p>\n <ul className=\"space-y-1\">\n {invalidFields.map((field) => (\n <li className=\"text-lt-muted-fg\" key={field.label}>\n <span className=\"font-medium text-lt-fg\">{field.label}</span> — {field.message}\n </li>\n ))}\n </ul>\n </div>\n )}\n </span>\n );\n}\n"],"mappings":";;;;;AAKA,SAAgB,iBAAiB,EAC/B,OACA,cACA,SACA,YAMC;CACD,MAAM,EAAE,aAAa,QAAQ,aAAa,eAAe,eAAe;CAExE,MAAM,gBAAgB,OAAO,QAAQ,MAAM,CAAC,CACzC,QAAQ,GAAG,aAAa,QAAQ,OAAO,CAAC,CAAC,CACzC,KAAK,CAAC,MAAM,cAAc;EAAE,OAAO,YAAY,SAAS;EAAe;CAAkB,EAAE;CAC9F,MAAM,YAAY,cAAc,SAAS;CAEzC,OACE,qBAAC,QAAD;EAAM,WAAU;EAAhB,UAAA,CACE,qBAAC,QAAD;GACE,qBAAmB;GACnB,aAAU;GACV,UAAU,cAAc;GACd;GACV,MAAK;GACI;GANX,UAAA,CAQG,cAAc,oBAAC,SAAD,CAAU,CAAA,GACxB,KACK;EAEP,CAAA,GAAA,aACC,qBAAC,OAAD;GACE,WAAU;GACV,MAAK;GAFP,UAAA,CAIE,oBAAC,KAAD;IAAG,WAAU;IAA+B,UAAA;GAAgB,CAAA,GAC5D,oBAAC,MAAD;IAAI,WAAU;IACX,UAAA,cAAc,KAAK,UAClB,qBAAC,MAAD;KAAI,WAAU;KAAd,UAAA;MACE,oBAAC,QAAD;OAAM,WAAU;OAA0B,UAAA,MAAM;MAAY,CAAA;MAAC;MAAI,MAAM;KACrE;IAFkC,GAAA,MAAM,KAExC,CACL;GACC,CAAA,CACD;EAEH,CAAA,CAAA;;AAEV"}
@@ -1 +1 @@
1
- {"version":3,"file":"add-row-menu.js","names":[],"sources":["../../../../resources/js/form/components/fields/add-row-menu.tsx"],"sourcesContent":["import { Icon } from \"@lattice-php/lattice/icons\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@lattice-php/lattice/ui/dropdown-menu\";\n\nexport type AddRowOption = { type: string; label: string };\n\nexport function AddRowMenu({\n addLabel,\n options,\n onSelect,\n}: {\n addLabel: string;\n options: AddRowOption[];\n onSelect: (type: string) => void;\n}) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n data-test=\"builder-add\"\n className=\"inline-flex items-center gap-1.5 self-start rounded-lt-sm border border-lt-border px-3 py-1.5 text-sm hover:bg-lt-accent [&_svg]:size-lt-icon-sm\"\n >\n <Icon name=\"plus\" />\n {addLabel}\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"min-w-[12rem]\">\n {options.map((option) => (\n <DropdownMenuItem\n key={option.type}\n data-test={`builder-add-${option.type}`}\n onClick={() => onSelect(option.type)}\n >\n {option.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"],"mappings":";;;;AAUA,SAAgB,WAAW,EACzB,UACA,SACA,YAKC;CACD,OACE,qBAAC,cAAD,EAAA,UAAA,CACE,oBAAC,qBAAD;EAAqB,SAAA;YACnB,qBAAC,UAAD;GACE,MAAK;GACL,aAAU;GACV,WAAU;aAHZ,CAKE,oBAAC,MAAD,EAAM,MAAK,OAAQ,CAAA,GAClB,QACK;;CACW,CAAA,GACrB,oBAAC,qBAAD;EAAqB,OAAM;EAAQ,WAAU;YAC1C,QAAQ,KAAK,WACZ,oBAAC,kBAAD;GAEE,aAAW,eAAe,OAAO;GACjC,eAAe,SAAS,OAAO,IAAI;aAElC,OAAO;EACQ,GALX,OAAO,IAKI,CACnB;CACkB,CAAA,CACT,EAAA,CAAA;AAElB"}
1
+ {"version":3,"file":"add-row-menu.js","names":[],"sources":["../../../../resources/js/form/components/fields/add-row-menu.tsx"],"sourcesContent":["import { Icon } from \"@lattice-php/lattice/icons\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@lattice-php/lattice/ui/dropdown-menu\";\n\nexport type AddRowOption = { type: string; label: string };\n\nexport function AddRowMenu({\n addLabel,\n options,\n onSelect,\n}: {\n addLabel: string;\n options: AddRowOption[];\n onSelect: (type: string) => void;\n}) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n data-test=\"builder-add\"\n className=\"inline-flex items-center gap-1.5 self-start rounded-lt-sm border border-lt-border px-3 py-1.5 text-sm hover:bg-lt-accent [&_svg]:size-lt-icon-sm\"\n >\n <Icon name=\"plus\" />\n {addLabel}\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"min-w-[12rem]\">\n {options.map((option) => (\n <DropdownMenuItem\n key={option.type}\n data-test={`builder-add-${option.type}`}\n onClick={() => onSelect(option.type)}\n >\n {option.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"],"mappings":";;;;AAUA,SAAgB,WAAW,EACzB,UACA,SACA,YAKC;CACD,OACE,qBAAC,cAAD,EAAA,UAAA,CACE,oBAAC,qBAAD;EAAqB,SAAA;EACnB,UAAA,qBAAC,UAAD;GACE,MAAK;GACL,aAAU;GACV,WAAU;GAHZ,UAAA,CAKE,oBAAC,MAAD,EAAM,MAAK,OAAQ,CAAA,GAClB,QACK;;CACW,CAAA,GACrB,oBAAC,qBAAD;EAAqB,OAAM;EAAQ,WAAU;EAC1C,UAAA,QAAQ,KAAK,WACZ,oBAAC,kBAAD;GAEE,aAAW,eAAe,OAAO;GACjC,eAAe,SAAS,OAAO,IAAI;GAElC,UAAA,OAAO;EACQ,GALX,OAAO,IAKI,CACnB;CACkB,CAAA,CACT,EAAA,CAAA;AAElB"}
@@ -23,7 +23,8 @@ var BuilderComponent = ({ node }) => {
23
23
  const { hidden, required } = useDependentField(node);
24
24
  const { path, rows, onField, onRemove, onMove, onDuplicate, append } = useRowCollection(name, props.defaultItems ?? 0);
25
25
  const { t } = useT("lattice");
26
- const registerRow = useFlipReorder(rows.map((r) => String(r["rowId"] ?? "")).join(","));
26
+ const orderSignature = rows.map((r) => String(r["rowId"] ?? "")).join(",");
27
+ const registerRow = useFlipReorder(orderSignature);
27
28
  const atMax = props.maxItems != null && rows.length >= props.maxItems;
28
29
  const atMin = props.minItems != null && rows.length <= props.minItems;
29
30
  const isTable = props.layout === "table";
@@ -1 +1 @@
1
- {"version":3,"file":"builder.js","names":[],"sources":["../../../../resources/js/form/components/fields/builder.tsx"],"sourcesContent":["import type { Node, RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { FormFieldFrame } from \"@lattice-php/lattice/form/components/base/field\";\nimport { useFormContext } from \"@lattice-php/lattice/form/hooks/context\";\nimport { useDependentField } from \"@lattice-php/lattice/form/hooks/use-dependent-field\";\nimport { AddRowMenu, type AddRowOption } from \"./add-row-menu\";\nimport { ROW_ID_KEY } from \"./repeater-rows\";\nimport { buildRowActions } from \"./row-action-menu\";\nimport { RowActions } from \"./row-actions\";\nimport { RowKeyInputs } from \"./row-key-inputs\";\nimport { RowItem } from \"./row-item\";\nimport { rowTemplatesOf, type RowTemplate } from \"./row-templates\";\nimport { columnsFromSchema, TableRows } from \"./table-rows\";\nimport { useFlipReorder } from \"./use-flip-reorder\";\nimport { useRowCollection } from \"./use-row-collection\";\n\nconst EMPTY_TEMPLATE: Node[] = [];\n\nexport const BuilderComponent: RendererComponent<\"field.builder\"> = ({ node }) => {\n const props = node.props;\n const name = props.name;\n const templates = rowTemplatesOf(node) ?? [];\n const { errors } = useFormContext();\n const { hidden, required } = useDependentField(node);\n const { path, rows, onField, onRemove, onMove, onDuplicate, append } = useRowCollection(\n name,\n props.defaultItems ?? 0,\n );\n const { t } = useT(\"lattice\");\n const orderSignature = rows.map((r) => String(r[ROW_ID_KEY] ?? \"\")).join(\",\");\n const registerRow = useFlipReorder(orderSignature);\n const atMax = props.maxItems != null && rows.length >= props.maxItems;\n const atMin = props.minItems != null && rows.length <= props.minItems;\n const isTable = props.layout === \"table\";\n\n const templateFor = (type: unknown): RowTemplate | undefined =>\n templates.find((template) => template.type === type);\n const options: AddRowOption[] = templates.map((template) => ({\n type: template.type,\n label: template.label,\n }));\n\n if (hidden) {\n return null;\n }\n\n const primary = templates[0];\n const tableRows = rows.map((row, index) => {\n const template = templateFor(row.type);\n const isPrimary = !!template && !!primary && template.type === primary.type;\n return {\n key: String(row[ROW_ID_KEY] ?? index),\n index,\n row,\n template: template?.schema ?? EMPTY_TEMPLATE,\n span: !isPrimary,\n heading: template?.label ?? `Unknown block: ${String(row.type)}`,\n };\n });\n\n return (\n <FormFieldFrame\n error={errors[path]}\n helperText={props.helperText ?? undefined}\n tooltip={props.tooltip ?? undefined}\n label={props.label ?? \"\"}\n name={path}\n required={required}\n >\n <div className=\"flex flex-col gap-3\">\n <RowKeyInputs path={path} rows={rows} rowKey={ROW_ID_KEY} />\n <RowKeyInputs path={path} rows={rows} rowKey=\"type\" />\n {isTable ? (\n <>\n <TableRows\n base={path}\n columns={columnsFromSchema(primary?.schema ?? [])}\n rows={tableRows}\n reorderable={props.reorderable ?? false}\n removable={() => !atMin}\n rowActions={props.rowActions}\n onField={onField}\n onMove={onMove}\n onRemove={onRemove}\n onDuplicate={onDuplicate}\n registerRow={registerRow}\n resizableColumns={props.resizableColumns === true}\n resizeIndicator={props.resizeIndicator === true}\n />\n </>\n ) : (\n rows.map((row, index) => {\n const template = templateFor(row.type);\n const key = String(row[ROW_ID_KEY] ?? index);\n\n return (\n <div key={key} ref={(el) => registerRow(key, el)} data-flip-key={key}>\n {template ? (\n <RowItem\n base={path}\n index={index}\n row={row}\n template={template.schema ?? EMPTY_TEMPLATE}\n heading={template.label}\n reorderable={props.reorderable ?? false}\n isFirst={index === 0}\n isLast={index === rows.length - 1}\n removable={!atMin}\n rowActions={props.rowActions}\n onField={onField}\n onRemove={onRemove}\n onMove={onMove}\n onDuplicate={onDuplicate}\n />\n ) : (\n <div\n data-test={`repeater-${name}-row-${index}`}\n className=\"flex items-center justify-between rounded-lt border border-dashed border-lt-border p-4 text-sm text-lt-muted-fg\"\n >\n <span>Unknown block: {String(row.type)}</span>\n <RowActions\n actions={buildRowActions(props.rowActions, {\n index,\n removable: !atMin,\n onRemove,\n onDuplicate,\n t,\n })}\n />\n </div>\n )}\n </div>\n );\n })\n )}\n\n {!atMax && (\n <AddRowMenu\n addLabel={props.addLabel ?? \"Add\"}\n options={options}\n onSelect={(type) => append({ type })}\n />\n )}\n </div>\n </FormFieldFrame>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"builder.js","names":[],"sources":["../../../../resources/js/form/components/fields/builder.tsx"],"sourcesContent":["import type { Node, RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { FormFieldFrame } from \"@lattice-php/lattice/form/components/base/field\";\nimport { useFormContext } from \"@lattice-php/lattice/form/hooks/context\";\nimport { useDependentField } from \"@lattice-php/lattice/form/hooks/use-dependent-field\";\nimport { AddRowMenu, type AddRowOption } from \"./add-row-menu\";\nimport { ROW_ID_KEY } from \"./repeater-rows\";\nimport { buildRowActions } from \"./row-action-menu\";\nimport { RowActions } from \"./row-actions\";\nimport { RowKeyInputs } from \"./row-key-inputs\";\nimport { RowItem } from \"./row-item\";\nimport { rowTemplatesOf, type RowTemplate } from \"./row-templates\";\nimport { columnsFromSchema, TableRows } from \"./table-rows\";\nimport { useFlipReorder } from \"./use-flip-reorder\";\nimport { useRowCollection } from \"./use-row-collection\";\n\nconst EMPTY_TEMPLATE: Node[] = [];\n\nexport const BuilderComponent: RendererComponent<\"field.builder\"> = ({ node }) => {\n const props = node.props;\n const name = props.name;\n const templates = rowTemplatesOf(node) ?? [];\n const { errors } = useFormContext();\n const { hidden, required } = useDependentField(node);\n const { path, rows, onField, onRemove, onMove, onDuplicate, append } = useRowCollection(\n name,\n props.defaultItems ?? 0,\n );\n const { t } = useT(\"lattice\");\n const orderSignature = rows.map((r) => String(r[ROW_ID_KEY] ?? \"\")).join(\",\");\n const registerRow = useFlipReorder(orderSignature);\n const atMax = props.maxItems != null && rows.length >= props.maxItems;\n const atMin = props.minItems != null && rows.length <= props.minItems;\n const isTable = props.layout === \"table\";\n\n const templateFor = (type: unknown): RowTemplate | undefined =>\n templates.find((template) => template.type === type);\n const options: AddRowOption[] = templates.map((template) => ({\n type: template.type,\n label: template.label,\n }));\n\n if (hidden) {\n return null;\n }\n\n const primary = templates[0];\n const tableRows = rows.map((row, index) => {\n const template = templateFor(row.type);\n const isPrimary = !!template && !!primary && template.type === primary.type;\n return {\n key: String(row[ROW_ID_KEY] ?? index),\n index,\n row,\n template: template?.schema ?? EMPTY_TEMPLATE,\n span: !isPrimary,\n heading: template?.label ?? `Unknown block: ${String(row.type)}`,\n };\n });\n\n return (\n <FormFieldFrame\n error={errors[path]}\n helperText={props.helperText ?? undefined}\n tooltip={props.tooltip ?? undefined}\n label={props.label ?? \"\"}\n name={path}\n required={required}\n >\n <div className=\"flex flex-col gap-3\">\n <RowKeyInputs path={path} rows={rows} rowKey={ROW_ID_KEY} />\n <RowKeyInputs path={path} rows={rows} rowKey=\"type\" />\n {isTable ? (\n <>\n <TableRows\n base={path}\n columns={columnsFromSchema(primary?.schema ?? [])}\n rows={tableRows}\n reorderable={props.reorderable ?? false}\n removable={() => !atMin}\n rowActions={props.rowActions}\n onField={onField}\n onMove={onMove}\n onRemove={onRemove}\n onDuplicate={onDuplicate}\n registerRow={registerRow}\n resizableColumns={props.resizableColumns === true}\n resizeIndicator={props.resizeIndicator === true}\n />\n </>\n ) : (\n rows.map((row, index) => {\n const template = templateFor(row.type);\n const key = String(row[ROW_ID_KEY] ?? index);\n\n return (\n <div key={key} ref={(el) => registerRow(key, el)} data-flip-key={key}>\n {template ? (\n <RowItem\n base={path}\n index={index}\n row={row}\n template={template.schema ?? EMPTY_TEMPLATE}\n heading={template.label}\n reorderable={props.reorderable ?? false}\n isFirst={index === 0}\n isLast={index === rows.length - 1}\n removable={!atMin}\n rowActions={props.rowActions}\n onField={onField}\n onRemove={onRemove}\n onMove={onMove}\n onDuplicate={onDuplicate}\n />\n ) : (\n <div\n data-test={`repeater-${name}-row-${index}`}\n className=\"flex items-center justify-between rounded-lt border border-dashed border-lt-border p-4 text-sm text-lt-muted-fg\"\n >\n <span>Unknown block: {String(row.type)}</span>\n <RowActions\n actions={buildRowActions(props.rowActions, {\n index,\n removable: !atMin,\n onRemove,\n onDuplicate,\n t,\n })}\n />\n </div>\n )}\n </div>\n );\n })\n )}\n\n {!atMax && (\n <AddRowMenu\n addLabel={props.addLabel ?? \"Add\"}\n options={options}\n onSelect={(type) => append({ type })}\n />\n )}\n </div>\n </FormFieldFrame>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox.js","names":[],"sources":["../../../../resources/js/form/components/fields/checkbox.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { testIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport { Checkbox } from \"@lattice-php/lattice/ui/checkbox\";\nimport { Label } from \"@lattice-php/lattice/ui/label\";\nimport { toBoolean } from \"@lattice-php/lattice/form/lib/conditions\";\nimport { useFormContext } from \"@lattice-php/lattice/form/hooks/context\";\nimport { fieldDomName } from \"@lattice-php/lattice/form/lib/field-dom-name\";\nimport { useFieldScope } from \"@lattice-php/lattice/form/hooks/field-scope\";\nimport { useDependentField } from \"@lattice-php/lattice/form/hooks/use-dependent-field\";\nimport { useFieldCommit } from \"@lattice-php/lattice/form/hooks/use-field-commit\";\nimport { useSeedDefault } from \"@lattice-php/lattice/form/hooks/use-seed-default\";\nimport { useFormValue } from \"@lattice-php/lattice/form/hooks/values\";\n\nexport const CheckboxComponent: RendererComponent<\"field.checkbox\"> = ({ node }) => {\n const { hidden, readOnly, disabled } = useDependentField(node);\n const localName = node.props.name;\n const scope = useFieldScope();\n const { fieldIdPrefix } = useFormContext();\n const name = fieldDomName(scope ? scope.scopedName(localName) : localName, fieldIdPrefix);\n const globalValue = useFormValue(localName);\n const storedValue = scope ? scope.getValue(localName) : globalValue;\n const { commit } = useFieldCommit();\n const defaultChecked = toBoolean(node.props.value);\n const checked = storedValue !== undefined ? toBoolean(storedValue) : defaultChecked;\n\n useSeedDefault(localName, defaultChecked);\n\n if (hidden) {\n return null;\n }\n\n return (\n <div>\n <div className=\"flex items-center space-x-3\">\n <Checkbox\n autoFocus={node.props.autoFocus ?? undefined}\n checked={checked}\n data-test={testIdentity(localName)}\n disabled={readOnly || disabled}\n id={name}\n name={name}\n onCheckedChange={(next) => {\n commit(localName, next === true);\n }}\n tabIndex={node.props.tabIndex ?? undefined}\n />\n <Label htmlFor={name}>{node.props.label}</Label>\n </div>\n {node.props.helperText && (\n <p className=\"mt-1 pl-7 text-sm text-lt-muted-fg\">{node.props.helperText}</p>\n )}\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;;AAaA,IAAa,qBAA0D,EAAE,WAAW;CAClF,MAAM,EAAE,QAAQ,UAAU,aAAa,kBAAkB,IAAI;CAC7D,MAAM,YAAY,KAAK,MAAM;CAC7B,MAAM,QAAQ,cAAc;CAC5B,MAAM,EAAE,kBAAkB,eAAe;CACzC,MAAM,OAAO,aAAa,QAAQ,MAAM,WAAW,SAAS,IAAI,WAAW,aAAa;CACxF,MAAM,cAAc,aAAa,SAAS;CAC1C,MAAM,cAAc,QAAQ,MAAM,SAAS,SAAS,IAAI;CACxD,MAAM,EAAE,WAAW,eAAe;CAClC,MAAM,iBAAiB,UAAU,KAAK,MAAM,KAAK;CACjD,MAAM,UAAU,gBAAgB,KAAA,IAAY,UAAU,WAAW,IAAI;CAErE,eAAe,WAAW,cAAc;CAExC,IAAI,QACF,OAAO;CAGT,OACE,qBAAC,OAAD,EAAA,UAAA,CACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,UAAD;GACE,WAAW,KAAK,MAAM,aAAa,KAAA;GAC1B;GACT,aAAW,aAAa,SAAS;GACjC,UAAU,YAAY;GACtB,IAAI;GACE;GACN,kBAAkB,SAAS;IACzB,OAAO,WAAW,SAAS,IAAI;GACjC;GACA,UAAU,KAAK,MAAM,YAAY,KAAA;EAClC,CAAA,GACD,oBAAC,OAAD;GAAO,SAAS;aAAO,KAAK,MAAM;EAAa,CAAA,CAC5C;KACJ,KAAK,MAAM,cACV,oBAAC,KAAD;EAAG,WAAU;YAAsC,KAAK,MAAM;CAAc,CAAA,CAE3E,EAAA,CAAA;AAET"}
1
+ {"version":3,"file":"checkbox.js","names":[],"sources":["../../../../resources/js/form/components/fields/checkbox.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { testIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport { Checkbox } from \"@lattice-php/lattice/ui/checkbox\";\nimport { Label } from \"@lattice-php/lattice/ui/label\";\nimport { toBoolean } from \"@lattice-php/lattice/form/lib/conditions\";\nimport { useFormContext } from \"@lattice-php/lattice/form/hooks/context\";\nimport { fieldDomName } from \"@lattice-php/lattice/form/lib/field-dom-name\";\nimport { useFieldScope } from \"@lattice-php/lattice/form/hooks/field-scope\";\nimport { useDependentField } from \"@lattice-php/lattice/form/hooks/use-dependent-field\";\nimport { useFieldCommit } from \"@lattice-php/lattice/form/hooks/use-field-commit\";\nimport { useSeedDefault } from \"@lattice-php/lattice/form/hooks/use-seed-default\";\nimport { useFormValue } from \"@lattice-php/lattice/form/hooks/values\";\n\nexport const CheckboxComponent: RendererComponent<\"field.checkbox\"> = ({ node }) => {\n const { hidden, readOnly, disabled } = useDependentField(node);\n const localName = node.props.name;\n const scope = useFieldScope();\n const { fieldIdPrefix } = useFormContext();\n const name = fieldDomName(scope ? scope.scopedName(localName) : localName, fieldIdPrefix);\n const globalValue = useFormValue(localName);\n const storedValue = scope ? scope.getValue(localName) : globalValue;\n const { commit } = useFieldCommit();\n const defaultChecked = toBoolean(node.props.value);\n const checked = storedValue !== undefined ? toBoolean(storedValue) : defaultChecked;\n\n useSeedDefault(localName, defaultChecked);\n\n if (hidden) {\n return null;\n }\n\n return (\n <div>\n <div className=\"flex items-center space-x-3\">\n <Checkbox\n autoFocus={node.props.autoFocus ?? undefined}\n checked={checked}\n data-test={testIdentity(localName)}\n disabled={readOnly || disabled}\n id={name}\n name={name}\n onCheckedChange={(next) => {\n commit(localName, next === true);\n }}\n tabIndex={node.props.tabIndex ?? undefined}\n />\n <Label htmlFor={name}>{node.props.label}</Label>\n </div>\n {node.props.helperText && (\n <p className=\"mt-1 pl-7 text-sm text-lt-muted-fg\">{node.props.helperText}</p>\n )}\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;;AAaA,IAAa,qBAA0D,EAAE,WAAW;CAClF,MAAM,EAAE,QAAQ,UAAU,aAAa,kBAAkB,IAAI;CAC7D,MAAM,YAAY,KAAK,MAAM;CAC7B,MAAM,QAAQ,cAAc;CAC5B,MAAM,EAAE,kBAAkB,eAAe;CACzC,MAAM,OAAO,aAAa,QAAQ,MAAM,WAAW,SAAS,IAAI,WAAW,aAAa;CACxF,MAAM,cAAc,aAAa,SAAS;CAC1C,MAAM,cAAc,QAAQ,MAAM,SAAS,SAAS,IAAI;CACxD,MAAM,EAAE,WAAW,eAAe;CAClC,MAAM,iBAAiB,UAAU,KAAK,MAAM,KAAK;CACjD,MAAM,UAAU,gBAAgB,KAAA,IAAY,UAAU,WAAW,IAAI;CAErE,eAAe,WAAW,cAAc;CAExC,IAAI,QACF,OAAO;CAGT,OACE,qBAAC,OAAD,EAAA,UAAA,CACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,UAAD;GACE,WAAW,KAAK,MAAM,aAAa,KAAA;GAC1B;GACT,aAAW,aAAa,SAAS;GACjC,UAAU,YAAY;GACtB,IAAI;GACE;GACN,kBAAkB,SAAS;IACzB,OAAO,WAAW,SAAS,IAAI;GACjC;GACA,UAAU,KAAK,MAAM,YAAY,KAAA;EAClC,CAAA,GACD,oBAAC,OAAD;GAAO,SAAS;GAAO,UAAA,KAAK,MAAM;EAAa,CAAA,CAC5C;CACJ,CAAA,GAAA,KAAK,MAAM,cACV,oBAAC,KAAD;EAAG,WAAU;EAAsC,UAAA,KAAK,MAAM;CAAc,CAAA,CAE3E,EAAA,CAAA;AAET"}
@@ -1 +1 @@
1
- {"version":3,"file":"choice.js","names":[],"sources":["../../../../resources/js/form/components/fields/choice.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport type { Option, RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { SegmentedPills } from \"@lattice-php/lattice/ui/segmented-pills\";\nimport { FormFieldFrame } from \"@lattice-php/lattice/form/components/base/field\";\nimport { useControlledField } from \"@lattice-php/lattice/form/hooks/use-controlled-field\";\nimport { useResolvedNode } from \"@lattice-php/lattice/form/hooks/resolved-nodes\";\nimport { useSeedDefault } from \"@lattice-php/lattice/form/hooks/use-seed-default\";\n\nexport const ChoiceComponent: RendererComponent<\"field.choice\"> = ({ node }) => {\n const resolvedNode = useResolvedNode(node);\n const { localName, name, testId, value, error, hidden, required, readOnly, disabled, commit } =\n useControlledField(node);\n const options = useMemo(\n () => (resolvedNode.props as { options?: Option[] }).options ?? [],\n [resolvedNode.props],\n );\n const fallbackValue = options[0]?.value ?? \"\";\n const selected = value || fallbackValue;\n\n useSeedDefault(localName, selected || undefined);\n\n if (hidden || options.length === 0) {\n return null;\n }\n\n return (\n <FormFieldFrame\n error={error}\n helperText={node.props.helperText ?? undefined}\n tooltip={node.props.tooltip ?? undefined}\n label={node.props.label ?? \"\"}\n name={name}\n required={required}\n >\n <input name={name} type=\"hidden\" value={selected} />\n <SegmentedPills\n ariaLabel={node.props.label ?? undefined}\n autoFocus={node.props.autoFocus ?? undefined}\n disabled={readOnly || disabled}\n name={testId}\n onSelect={commit}\n options={options}\n tabIndex={node.props.tabIndex ?? undefined}\n value={selected}\n />\n </FormFieldFrame>\n );\n};\n"],"mappings":";;;;;;;;AAQA,IAAa,mBAAsD,EAAE,WAAW;CAC9E,MAAM,eAAe,gBAAgB,IAAI;CACzC,MAAM,EAAE,WAAW,MAAM,QAAQ,OAAO,OAAO,QAAQ,UAAU,UAAU,UAAU,WACnF,mBAAmB,IAAI;CACzB,MAAM,UAAU,cACP,aAAa,MAAiC,WAAW,CAAC,GACjE,CAAC,aAAa,KAAK,CACrB;CACA,MAAM,gBAAgB,QAAQ,IAAI,SAAS;CAC3C,MAAM,WAAW,SAAS;CAE1B,eAAe,WAAW,YAAY,KAAA,CAAS;CAE/C,IAAI,UAAU,QAAQ,WAAW,GAC/B,OAAO;CAGT,OACE,qBAAC,gBAAD;EACS;EACP,YAAY,KAAK,MAAM,cAAc,KAAA;EACrC,SAAS,KAAK,MAAM,WAAW,KAAA;EAC/B,OAAO,KAAK,MAAM,SAAS;EACrB;EACI;YANZ,CAQE,oBAAC,SAAD;GAAa;GAAM,MAAK;GAAS,OAAO;EAAW,CAAA,GACnD,oBAAC,gBAAD;GACE,WAAW,KAAK,MAAM,SAAS,KAAA;GAC/B,WAAW,KAAK,MAAM,aAAa,KAAA;GACnC,UAAU,YAAY;GACtB,MAAM;GACN,UAAU;GACD;GACT,UAAU,KAAK,MAAM,YAAY,KAAA;GACjC,OAAO;EACR,CAAA,CACa;;AAEpB"}
1
+ {"version":3,"file":"choice.js","names":[],"sources":["../../../../resources/js/form/components/fields/choice.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport type { Option, RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { SegmentedPills } from \"@lattice-php/lattice/ui/segmented-pills\";\nimport { FormFieldFrame } from \"@lattice-php/lattice/form/components/base/field\";\nimport { useControlledField } from \"@lattice-php/lattice/form/hooks/use-controlled-field\";\nimport { useResolvedNode } from \"@lattice-php/lattice/form/hooks/resolved-nodes\";\nimport { useSeedDefault } from \"@lattice-php/lattice/form/hooks/use-seed-default\";\n\nexport const ChoiceComponent: RendererComponent<\"field.choice\"> = ({ node }) => {\n const resolvedNode = useResolvedNode(node);\n const { localName, name, testId, value, error, hidden, required, readOnly, disabled, commit } =\n useControlledField(node);\n const options = useMemo(\n () => (resolvedNode.props as { options?: Option[] }).options ?? [],\n [resolvedNode.props],\n );\n const fallbackValue = options[0]?.value ?? \"\";\n const selected = value || fallbackValue;\n\n useSeedDefault(localName, selected || undefined);\n\n if (hidden || options.length === 0) {\n return null;\n }\n\n return (\n <FormFieldFrame\n error={error}\n helperText={node.props.helperText ?? undefined}\n tooltip={node.props.tooltip ?? undefined}\n label={node.props.label ?? \"\"}\n name={name}\n required={required}\n >\n <input name={name} type=\"hidden\" value={selected} />\n <SegmentedPills\n ariaLabel={node.props.label ?? undefined}\n autoFocus={node.props.autoFocus ?? undefined}\n disabled={readOnly || disabled}\n name={testId}\n onSelect={commit}\n options={options}\n tabIndex={node.props.tabIndex ?? undefined}\n value={selected}\n />\n </FormFieldFrame>\n );\n};\n"],"mappings":";;;;;;;;AAQA,IAAa,mBAAsD,EAAE,WAAW;CAC9E,MAAM,eAAe,gBAAgB,IAAI;CACzC,MAAM,EAAE,WAAW,MAAM,QAAQ,OAAO,OAAO,QAAQ,UAAU,UAAU,UAAU,WACnF,mBAAmB,IAAI;CACzB,MAAM,UAAU,cACP,aAAa,MAAiC,WAAW,CAAC,GACjE,CAAC,aAAa,KAAK,CACrB;CACA,MAAM,gBAAgB,QAAQ,EAAE,EAAE,SAAS;CAC3C,MAAM,WAAW,SAAS;CAE1B,eAAe,WAAW,YAAY,KAAA,CAAS;CAE/C,IAAI,UAAU,QAAQ,WAAW,GAC/B,OAAO;CAGT,OACE,qBAAC,gBAAD;EACS;EACP,YAAY,KAAK,MAAM,cAAc,KAAA;EACrC,SAAS,KAAK,MAAM,WAAW,KAAA;EAC/B,OAAO,KAAK,MAAM,SAAS;EACrB;EACI;EANZ,UAAA,CAQE,oBAAC,SAAD;GAAa;GAAM,MAAK;GAAS,OAAO;EAAW,CAAA,GACnD,oBAAC,gBAAD;GACE,WAAW,KAAK,MAAM,SAAS,KAAA;GAC/B,WAAW,KAAK,MAAM,aAAa,KAAA;GACnC,UAAU,YAAY;GACtB,MAAM;GACN,UAAU;GACD;GACT,UAAU,KAAK,MAAM,YAAY,KAAA;GACjC,OAAO;EACR,CAAA,CACa;;AAEpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"color-picker-field.js","names":[],"sources":["../../../../resources/js/form/components/fields/color-picker-field.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { ColorPicker, normalizeHex } from \"@lattice-php/lattice/ui/color-picker\";\nimport { controlSurface } from \"@lattice-php/lattice/ui/control\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@lattice-php/lattice/ui/popover\";\nimport { SimpleField } from \"./simple-field\";\n\nexport const ColorPickerFieldComponent: RendererComponent<\"field.color-picker\"> = ({ node }) => {\n const props = node.props;\n\n return (\n <SimpleField node={node} label={props.label ?? \"\"}>\n {({ name, value, readOnly, disabled, commit }) => {\n const hex = normalizeHex(value);\n\n return (\n <Popover>\n <input name={name} type=\"hidden\" value={hex ?? \"\"} />\n <PopoverTrigger asChild>\n <button\n className={cn(controlSurface(), \"flex items-center gap-2 text-left\")}\n data-test={`color-picker-${name}`}\n disabled={disabled || readOnly}\n id={name}\n type=\"button\"\n >\n {hex ? (\n <>\n <span\n aria-hidden=\"true\"\n className=\"size-4 shrink-0 rounded-full border border-lt-border\"\n style={{ background: hex }}\n />\n <span className=\"tabular-nums\">{hex}</span>\n </>\n ) : (\n <span className=\"text-lt-muted-fg\">{props.placeholder ?? \"\"}</span>\n )}\n </button>\n </PopoverTrigger>\n <PopoverContent className=\"p-3\">\n <ColorPicker\n onChange={(next) => commit(next)}\n palette={props.palette}\n value={hex ?? \"#6b7280\"}\n />\n </PopoverContent>\n </Popover>\n );\n }}\n </SimpleField>\n );\n};\n"],"mappings":";;;;;;;AAOA,IAAa,6BAAsE,EAAE,WAAW;CAC9F,MAAM,QAAQ,KAAK;CAEnB,OACE,oBAAC,aAAD;EAAmB;EAAM,OAAO,MAAM,SAAS;aAC3C,EAAE,MAAM,OAAO,UAAU,UAAU,aAAa;GAChD,MAAM,MAAM,aAAa,KAAK;GAE9B,OACE,qBAAC,SAAD,EAAA,UAAA;IACE,oBAAC,SAAD;KAAa;KAAM,MAAK;KAAS,OAAO,OAAO;IAAK,CAAA;IACpD,oBAAC,gBAAD;KAAgB,SAAA;eACd,oBAAC,UAAD;MACE,WAAW,GAAG,eAAe,GAAG,mCAAmC;MACnE,aAAW,gBAAgB;MAC3B,UAAU,YAAY;MACtB,IAAI;MACJ,MAAK;gBAEJ,MACC,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,QAAD;OACE,eAAY;OACZ,WAAU;OACV,OAAO,EAAE,YAAY,IAAI;MAC1B,CAAA,GACD,oBAAC,QAAD;OAAM,WAAU;iBAAgB;MAAU,CAAA,CAC1C,EAAA,CAAA,IAEF,oBAAC,QAAD;OAAM,WAAU;iBAAoB,MAAM,eAAe;MAAS,CAAA;KAE9D,CAAA;IACM,CAAA;IAChB,oBAAC,gBAAD;KAAgB,WAAU;eACxB,oBAAC,aAAD;MACE,WAAW,SAAS,OAAO,IAAI;MAC/B,SAAS,MAAM;MACf,OAAO,OAAO;KACf,CAAA;IACa,CAAA;GACT,EAAA,CAAA;EAEb;CACW,CAAA;AAEjB"}
1
+ {"version":3,"file":"color-picker-field.js","names":[],"sources":["../../../../resources/js/form/components/fields/color-picker-field.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { ColorPicker, normalizeHex } from \"@lattice-php/lattice/ui/color-picker\";\nimport { controlSurface } from \"@lattice-php/lattice/ui/control\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@lattice-php/lattice/ui/popover\";\nimport { SimpleField } from \"./simple-field\";\n\nexport const ColorPickerFieldComponent: RendererComponent<\"field.color-picker\"> = ({ node }) => {\n const props = node.props;\n\n return (\n <SimpleField node={node} label={props.label ?? \"\"}>\n {({ name, value, readOnly, disabled, commit }) => {\n const hex = normalizeHex(value);\n\n return (\n <Popover>\n <input name={name} type=\"hidden\" value={hex ?? \"\"} />\n <PopoverTrigger asChild>\n <button\n className={cn(controlSurface(), \"flex items-center gap-2 text-left\")}\n data-test={`color-picker-${name}`}\n disabled={disabled || readOnly}\n id={name}\n type=\"button\"\n >\n {hex ? (\n <>\n <span\n aria-hidden=\"true\"\n className=\"size-4 shrink-0 rounded-full border border-lt-border\"\n style={{ background: hex }}\n />\n <span className=\"tabular-nums\">{hex}</span>\n </>\n ) : (\n <span className=\"text-lt-muted-fg\">{props.placeholder ?? \"\"}</span>\n )}\n </button>\n </PopoverTrigger>\n <PopoverContent className=\"p-3\">\n <ColorPicker\n onChange={(next) => commit(next)}\n palette={props.palette}\n value={hex ?? \"#6b7280\"}\n />\n </PopoverContent>\n </Popover>\n );\n }}\n </SimpleField>\n );\n};\n"],"mappings":";;;;;;;AAOA,IAAa,6BAAsE,EAAE,WAAW;CAC9F,MAAM,QAAQ,KAAK;CAEnB,OACE,oBAAC,aAAD;EAAmB;EAAM,OAAO,MAAM,SAAS;EAC3C,WAAA,EAAE,MAAM,OAAO,UAAU,UAAU,aAAa;GAChD,MAAM,MAAM,aAAa,KAAK;GAE9B,OACE,qBAAC,SAAD,EAAA,UAAA;IACE,oBAAC,SAAD;KAAa;KAAM,MAAK;KAAS,OAAO,OAAO;IAAK,CAAA;IACpD,oBAAC,gBAAD;KAAgB,SAAA;KACd,UAAA,oBAAC,UAAD;MACE,WAAW,GAAG,eAAe,GAAG,mCAAmC;MACnE,aAAW,gBAAgB;MAC3B,UAAU,YAAY;MACtB,IAAI;MACJ,MAAK;MAEJ,UAAA,MACC,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,QAAD;OACE,eAAY;OACZ,WAAU;OACV,OAAO,EAAE,YAAY,IAAI;MAC1B,CAAA,GACD,oBAAC,QAAD;OAAM,WAAU;OAAgB,UAAA;MAAU,CAAA,CAC1C,EAAA,CAAA,IAEF,oBAAC,QAAD;OAAM,WAAU;OAAoB,UAAA,MAAM,eAAe;MAAS,CAAA;KAE9D,CAAA;IACM,CAAA;IAChB,oBAAC,gBAAD;KAAgB,WAAU;KACxB,UAAA,oBAAC,aAAD;MACE,WAAW,SAAS,OAAO,IAAI;MAC/B,SAAS,MAAM;MACf,OAAO,OAAO;KACf,CAAA;IACa,CAAA;GACT,EAAA,CAAA;EAEb;CACW,CAAA;AAEjB"}
@@ -1 +1 @@
1
- {"version":3,"file":"date-input.js","names":[],"sources":["../../../../resources/js/form/components/fields/date-input.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { DatePicker } from \"./date-picker\";\nimport { SimpleField } from \"./simple-field\";\n\nexport const DateInputComponent: RendererComponent<\"field.date-input\"> = ({ node }) => {\n const props = node.props;\n\n return (\n <SimpleField node={node} label={props.label ?? \"\"}>\n {({ name, testId, value, readOnly, disabled, change, blur }) => (\n <DatePicker\n autoFocus={props.autoFocus ?? false}\n disabled={disabled}\n label={props.label ?? props.name}\n max={props.max || undefined}\n min={props.min || undefined}\n mode=\"date\"\n name={name}\n onBlur={blur}\n onChange={change}\n readOnly={readOnly}\n tabIndex={props.tabIndex ?? undefined}\n testId={testId ?? props.name}\n value={value}\n />\n )}\n </SimpleField>\n );\n};\n"],"mappings":";;;;AAIA,IAAa,sBAA6D,EAAE,WAAW;CACrF,MAAM,QAAQ,KAAK;CAEnB,OACE,oBAAC,aAAD;EAAmB;EAAM,OAAO,MAAM,SAAS;aAC3C,EAAE,MAAM,QAAQ,OAAO,UAAU,UAAU,QAAQ,WACnD,oBAAC,YAAD;GACE,WAAW,MAAM,aAAa;GACpB;GACV,OAAO,MAAM,SAAS,MAAM;GAC5B,KAAK,MAAM,OAAO,KAAA;GAClB,KAAK,MAAM,OAAO,KAAA;GAClB,MAAK;GACC;GACN,QAAQ;GACR,UAAU;GACA;GACV,UAAU,MAAM,YAAY,KAAA;GAC5B,QAAQ,UAAU,MAAM;GACjB;EACR,CAAA;CAEQ,CAAA;AAEjB"}
1
+ {"version":3,"file":"date-input.js","names":[],"sources":["../../../../resources/js/form/components/fields/date-input.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { DatePicker } from \"./date-picker\";\nimport { SimpleField } from \"./simple-field\";\n\nexport const DateInputComponent: RendererComponent<\"field.date-input\"> = ({ node }) => {\n const props = node.props;\n\n return (\n <SimpleField node={node} label={props.label ?? \"\"}>\n {({ name, testId, value, readOnly, disabled, change, blur }) => (\n <DatePicker\n autoFocus={props.autoFocus ?? false}\n disabled={disabled}\n label={props.label ?? props.name}\n max={props.max || undefined}\n min={props.min || undefined}\n mode=\"date\"\n name={name}\n onBlur={blur}\n onChange={change}\n readOnly={readOnly}\n tabIndex={props.tabIndex ?? undefined}\n testId={testId ?? props.name}\n value={value}\n />\n )}\n </SimpleField>\n );\n};\n"],"mappings":";;;;AAIA,IAAa,sBAA6D,EAAE,WAAW;CACrF,MAAM,QAAQ,KAAK;CAEnB,OACE,oBAAC,aAAD;EAAmB;EAAM,OAAO,MAAM,SAAS;EAC3C,WAAA,EAAE,MAAM,QAAQ,OAAO,UAAU,UAAU,QAAQ,WACnD,oBAAC,YAAD;GACE,WAAW,MAAM,aAAa;GACpB;GACV,OAAO,MAAM,SAAS,MAAM;GAC5B,KAAK,MAAM,OAAO,KAAA;GAClB,KAAK,MAAM,OAAO,KAAA;GAClB,MAAK;GACC;GACN,QAAQ;GACR,UAAU;GACA;GACV,UAAU,MAAM,YAAY,KAAA;GAC5B,QAAQ,UAAU,MAAM;GACjB;EACR,CAAA;CAEQ,CAAA;AAEjB"}
@@ -1 +1 @@
1
- {"version":3,"file":"date-picker-field.js","names":[],"sources":["../../../../resources/js/form/components/fields/date-picker-field.tsx"],"sourcesContent":["import type { DateValue } from \"@internationalized/date\";\nimport * as datePicker from \"@zag-js/date-picker\";\nimport { normalizeProps, useMachine } from \"@zag-js/react\";\nimport { useId, useMemo } from \"react\";\nimport { Button } from \"@lattice-php/lattice/ui/button\";\nimport { Icon } from \"@lattice-php/lattice/icons\";\nimport { useLocale } from \"@lattice-php/lattice/i18n\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { Input } from \"@lattice-php/lattice/ui/input\";\nimport {\n formatDateDisplayValue,\n formatDateTimeDisplayValue,\n formatDateTimeValue,\n formatDateValue,\n formatTimeInputValue,\n parseDateDisplayValue,\n parseDateTimeDisplayValue,\n parseDateTimeValue,\n parseDateValue,\n} from \"./date-picker-value\";\nimport { TimePicker } from \"./time-picker\";\nimport { parseTimeString } from \"./time-picker-columns\";\n\nexport type DatePickerFieldProps = {\n mode: \"date\" | \"date-time\";\n label: string;\n name: string;\n testId: string;\n value: unknown;\n min?: string | null;\n max?: string | null;\n step?: number | null;\n disabled: boolean;\n readOnly: boolean;\n autoFocus?: boolean;\n tabIndex?: number | null;\n timezone?: string;\n onChange: (value: string) => void;\n onBlur?: () => void;\n};\n\nexport function DatePickerField({\n mode,\n label,\n name,\n testId,\n value,\n min,\n max,\n step,\n disabled,\n readOnly,\n autoFocus = false,\n tabIndex,\n timezone = \"UTC\",\n onChange,\n onBlur,\n}: DatePickerFieldProps) {\n const id = useId();\n const { locale } = useLocale();\n const selected = useMemo(\n () =>\n [mode === \"date\" ? parseDateValue(value) : parseDateTimeValue(value, timezone)].filter(\n Boolean,\n ) as DateValue[],\n [mode, timezone, value],\n );\n const service = useMachine(datePicker.machine, {\n id,\n name,\n value: selected.length > 0 ? selected : undefined,\n min: min ? parseDateValue(min) : undefined,\n max: max ? parseDateValue(max) : undefined,\n disabled,\n readOnly,\n locale,\n selectionMode: \"single\",\n timeZone: timezone,\n closeOnSelect: mode === \"date\",\n format(date) {\n return mode === \"date\"\n ? formatDateDisplayValue(date, locale)\n : formatDateTimeDisplayValue(date, locale, timezone);\n },\n parse(text) {\n return mode === \"date\"\n ? parseDateDisplayValue(text, locale)\n : parseDateTimeDisplayValue(text, locale, timezone);\n },\n onValueChange(details) {\n const next = details.value[0];\n\n onChange(mode === \"date\" ? formatDateValue(next) : formatDateTimeValue(next, timezone));\n },\n onOpenChange(details) {\n if (!details.open) {\n onBlur?.();\n }\n },\n });\n const api = datePicker.connect(service, normalizeProps);\n const { name: _inputName, onInput, ...inputProps } = api.getInputProps();\n const submittedValue =\n mode === \"date\" ? formatDateValue(selected[0]) : formatDateTimeValue(selected[0], timezone);\n\n return (\n <div {...api.getRootProps()} className={cn(\"relative\", api.open && \"z-lt-popover\")}>\n <input type=\"hidden\" name={name} value={submittedValue} data-test={`${testId}-value`} />\n <div {...api.getControlProps()} className=\"flex gap-2\">\n <Input\n {...inputProps}\n aria-label={label}\n autoFocus={autoFocus}\n data-test={testId}\n disabled={disabled}\n id={name}\n onInput={(event) => {\n onInput?.(event);\n\n if (mode !== \"date\") {\n return;\n }\n\n const normalized = normalizeDateInputValue(event.currentTarget.value);\n\n if (!normalized) {\n return;\n }\n\n const next = parseDateValue(normalized);\n\n if (!next) {\n return;\n }\n\n event.currentTarget.value = normalized;\n api.setValue([next]);\n event.currentTarget.value = formatDateDisplayValue(next, locale);\n onChange(formatDateValue(next));\n }}\n readOnly={readOnly}\n tabIndex={tabIndex ?? undefined}\n />\n <Button\n {...api.getTriggerProps()}\n aria-label={`Open ${label || name} calendar`}\n disabled={disabled || readOnly}\n size=\"icon\"\n type=\"button\"\n variant=\"secondary\"\n >\n <Icon name=\"calendar\" className=\"size-lt-icon-md\" aria-hidden=\"true\" />\n </Button>\n </div>\n {api.open ? (\n <div\n {...api.getPositionerProps()}\n className=\"absolute z-lt-popover mt-2 rounded-lt-sm border border-lt-border bg-lt-popover p-3 text-lt-popover-fg shadow-lt-md\"\n >\n <div {...api.getContentProps()} className=\"grid gap-3\">\n <div className=\"flex items-center justify-between gap-2\">\n <Button {...api.getPrevTriggerProps()} emphasis=\"ghost\" size=\"icon\" type=\"button\">\n <Icon name=\"chevron-left\" className=\"size-lt-icon-md\" aria-hidden=\"true\" />\n </Button>\n <div {...api.getRangeTextProps()} className=\"text-sm font-medium text-lt-fg\" />\n <Button {...api.getNextTriggerProps()} emphasis=\"ghost\" size=\"icon\" type=\"button\">\n <Icon name=\"chevron-right\" className=\"size-lt-icon-md\" aria-hidden=\"true\" />\n </Button>\n </div>\n <table {...api.getTableProps()} className=\"w-full border-collapse text-sm\">\n <thead {...api.getTableHeadProps()}>\n <tr {...api.getTableRowProps()}>\n {api.weekDays.map((day) => (\n <th\n {...api.getTableHeaderProps()}\n aria-label={day.long}\n key={day.value.toString()}\n className=\"size-8 text-center text-xs font-medium text-lt-muted-fg\"\n >\n {day.narrow}\n </th>\n ))}\n </tr>\n </thead>\n <tbody {...api.getTableBodyProps()}>\n {api.weeks.map((week, weekIndex) => (\n <tr {...api.getTableRowProps()} key={weekIndex}>\n {week.map((day) => {\n const state = api.getDayTableCellState({ value: day });\n\n return (\n <td\n {...api.getDayTableCellProps({ value: day })}\n key={day.toString()}\n className=\"p-0 text-center\"\n >\n <button\n {...api.getDayTableCellTriggerProps({ value: day })}\n type=\"button\"\n className={cn(\n \"size-8 rounded-lt-sm text-sm text-lt-fg hover:bg-lt-muted\",\n state.selected && \"bg-lt-primary text-lt-primary-fg\",\n state.outsideRange && \"text-lt-muted-fg\",\n state.disabled && \"cursor-not-allowed opacity-40\",\n )}\n >\n {day.day}\n </button>\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n {mode === \"date-time\" ? (\n <TimePicker\n value={parseTimeString(formatTimeInputValue(selected[0], timezone))}\n onChange={(next) =>\n api.setTime({ hour: next.hour, minute: next.minute, second: next.second })\n }\n step={step}\n disabled={disabled}\n readOnly={readOnly}\n testId={`${testId}-time`}\n />\n ) : null}\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction normalizeDateInputValue(value: string): string | undefined {\n const compact = value.replace(/\\D/g, \"\");\n\n if (compact.length !== 8) {\n return undefined;\n }\n\n return `${compact.slice(0, 4)}-${compact.slice(4, 6)}-${compact.slice(6, 8)}`;\n}\n"],"mappings":";;;;;;;;;;;;;AAyCA,SAAgB,gBAAgB,EAC9B,MACA,OACA,MACA,QACA,OACA,KACA,KACA,MACA,UACA,UACA,YAAY,OACZ,UACA,WAAW,OACX,UACA,UACuB;CACvB,MAAM,KAAK,MAAM;CACjB,MAAM,EAAE,WAAW,UAAU;CAC7B,MAAM,WAAW,cAEb,CAAC,SAAS,SAAS,eAAe,KAAK,IAAI,mBAAmB,OAAO,QAAQ,CAAC,EAAE,OAC9E,OACF,GACF;EAAC;EAAM;EAAU;CAAK,CACxB;CACA,MAAM,UAAU,WAAW,WAAW,SAAS;EAC7C;EACA;EACA,OAAO,SAAS,SAAS,IAAI,WAAW,KAAA;EACxC,KAAK,MAAM,eAAe,GAAG,IAAI,KAAA;EACjC,KAAK,MAAM,eAAe,GAAG,IAAI,KAAA;EACjC;EACA;EACA;EACA,eAAe;EACf,UAAU;EACV,eAAe,SAAS;EACxB,OAAO,MAAM;GACX,OAAO,SAAS,SACZ,uBAAuB,MAAM,MAAM,IACnC,2BAA2B,MAAM,QAAQ,QAAQ;EACvD;EACA,MAAM,MAAM;GACV,OAAO,SAAS,SACZ,sBAAsB,MAAM,MAAM,IAClC,0BAA0B,MAAM,QAAQ,QAAQ;EACtD;EACA,cAAc,SAAS;GACrB,MAAM,OAAO,QAAQ,MAAM;GAE3B,SAAS,SAAS,SAAS,gBAAgB,IAAI,IAAI,oBAAoB,MAAM,QAAQ,CAAC;EACxF;EACA,aAAa,SAAS;GACpB,IAAI,CAAC,QAAQ,MACX,SAAS;EAEb;CACF,CAAC;CACD,MAAM,MAAM,WAAW,QAAQ,SAAS,cAAc;CACtD,MAAM,EAAE,MAAM,YAAY,SAAS,GAAG,eAAe,IAAI,cAAc;CACvE,MAAM,iBACJ,SAAS,SAAS,gBAAgB,SAAS,EAAE,IAAI,oBAAoB,SAAS,IAAI,QAAQ;CAE5F,OACE,qBAAC,OAAD;EAAK,GAAI,IAAI,aAAa;EAAG,WAAW,GAAG,YAAY,IAAI,QAAQ,cAAc;YAAjF;GACE,oBAAC,SAAD;IAAO,MAAK;IAAe;IAAM,OAAO;IAAgB,aAAW,GAAG,OAAO;GAAU,CAAA;GACvF,qBAAC,OAAD;IAAK,GAAI,IAAI,gBAAgB;IAAG,WAAU;cAA1C,CACE,oBAAC,OAAD;KACE,GAAI;KACJ,cAAY;KACD;KACX,aAAW;KACD;KACV,IAAI;KACJ,UAAU,UAAU;MAClB,UAAU,KAAK;MAEf,IAAI,SAAS,QACX;MAGF,MAAM,aAAa,wBAAwB,MAAM,cAAc,KAAK;MAEpE,IAAI,CAAC,YACH;MAGF,MAAM,OAAO,eAAe,UAAU;MAEtC,IAAI,CAAC,MACH;MAGF,MAAM,cAAc,QAAQ;MAC5B,IAAI,SAAS,CAAC,IAAI,CAAC;MACnB,MAAM,cAAc,QAAQ,uBAAuB,MAAM,MAAM;MAC/D,SAAS,gBAAgB,IAAI,CAAC;KAChC;KACU;KACV,UAAU,YAAY,KAAA;IACvB,CAAA,GACD,oBAAC,QAAD;KACE,GAAI,IAAI,gBAAgB;KACxB,cAAY,QAAQ,SAAS,KAAK;KAClC,UAAU,YAAY;KACtB,MAAK;KACL,MAAK;KACL,SAAQ;eAER,oBAAC,MAAD;MAAM,MAAK;MAAW,WAAU;MAAkB,eAAY;KAAQ,CAAA;IAChE,CAAA,CACL;;GACJ,IAAI,OACH,oBAAC,OAAD;IACE,GAAI,IAAI,mBAAmB;IAC3B,WAAU;cAEV,qBAAC,OAAD;KAAK,GAAI,IAAI,gBAAgB;KAAG,WAAU;eAA1C;MACE,qBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,oBAAC,QAAD;SAAQ,GAAI,IAAI,oBAAoB;SAAG,UAAS;SAAQ,MAAK;SAAO,MAAK;mBACvE,oBAAC,MAAD;UAAM,MAAK;UAAe,WAAU;UAAkB,eAAY;SAAQ,CAAA;QACpE,CAAA;QACR,oBAAC,OAAD;SAAK,GAAI,IAAI,kBAAkB;SAAG,WAAU;QAAkC,CAAA;QAC9E,oBAAC,QAAD;SAAQ,GAAI,IAAI,oBAAoB;SAAG,UAAS;SAAQ,MAAK;SAAO,MAAK;mBACvE,oBAAC,MAAD;UAAM,MAAK;UAAgB,WAAU;UAAkB,eAAY;SAAQ,CAAA;QACrE,CAAA;OACL;;MACL,qBAAC,SAAD;OAAO,GAAI,IAAI,cAAc;OAAG,WAAU;iBAA1C,CACE,oBAAC,SAAD;QAAO,GAAI,IAAI,kBAAkB;kBAC/B,oBAAC,MAAD;SAAI,GAAI,IAAI,iBAAiB;mBAC1B,IAAI,SAAS,KAAK,QACjB,8BAAC,MAAD;UACE,GAAI,IAAI,oBAAoB;UAC5B,cAAY,IAAI;UAChB,KAAK,IAAI,MAAM,SAAS;UACxB,WAAU;SAGR,GADD,IAAI,MACH,CACL;QACC,CAAA;OACC,CAAA,GACP,oBAAC,SAAD;QAAO,GAAI,IAAI,kBAAkB;kBAC9B,IAAI,MAAM,KAAK,MAAM,cACpB,8BAAC,MAAD;SAAI,GAAI,IAAI,iBAAiB;SAAG,KAAK;QAyBjC,GAxBD,KAAK,KAAK,QAAQ;SACjB,MAAM,QAAQ,IAAI,qBAAqB,EAAE,OAAO,IAAI,CAAC;SAErD,OACE,8BAAC,MAAD;UACE,GAAI,IAAI,qBAAqB,EAAE,OAAO,IAAI,CAAC;UAC3C,KAAK,IAAI,SAAS;UAClB,WAAU;SAcR,GAZF,oBAAC,UAAD;UACE,GAAI,IAAI,4BAA4B,EAAE,OAAO,IAAI,CAAC;UAClD,MAAK;UACL,WAAW,GACT,6DACA,MAAM,YAAY,oCAClB,MAAM,gBAAgB,oBACtB,MAAM,YAAY,+BACpB;oBAEC,IAAI;SACC,CAAA,CACN;QAER,CAAC,CACC,CACL;OACI,CAAA,CACF;;MACN,SAAS,cACR,oBAAC,YAAD;OACE,OAAO,gBAAgB,qBAAqB,SAAS,IAAI,QAAQ,CAAC;OAClE,WAAW,SACT,IAAI,QAAQ;QAAE,MAAM,KAAK;QAAM,QAAQ,KAAK;QAAQ,QAAQ,KAAK;OAAO,CAAC;OAErE;OACI;OACA;OACV,QAAQ,GAAG,OAAO;MACnB,CAAA,IACC;KACD;;GACF,CAAA,IACH;EACD;;AAET;AAEA,SAAS,wBAAwB,OAAmC;CAClE,MAAM,UAAU,MAAM,QAAQ,OAAO,EAAE;CAEvC,IAAI,QAAQ,WAAW,GACrB;CAGF,OAAO,GAAG,QAAQ,MAAM,GAAG,CAAC,EAAE,GAAG,QAAQ,MAAM,GAAG,CAAC,EAAE,GAAG,QAAQ,MAAM,GAAG,CAAC;AAC5E"}
1
+ {"version":3,"file":"date-picker-field.js","names":[],"sources":["../../../../resources/js/form/components/fields/date-picker-field.tsx"],"sourcesContent":["import type { DateValue } from \"@internationalized/date\";\nimport * as datePicker from \"@zag-js/date-picker\";\nimport { normalizeProps, useMachine } from \"@zag-js/react\";\nimport { useId, useMemo } from \"react\";\nimport { Button } from \"@lattice-php/lattice/ui/button\";\nimport { Icon } from \"@lattice-php/lattice/icons\";\nimport { useLocale } from \"@lattice-php/lattice/i18n\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { Input } from \"@lattice-php/lattice/ui/input\";\nimport {\n formatDateDisplayValue,\n formatDateTimeDisplayValue,\n formatDateTimeValue,\n formatDateValue,\n formatTimeInputValue,\n parseDateDisplayValue,\n parseDateTimeDisplayValue,\n parseDateTimeValue,\n parseDateValue,\n} from \"./date-picker-value\";\nimport { TimePicker } from \"./time-picker\";\nimport { parseTimeString } from \"./time-picker-columns\";\n\nexport type DatePickerFieldProps = {\n mode: \"date\" | \"date-time\";\n label: string;\n name: string;\n testId: string;\n value: unknown;\n min?: string | null;\n max?: string | null;\n step?: number | null;\n disabled: boolean;\n readOnly: boolean;\n autoFocus?: boolean;\n tabIndex?: number | null;\n timezone?: string;\n onChange: (value: string) => void;\n onBlur?: () => void;\n};\n\nexport function DatePickerField({\n mode,\n label,\n name,\n testId,\n value,\n min,\n max,\n step,\n disabled,\n readOnly,\n autoFocus = false,\n tabIndex,\n timezone = \"UTC\",\n onChange,\n onBlur,\n}: DatePickerFieldProps) {\n const id = useId();\n const { locale } = useLocale();\n const selected = useMemo(\n () =>\n [mode === \"date\" ? parseDateValue(value) : parseDateTimeValue(value, timezone)].filter(\n Boolean,\n ) as DateValue[],\n [mode, timezone, value],\n );\n const service = useMachine(datePicker.machine, {\n id,\n name,\n value: selected.length > 0 ? selected : undefined,\n min: min ? parseDateValue(min) : undefined,\n max: max ? parseDateValue(max) : undefined,\n disabled,\n readOnly,\n locale,\n selectionMode: \"single\",\n timeZone: timezone,\n closeOnSelect: mode === \"date\",\n format(date) {\n return mode === \"date\"\n ? formatDateDisplayValue(date, locale)\n : formatDateTimeDisplayValue(date, locale, timezone);\n },\n parse(text) {\n return mode === \"date\"\n ? parseDateDisplayValue(text, locale)\n : parseDateTimeDisplayValue(text, locale, timezone);\n },\n onValueChange(details) {\n const next = details.value[0];\n\n onChange(mode === \"date\" ? formatDateValue(next) : formatDateTimeValue(next, timezone));\n },\n onOpenChange(details) {\n if (!details.open) {\n onBlur?.();\n }\n },\n });\n const api = datePicker.connect(service, normalizeProps);\n const { name: _inputName, onInput, ...inputProps } = api.getInputProps();\n const submittedValue =\n mode === \"date\" ? formatDateValue(selected[0]) : formatDateTimeValue(selected[0], timezone);\n\n return (\n <div {...api.getRootProps()} className={cn(\"relative\", api.open && \"z-lt-popover\")}>\n <input type=\"hidden\" name={name} value={submittedValue} data-test={`${testId}-value`} />\n <div {...api.getControlProps()} className=\"flex gap-2\">\n <Input\n {...inputProps}\n aria-label={label}\n autoFocus={autoFocus}\n data-test={testId}\n disabled={disabled}\n id={name}\n onInput={(event) => {\n onInput?.(event);\n\n if (mode !== \"date\") {\n return;\n }\n\n const normalized = normalizeDateInputValue(event.currentTarget.value);\n\n if (!normalized) {\n return;\n }\n\n const next = parseDateValue(normalized);\n\n if (!next) {\n return;\n }\n\n event.currentTarget.value = normalized;\n api.setValue([next]);\n event.currentTarget.value = formatDateDisplayValue(next, locale);\n onChange(formatDateValue(next));\n }}\n readOnly={readOnly}\n tabIndex={tabIndex ?? undefined}\n />\n <Button\n {...api.getTriggerProps()}\n aria-label={`Open ${label || name} calendar`}\n disabled={disabled || readOnly}\n size=\"icon\"\n type=\"button\"\n variant=\"secondary\"\n >\n <Icon name=\"calendar\" className=\"size-lt-icon-md\" aria-hidden=\"true\" />\n </Button>\n </div>\n {api.open ? (\n <div\n {...api.getPositionerProps()}\n className=\"absolute z-lt-popover mt-2 rounded-lt-sm border border-lt-border bg-lt-popover p-3 text-lt-popover-fg shadow-lt-md\"\n >\n <div {...api.getContentProps()} className=\"grid gap-3\">\n <div className=\"flex items-center justify-between gap-2\">\n <Button {...api.getPrevTriggerProps()} emphasis=\"ghost\" size=\"icon\" type=\"button\">\n <Icon name=\"chevron-left\" className=\"size-lt-icon-md\" aria-hidden=\"true\" />\n </Button>\n <div {...api.getRangeTextProps()} className=\"text-sm font-medium text-lt-fg\" />\n <Button {...api.getNextTriggerProps()} emphasis=\"ghost\" size=\"icon\" type=\"button\">\n <Icon name=\"chevron-right\" className=\"size-lt-icon-md\" aria-hidden=\"true\" />\n </Button>\n </div>\n <table {...api.getTableProps()} className=\"w-full border-collapse text-sm\">\n <thead {...api.getTableHeadProps()}>\n <tr {...api.getTableRowProps()}>\n {api.weekDays.map((day) => (\n <th\n {...api.getTableHeaderProps()}\n aria-label={day.long}\n key={day.value.toString()}\n className=\"size-8 text-center text-xs font-medium text-lt-muted-fg\"\n >\n {day.narrow}\n </th>\n ))}\n </tr>\n </thead>\n <tbody {...api.getTableBodyProps()}>\n {api.weeks.map((week, weekIndex) => (\n <tr {...api.getTableRowProps()} key={weekIndex}>\n {week.map((day) => {\n const state = api.getDayTableCellState({ value: day });\n\n return (\n <td\n {...api.getDayTableCellProps({ value: day })}\n key={day.toString()}\n className=\"p-0 text-center\"\n >\n <button\n {...api.getDayTableCellTriggerProps({ value: day })}\n type=\"button\"\n className={cn(\n \"size-8 rounded-lt-sm text-sm text-lt-fg hover:bg-lt-muted\",\n state.selected && \"bg-lt-primary text-lt-primary-fg\",\n state.outsideRange && \"text-lt-muted-fg\",\n state.disabled && \"cursor-not-allowed opacity-40\",\n )}\n >\n {day.day}\n </button>\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n {mode === \"date-time\" ? (\n <TimePicker\n value={parseTimeString(formatTimeInputValue(selected[0], timezone))}\n onChange={(next) =>\n api.setTime({ hour: next.hour, minute: next.minute, second: next.second })\n }\n step={step}\n disabled={disabled}\n readOnly={readOnly}\n testId={`${testId}-time`}\n />\n ) : null}\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction normalizeDateInputValue(value: string): string | undefined {\n const compact = value.replace(/\\D/g, \"\");\n\n if (compact.length !== 8) {\n return undefined;\n }\n\n return `${compact.slice(0, 4)}-${compact.slice(4, 6)}-${compact.slice(6, 8)}`;\n}\n"],"mappings":"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"}