@lattice-php/lattice 0.19.0 → 0.20.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 (236) hide show
  1. package/dist/core/index.js +2 -2
  2. package/dist/core/types.d.ts +16 -4
  3. package/dist/create-app.d.ts +31 -3
  4. package/dist/create-app.js +48 -10
  5. package/dist/create-app.js.map +1 -1
  6. package/dist/effects/registry.d.ts +3 -3
  7. package/dist/effects/registry.js +4 -4
  8. package/dist/effects/registry.js.map +1 -1
  9. package/dist/form/components/base/field.d.ts +2 -2
  10. package/dist/form/components/base/field.js +2 -2
  11. package/dist/form/components/base/field.js.map +1 -1
  12. package/dist/form/components/fields/color-picker-field.d.ts +2 -0
  13. package/dist/form/components/fields/color-picker-field.js +57 -0
  14. package/dist/form/components/fields/color-picker-field.js.map +1 -0
  15. package/dist/form/components/fields/date-input.js +1 -1
  16. package/dist/form/components/fields/date-picker-field.js +1 -1
  17. package/dist/form/components/fields/date-time-input.js +1 -1
  18. package/dist/form/components/fields/file-upload.js +7 -12
  19. package/dist/form/components/fields/file-upload.js.map +1 -1
  20. package/dist/form/components/fields/number-input.js +1 -1
  21. package/dist/form/components/fields/rich-editor-field.js +35 -276
  22. package/dist/form/components/fields/rich-editor-field.js.map +1 -1
  23. package/dist/form/components/fields/row-action-menu.js +2 -2
  24. package/dist/form/components/fields/row-action-menu.js.map +1 -1
  25. package/dist/form/components/fields/row-actions.js +3 -1
  26. package/dist/form/components/fields/row-actions.js.map +1 -1
  27. package/dist/form/components/fields/select.js +59 -16
  28. package/dist/form/components/fields/select.js.map +1 -1
  29. package/dist/form/components/fields/table-rows.js +2 -2
  30. package/dist/form/components/fields/table-rows.js.map +1 -1
  31. package/dist/form/components/fields/text-input.js +8 -1
  32. package/dist/form/components/fields/text-input.js.map +1 -1
  33. package/dist/form/components/fields/time-input.js +1 -1
  34. package/dist/form/components/index.d.ts +1 -0
  35. package/dist/form/components/index.js +2 -1
  36. package/dist/form/embed.d.ts +1 -0
  37. package/dist/form/embed.js +2 -1
  38. package/dist/form/hooks/use-form-resolver.js.map +1 -1
  39. package/dist/form/index.js +2 -1
  40. package/dist/form/lib/conditions.d.ts +4 -10
  41. package/dist/form/lib/conditions.js.map +1 -1
  42. package/dist/form/lib/field-props.d.ts +4 -18
  43. package/dist/form/lib/field-props.js.map +1 -1
  44. package/dist/form/plugin.js +2 -0
  45. package/dist/form/plugin.js.map +1 -1
  46. package/dist/form/rich-editor/builtins.d.ts +6 -0
  47. package/dist/form/rich-editor/builtins.js +400 -0
  48. package/dist/form/rich-editor/builtins.js.map +1 -0
  49. package/dist/form/rich-editor/index.d.ts +7 -0
  50. package/dist/form/rich-editor/index.js +3 -0
  51. package/dist/form/rich-editor/registry.d.ts +67 -0
  52. package/dist/form/rich-editor/registry.js +79 -0
  53. package/dist/form/rich-editor/registry.js.map +1 -0
  54. package/dist/form/rich-editor/toolbar-button.d.ts +12 -0
  55. package/dist/form/rich-editor/toolbar-button.js +28 -0
  56. package/dist/form/rich-editor/toolbar-button.js.map +1 -0
  57. package/dist/form/types.d.ts +1 -6
  58. package/dist/format/date-time.d.ts +3 -2
  59. package/dist/format/date-time.js.map +1 -1
  60. package/dist/i18n/backend.js +1 -1
  61. package/dist/i18n/date-time.d.ts +3 -2
  62. package/dist/i18n/date-time.js.map +1 -1
  63. package/dist/i18n/index.js +3 -2
  64. package/dist/i18n/instance.js +1 -1
  65. package/dist/i18n/page-props.d.ts +3 -2
  66. package/dist/i18n/page-props.js +1 -15
  67. package/dist/i18n/page-props.js.map +1 -1
  68. package/dist/i18n/shared-props.d.ts +7 -0
  69. package/dist/i18n/shared-props.js +25 -0
  70. package/dist/i18n/shared-props.js.map +1 -0
  71. package/dist/index.d.ts +5 -3
  72. package/dist/index.js +7 -6
  73. package/dist/lattice.css +107 -47
  74. package/dist/layout/components/breadcrumbs.js +3 -1
  75. package/dist/layout/components/breadcrumbs.js.map +1 -1
  76. package/dist/layout/components/callouts.js +1 -1
  77. package/dist/lib/color.d.ts +9 -0
  78. package/dist/lib/color.js +48 -0
  79. package/dist/lib/color.js.map +1 -0
  80. package/dist/notifications/api.d.ts +6 -6
  81. package/dist/notifications/api.js.map +1 -1
  82. package/dist/notifications/types.d.ts +2 -10
  83. package/dist/provider-base.js +1 -1
  84. package/dist/realtime/build-effects.js +5 -5
  85. package/dist/realtime/build-effects.js.map +1 -1
  86. package/dist/realtime/listeners.d.ts +2 -2
  87. package/dist/realtime/listeners.js.map +1 -1
  88. package/dist/realtime/subscriptions.d.ts +2 -2
  89. package/dist/realtime/subscriptions.js.map +1 -1
  90. package/dist/table/components/bulk-bar.js +5 -5
  91. package/dist/table/components/bulk-bar.js.map +1 -1
  92. package/dist/table/components/cells/badge-cell.js +4 -1
  93. package/dist/table/components/cells/badge-cell.js.map +1 -1
  94. package/dist/table/components/cells/boolean-cell.js +3 -1
  95. package/dist/table/components/cells/boolean-cell.js.map +1 -1
  96. package/dist/table/components/cells/icon-cell.js +5 -2
  97. package/dist/table/components/cells/icon-cell.js.map +1 -1
  98. package/dist/table/components/cells/image-cell.js +8 -9
  99. package/dist/table/components/cells/image-cell.js.map +1 -1
  100. package/dist/table/components/cells/money-cell.js +9 -1
  101. package/dist/table/components/cells/money-cell.js.map +1 -1
  102. package/dist/table/components/cells/number-cell.js +9 -1
  103. package/dist/table/components/cells/number-cell.js.map +1 -1
  104. package/dist/table/components/cells/text-cell.js +4 -1
  105. package/dist/table/components/cells/text-cell.js.map +1 -1
  106. package/dist/table/components/column-filter-control.js +25 -32
  107. package/dist/table/components/column-filter-control.js.map +1 -1
  108. package/dist/table/components/column-header.d.ts +3 -3
  109. package/dist/table/components/column-header.js +5 -3
  110. package/dist/table/components/column-header.js.map +1 -1
  111. package/dist/table/components/column-visibility-menu.js +6 -11
  112. package/dist/table/components/column-visibility-menu.js.map +1 -1
  113. package/dist/table/components/filter-bar.d.ts +2 -2
  114. package/dist/table/components/filter-bar.js +13 -22
  115. package/dist/table/components/filter-bar.js.map +1 -1
  116. package/dist/table/components/filter-controls.d.ts +2 -1
  117. package/dist/table/components/filter-controls.js +36 -35
  118. package/dist/table/components/filter-controls.js.map +1 -1
  119. package/dist/table/components/filter-value-input.d.ts +0 -1
  120. package/dist/table/components/filter-value-input.js +21 -20
  121. package/dist/table/components/filter-value-input.js.map +1 -1
  122. package/dist/table/components/pagination.js +16 -20
  123. package/dist/table/components/pagination.js.map +1 -1
  124. package/dist/table/components/sort-bar.d.ts +3 -3
  125. package/dist/table/components/sort-bar.js +11 -12
  126. package/dist/table/components/sort-bar.js.map +1 -1
  127. package/dist/table/components/table-search.d.ts +9 -0
  128. package/dist/table/components/table-search.js +75 -0
  129. package/dist/table/components/table-search.js.map +1 -0
  130. package/dist/table/components/table.js +72 -19
  131. package/dist/table/components/table.js.map +1 -1
  132. package/dist/table/hooks/use-expanded-rows.d.ts +8 -0
  133. package/dist/table/hooks/use-expanded-rows.js +24 -0
  134. package/dist/table/hooks/use-expanded-rows.js.map +1 -0
  135. package/dist/table/hooks/use-table.d.ts +5 -3
  136. package/dist/table/hooks/use-table.js +56 -44
  137. package/dist/table/hooks/use-table.js.map +1 -1
  138. package/dist/table/lib/payload.d.ts +3 -2
  139. package/dist/table/lib/payload.js +16 -10
  140. package/dist/table/lib/payload.js.map +1 -1
  141. package/dist/table/lib/query.d.ts +5 -5
  142. package/dist/table/lib/query.js +20 -18
  143. package/dist/table/lib/query.js.map +1 -1
  144. package/dist/table/types.d.ts +3 -26
  145. package/dist/toast/callout.js +1 -3
  146. package/dist/toast/callout.js.map +1 -1
  147. package/dist/toast/toast.d.ts +1 -5
  148. package/dist/toast/toast.js +2 -7
  149. package/dist/toast/toast.js.map +1 -1
  150. package/dist/toast/toaster.js +2 -2
  151. package/dist/toast/toaster.js.map +1 -1
  152. package/dist/types/generated.d.ts +263 -188
  153. package/dist/ui/affix-group.d.ts +2 -1
  154. package/dist/ui/affix-group.js +9 -7
  155. package/dist/ui/affix-group.js.map +1 -1
  156. package/dist/ui/avatar.d.ts +3 -0
  157. package/dist/ui/avatar.js +52 -0
  158. package/dist/ui/avatar.js.map +1 -0
  159. package/dist/ui/button.d.ts +3 -1
  160. package/dist/ui/button.js +10 -3
  161. package/dist/ui/button.js.map +1 -1
  162. package/dist/ui/chart-view.js +161 -11
  163. package/dist/ui/chart-view.js.map +1 -1
  164. package/dist/ui/click-behavior.d.ts +1 -1
  165. package/dist/ui/click-behavior.js.map +1 -1
  166. package/dist/ui/color-picker.d.ts +8 -0
  167. package/dist/ui/color-picker.js +59 -0
  168. package/dist/ui/color-picker.js.map +1 -0
  169. package/dist/ui/combobox.d.ts +11 -2
  170. package/dist/ui/combobox.js +51 -8
  171. package/dist/ui/combobox.js.map +1 -1
  172. package/dist/ui/copyable-text.d.ts +7 -0
  173. package/dist/ui/copyable-text.js +21 -13
  174. package/dist/ui/copyable-text.js.map +1 -1
  175. package/dist/ui/fragment.js.map +1 -1
  176. package/dist/ui/heading.js +39 -21
  177. package/dist/ui/heading.js.map +1 -1
  178. package/dist/ui/icon-button.d.ts +22 -0
  179. package/dist/ui/icon-button.js +51 -0
  180. package/dist/ui/icon-button.js.map +1 -0
  181. package/dist/ui/icon.js +10 -11
  182. package/dist/ui/icon.js.map +1 -1
  183. package/dist/ui/image-preview.d.ts +12 -0
  184. package/dist/ui/image-preview.js +65 -0
  185. package/dist/ui/image-preview.js.map +1 -0
  186. package/dist/ui/image.d.ts +3 -0
  187. package/dist/ui/image.js +21 -0
  188. package/dist/ui/image.js.map +1 -0
  189. package/dist/ui/index.d.ts +2 -1
  190. package/dist/ui/index.js +4 -3
  191. package/dist/ui/info-tooltip.js +1 -1
  192. package/dist/ui/info-tooltip.js.map +1 -1
  193. package/dist/ui/input.d.ts +3 -1
  194. package/dist/ui/input.js +2 -2
  195. package/dist/ui/input.js.map +1 -1
  196. package/dist/ui/modal.js +14 -2
  197. package/dist/ui/modal.js.map +1 -1
  198. package/dist/ui/native-select.d.ts +10 -0
  199. package/dist/ui/native-select.js +23 -0
  200. package/dist/ui/native-select.js.map +1 -0
  201. package/dist/ui/plugin.js +11 -1
  202. package/dist/ui/plugin.js.map +1 -1
  203. package/dist/ui/progress.d.ts +3 -0
  204. package/dist/ui/progress.js +114 -0
  205. package/dist/ui/progress.js.map +1 -0
  206. package/dist/ui/separator.d.ts +3 -0
  207. package/dist/ui/separator.js +15 -0
  208. package/dist/ui/separator.js.map +1 -0
  209. package/dist/ui/text.js +5 -10
  210. package/dist/ui/text.js.map +1 -1
  211. package/dist/ui/tree-context.d.ts +33 -0
  212. package/dist/ui/tree-context.js +137 -0
  213. package/dist/ui/tree-context.js.map +1 -0
  214. package/dist/ui/tree.d.ts +19 -0
  215. package/dist/ui/tree.js +187 -0
  216. package/dist/ui/tree.js.map +1 -0
  217. package/dist-standalone/chunks/chart-view-wJmnVu7L.js +36 -0
  218. package/dist-standalone/chunks/date-picker-field-VbH9xrQO.js +1 -0
  219. package/dist-standalone/chunks/jsx-runtime-Drll_-DD.js +1 -0
  220. package/dist-standalone/chunks/locale-CXqr7LPR.js +1 -0
  221. package/dist-standalone/chunks/page-props-AIa5UR6n.js +1 -0
  222. package/dist-standalone/chunks/rich-editor-field-DLQTyt36.js +154 -0
  223. package/dist-standalone/chunks/{subscriptions-B3UuDBmx.js → subscriptions-DY2tj9Im.js} +1 -1
  224. package/dist-standalone/chunks/use-effect-dispatcher-feEs0GCP.js +97 -0
  225. package/dist-standalone/lattice.css +1 -1
  226. package/dist-standalone/lattice.js +15 -15
  227. package/dist-standalone/manifest.json +11 -9
  228. package/dist-standalone/sprite.svg +1 -1
  229. package/package.json +6 -1
  230. package/resources/icons/code-xml.svg +17 -0
  231. package/resources/icons/heading.svg +17 -0
  232. package/dist-standalone/chunks/chart-view-CK5fKIkR.js +0 -36
  233. package/dist-standalone/chunks/date-picker-field-BlCPFhZd.js +0 -1
  234. package/dist-standalone/chunks/jsx-runtime-CJ_btYLc.js +0 -1
  235. package/dist-standalone/chunks/rich-editor-field-DH5dS5c1.js +0 -154
  236. package/dist-standalone/chunks/use-effect-dispatcher-k98Nzf9M.js +0 -97
@@ -1 +1 @@
1
- {"version":3,"file":"filter-value-input.js","names":[],"sources":["../../../resources/js/table/components/filter-value-input.tsx"],"sourcesContent":["import { Icon } from \"@lattice-php/lattice/icons\";\nimport { useEffect, useState } from \"react\";\nimport { controlSurface } from \"@lattice-php/lattice/ui/control\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport type { FilterType } from \"@lattice-php/lattice/types/generated\";\n\nexport const fieldClass = controlSurface({ density: \"compact\" });\n\nexport function FilterValueInput({\n type,\n label,\n value,\n processing,\n withSearchIcon = false,\n grouped = false,\n ariaLabel,\n testId,\n onCommit,\n onClear,\n}: {\n type: FilterType;\n label: string;\n value: string;\n processing: boolean;\n withSearchIcon?: boolean;\n grouped?: boolean;\n ariaLabel?: string;\n testId?: string;\n onCommit: (value: string) => void;\n onClear?: () => void;\n}) {\n const { t } = useT(\"lattice\");\n const [draft, setDraft] = useState(value);\n const inputLabel = ariaLabel ?? t(\"table.filter.filterBy\", \"Filter {{label}}\", { label });\n const groupedClass = grouped ? \"rounded-r-none\" : \"\";\n\n useEffect(() => {\n setDraft(value);\n }, [value]);\n\n if (type === \"boolean\") {\n return (\n <select\n aria-label={inputLabel}\n data-test={testId}\n className={`${fieldClass} ${groupedClass}`}\n disabled={processing}\n value={value}\n onChange={(event) => onCommit(event.target.value)}\n >\n <option value=\"\">{t(\"table.filter.all\", \"All\")}</option>\n <option value=\"true\">{t(\"table.filter.true\", \"True\")}</option>\n <option value=\"false\">{t(\"table.filter.false\", \"False\")}</option>\n </select>\n );\n }\n\n if (type === \"date\") {\n return (\n <input\n type=\"date\"\n aria-label={inputLabel}\n data-test={testId}\n className={`${fieldClass} ${groupedClass}`}\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 w-full min-w-0 items-center\">\n {withSearchIcon && (\n <Icon\n name=\"search\"\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-2 size-lt-icon-md text-lt-muted-fg\"\n />\n )}\n <input\n type={type === \"number\" ? \"number\" : \"text\"}\n aria-label={inputLabel}\n data-test={testId}\n className={`${fieldClass} ${groupedClass} ${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={t(\"table.filter.clear\", \"Clear {{label}} filter\", { label })}\n data-test={testId ? `${testId}-clear` : undefined}\n className=\"absolute right-1 inline-flex size-6 items-center justify-center rounded-lt-sm hover:bg-lt-muted disabled:opacity-50\"\n disabled={processing}\n onClick={onClear}\n >\n <Icon name=\"x\" aria-hidden=\"true\" className=\"size-lt-icon-sm\" />\n </button>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;AAMA,IAAa,aAAa,eAAe,EAAE,SAAS,UAAU,CAAC;AAE/D,SAAgB,iBAAiB,EAC/B,MACA,OACA,OACA,YACA,iBAAiB,OACjB,UAAU,OACV,WACA,QACA,UACA,WAYC;CACD,MAAM,EAAE,MAAM,KAAK,SAAS;CAC5B,MAAM,CAAC,OAAO,YAAY,SAAS,KAAK;CACxC,MAAM,aAAa,aAAa,EAAE,yBAAyB,oBAAoB,EAAE,MAAM,CAAC;CACxF,MAAM,eAAe,UAAU,mBAAmB;CAElD,gBAAgB;EACd,SAAS,KAAK;CAChB,GAAG,CAAC,KAAK,CAAC;CAEV,IAAI,SAAS,WACX,OACE,qBAAC,UAAD;EACE,cAAY;EACZ,aAAW;EACX,WAAW,GAAG,WAAW,GAAG;EAC5B,UAAU;EACH;EACP,WAAW,UAAU,SAAS,MAAM,OAAO,KAAK;YANlD;GAQE,oBAAC,UAAD;IAAQ,OAAM;cAAI,EAAE,oBAAoB,KAAK;GAAU,CAAA;GACvD,oBAAC,UAAD;IAAQ,OAAM;cAAQ,EAAE,qBAAqB,MAAM;GAAU,CAAA;GAC7D,oBAAC,UAAD;IAAQ,OAAM;cAAS,EAAE,sBAAsB,OAAO;GAAU,CAAA;EAC1D;;CAIZ,IAAI,SAAS,QACX,OACE,oBAAC,SAAD;EACE,MAAK;EACL,cAAY;EACZ,aAAW;EACX,WAAW,GAAG,WAAW,GAAG;EAC5B,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,MAAD;IACE,MAAK;IACL,eAAY;IACZ,WAAU;GACX,CAAA;GAEH,oBAAC,SAAD;IACE,MAAM,SAAS,WAAW,WAAW;IACrC,cAAY;IACZ,aAAW;IACX,WAAW,GAAG,WAAW,GAAG,aAAa,GAAG,iBAAiB,SAAS,GAAG,GAAG,UAAU,SAAS;IAC/F,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,EAAE,sBAAsB,0BAA0B,EAAE,MAAM,CAAC;IACvE,aAAW,SAAS,GAAG,OAAO,UAAU,KAAA;IACxC,WAAU;IACV,UAAU;IACV,SAAS;cAET,oBAAC,MAAD;KAAM,MAAK;KAAI,eAAY;KAAO,WAAU;IAAmB,CAAA;GACzD,CAAA;EAEP;;AAET"}
1
+ {"version":3,"file":"filter-value-input.js","names":[],"sources":["../../../resources/js/table/components/filter-value-input.tsx"],"sourcesContent":["import { Icon } from \"@lattice-php/lattice/icons\";\nimport { useEffect, useState } from \"react\";\nimport { IconButton } from \"@lattice-php/lattice/ui/icon-button\";\nimport { Input } from \"@lattice-php/lattice/ui/input\";\nimport { NativeSelect } from \"@lattice-php/lattice/ui/native-select\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport type { FilterType } from \"@lattice-php/lattice/types/generated\";\n\nexport function FilterValueInput({\n type,\n label,\n value,\n processing,\n withSearchIcon = false,\n grouped = false,\n ariaLabel,\n testId,\n onCommit,\n onClear,\n}: {\n type: FilterType;\n label: string;\n value: string;\n processing: boolean;\n withSearchIcon?: boolean;\n grouped?: boolean;\n ariaLabel?: string;\n testId?: string;\n onCommit: (value: string) => void;\n onClear?: () => void;\n}) {\n const { t } = useT(\"lattice\");\n const [draft, setDraft] = useState(value);\n const inputLabel = ariaLabel ?? t(\"table.filter.filter-by\", \"Filter {{label}}\", { label });\n const groupedClass = grouped ? \"rounded-r-none\" : \"\";\n\n useEffect(() => {\n setDraft(value);\n }, [value]);\n\n if (type === \"boolean\") {\n return (\n <NativeSelect\n density=\"compact\"\n aria-label={inputLabel}\n data-test={testId}\n className={groupedClass}\n disabled={processing}\n value={value}\n onChange={(event) => onCommit(event.target.value)}\n >\n <option value=\"\">{t(\"table.filter.all\", \"All\")}</option>\n <option value=\"true\">{t(\"table.filter.true\", \"True\")}</option>\n <option value=\"false\">{t(\"table.filter.false\", \"False\")}</option>\n </NativeSelect>\n );\n }\n\n if (type === \"date\") {\n return (\n <Input\n type=\"date\"\n density=\"compact\"\n aria-label={inputLabel}\n data-test={testId}\n className={groupedClass}\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 w-full min-w-0 items-center\">\n {withSearchIcon && (\n <Icon\n name=\"search\"\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-2 size-lt-icon-md text-lt-muted-fg\"\n />\n )}\n <Input\n type={type === \"number\" ? \"number\" : \"text\"}\n density=\"compact\"\n aria-label={inputLabel}\n data-test={testId}\n className={cn(groupedClass, 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 <IconButton\n size=\"xs\"\n icon=\"x\"\n label={t(\"table.filter.clear\", \"Clear {{label}} filter\", { label })}\n data-test={testId ? `${testId}-clear` : undefined}\n className=\"absolute right-1 size-6\"\n disabled={processing}\n onClick={onClear}\n />\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AASA,SAAgB,iBAAiB,EAC/B,MACA,OACA,OACA,YACA,iBAAiB,OACjB,UAAU,OACV,WACA,QACA,UACA,WAYC;CACD,MAAM,EAAE,MAAM,KAAK,SAAS;CAC5B,MAAM,CAAC,OAAO,YAAY,SAAS,KAAK;CACxC,MAAM,aAAa,aAAa,EAAE,0BAA0B,oBAAoB,EAAE,MAAM,CAAC;CACzF,MAAM,eAAe,UAAU,mBAAmB;CAElD,gBAAgB;EACd,SAAS,KAAK;CAChB,GAAG,CAAC,KAAK,CAAC;CAEV,IAAI,SAAS,WACX,OACE,qBAAC,cAAD;EACE,SAAQ;EACR,cAAY;EACZ,aAAW;EACX,WAAW;EACX,UAAU;EACH;EACP,WAAW,UAAU,SAAS,MAAM,OAAO,KAAK;YAPlD;GASE,oBAAC,UAAD;IAAQ,OAAM;cAAI,EAAE,oBAAoB,KAAK;GAAU,CAAA;GACvD,oBAAC,UAAD;IAAQ,OAAM;cAAQ,EAAE,qBAAqB,MAAM;GAAU,CAAA;GAC7D,oBAAC,UAAD;IAAQ,OAAM;cAAS,EAAE,sBAAsB,OAAO;GAAU,CAAA;EACpD;;CAIlB,IAAI,SAAS,QACX,OACE,oBAAC,OAAD;EACE,MAAK;EACL,SAAQ;EACR,cAAY;EACZ,aAAW;EACX,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,MAAD;IACE,MAAK;IACL,eAAY;IACZ,WAAU;GACX,CAAA;GAEH,oBAAC,OAAD;IACE,MAAM,SAAS,WAAW,WAAW;IACrC,SAAQ;IACR,cAAY;IACZ,aAAW;IACX,WAAW,GAAG,cAAc,kBAAkB,QAAQ,WAAW,MAAM;IACvE,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,YAAD;IACE,MAAK;IACL,MAAK;IACL,OAAO,EAAE,sBAAsB,0BAA0B,EAAE,MAAM,CAAC;IAClE,aAAW,SAAS,GAAG,OAAO,UAAU,KAAA;IACxC,WAAU;IACV,UAAU;IACV,SAAS;GACV,CAAA;EAEA;;AAET"}
@@ -1,4 +1,5 @@
1
1
  import { useT } from "../../i18n/instance.js";
2
+ import { Button } from "../../ui/button.js";
2
3
  import { jsx, jsxs } from "react/jsx-runtime";
3
4
  //#region resources/js/table/components/pagination.tsx
4
5
  function TablePagination({ pagination, currentPage, processing, mode, hasNextPage, visiblePages, infiniteLoaderRef, onPage, onLoadMore }) {
@@ -13,30 +14,27 @@ function TablePagination({ pagination, currentPage, processing, mode, hasNextPag
13
14
  }) }), mode === "infinite" ? /* @__PURE__ */ jsx("div", {
14
15
  ref: infiniteLoaderRef,
15
16
  className: "flex items-center gap-2",
16
- children: pagination.hasMore ? /* @__PURE__ */ jsx("button", {
17
- type: "button",
17
+ children: pagination.hasMore ? /* @__PURE__ */ jsx(Button, {
18
+ variant: "outline",
18
19
  "data-test": "pagination-load-more",
19
- className: "h-lt-control-md rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50",
20
20
  disabled: processing,
21
21
  onClick: onLoadMore,
22
- children: processing ? t("table.pagination.loading", "Loading...") : t("table.pagination.loadMore", "Load more")
22
+ children: processing ? t("table.pagination.loading", "Loading...") : t("table.pagination.load-more", "Load more")
23
23
  }) : /* @__PURE__ */ jsx("span", {
24
24
  className: "text-lt-muted-fg",
25
- children: t("table.pagination.allLoaded", "All rows loaded")
25
+ children: t("table.pagination.all-loaded", "All rows loaded")
26
26
  })
27
27
  }) : mode === "simple" ? /* @__PURE__ */ jsxs("div", {
28
28
  className: "flex items-center gap-2",
29
- children: [/* @__PURE__ */ jsx("button", {
30
- type: "button",
29
+ children: [/* @__PURE__ */ jsx(Button, {
30
+ variant: "outline",
31
31
  "data-test": "pagination-previous",
32
- className: "h-lt-control-md rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50",
33
32
  disabled: processing || currentPage <= 1,
34
33
  onClick: () => onPage(currentPage - 1),
35
34
  children: t("table.pagination.previous", "Previous")
36
- }), /* @__PURE__ */ jsx("button", {
37
- type: "button",
35
+ }), /* @__PURE__ */ jsx(Button, {
36
+ variant: "outline",
38
37
  "data-test": "pagination-next",
39
- className: "h-lt-control-md rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50",
40
38
  disabled: processing || !hasNextPage,
41
39
  onClick: () => onPage(currentPage + 1),
42
40
  children: t("table.pagination.next", "Next")
@@ -44,28 +42,26 @@ function TablePagination({ pagination, currentPage, processing, mode, hasNextPag
44
42
  }) : mode === "table" ? /* @__PURE__ */ jsxs("div", {
45
43
  className: "flex items-center gap-2",
46
44
  children: [
47
- /* @__PURE__ */ jsx("button", {
48
- type: "button",
45
+ /* @__PURE__ */ jsx(Button, {
46
+ variant: "outline",
49
47
  "data-test": "pagination-previous",
50
- className: "h-lt-control-md rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50",
51
48
  disabled: processing || currentPage <= 1,
52
49
  onClick: () => onPage(currentPage - 1),
53
50
  children: t("table.pagination.previous", "Previous")
54
51
  }),
55
- visiblePages.map((pageNumber) => /* @__PURE__ */ jsx("button", {
56
- type: "button",
52
+ visiblePages.map((pageNumber) => /* @__PURE__ */ jsx(Button, {
53
+ variant: "outline",
54
+ size: "icon",
57
55
  "data-test": `pagination-page-${pageNumber}`,
58
- className: "inline-flex size-lt-control-md items-center justify-center rounded-lt-sm border border-lt-border font-medium disabled:opacity-50",
59
56
  disabled: processing || pageNumber === currentPage,
60
57
  "aria-current": pageNumber === currentPage ? "page" : void 0,
61
58
  "aria-label": t("table.pagination.page", "Page {{page}}", { page: pageNumber }),
62
59
  onClick: () => onPage(pageNumber),
63
60
  children: pageNumber
64
61
  }, pageNumber)),
65
- /* @__PURE__ */ jsx("button", {
66
- type: "button",
62
+ /* @__PURE__ */ jsx(Button, {
63
+ variant: "outline",
67
64
  "data-test": "pagination-next",
68
- className: "h-lt-control-md rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50",
69
65
  disabled: processing || !hasNextPage,
70
66
  onClick: () => onPage(currentPage + 1),
71
67
  children: t("table.pagination.next", "Next")
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.js","names":[],"sources":["../../../resources/js/table/components/pagination.tsx"],"sourcesContent":["import type { RefObject } from \"react\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport type { PaginationType } from \"@lattice-php/lattice/types/generated\";\nimport type { TablePagination as TablePaginationData } from \"@lattice-php/lattice/table/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 const { t } = useT(\"lattice\");\n\n return (\n <div\n data-slot=\"table-pagination\"\n className=\"flex items-center justify-between gap-3 border-t border-lt-border p-4 text-sm\"\n >\n <span>\n {pagination.total == null\n ? t(\"table.pagination.page\", \"Page {{page}}\", { page: currentPage })\n : t(\"table.pagination.showing\", \"Showing {{from}}-{{to}} of {{total}}\", {\n from: pagination.from ?? 0,\n to: pagination.to ?? 0,\n total: pagination.total,\n })}\n </span>\n {mode === \"infinite\" ? (\n <div ref={infiniteLoaderRef} className=\"flex items-center gap-2\">\n {pagination.hasMore ? (\n <button\n type=\"button\"\n data-test=\"pagination-load-more\"\n className=\"h-lt-control-md rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50\"\n disabled={processing}\n onClick={onLoadMore}\n >\n {processing\n ? t(\"table.pagination.loading\", \"Loading...\")\n : t(\"table.pagination.loadMore\", \"Load more\")}\n </button>\n ) : (\n <span className=\"text-lt-muted-fg\">\n {t(\"table.pagination.allLoaded\", \"All rows loaded\")}\n </span>\n )}\n </div>\n ) : mode === \"simple\" ? (\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n data-test=\"pagination-previous\"\n className=\"h-lt-control-md 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 {t(\"table.pagination.previous\", \"Previous\")}\n </button>\n <button\n type=\"button\"\n data-test=\"pagination-next\"\n className=\"h-lt-control-md 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 {t(\"table.pagination.next\", \"Next\")}\n </button>\n </div>\n ) : mode === \"table\" ? (\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n data-test=\"pagination-previous\"\n className=\"h-lt-control-md 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 {t(\"table.pagination.previous\", \"Previous\")}\n </button>\n {visiblePages.map((pageNumber) => (\n <button\n key={pageNumber}\n type=\"button\"\n data-test={`pagination-page-${pageNumber}`}\n className=\"inline-flex size-lt-control-md 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={t(\"table.pagination.page\", \"Page {{page}}\", { page: pageNumber })}\n onClick={() => onPage(pageNumber)}\n >\n {pageNumber}\n </button>\n ))}\n <button\n type=\"button\"\n data-test=\"pagination-next\"\n className=\"h-lt-control-md 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 {t(\"table.pagination.next\", \"Next\")}\n </button>\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":";;;AAKA,SAAgB,gBAAgB,EAC9B,YACA,aACA,YACA,MACA,aACA,cACA,mBACA,QACA,cAWC;CACD,MAAM,EAAE,MAAM,KAAK,SAAS;CAE5B,OACE,qBAAC,OAAD;EACE,aAAU;EACV,WAAU;YAFZ,CAIE,oBAAC,QAAD,EAAA,UACG,WAAW,SAAS,OACjB,EAAE,yBAAyB,iBAAiB,EAAE,MAAM,YAAY,CAAC,IACjE,EAAE,4BAA4B,wCAAwC;GACpE,MAAM,WAAW,QAAQ;GACzB,IAAI,WAAW,MAAM;GACrB,OAAO,WAAW;EACpB,CAAC,EACD,CAAA,GACL,SAAS,aACR,oBAAC,OAAD;GAAK,KAAK;GAAmB,WAAU;aACpC,WAAW,UACV,oBAAC,UAAD;IACE,MAAK;IACL,aAAU;IACV,WAAU;IACV,UAAU;IACV,SAAS;cAER,aACG,EAAE,4BAA4B,YAAY,IAC1C,EAAE,6BAA6B,WAAW;GACxC,CAAA,IAER,oBAAC,QAAD;IAAM,WAAU;cACb,EAAE,8BAA8B,iBAAiB;GAC9C,CAAA;EAEL,CAAA,IACH,SAAS,WACX,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,UAAD;IACE,MAAK;IACL,aAAU;IACV,WAAU;IACV,UAAU,cAAc,eAAe;IACvC,eAAe,OAAO,cAAc,CAAC;cAEpC,EAAE,6BAA6B,UAAU;GACpC,CAAA,GACR,oBAAC,UAAD;IACE,MAAK;IACL,aAAU;IACV,WAAU;IACV,UAAU,cAAc,CAAC;IACzB,eAAe,OAAO,cAAc,CAAC;cAEpC,EAAE,yBAAyB,MAAM;GAC5B,CAAA,CACL;OACH,SAAS,UACX,qBAAC,OAAD;GAAK,WAAU;aAAf;IACE,oBAAC,UAAD;KACE,MAAK;KACL,aAAU;KACV,WAAU;KACV,UAAU,cAAc,eAAe;KACvC,eAAe,OAAO,cAAc,CAAC;eAEpC,EAAE,6BAA6B,UAAU;IACpC,CAAA;IACP,aAAa,KAAK,eACjB,oBAAC,UAAD;KAEE,MAAK;KACL,aAAW,mBAAmB;KAC9B,WAAU;KACV,UAAU,cAAc,eAAe;KACvC,gBAAc,eAAe,cAAc,SAAS,KAAA;KACpD,cAAY,EAAE,yBAAyB,iBAAiB,EAAE,MAAM,WAAW,CAAC;KAC5E,eAAe,OAAO,UAAU;eAE/B;IACK,GAVD,UAUC,CACT;IACD,oBAAC,UAAD;KACE,MAAK;KACL,aAAU;KACV,WAAU;KACV,UAAU,cAAc,CAAC;KACzB,eAAe,OAAO,cAAc,CAAC;eAEpC,EAAE,yBAAyB,MAAM;IAC5B,CAAA;GACL;OACH,IACD;;AAET"}
1
+ {"version":3,"file":"pagination.js","names":[],"sources":["../../../resources/js/table/components/pagination.tsx"],"sourcesContent":["import type { RefObject } from \"react\";\nimport { Button } from \"@lattice-php/lattice/ui/button\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport type { PaginationType } from \"@lattice-php/lattice/types/generated\";\nimport type { TablePagination as TablePaginationData } from \"@lattice-php/lattice/table/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 const { t } = useT(\"lattice\");\n\n return (\n <div\n data-slot=\"table-pagination\"\n className=\"flex items-center justify-between gap-3 border-t border-lt-border p-4 text-sm\"\n >\n <span>\n {pagination.total == null\n ? t(\"table.pagination.page\", \"Page {{page}}\", { page: currentPage })\n : t(\"table.pagination.showing\", \"Showing {{from}}-{{to}} of {{total}}\", {\n from: pagination.from ?? 0,\n to: pagination.to ?? 0,\n total: pagination.total,\n })}\n </span>\n {mode === \"infinite\" ? (\n <div ref={infiniteLoaderRef} className=\"flex items-center gap-2\">\n {pagination.hasMore ? (\n <Button\n variant=\"outline\"\n data-test=\"pagination-load-more\"\n disabled={processing}\n onClick={onLoadMore}\n >\n {processing\n ? t(\"table.pagination.loading\", \"Loading...\")\n : t(\"table.pagination.load-more\", \"Load more\")}\n </Button>\n ) : (\n <span className=\"text-lt-muted-fg\">\n {t(\"table.pagination.all-loaded\", \"All rows loaded\")}\n </span>\n )}\n </div>\n ) : mode === \"simple\" ? (\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n data-test=\"pagination-previous\"\n disabled={processing || currentPage <= 1}\n onClick={() => onPage(currentPage - 1)}\n >\n {t(\"table.pagination.previous\", \"Previous\")}\n </Button>\n <Button\n variant=\"outline\"\n data-test=\"pagination-next\"\n disabled={processing || !hasNextPage}\n onClick={() => onPage(currentPage + 1)}\n >\n {t(\"table.pagination.next\", \"Next\")}\n </Button>\n </div>\n ) : mode === \"table\" ? (\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n data-test=\"pagination-previous\"\n disabled={processing || currentPage <= 1}\n onClick={() => onPage(currentPage - 1)}\n >\n {t(\"table.pagination.previous\", \"Previous\")}\n </Button>\n {visiblePages.map((pageNumber) => (\n <Button\n key={pageNumber}\n variant=\"outline\"\n size=\"icon\"\n data-test={`pagination-page-${pageNumber}`}\n disabled={processing || pageNumber === currentPage}\n aria-current={pageNumber === currentPage ? \"page\" : undefined}\n aria-label={t(\"table.pagination.page\", \"Page {{page}}\", { page: pageNumber })}\n onClick={() => onPage(pageNumber)}\n >\n {pageNumber}\n </Button>\n ))}\n <Button\n variant=\"outline\"\n data-test=\"pagination-next\"\n disabled={processing || !hasNextPage}\n onClick={() => onPage(currentPage + 1)}\n >\n {t(\"table.pagination.next\", \"Next\")}\n </Button>\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":";;;;AAMA,SAAgB,gBAAgB,EAC9B,YACA,aACA,YACA,MACA,aACA,cACA,mBACA,QACA,cAWC;CACD,MAAM,EAAE,MAAM,KAAK,SAAS;CAE5B,OACE,qBAAC,OAAD;EACE,aAAU;EACV,WAAU;YAFZ,CAIE,oBAAC,QAAD,EAAA,UACG,WAAW,SAAS,OACjB,EAAE,yBAAyB,iBAAiB,EAAE,MAAM,YAAY,CAAC,IACjE,EAAE,4BAA4B,wCAAwC;GACpE,MAAM,WAAW,QAAQ;GACzB,IAAI,WAAW,MAAM;GACrB,OAAO,WAAW;EACpB,CAAC,EACD,CAAA,GACL,SAAS,aACR,oBAAC,OAAD;GAAK,KAAK;GAAmB,WAAU;aACpC,WAAW,UACV,oBAAC,QAAD;IACE,SAAQ;IACR,aAAU;IACV,UAAU;IACV,SAAS;cAER,aACG,EAAE,4BAA4B,YAAY,IAC1C,EAAE,8BAA8B,WAAW;GACzC,CAAA,IAER,oBAAC,QAAD;IAAM,WAAU;cACb,EAAE,+BAA+B,iBAAiB;GAC/C,CAAA;EAEL,CAAA,IACH,SAAS,WACX,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,QAAD;IACE,SAAQ;IACR,aAAU;IACV,UAAU,cAAc,eAAe;IACvC,eAAe,OAAO,cAAc,CAAC;cAEpC,EAAE,6BAA6B,UAAU;GACpC,CAAA,GACR,oBAAC,QAAD;IACE,SAAQ;IACR,aAAU;IACV,UAAU,cAAc,CAAC;IACzB,eAAe,OAAO,cAAc,CAAC;cAEpC,EAAE,yBAAyB,MAAM;GAC5B,CAAA,CACL;OACH,SAAS,UACX,qBAAC,OAAD;GAAK,WAAU;aAAf;IACE,oBAAC,QAAD;KACE,SAAQ;KACR,aAAU;KACV,UAAU,cAAc,eAAe;KACvC,eAAe,OAAO,cAAc,CAAC;eAEpC,EAAE,6BAA6B,UAAU;IACpC,CAAA;IACP,aAAa,KAAK,eACjB,oBAAC,QAAD;KAEE,SAAQ;KACR,MAAK;KACL,aAAW,mBAAmB;KAC9B,UAAU,cAAc,eAAe;KACvC,gBAAc,eAAe,cAAc,SAAS,KAAA;KACpD,cAAY,EAAE,yBAAyB,iBAAiB,EAAE,MAAM,WAAW,CAAC;KAC5E,eAAe,OAAO,UAAU;eAE/B;IACK,GAVD,UAUC,CACT;IACD,oBAAC,QAAD;KACE,SAAQ;KACR,aAAU;KACV,UAAU,cAAc,CAAC;KACzB,eAAe,OAAO,cAAc,CAAC;eAEpC,EAAE,yBAAyB,MAAM;IAC5B,CAAA;GACL;OACH,IACD;;AAET"}
@@ -1,7 +1,7 @@
1
- import { TableColumn, TableSort, TableState } from '../types.js';
2
- export declare function SortBar({ columnsByKey, state, processing, onClear, }: {
1
+ import { TableColumn, TableSort, TableQuery } from '../types.js';
2
+ export declare function SortBar({ columnsByKey, query, processing, onClear, }: {
3
3
  columnsByKey: Map<string, TableColumn>;
4
- state: TableState;
4
+ query: TableQuery;
5
5
  processing: boolean;
6
6
  onClear: (sort: TableSort) => void;
7
7
  }): import("react").JSX.Element;
@@ -1,11 +1,14 @@
1
1
  import { Icon } from "../../icons/sprite.js";
2
+ import { useT } from "../../i18n/instance.js";
3
+ import { IconButton } from "../../ui/icon-button.js";
2
4
  import { getSortDirectionLabel } from "../lib/query.js";
3
5
  import { jsx, jsxs } from "react/jsx-runtime";
4
6
  //#region resources/js/table/components/sort-bar.tsx
5
- function SortBar({ columnsByKey, state, processing, onClear }) {
7
+ function SortBar({ columnsByKey, query, processing, onClear }) {
8
+ const { t } = useT("lattice");
6
9
  return /* @__PURE__ */ jsx("div", {
7
10
  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) => {
11
+ children: query.sorts.map((sort, index) => {
9
12
  const label = columnsByKey.get(sort.key)?.props.label ?? sort.key;
10
13
  const arrow = sort.direction === "desc" ? "arrow-down" : "arrow-up";
11
14
  return /* @__PURE__ */ jsxs("span", {
@@ -22,17 +25,13 @@ function SortBar({ columnsByKey, state, processing, onClear }) {
22
25
  "aria-label": getSortDirectionLabel(sort.direction),
23
26
  className: "size-lt-icon-sm text-lt-muted-fg"
24
27
  }),
25
- /* @__PURE__ */ jsx("button", {
26
- type: "button",
27
- className: "inline-flex size-5 items-center justify-center rounded-lt-sm text-lt-muted-fg hover:bg-lt-muted disabled:opacity-50",
28
- disabled: processing,
29
- "aria-label": `Clear ${label} sort`,
28
+ /* @__PURE__ */ jsx(IconButton, {
29
+ size: "xs",
30
+ icon: "x",
31
+ label: t("table.sort.clear", "Clear {{label}} sort", { label }),
30
32
  "data-test": `clear-${sort.key}-sort`,
31
- onClick: () => onClear(sort),
32
- children: /* @__PURE__ */ jsx(Icon, {
33
- name: "x",
34
- className: "size-lt-icon-sm"
35
- })
33
+ disabled: processing,
34
+ onClick: () => onClear(sort)
36
35
  })
37
36
  ]
38
37
  }, sort.key);
@@ -1 +1 @@
1
- {"version":3,"file":"sort-bar.js","names":[],"sources":["../../../resources/js/table/components/sort-bar.tsx"],"sourcesContent":["import { Icon } from \"@lattice-php/lattice/icons\";\nimport { getSortDirectionLabel } from \"@lattice-php/lattice/table/lib/query\";\nimport type { TableColumn, TableSort, TableState } from \"@lattice-php/lattice/table/types\";\n\nexport function SortBar({\n columnsByKey,\n state,\n processing,\n onClear,\n}: {\n columnsByKey: Map<string, 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 = columnsByKey.get(sort.key);\n const label = column?.props.label ?? sort.key;\n const arrow = sort.direction === \"desc\" ? \"arrow-down\" : \"arrow-up\";\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 <Icon\n name={arrow}\n role=\"img\"\n aria-hidden={false}\n aria-label={getSortDirectionLabel(sort.direction)}\n className=\"size-lt-icon-sm text-lt-muted-fg\"\n />\n <button\n type=\"button\"\n className=\"inline-flex size-5 items-center justify-center rounded-lt-sm 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 <Icon name=\"x\" className=\"size-lt-icon-sm\" />\n </button>\n </span>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;;AAIA,SAAgB,QAAQ,EACtB,cACA,OACA,YACA,WAMC;CACD,OACE,oBAAC,OAAD;EAAK,WAAU;YACZ,MAAM,MAAM,KAAK,MAAM,UAAU;GAEhC,MAAM,QADS,aAAa,IAAI,KAAK,GACvB,GAAQ,MAAM,SAAS,KAAK;GAC1C,MAAM,QAAQ,KAAK,cAAc,SAAS,eAAe;GAEzD,OACE,qBAAC,QAAD;IAAqB,WAAU;cAA/B;KACE,oBAAC,QAAD;MAAM,WAAU;gBAAe,GAAG,QAAQ,EAAE,IAAI;KAAc,CAAA;KAC9D,oBAAC,MAAD;MACE,MAAM;MACN,MAAK;MACL,eAAa;MACb,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,MAAD;OAAM,MAAK;OAAI,WAAU;MAAmB,CAAA;KACtC,CAAA;IACJ;MAnBK,KAAK,GAmBV;EAEV,CAAC;CACE,CAAA;AAET"}
1
+ {"version":3,"file":"sort-bar.js","names":[],"sources":["../../../resources/js/table/components/sort-bar.tsx"],"sourcesContent":["import { Icon } from \"@lattice-php/lattice/icons\";\nimport { IconButton } from \"@lattice-php/lattice/ui/icon-button\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { getSortDirectionLabel } from \"@lattice-php/lattice/table/lib/query\";\nimport type { TableColumn, TableSort, TableQuery } from \"@lattice-php/lattice/table/types\";\n\nexport function SortBar({\n columnsByKey,\n query,\n processing,\n onClear,\n}: {\n columnsByKey: Map<string, TableColumn>;\n query: TableQuery;\n processing: boolean;\n onClear: (sort: TableSort) => void;\n}) {\n const { t } = useT(\"lattice\");\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 {query.sorts.map((sort, index) => {\n const column = columnsByKey.get(sort.key);\n const label = column?.props.label ?? sort.key;\n const arrow = sort.direction === \"desc\" ? \"arrow-down\" : \"arrow-up\";\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 <Icon\n name={arrow}\n role=\"img\"\n aria-hidden={false}\n aria-label={getSortDirectionLabel(sort.direction)}\n className=\"size-lt-icon-sm text-lt-muted-fg\"\n />\n <IconButton\n size=\"xs\"\n icon=\"x\"\n label={t(\"table.sort.clear\", \"Clear {{label}} sort\", { label })}\n data-test={`clear-${sort.key}-sort`}\n disabled={processing}\n onClick={() => onClear(sort)}\n />\n </span>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;;;;AAMA,SAAgB,QAAQ,EACtB,cACA,OACA,YACA,WAMC;CACD,MAAM,EAAE,MAAM,KAAK,SAAS;CAE5B,OACE,oBAAC,OAAD;EAAK,WAAU;YACZ,MAAM,MAAM,KAAK,MAAM,UAAU;GAEhC,MAAM,QADS,aAAa,IAAI,KAAK,GACvB,GAAQ,MAAM,SAAS,KAAK;GAC1C,MAAM,QAAQ,KAAK,cAAc,SAAS,eAAe;GAEzD,OACE,qBAAC,QAAD;IAAqB,WAAU;cAA/B;KACE,oBAAC,QAAD;MAAM,WAAU;gBAAe,GAAG,QAAQ,EAAE,IAAI;KAAc,CAAA;KAC9D,oBAAC,MAAD;MACE,MAAM;MACN,MAAK;MACL,eAAa;MACb,cAAY,sBAAsB,KAAK,SAAS;MAChD,WAAU;KACX,CAAA;KACD,oBAAC,YAAD;MACE,MAAK;MACL,MAAK;MACL,OAAO,EAAE,oBAAoB,wBAAwB,EAAE,MAAM,CAAC;MAC9D,aAAW,SAAS,KAAK,IAAI;MAC7B,UAAU;MACV,eAAe,QAAQ,IAAI;KAC5B,CAAA;IACG;MAjBK,KAAK,GAiBV;EAEV,CAAC;CACE,CAAA;AAET"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * The table-level quick-search box. Keystrokes update the input immediately and
3
+ * commit the term to the server after a short debounce; an externally-changed
4
+ * value (e.g. a filter reset) is adopted without echoing keystroke round-trips.
5
+ */
6
+ export declare function TableSearch({ value, onSearch, }: {
7
+ value: string;
8
+ onSearch: (term: string) => void;
9
+ }): import("react").JSX.Element;
@@ -0,0 +1,75 @@
1
+ import { cn } from "../../lib/utils.js";
2
+ import { Icon } from "../../icons/sprite.js";
3
+ import { useT } from "../../i18n/instance.js";
4
+ import { Input } from "../../ui/input.js";
5
+ import { IconButton } from "../../ui/icon-button.js";
6
+ import { useEffect, useRef, useState } from "react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ //#region resources/js/table/components/table-search.tsx
9
+ var DEBOUNCE_MS = 300;
10
+ /**
11
+ * The table-level quick-search box. Keystrokes update the input immediately and
12
+ * commit the term to the server after a short debounce; an externally-changed
13
+ * value (e.g. a filter reset) is adopted without echoing keystroke round-trips.
14
+ */
15
+ function TableSearch({ value, onSearch }) {
16
+ const { t } = useT("lattice");
17
+ const [term, setTerm] = useState(value);
18
+ const timer = useRef(null);
19
+ const committed = useRef(value);
20
+ useEffect(() => {
21
+ if (value !== committed.current) {
22
+ committed.current = value;
23
+ setTerm(value);
24
+ }
25
+ }, [value]);
26
+ useEffect(() => () => {
27
+ if (timer.current) clearTimeout(timer.current);
28
+ }, []);
29
+ function commit(next) {
30
+ committed.current = next;
31
+ onSearch(next);
32
+ }
33
+ function change(next) {
34
+ setTerm(next);
35
+ if (timer.current) clearTimeout(timer.current);
36
+ timer.current = setTimeout(() => commit(next), DEBOUNCE_MS);
37
+ }
38
+ function clear() {
39
+ if (timer.current) clearTimeout(timer.current);
40
+ setTerm("");
41
+ commit("");
42
+ }
43
+ const label = t("table.search.placeholder", "Search");
44
+ return /* @__PURE__ */ jsxs("div", {
45
+ className: "relative w-full max-w-xs",
46
+ children: [
47
+ /* @__PURE__ */ jsx(Icon, {
48
+ name: "search",
49
+ "aria-hidden": "true",
50
+ className: "pointer-events-none absolute left-2.5 top-1/2 size-lt-icon-sm -translate-y-1/2 text-lt-muted-fg"
51
+ }),
52
+ /* @__PURE__ */ jsx(Input, {
53
+ type: "search",
54
+ "data-test": "table-search",
55
+ value: term,
56
+ placeholder: label,
57
+ "aria-label": label,
58
+ onChange: (event) => change(event.target.value),
59
+ className: cn("px-8", "[&::-webkit-search-cancel-button]:hidden")
60
+ }),
61
+ term !== "" && /* @__PURE__ */ jsx(IconButton, {
62
+ size: "xs",
63
+ icon: "x",
64
+ label: t("table.search.clear", "Clear search"),
65
+ "data-test": "table-search-clear",
66
+ className: "absolute right-1.5 top-1/2 -translate-y-1/2",
67
+ onClick: clear
68
+ })
69
+ ]
70
+ });
71
+ }
72
+ //#endregion
73
+ export { TableSearch };
74
+
75
+ //# sourceMappingURL=table-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-search.js","names":[],"sources":["../../../resources/js/table/components/table-search.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { Icon } from \"@lattice-php/lattice/icons\";\nimport { IconButton } from \"@lattice-php/lattice/ui/icon-button\";\nimport { Input } from \"@lattice-php/lattice/ui/input\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\n\nconst DEBOUNCE_MS = 300;\n\n/**\n * The table-level quick-search box. Keystrokes update the input immediately and\n * commit the term to the server after a short debounce; an externally-changed\n * value (e.g. a filter reset) is adopted without echoing keystroke round-trips.\n */\nexport function TableSearch({\n value,\n onSearch,\n}: {\n value: string;\n onSearch: (term: string) => void;\n}) {\n const { t } = useT(\"lattice\");\n const [term, setTerm] = useState(value);\n const timer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const committed = useRef(value);\n\n useEffect(() => {\n if (value !== committed.current) {\n committed.current = value;\n setTerm(value);\n }\n }, [value]);\n\n useEffect(\n () => () => {\n if (timer.current) {\n clearTimeout(timer.current);\n }\n },\n [],\n );\n\n function commit(next: string): void {\n committed.current = next;\n onSearch(next);\n }\n\n function change(next: string): void {\n setTerm(next);\n\n if (timer.current) {\n clearTimeout(timer.current);\n }\n\n timer.current = setTimeout(() => commit(next), DEBOUNCE_MS);\n }\n\n function clear(): void {\n if (timer.current) {\n clearTimeout(timer.current);\n }\n\n setTerm(\"\");\n commit(\"\");\n }\n\n const label = t(\"table.search.placeholder\", \"Search\");\n\n return (\n <div className=\"relative w-full max-w-xs\">\n <Icon\n name=\"search\"\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-2.5 top-1/2 size-lt-icon-sm -translate-y-1/2 text-lt-muted-fg\"\n />\n <Input\n type=\"search\"\n data-test=\"table-search\"\n value={term}\n placeholder={label}\n aria-label={label}\n onChange={(event) => change(event.target.value)}\n className={cn(\"px-8\", \"[&::-webkit-search-cancel-button]:hidden\")}\n />\n {term !== \"\" && (\n <IconButton\n size=\"xs\"\n icon=\"x\"\n label={t(\"table.search.clear\", \"Clear search\")}\n data-test=\"table-search-clear\"\n className=\"absolute right-1.5 top-1/2 -translate-y-1/2\"\n onClick={clear}\n />\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;AAOA,IAAM,cAAc;;;;;;AAOpB,SAAgB,YAAY,EAC1B,OACA,YAIC;CACD,MAAM,EAAE,MAAM,KAAK,SAAS;CAC5B,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,QAAQ,OAA6C,IAAI;CAC/D,MAAM,YAAY,OAAO,KAAK;CAE9B,gBAAgB;EACd,IAAI,UAAU,UAAU,SAAS;GAC/B,UAAU,UAAU;GACpB,QAAQ,KAAK;EACf;CACF,GAAG,CAAC,KAAK,CAAC;CAEV,sBACc;EACV,IAAI,MAAM,SACR,aAAa,MAAM,OAAO;CAE9B,GACA,CAAC,CACH;CAEA,SAAS,OAAO,MAAoB;EAClC,UAAU,UAAU;EACpB,SAAS,IAAI;CACf;CAEA,SAAS,OAAO,MAAoB;EAClC,QAAQ,IAAI;EAEZ,IAAI,MAAM,SACR,aAAa,MAAM,OAAO;EAG5B,MAAM,UAAU,iBAAiB,OAAO,IAAI,GAAG,WAAW;CAC5D;CAEA,SAAS,QAAc;EACrB,IAAI,MAAM,SACR,aAAa,MAAM,OAAO;EAG5B,QAAQ,EAAE;EACV,OAAO,EAAE;CACX;CAEA,MAAM,QAAQ,EAAE,4BAA4B,QAAQ;CAEpD,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf;GACE,oBAAC,MAAD;IACE,MAAK;IACL,eAAY;IACZ,WAAU;GACX,CAAA;GACD,oBAAC,OAAD;IACE,MAAK;IACL,aAAU;IACV,OAAO;IACP,aAAa;IACb,cAAY;IACZ,WAAW,UAAU,OAAO,MAAM,OAAO,KAAK;IAC9C,WAAW,GAAG,QAAQ,0CAA0C;GACjE,CAAA;GACA,SAAS,MACR,oBAAC,YAAD;IACE,MAAK;IACL,MAAK;IACL,OAAO,EAAE,sBAAsB,cAAc;IAC7C,aAAU;IACV,WAAU;IACV,SAAS;GACV,CAAA;EAEA;;AAET"}
@@ -1,13 +1,15 @@
1
1
  import { cn } from "../../lib/utils.js";
2
2
  import { Icon } from "../../icons/sprite.js";
3
+ import { Renderer } from "../../core/renderer.js";
3
4
  import { useT } from "../../i18n/instance.js";
4
5
  import { nodeIdentity } from "../../core/test-id.js";
5
6
  import { useColumnResizing } from "../../core/hooks/use-column-resizing.js";
6
7
  import { Checkbox } from "../../ui/checkbox.js";
7
8
  import { useColumnVisibility } from "../hooks/use-column-visibility.js";
9
+ import { useExpandedRows } from "../hooks/use-expanded-rows.js";
8
10
  import { alignJustifyItems, alignText } from "../lib/align.js";
9
11
  import { getBulkActions } from "../lib/bulk.js";
10
- import { getRowActions, getRowKey } from "../lib/payload.js";
12
+ import { getRowActions, getRowDetail, getRowKey } from "../lib/payload.js";
11
13
  import { getQueryParams, getTableSizingColumns, getTableUtilityTracks, getVisiblePages } from "../lib/query.js";
12
14
  import { useTable } from "../hooks/use-table.js";
13
15
  import { useTableSelection } from "../hooks/use-table-selection.js";
@@ -18,29 +20,33 @@ import { ColumnVisibilityMenu } from "./column-visibility-menu.js";
18
20
  import { FilterBar, FilterMenu } from "./filter-bar.js";
19
21
  import { TablePagination } from "./pagination.js";
20
22
  import { SortBar } from "./sort-bar.js";
23
+ import { TableSearch } from "./table-search.js";
21
24
  import { TableActionNode } from "./table-action-node.js";
22
25
  import { ColumnCell } from "./table-cell.js";
23
- import { useMemo } from "react";
26
+ import { Fragment, useMemo } from "react";
24
27
  import { jsx, jsxs } from "react/jsx-runtime";
25
28
  //#region resources/js/table/components/table.tsx
26
29
  var TableComponent = ({ node }) => {
27
30
  const { t } = useT("lattice");
28
- const { columns, rows, pagination, state, filters, tableFilters, addFilter, updateFilter, removeFilter, replaceColumnFilters, setTableFilter, resetFilters, searchFilterOptions, processing, hasLoaded, infiniteLoaderRef, sort, clearSort, goToPage, loadMore } = useTable(node);
31
+ const { columns, rows, pagination, query, filters, tableFilters, search, addFilter, updateFilter, removeFilter, replaceColumnFilters, setTableFilter, resetFilters, setSearch, searchFilterOptions, processing, hasLoaded, infiniteLoaderRef, sort, clearSort, goToPage, loadMore } = useTable(node);
29
32
  const bulkActions = useMemo(() => getBulkActions(node.props?.bulkActions), [node.props?.bulkActions]);
30
33
  const hasBulkActions = bulkActions.length > 0;
31
34
  const rowEntries = useMemo(() => rows.map((row, index) => ({
32
35
  row,
33
36
  actions: getRowActions(row),
37
+ detail: getRowDetail(row),
34
38
  key: getRowKey(row, index)
35
39
  })), [rows]);
36
40
  const selection = useTableSelection(rowEntries.map((entry) => entry.key));
41
+ const { isExpanded, toggle: toggleRow } = useExpandedRows();
42
+ const hasExpandable = rowEntries.some((entry) => entry.detail != null);
37
43
  const columnsByKey = useMemo(() => new Map(columns.map((column) => [column.key, column])), [columns]);
38
44
  const visibilityIdentity = nodeIdentity(node);
39
45
  const { hasToggleableColumns, hasHidden, isVisible, resetVisibility, setColumnVisible, toggleableColumns, visibleColumns } = useColumnVisibility({
40
46
  columns,
41
47
  storageKey: visibilityIdentity ? `lattice:table-column-visibility:${visibilityIdentity}` : void 0
42
48
  });
43
- const currentPage = pagination.currentPage ?? state.page;
49
+ const currentPage = pagination.currentPage ?? query.page;
44
50
  const lastPage = pagination.lastPage ?? currentPage;
45
51
  const mode = pagination.mode ?? "table";
46
52
  const visiblePages = getVisiblePages(currentPage, lastPage);
@@ -56,7 +62,11 @@ var TableComponent = ({ node }) => {
56
62
  const hasDedicatedFilters = filterDefinitions.length > 0;
57
63
  const hasTrailingUtility = hasActions || hasDedicatedFilters || hasToggleableColumns;
58
64
  const sizingColumns = useMemo(() => getTableSizingColumns(visibleColumns), [visibleColumns]);
59
- const utilityTracks = useMemo(() => getTableUtilityTracks(hasTrailingUtility, hasBulkActions), [hasTrailingUtility, hasBulkActions]);
65
+ const utilityTracks = useMemo(() => getTableUtilityTracks(hasTrailingUtility, hasBulkActions, hasExpandable), [
66
+ hasTrailingUtility,
67
+ hasBulkActions,
68
+ hasExpandable
69
+ ]);
60
70
  const resizingEnabled = node.props?.resizableColumns === true;
61
71
  const resizeStorageIdentity = nodeIdentity(node);
62
72
  const { getResizeHandleProps, gridTemplateColumns, hasOverrides, resizeRootRef, resetColumns } = useColumnResizing({
@@ -72,11 +82,11 @@ var TableComponent = ({ node }) => {
72
82
  "data-lattice-component": node.id,
73
83
  className: "relative",
74
84
  children: [hasOverrides && /* @__PURE__ */ jsx("button", {
75
- "aria-label": t("table.resetColumnWidths", "Reset column widths"),
85
+ "aria-label": t("table.reset-column-widths", "Reset column widths"),
76
86
  className: "absolute right-1 top-1 z-10 hidden rounded-lt-sm p-1 text-lt-muted-fg hover:text-lt-fg md:inline-flex",
77
87
  "data-test": "table-reset-columns",
78
88
  onClick: resetColumns,
79
- title: t("table.resetColumnWidths", "Reset column widths"),
89
+ title: t("table.reset-column-widths", "Reset column widths"),
80
90
  type: "button",
81
91
  children: /* @__PURE__ */ jsx(Icon, {
82
92
  name: "rotate-ccw",
@@ -86,10 +96,18 @@ var TableComponent = ({ node }) => {
86
96
  "data-slot": "table-scroll",
87
97
  className: "overflow-x-auto rounded-lt-sm border border-lt-border",
88
98
  children: [
99
+ node.props?.searchable && /* @__PURE__ */ jsx("div", {
100
+ "data-slot": "table-toolbar",
101
+ className: "flex items-center gap-2 border-b border-lt-border px-4 py-2",
102
+ children: /* @__PURE__ */ jsx(TableSearch, {
103
+ value: search,
104
+ onSearch: setSearch
105
+ })
106
+ }),
89
107
  /* @__PURE__ */ jsx(FilterBar, {
90
108
  clauses: filters,
91
109
  columnsByKey,
92
- indicators: state.tableFilterIndicators,
110
+ indicators: query.tableFilterIndicators,
93
111
  processing,
94
112
  onRemoveClause: removeFilter,
95
113
  onChange: setTableFilter,
@@ -100,14 +118,14 @@ var TableComponent = ({ node }) => {
100
118
  selectedKeys: selection.selectedKeys,
101
119
  allMatching: selection.allMatching,
102
120
  total: pagination.total ?? void 0,
103
- query: getQueryParams(state),
121
+ query: getQueryParams(query),
104
122
  canSelectAllMatching: selection.allVisibleSelected && !selection.allMatching && pagination.total != null && pagination.total > selection.selectedKeys.length,
105
123
  onSelectAllMatching: selection.selectAllMatching,
106
124
  onCompleted: selection.clear
107
125
  }),
108
- state.sorts.length > 0 && /* @__PURE__ */ jsx(SortBar, {
126
+ query.sorts.length > 0 && /* @__PURE__ */ jsx(SortBar, {
109
127
  columnsByKey,
110
- state,
128
+ query,
111
129
  processing,
112
130
  onClear: clearSort
113
131
  }),
@@ -124,11 +142,16 @@ var TableComponent = ({ node }) => {
124
142
  className: "hidden min-w-full md:grid md:grid-cols-[var(--lattice-table-columns)]",
125
143
  role: "row",
126
144
  children: [
145
+ hasExpandable && /* @__PURE__ */ jsx("div", {
146
+ className: "px-2 py-3",
147
+ role: "columnheader",
148
+ "aria-hidden": "true"
149
+ }),
127
150
  hasBulkActions && /* @__PURE__ */ jsx("div", {
128
151
  className: "flex items-center px-4 py-3",
129
152
  role: "columnheader",
130
153
  children: /* @__PURE__ */ jsx(Checkbox, {
131
- "aria-label": t("table.selectAllRows", "Select all rows"),
154
+ "aria-label": t("table.select-all-rows", "Select all rows"),
132
155
  "data-test": "select-all",
133
156
  checked: selection.allSelected,
134
157
  onCheckedChange: () => selection.toggleAll()
@@ -139,7 +162,7 @@ var TableComponent = ({ node }) => {
139
162
  processing,
140
163
  resizeHandleProps: resizingEnabled ? getResizeHandleProps(sizingColumns[index]) : void 0,
141
164
  sort,
142
- state
165
+ query
143
166
  }, column.key)),
144
167
  hasTrailingUtility && /* @__PURE__ */ jsxs("div", {
145
168
  className: "flex items-center justify-end gap-2 px-4 py-2 align-middle font-semibold text-lt-fg",
@@ -163,7 +186,7 @@ var TableComponent = ({ node }) => {
163
186
  }),
164
187
  hasActions && /* @__PURE__ */ jsx("span", {
165
188
  className: "sr-only",
166
- children: node.props?.actionsLabel
189
+ children: node.props?.actionsLabel ?? t("table.actions", "Actions")
167
190
  })
168
191
  ]
169
192
  })
@@ -172,6 +195,10 @@ var TableComponent = ({ node }) => {
172
195
  className: "hidden min-w-full border-t border-lt-border md:grid md:grid-cols-[var(--lattice-table-columns)]",
173
196
  role: "row",
174
197
  children: [
198
+ hasExpandable && /* @__PURE__ */ jsx("div", {
199
+ className: "px-2 py-2",
200
+ role: "cell"
201
+ }),
175
202
  hasBulkActions && /* @__PURE__ */ jsx("div", {
176
203
  className: "px-4 py-2",
177
204
  role: "cell"
@@ -211,19 +238,39 @@ var TableComponent = ({ node }) => {
211
238
  role: "row",
212
239
  children: /* @__PURE__ */ jsx("div", {
213
240
  role: "cell",
214
- children: node.props?.emptyLabel
241
+ children: node.props?.emptyLabel ?? t("table.empty", "No results")
215
242
  })
216
- }) : rowEntries.map(({ row, actions, key }) => {
217
- return /* @__PURE__ */ jsxs("div", {
243
+ }) : rowEntries.map(({ row, actions, detail, key }) => {
244
+ const expanded = detail != null && isExpanded(key);
245
+ const detailId = `${nodeIdentity(node) ?? "table"}-row-detail-${key}`;
246
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
218
247
  "data-slot": "table-row",
219
248
  className: `grid grid-cols-1 border-b border-lt-border last:border-b-0 md:grid-cols-[var(--lattice-table-columns)] ${striped ? "odd:bg-lt-muted/30" : ""}`,
220
249
  role: "row",
221
250
  children: [
251
+ hasExpandable && /* @__PURE__ */ jsx("div", {
252
+ className: "flex items-center px-2 py-lt-cell-y",
253
+ role: "cell",
254
+ children: detail && /* @__PURE__ */ jsx("button", {
255
+ type: "button",
256
+ "data-test": `row-expand-${key}`,
257
+ "aria-expanded": expanded,
258
+ "aria-controls": detailId,
259
+ "aria-label": t("table.row-detail.toggle", "Toggle detail"),
260
+ className: "inline-flex size-6 items-center justify-center rounded-lt-sm text-lt-muted-fg hover:bg-lt-muted hover:text-lt-fg",
261
+ onClick: () => toggleRow(key),
262
+ children: /* @__PURE__ */ jsx(Icon, {
263
+ name: "chevron-down",
264
+ "aria-hidden": "true",
265
+ className: cn("size-lt-icon-md transition-transform", !expanded && "-rotate-90")
266
+ })
267
+ })
268
+ }),
222
269
  hasBulkActions && /* @__PURE__ */ jsx("div", {
223
270
  className: "flex items-center px-lt-cell-x py-lt-cell-y",
224
271
  role: "cell",
225
272
  children: /* @__PURE__ */ jsx(Checkbox, {
226
- "aria-label": t("table.selectRow", "Select row {{key}}", { key }),
273
+ "aria-label": t("table.select-row", "Select row {{key}}", { key }),
227
274
  "data-test": `select-row-${key}`,
228
275
  checked: selection.isSelected(key),
229
276
  onCheckedChange: () => selection.toggle(key)
@@ -252,7 +299,13 @@ var TableComponent = ({ node }) => {
252
299
  children: actions.map((action, actionIndex) => /* @__PURE__ */ jsx(TableActionNode, { node: action }, action.key ?? action.id ?? actionIndex))
253
300
  })
254
301
  ]
255
- }, key);
302
+ }), expanded && detail && /* @__PURE__ */ jsx("div", {
303
+ id: detailId,
304
+ role: "region",
305
+ "data-slot": "table-row-detail",
306
+ className: "border-b border-lt-border bg-lt-muted/20 px-lt-cell-x py-lt-cell-y",
307
+ children: /* @__PURE__ */ jsx(Renderer, { nodes: [detail] })
308
+ })] }, key);
256
309
  })
257
310
  })]
258
311
  }),