@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,37 @@
1
+ import { getColumnAriaSort, getColumnSort } from "../query.js";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { ArrowDown, ArrowUp, ChevronsUpDown } from "lucide-react";
4
+ //#region resources/js/table/components/column-header.tsx
5
+ function SortIndicator({ sort }) {
6
+ if (sort?.direction === "asc") return /* @__PURE__ */ jsx(ArrowUp, {
7
+ "aria-hidden": "true",
8
+ className: "size-3.5"
9
+ });
10
+ if (sort?.direction === "desc") return /* @__PURE__ */ jsx(ArrowDown, {
11
+ "aria-hidden": "true",
12
+ className: "size-3.5"
13
+ });
14
+ return /* @__PURE__ */ jsx(ChevronsUpDown, {
15
+ "aria-hidden": "true",
16
+ className: "size-3.5 opacity-50"
17
+ });
18
+ }
19
+ function ColumnHeader({ column, processing, sort, state }) {
20
+ const columnSort = getColumnSort(state, column);
21
+ return /* @__PURE__ */ jsx("div", {
22
+ "aria-sort": getColumnAriaSort(columnSort),
23
+ className: "px-4 py-3 text-left align-middle font-medium text-lt-muted-fg",
24
+ role: "columnheader",
25
+ children: column.sortable ? /* @__PURE__ */ jsxs("button", {
26
+ type: "button",
27
+ className: "inline-flex items-center gap-1.5 font-medium",
28
+ disabled: processing,
29
+ onClick: () => sort(column),
30
+ children: [`Sort ${column.label}`, /* @__PURE__ */ jsx(SortIndicator, { sort: columnSort })]
31
+ }) : /* @__PURE__ */ jsx("span", { children: column.label })
32
+ });
33
+ }
34
+ //#endregion
35
+ export { ColumnHeader };
36
+
37
+ //# sourceMappingURL=column-header.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"column-header.js","names":[],"sources":["../../../resources/js/table/components/column-header.tsx"],"sourcesContent":["import { ArrowDown, ArrowUp, ChevronsUpDown } from \"lucide-react\";\nimport { getColumnAriaSort, getColumnSort } from \"../query\";\nimport type { TableColumn, TableSort, TableState } from \"../types\";\n\nfunction SortIndicator({ sort }: { sort: TableSort | undefined }) {\n if (sort?.direction === \"asc\") {\n return <ArrowUp aria-hidden=\"true\" className=\"size-3.5\" />;\n }\n\n if (sort?.direction === \"desc\") {\n return <ArrowDown aria-hidden=\"true\" className=\"size-3.5\" />;\n }\n\n return <ChevronsUpDown aria-hidden=\"true\" className=\"size-3.5 opacity-50\" />;\n}\n\nexport function ColumnHeader({\n column,\n processing,\n sort,\n state,\n}: {\n column: TableColumn;\n processing: boolean;\n sort: (column: TableColumn) => void;\n state: TableState;\n}) {\n const columnSort = getColumnSort(state, column);\n\n return (\n <div\n aria-sort={getColumnAriaSort(columnSort)}\n className=\"px-4 py-3 text-left align-middle font-medium text-lt-muted-fg\"\n role=\"columnheader\"\n >\n {column.sortable ? (\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1.5 font-medium\"\n disabled={processing}\n onClick={() => sort(column)}\n >\n {`Sort ${column.label}`}\n <SortIndicator sort={columnSort} />\n </button>\n ) : (\n <span>{column.label}</span>\n )}\n </div>\n );\n}\n"],"mappings":";;;;AAIA,SAAS,cAAc,EAAE,QAAyC;CAChE,IAAI,MAAM,cAAc,OACtB,OAAO,oBAAC,SAAD;EAAS,eAAY;EAAO,WAAU;CAAY,CAAA;CAG3D,IAAI,MAAM,cAAc,QACtB,OAAO,oBAAC,WAAD;EAAW,eAAY;EAAO,WAAU;CAAY,CAAA;CAG7D,OAAO,oBAAC,gBAAD;EAAgB,eAAY;EAAO,WAAU;CAAuB,CAAA;AAC7E;AAEA,SAAgB,aAAa,EAC3B,QACA,YACA,MACA,SAMC;CACD,MAAM,aAAa,cAAc,OAAO,MAAM;CAE9C,OACE,oBAAC,OAAD;EACE,aAAW,kBAAkB,UAAU;EACvC,WAAU;EACV,MAAK;YAEJ,OAAO,WACN,qBAAC,UAAD;GACE,MAAK;GACL,WAAU;GACV,UAAU;GACV,eAAe,KAAK,MAAM;aAJ5B,CAMG,QAAQ,OAAO,SAChB,oBAAC,eAAD,EAAe,MAAM,WAAa,CAAA,CAC5B;OAER,oBAAC,QAAD,EAAA,UAAO,OAAO,MAAY,CAAA;CAEzB,CAAA;AAET"}
@@ -0,0 +1,7 @@
1
+ import { FilterClause, TableColumn } from '../types';
2
+ export declare function FilterStackBar({ filters, columns, processing, onRemove, }: {
3
+ filters: FilterClause[];
4
+ columns: TableColumn[];
5
+ processing: boolean;
6
+ onRemove: (index: number) => void;
7
+ }): import("react").JSX.Element;
@@ -0,0 +1,35 @@
1
+ import { flattenColumns } from "../payload.js";
2
+ import { operatorLabel } from "../query.js";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { X } from "lucide-react";
5
+ //#region resources/js/table/components/filter-stack-bar.tsx
6
+ function FilterStackBar({ filters, columns, processing, onRemove }) {
7
+ const labels = new Map(flattenColumns(columns).map((column) => [column.key, column.label]));
8
+ return /* @__PURE__ */ jsx("div", {
9
+ className: "flex flex-wrap items-center gap-4 border-b border-lt-border px-4 py-2.5 text-sm",
10
+ children: filters.map((clause, index) => {
11
+ const label = labels.get(clause.field) ?? clause.field;
12
+ return /* @__PURE__ */ jsxs("span", {
13
+ className: "inline-flex items-center gap-1.5",
14
+ children: [/* @__PURE__ */ jsxs("span", { children: [`${label} ${operatorLabel(clause.operator)}: `, /* @__PURE__ */ jsx("span", {
15
+ className: "font-semibold",
16
+ children: clause.value
17
+ })] }), /* @__PURE__ */ jsx("button", {
18
+ type: "button",
19
+ className: "inline-flex size-5 items-center justify-center rounded text-lt-muted-fg hover:bg-lt-muted disabled:opacity-50",
20
+ disabled: processing,
21
+ "aria-label": `Remove ${label} filter`,
22
+ onClick: () => onRemove(index),
23
+ children: /* @__PURE__ */ jsx(X, {
24
+ "aria-hidden": "true",
25
+ className: "size-3.5"
26
+ })
27
+ })]
28
+ }, `${clause.field}-${clause.operator}-${index}`);
29
+ })
30
+ });
31
+ }
32
+ //#endregion
33
+ export { FilterStackBar };
34
+
35
+ //# sourceMappingURL=filter-stack-bar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-stack-bar.js","names":[],"sources":["../../../resources/js/table/components/filter-stack-bar.tsx"],"sourcesContent":["import { X } from \"lucide-react\";\nimport { flattenColumns } from \"../payload\";\nimport { operatorLabel } from \"../query\";\nimport type { FilterClause, TableColumn } from \"../types\";\n\nexport function FilterStackBar({\n filters,\n columns,\n processing,\n onRemove,\n}: {\n filters: FilterClause[];\n columns: TableColumn[];\n processing: boolean;\n onRemove: (index: number) => void;\n}) {\n const labels = new Map(flattenColumns(columns).map((column) => [column.key, column.label]));\n\n return (\n <div className=\"flex flex-wrap items-center gap-4 border-b border-lt-border px-4 py-2.5 text-sm\">\n {filters.map((clause, index) => {\n const label = labels.get(clause.field) ?? clause.field;\n\n return (\n <span\n key={`${clause.field}-${clause.operator}-${index}`}\n className=\"inline-flex items-center gap-1.5\"\n >\n <span>\n {`${label} ${operatorLabel(clause.operator)}: `}\n <span className=\"font-semibold\">{clause.value}</span>\n </span>\n <button\n type=\"button\"\n className=\"inline-flex size-5 items-center justify-center rounded text-lt-muted-fg hover:bg-lt-muted disabled:opacity-50\"\n disabled={processing}\n aria-label={`Remove ${label} filter`}\n onClick={() => onRemove(index)}\n >\n <X aria-hidden=\"true\" className=\"size-3.5\" />\n </button>\n </span>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;;;AAKA,SAAgB,eAAe,EAC7B,SACA,SACA,YACA,YAMC;CACD,MAAM,SAAS,IAAI,IAAI,eAAe,OAAO,EAAE,KAAK,WAAW,CAAC,OAAO,KAAK,OAAO,KAAK,CAAC,CAAC;CAE1F,OACE,oBAAC,OAAD;EAAK,WAAU;YACZ,QAAQ,KAAK,QAAQ,UAAU;GAC9B,MAAM,QAAQ,OAAO,IAAI,OAAO,KAAK,KAAK,OAAO;GAEjD,OACE,qBAAC,QAAD;IAEE,WAAU;cAFZ,CAIE,qBAAC,QAAD,EAAA,UAAA,CACG,GAAG,MAAM,GAAG,cAAc,OAAO,QAAQ,EAAE,KAC5C,oBAAC,QAAD;KAAM,WAAU;eAAiB,OAAO;IAAY,CAAA,CAChD,EAAA,CAAA,GACN,oBAAC,UAAD;KACE,MAAK;KACL,WAAU;KACV,UAAU;KACV,cAAY,UAAU,MAAM;KAC5B,eAAe,SAAS,KAAK;eAE7B,oBAAC,GAAD;MAAG,eAAY;MAAO,WAAU;KAAY,CAAA;IACtC,CAAA,CACJ;MAhBC,GAAG,OAAO,MAAM,GAAG,OAAO,SAAS,GAAG,OAgBvC;EAEV,CAAC;CACE,CAAA;AAET"}
@@ -0,0 +1,11 @@
1
+ import { ControlType } from '../../../../generated/types';
2
+ export declare function FilterValueInput({ type, label, value, processing, withSearchIcon, ariaLabel, onCommit, onClear, }: {
3
+ type: ControlType;
4
+ label: string;
5
+ value: string;
6
+ processing: boolean;
7
+ withSearchIcon?: boolean;
8
+ ariaLabel?: string;
9
+ onCommit: (value: string) => void;
10
+ onClear?: () => void;
11
+ }): import("react").JSX.Element;
@@ -0,0 +1,82 @@
1
+ import { useEffect, useState } from "react";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { Search, X } from "lucide-react";
4
+ //#region resources/js/table/components/filter-value-input.tsx
5
+ var baseClass = "h-9 w-full rounded-lt-sm border border-lt-input bg-lt-bg px-2 text-sm font-normal";
6
+ function FilterValueInput({ type, label, value, processing, withSearchIcon = false, ariaLabel, onCommit, onClear }) {
7
+ const [draft, setDraft] = useState(value);
8
+ const inputLabel = ariaLabel ?? `Filter ${label}`;
9
+ useEffect(() => {
10
+ setDraft(value);
11
+ }, [value]);
12
+ if (type === "boolean") return /* @__PURE__ */ jsxs("select", {
13
+ "aria-label": inputLabel,
14
+ className: baseClass,
15
+ disabled: processing,
16
+ value,
17
+ onChange: (event) => onCommit(event.target.value),
18
+ children: [
19
+ /* @__PURE__ */ jsx("option", {
20
+ value: "",
21
+ children: "All"
22
+ }),
23
+ /* @__PURE__ */ jsx("option", {
24
+ value: "true",
25
+ children: "True"
26
+ }),
27
+ /* @__PURE__ */ jsx("option", {
28
+ value: "false",
29
+ children: "False"
30
+ })
31
+ ]
32
+ });
33
+ if (type === "date") return /* @__PURE__ */ jsx("input", {
34
+ type: "date",
35
+ "aria-label": inputLabel,
36
+ className: baseClass,
37
+ disabled: processing,
38
+ value: draft,
39
+ onChange: (event) => {
40
+ setDraft(event.target.value);
41
+ onCommit(event.target.value);
42
+ }
43
+ });
44
+ return /* @__PURE__ */ jsxs("div", {
45
+ className: "relative flex items-center",
46
+ children: [
47
+ withSearchIcon && /* @__PURE__ */ jsx(Search, {
48
+ "aria-hidden": "true",
49
+ className: "pointer-events-none absolute left-2 size-4 text-lt-muted-fg"
50
+ }),
51
+ /* @__PURE__ */ jsx("input", {
52
+ type: type === "number" ? "number" : "text",
53
+ "aria-label": inputLabel,
54
+ className: `${baseClass} ${withSearchIcon ? "pl-8" : ""} ${onClear ? "pr-8" : ""}`,
55
+ disabled: processing,
56
+ value: draft,
57
+ onChange: (event) => setDraft(event.target.value),
58
+ onKeyDown: (event) => {
59
+ if (event.key === "Enter") onCommit(draft);
60
+ },
61
+ onBlur: () => {
62
+ if (draft !== value) onCommit(draft);
63
+ }
64
+ }),
65
+ onClear && draft !== "" && /* @__PURE__ */ jsx("button", {
66
+ type: "button",
67
+ "aria-label": `Clear ${label} filter`,
68
+ className: "absolute right-1 inline-flex size-6 items-center justify-center rounded hover:bg-lt-muted disabled:opacity-50",
69
+ disabled: processing,
70
+ onClick: onClear,
71
+ children: /* @__PURE__ */ jsx(X, {
72
+ "aria-hidden": "true",
73
+ className: "size-3.5"
74
+ })
75
+ })
76
+ ]
77
+ });
78
+ }
79
+ //#endregion
80
+ export { FilterValueInput };
81
+
82
+ //# sourceMappingURL=filter-value-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-value-input.js","names":[],"sources":["../../../resources/js/table/components/filter-value-input.tsx"],"sourcesContent":["import { Search, X } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport type { ControlType } from \"@lattice/lattice/generated/types\";\n\nconst baseClass =\n \"h-9 w-full rounded-lt-sm border border-lt-input bg-lt-bg px-2 text-sm font-normal\";\n\nexport function FilterValueInput({\n type,\n label,\n value,\n processing,\n withSearchIcon = false,\n ariaLabel,\n onCommit,\n onClear,\n}: {\n type: ControlType;\n label: string;\n value: string;\n processing: boolean;\n withSearchIcon?: boolean;\n ariaLabel?: string;\n onCommit: (value: string) => void;\n onClear?: () => void;\n}) {\n const [draft, setDraft] = useState(value);\n const inputLabel = ariaLabel ?? `Filter ${label}`;\n\n useEffect(() => {\n setDraft(value);\n }, [value]);\n\n if (type === \"boolean\") {\n return (\n <select\n aria-label={inputLabel}\n className={baseClass}\n disabled={processing}\n value={value}\n onChange={(event) => onCommit(event.target.value)}\n >\n <option value=\"\">All</option>\n <option value=\"true\">True</option>\n <option value=\"false\">False</option>\n </select>\n );\n }\n\n if (type === \"date\") {\n return (\n <input\n type=\"date\"\n aria-label={inputLabel}\n className={baseClass}\n disabled={processing}\n value={draft}\n onChange={(event) => {\n setDraft(event.target.value);\n onCommit(event.target.value);\n }}\n />\n );\n }\n\n return (\n <div className=\"relative flex items-center\">\n {withSearchIcon && (\n <Search\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-2 size-4 text-lt-muted-fg\"\n />\n )}\n <input\n type={type === \"number\" ? \"number\" : \"text\"}\n aria-label={inputLabel}\n className={`${baseClass} ${withSearchIcon ? \"pl-8\" : \"\"} ${onClear ? \"pr-8\" : \"\"}`}\n disabled={processing}\n value={draft}\n onChange={(event) => setDraft(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") {\n onCommit(draft);\n }\n }}\n onBlur={() => {\n if (draft !== value) {\n onCommit(draft);\n }\n }}\n />\n {onClear && draft !== \"\" && (\n <button\n type=\"button\"\n aria-label={`Clear ${label} filter`}\n className=\"absolute right-1 inline-flex size-6 items-center justify-center rounded hover:bg-lt-muted disabled:opacity-50\"\n disabled={processing}\n onClick={onClear}\n >\n <X aria-hidden=\"true\" className=\"size-3.5\" />\n </button>\n )}\n </div>\n );\n}\n"],"mappings":";;;;AAIA,IAAM,YACJ;AAEF,SAAgB,iBAAiB,EAC/B,MACA,OACA,OACA,YACA,iBAAiB,OACjB,WACA,UACA,WAUC;CACD,MAAM,CAAC,OAAO,YAAY,SAAS,KAAK;CACxC,MAAM,aAAa,aAAa,UAAU;CAE1C,gBAAgB;EACd,SAAS,KAAK;CAChB,GAAG,CAAC,KAAK,CAAC;CAEV,IAAI,SAAS,WACX,OACE,qBAAC,UAAD;EACE,cAAY;EACZ,WAAW;EACX,UAAU;EACH;EACP,WAAW,UAAU,SAAS,MAAM,OAAO,KAAK;YALlD;GAOE,oBAAC,UAAD;IAAQ,OAAM;cAAG;GAAW,CAAA;GAC5B,oBAAC,UAAD;IAAQ,OAAM;cAAO;GAAY,CAAA;GACjC,oBAAC,UAAD;IAAQ,OAAM;cAAQ;GAAa,CAAA;EAC7B;;CAIZ,IAAI,SAAS,QACX,OACE,oBAAC,SAAD;EACE,MAAK;EACL,cAAY;EACZ,WAAW;EACX,UAAU;EACV,OAAO;EACP,WAAW,UAAU;GACnB,SAAS,MAAM,OAAO,KAAK;GAC3B,SAAS,MAAM,OAAO,KAAK;EAC7B;CACD,CAAA;CAIL,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf;GACG,kBACC,oBAAC,QAAD;IACE,eAAY;IACZ,WAAU;GACX,CAAA;GAEH,oBAAC,SAAD;IACE,MAAM,SAAS,WAAW,WAAW;IACrC,cAAY;IACZ,WAAW,GAAG,UAAU,GAAG,iBAAiB,SAAS,GAAG,GAAG,UAAU,SAAS;IAC9E,UAAU;IACV,OAAO;IACP,WAAW,UAAU,SAAS,MAAM,OAAO,KAAK;IAChD,YAAY,UAAU;KACpB,IAAI,MAAM,QAAQ,SAChB,SAAS,KAAK;IAElB;IACA,cAAc;KACZ,IAAI,UAAU,OACZ,SAAS,KAAK;IAElB;GACD,CAAA;GACA,WAAW,UAAU,MACpB,oBAAC,UAAD;IACE,MAAK;IACL,cAAY,SAAS,MAAM;IAC3B,WAAU;IACV,UAAU;IACV,SAAS;cAET,oBAAC,GAAD;KAAG,eAAY;KAAO,WAAU;IAAY,CAAA;GACtC,CAAA;EAEP;;AAET"}
@@ -0,0 +1,14 @@
1
+ import { RefObject } from 'react';
2
+ import { PaginationType } from '../../../../generated/types';
3
+ import { TablePagination as TablePaginationData } from '../types';
4
+ export declare function TablePagination({ pagination, currentPage, processing, mode, hasNextPage, visiblePages, infiniteLoaderRef, onPage, onLoadMore, }: {
5
+ pagination: TablePaginationData;
6
+ currentPage: number;
7
+ processing: boolean;
8
+ mode: PaginationType;
9
+ hasNextPage: boolean;
10
+ visiblePages: number[];
11
+ infiniteLoaderRef: RefObject<HTMLDivElement | null>;
12
+ onPage: (page: number) => void;
13
+ onLoadMore: () => void;
14
+ }): import("react").JSX.Element;
@@ -0,0 +1,67 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ //#region resources/js/table/components/pagination.tsx
3
+ function TablePagination({ pagination, currentPage, processing, mode, hasNextPage, visiblePages, infiniteLoaderRef, onPage, onLoadMore }) {
4
+ return /* @__PURE__ */ jsxs("div", {
5
+ className: "flex items-center justify-between gap-3 border-t border-lt-border p-4 text-sm",
6
+ children: [/* @__PURE__ */ jsx("span", { children: pagination.total === void 0 ? `Page ${currentPage}` : `Showing ${pagination.from ?? 0}-${pagination.to ?? 0} of ${pagination.total}` }), mode === "infinite" ? /* @__PURE__ */ jsx("div", {
7
+ ref: infiniteLoaderRef,
8
+ className: "flex items-center gap-2",
9
+ children: pagination.hasMore ? /* @__PURE__ */ jsx("button", {
10
+ type: "button",
11
+ className: "h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50",
12
+ disabled: processing,
13
+ onClick: onLoadMore,
14
+ children: processing ? "Loading..." : "Load more"
15
+ }) : /* @__PURE__ */ jsx("span", {
16
+ className: "text-lt-muted-fg",
17
+ children: "All rows loaded"
18
+ })
19
+ }) : mode === "simple" ? /* @__PURE__ */ jsxs("div", {
20
+ className: "flex items-center gap-2",
21
+ children: [/* @__PURE__ */ jsx("button", {
22
+ type: "button",
23
+ className: "h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50",
24
+ disabled: processing || currentPage <= 1,
25
+ onClick: () => onPage(currentPage - 1),
26
+ children: "Previous"
27
+ }), /* @__PURE__ */ jsx("button", {
28
+ type: "button",
29
+ className: "h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50",
30
+ disabled: processing || !hasNextPage,
31
+ onClick: () => onPage(currentPage + 1),
32
+ children: "Next"
33
+ })]
34
+ }) : mode === "table" ? /* @__PURE__ */ jsxs("div", {
35
+ className: "flex items-center gap-2",
36
+ children: [
37
+ /* @__PURE__ */ jsx("button", {
38
+ type: "button",
39
+ className: "h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50",
40
+ disabled: processing || currentPage <= 1,
41
+ onClick: () => onPage(currentPage - 1),
42
+ children: "Previous"
43
+ }),
44
+ visiblePages.map((pageNumber) => /* @__PURE__ */ jsx("button", {
45
+ type: "button",
46
+ className: "inline-flex size-9 items-center justify-center rounded-lt-sm border border-lt-border font-medium disabled:opacity-50",
47
+ disabled: processing || pageNumber === currentPage,
48
+ "aria-current": pageNumber === currentPage ? "page" : void 0,
49
+ "aria-label": `Page ${pageNumber}`,
50
+ onClick: () => onPage(pageNumber),
51
+ children: pageNumber
52
+ }, pageNumber)),
53
+ /* @__PURE__ */ jsx("button", {
54
+ type: "button",
55
+ className: "h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50",
56
+ disabled: processing || !hasNextPage,
57
+ onClick: () => onPage(currentPage + 1),
58
+ children: "Next"
59
+ })
60
+ ]
61
+ }) : null]
62
+ });
63
+ }
64
+ //#endregion
65
+ export { TablePagination };
66
+
67
+ //# sourceMappingURL=pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.js","names":[],"sources":["../../../resources/js/table/components/pagination.tsx"],"sourcesContent":["import type { RefObject } from \"react\";\nimport type { PaginationType } from \"@lattice/lattice/generated/types\";\nimport type { TablePagination as TablePaginationData } from \"../types\";\n\nexport function TablePagination({\n pagination,\n currentPage,\n processing,\n mode,\n hasNextPage,\n visiblePages,\n infiniteLoaderRef,\n onPage,\n onLoadMore,\n}: {\n pagination: TablePaginationData;\n currentPage: number;\n processing: boolean;\n mode: PaginationType;\n hasNextPage: boolean;\n visiblePages: number[];\n infiniteLoaderRef: RefObject<HTMLDivElement | null>;\n onPage: (page: number) => void;\n onLoadMore: () => void;\n}) {\n return (\n <div className=\"flex items-center justify-between gap-3 border-t border-lt-border p-4 text-sm\">\n <span>\n {pagination.total === undefined\n ? `Page ${currentPage}`\n : `Showing ${pagination.from ?? 0}-${pagination.to ?? 0} of ${pagination.total}`}\n </span>\n {mode === \"infinite\" ? (\n <div ref={infiniteLoaderRef} className=\"flex items-center gap-2\">\n {pagination.hasMore ? (\n <button\n type=\"button\"\n className=\"h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50\"\n disabled={processing}\n onClick={onLoadMore}\n >\n {processing ? \"Loading...\" : \"Load more\"}\n </button>\n ) : (\n <span className=\"text-lt-muted-fg\">All rows loaded</span>\n )}\n </div>\n ) : mode === \"simple\" ? (\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n className=\"h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50\"\n disabled={processing || currentPage <= 1}\n onClick={() => onPage(currentPage - 1)}\n >\n Previous\n </button>\n <button\n type=\"button\"\n className=\"h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50\"\n disabled={processing || !hasNextPage}\n onClick={() => onPage(currentPage + 1)}\n >\n Next\n </button>\n </div>\n ) : mode === \"table\" ? (\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n className=\"h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50\"\n disabled={processing || currentPage <= 1}\n onClick={() => onPage(currentPage - 1)}\n >\n Previous\n </button>\n {visiblePages.map((pageNumber) => (\n <button\n key={pageNumber}\n type=\"button\"\n className=\"inline-flex size-9 items-center justify-center rounded-lt-sm border border-lt-border font-medium disabled:opacity-50\"\n disabled={processing || pageNumber === currentPage}\n aria-current={pageNumber === currentPage ? \"page\" : undefined}\n aria-label={`Page ${pageNumber}`}\n onClick={() => onPage(pageNumber)}\n >\n {pageNumber}\n </button>\n ))}\n <button\n type=\"button\"\n className=\"h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50\"\n disabled={processing || !hasNextPage}\n onClick={() => onPage(currentPage + 1)}\n >\n Next\n </button>\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":";;AAIA,SAAgB,gBAAgB,EAC9B,YACA,aACA,YACA,MACA,aACA,cACA,mBACA,QACA,cAWC;CACD,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,QAAD,EAAA,UACG,WAAW,UAAU,KAAA,IAClB,QAAQ,gBACR,WAAW,WAAW,QAAQ,EAAE,GAAG,WAAW,MAAM,EAAE,MAAM,WAAW,QACvE,CAAA,GACL,SAAS,aACR,oBAAC,OAAD;GAAK,KAAK;GAAmB,WAAU;aACpC,WAAW,UACV,oBAAC,UAAD;IACE,MAAK;IACL,WAAU;IACV,UAAU;IACV,SAAS;cAER,aAAa,eAAe;GACvB,CAAA,IAER,oBAAC,QAAD;IAAM,WAAU;cAAmB;GAAqB,CAAA;EAEvD,CAAA,IACH,SAAS,WACX,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,UAAD;IACE,MAAK;IACL,WAAU;IACV,UAAU,cAAc,eAAe;IACvC,eAAe,OAAO,cAAc,CAAC;cACtC;GAEO,CAAA,GACR,oBAAC,UAAD;IACE,MAAK;IACL,WAAU;IACV,UAAU,cAAc,CAAC;IACzB,eAAe,OAAO,cAAc,CAAC;cACtC;GAEO,CAAA,CACL;OACH,SAAS,UACX,qBAAC,OAAD;GAAK,WAAU;aAAf;IACE,oBAAC,UAAD;KACE,MAAK;KACL,WAAU;KACV,UAAU,cAAc,eAAe;KACvC,eAAe,OAAO,cAAc,CAAC;eACtC;IAEO,CAAA;IACP,aAAa,KAAK,eACjB,oBAAC,UAAD;KAEE,MAAK;KACL,WAAU;KACV,UAAU,cAAc,eAAe;KACvC,gBAAc,eAAe,cAAc,SAAS,KAAA;KACpD,cAAY,QAAQ;KACpB,eAAe,OAAO,UAAU;eAE/B;IACK,GATD,UASC,CACT;IACD,oBAAC,UAAD;KACE,MAAK;KACL,WAAU;KACV,UAAU,cAAc,CAAC;KACzB,eAAe,OAAO,cAAc,CAAC;eACtC;IAEO,CAAA;GACL;OACH,IACD;;AAET"}
@@ -0,0 +1,7 @@
1
+ import { TableColumn, TableSort, TableState } from '../types';
2
+ export declare function SortBar({ columns, state, processing, onClear, }: {
3
+ columns: TableColumn[];
4
+ state: TableState;
5
+ processing: boolean;
6
+ onClear: (sort: TableSort) => void;
7
+ }): import("react").JSX.Element;
@@ -0,0 +1,43 @@
1
+ import { getSortColumn, getSortDirectionLabel } from "../query.js";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { ArrowDown, ArrowUp, X } from "lucide-react";
4
+ //#region resources/js/table/components/sort-bar.tsx
5
+ function SortBar({ columns, state, processing, onClear }) {
6
+ return /* @__PURE__ */ jsx("div", {
7
+ className: "flex flex-wrap items-center gap-4 border-b border-lt-border px-4 py-2.5 text-sm",
8
+ children: state.sorts.map((sort, index) => {
9
+ const label = getSortColumn(columns, sort)?.label ?? sort.key;
10
+ const Chevron = sort.direction === "desc" ? ArrowDown : ArrowUp;
11
+ return /* @__PURE__ */ jsxs("span", {
12
+ className: "inline-flex items-center gap-1.5",
13
+ children: [
14
+ /* @__PURE__ */ jsx("span", {
15
+ className: "font-medium",
16
+ children: `${index + 1}. ${label}`
17
+ }),
18
+ /* @__PURE__ */ jsx(Chevron, {
19
+ role: "img",
20
+ "aria-label": getSortDirectionLabel(sort.direction),
21
+ className: "size-3.5 text-lt-muted-fg"
22
+ }),
23
+ /* @__PURE__ */ jsx("button", {
24
+ type: "button",
25
+ className: "inline-flex size-5 items-center justify-center rounded text-lt-muted-fg hover:bg-lt-muted disabled:opacity-50",
26
+ disabled: processing,
27
+ "aria-label": `Clear ${label} sort`,
28
+ "data-test": `clear-${sort.key}-sort`,
29
+ onClick: () => onClear(sort),
30
+ children: /* @__PURE__ */ jsx(X, {
31
+ "aria-hidden": "true",
32
+ className: "size-3.5"
33
+ })
34
+ })
35
+ ]
36
+ }, sort.key);
37
+ })
38
+ });
39
+ }
40
+ //#endregion
41
+ export { SortBar };
42
+
43
+ //# sourceMappingURL=sort-bar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sort-bar.js","names":[],"sources":["../../../resources/js/table/components/sort-bar.tsx"],"sourcesContent":["import { ArrowDown, ArrowUp, X } from \"lucide-react\";\nimport { getSortColumn, getSortDirectionLabel } from \"../query\";\nimport type { TableColumn, TableSort, TableState } from \"../types\";\n\nexport function SortBar({\n columns,\n state,\n processing,\n onClear,\n}: {\n columns: TableColumn[];\n state: TableState;\n processing: boolean;\n onClear: (sort: TableSort) => void;\n}) {\n return (\n <div className=\"flex flex-wrap items-center gap-4 border-b border-lt-border px-4 py-2.5 text-sm\">\n {state.sorts.map((sort, index) => {\n const column = getSortColumn(columns, sort);\n const label = column?.label ?? sort.key;\n const Chevron = sort.direction === \"desc\" ? ArrowDown : ArrowUp;\n\n return (\n <span key={sort.key} className=\"inline-flex items-center gap-1.5\">\n <span className=\"font-medium\">{`${index + 1}. ${label}`}</span>\n <Chevron\n role=\"img\"\n aria-label={getSortDirectionLabel(sort.direction)}\n className=\"size-3.5 text-lt-muted-fg\"\n />\n <button\n type=\"button\"\n className=\"inline-flex size-5 items-center justify-center rounded text-lt-muted-fg hover:bg-lt-muted disabled:opacity-50\"\n disabled={processing}\n aria-label={`Clear ${label} sort`}\n data-test={`clear-${sort.key}-sort`}\n onClick={() => onClear(sort)}\n >\n <X aria-hidden=\"true\" className=\"size-3.5\" />\n </button>\n </span>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;;AAIA,SAAgB,QAAQ,EACtB,SACA,OACA,YACA,WAMC;CACD,OACE,oBAAC,OAAD;EAAK,WAAU;YACZ,MAAM,MAAM,KAAK,MAAM,UAAU;GAEhC,MAAM,QADS,cAAc,SAAS,IACxB,GAAQ,SAAS,KAAK;GACpC,MAAM,UAAU,KAAK,cAAc,SAAS,YAAY;GAExD,OACE,qBAAC,QAAD;IAAqB,WAAU;cAA/B;KACE,oBAAC,QAAD;MAAM,WAAU;gBAAe,GAAG,QAAQ,EAAE,IAAI;KAAc,CAAA;KAC9D,oBAAC,SAAD;MACE,MAAK;MACL,cAAY,sBAAsB,KAAK,SAAS;MAChD,WAAU;KACX,CAAA;KACD,oBAAC,UAAD;MACE,MAAK;MACL,WAAU;MACV,UAAU;MACV,cAAY,SAAS,MAAM;MAC3B,aAAW,SAAS,KAAK,IAAI;MAC7B,eAAe,QAAQ,IAAI;gBAE3B,oBAAC,GAAD;OAAG,eAAY;OAAO,WAAU;MAAY,CAAA;KACtC,CAAA;IACJ;MAjBK,KAAK,GAiBV;EAEV,CAAC;CACE,CAAA;AAET"}
@@ -0,0 +1,4 @@
1
+ import { Node } from '../../../../core/types';
2
+ export declare function TableActionNode({ node }: {
3
+ node: Node;
4
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,24 @@
1
+ import ActionComponent from "../../action/components/action.js";
2
+ import ActionGroupComponent from "../../action/components/action-group.js";
3
+ import LinkComponent from "../../core/components/link.js";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region resources/js/table/components/table-action-node.tsx
6
+ function TableActionNode({ node }) {
7
+ if (node.type === "action") return /* @__PURE__ */ jsx(ActionComponent, {
8
+ node,
9
+ children: null
10
+ });
11
+ if (node.type === "action.group") return /* @__PURE__ */ jsx(ActionGroupComponent, {
12
+ node,
13
+ children: node.children?.map((childNode, index) => /* @__PURE__ */ jsx(TableActionNode, { node: childNode }, childNode.key ?? childNode.id ?? `${childNode.type}-${index}`)) ?? null
14
+ });
15
+ if (node.type === "link") return /* @__PURE__ */ jsx(LinkComponent, {
16
+ node,
17
+ children: null
18
+ });
19
+ return null;
20
+ }
21
+ //#endregion
22
+ export { TableActionNode };
23
+
24
+ //# sourceMappingURL=table-action-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-action-node.js","names":[],"sources":["../../../resources/js/table/components/table-action-node.tsx"],"sourcesContent":["import type { Node } from \"@lattice/lattice/core/types\";\nimport ActionComponent from \"@lattice/lattice/action/components/action\";\nimport ActionGroupComponent from \"@lattice/lattice/action/components/action-group\";\nimport LinkComponent from \"@lattice/lattice/core/components/link\";\n\nexport function TableActionNode({ node }: { node: Node }) {\n if (node.type === \"action\") {\n return <ActionComponent node={node as Node<\"action\">}>{null}</ActionComponent>;\n }\n\n if (node.type === \"action.group\") {\n return (\n <ActionGroupComponent node={node as Node<\"action.group\">}>\n {node.children?.map((childNode, index) => (\n <TableActionNode\n key={childNode.key ?? childNode.id ?? `${childNode.type}-${index}`}\n node={childNode}\n />\n )) ?? null}\n </ActionGroupComponent>\n );\n }\n\n if (node.type === \"link\") {\n return <LinkComponent node={node as Node<\"link\">}>{null}</LinkComponent>;\n }\n\n return null;\n}\n"],"mappings":";;;;;AAKA,SAAgB,gBAAgB,EAAE,QAAwB;CACxD,IAAI,KAAK,SAAS,UAChB,OAAO,oBAAC,iBAAD;EAAuB;YAAyB;CAAsB,CAAA;CAG/E,IAAI,KAAK,SAAS,gBAChB,OACE,oBAAC,sBAAD;EAA4B;YACzB,KAAK,UAAU,KAAK,WAAW,UAC9B,oBAAC,iBAAD,EAEE,MAAM,UACP,GAFM,UAAU,OAAO,UAAU,MAAM,GAAG,UAAU,KAAK,GAAG,OAE5D,CACF,KAAK;CACc,CAAA;CAI1B,IAAI,KAAK,SAAS,QAChB,OAAO,oBAAC,eAAD;EAAqB;YAAuB;CAAoB,CAAA;CAGzE,OAAO;AACT"}
@@ -0,0 +1,5 @@
1
+ import { TableColumn, TableRow } from '../types';
2
+ export declare function ColumnCell({ column, row }: {
3
+ column: TableColumn;
4
+ row: TableRow;
5
+ }): import("react").JSX.Element;
@@ -0,0 +1,63 @@
1
+ import { copyToClipboard } from "../../clipboard/index.js";
2
+ import { formatCell, resolveLink } from "../format.js";
3
+ import { useEffect, useState } from "react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { Check, Copy } from "lucide-react";
6
+ //#region resources/js/table/components/table-cell.tsx
7
+ function ColumnCell({ column, row }) {
8
+ if (column.type === "stack") return /* @__PURE__ */ jsx("div", {
9
+ className: "grid gap-1",
10
+ children: (column.columns ?? []).map((stackedColumn) => /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(TextCell, {
11
+ column: stackedColumn,
12
+ row,
13
+ value: row[stackedColumn.key]
14
+ }) }, stackedColumn.key))
15
+ });
16
+ return /* @__PURE__ */ jsx(TextCell, {
17
+ column,
18
+ row,
19
+ value: row[column.key]
20
+ });
21
+ }
22
+ function TextCell({ column, row, value }) {
23
+ const text = formatCell(value, column);
24
+ const [copied, setCopied] = useState(false);
25
+ const href = resolveLink(column, row, value);
26
+ const content = href ? /* @__PURE__ */ jsx("a", {
27
+ className: "underline underline-offset-2",
28
+ href,
29
+ rel: column.link?.external ? "noreferrer" : void 0,
30
+ target: column.link?.external ? "_blank" : void 0,
31
+ children: text
32
+ }) : text;
33
+ useEffect(() => {
34
+ if (!copied) return;
35
+ const timeout = window.setTimeout(() => setCopied(false), 1500);
36
+ return () => window.clearTimeout(timeout);
37
+ }, [copied]);
38
+ function handleCopy() {
39
+ copyToClipboard(text);
40
+ setCopied(true);
41
+ }
42
+ if (!column.copyable) return content;
43
+ return /* @__PURE__ */ jsxs("span", {
44
+ className: "inline-flex items-center gap-2",
45
+ children: [/* @__PURE__ */ jsx("span", { children: content }), /* @__PURE__ */ jsxs("button", {
46
+ type: "button",
47
+ className: "inline-flex items-center gap-1 rounded border border-lt-border px-2 py-1 text-xs",
48
+ "aria-label": `${copied ? "Copied" : "Copy"} ${column.label}`,
49
+ onClick: handleCopy,
50
+ children: [copied ? /* @__PURE__ */ jsx(Check, {
51
+ "aria-hidden": "true",
52
+ className: "size-3"
53
+ }) : /* @__PURE__ */ jsx(Copy, {
54
+ "aria-hidden": "true",
55
+ className: "size-3"
56
+ }), copied ? "Copied" : "Copy"]
57
+ })]
58
+ });
59
+ }
60
+ //#endregion
61
+ export { ColumnCell };
62
+
63
+ //# sourceMappingURL=table-cell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-cell.js","names":[],"sources":["../../../resources/js/table/components/table-cell.tsx"],"sourcesContent":["import { copyToClipboard } from \"@lattice/lattice/clipboard\";\nimport { Check, Copy } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { formatCell, resolveLink } from \"../format\";\nimport type { TableColumn, TableRow } from \"../types\";\n\nexport function ColumnCell({ column, row }: { column: TableColumn; row: TableRow }) {\n if (column.type === \"stack\") {\n return (\n <div className=\"grid gap-1\">\n {(column.columns ?? []).map((stackedColumn) => (\n <span key={stackedColumn.key}>\n <TextCell column={stackedColumn} row={row} value={row[stackedColumn.key]} />\n </span>\n ))}\n </div>\n );\n }\n\n return <TextCell column={column} row={row} value={row[column.key]} />;\n}\n\nfunction TextCell({ column, row, value }: { column: TableColumn; row: TableRow; value: unknown }) {\n const text = formatCell(value, column);\n const [copied, setCopied] = useState(false);\n const href = resolveLink(column, row, value);\n const content = href ? (\n <a\n className=\"underline underline-offset-2\"\n href={href}\n rel={column.link?.external ? \"noreferrer\" : undefined}\n target={column.link?.external ? \"_blank\" : undefined}\n >\n {text}\n </a>\n ) : (\n text\n );\n\n useEffect(() => {\n if (!copied) {\n return;\n }\n\n const timeout = window.setTimeout(() => setCopied(false), 1500);\n\n return () => window.clearTimeout(timeout);\n }, [copied]);\n\n function handleCopy(): void {\n void copyToClipboard(text);\n setCopied(true);\n }\n\n if (!column.copyable) {\n return content;\n }\n\n return (\n <span className=\"inline-flex items-center gap-2\">\n <span>{content}</span>\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1 rounded border border-lt-border px-2 py-1 text-xs\"\n aria-label={`${copied ? \"Copied\" : \"Copy\"} ${column.label}`}\n onClick={handleCopy}\n >\n {copied ? (\n <Check aria-hidden=\"true\" className=\"size-3\" />\n ) : (\n <Copy aria-hidden=\"true\" className=\"size-3\" />\n )}\n {copied ? \"Copied\" : \"Copy\"}\n </button>\n </span>\n );\n}\n"],"mappings":";;;;;;AAMA,SAAgB,WAAW,EAAE,QAAQ,OAA+C;CAClF,IAAI,OAAO,SAAS,SAClB,OACE,oBAAC,OAAD;EAAK,WAAU;aACX,OAAO,WAAW,CAAC,GAAG,KAAK,kBAC3B,oBAAC,QAAD,EAAA,UACE,oBAAC,UAAD;GAAU,QAAQ;GAAoB;GAAK,OAAO,IAAI,cAAc;EAAO,CAAA,EACvE,GAFK,cAAc,GAEnB,CACP;CACE,CAAA;CAIT,OAAO,oBAAC,UAAD;EAAkB;EAAa;EAAK,OAAO,IAAI,OAAO;CAAO,CAAA;AACtE;AAEA,SAAS,SAAS,EAAE,QAAQ,KAAK,SAAiE;CAChG,MAAM,OAAO,WAAW,OAAO,MAAM;CACrC,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK;CAC1C,MAAM,OAAO,YAAY,QAAQ,KAAK,KAAK;CAC3C,MAAM,UAAU,OACd,oBAAC,KAAD;EACE,WAAU;EACJ;EACN,KAAK,OAAO,MAAM,WAAW,eAAe,KAAA;EAC5C,QAAQ,OAAO,MAAM,WAAW,WAAW,KAAA;YAE1C;CACA,CAAA,IAEH;CAGF,gBAAgB;EACd,IAAI,CAAC,QACH;EAGF,MAAM,UAAU,OAAO,iBAAiB,UAAU,KAAK,GAAG,IAAI;EAE9D,aAAa,OAAO,aAAa,OAAO;CAC1C,GAAG,CAAC,MAAM,CAAC;CAEX,SAAS,aAAmB;EAC1B,gBAAqB,IAAI;EACzB,UAAU,IAAI;CAChB;CAEA,IAAI,CAAC,OAAO,UACV,OAAO;CAGT,OACE,qBAAC,QAAD;EAAM,WAAU;YAAhB,CACE,oBAAC,QAAD,EAAA,UAAO,QAAc,CAAA,GACrB,qBAAC,UAAD;GACE,MAAK;GACL,WAAU;GACV,cAAY,GAAG,SAAS,WAAW,OAAO,GAAG,OAAO;GACpD,SAAS;aAJX,CAMG,SACC,oBAAC,OAAD;IAAO,eAAY;IAAO,WAAU;GAAU,CAAA,IAE9C,oBAAC,MAAD;IAAM,eAAY;IAAO,WAAU;GAAU,CAAA,GAE9C,SAAS,WAAW,MACf;IACJ;;AAEV"}
@@ -0,0 +1,3 @@
1
+ import { RendererComponent } from '../../../../core/types';
2
+ declare const TableComponent: RendererComponent<"table">;
3
+ export default TableComponent;