@lattice-php/lattice 0.19.0 → 0.21.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 (343) hide show
  1. package/dist/action/components/action-form.d.ts +6 -1
  2. package/dist/action/components/action-form.js +34 -49
  3. package/dist/action/components/action-form.js.map +1 -1
  4. package/dist/action/components/action-trigger-provider.d.ts +1 -1
  5. package/dist/action/components/action-trigger-provider.js.map +1 -1
  6. package/dist/action/hooks/use-action.d.ts +1 -1
  7. package/dist/action/hooks/use-action.js +3 -1
  8. package/dist/action/hooks/use-action.js.map +1 -1
  9. package/dist/action/index.d.ts +0 -2
  10. package/dist/action/index.js +1 -2
  11. package/dist/chat/plugin.d.ts +0 -1
  12. package/dist/chat/plugin.js.map +1 -1
  13. package/dist/clipboard/index.d.ts +0 -4
  14. package/dist/clipboard/index.js +1 -15
  15. package/dist/{events → core}/event-names.js +1 -1
  16. package/dist/core/event-names.js.map +1 -0
  17. package/dist/core/hooks/use-window-event.d.ts +8 -0
  18. package/dist/core/hooks/use-window-event.js +22 -0
  19. package/dist/core/hooks/use-window-event.js.map +1 -0
  20. package/dist/core/index.js +1 -1
  21. package/dist/core/types.d.ts +8 -61
  22. package/dist/create-app.d.ts +31 -3
  23. package/dist/create-app.js +48 -10
  24. package/dist/create-app.js.map +1 -1
  25. package/dist/effects/dispatch.js +1 -1
  26. package/dist/effects/dispatch.js.map +1 -1
  27. package/dist/effects/registry.d.ts +2 -18
  28. package/dist/effects/registry.js +5 -9
  29. package/dist/effects/registry.js.map +1 -1
  30. package/dist/event-bridge.js +10 -23
  31. package/dist/event-bridge.js.map +1 -1
  32. package/dist/form/components/base/field.d.ts +2 -2
  33. package/dist/form/components/base/field.js +2 -2
  34. package/dist/form/components/base/field.js.map +1 -1
  35. package/dist/form/components/fields/color-picker-field.d.ts +2 -0
  36. package/dist/form/components/fields/color-picker-field.js +57 -0
  37. package/dist/form/components/fields/color-picker-field.js.map +1 -0
  38. package/dist/form/components/fields/date-input.js +1 -1
  39. package/dist/form/components/fields/date-time-input.js +1 -1
  40. package/dist/form/components/fields/file-upload.js +11 -18
  41. package/dist/form/components/fields/file-upload.js.map +1 -1
  42. package/dist/form/components/fields/number-input.js +1 -1
  43. package/dist/form/components/fields/rich-editor-field.js +35 -276
  44. package/dist/form/components/fields/rich-editor-field.js.map +1 -1
  45. package/dist/form/components/fields/row-action-menu.js +2 -2
  46. package/dist/form/components/fields/row-action-menu.js.map +1 -1
  47. package/dist/form/components/fields/row-actions.js +3 -1
  48. package/dist/form/components/fields/row-actions.js.map +1 -1
  49. package/dist/form/components/fields/select.js +60 -17
  50. package/dist/form/components/fields/select.js.map +1 -1
  51. package/dist/form/components/fields/table-rows.js +5 -17
  52. package/dist/form/components/fields/table-rows.js.map +1 -1
  53. package/dist/form/components/fields/text-input.js +8 -1
  54. package/dist/form/components/fields/text-input.js.map +1 -1
  55. package/dist/form/components/fields/time-input.js +1 -1
  56. package/dist/form/components/form.js +8 -23
  57. package/dist/form/components/form.js.map +1 -1
  58. package/dist/form/components/index.d.ts +1 -0
  59. package/dist/form/components/index.js +2 -1
  60. package/dist/form/embed.d.ts +5 -0
  61. package/dist/form/embed.js +4 -1
  62. package/dist/form/hooks/use-form-resolver.js.map +1 -1
  63. package/dist/form/index.js +2 -1
  64. package/dist/form/lib/collect-fields.d.ts +7 -0
  65. package/dist/form/lib/collect-fields.js +19 -0
  66. package/dist/form/lib/collect-fields.js.map +1 -0
  67. package/dist/form/lib/conditions.d.ts +4 -10
  68. package/dist/form/lib/conditions.js.map +1 -1
  69. package/dist/form/lib/field-errors.d.ts +3 -0
  70. package/dist/form/lib/field-errors.js +11 -0
  71. package/dist/form/lib/field-errors.js.map +1 -0
  72. package/dist/form/lib/field-props.d.ts +4 -18
  73. package/dist/form/lib/field-props.js.map +1 -1
  74. package/dist/form/plugin.js +2 -0
  75. package/dist/form/plugin.js.map +1 -1
  76. package/dist/form/rich-editor/builtins.d.ts +6 -0
  77. package/dist/form/rich-editor/builtins.js +400 -0
  78. package/dist/form/rich-editor/builtins.js.map +1 -0
  79. package/dist/form/rich-editor/index.d.ts +7 -0
  80. package/dist/form/rich-editor/index.js +3 -0
  81. package/dist/form/rich-editor/registry.d.ts +67 -0
  82. package/dist/form/rich-editor/registry.js +79 -0
  83. package/dist/form/rich-editor/registry.js.map +1 -0
  84. package/dist/form/rich-editor/toolbar-button.d.ts +12 -0
  85. package/dist/form/rich-editor/toolbar-button.js +28 -0
  86. package/dist/form/rich-editor/toolbar-button.js.map +1 -0
  87. package/dist/form/types.d.ts +1 -6
  88. package/dist/format/date-time.d.ts +3 -2
  89. package/dist/format/date-time.js.map +1 -1
  90. package/dist/format/format-context.d.ts +6 -0
  91. package/dist/format/format-context.js +17 -0
  92. package/dist/format/format-context.js.map +1 -0
  93. package/dist/i18n/date-time.d.ts +3 -2
  94. package/dist/i18n/date-time.js.map +1 -1
  95. package/dist/i18n/index.js +3 -2
  96. package/dist/i18n/locale-reload.d.ts +1 -1
  97. package/dist/i18n/locale-reload.js +7 -6
  98. package/dist/i18n/locale-reload.js.map +1 -1
  99. package/dist/i18n/locale.js +1 -1
  100. package/dist/i18n/locale.js.map +1 -1
  101. package/dist/i18n/page-props.d.ts +3 -2
  102. package/dist/i18n/page-props.js +1 -15
  103. package/dist/i18n/page-props.js.map +1 -1
  104. package/dist/i18n/shared-props.d.ts +7 -0
  105. package/dist/i18n/shared-props.js +23 -0
  106. package/dist/i18n/shared-props.js.map +1 -0
  107. package/dist/i18n/timezone.js +1 -1
  108. package/dist/i18n/timezone.js.map +1 -1
  109. package/dist/index.d.ts +11 -10
  110. package/dist/index.js +5 -5
  111. package/dist/lattice.css +212 -47
  112. package/dist/layout/components/breadcrumbs.js +3 -1
  113. package/dist/layout/components/breadcrumbs.js.map +1 -1
  114. package/dist/layout/components/sidebar.js +15 -48
  115. package/dist/layout/components/sidebar.js.map +1 -1
  116. package/dist/layout/plugin.d.ts +0 -1
  117. package/dist/layout/plugin.js.map +1 -1
  118. package/dist/lib/color.d.ts +9 -0
  119. package/dist/lib/color.js +48 -0
  120. package/dist/lib/color.js.map +1 -0
  121. package/dist/lib/is-truthy.d.ts +2 -0
  122. package/dist/lib/is-truthy.js +9 -0
  123. package/dist/lib/is-truthy.js.map +1 -0
  124. package/dist/lib/use-debounced-callback.d.ts +10 -0
  125. package/dist/lib/use-debounced-callback.js +34 -0
  126. package/dist/lib/use-debounced-callback.js.map +1 -0
  127. package/dist/lib/use-media-query.d.ts +5 -0
  128. package/dist/lib/use-media-query.js +26 -0
  129. package/dist/lib/use-media-query.js.map +1 -0
  130. package/dist/lib/use-persistent-state.d.ts +13 -0
  131. package/dist/lib/use-persistent-state.js +62 -0
  132. package/dist/lib/use-persistent-state.js.map +1 -0
  133. package/dist/notifications/api.d.ts +6 -6
  134. package/dist/notifications/api.js.map +1 -1
  135. package/dist/notifications/components/notifications.js +3 -1
  136. package/dist/notifications/components/notifications.js.map +1 -1
  137. package/dist/notifications/plugin.d.ts +0 -1
  138. package/dist/notifications/plugin.js.map +1 -1
  139. package/dist/notifications/types.d.ts +2 -10
  140. package/dist/provider-base.js +1 -1
  141. package/dist/realtime/build-effects.js +5 -5
  142. package/dist/realtime/build-effects.js.map +1 -1
  143. package/dist/realtime/listeners.d.ts +2 -2
  144. package/dist/realtime/listeners.js +1 -1
  145. package/dist/realtime/listeners.js.map +1 -1
  146. package/dist/realtime/subscriptions.d.ts +2 -2
  147. package/dist/realtime/subscriptions.js.map +1 -1
  148. package/dist/registry.d.ts +5 -0
  149. package/dist/registry.js.map +1 -1
  150. package/dist/remote/components/data-list.js +1 -1
  151. package/dist/remote/plugin.d.ts +0 -1
  152. package/dist/remote/plugin.js.map +1 -1
  153. package/dist/table/components/bulk-bar.js +7 -5
  154. package/dist/table/components/bulk-bar.js.map +1 -1
  155. package/dist/table/components/cells/badge-cell.js +4 -1
  156. package/dist/table/components/cells/badge-cell.js.map +1 -1
  157. package/dist/table/components/cells/boolean-cell.js +4 -4
  158. package/dist/table/components/cells/boolean-cell.js.map +1 -1
  159. package/dist/table/components/cells/copyable-cell.d.ts +9 -0
  160. package/dist/table/components/cells/copyable-cell.js +17 -0
  161. package/dist/table/components/cells/copyable-cell.js.map +1 -0
  162. package/dist/table/components/cells/icon-cell.js +5 -2
  163. package/dist/table/components/cells/icon-cell.js.map +1 -1
  164. package/dist/table/components/cells/image-cell.js +8 -9
  165. package/dist/table/components/cells/image-cell.js.map +1 -1
  166. package/dist/table/components/cells/money-cell.js +7 -10
  167. package/dist/table/components/cells/money-cell.js.map +1 -1
  168. package/dist/table/components/cells/number-cell.js +14 -19
  169. package/dist/table/components/cells/number-cell.js.map +1 -1
  170. package/dist/table/components/cells/numeric-cell.d.ts +10 -0
  171. package/dist/table/components/cells/numeric-cell.js +25 -0
  172. package/dist/table/components/cells/numeric-cell.js.map +1 -0
  173. package/dist/table/components/cells/stack-cell.js +1 -1
  174. package/dist/table/components/cells/text-cell.js +8 -6
  175. package/dist/table/components/cells/text-cell.js.map +1 -1
  176. package/dist/table/components/column-filter-control.js +25 -32
  177. package/dist/table/components/column-filter-control.js.map +1 -1
  178. package/dist/table/components/column-header.d.ts +3 -3
  179. package/dist/table/components/column-header.js +5 -3
  180. package/dist/table/components/column-header.js.map +1 -1
  181. package/dist/table/components/column-visibility-menu.js +6 -11
  182. package/dist/table/components/column-visibility-menu.js.map +1 -1
  183. package/dist/table/components/filter-bar.d.ts +2 -2
  184. package/dist/table/components/filter-bar.js +13 -22
  185. package/dist/table/components/filter-bar.js.map +1 -1
  186. package/dist/table/components/filter-controls.d.ts +2 -1
  187. package/dist/table/components/filter-controls.js +37 -38
  188. package/dist/table/components/filter-controls.js.map +1 -1
  189. package/dist/table/components/filter-value-input.d.ts +0 -1
  190. package/dist/table/components/filter-value-input.js +21 -20
  191. package/dist/table/components/filter-value-input.js.map +1 -1
  192. package/dist/table/components/pagination.js +16 -20
  193. package/dist/table/components/pagination.js.map +1 -1
  194. package/dist/table/components/sort-bar.d.ts +3 -3
  195. package/dist/table/components/sort-bar.js +11 -12
  196. package/dist/table/components/sort-bar.js.map +1 -1
  197. package/dist/table/components/table-cell.js.map +1 -1
  198. package/dist/table/components/table-search.d.ts +9 -0
  199. package/dist/table/components/table-search.js +72 -0
  200. package/dist/table/components/table-search.js.map +1 -0
  201. package/dist/table/components/table.js +73 -21
  202. package/dist/table/components/table.js.map +1 -1
  203. package/dist/table/hooks/use-column-visibility.js +29 -58
  204. package/dist/table/hooks/use-column-visibility.js.map +1 -1
  205. package/dist/table/hooks/use-expanded-rows.d.ts +8 -0
  206. package/dist/table/hooks/use-expanded-rows.js +24 -0
  207. package/dist/table/hooks/use-expanded-rows.js.map +1 -0
  208. package/dist/table/hooks/use-table.d.ts +5 -3
  209. package/dist/table/hooks/use-table.js +59 -55
  210. package/dist/table/hooks/use-table.js.map +1 -1
  211. package/dist/table/lib/bulk.d.ts +2 -0
  212. package/dist/table/lib/bulk.js +3 -1
  213. package/dist/table/lib/bulk.js.map +1 -1
  214. package/dist/table/lib/payload.d.ts +3 -2
  215. package/dist/table/lib/payload.js +16 -10
  216. package/dist/table/lib/payload.js.map +1 -1
  217. package/dist/table/lib/query.d.ts +5 -5
  218. package/dist/table/lib/query.js +21 -19
  219. package/dist/table/lib/query.js.map +1 -1
  220. package/dist/table/plugin.d.ts +0 -1
  221. package/dist/table/plugin.js.map +1 -1
  222. package/dist/table/types.d.ts +5 -81
  223. package/dist/toast/callout.js +2 -4
  224. package/dist/toast/callout.js.map +1 -1
  225. package/dist/toast/index.d.ts +1 -1
  226. package/dist/toast/index.js +2 -2
  227. package/dist/toast/toast.d.ts +1 -7
  228. package/dist/toast/toast.js +3 -15
  229. package/dist/toast/toast.js.map +1 -1
  230. package/dist/toast/toaster.js.map +1 -1
  231. package/dist/types/generated.d.ts +444 -225
  232. package/dist/types/index.d.ts +1 -1
  233. package/dist/ui/affix-group.d.ts +2 -1
  234. package/dist/ui/affix-group.js +9 -7
  235. package/dist/ui/affix-group.js.map +1 -1
  236. package/dist/ui/avatar.d.ts +3 -0
  237. package/dist/ui/avatar.js +52 -0
  238. package/dist/ui/avatar.js.map +1 -0
  239. package/dist/ui/button.d.ts +5 -3
  240. package/dist/ui/button.js +10 -3
  241. package/dist/ui/button.js.map +1 -1
  242. package/dist/ui/chart-view.js +155 -28
  243. package/dist/ui/chart-view.js.map +1 -1
  244. package/dist/ui/click-behavior.d.ts +4 -4
  245. package/dist/ui/click-behavior.js.map +1 -1
  246. package/dist/ui/collapsible.js +3 -15
  247. package/dist/ui/collapsible.js.map +1 -1
  248. package/dist/ui/color-picker.d.ts +8 -0
  249. package/dist/ui/color-picker.js +59 -0
  250. package/dist/ui/color-picker.js.map +1 -0
  251. package/dist/ui/combobox.d.ts +11 -2
  252. package/dist/ui/combobox.js +57 -11
  253. package/dist/ui/combobox.js.map +1 -1
  254. package/dist/ui/confirm-dialog.js +1 -1
  255. package/dist/ui/confirm-dialog.js.map +1 -1
  256. package/dist/ui/control.d.ts +1 -1
  257. package/dist/ui/copyable-text.d.ts +7 -0
  258. package/dist/ui/copyable-text.js +21 -13
  259. package/dist/ui/copyable-text.js.map +1 -1
  260. package/dist/ui/dialog.d.ts +6 -2
  261. package/dist/ui/dialog.js +29 -5
  262. package/dist/ui/dialog.js.map +1 -1
  263. package/dist/ui/fragment.js +1 -1
  264. package/dist/ui/fragment.js.map +1 -1
  265. package/dist/ui/heading.js +39 -21
  266. package/dist/ui/heading.js.map +1 -1
  267. package/dist/ui/icon-button.d.ts +22 -0
  268. package/dist/ui/icon-button.js +51 -0
  269. package/dist/ui/icon-button.js.map +1 -0
  270. package/dist/ui/icon.js +10 -11
  271. package/dist/ui/icon.js.map +1 -1
  272. package/dist/ui/image-preview.d.ts +12 -0
  273. package/dist/ui/image-preview.js +65 -0
  274. package/dist/ui/image-preview.js.map +1 -0
  275. package/dist/ui/image.d.ts +3 -0
  276. package/dist/ui/image.js +21 -0
  277. package/dist/ui/image.js.map +1 -0
  278. package/dist/ui/index.d.ts +2 -1
  279. package/dist/ui/index.js +4 -3
  280. package/dist/ui/info-tooltip.js +1 -1
  281. package/dist/ui/info-tooltip.js.map +1 -1
  282. package/dist/ui/input.d.ts +3 -1
  283. package/dist/ui/input.js +2 -2
  284. package/dist/ui/input.js.map +1 -1
  285. package/dist/ui/modal.js +17 -4
  286. package/dist/ui/modal.js.map +1 -1
  287. package/dist/ui/native-select.d.ts +10 -0
  288. package/dist/ui/native-select.js +23 -0
  289. package/dist/ui/native-select.js.map +1 -0
  290. package/dist/ui/pill.d.ts +2 -0
  291. package/dist/ui/pill.js +10 -0
  292. package/dist/ui/pill.js.map +1 -0
  293. package/dist/ui/plugin.js +11 -1
  294. package/dist/ui/plugin.js.map +1 -1
  295. package/dist/ui/progress.d.ts +3 -0
  296. package/dist/ui/progress.js +114 -0
  297. package/dist/ui/progress.js.map +1 -0
  298. package/dist/ui/section.js +2 -15
  299. package/dist/ui/section.js.map +1 -1
  300. package/dist/ui/segmented-pills.js +2 -1
  301. package/dist/ui/segmented-pills.js.map +1 -1
  302. package/dist/ui/separator.d.ts +3 -0
  303. package/dist/ui/separator.js +15 -0
  304. package/dist/ui/separator.js.map +1 -0
  305. package/dist/ui/tabs.js +12 -10
  306. package/dist/ui/tabs.js.map +1 -1
  307. package/dist/ui/text.js +5 -10
  308. package/dist/ui/text.js.map +1 -1
  309. package/dist/ui/tree-context.d.ts +33 -0
  310. package/dist/ui/tree-context.js +135 -0
  311. package/dist/ui/tree-context.js.map +1 -0
  312. package/dist/ui/tree.d.ts +19 -0
  313. package/dist/ui/tree.js +187 -0
  314. package/dist/ui/tree.js.map +1 -0
  315. package/dist/ui/use-collapsible-state.d.ts +7 -0
  316. package/dist/ui/use-collapsible-state.js +21 -0
  317. package/dist/ui/use-collapsible-state.js.map +1 -0
  318. package/dist-standalone/chunks/chart-view-C6R5iPra.js +36 -0
  319. package/dist-standalone/chunks/date-picker-field-DhhEB-Mh.js +1 -0
  320. package/dist-standalone/chunks/jsx-runtime-Drll_-DD.js +1 -0
  321. package/dist-standalone/chunks/locale-CXqr7LPR.js +1 -0
  322. package/dist-standalone/chunks/page-props-DOfg30l5.js +1 -0
  323. package/dist-standalone/chunks/rich-editor-field-DORXTHPw.js +154 -0
  324. package/dist-standalone/chunks/{subscriptions-B3UuDBmx.js → subscriptions-B_ISgA7V.js} +1 -1
  325. package/dist-standalone/chunks/use-effect-dispatcher-D1wPPwHj.js +97 -0
  326. package/dist-standalone/lattice.css +1 -1
  327. package/dist-standalone/lattice.js +15 -15
  328. package/dist-standalone/manifest.json +11 -9
  329. package/dist-standalone/sprite.svg +1 -1
  330. package/package.json +6 -1
  331. package/resources/icons/code-xml.svg +17 -0
  332. package/resources/icons/heading.svg +17 -0
  333. package/dist/clipboard/index.js.map +0 -1
  334. package/dist/events/event-names.js.map +0 -1
  335. package/dist/table/components/table-action-node.d.ts +0 -4
  336. package/dist/table/components/table-action-node.js +0 -24
  337. package/dist/table/components/table-action-node.js.map +0 -1
  338. package/dist-standalone/chunks/chart-view-CK5fKIkR.js +0 -36
  339. package/dist-standalone/chunks/date-picker-field-BlCPFhZd.js +0 -1
  340. package/dist-standalone/chunks/jsx-runtime-CJ_btYLc.js +0 -1
  341. package/dist-standalone/chunks/rich-editor-field-DH5dS5c1.js +0 -154
  342. package/dist-standalone/chunks/use-effect-dispatcher-k98Nzf9M.js +0 -97
  343. /package/dist/{events → core}/event-names.d.ts +0 -0
@@ -1,5 +1,6 @@
1
1
  import { cn } from "../lib/utils.js";
2
2
  import { InfoTooltip } from "./info-tooltip.js";
3
+ import { CopyableText } from "./copyable-text.js";
3
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
5
  //#region resources/js/ui/heading.tsx
5
6
  var HeadingComponent = ({ node }) => {
@@ -7,32 +8,49 @@ var HeadingComponent = ({ node }) => {
7
8
  const level = Math.min(Math.max(node.props.level, 1), 6);
8
9
  const className = cn("max-w-3xl font-semibold tracking-normal text-balance text-lt-fg", level === 1 && "text-2xl font-bold leading-tight", level === 2 && "text-xl", level > 2 && "text-base");
9
10
  const content = /* @__PURE__ */ jsxs(Fragment, { children: [text, /* @__PURE__ */ jsx(InfoTooltip, { content: tooltip })] });
11
+ let heading;
10
12
  switch (level) {
11
- case 1: return /* @__PURE__ */ jsx("h1", {
12
- className,
13
- children: content
14
- });
15
- case 2: return /* @__PURE__ */ jsx("h2", {
16
- className,
17
- children: content
18
- });
19
- case 3: return /* @__PURE__ */ jsx("h3", {
20
- className,
21
- children: content
22
- });
23
- case 4: return /* @__PURE__ */ jsx("h4", {
24
- className,
25
- children: content
26
- });
27
- case 5: return /* @__PURE__ */ jsx("h5", {
28
- className,
29
- children: content
30
- });
31
- default: return /* @__PURE__ */ jsx("h6", {
13
+ case 1:
14
+ heading = /* @__PURE__ */ jsx("h1", {
15
+ className,
16
+ children: content
17
+ });
18
+ break;
19
+ case 2:
20
+ heading = /* @__PURE__ */ jsx("h2", {
21
+ className,
22
+ children: content
23
+ });
24
+ break;
25
+ case 3:
26
+ heading = /* @__PURE__ */ jsx("h3", {
27
+ className,
28
+ children: content
29
+ });
30
+ break;
31
+ case 4:
32
+ heading = /* @__PURE__ */ jsx("h4", {
33
+ className,
34
+ children: content
35
+ });
36
+ break;
37
+ case 5:
38
+ heading = /* @__PURE__ */ jsx("h5", {
39
+ className,
40
+ children: content
41
+ });
42
+ break;
43
+ default: heading = /* @__PURE__ */ jsx("h6", {
32
44
  className,
33
45
  children: content
34
46
  });
35
47
  }
48
+ if (!node.props.copyable) return heading;
49
+ return /* @__PURE__ */ jsx(CopyableText, {
50
+ value: text,
51
+ label: text,
52
+ children: heading
53
+ });
36
54
  };
37
55
  //#endregion
38
56
  export { HeadingComponent as default };
@@ -1 +1 @@
1
- {"version":3,"file":"heading.js","names":[],"sources":["../../resources/js/ui/heading.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { InfoTooltip } from \"./info-tooltip\";\n\nconst HeadingComponent: RendererComponent<\"heading\"> = ({ node }) => {\n const { text, tooltip } = node.props;\n const level = Math.min(Math.max(node.props.level, 1), 6);\n const className = cn(\n \"max-w-3xl font-semibold tracking-normal text-balance text-lt-fg\",\n level === 1 && \"text-2xl font-bold leading-tight\",\n level === 2 && \"text-xl\",\n level > 2 && \"text-base\",\n );\n\n const content = (\n <>\n {text}\n <InfoTooltip content={tooltip} />\n </>\n );\n\n switch (level) {\n case 1:\n return <h1 className={className}>{content}</h1>;\n case 2:\n return <h2 className={className}>{content}</h2>;\n case 3:\n return <h3 className={className}>{content}</h3>;\n case 4:\n return <h4 className={className}>{content}</h4>;\n case 5:\n return <h5 className={className}>{content}</h5>;\n default:\n return <h6 className={className}>{content}</h6>;\n }\n};\n\nexport default HeadingComponent;\n"],"mappings":";;;;AAIA,IAAM,oBAAkD,EAAE,WAAW;CACnE,MAAM,EAAE,MAAM,YAAY,KAAK;CAC/B,MAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,KAAK,MAAM,OAAO,CAAC,GAAG,CAAC;CACvD,MAAM,YAAY,GAChB,mEACA,UAAU,KAAK,oCACf,UAAU,KAAK,WACf,QAAQ,KAAK,WACf;CAEA,MAAM,UACJ,qBAAA,UAAA,EAAA,UAAA,CACG,MACD,oBAAC,aAAD,EAAa,SAAS,QAAU,CAAA,CAChC,EAAA,CAAA;CAGJ,QAAQ,OAAR;EACE,KAAK,GACH,OAAO,oBAAC,MAAD;GAAe;aAAY;EAAY,CAAA;EAChD,KAAK,GACH,OAAO,oBAAC,MAAD;GAAe;aAAY;EAAY,CAAA;EAChD,KAAK,GACH,OAAO,oBAAC,MAAD;GAAe;aAAY;EAAY,CAAA;EAChD,KAAK,GACH,OAAO,oBAAC,MAAD;GAAe;aAAY;EAAY,CAAA;EAChD,KAAK,GACH,OAAO,oBAAC,MAAD;GAAe;aAAY;EAAY,CAAA;EAChD,SACE,OAAO,oBAAC,MAAD;GAAe;aAAY;EAAY,CAAA;CAClD;AACF"}
1
+ {"version":3,"file":"heading.js","names":[],"sources":["../../resources/js/ui/heading.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { CopyableText } from \"./copyable-text\";\nimport { InfoTooltip } from \"./info-tooltip\";\n\nconst HeadingComponent: RendererComponent<\"heading\"> = ({ node }) => {\n const { text, tooltip } = node.props;\n const level = Math.min(Math.max(node.props.level, 1), 6);\n const className = cn(\n \"max-w-3xl font-semibold tracking-normal text-balance text-lt-fg\",\n level === 1 && \"text-2xl font-bold leading-tight\",\n level === 2 && \"text-xl\",\n level > 2 && \"text-base\",\n );\n\n const content = (\n <>\n {text}\n <InfoTooltip content={tooltip} />\n </>\n );\n\n let heading: ReactNode;\n\n switch (level) {\n case 1:\n heading = <h1 className={className}>{content}</h1>;\n break;\n case 2:\n heading = <h2 className={className}>{content}</h2>;\n break;\n case 3:\n heading = <h3 className={className}>{content}</h3>;\n break;\n case 4:\n heading = <h4 className={className}>{content}</h4>;\n break;\n case 5:\n heading = <h5 className={className}>{content}</h5>;\n break;\n default:\n heading = <h6 className={className}>{content}</h6>;\n }\n\n if (!node.props.copyable) {\n return heading;\n }\n\n return (\n <CopyableText value={text} label={text}>\n {heading}\n </CopyableText>\n );\n};\n\nexport default HeadingComponent;\n"],"mappings":";;;;;AAMA,IAAM,oBAAkD,EAAE,WAAW;CACnE,MAAM,EAAE,MAAM,YAAY,KAAK;CAC/B,MAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,KAAK,MAAM,OAAO,CAAC,GAAG,CAAC;CACvD,MAAM,YAAY,GAChB,mEACA,UAAU,KAAK,oCACf,UAAU,KAAK,WACf,QAAQ,KAAK,WACf;CAEA,MAAM,UACJ,qBAAA,UAAA,EAAA,UAAA,CACG,MACD,oBAAC,aAAD,EAAa,SAAS,QAAU,CAAA,CAChC,EAAA,CAAA;CAGJ,IAAI;CAEJ,QAAQ,OAAR;EACE,KAAK;GACH,UAAU,oBAAC,MAAD;IAAe;cAAY;GAAY,CAAA;GACjD;EACF,KAAK;GACH,UAAU,oBAAC,MAAD;IAAe;cAAY;GAAY,CAAA;GACjD;EACF,KAAK;GACH,UAAU,oBAAC,MAAD;IAAe;cAAY;GAAY,CAAA;GACjD;EACF,KAAK;GACH,UAAU,oBAAC,MAAD;IAAe;cAAY;GAAY,CAAA;GACjD;EACF,KAAK;GACH,UAAU,oBAAC,MAAD;IAAe;cAAY;GAAY,CAAA;GACjD;EACF,SACE,UAAU,oBAAC,MAAD;GAAe;aAAY;EAAY,CAAA;CACrD;CAEA,IAAI,CAAC,KAAK,MAAM,UACd,OAAO;CAGT,OACE,oBAAC,cAAD;EAAc,OAAO;EAAM,OAAO;YAC/B;CACW,CAAA;AAElB"}
@@ -0,0 +1,22 @@
1
+ import { VariantProps } from 'class-variance-authority';
2
+ import * as React from "react";
3
+ /**
4
+ * A compact, resizable icon button — the shared affordance behind toolbar
5
+ * triggers, popover triggers, and inline clear/remove buttons. `ghost` matches
6
+ * `Button variant="ghost"` (accent hover) and reacts to `aria-pressed` (toggle)
7
+ * and `data-[state=open]` (a popover trigger). `segmented` joins onto the right
8
+ * of an adjacent input. Size defaults to `sm`; pass `size` to resize.
9
+ */
10
+ declare const iconButtonVariants: (props?: ({
11
+ variant?: "ghost" | "segmented" | null | undefined;
12
+ size?: "sm" | "md" | "xs" | null | undefined;
13
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
14
+ export declare function IconButton({ icon, label, active, size, variant, className, children, ref, ...props }: Omit<React.ComponentProps<"button">, "aria-pressed"> & VariantProps<typeof iconButtonVariants> & {
15
+ /** Icon glyph name; omit and pass `children` for custom content. */
16
+ icon?: string;
17
+ /** Accessible name (also used when the button shows only an icon). */
18
+ label: string;
19
+ /** Toggle state — sets `aria-pressed` and the pressed styling. */
20
+ active?: boolean;
21
+ }): React.JSX.Element;
22
+ export { iconButtonVariants };
@@ -0,0 +1,51 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { Icon } from "../icons/sprite.js";
3
+ import "react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { cva } from "class-variance-authority";
6
+ //#region resources/js/ui/icon-button.tsx
7
+ /**
8
+ * A compact, resizable icon button — the shared affordance behind toolbar
9
+ * triggers, popover triggers, and inline clear/remove buttons. `ghost` matches
10
+ * `Button variant="ghost"` (accent hover) and reacts to `aria-pressed` (toggle)
11
+ * and `data-[state=open]` (a popover trigger). `segmented` joins onto the right
12
+ * of an adjacent input. Size defaults to `sm`; pass `size` to resize.
13
+ */
14
+ var iconButtonVariants = cva(cn("relative inline-flex shrink-0 items-center justify-center rounded-lt-sm transition-colors", "outline-none focus-visible:ring-2 focus-visible:ring-lt-ring/50", "disabled:pointer-events-none disabled:opacity-50"), {
15
+ variants: {
16
+ variant: {
17
+ ghost: cn("text-lt-muted-fg hover:bg-lt-accent hover:text-lt-accent-fg", "data-[state=open]:bg-lt-accent data-[state=open]:text-lt-accent-fg", "aria-pressed:bg-lt-accent aria-pressed:text-lt-accent-fg"),
18
+ segmented: cn("-ml-px rounded-l-none border border-lt-input text-lt-muted-fg hover:bg-lt-accent hover:text-lt-accent-fg", "data-[state=open]:z-10 data-[state=open]:border-lt-primary data-[state=open]:text-lt-fg")
19
+ },
20
+ size: {
21
+ xs: "size-5 [&_svg]:size-lt-icon-sm",
22
+ sm: "size-7 [&_svg]:size-lt-icon-md",
23
+ md: "size-lt-control-md [&_svg]:size-lt-icon-md"
24
+ }
25
+ },
26
+ defaultVariants: {
27
+ variant: "ghost",
28
+ size: "sm"
29
+ }
30
+ });
31
+ function IconButton({ icon, label, active, size, variant, className, children, ref, ...props }) {
32
+ return /* @__PURE__ */ jsxs("button", {
33
+ ref,
34
+ type: "button",
35
+ "aria-label": label,
36
+ "aria-pressed": active,
37
+ className: cn(iconButtonVariants({
38
+ variant,
39
+ size
40
+ }), className),
41
+ ...props,
42
+ children: [icon ? /* @__PURE__ */ jsx(Icon, {
43
+ name: icon,
44
+ "aria-hidden": "true"
45
+ }) : null, children]
46
+ });
47
+ }
48
+ //#endregion
49
+ export { IconButton, iconButtonVariants };
50
+
51
+ //# sourceMappingURL=icon-button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icon-button.js","names":[],"sources":["../../resources/js/ui/icon-button.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { Icon } from \"@lattice-php/lattice/icons\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\n\n/**\n * A compact, resizable icon button — the shared affordance behind toolbar\n * triggers, popover triggers, and inline clear/remove buttons. `ghost` matches\n * `Button variant=\"ghost\"` (accent hover) and reacts to `aria-pressed` (toggle)\n * and `data-[state=open]` (a popover trigger). `segmented` joins onto the right\n * of an adjacent input. Size defaults to `sm`; pass `size` to resize.\n */\nconst iconButtonVariants = cva(\n cn(\n \"relative inline-flex shrink-0 items-center justify-center rounded-lt-sm transition-colors\",\n \"outline-none focus-visible:ring-2 focus-visible:ring-lt-ring/50\",\n \"disabled:pointer-events-none disabled:opacity-50\",\n ),\n {\n variants: {\n variant: {\n ghost: cn(\n \"text-lt-muted-fg hover:bg-lt-accent hover:text-lt-accent-fg\",\n \"data-[state=open]:bg-lt-accent data-[state=open]:text-lt-accent-fg\",\n \"aria-pressed:bg-lt-accent aria-pressed:text-lt-accent-fg\",\n ),\n segmented: cn(\n \"-ml-px rounded-l-none border border-lt-input text-lt-muted-fg hover:bg-lt-accent hover:text-lt-accent-fg\",\n \"data-[state=open]:z-10 data-[state=open]:border-lt-primary data-[state=open]:text-lt-fg\",\n ),\n },\n size: {\n xs: \"size-5 [&_svg]:size-lt-icon-sm\",\n sm: \"size-7 [&_svg]:size-lt-icon-md\",\n md: \"size-lt-control-md [&_svg]:size-lt-icon-md\",\n },\n },\n defaultVariants: { variant: \"ghost\", size: \"sm\" },\n },\n);\n\nexport function IconButton({\n icon,\n label,\n active,\n size,\n variant,\n className,\n children,\n ref,\n ...props\n}: Omit<React.ComponentProps<\"button\">, \"aria-pressed\"> &\n VariantProps<typeof iconButtonVariants> & {\n /** Icon glyph name; omit and pass `children` for custom content. */\n icon?: string;\n /** Accessible name (also used when the button shows only an icon). */\n label: string;\n /** Toggle state — sets `aria-pressed` and the pressed styling. */\n active?: boolean;\n }) {\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label={label}\n aria-pressed={active}\n className={cn(iconButtonVariants({ variant, size }), className)}\n {...props}\n >\n {icon ? <Icon name={icon} aria-hidden=\"true\" /> : null}\n {children}\n </button>\n );\n}\n\nexport { iconButtonVariants };\n"],"mappings":";;;;;;;;;;;;;AAYA,IAAM,qBAAqB,IACzB,GACE,6FACA,mEACA,kDACF,GACA;CACE,UAAU;EACR,SAAS;GACP,OAAO,GACL,+DACA,sEACA,0DACF;GACA,WAAW,GACT,4GACA,yFACF;EACF;EACA,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;CACF;CACA,iBAAiB;EAAE,SAAS;EAAS,MAAM;CAAK;AAClD,CACF;AAEA,SAAgB,WAAW,EACzB,MACA,OACA,QACA,MACA,SACA,WACA,UACA,KACA,GAAG,SASA;CACH,OACE,qBAAC,UAAD;EACO;EACL,MAAK;EACL,cAAY;EACZ,gBAAc;EACd,WAAW,GAAG,mBAAmB;GAAE;GAAS;EAAK,CAAC,GAAG,SAAS;EAC9D,GAAI;YANN,CAQG,OAAO,oBAAC,MAAD;GAAM,MAAM;GAAM,eAAY;EAAQ,CAAA,IAAI,MACjD,QACK;;AAEZ"}
package/dist/ui/icon.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { cn } from "../lib/utils.js";
2
2
  import { IconRenderer } from "../icons/icon-renderer.js";
3
+ import { coerceColor, colorValue } from "../lib/color.js";
3
4
  import { jsx } from "react/jsx-runtime";
4
5
  //#region resources/js/ui/icon.tsx
5
6
  var sizeClass = {
@@ -12,20 +13,18 @@ var sizeClass = {
12
13
  "3xl": "size-lt-icon-3xl",
13
14
  "4xl": "size-lt-icon-4xl"
14
15
  };
15
- var colorClass = {
16
- default: "text-lt-fg",
17
- muted: "text-lt-muted-fg",
18
- primary: "text-lt-primary",
19
- success: "text-lt-success",
20
- info: "text-lt-info",
21
- warning: "text-lt-warning",
22
- danger: "text-lt-danger"
23
- };
24
16
  var IconComponent = ({ node }) => {
25
17
  const { name, size, color, class: className } = node.props;
26
- return /* @__PURE__ */ jsx(IconRenderer, {
18
+ const icon = /* @__PURE__ */ jsx(IconRenderer, {
27
19
  icon: name,
28
- className: cn(sizeClass[size], color ? colorClass[color] : void 0, className)
20
+ className: cn(sizeClass[size], className)
21
+ });
22
+ const coerced = coerceColor(color);
23
+ if (!coerced) return icon;
24
+ return /* @__PURE__ */ jsx("span", {
25
+ className: "contents",
26
+ style: { color: colorValue(coerced) },
27
+ children: icon
29
28
  });
30
29
  };
31
30
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"icon.js","names":[],"sources":["../../resources/js/ui/icon.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { IconRenderer } from \"@lattice-php/lattice/icons\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport type { Color, Size } from \"@lattice-php/lattice/types/generated\";\n\nconst sizeClass: Record<Size, string> = {\n xs: \"size-lt-icon-xs\",\n sm: \"size-lt-icon-sm\",\n md: \"size-lt-icon-md\",\n lg: \"size-lt-icon-lg\",\n xl: \"size-lt-icon-xl\",\n \"2xl\": \"size-lt-icon-2xl\",\n \"3xl\": \"size-lt-icon-3xl\",\n \"4xl\": \"size-lt-icon-4xl\",\n};\n\nconst colorClass: Record<Color, string> = {\n default: \"text-lt-fg\",\n muted: \"text-lt-muted-fg\",\n primary: \"text-lt-primary\",\n success: \"text-lt-success\",\n info: \"text-lt-info\",\n warning: \"text-lt-warning\",\n danger: \"text-lt-danger\",\n};\n\nconst IconComponent: RendererComponent<\"icon\"> = ({ node }) => {\n const { name, size, color, class: className } = node.props;\n\n return (\n <IconRenderer\n icon={name}\n className={cn(sizeClass[size], color ? colorClass[color] : undefined, className)}\n />\n );\n};\n\nexport default IconComponent;\n"],"mappings":";;;;AAKA,IAAM,YAAkC;CACtC,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,OAAO;CACP,OAAO;CACP,OAAO;AACT;AAEA,IAAM,aAAoC;CACxC,SAAS;CACT,OAAO;CACP,SAAS;CACT,SAAS;CACT,MAAM;CACN,SAAS;CACT,QAAQ;AACV;AAEA,IAAM,iBAA4C,EAAE,WAAW;CAC7D,MAAM,EAAE,MAAM,MAAM,OAAO,OAAO,cAAc,KAAK;CAErD,OACE,oBAAC,cAAD;EACE,MAAM;EACN,WAAW,GAAG,UAAU,OAAO,QAAQ,WAAW,SAAS,KAAA,GAAW,SAAS;CAChF,CAAA;AAEL"}
1
+ {"version":3,"file":"icon.js","names":[],"sources":["../../resources/js/ui/icon.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { IconRenderer } from \"@lattice-php/lattice/icons\";\nimport { coerceColor, colorValue } from \"@lattice-php/lattice/lib/color\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport type { Size } from \"@lattice-php/lattice/types/generated\";\n\nconst sizeClass: Record<Size, string> = {\n xs: \"size-lt-icon-xs\",\n sm: \"size-lt-icon-sm\",\n md: \"size-lt-icon-md\",\n lg: \"size-lt-icon-lg\",\n xl: \"size-lt-icon-xl\",\n \"2xl\": \"size-lt-icon-2xl\",\n \"3xl\": \"size-lt-icon-3xl\",\n \"4xl\": \"size-lt-icon-4xl\",\n};\n\nconst IconComponent: RendererComponent<\"icon\"> = ({ node }) => {\n const { name, size, color, class: className } = node.props;\n const icon = <IconRenderer icon={name} className={cn(sizeClass[size], className)} />;\n const coerced = coerceColor(color);\n\n if (!coerced) {\n return icon;\n }\n\n return (\n <span className=\"contents\" style={{ color: colorValue(coerced) }}>\n {icon}\n </span>\n );\n};\n\nexport default IconComponent;\n"],"mappings":";;;;;AAMA,IAAM,YAAkC;CACtC,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,OAAO;CACP,OAAO;CACP,OAAO;AACT;AAEA,IAAM,iBAA4C,EAAE,WAAW;CAC7D,MAAM,EAAE,MAAM,MAAM,OAAO,OAAO,cAAc,KAAK;CACrD,MAAM,OAAO,oBAAC,cAAD;EAAc,MAAM;EAAM,WAAW,GAAG,UAAU,OAAO,SAAS;CAAI,CAAA;CACnF,MAAM,UAAU,YAAY,KAAK;CAEjC,IAAI,CAAC,SACH,OAAO;CAGT,OACE,oBAAC,QAAD;EAAM,WAAU;EAAW,OAAO,EAAE,OAAO,WAAW,OAAO,EAAE;YAC5D;CACG,CAAA;AAEV"}
@@ -0,0 +1,12 @@
1
+ import { ReactNode } from 'react';
2
+ interface PreviewableImageProps {
3
+ src: string;
4
+ alt: string;
5
+ previewable: boolean;
6
+ width?: number;
7
+ height?: number;
8
+ className?: string;
9
+ testId?: string;
10
+ }
11
+ export declare function PreviewableImage({ src, alt, previewable, width, height, className, testId, }: PreviewableImageProps): ReactNode;
12
+ export {};
@@ -0,0 +1,65 @@
1
+ import { useT } from "../i18n/instance.js";
2
+ import { Button } from "./button.js";
3
+ import { Dialog, DialogClose, DialogContent, DialogTitle } from "./dialog.js";
4
+ import { useState } from "react";
5
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
6
+ //#region resources/js/ui/image-preview.tsx
7
+ function PreviewableImage({ src, alt, previewable, width, height, className, testId }) {
8
+ const { t } = useT("lattice");
9
+ const [open, setOpen] = useState(false);
10
+ const image = /* @__PURE__ */ jsx("img", {
11
+ alt,
12
+ src,
13
+ width,
14
+ height,
15
+ className,
16
+ style: width ? {
17
+ width,
18
+ height
19
+ } : void 0
20
+ });
21
+ if (!previewable) return image;
22
+ const openLabel = t("common.image.open-preview", "View image");
23
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("button", {
24
+ type: "button",
25
+ "data-test": testId,
26
+ className: "cursor-zoom-in",
27
+ "aria-label": openLabel,
28
+ onClick: () => setOpen(true),
29
+ children: image
30
+ }), /* @__PURE__ */ jsx(Dialog, {
31
+ open,
32
+ onOpenChange: setOpen,
33
+ children: /* @__PURE__ */ jsxs(DialogContent, {
34
+ "aria-describedby": void 0,
35
+ className: "max-h-[90vh] w-auto max-w-[90vw] border-none bg-transparent p-0 shadow-none",
36
+ children: [
37
+ /* @__PURE__ */ jsx(DialogTitle, {
38
+ className: "sr-only",
39
+ children: alt || openLabel
40
+ }),
41
+ /* @__PURE__ */ jsx("img", {
42
+ alt,
43
+ src,
44
+ "data-slot": "image-lightbox",
45
+ className: "max-h-[90vh] max-w-[90vw] rounded-lt object-contain"
46
+ }),
47
+ /* @__PURE__ */ jsx(DialogClose, {
48
+ asChild: true,
49
+ children: /* @__PURE__ */ jsx(Button, {
50
+ icon: "x",
51
+ "aria-label": t("common.close", "Close"),
52
+ "data-test": "lightbox-close",
53
+ size: "icon",
54
+ variant: "ghost",
55
+ className: "absolute top-2 right-2 bg-lt-bg/80 hover:bg-lt-bg"
56
+ })
57
+ })
58
+ ]
59
+ })
60
+ })] });
61
+ }
62
+ //#endregion
63
+ export { PreviewableImage };
64
+
65
+ //# sourceMappingURL=image-preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-preview.js","names":[],"sources":["../../resources/js/ui/image-preview.tsx"],"sourcesContent":["import { useT } from \"@lattice-php/lattice/i18n\";\nimport { type ReactNode, useState } from \"react\";\nimport { Button } from \"@lattice-php/lattice/ui/button\";\nimport { Dialog, DialogClose, DialogContent, DialogTitle } from \"./dialog\";\n\ninterface PreviewableImageProps {\n src: string;\n alt: string;\n previewable: boolean;\n width?: number;\n height?: number;\n className?: string;\n testId?: string;\n}\n\nexport function PreviewableImage({\n src,\n alt,\n previewable,\n width,\n height,\n className,\n testId,\n}: PreviewableImageProps): ReactNode {\n const { t } = useT(\"lattice\");\n const [open, setOpen] = useState(false);\n\n const image = (\n <img\n alt={alt}\n src={src}\n width={width}\n height={height}\n className={className}\n style={width ? { width, height } : undefined}\n />\n );\n\n if (!previewable) {\n return image;\n }\n\n const openLabel = t(\"common.image.open-preview\", \"View image\");\n\n return (\n <>\n <button\n type=\"button\"\n data-test={testId}\n className=\"cursor-zoom-in\"\n aria-label={openLabel}\n onClick={() => setOpen(true)}\n >\n {image}\n </button>\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogContent\n aria-describedby={undefined}\n className=\"max-h-[90vh] w-auto max-w-[90vw] border-none bg-transparent p-0 shadow-none\"\n >\n <DialogTitle className=\"sr-only\">{alt || openLabel}</DialogTitle>\n <img\n alt={alt}\n src={src}\n data-slot=\"image-lightbox\"\n className=\"max-h-[90vh] max-w-[90vw] rounded-lt object-contain\"\n />\n <DialogClose asChild>\n <Button\n icon=\"x\"\n aria-label={t(\"common.close\", \"Close\")}\n data-test=\"lightbox-close\"\n size=\"icon\"\n variant=\"ghost\"\n className=\"absolute top-2 right-2 bg-lt-bg/80 hover:bg-lt-bg\"\n />\n </DialogClose>\n </DialogContent>\n </Dialog>\n </>\n );\n}\n"],"mappings":";;;;;;AAeA,SAAgB,iBAAiB,EAC/B,KACA,KACA,aACA,OACA,QACA,WACA,UACmC;CACnC,MAAM,EAAE,MAAM,KAAK,SAAS;CAC5B,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CAEtC,MAAM,QACJ,oBAAC,OAAD;EACO;EACA;EACE;EACC;EACG;EACX,OAAO,QAAQ;GAAE;GAAO;EAAO,IAAI,KAAA;CACpC,CAAA;CAGH,IAAI,CAAC,aACH,OAAO;CAGT,MAAM,YAAY,EAAE,6BAA6B,YAAY;CAE7D,OACE,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,UAAD;EACE,MAAK;EACL,aAAW;EACX,WAAU;EACV,cAAY;EACZ,eAAe,QAAQ,IAAI;YAE1B;CACK,CAAA,GACR,oBAAC,QAAD;EAAc;EAAM,cAAc;YAChC,qBAAC,eAAD;GACE,oBAAkB,KAAA;GAClB,WAAU;aAFZ;IAIE,oBAAC,aAAD;KAAa,WAAU;eAAW,OAAO;IAAuB,CAAA;IAChE,oBAAC,OAAD;KACO;KACA;KACL,aAAU;KACV,WAAU;IACX,CAAA;IACD,oBAAC,aAAD;KAAa,SAAA;eACX,oBAAC,QAAD;MACE,MAAK;MACL,cAAY,EAAE,gBAAgB,OAAO;MACrC,aAAU;MACV,MAAK;MACL,SAAQ;MACR,WAAU;KACX,CAAA;IACU,CAAA;GACA;;CACT,CAAA,CACR,EAAA,CAAA;AAEN"}
@@ -0,0 +1,3 @@
1
+ import { RendererComponent } from '../core/types.js';
2
+ declare const ImageComponent: RendererComponent<"image">;
3
+ export default ImageComponent;
@@ -0,0 +1,21 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { nodeIdentity } from "../core/test-id.js";
3
+ import { PreviewableImage } from "./image-preview.js";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region resources/js/ui/image.tsx
6
+ var ImageComponent = ({ node }) => {
7
+ const { src, alt, size, circular, previewable } = node.props;
8
+ return /* @__PURE__ */ jsx(PreviewableImage, {
9
+ alt: alt ?? "",
10
+ className: cn("object-cover", circular ? "rounded-full" : "rounded-lt-sm"),
11
+ height: size ?? void 0,
12
+ previewable,
13
+ src,
14
+ testId: nodeIdentity(node),
15
+ width: size ?? void 0
16
+ });
17
+ };
18
+ //#endregion
19
+ export { ImageComponent as default };
20
+
21
+ //# sourceMappingURL=image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image.js","names":[],"sources":["../../resources/js/ui/image.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport { PreviewableImage } from \"./image-preview\";\n\nconst ImageComponent: RendererComponent<\"image\"> = ({ node }) => {\n const { src, alt, size, circular, previewable } = node.props;\n\n return (\n <PreviewableImage\n alt={alt ?? \"\"}\n className={cn(\"object-cover\", circular ? \"rounded-full\" : \"rounded-lt-sm\")}\n height={size ?? undefined}\n previewable={previewable}\n src={src}\n testId={nodeIdentity(node)}\n width={size ?? undefined}\n />\n );\n};\n\nexport default ImageComponent;\n"],"mappings":";;;;;AAKA,IAAM,kBAA8C,EAAE,WAAW;CAC/D,MAAM,EAAE,KAAK,KAAK,MAAM,UAAU,gBAAgB,KAAK;CAEvD,OACE,oBAAC,kBAAD;EACE,KAAK,OAAO;EACZ,WAAW,GAAG,gBAAgB,WAAW,iBAAiB,eAAe;EACzE,QAAQ,QAAQ,KAAA;EACH;EACR;EACL,QAAQ,aAAa,IAAI;EACzB,OAAO,QAAQ,KAAA;CAChB,CAAA;AAEL"}
@@ -10,8 +10,9 @@ export { ConfirmDialog } from './confirm-dialog.js';
10
10
  export { ActionTrigger, ActionTriggerProvider, useActionTrigger, useClickBehavior, } from './click-behavior.js';
11
11
  export type { ActionTriggerRenderer, ClickBehavior, TriggerState } from './click-behavior.js';
12
12
  export { Dialog, DialogClose, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from './dialog.js';
13
- export { CopyableText, copyToClipboard } from './copyable-text.js';
13
+ export { CopyButton, CopyableText, copyToClipboard } from './copyable-text.js';
14
14
  export { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from './dropdown-menu.js';
15
+ export { PreviewableImage } from './image-preview.js';
15
16
  export { InfoTooltip } from './info-tooltip.js';
16
17
  export { Input } from './input.js';
17
18
  export { default as InputError } from './input-error.js';
package/dist/ui/index.js CHANGED
@@ -10,17 +10,18 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigge
10
10
  import { Badge, badgeVariants } from "./badge.js";
11
11
  import { InfoTooltip } from "./info-tooltip.js";
12
12
  import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "./card.js";
13
+ import { CopyButton, CopyableText, copyToClipboard } from "./copyable-text.js";
14
+ import { PreviewableImage } from "./image-preview.js";
13
15
  import { TextLink } from "./link.js";
14
16
  import { SegmentedPills } from "./segmented-pills.js";
15
- import { CopyableText, copyToClipboard } from "./copyable-text.js";
16
17
  import { uiComponents } from "./plugin.js";
17
18
  import InputError from "./input-error.js";
18
19
  import { Label } from "./label.js";
19
20
  import { Checkbox } from "./checkbox.js";
20
- import { AffixGroup } from "./affix-group.js";
21
21
  import { Input } from "./input.js";
22
+ import { AffixGroup } from "./affix-group.js";
22
23
  import { InputOTP } from "./input-otp.js";
23
24
  import PasswordInput from "./password-input.js";
24
25
  import { Combobox } from "./combobox.js";
25
26
  import { Textarea } from "./textarea.js";
26
- export { ActionMenuProvider, ActionTrigger, ActionTriggerProvider, AffixGroup, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Combobox, ConfirmDialog, CopyableText, Dialog, DialogClose, DialogContent, DialogDescription, DialogHeader, DialogTitle, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, InfoTooltip, Input, InputError, InputOTP, Label, PasswordInput, Popover, PopoverClose, PopoverContent, PopoverTrigger, SegmentedPills, Skeleton, Spinner, TextLink, Textarea, actionMenuItemClassName, badgeVariants, buttonVariants, copyToClipboard, uiComponents, useActionMenu, useActionTrigger, useClickBehavior };
27
+ export { ActionMenuProvider, ActionTrigger, ActionTriggerProvider, AffixGroup, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Combobox, ConfirmDialog, CopyButton, CopyableText, Dialog, DialogClose, DialogContent, DialogDescription, DialogHeader, DialogTitle, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, InfoTooltip, Input, InputError, InputOTP, Label, PasswordInput, Popover, PopoverClose, PopoverContent, PopoverTrigger, PreviewableImage, SegmentedPills, Skeleton, Spinner, TextLink, Textarea, actionMenuItemClassName, badgeVariants, buttonVariants, copyToClipboard, uiComponents, useActionMenu, useActionTrigger, useClickBehavior };
@@ -8,7 +8,7 @@ function InfoTooltip({ content }) {
8
8
  if (!content) return null;
9
9
  return /* @__PURE__ */ jsxs(Popover, { children: [/* @__PURE__ */ jsx(PopoverTrigger, {
10
10
  type: "button",
11
- "aria-label": t("common.moreInfo", "More information"),
11
+ "aria-label": t("common.more-info", "More information"),
12
12
  className: "ml-1 inline-flex rounded-lt-sm text-lt-muted-fg outline-none hover:text-lt-fg focus-visible:text-lt-fg focus-visible:ring-lt-ring/50 focus-visible:ring-[3px]",
13
13
  children: /* @__PURE__ */ jsx(Icon, {
14
14
  name: "info",
@@ -1 +1 @@
1
- {"version":3,"file":"info-tooltip.js","names":[],"sources":["../../resources/js/ui/info-tooltip.tsx"],"sourcesContent":["import { Icon } from \"@lattice-php/lattice/icons\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\n\nexport function InfoTooltip({ content }: { content?: string | null }) {\n const { t } = useT(\"lattice\");\n\n if (!content) {\n return null;\n }\n\n return (\n <Popover>\n <PopoverTrigger\n type=\"button\"\n aria-label={t(\"common.moreInfo\", \"More information\")}\n className=\"ml-1 inline-flex rounded-lt-sm text-lt-muted-fg outline-none hover:text-lt-fg focus-visible:text-lt-fg focus-visible:ring-lt-ring/50 focus-visible:ring-[3px]\"\n >\n <Icon name=\"info\" className=\"size-lt-icon-sm\" />\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n className=\"max-w-xs p-3 text-sm [&_a]:underline\"\n dangerouslySetInnerHTML={{ __html: content }}\n />\n </Popover>\n );\n}\n"],"mappings":";;;;;AAIA,SAAgB,YAAY,EAAE,WAAwC;CACpE,MAAM,EAAE,MAAM,KAAK,SAAS;CAE5B,IAAI,CAAC,SACH,OAAO;CAGT,OACE,qBAAC,SAAD,EAAA,UAAA,CACE,oBAAC,gBAAD;EACE,MAAK;EACL,cAAY,EAAE,mBAAmB,kBAAkB;EACnD,WAAU;YAEV,oBAAC,MAAD;GAAM,MAAK;GAAO,WAAU;EAAmB,CAAA;CACjC,CAAA,GAChB,oBAAC,gBAAD;EACE,OAAM;EACN,WAAU;EACV,yBAAyB,EAAE,QAAQ,QAAQ;CAC5C,CAAA,CACM,EAAA,CAAA;AAEb"}
1
+ {"version":3,"file":"info-tooltip.js","names":[],"sources":["../../resources/js/ui/info-tooltip.tsx"],"sourcesContent":["import { Icon } from \"@lattice-php/lattice/icons\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\n\nexport function InfoTooltip({ content }: { content?: string | null }) {\n const { t } = useT(\"lattice\");\n\n if (!content) {\n return null;\n }\n\n return (\n <Popover>\n <PopoverTrigger\n type=\"button\"\n aria-label={t(\"common.more-info\", \"More information\")}\n className=\"ml-1 inline-flex rounded-lt-sm text-lt-muted-fg outline-none hover:text-lt-fg focus-visible:text-lt-fg focus-visible:ring-lt-ring/50 focus-visible:ring-[3px]\"\n >\n <Icon name=\"info\" className=\"size-lt-icon-sm\" />\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n className=\"max-w-xs p-3 text-sm [&_a]:underline\"\n dangerouslySetInnerHTML={{ __html: content }}\n />\n </Popover>\n );\n}\n"],"mappings":";;;;;AAIA,SAAgB,YAAY,EAAE,WAAwC;CACpE,MAAM,EAAE,MAAM,KAAK,SAAS;CAE5B,IAAI,CAAC,SACH,OAAO;CAGT,OACE,qBAAC,SAAD,EAAA,UAAA,CACE,oBAAC,gBAAD;EACE,MAAK;EACL,cAAY,EAAE,oBAAoB,kBAAkB;EACpD,WAAU;YAEV,oBAAC,MAAD;GAAM,MAAK;GAAO,WAAU;EAAmB,CAAA;CACjC,CAAA,GAChB,oBAAC,gBAAD;EACE,OAAM;EACN,WAAU;EACV,yBAAyB,EAAE,QAAQ,QAAQ;CAC5C,CAAA,CACM,EAAA,CAAA;AAEb"}
@@ -1,3 +1,5 @@
1
+ import { VariantProps } from 'class-variance-authority';
2
+ import { controlSurface } from './control.js';
1
3
  import * as React from "react";
2
- declare function Input({ className, type, ...props }: React.ComponentProps<"input">): React.JSX.Element;
4
+ declare function Input({ className, type, density, ...props }: React.ComponentProps<"input"> & VariantProps<typeof controlSurface>): React.JSX.Element;
3
5
  export { Input };
package/dist/ui/input.js CHANGED
@@ -3,11 +3,11 @@ import { controlSurface } from "./control.js";
3
3
  import "react";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  //#region resources/js/ui/input.tsx
6
- function Input({ className, type, ...props }) {
6
+ function Input({ className, type, density, ...props }) {
7
7
  return /* @__PURE__ */ jsx("input", {
8
8
  type,
9
9
  "data-slot": "input",
10
- className: cn(controlSurface(), "file:text-lt-fg selection:bg-lt-primary selection:text-lt-primary-fg file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium", className),
10
+ className: cn(controlSurface({ density }), "file:text-lt-fg selection:bg-lt-primary selection:text-lt-primary-fg file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium", className),
11
11
  ...props
12
12
  });
13
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"input.js","names":[],"sources":["../../resources/js/ui/input.tsx"],"sourcesContent":["import * as React from \"react\";\n\nimport { controlSurface } from \"@lattice-php/lattice/ui/control\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <input\n type={type}\n data-slot=\"input\"\n className={cn(\n controlSurface(),\n \"file:text-lt-fg selection:bg-lt-primary selection:text-lt-primary-fg file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Input };\n"],"mappings":";;;;;AAKA,SAAS,MAAM,EAAE,WAAW,MAAM,GAAG,SAAwC;CAC3E,OACE,oBAAC,SAAD;EACQ;EACN,aAAU;EACV,WAAW,GACT,eAAe,GACf,kKACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
1
+ {"version":3,"file":"input.js","names":[],"sources":["../../resources/js/ui/input.tsx"],"sourcesContent":["import * as React from \"react\";\nimport type { VariantProps } from \"class-variance-authority\";\n\nimport { controlSurface } from \"@lattice-php/lattice/ui/control\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\n\nfunction Input({\n className,\n type,\n density,\n ...props\n}: React.ComponentProps<\"input\"> & VariantProps<typeof controlSurface>) {\n return (\n <input\n type={type}\n data-slot=\"input\"\n className={cn(\n controlSurface({ density }),\n \"file:text-lt-fg selection:bg-lt-primary selection:text-lt-primary-fg file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Input };\n"],"mappings":";;;;;AAMA,SAAS,MAAM,EACb,WACA,MACA,SACA,GAAG,SACmE;CACtE,OACE,oBAAC,SAAD;EACQ;EACN,aAAU;EACV,WAAW,GACT,eAAe,EAAE,QAAQ,CAAC,GAC1B,kKACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
package/dist/ui/modal.js CHANGED
@@ -1,6 +1,6 @@
1
- import { LATTICE_EVENT } from "../events/event-names.js";
1
+ import { LATTICE_EVENT } from "../core/event-names.js";
2
2
  import { Dialog, DialogContent, DialogHeader } from "./dialog.js";
3
- import { useEffect, useState } from "react";
3
+ import { useEffect, useRef, useState } from "react";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region resources/js/ui/modal.tsx
6
6
  function matchesModal(event, modal) {
@@ -12,12 +12,17 @@ var ModalComponent = ({ children, node }) => {
12
12
  const description = node.props.description;
13
13
  const closeLabel = node.props.closeLabel;
14
14
  const [isOpen, setIsOpen] = useState(node.props.open === true);
15
+ const openerRef = useRef(null);
16
+ const wasOpenRef = useRef(isOpen);
15
17
  useEffect(() => {
16
18
  if (node.props.open === true) setIsOpen(true);
17
19
  }, [node.props.open]);
18
20
  useEffect(() => {
19
21
  function open(event) {
20
- if (node.id && matchesModal(event, node.id)) setIsOpen(true);
22
+ if (node.id && matchesModal(event, node.id)) {
23
+ openerRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
24
+ setIsOpen(true);
25
+ }
21
26
  }
22
27
  function close(event) {
23
28
  if (!node.id || matchesModal(event, node.id)) setIsOpen(false);
@@ -29,12 +34,20 @@ var ModalComponent = ({ children, node }) => {
29
34
  window.removeEventListener(LATTICE_EVENT.closeModal, close);
30
35
  };
31
36
  }, [node.id]);
37
+ useEffect(() => {
38
+ if (wasOpenRef.current && !isOpen) {
39
+ const opener = openerRef.current;
40
+ if (opener) requestAnimationFrame(() => opener.focus());
41
+ }
42
+ wasOpenRef.current = isOpen;
43
+ }, [isOpen]);
32
44
  return /* @__PURE__ */ jsx(Dialog, {
33
45
  open: isOpen,
34
46
  onOpenChange: setIsOpen,
35
47
  children: /* @__PURE__ */ jsxs(DialogContent, {
36
48
  ...description ? {} : { "aria-describedby": void 0 },
37
- className: "max-h-[min(680px,calc(100vh-2rem))] w-full max-w-lg overflow-y-auto",
49
+ placement: node.props.side ?? "center",
50
+ width: node.props.width,
38
51
  children: [/* @__PURE__ */ jsx(DialogHeader, {
39
52
  closeLabel,
40
53
  description,
@@ -1 +1 @@
1
- {"version":3,"file":"modal.js","names":[],"sources":["../../resources/js/ui/modal.tsx"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport { Dialog, DialogContent, DialogHeader } from \"@lattice-php/lattice/ui/dialog\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/events/event-names\";\n\ntype ModalEvent = CustomEvent<{\n modal: string | null;\n}>;\n\nfunction matchesModal(event: Event, modal: string): boolean {\n const target = (event as ModalEvent).detail?.modal;\n\n return target == null || target === modal;\n}\n\nconst ModalComponent: RendererComponent<\"modal\"> = ({ children, node }) => {\n const title = node.props.title ?? \"Dialog\";\n const description = node.props.description;\n const closeLabel = node.props.closeLabel;\n const [isOpen, setIsOpen] = useState(node.props.open === true);\n\n // Honour server-driven open changes across re-renders, not just on mount. One\n // way on purpose: closing stays user/closeModal-driven so it never fights a\n // manual close, and the dep keeps it from re-firing while open stays true.\n useEffect(() => {\n if (node.props.open === true) {\n setIsOpen(true);\n }\n }, [node.props.open]);\n\n useEffect(() => {\n function open(event: Event): void {\n if (node.id && matchesModal(event, node.id)) {\n setIsOpen(true);\n }\n }\n\n function close(event: Event): void {\n if (!node.id || matchesModal(event, node.id)) {\n setIsOpen(false);\n }\n }\n\n window.addEventListener(LATTICE_EVENT.openModal, open);\n window.addEventListener(LATTICE_EVENT.closeModal, close);\n\n return () => {\n window.removeEventListener(LATTICE_EVENT.openModal, open);\n window.removeEventListener(LATTICE_EVENT.closeModal, close);\n };\n }, [node.id]);\n\n return (\n <Dialog open={isOpen} onOpenChange={setIsOpen}>\n <DialogContent\n {...(description ? {} : { \"aria-describedby\": undefined })}\n className=\"max-h-[min(680px,calc(100vh-2rem))] w-full max-w-lg overflow-y-auto\"\n >\n <DialogHeader closeLabel={closeLabel} description={description} title={title} />\n <div className=\"mt-6 space-y-6\">{children}</div>\n </DialogContent>\n </Dialog>\n );\n};\n\nexport default ModalComponent;\n"],"mappings":";;;;;AASA,SAAS,aAAa,OAAc,OAAwB;CAC1D,MAAM,SAAU,MAAqB,QAAQ;CAE7C,OAAO,UAAU,QAAQ,WAAW;AACtC;AAEA,IAAM,kBAA8C,EAAE,UAAU,WAAW;CACzE,MAAM,QAAQ,KAAK,MAAM,SAAS;CAClC,MAAM,cAAc,KAAK,MAAM;CAC/B,MAAM,aAAa,KAAK,MAAM;CAC9B,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK,MAAM,SAAS,IAAI;CAK7D,gBAAgB;EACd,IAAI,KAAK,MAAM,SAAS,MACtB,UAAU,IAAI;CAElB,GAAG,CAAC,KAAK,MAAM,IAAI,CAAC;CAEpB,gBAAgB;EACd,SAAS,KAAK,OAAoB;GAChC,IAAI,KAAK,MAAM,aAAa,OAAO,KAAK,EAAE,GACxC,UAAU,IAAI;EAElB;EAEA,SAAS,MAAM,OAAoB;GACjC,IAAI,CAAC,KAAK,MAAM,aAAa,OAAO,KAAK,EAAE,GACzC,UAAU,KAAK;EAEnB;EAEA,OAAO,iBAAiB,cAAc,WAAW,IAAI;EACrD,OAAO,iBAAiB,cAAc,YAAY,KAAK;EAEvD,aAAa;GACX,OAAO,oBAAoB,cAAc,WAAW,IAAI;GACxD,OAAO,oBAAoB,cAAc,YAAY,KAAK;EAC5D;CACF,GAAG,CAAC,KAAK,EAAE,CAAC;CAEZ,OACE,oBAAC,QAAD;EAAQ,MAAM;EAAQ,cAAc;YAClC,qBAAC,eAAD;GACE,GAAK,cAAc,CAAC,IAAI,EAAE,oBAAoB,KAAA,EAAU;GACxD,WAAU;aAFZ,CAIE,oBAAC,cAAD;IAA0B;IAAyB;IAAoB;GAAQ,CAAA,GAC/E,oBAAC,OAAD;IAAK,WAAU;IAAkB;GAAc,CAAA,CAClC;;CACT,CAAA;AAEZ"}
1
+ {"version":3,"file":"modal.js","names":[],"sources":["../../resources/js/ui/modal.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { Dialog, DialogContent, DialogHeader } from \"@lattice-php/lattice/ui/dialog\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/core/event-names\";\n\ntype ModalEvent = CustomEvent<{\n modal: string | null;\n}>;\n\nfunction matchesModal(event: Event, modal: string): boolean {\n const target = (event as ModalEvent).detail?.modal;\n\n return target == null || target === modal;\n}\n\nconst ModalComponent: RendererComponent<\"modal\"> = ({ children, node }) => {\n const title = node.props.title ?? \"Dialog\";\n const description = node.props.description;\n const closeLabel = node.props.closeLabel;\n const [isOpen, setIsOpen] = useState(node.props.open === true);\n const openerRef = useRef<HTMLElement | null>(null);\n const wasOpenRef = useRef(isOpen);\n\n // Honour server-driven open changes across re-renders, not just on mount. One\n // way on purpose: closing stays user/closeModal-driven so it never fights a\n // manual close, and the dep keeps it from re-firing while open stays true.\n useEffect(() => {\n if (node.props.open === true) {\n setIsOpen(true);\n }\n }, [node.props.open]);\n\n useEffect(() => {\n function open(event: Event): void {\n if (node.id && matchesModal(event, node.id)) {\n openerRef.current =\n document.activeElement instanceof HTMLElement ? document.activeElement : null;\n setIsOpen(true);\n }\n }\n\n function close(event: Event): void {\n if (!node.id || matchesModal(event, node.id)) {\n setIsOpen(false);\n }\n }\n\n window.addEventListener(LATTICE_EVENT.openModal, open);\n window.addEventListener(LATTICE_EVENT.closeModal, close);\n\n return () => {\n window.removeEventListener(LATTICE_EVENT.openModal, open);\n window.removeEventListener(LATTICE_EVENT.closeModal, close);\n };\n }, [node.id]);\n\n // Radix only restores focus to a `DialogTrigger`-registered element, and this\n // modal is opened imperatively rather than through one. Own the restore\n // ourselves instead: whatever had focus when the modal opened gets it back\n // once the closing dialog has finished unmounting.\n useEffect(() => {\n if (wasOpenRef.current && !isOpen) {\n const opener = openerRef.current;\n\n if (opener) {\n requestAnimationFrame(() => opener.focus());\n }\n }\n\n wasOpenRef.current = isOpen;\n }, [isOpen]);\n\n return (\n <Dialog open={isOpen} onOpenChange={setIsOpen}>\n <DialogContent\n {...(description ? {} : { \"aria-describedby\": undefined })}\n placement={node.props.side ?? \"center\"}\n width={node.props.width}\n >\n <DialogHeader closeLabel={closeLabel} description={description} title={title} />\n <div className=\"mt-6 space-y-6\">{children}</div>\n </DialogContent>\n </Dialog>\n );\n};\n\nexport default ModalComponent;\n"],"mappings":";;;;;AASA,SAAS,aAAa,OAAc,OAAwB;CAC1D,MAAM,SAAU,MAAqB,QAAQ;CAE7C,OAAO,UAAU,QAAQ,WAAW;AACtC;AAEA,IAAM,kBAA8C,EAAE,UAAU,WAAW;CACzE,MAAM,QAAQ,KAAK,MAAM,SAAS;CAClC,MAAM,cAAc,KAAK,MAAM;CAC/B,MAAM,aAAa,KAAK,MAAM;CAC9B,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK,MAAM,SAAS,IAAI;CAC7D,MAAM,YAAY,OAA2B,IAAI;CACjD,MAAM,aAAa,OAAO,MAAM;CAKhC,gBAAgB;EACd,IAAI,KAAK,MAAM,SAAS,MACtB,UAAU,IAAI;CAElB,GAAG,CAAC,KAAK,MAAM,IAAI,CAAC;CAEpB,gBAAgB;EACd,SAAS,KAAK,OAAoB;GAChC,IAAI,KAAK,MAAM,aAAa,OAAO,KAAK,EAAE,GAAG;IAC3C,UAAU,UACR,SAAS,yBAAyB,cAAc,SAAS,gBAAgB;IAC3E,UAAU,IAAI;GAChB;EACF;EAEA,SAAS,MAAM,OAAoB;GACjC,IAAI,CAAC,KAAK,MAAM,aAAa,OAAO,KAAK,EAAE,GACzC,UAAU,KAAK;EAEnB;EAEA,OAAO,iBAAiB,cAAc,WAAW,IAAI;EACrD,OAAO,iBAAiB,cAAc,YAAY,KAAK;EAEvD,aAAa;GACX,OAAO,oBAAoB,cAAc,WAAW,IAAI;GACxD,OAAO,oBAAoB,cAAc,YAAY,KAAK;EAC5D;CACF,GAAG,CAAC,KAAK,EAAE,CAAC;CAMZ,gBAAgB;EACd,IAAI,WAAW,WAAW,CAAC,QAAQ;GACjC,MAAM,SAAS,UAAU;GAEzB,IAAI,QACF,4BAA4B,OAAO,MAAM,CAAC;EAE9C;EAEA,WAAW,UAAU;CACvB,GAAG,CAAC,MAAM,CAAC;CAEX,OACE,oBAAC,QAAD;EAAQ,MAAM;EAAQ,cAAc;YAClC,qBAAC,eAAD;GACE,GAAK,cAAc,CAAC,IAAI,EAAE,oBAAoB,KAAA,EAAU;GACxD,WAAW,KAAK,MAAM,QAAQ;GAC9B,OAAO,KAAK,MAAM;aAHpB,CAKE,oBAAC,cAAD;IAA0B;IAAyB;IAAoB;GAAQ,CAAA,GAC/E,oBAAC,OAAD;IAAK,WAAU;IAAkB;GAAc,CAAA,CAClC;;CACT,CAAA;AAEZ"}
@@ -0,0 +1,10 @@
1
+ import { VariantProps } from 'class-variance-authority';
2
+ import { controlSurface } from './control.js';
3
+ import * as React from "react";
4
+ /**
5
+ * A native `<select>` wearing the shared control chrome — for short, fixed
6
+ * option lists (filter operators, boolean/ternary states) where the full
7
+ * Combobox is overkill. `density` matches {@link Input}; defaults to comfortable.
8
+ */
9
+ declare function NativeSelect({ className, density, children, ref, ...props }: React.ComponentProps<"select"> & VariantProps<typeof controlSurface>): React.JSX.Element;
10
+ export { NativeSelect };
@@ -0,0 +1,23 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { controlSurface } from "./control.js";
3
+ import "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region resources/js/ui/native-select.tsx
6
+ /**
7
+ * A native `<select>` wearing the shared control chrome — for short, fixed
8
+ * option lists (filter operators, boolean/ternary states) where the full
9
+ * Combobox is overkill. `density` matches {@link Input}; defaults to comfortable.
10
+ */
11
+ function NativeSelect({ className, density, children, ref, ...props }) {
12
+ return /* @__PURE__ */ jsx("select", {
13
+ ref,
14
+ "data-slot": "native-select",
15
+ className: cn(controlSurface({ density }), "cursor-pointer", className),
16
+ ...props,
17
+ children
18
+ });
19
+ }
20
+ //#endregion
21
+ export { NativeSelect };
22
+
23
+ //# sourceMappingURL=native-select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-select.js","names":[],"sources":["../../resources/js/ui/native-select.tsx"],"sourcesContent":["import * as React from \"react\";\nimport type { VariantProps } from \"class-variance-authority\";\n\nimport { controlSurface } from \"@lattice-php/lattice/ui/control\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\n\n/**\n * A native `<select>` wearing the shared control chrome — for short, fixed\n * option lists (filter operators, boolean/ternary states) where the full\n * Combobox is overkill. `density` matches {@link Input}; defaults to comfortable.\n */\nfunction NativeSelect({\n className,\n density,\n children,\n ref,\n ...props\n}: React.ComponentProps<\"select\"> & VariantProps<typeof controlSurface>) {\n return (\n <select\n ref={ref}\n data-slot=\"native-select\"\n className={cn(controlSurface({ density }), \"cursor-pointer\", className)}\n {...props}\n >\n {children}\n </select>\n );\n}\n\nexport { NativeSelect };\n"],"mappings":";;;;;;;;;;AAWA,SAAS,aAAa,EACpB,WACA,SACA,UACA,KACA,GAAG,SACoE;CACvE,OACE,oBAAC,UAAD;EACO;EACL,aAAU;EACV,WAAW,GAAG,eAAe,EAAE,QAAQ,CAAC,GAAG,kBAAkB,SAAS;EACtE,GAAI;EAEH;CACK,CAAA;AAEZ"}
@@ -0,0 +1,2 @@
1
+ /** Shared pill styling for the tabs strip and the segmented control. */
2
+ export declare function pillClassName(active: boolean): string;
@@ -0,0 +1,10 @@
1
+ import { cn } from "../lib/utils.js";
2
+ //#region resources/js/ui/pill.ts
3
+ /** Shared pill styling for the tabs strip and the segmented control. */
4
+ function pillClassName(active) {
5
+ return cn("whitespace-nowrap rounded-lt-sm px-3 py-1.5 text-sm font-medium transition-colors", active ? "bg-lt-bg text-lt-fg shadow-lt-xs" : "text-lt-muted-fg hover:bg-lt-bg/60 hover:text-lt-fg");
6
+ }
7
+ //#endregion
8
+ export { pillClassName };
9
+
10
+ //# sourceMappingURL=pill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pill.js","names":[],"sources":["../../resources/js/ui/pill.ts"],"sourcesContent":["import { cn } from \"@lattice-php/lattice/lib/utils\";\n\n/** Shared pill styling for the tabs strip and the segmented control. */\nexport function pillClassName(active: boolean): string {\n return cn(\n \"whitespace-nowrap rounded-lt-sm px-3 py-1.5 text-sm font-medium transition-colors\",\n active\n ? \"bg-lt-bg text-lt-fg shadow-lt-xs\"\n : \"text-lt-muted-fg hover:bg-lt-bg/60 hover:text-lt-fg\",\n );\n}\n"],"mappings":";;;AAGA,SAAgB,cAAc,QAAyB;CACrD,OAAO,GACL,qFACA,SACI,qCACA,qDACN;AACF"}