@lattice-php/lattice 0.1.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 (277) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +39 -0
  3. package/dist/action/components/action-group.d.ts +10 -0
  4. package/dist/action/components/action-group.js +79 -0
  5. package/dist/action/components/action-group.js.map +1 -0
  6. package/dist/action/components/action.d.ts +26 -0
  7. package/dist/action/components/action.js +87 -0
  8. package/dist/action/components/action.js.map +1 -0
  9. package/dist/action/effects.d.ts +30 -0
  10. package/dist/action/effects.js +44 -0
  11. package/dist/action/effects.js.map +1 -0
  12. package/dist/action/index.d.ts +1 -0
  13. package/dist/action/index.js +15 -0
  14. package/dist/action/index.js.map +1 -0
  15. package/dist/appearance/index.d.ts +9 -0
  16. package/dist/appearance/index.js +66 -0
  17. package/dist/appearance/index.js.map +1 -0
  18. package/dist/clipboard/index.d.ts +5 -0
  19. package/dist/clipboard/index.js +24 -0
  20. package/dist/clipboard/index.js.map +1 -0
  21. package/dist/core/component-ref.d.ts +8 -0
  22. package/dist/core/component-ref.js +15 -0
  23. package/dist/core/component-ref.js.map +1 -0
  24. package/dist/core/components/badge.d.ts +19 -0
  25. package/dist/core/components/badge.js +32 -0
  26. package/dist/core/components/badge.js.map +1 -0
  27. package/dist/core/components/button.d.ts +23 -0
  28. package/dist/core/components/button.js +68 -0
  29. package/dist/core/components/button.js.map +1 -0
  30. package/dist/core/components/card.d.ts +19 -0
  31. package/dist/core/components/card.js +62 -0
  32. package/dist/core/components/card.js.map +1 -0
  33. package/dist/core/components/confirm-dialog.d.ts +13 -0
  34. package/dist/core/components/confirm-dialog.js +47 -0
  35. package/dist/core/components/confirm-dialog.js.map +1 -0
  36. package/dist/core/components/fragment.d.ts +12 -0
  37. package/dist/core/components/fragment.js +62 -0
  38. package/dist/core/components/fragment.js.map +1 -0
  39. package/dist/core/components/grid.d.ts +10 -0
  40. package/dist/core/components/grid.js +16 -0
  41. package/dist/core/components/grid.js.map +1 -0
  42. package/dist/core/components/heading.d.ts +11 -0
  43. package/dist/core/components/heading.js +39 -0
  44. package/dist/core/components/heading.js.map +1 -0
  45. package/dist/core/components/index.d.ts +1 -0
  46. package/dist/core/components/index.js +36 -0
  47. package/dist/core/components/index.js.map +1 -0
  48. package/dist/core/components/link.d.ts +18 -0
  49. package/dist/core/components/link.js +26 -0
  50. package/dist/core/components/link.js.map +1 -0
  51. package/dist/core/components/modal.d.ts +13 -0
  52. package/dist/core/components/modal.js +75 -0
  53. package/dist/core/components/modal.js.map +1 -0
  54. package/dist/core/components/segmented-control.d.ts +16 -0
  55. package/dist/core/components/segmented-control.js +30 -0
  56. package/dist/core/components/segmented-control.js.map +1 -0
  57. package/dist/core/components/segmented-pills.d.ts +13 -0
  58. package/dist/core/components/segmented-pills.js +31 -0
  59. package/dist/core/components/segmented-pills.js.map +1 -0
  60. package/dist/core/components/spinner.d.ts +2 -0
  61. package/dist/core/components/spinner.js +16 -0
  62. package/dist/core/components/spinner.js.map +1 -0
  63. package/dist/core/components/stack.d.ts +13 -0
  64. package/dist/core/components/stack.js +47 -0
  65. package/dist/core/components/stack.js.map +1 -0
  66. package/dist/core/components/tabs.d.ts +22 -0
  67. package/dist/core/components/tabs.js +118 -0
  68. package/dist/core/components/tabs.js.map +1 -0
  69. package/dist/core/components/text.d.ts +11 -0
  70. package/dist/core/components/text.js +18 -0
  71. package/dist/core/components/text.js.map +1 -0
  72. package/dist/core/props.d.ts +14 -0
  73. package/dist/core/props.js +30 -0
  74. package/dist/core/props.js.map +1 -0
  75. package/dist/core/registry.d.ts +26 -0
  76. package/dist/core/registry.js +36 -0
  77. package/dist/core/registry.js.map +1 -0
  78. package/dist/core/renderer.d.ts +16 -0
  79. package/dist/core/renderer.js +61 -0
  80. package/dist/core/renderer.js.map +1 -0
  81. package/dist/core/types.d.ts +55 -0
  82. package/dist/core/types.js +0 -0
  83. package/dist/events/event-bridge.d.ts +14 -0
  84. package/dist/events/event-bridge.js +75 -0
  85. package/dist/events/event-bridge.js.map +1 -0
  86. package/dist/events/event-names.d.ts +21 -0
  87. package/dist/events/event-names.js +22 -0
  88. package/dist/events/event-names.js.map +1 -0
  89. package/dist/form/components/base/checkbox.d.ts +4 -0
  90. package/dist/form/components/base/checkbox.js +22 -0
  91. package/dist/form/components/base/checkbox.js.map +1 -0
  92. package/dist/form/components/base/field.d.ts +9 -0
  93. package/dist/form/components/base/field.js +38 -0
  94. package/dist/form/components/base/field.js.map +1 -0
  95. package/dist/form/components/base/input-error.d.ts +4 -0
  96. package/dist/form/components/base/input-error.js +14 -0
  97. package/dist/form/components/base/input-error.js.map +1 -0
  98. package/dist/form/components/base/input.d.ts +3 -0
  99. package/dist/form/components/base/input.js +16 -0
  100. package/dist/form/components/base/input.js.map +1 -0
  101. package/dist/form/components/base/label.d.ts +4 -0
  102. package/dist/form/components/base/label.js +16 -0
  103. package/dist/form/components/base/label.js.map +1 -0
  104. package/dist/form/components/base/password-input.d.ts +7 -0
  105. package/dist/form/components/base/password-input.js +29 -0
  106. package/dist/form/components/base/password-input.js.map +1 -0
  107. package/dist/form/components/base/submit-button.d.ts +6 -0
  108. package/dist/form/components/base/submit-button.js +46 -0
  109. package/dist/form/components/base/submit-button.js.map +1 -0
  110. package/dist/form/components/base/textarea.d.ts +3 -0
  111. package/dist/form/components/base/textarea.js +15 -0
  112. package/dist/form/components/base/textarea.js.map +1 -0
  113. package/dist/form/components/conditions.d.ts +25 -0
  114. package/dist/form/components/conditions.js +62 -0
  115. package/dist/form/components/conditions.js.map +1 -0
  116. package/dist/form/components/context.d.ts +20 -0
  117. package/dist/form/components/context.js +30 -0
  118. package/dist/form/components/context.js.map +1 -0
  119. package/dist/form/components/fields/checkbox.d.ts +16 -0
  120. package/dist/form/components/fields/checkbox.js +51 -0
  121. package/dist/form/components/fields/checkbox.js.map +1 -0
  122. package/dist/form/components/fields/choice.d.ts +14 -0
  123. package/dist/form/components/fields/choice.js +49 -0
  124. package/dist/form/components/fields/choice.js.map +1 -0
  125. package/dist/form/components/fields/date-input.d.ts +20 -0
  126. package/dist/form/components/fields/date-input.js +33 -0
  127. package/dist/form/components/fields/date-input.js.map +1 -0
  128. package/dist/form/components/fields/hidden-input.d.ts +10 -0
  129. package/dist/form/components/fields/hidden-input.js +12 -0
  130. package/dist/form/components/fields/hidden-input.js.map +1 -0
  131. package/dist/form/components/fields/number-input.d.ts +23 -0
  132. package/dist/form/components/fields/number-input.js +55 -0
  133. package/dist/form/components/fields/number-input.js.map +1 -0
  134. package/dist/form/components/fields/password-input.d.ts +29 -0
  135. package/dist/form/components/fields/password-input.js +73 -0
  136. package/dist/form/components/fields/password-input.js.map +1 -0
  137. package/dist/form/components/fields/rich-editor.d.ts +17 -0
  138. package/dist/form/components/fields/rich-editor.js +302 -0
  139. package/dist/form/components/fields/rich-editor.js.map +1 -0
  140. package/dist/form/components/fields/select.d.ts +23 -0
  141. package/dist/form/components/fields/select.js +182 -0
  142. package/dist/form/components/fields/select.js.map +1 -0
  143. package/dist/form/components/fields/submit-button.d.ts +10 -0
  144. package/dist/form/components/fields/submit-button.js +14 -0
  145. package/dist/form/components/fields/submit-button.js.map +1 -0
  146. package/dist/form/components/fields/text-input.d.ts +21 -0
  147. package/dist/form/components/fields/text-input.js +33 -0
  148. package/dist/form/components/fields/text-input.js.map +1 -0
  149. package/dist/form/components/fields/textarea.d.ts +20 -0
  150. package/dist/form/components/fields/textarea.js +32 -0
  151. package/dist/form/components/fields/textarea.js.map +1 -0
  152. package/dist/form/components/form-transport.d.ts +8 -0
  153. package/dist/form/components/form-transport.js +31 -0
  154. package/dist/form/components/form-transport.js.map +1 -0
  155. package/dist/form/components/form.d.ts +21 -0
  156. package/dist/form/components/form.js +126 -0
  157. package/dist/form/components/form.js.map +1 -0
  158. package/dist/form/components/index.d.ts +11 -0
  159. package/dist/form/components/index.js +12 -0
  160. package/dist/form/components/resolved-nodes.d.ts +6 -0
  161. package/dist/form/components/resolved-nodes.js +20 -0
  162. package/dist/form/components/resolved-nodes.js.map +1 -0
  163. package/dist/form/components/types.d.ts +7 -0
  164. package/dist/form/components/types.js +0 -0
  165. package/dist/form/components/use-controlled-field.d.ts +16 -0
  166. package/dist/form/components/use-controlled-field.js +33 -0
  167. package/dist/form/components/use-controlled-field.js.map +1 -0
  168. package/dist/form/components/use-dependent-field.d.ts +3 -0
  169. package/dist/form/components/use-dependent-field.js +18 -0
  170. package/dist/form/components/use-dependent-field.js.map +1 -0
  171. package/dist/form/components/use-field-commit.d.ts +14 -0
  172. package/dist/form/components/use-field-commit.js +30 -0
  173. package/dist/form/components/use-field-commit.js.map +1 -0
  174. package/dist/form/components/use-form-resolver.d.ts +2 -0
  175. package/dist/form/components/use-form-resolver.js +57 -0
  176. package/dist/form/components/use-form-resolver.js.map +1 -0
  177. package/dist/form/components/values.d.ts +7 -0
  178. package/dist/form/components/values.js +37 -0
  179. package/dist/form/components/values.js.map +1 -0
  180. package/dist/form/index.d.ts +1 -0
  181. package/dist/form/index.js +33 -0
  182. package/dist/form/index.js.map +1 -0
  183. package/dist/form/skeleton.d.ts +2 -0
  184. package/dist/form/skeleton.js +21 -0
  185. package/dist/form/skeleton.js.map +1 -0
  186. package/dist/generated/types.d.ts +17 -0
  187. package/dist/generated/types.js +0 -0
  188. package/dist/icons/default-icons.d.ts +3 -0
  189. package/dist/icons/default-icons.js +44 -0
  190. package/dist/icons/default-icons.js.map +1 -0
  191. package/dist/icons/dynamic-lucide-renderer.d.ts +2 -0
  192. package/dist/icons/dynamic-lucide-renderer.js +18 -0
  193. package/dist/icons/dynamic-lucide-renderer.js.map +1 -0
  194. package/dist/icons/icon-renderer.d.ts +14 -0
  195. package/dist/icons/icon-renderer.js +35 -0
  196. package/dist/icons/icon-renderer.js.map +1 -0
  197. package/dist/icons/index.d.ts +2 -0
  198. package/dist/icons/index.js +2 -0
  199. package/dist/index.d.ts +22 -0
  200. package/dist/index.js +14 -0
  201. package/dist/inertia.d.ts +17 -0
  202. package/dist/inertia.js +26 -0
  203. package/dist/inertia.js.map +1 -0
  204. package/dist/lattice.css +247 -0
  205. package/dist/lib/utils.d.ts +4 -0
  206. package/dist/lib/utils.js +13 -0
  207. package/dist/lib/utils.js.map +1 -0
  208. package/dist/menu/index.d.ts +1 -0
  209. package/dist/menu/index.js +2 -0
  210. package/dist/menu/use-menu.d.ts +2 -0
  211. package/dist/menu/use-menu.js +9 -0
  212. package/dist/menu/use-menu.js.map +1 -0
  213. package/dist/page.d.ts +6 -0
  214. package/dist/page.js +30 -0
  215. package/dist/page.js.map +1 -0
  216. package/dist/provider.d.ts +7 -0
  217. package/dist/provider.js +19 -0
  218. package/dist/provider.js.map +1 -0
  219. package/dist/registry.d.ts +1 -0
  220. package/dist/registry.js +11 -0
  221. package/dist/registry.js.map +1 -0
  222. package/dist/table/bulk.d.ts +18 -0
  223. package/dist/table/bulk.js +44 -0
  224. package/dist/table/bulk.js.map +1 -0
  225. package/dist/table/components/bulk-bar.d.ts +11 -0
  226. package/dist/table/components/bulk-bar.js +76 -0
  227. package/dist/table/components/bulk-bar.js.map +1 -0
  228. package/dist/table/components/column-filter-control.d.ts +14 -0
  229. package/dist/table/components/column-filter-control.js +244 -0
  230. package/dist/table/components/column-filter-control.js.map +1 -0
  231. package/dist/table/components/column-header.d.ts +7 -0
  232. package/dist/table/components/column-header.js +37 -0
  233. package/dist/table/components/column-header.js.map +1 -0
  234. package/dist/table/components/filter-stack-bar.d.ts +7 -0
  235. package/dist/table/components/filter-stack-bar.js +35 -0
  236. package/dist/table/components/filter-stack-bar.js.map +1 -0
  237. package/dist/table/components/filter-value-input.d.ts +11 -0
  238. package/dist/table/components/filter-value-input.js +82 -0
  239. package/dist/table/components/filter-value-input.js.map +1 -0
  240. package/dist/table/components/pagination.d.ts +14 -0
  241. package/dist/table/components/pagination.js +67 -0
  242. package/dist/table/components/pagination.js.map +1 -0
  243. package/dist/table/components/sort-bar.d.ts +7 -0
  244. package/dist/table/components/sort-bar.js +43 -0
  245. package/dist/table/components/sort-bar.js.map +1 -0
  246. package/dist/table/components/table-action-node.d.ts +4 -0
  247. package/dist/table/components/table-action-node.js +24 -0
  248. package/dist/table/components/table-action-node.js.map +1 -0
  249. package/dist/table/components/table-cell.d.ts +5 -0
  250. package/dist/table/components/table-cell.js +63 -0
  251. package/dist/table/components/table-cell.js.map +1 -0
  252. package/dist/table/components/table.d.ts +3 -0
  253. package/dist/table/components/table.js +189 -0
  254. package/dist/table/components/table.js.map +1 -0
  255. package/dist/table/format.d.ts +3 -0
  256. package/dist/table/format.js +41 -0
  257. package/dist/table/format.js.map +1 -0
  258. package/dist/table/index.d.ts +1 -0
  259. package/dist/table/index.js +10 -0
  260. package/dist/table/index.js.map +1 -0
  261. package/dist/table/payload.d.ts +9 -0
  262. package/dist/table/payload.js +46 -0
  263. package/dist/table/payload.js.map +1 -0
  264. package/dist/table/query.d.ts +12 -0
  265. package/dist/table/query.js +83 -0
  266. package/dist/table/query.js.map +1 -0
  267. package/dist/table/types.d.ts +67 -0
  268. package/dist/table/types.js +0 -0
  269. package/dist/table/use-table-selection.d.ts +12 -0
  270. package/dist/table/use-table-selection.js +46 -0
  271. package/dist/table/use-table-selection.js.map +1 -0
  272. package/dist/table/use-table.d.ts +19 -0
  273. package/dist/table/use-table.js +157 -0
  274. package/dist/table/use-table.js.map +1 -0
  275. package/dist/types/index.d.ts +2 -0
  276. package/dist/types/index.js +0 -0
  277. package/package.json +151 -0
@@ -0,0 +1,75 @@
1
+ import { getStringProp } from "../props.js";
2
+ import { Button } from "./button.js";
3
+ import { LATTICE_EVENT } from "../../events/event-names.js";
4
+ import { useEffect, useState } from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { X } from "lucide-react";
7
+ //#region resources/js/core/components/modal.tsx
8
+ function matchesModal(event, modal) {
9
+ const target = event.detail?.modal;
10
+ return target === void 0 || target === modal;
11
+ }
12
+ var ModalComponent = ({ children, node }) => {
13
+ const title = getStringProp(node.props, "title", "Dialog");
14
+ const description = getStringProp(node.props, "description");
15
+ const closeLabel = getStringProp(node.props, "closeLabel", "Close");
16
+ const [isOpen, setIsOpen] = useState(node.props?.open === true);
17
+ const titleId = `${node.id ?? node.key ?? "lattice-modal"}-title`;
18
+ const descriptionId = `${node.id ?? node.key ?? "lattice-modal"}-description`;
19
+ useEffect(() => {
20
+ function open(event) {
21
+ if (node.id && matchesModal(event, node.id)) setIsOpen(true);
22
+ }
23
+ function close(event) {
24
+ if (!node.id || matchesModal(event, node.id)) setIsOpen(false);
25
+ }
26
+ window.addEventListener(LATTICE_EVENT.openModal, open);
27
+ window.addEventListener(LATTICE_EVENT.closeModal, close);
28
+ return () => {
29
+ window.removeEventListener(LATTICE_EVENT.openModal, open);
30
+ window.removeEventListener(LATTICE_EVENT.closeModal, close);
31
+ };
32
+ }, [node.id]);
33
+ if (!isOpen) return null;
34
+ return /* @__PURE__ */ jsx("div", {
35
+ className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4",
36
+ children: /* @__PURE__ */ jsxs("div", {
37
+ "aria-describedby": description ? descriptionId : void 0,
38
+ "aria-labelledby": titleId,
39
+ "aria-modal": "true",
40
+ className: "max-h-[min(680px,calc(100vh-2rem))] w-full max-w-lg overflow-y-auto rounded-lt border border-lt-border bg-lt-bg p-6 shadow-lg",
41
+ role: "dialog",
42
+ children: [/* @__PURE__ */ jsxs("div", {
43
+ className: "flex items-start justify-between gap-4",
44
+ children: [/* @__PURE__ */ jsxs("div", {
45
+ className: "grid gap-2",
46
+ children: [/* @__PURE__ */ jsx("h2", {
47
+ className: "text-lg font-semibold leading-none tracking-tight",
48
+ id: titleId,
49
+ children: title
50
+ }), description && /* @__PURE__ */ jsx("p", {
51
+ className: "text-sm text-lt-muted-fg",
52
+ id: descriptionId,
53
+ children: description
54
+ })]
55
+ }), /* @__PURE__ */ jsx(Button, {
56
+ "aria-label": closeLabel,
57
+ onClick: () => setIsOpen(false),
58
+ size: "icon",
59
+ variant: "ghost",
60
+ children: /* @__PURE__ */ jsx(X, {
61
+ "aria-hidden": "true",
62
+ className: "size-4"
63
+ })
64
+ })]
65
+ }), /* @__PURE__ */ jsx("div", {
66
+ className: "mt-6 space-y-6",
67
+ children
68
+ })]
69
+ })
70
+ });
71
+ };
72
+ //#endregion
73
+ export { ModalComponent as default };
74
+
75
+ //# sourceMappingURL=modal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modal.js","names":[],"sources":["../../../resources/js/core/components/modal.tsx"],"sourcesContent":["import { X } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { Button } from \"@lattice/lattice/core/components/button\";\nimport { getStringProp } from \"@lattice/lattice/core/props\";\nimport type { RendererComponent } from \"@lattice/lattice/core/types\";\nimport { LATTICE_EVENT } from \"@lattice/lattice/events/event-names\";\n\ntype ModalEvent = CustomEvent<{\n modal?: string;\n}>;\n\ndeclare module \"@lattice/lattice/core/types\" {\n interface ComponentProps {\n modal: {\n closeLabel?: string;\n description?: string;\n open?: boolean;\n title?: string;\n };\n }\n}\n\nfunction matchesModal(event: Event, modal: string): boolean {\n const target = (event as ModalEvent).detail?.modal;\n\n return target === undefined || target === modal;\n}\n\nconst ModalComponent: RendererComponent<\"modal\"> = ({ children, node }) => {\n const title = getStringProp(node.props, \"title\", \"Dialog\");\n const description = getStringProp(node.props, \"description\");\n const closeLabel = getStringProp(node.props, \"closeLabel\", \"Close\");\n const [isOpen, setIsOpen] = useState(node.props?.open === true);\n const titleId = `${node.id ?? node.key ?? \"lattice-modal\"}-title`;\n const descriptionId = `${node.id ?? node.key ?? \"lattice-modal\"}-description`;\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 if (!isOpen) {\n return null;\n }\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\">\n <div\n aria-describedby={description ? descriptionId : undefined}\n aria-labelledby={titleId}\n aria-modal=\"true\"\n className=\"max-h-[min(680px,calc(100vh-2rem))] w-full max-w-lg overflow-y-auto rounded-lt border border-lt-border bg-lt-bg p-6 shadow-lg\"\n role=\"dialog\"\n >\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"grid gap-2\">\n <h2 className=\"text-lg font-semibold leading-none tracking-tight\" id={titleId}>\n {title}\n </h2>\n\n {description && (\n <p className=\"text-sm text-lt-muted-fg\" id={descriptionId}>\n {description}\n </p>\n )}\n </div>\n\n <Button\n aria-label={closeLabel}\n onClick={() => setIsOpen(false)}\n size=\"icon\"\n variant=\"ghost\"\n >\n <X aria-hidden=\"true\" className=\"size-4\" />\n </Button>\n </div>\n\n <div className=\"mt-6 space-y-6\">{children}</div>\n </div>\n </div>\n );\n};\n\nexport default ModalComponent;\n"],"mappings":";;;;;;;AAsBA,SAAS,aAAa,OAAc,OAAwB;CAC1D,MAAM,SAAU,MAAqB,QAAQ;CAE7C,OAAO,WAAW,KAAA,KAAa,WAAW;AAC5C;AAEA,IAAM,kBAA8C,EAAE,UAAU,WAAW;CACzE,MAAM,QAAQ,cAAc,KAAK,OAAO,SAAS,QAAQ;CACzD,MAAM,cAAc,cAAc,KAAK,OAAO,aAAa;CAC3D,MAAM,aAAa,cAAc,KAAK,OAAO,cAAc,OAAO;CAClE,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK,OAAO,SAAS,IAAI;CAC9D,MAAM,UAAU,GAAG,KAAK,MAAM,KAAK,OAAO,gBAAgB;CAC1D,MAAM,gBAAgB,GAAG,KAAK,MAAM,KAAK,OAAO,gBAAgB;CAEhE,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,IAAI,CAAC,QACH,OAAO;CAGT,OACE,oBAAC,OAAD;EAAK,WAAU;YACb,qBAAC,OAAD;GACE,oBAAkB,cAAc,gBAAgB,KAAA;GAChD,mBAAiB;GACjB,cAAW;GACX,WAAU;GACV,MAAK;aALP,CAOE,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,qBAAC,OAAD;KAAK,WAAU;eAAf,CACE,oBAAC,MAAD;MAAI,WAAU;MAAoD,IAAI;gBACnE;KACC,CAAA,GAEH,eACC,oBAAC,KAAD;MAAG,WAAU;MAA2B,IAAI;gBACzC;KACA,CAAA,CAEF;QAEL,oBAAC,QAAD;KACE,cAAY;KACZ,eAAe,UAAU,KAAK;KAC9B,MAAK;KACL,SAAQ;eAER,oBAAC,GAAD;MAAG,eAAY;MAAO,WAAU;KAAU,CAAA;IACpC,CAAA,CACL;OAEL,oBAAC,OAAD;IAAK,WAAU;IAAkB;GAAc,CAAA,CAC5C;;CACF,CAAA;AAET"}
@@ -0,0 +1,16 @@
1
+ import { Option } from '../../../../core/props';
2
+ import { RendererComponent } from '../../../../core/types';
3
+ declare module '../../../../core/types' {
4
+ interface ComponentProps {
5
+ "segmented-control": {
6
+ emits?: string;
7
+ label?: string;
8
+ name?: string;
9
+ options?: Option[];
10
+ tabIndex?: number;
11
+ value?: string;
12
+ };
13
+ }
14
+ }
15
+ declare const SegmentedControlComponent: RendererComponent<"segmented-control">;
16
+ export default SegmentedControlComponent;
@@ -0,0 +1,30 @@
1
+ import { getOptionalNumberProp, getOptions, getStringProp } from "../props.js";
2
+ import { SegmentedPills } from "./segmented-pills.js";
3
+ import { useState } from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region resources/js/core/components/segmented-control.tsx
6
+ var SegmentedControlComponent = ({ node }) => {
7
+ const options = getOptions(node.props);
8
+ const name = getStringProp(node.props, "name");
9
+ const emits = getStringProp(node.props, "emits");
10
+ const [value, setValue] = useState(getStringProp(node.props, "value") || options[0]?.value || "");
11
+ if (options.length === 0) return null;
12
+ function select(next) {
13
+ setValue(next);
14
+ if (emits) window.dispatchEvent(new CustomEvent(emits, { detail: {
15
+ name,
16
+ value: next
17
+ } }));
18
+ }
19
+ return /* @__PURE__ */ jsx(SegmentedPills, {
20
+ ariaLabel: getStringProp(node.props, "label"),
21
+ onSelect: select,
22
+ options,
23
+ tabIndex: getOptionalNumberProp(node.props, "tabIndex"),
24
+ value
25
+ });
26
+ };
27
+ //#endregion
28
+ export { SegmentedControlComponent as default };
29
+
30
+ //# sourceMappingURL=segmented-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segmented-control.js","names":[],"sources":["../../../resources/js/core/components/segmented-control.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport {\n type Option,\n getOptionalNumberProp,\n getOptions,\n getStringProp,\n} from \"@lattice/lattice/core/props\";\nimport type { RendererComponent } from \"@lattice/lattice/core/types\";\nimport { SegmentedPills } from \"./segmented-pills\";\n\ndeclare module \"@lattice/lattice/core/types\" {\n interface ComponentProps {\n \"segmented-control\": {\n emits?: string;\n label?: string;\n name?: string;\n options?: Option[];\n tabIndex?: number;\n value?: string;\n };\n }\n}\n\nconst SegmentedControlComponent: RendererComponent<\"segmented-control\"> = ({ node }) => {\n const options = getOptions(node.props);\n const name = getStringProp(node.props, \"name\");\n const emits = getStringProp(node.props, \"emits\");\n const [value, setValue] = useState(getStringProp(node.props, \"value\") || options[0]?.value || \"\");\n\n if (options.length === 0) {\n return null;\n }\n\n function select(next: string): void {\n setValue(next);\n\n if (emits) {\n window.dispatchEvent(new CustomEvent(emits, { detail: { name, value: next } }));\n }\n }\n\n return (\n <SegmentedPills\n ariaLabel={getStringProp(node.props, \"label\")}\n onSelect={select}\n options={options}\n tabIndex={getOptionalNumberProp(node.props, \"tabIndex\")}\n value={value}\n />\n );\n};\n\nexport default SegmentedControlComponent;\n"],"mappings":";;;;;AAuBA,IAAM,6BAAqE,EAAE,WAAW;CACtF,MAAM,UAAU,WAAW,KAAK,KAAK;CACrC,MAAM,OAAO,cAAc,KAAK,OAAO,MAAM;CAC7C,MAAM,QAAQ,cAAc,KAAK,OAAO,OAAO;CAC/C,MAAM,CAAC,OAAO,YAAY,SAAS,cAAc,KAAK,OAAO,OAAO,KAAK,QAAQ,IAAI,SAAS,EAAE;CAEhG,IAAI,QAAQ,WAAW,GACrB,OAAO;CAGT,SAAS,OAAO,MAAoB;EAClC,SAAS,IAAI;EAEb,IAAI,OACF,OAAO,cAAc,IAAI,YAAY,OAAO,EAAE,QAAQ;GAAE;GAAM,OAAO;EAAK,EAAE,CAAC,CAAC;CAElF;CAEA,OACE,oBAAC,gBAAD;EACE,WAAW,cAAc,KAAK,OAAO,OAAO;EAC5C,UAAU;EACD;EACT,UAAU,sBAAsB,KAAK,OAAO,UAAU;EAC/C;CACR,CAAA;AAEL"}
@@ -0,0 +1,13 @@
1
+ import { Option } from '../../../../core/props';
2
+ /**
3
+ * Presentational segmented pill group. Used by the form choice field (bound to a
4
+ * form value) and the core segmented control (standalone, emits an event).
5
+ */
6
+ export declare function SegmentedPills({ ariaLabel, disabled, onSelect, options, tabIndex, value, }: {
7
+ ariaLabel?: string;
8
+ disabled?: boolean;
9
+ onSelect: (value: string) => void;
10
+ options: Option[];
11
+ tabIndex?: number;
12
+ value: string;
13
+ }): import("react").JSX.Element;
@@ -0,0 +1,31 @@
1
+ import { cn } from "../../lib/utils.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region resources/js/core/components/segmented-pills.tsx
4
+ /**
5
+ * Presentational segmented pill group. Used by the form choice field (bound to a
6
+ * form value) and the core segmented control (standalone, emits an event).
7
+ */
8
+ function SegmentedPills({ ariaLabel, disabled = false, onSelect, options, tabIndex, value }) {
9
+ return /* @__PURE__ */ jsx("div", {
10
+ "aria-label": ariaLabel,
11
+ className: "inline-flex w-fit max-w-full gap-1 overflow-x-auto rounded-lt bg-lt-muted p-1",
12
+ role: "radiogroup",
13
+ children: options.map((option) => {
14
+ const isSelected = value === option.value;
15
+ return /* @__PURE__ */ jsx("button", {
16
+ "aria-checked": isSelected,
17
+ className: cn("whitespace-nowrap rounded-lt-sm px-3 py-1.5 text-sm font-medium transition-colors", isSelected ? "bg-lt-bg text-lt-fg shadow-xs" : "text-lt-muted-fg hover:bg-lt-bg/60 hover:text-lt-fg", disabled && "cursor-not-allowed opacity-60"),
18
+ disabled,
19
+ onClick: () => onSelect(option.value),
20
+ role: "radio",
21
+ tabIndex,
22
+ type: "button",
23
+ children: option.label
24
+ }, option.value);
25
+ })
26
+ });
27
+ }
28
+ //#endregion
29
+ export { SegmentedPills };
30
+
31
+ //# sourceMappingURL=segmented-pills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segmented-pills.js","names":[],"sources":["../../../resources/js/core/components/segmented-pills.tsx"],"sourcesContent":["import type { Option } from \"@lattice/lattice/core/props\";\nimport { cn } from \"@lattice/lattice/lib/utils\";\n\n/**\n * Presentational segmented pill group. Used by the form choice field (bound to a\n * form value) and the core segmented control (standalone, emits an event).\n */\nexport function SegmentedPills({\n ariaLabel,\n disabled = false,\n onSelect,\n options,\n tabIndex,\n value,\n}: {\n ariaLabel?: string;\n disabled?: boolean;\n onSelect: (value: string) => void;\n options: Option[];\n tabIndex?: number;\n value: string;\n}) {\n return (\n <div\n aria-label={ariaLabel}\n className=\"inline-flex w-fit max-w-full gap-1 overflow-x-auto rounded-lt bg-lt-muted p-1\"\n role=\"radiogroup\"\n >\n {options.map((option) => {\n const isSelected = value === option.value;\n\n return (\n <button\n aria-checked={isSelected}\n className={cn(\n \"whitespace-nowrap rounded-lt-sm px-3 py-1.5 text-sm font-medium transition-colors\",\n isSelected\n ? \"bg-lt-bg text-lt-fg shadow-xs\"\n : \"text-lt-muted-fg hover:bg-lt-bg/60 hover:text-lt-fg\",\n disabled && \"cursor-not-allowed opacity-60\",\n )}\n disabled={disabled}\n key={option.value}\n onClick={() => onSelect(option.value)}\n role=\"radio\"\n tabIndex={tabIndex}\n type=\"button\"\n >\n {option.label}\n </button>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;;;;;AAOA,SAAgB,eAAe,EAC7B,WACA,WAAW,OACX,UACA,SACA,UACA,SAQC;CACD,OACE,oBAAC,OAAD;EACE,cAAY;EACZ,WAAU;EACV,MAAK;YAEJ,QAAQ,KAAK,WAAW;GACvB,MAAM,aAAa,UAAU,OAAO;GAEpC,OACE,oBAAC,UAAD;IACE,gBAAc;IACd,WAAW,GACT,qFACA,aACI,kCACA,uDACJ,YAAY,+BACd;IACU;IAEV,eAAe,SAAS,OAAO,KAAK;IACpC,MAAK;IACK;IACV,MAAK;cAEJ,OAAO;GACF,GAPD,OAAO,KAON;EAEZ,CAAC;CACE,CAAA;AAET"}
@@ -0,0 +1,2 @@
1
+ declare function Spinner({ className, ...props }: React.ComponentProps<"svg">): import("react").JSX.Element;
2
+ export { Spinner };
@@ -0,0 +1,16 @@
1
+ import { cn } from "../../lib/utils.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { Loader2Icon } from "lucide-react";
4
+ //#region resources/js/core/components/spinner.tsx
5
+ function Spinner({ className, ...props }) {
6
+ return /* @__PURE__ */ jsx(Loader2Icon, {
7
+ role: "status",
8
+ "aria-label": "Loading",
9
+ className: cn("size-4 animate-spin", className),
10
+ ...props
11
+ });
12
+ }
13
+ //#endregion
14
+ export { Spinner };
15
+
16
+ //# sourceMappingURL=spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.js","names":[],"sources":["../../../resources/js/core/components/spinner.tsx"],"sourcesContent":["import { Loader2Icon } from \"lucide-react\";\n\nimport { cn } from \"@lattice/lattice/lib/utils\";\n\nfunction Spinner({ className, ...props }: React.ComponentProps<\"svg\">) {\n return (\n <Loader2Icon\n role=\"status\"\n aria-label=\"Loading\"\n className={cn(\"size-4 animate-spin\", className)}\n {...props}\n />\n );\n}\n\nexport { Spinner };\n"],"mappings":";;;;AAIA,SAAS,QAAQ,EAAE,WAAW,GAAG,SAAsC;CACrE,OACE,oBAAC,aAAD;EACE,MAAK;EACL,cAAW;EACX,WAAW,GAAG,uBAAuB,SAAS;EAC9C,GAAI;CACL,CAAA;AAEL"}
@@ -0,0 +1,13 @@
1
+ import { RendererComponent } from '../../../../core/types';
2
+ declare module '../../../../core/types' {
3
+ interface ComponentProps {
4
+ stack: {
5
+ align?: string;
6
+ direction?: string;
7
+ gap?: string;
8
+ width?: string;
9
+ };
10
+ }
11
+ }
12
+ declare const StackComponent: RendererComponent<"stack">;
13
+ export default StackComponent;
@@ -0,0 +1,47 @@
1
+ import { cn } from "../../lib/utils.js";
2
+ import { getStringProp } from "../props.js";
3
+ import { jsx } from "react/jsx-runtime";
4
+ //#region resources/js/core/components/stack.tsx
5
+ var gridAlignments = {
6
+ center: "justify-items-center text-center",
7
+ start: "justify-items-start text-left",
8
+ stretch: "justify-items-stretch"
9
+ };
10
+ var flexAlignments = {
11
+ center: "items-center justify-center text-center",
12
+ start: "items-center justify-start text-left",
13
+ stretch: "items-stretch justify-stretch"
14
+ };
15
+ var stackGaps = {
16
+ xs: "gap-1",
17
+ lg: "gap-6",
18
+ md: "gap-4",
19
+ sm: "gap-2",
20
+ xl: "gap-8"
21
+ };
22
+ var stackWidths = {
23
+ full: "w-full",
24
+ lg: "mx-auto w-full max-w-4xl",
25
+ md: "mx-auto w-full max-w-2xl",
26
+ sm: "mx-auto w-full max-w-md"
27
+ };
28
+ var StackComponent = ({ children, node }) => {
29
+ const align = getStringProp(node.props, "align", "stretch");
30
+ const direction = getStringProp(node.props, "direction", "column");
31
+ const gap = getStringProp(node.props, "gap", "md");
32
+ const width = getStringProp(node.props, "width", "full");
33
+ if (direction === "row") return /* @__PURE__ */ jsx("div", {
34
+ "data-lattice-component": node.id,
35
+ className: cn("flex flex-wrap", flexAlignments[align] ?? flexAlignments.stretch, stackGaps[gap] ?? stackGaps.md, stackWidths[width] ?? stackWidths.full),
36
+ children
37
+ });
38
+ return /* @__PURE__ */ jsx("div", {
39
+ "data-lattice-component": node.id,
40
+ className: cn("grid", gridAlignments[align] ?? gridAlignments.stretch, stackGaps[gap] ?? stackGaps.md, stackWidths[width] ?? stackWidths.full),
41
+ children
42
+ });
43
+ };
44
+ //#endregion
45
+ export { StackComponent as default };
46
+
47
+ //# sourceMappingURL=stack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack.js","names":[],"sources":["../../../resources/js/core/components/stack.tsx"],"sourcesContent":["import { getStringProp } from \"@lattice/lattice/core/props\";\nimport type { RendererComponent } from \"@lattice/lattice/core/types\";\nimport { cn } from \"@lattice/lattice/lib/utils\";\n\ndeclare module \"@lattice/lattice/core/types\" {\n interface ComponentProps {\n stack: {\n align?: string;\n direction?: string;\n gap?: string;\n width?: string;\n };\n }\n}\n\nconst gridAlignments: Record<string, string> = {\n center: \"justify-items-center text-center\",\n start: \"justify-items-start text-left\",\n stretch: \"justify-items-stretch\",\n};\n\nconst flexAlignments: Record<string, string> = {\n center: \"items-center justify-center text-center\",\n start: \"items-center justify-start text-left\",\n stretch: \"items-stretch justify-stretch\",\n};\n\nconst stackGaps: Record<string, string> = {\n xs: \"gap-1\",\n lg: \"gap-6\",\n md: \"gap-4\",\n sm: \"gap-2\",\n xl: \"gap-8\",\n};\n\nconst stackWidths: Record<string, string> = {\n full: \"w-full\",\n lg: \"mx-auto w-full max-w-4xl\",\n md: \"mx-auto w-full max-w-2xl\",\n sm: \"mx-auto w-full max-w-md\",\n};\n\nconst StackComponent: RendererComponent<\"stack\"> = ({ children, node }) => {\n const align = getStringProp(node.props, \"align\", \"stretch\");\n const direction = getStringProp(node.props, \"direction\", \"column\");\n const gap = getStringProp(node.props, \"gap\", \"md\");\n const width = getStringProp(node.props, \"width\", \"full\");\n\n if (direction === \"row\") {\n return (\n <div\n data-lattice-component={node.id}\n className={cn(\n \"flex flex-wrap\",\n flexAlignments[align] ?? flexAlignments.stretch,\n stackGaps[gap] ?? stackGaps.md,\n stackWidths[width] ?? stackWidths.full,\n )}\n >\n {children}\n </div>\n );\n }\n\n return (\n <div\n data-lattice-component={node.id}\n className={cn(\n \"grid\",\n gridAlignments[align] ?? gridAlignments.stretch,\n stackGaps[gap] ?? stackGaps.md,\n stackWidths[width] ?? stackWidths.full,\n )}\n >\n {children}\n </div>\n );\n};\n\nexport default StackComponent;\n"],"mappings":";;;;AAeA,IAAM,iBAAyC;CAC7C,QAAQ;CACR,OAAO;CACP,SAAS;AACX;AAEA,IAAM,iBAAyC;CAC7C,QAAQ;CACR,OAAO;CACP,SAAS;AACX;AAEA,IAAM,YAAoC;CACxC,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;AAEA,IAAM,cAAsC;CAC1C,MAAM;CACN,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;AAEA,IAAM,kBAA8C,EAAE,UAAU,WAAW;CACzE,MAAM,QAAQ,cAAc,KAAK,OAAO,SAAS,SAAS;CAC1D,MAAM,YAAY,cAAc,KAAK,OAAO,aAAa,QAAQ;CACjE,MAAM,MAAM,cAAc,KAAK,OAAO,OAAO,IAAI;CACjD,MAAM,QAAQ,cAAc,KAAK,OAAO,SAAS,MAAM;CAEvD,IAAI,cAAc,OAChB,OACE,oBAAC,OAAD;EACE,0BAAwB,KAAK;EAC7B,WAAW,GACT,kBACA,eAAe,UAAU,eAAe,SACxC,UAAU,QAAQ,UAAU,IAC5B,YAAY,UAAU,YAAY,IACpC;EAEC;CACE,CAAA;CAIT,OACE,oBAAC,OAAD;EACE,0BAAwB,KAAK;EAC7B,WAAW,GACT,QACA,eAAe,UAAU,eAAe,SACxC,UAAU,QAAQ,UAAU,IAC5B,YAAY,UAAU,YAAY,IACpC;EAEC;CACE,CAAA;AAET"}
@@ -0,0 +1,22 @@
1
+ import { RendererComponent } from '../../../../core/types';
2
+ declare module '../../../../core/types' {
3
+ interface ComponentProps {
4
+ tab: {
5
+ confirm?: {
6
+ redirectUrl?: string;
7
+ required?: boolean;
8
+ timeout?: number;
9
+ };
10
+ label?: string;
11
+ value?: string;
12
+ };
13
+ tabs: {
14
+ activeValue?: string;
15
+ defaultValue?: string;
16
+ queryKey?: string;
17
+ };
18
+ }
19
+ }
20
+ export declare const TabsComponent: RendererComponent<"tabs">;
21
+ declare const TabComponent: RendererComponent<"tab">;
22
+ export default TabComponent;
@@ -0,0 +1,118 @@
1
+ import { cn } from "../../lib/utils.js";
2
+ import { getStringProp } from "../props.js";
3
+ import { createContext, useContext, useEffect, useMemo, useState } from "react";
4
+ import { router } from "@inertiajs/react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ //#region resources/js/core/components/tabs.tsx
7
+ var TabsContext = createContext(null);
8
+ function useTabsContext() {
9
+ const context = useContext(TabsContext);
10
+ if (!context) return {
11
+ activeValue: "",
12
+ setActiveValue: () => {}
13
+ };
14
+ return context;
15
+ }
16
+ function getTabs(node) {
17
+ return (node.children ?? []).filter((child) => child.type === "tab").map((child) => ({
18
+ confirm: getConfirmationProp(child.props),
19
+ label: getStringProp(child.props, "label"),
20
+ value: getStringProp(child.props, "value")
21
+ })).filter((tab) => tab.value !== "");
22
+ }
23
+ function getConfirmationProp(props) {
24
+ const confirm = props?.confirm;
25
+ if (!confirm || typeof confirm !== "object" || Array.isArray(confirm)) return;
26
+ return { required: confirm.required === true };
27
+ }
28
+ function queryValue(queryKey, tabs) {
29
+ if (typeof window === "undefined") return null;
30
+ const value = new URLSearchParams(window.location.search).get(queryKey);
31
+ if (!value || !tabs.some((tab) => tab.value === value)) return null;
32
+ return value;
33
+ }
34
+ function replaceQueryValue(queryKey, value) {
35
+ if (typeof window === "undefined") return;
36
+ const url = new URL(window.location.href);
37
+ url.searchParams.set(queryKey, value);
38
+ window.history.replaceState(window.history.state, "", `${url.pathname}${url.search}${url.hash}`);
39
+ }
40
+ function queryUrl(queryKey, value) {
41
+ if (typeof window === "undefined") return "";
42
+ const url = new URL(window.location.href);
43
+ url.searchParams.set(queryKey, value);
44
+ return `${url.pathname}${url.search}${url.hash}`;
45
+ }
46
+ var TabsComponent = ({ children, node }) => {
47
+ const tabs = useMemo(() => getTabs(node), [node]);
48
+ const firstValue = tabs[0]?.value ?? "";
49
+ const queryKey = getStringProp(node.props, "queryKey", "tabs");
50
+ const serverActiveValue = getStringProp(node.props, "activeValue", "");
51
+ const defaultValue = getStringProp(node.props, "defaultValue", firstValue);
52
+ const [activeValue, setActiveTabValue] = useState(() => serverActiveValue || (queryValue(queryKey, tabs) ?? defaultValue) || firstValue);
53
+ function selectTab(tab) {
54
+ if (tab.confirm?.required) {
55
+ router.visit(queryUrl(queryKey, tab.value), { preserveScroll: true });
56
+ return;
57
+ }
58
+ setActiveTabValue(tab.value);
59
+ replaceQueryValue(queryKey, tab.value);
60
+ }
61
+ function selectTabValue(value) {
62
+ const tab = tabs.find((item) => item.value === value);
63
+ if (tab) selectTab(tab);
64
+ }
65
+ return /* @__PURE__ */ jsx(TabsContext.Provider, {
66
+ value: {
67
+ activeValue,
68
+ setActiveValue: selectTabValue
69
+ },
70
+ children: /* @__PURE__ */ jsxs("div", {
71
+ className: "grid gap-6",
72
+ "data-lattice-tabs": node.key ?? node.id,
73
+ children: [/* @__PURE__ */ jsx("div", {
74
+ "aria-label": getStringProp(node.props, "label", "Tabs"),
75
+ className: "inline-flex w-fit max-w-full gap-1 overflow-x-auto rounded-lt bg-lt-muted p-1",
76
+ role: "tablist",
77
+ children: tabs.map((tab) => {
78
+ const isActive = activeValue === tab.value;
79
+ return /* @__PURE__ */ jsx("button", {
80
+ "aria-controls": `${tab.value}-panel`,
81
+ "aria-selected": isActive,
82
+ className: cn("whitespace-nowrap rounded-lt-sm px-3 py-1.5 text-sm font-medium transition-colors", isActive ? "bg-lt-bg text-lt-fg shadow-xs" : "text-lt-muted-fg hover:bg-lt-bg/60 hover:text-lt-fg"),
83
+ id: `${tab.value}-tab`,
84
+ onClick: () => selectTab(tab),
85
+ role: "tab",
86
+ type: "button",
87
+ children: tab.label
88
+ }, tab.value);
89
+ })
90
+ }), /* @__PURE__ */ jsx("div", {
91
+ className: "min-w-0",
92
+ children
93
+ })]
94
+ })
95
+ });
96
+ };
97
+ var TabComponent = ({ children, node }) => {
98
+ const { activeValue } = useTabsContext();
99
+ const value = getStringProp(node.props, "value");
100
+ const isActive = activeValue === value;
101
+ const [hasOpened, setHasOpened] = useState(isActive);
102
+ useEffect(() => {
103
+ if (isActive) setHasOpened(true);
104
+ }, [isActive]);
105
+ return /* @__PURE__ */ jsx("section", {
106
+ "aria-labelledby": `${value}-tab`,
107
+ className: cn("space-y-8", !isActive && "hidden"),
108
+ hidden: !isActive,
109
+ id: `${value}-panel`,
110
+ role: "tabpanel",
111
+ tabIndex: 0,
112
+ children: hasOpened ? children : null
113
+ });
114
+ };
115
+ //#endregion
116
+ export { TabsComponent, TabComponent as default };
117
+
118
+ //# sourceMappingURL=tabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabs.js","names":[],"sources":["../../../resources/js/core/components/tabs.tsx"],"sourcesContent":["import { router } from \"@inertiajs/react\";\nimport { createContext, useContext, useEffect, useMemo, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { getStringProp } from \"@lattice/lattice/core/props\";\nimport type { Node, RendererComponent } from \"@lattice/lattice/core/types\";\nimport { cn } from \"@lattice/lattice/lib/utils\";\n\ntype TabsContextValue = {\n activeValue: string;\n setActiveValue: (value: string) => void;\n};\n\nconst TabsContext = createContext<TabsContextValue | null>(null);\n\nfunction useTabsContext(): TabsContextValue {\n const context = useContext(TabsContext);\n\n if (!context) {\n return {\n activeValue: \"\",\n setActiveValue: () => {},\n };\n }\n\n return context;\n}\n\ntype TabItem = {\n confirm?: {\n required?: boolean;\n };\n label: string;\n value: string;\n};\n\nfunction getTabs(node: Node): TabItem[] {\n return (node.children ?? [])\n .filter((child) => child.type === \"tab\")\n .map((child) => ({\n confirm: getConfirmationProp(child.props),\n label: getStringProp(child.props, \"label\"),\n value: getStringProp(child.props, \"value\"),\n }))\n .filter((tab) => tab.value !== \"\");\n}\n\nfunction getConfirmationProp(props: Node[\"props\"]): TabItem[\"confirm\"] {\n const confirm = props?.confirm;\n\n if (!confirm || typeof confirm !== \"object\" || Array.isArray(confirm)) {\n return undefined;\n }\n\n const confirmation = confirm as Record<string, unknown>;\n\n return {\n required: confirmation.required === true,\n };\n}\n\nfunction queryValue(queryKey: string, tabs: Array<{ value: string }>): string | null {\n if (typeof window === \"undefined\") {\n return null;\n }\n\n const value = new URLSearchParams(window.location.search).get(queryKey);\n\n if (!value || !tabs.some((tab) => tab.value === value)) {\n return null;\n }\n\n return value;\n}\n\nfunction replaceQueryValue(queryKey: string, value: string): void {\n if (typeof window === \"undefined\") {\n return;\n }\n\n const url = new URL(window.location.href);\n url.searchParams.set(queryKey, value);\n window.history.replaceState(window.history.state, \"\", `${url.pathname}${url.search}${url.hash}`);\n}\n\nfunction queryUrl(queryKey: string, value: string): string {\n if (typeof window === \"undefined\") {\n return \"\";\n }\n\n const url = new URL(window.location.href);\n url.searchParams.set(queryKey, value);\n\n return `${url.pathname}${url.search}${url.hash}`;\n}\n\ndeclare module \"@lattice/lattice/core/types\" {\n interface ComponentProps {\n tab: {\n confirm?: {\n redirectUrl?: string;\n required?: boolean;\n timeout?: number;\n };\n label?: string;\n value?: string;\n };\n tabs: {\n activeValue?: string;\n defaultValue?: string;\n queryKey?: string;\n };\n }\n}\n\nexport const TabsComponent: RendererComponent<\"tabs\"> = ({ children, node }) => {\n const tabs = useMemo(() => getTabs(node), [node]);\n const firstValue = tabs[0]?.value ?? \"\";\n const queryKey = getStringProp(node.props, \"queryKey\", \"tabs\");\n const serverActiveValue = getStringProp(node.props, \"activeValue\", \"\");\n const defaultValue = getStringProp(node.props, \"defaultValue\", firstValue);\n const [activeValue, setActiveTabValue] = useState(\n () => serverActiveValue || (queryValue(queryKey, tabs) ?? defaultValue) || firstValue,\n );\n\n function selectTab(tab: TabItem): void {\n if (tab.confirm?.required) {\n router.visit(queryUrl(queryKey, tab.value), {\n preserveScroll: true,\n });\n\n return;\n }\n\n setActiveTabValue(tab.value);\n replaceQueryValue(queryKey, tab.value);\n }\n\n function selectTabValue(value: string): void {\n const tab = tabs.find((item) => item.value === value);\n\n if (tab) {\n selectTab(tab);\n }\n }\n\n return (\n <TabsContext.Provider value={{ activeValue, setActiveValue: selectTabValue }}>\n <div className=\"grid gap-6\" data-lattice-tabs={node.key ?? node.id}>\n <div\n aria-label={getStringProp(node.props, \"label\", \"Tabs\")}\n className=\"inline-flex w-fit max-w-full gap-1 overflow-x-auto rounded-lt bg-lt-muted p-1\"\n role=\"tablist\"\n >\n {tabs.map((tab) => {\n const isActive = activeValue === tab.value;\n\n return (\n <button\n aria-controls={`${tab.value}-panel`}\n aria-selected={isActive}\n className={cn(\n \"whitespace-nowrap rounded-lt-sm px-3 py-1.5 text-sm font-medium transition-colors\",\n isActive\n ? \"bg-lt-bg text-lt-fg shadow-xs\"\n : \"text-lt-muted-fg hover:bg-lt-bg/60 hover:text-lt-fg\",\n )}\n id={`${tab.value}-tab`}\n key={tab.value}\n onClick={() => selectTab(tab)}\n role=\"tab\"\n type=\"button\"\n >\n {tab.label}\n </button>\n );\n })}\n </div>\n\n <div className=\"min-w-0\">{children}</div>\n </div>\n </TabsContext.Provider>\n );\n};\n\nconst TabComponent: RendererComponent<\"tab\"> = ({ children, node }) => {\n const { activeValue } = useTabsContext();\n const value = getStringProp(node.props, \"value\");\n const isActive = activeValue === value;\n const [hasOpened, setHasOpened] = useState(isActive);\n\n useEffect(() => {\n if (isActive) {\n setHasOpened(true);\n }\n }, [isActive]);\n\n return (\n <section\n aria-labelledby={`${value}-tab`}\n className={cn(\"space-y-8\", !isActive && \"hidden\")}\n hidden={!isActive}\n id={`${value}-panel`}\n role=\"tabpanel\"\n tabIndex={0}\n >\n {hasOpened ? (children as ReactNode) : null}\n </section>\n );\n};\n\nexport default TabComponent;\n"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { RendererComponent } from '../../../../core/types';
2
+ declare module '../../../../core/types' {
3
+ interface ComponentProps {
4
+ text: {
5
+ align?: string;
6
+ text?: string;
7
+ };
8
+ }
9
+ }
10
+ declare const TextComponent: RendererComponent<"text">;
11
+ export default TextComponent;
@@ -0,0 +1,18 @@
1
+ import { cn } from "../../lib/utils.js";
2
+ import { getStringProp } from "../props.js";
3
+ import { jsx } from "react/jsx-runtime";
4
+ //#region resources/js/core/components/text.tsx
5
+ var textAlignments = {
6
+ center: "text-center",
7
+ left: "text-left"
8
+ };
9
+ var TextComponent = ({ node }) => {
10
+ return /* @__PURE__ */ jsx("p", {
11
+ className: cn("max-w-2xl text-base leading-7 text-lt-muted-fg", textAlignments[getStringProp(node.props, "align", "left")] ?? textAlignments.left),
12
+ children: getStringProp(node.props, "text")
13
+ });
14
+ };
15
+ //#endregion
16
+ export { TextComponent as default };
17
+
18
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","names":[],"sources":["../../../resources/js/core/components/text.tsx"],"sourcesContent":["import { getStringProp } from \"@lattice/lattice/core/props\";\nimport type { RendererComponent } from \"@lattice/lattice/core/types\";\nimport { cn } from \"@lattice/lattice/lib/utils\";\n\ndeclare module \"@lattice/lattice/core/types\" {\n interface ComponentProps {\n text: {\n align?: string;\n text?: string;\n };\n }\n}\n\nconst textAlignments: Record<string, string> = {\n center: \"text-center\",\n left: \"text-left\",\n};\n\nconst TextComponent: RendererComponent<\"text\"> = ({ node }) => {\n const align = getStringProp(node.props, \"align\", \"left\");\n\n return (\n <p\n className={cn(\n \"max-w-2xl text-base leading-7 text-lt-muted-fg\",\n textAlignments[align] ?? textAlignments.left,\n )}\n >\n {getStringProp(node.props, \"text\")}\n </p>\n );\n};\n\nexport default TextComponent;\n"],"mappings":";;;;AAaA,IAAM,iBAAyC;CAC7C,QAAQ;CACR,MAAM;AACR;AAEA,IAAM,iBAA4C,EAAE,WAAW;CAG7D,OACE,oBAAC,KAAD;EACE,WAAW,GACT,kDACA,eANQ,cAAc,KAAK,OAAO,SAAS,MAM5B,MAAU,eAAe,IAC1C;YAEC,cAAc,KAAK,OAAO,MAAM;CAChC,CAAA;AAEP"}
@@ -0,0 +1,14 @@
1
+ import { NodeProps } from './types';
2
+ export type Option = {
3
+ label: string;
4
+ value: string;
5
+ };
6
+ /**
7
+ * Read and validate an `options` prop, keeping only well-formed `{ label, value }`
8
+ * entries. Shared by the choice/select form fields and the segmented control.
9
+ */
10
+ export declare function getOptions(props: NodeProps | undefined): Option[];
11
+ export declare function getStringProp(props: NodeProps | undefined, name: string, fallback?: string): string;
12
+ export declare function getNumberProp(props: NodeProps | undefined, name: string, fallback: number): number;
13
+ export declare function getOptionalNumberProp(props: NodeProps | undefined, name: string): number | undefined;
14
+ export declare function getBooleanProp(props: NodeProps | undefined, name: string, fallback?: boolean): boolean;
@@ -0,0 +1,30 @@
1
+ //#region resources/js/core/props.ts
2
+ /**
3
+ * Read and validate an `options` prop, keeping only well-formed `{ label, value }`
4
+ * entries. Shared by the choice/select form fields and the segmented control.
5
+ */
6
+ function getOptions(props) {
7
+ const value = props?.options;
8
+ if (!Array.isArray(value)) return [];
9
+ return value.filter((option) => typeof option === "object" && option !== null && typeof option.label === "string" && typeof option.value === "string");
10
+ }
11
+ function getStringProp(props, name, fallback = "") {
12
+ const value = props?.[name];
13
+ return typeof value === "string" ? value : fallback;
14
+ }
15
+ function getNumberProp(props, name, fallback) {
16
+ const value = props?.[name];
17
+ return typeof value === "number" ? value : fallback;
18
+ }
19
+ function getOptionalNumberProp(props, name) {
20
+ const value = props?.[name];
21
+ return typeof value === "number" ? value : void 0;
22
+ }
23
+ function getBooleanProp(props, name, fallback = false) {
24
+ const value = props?.[name];
25
+ return typeof value === "boolean" ? value : fallback;
26
+ }
27
+ //#endregion
28
+ export { getBooleanProp, getNumberProp, getOptionalNumberProp, getOptions, getStringProp };
29
+
30
+ //# sourceMappingURL=props.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"props.js","names":[],"sources":["../../resources/js/core/props.ts"],"sourcesContent":["import type { NodeProps } from \"./types\";\n\nexport type Option = {\n label: string;\n value: string;\n};\n\n/**\n * Read and validate an `options` prop, keeping only well-formed `{ label, value }`\n * entries. Shared by the choice/select form fields and the segmented control.\n */\nexport function getOptions(props: NodeProps | undefined): Option[] {\n const value = props?.options;\n\n if (!Array.isArray(value)) {\n return [];\n }\n\n return value.filter(\n (option): option is Option =>\n typeof option === \"object\" &&\n option !== null &&\n typeof option.label === \"string\" &&\n typeof option.value === \"string\",\n );\n}\n\nexport function getStringProp(props: NodeProps | undefined, name: string, fallback = \"\") {\n const value = props?.[name];\n\n return typeof value === \"string\" ? value : fallback;\n}\n\nexport function getNumberProp(props: NodeProps | undefined, name: string, fallback: number) {\n const value = props?.[name];\n\n return typeof value === \"number\" ? value : fallback;\n}\n\nexport function getOptionalNumberProp(props: NodeProps | undefined, name: string) {\n const value = props?.[name];\n\n return typeof value === \"number\" ? value : undefined;\n}\n\nexport function getBooleanProp(props: NodeProps | undefined, name: string, fallback = false) {\n const value = props?.[name];\n\n return typeof value === \"boolean\" ? value : fallback;\n}\n"],"mappings":";;;;;AAWA,SAAgB,WAAW,OAAwC;CACjE,MAAM,QAAQ,OAAO;CAErB,IAAI,CAAC,MAAM,QAAQ,KAAK,GACtB,OAAO,CAAC;CAGV,OAAO,MAAM,QACV,WACC,OAAO,WAAW,YAClB,WAAW,QACX,OAAO,OAAO,UAAU,YACxB,OAAO,OAAO,UAAU,QAC5B;AACF;AAEA,SAAgB,cAAc,OAA8B,MAAc,WAAW,IAAI;CACvF,MAAM,QAAQ,QAAQ;CAEtB,OAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEA,SAAgB,cAAc,OAA8B,MAAc,UAAkB;CAC1F,MAAM,QAAQ,QAAQ;CAEtB,OAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEA,SAAgB,sBAAsB,OAA8B,MAAc;CAChF,MAAM,QAAQ,QAAQ;CAEtB,OAAO,OAAO,UAAU,WAAW,QAAQ,KAAA;AAC7C;AAEA,SAAgB,eAAe,OAA8B,MAAc,WAAW,OAAO;CAC3F,MAAM,QAAQ,QAAQ;CAEtB,OAAO,OAAO,UAAU,YAAY,QAAQ;AAC9C"}
@@ -0,0 +1,26 @@
1
+ import { LazyExoticComponent } from 'react';
2
+ import { RendererComponent, RendererComponentModule } from './types';
3
+ export type EagerComponentRegistration = {
4
+ component: RendererComponent;
5
+ mode: "eager";
6
+ };
7
+ export type LazyComponentRegistration = {
8
+ component: LazyExoticComponent<RendererComponent>;
9
+ fallback?: RendererComponent;
10
+ load: () => Promise<RendererComponentModule>;
11
+ mode: "lazy";
12
+ };
13
+ export type ComponentRegistration = EagerComponentRegistration | LazyComponentRegistration;
14
+ export type ComponentRegistry = Record<string, ComponentRegistration>;
15
+ export type Plugin = {
16
+ components: ComponentRegistry;
17
+ name: string;
18
+ };
19
+ export type LazyComponentOptions<TType extends string> = {
20
+ fallback?: RendererComponent<TType>;
21
+ };
22
+ export declare function eagerComponent<TType extends string>(component: RendererComponent<TType>): EagerComponentRegistration;
23
+ export declare function lazyComponent<TType extends string>(load: () => Promise<RendererComponentModule<TType>>, options?: LazyComponentOptions<TType>): LazyComponentRegistration;
24
+ export declare function createPlugin(plugin: Plugin): Plugin;
25
+ export declare function createRegistry(...plugins: Plugin[]): ComponentRegistry;
26
+ export declare function extendRegistry(registry: ComponentRegistry, ...plugins: Plugin[]): ComponentRegistry;
@@ -0,0 +1,36 @@
1
+ import { lazy } from "react";
2
+ //#region resources/js/core/registry.ts
3
+ function eagerComponent(component) {
4
+ return {
5
+ component,
6
+ mode: "eager"
7
+ };
8
+ }
9
+ function lazyComponent(load, options = {}) {
10
+ const erasedLoader = load;
11
+ return {
12
+ component: lazy(erasedLoader),
13
+ fallback: options.fallback,
14
+ load: erasedLoader,
15
+ mode: "lazy"
16
+ };
17
+ }
18
+ function createPlugin(plugin) {
19
+ return plugin;
20
+ }
21
+ function createRegistry(...plugins) {
22
+ return plugins.reduce((registry, plugin) => ({
23
+ ...registry,
24
+ ...plugin.components
25
+ }), {});
26
+ }
27
+ function extendRegistry(registry, ...plugins) {
28
+ return {
29
+ ...registry,
30
+ ...createRegistry(...plugins)
31
+ };
32
+ }
33
+ //#endregion
34
+ export { createPlugin, createRegistry, eagerComponent, extendRegistry, lazyComponent };
35
+
36
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","names":[],"sources":["../../resources/js/core/registry.ts"],"sourcesContent":["import { lazy } from \"react\";\nimport type { LazyExoticComponent } from \"react\";\nimport type { RendererComponent, RendererComponentModule } from \"./types\";\n\nexport type EagerComponentRegistration = {\n component: RendererComponent;\n mode: \"eager\";\n};\n\nexport type LazyComponentRegistration = {\n component: LazyExoticComponent<RendererComponent>;\n fallback?: RendererComponent;\n load: () => Promise<RendererComponentModule>;\n mode: \"lazy\";\n};\n\nexport type ComponentRegistration = EagerComponentRegistration | LazyComponentRegistration;\n\nexport type ComponentRegistry = Record<string, ComponentRegistration>;\n\nexport type Plugin = {\n components: ComponentRegistry;\n name: string;\n};\n\nexport type LazyComponentOptions<TType extends string> = {\n fallback?: RendererComponent<TType>;\n};\n\nexport function eagerComponent<TType extends string>(\n component: RendererComponent<TType>,\n): EagerComponentRegistration {\n return {\n component: component as RendererComponent,\n mode: \"eager\",\n };\n}\n\nexport function lazyComponent<TType extends string>(\n load: () => Promise<RendererComponentModule<TType>>,\n options: LazyComponentOptions<TType> = {},\n): LazyComponentRegistration {\n const erasedLoader = load as unknown as () => Promise<RendererComponentModule>;\n\n return {\n component: lazy(erasedLoader),\n fallback: options.fallback as RendererComponent | undefined,\n load: erasedLoader,\n mode: \"lazy\",\n };\n}\n\nexport function createPlugin(plugin: Plugin): Plugin {\n return plugin;\n}\n\nexport function createRegistry(...plugins: Plugin[]): ComponentRegistry {\n return plugins.reduce<ComponentRegistry>(\n (registry, plugin) => ({\n ...registry,\n ...plugin.components,\n }),\n {},\n );\n}\n\nexport function extendRegistry(\n registry: ComponentRegistry,\n ...plugins: Plugin[]\n): ComponentRegistry {\n return {\n ...registry,\n ...createRegistry(...plugins),\n };\n}\n"],"mappings":";;AA6BA,SAAgB,eACd,WAC4B;CAC5B,OAAO;EACM;EACX,MAAM;CACR;AACF;AAEA,SAAgB,cACd,MACA,UAAuC,CAAC,GACb;CAC3B,MAAM,eAAe;CAErB,OAAO;EACL,WAAW,KAAK,YAAY;EAC5B,UAAU,QAAQ;EAClB,MAAM;EACN,MAAM;CACR;AACF;AAEA,SAAgB,aAAa,QAAwB;CACnD,OAAO;AACT;AAEA,SAAgB,eAAe,GAAG,SAAsC;CACtE,OAAO,QAAQ,QACZ,UAAU,YAAY;EACrB,GAAG;EACH,GAAG,OAAO;CACZ,IACA,CAAC,CACH;AACF;AAEA,SAAgB,eACd,UACA,GAAG,SACgB;CACnB,OAAO;EACL,GAAG;EACH,GAAG,eAAe,GAAG,OAAO;CAC9B;AACF"}
@@ -0,0 +1,16 @@
1
+ import { ReactNode } from 'react';
2
+ import { ComponentRegistry } from './registry';
3
+ import { Node, UnknownComponent } from './types';
4
+ type RendererContextValue = {
5
+ fallback: ReactNode;
6
+ missingComponent: UnknownComponent;
7
+ registry: ComponentRegistry;
8
+ };
9
+ export declare function useRendererContext(): RendererContextValue;
10
+ export declare function Renderer({ fallback, missingComponent: UnknownComponent, nodes, registry, }: {
11
+ fallback?: ReactNode;
12
+ missingComponent?: UnknownComponent;
13
+ nodes: Node[];
14
+ registry: ComponentRegistry;
15
+ }): import("react").JSX.Element;
16
+ export {};