@aglyn/shared-ui-jsx 1.0.0-beta.143

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 (261) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +7 -0
  3. package/package.json +63 -0
  4. package/src/index.d.ts +48 -0
  5. package/src/index.js +179 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/components/aglyn-text.d.ts +86 -0
  8. package/src/lib/components/aglyn-text.js +44 -0
  9. package/src/lib/components/aglyn-text.js.map +1 -0
  10. package/src/lib/components/app-link.d.ts +74 -0
  11. package/src/lib/components/app-link.js +139 -0
  12. package/src/lib/components/app-link.js.map +1 -0
  13. package/src/lib/components/aspect-ratio.d.ts +59 -0
  14. package/src/lib/components/aspect-ratio.js +153 -0
  15. package/src/lib/components/aspect-ratio.js.map +1 -0
  16. package/src/lib/components/background-image.component.d.ts +30 -0
  17. package/src/lib/components/background-image.component.js +42 -0
  18. package/src/lib/components/background-image.component.js.map +1 -0
  19. package/src/lib/components/card-columns.d.ts +86 -0
  20. package/src/lib/components/card-columns.js +148 -0
  21. package/src/lib/components/card-columns.js.map +1 -0
  22. package/src/lib/components/card-display.d.ts +36 -0
  23. package/src/lib/components/card-display.js +158 -0
  24. package/src/lib/components/card-display.js.map +1 -0
  25. package/src/lib/components/card-list-item.d.ts +35 -0
  26. package/src/lib/components/card-list-item.js +137 -0
  27. package/src/lib/components/card-list-item.js.map +1 -0
  28. package/src/lib/components/children-function-prop.d.ts +25 -0
  29. package/src/lib/components/children-function-prop.js +29 -0
  30. package/src/lib/components/children-function-prop.js.map +1 -0
  31. package/src/lib/components/confirmation-provider.component.d.ts +19 -0
  32. package/src/lib/components/confirmation-provider.component.js +83 -0
  33. package/src/lib/components/confirmation-provider.component.js.map +1 -0
  34. package/src/lib/components/container.d.ts +25 -0
  35. package/src/lib/components/container.js +62 -0
  36. package/src/lib/components/container.js.map +1 -0
  37. package/src/lib/components/data-table.component.d.ts +54 -0
  38. package/src/lib/components/data-table.component.js +211 -0
  39. package/src/lib/components/data-table.component.js.map +1 -0
  40. package/src/lib/components/dialog-confirm.d.ts +36 -0
  41. package/src/lib/components/dialog-confirm.js +74 -0
  42. package/src/lib/components/dialog-confirm.js.map +1 -0
  43. package/src/lib/components/ellipsis-pulse.component.d.ts +22 -0
  44. package/src/lib/components/ellipsis-pulse.component.js +51 -0
  45. package/src/lib/components/ellipsis-pulse.component.js.map +1 -0
  46. package/src/lib/components/emotion-cache-provider.d.ts +31 -0
  47. package/src/lib/components/emotion-cache-provider.js +40 -0
  48. package/src/lib/components/emotion-cache-provider.js.map +1 -0
  49. package/src/lib/components/empty-state.component.d.ts +63 -0
  50. package/src/lib/components/empty-state.component.js +214 -0
  51. package/src/lib/components/empty-state.component.js.map +1 -0
  52. package/src/lib/components/error-boundary.component.d.ts +28 -0
  53. package/src/lib/components/error-boundary.component.js +86 -0
  54. package/src/lib/components/error-boundary.component.js.map +1 -0
  55. package/src/lib/components/grid-buttons.d.ts +26 -0
  56. package/src/lib/components/grid-buttons.js +45 -0
  57. package/src/lib/components/grid-buttons.js.map +1 -0
  58. package/src/lib/components/grid-items.d.ts +103 -0
  59. package/src/lib/components/grid-items.js +336 -0
  60. package/src/lib/components/grid-items.js.map +1 -0
  61. package/src/lib/components/grid-list.d.ts +37 -0
  62. package/src/lib/components/grid-list.js +156 -0
  63. package/src/lib/components/grid-list.js.map +1 -0
  64. package/src/lib/components/help-tip.component.d.ts +30 -0
  65. package/src/lib/components/help-tip.component.js +139 -0
  66. package/src/lib/components/help-tip.component.js.map +1 -0
  67. package/src/lib/components/link-navigation-reporter.d.ts +24 -0
  68. package/src/lib/components/link-navigation-reporter.js +64 -0
  69. package/src/lib/components/link-navigation-reporter.js.map +1 -0
  70. package/src/lib/components/list-pagination.component.d.ts +57 -0
  71. package/src/lib/components/list-pagination.component.js +90 -0
  72. package/src/lib/components/list-pagination.component.js.map +1 -0
  73. package/src/lib/components/list-table.component.d.ts +155 -0
  74. package/src/lib/components/list-table.component.js +369 -0
  75. package/src/lib/components/list-table.component.js.map +1 -0
  76. package/src/lib/components/loading-layout-app.component.d.ts +35 -0
  77. package/src/lib/components/loading-layout-app.component.js +42 -0
  78. package/src/lib/components/loading-layout-app.component.js.map +1 -0
  79. package/src/lib/components/loading-modal-overlay.d.ts +30 -0
  80. package/src/lib/components/loading-modal-overlay.js +156 -0
  81. package/src/lib/components/loading-modal-overlay.js.map +1 -0
  82. package/src/lib/components/loading-modal.d.ts +19 -0
  83. package/src/lib/components/loading-modal.js +113 -0
  84. package/src/lib/components/loading-modal.js.map +1 -0
  85. package/src/lib/components/loading-text.component.d.ts +21 -0
  86. package/src/lib/components/loading-text.component.js +40 -0
  87. package/src/lib/components/loading-text.component.js.map +1 -0
  88. package/src/lib/components/mdi-icon/index.d.ts +2 -0
  89. package/src/lib/components/mdi-icon/index.js +4 -0
  90. package/src/lib/components/mdi-icon/index.js.map +1 -0
  91. package/src/lib/components/mdi-icon/md-icon-stack.d.ts +31 -0
  92. package/src/lib/components/mdi-icon/md-icon-stack.js +101 -0
  93. package/src/lib/components/mdi-icon/md-icon-stack.js.map +1 -0
  94. package/src/lib/components/mdi-icon/md-icon.d.ts +32 -0
  95. package/src/lib/components/mdi-icon/md-icon.js +147 -0
  96. package/src/lib/components/mdi-icon/md-icon.js.map +1 -0
  97. package/src/lib/components/mdi-icon/mdi-icon-from-id.d.ts +23 -0
  98. package/src/lib/components/mdi-icon/mdi-icon-from-id.js +35 -0
  99. package/src/lib/components/mdi-icon/mdi-icon-from-id.js.map +1 -0
  100. package/src/lib/components/mdi-icon/mdi-icon.d.ts +24 -0
  101. package/src/lib/components/mdi-icon/mdi-icon.js +46 -0
  102. package/src/lib/components/mdi-icon/mdi-icon.js.map +1 -0
  103. package/src/lib/components/measured-figures.component.d.ts +64 -0
  104. package/src/lib/components/measured-figures.component.js +161 -0
  105. package/src/lib/components/measured-figures.component.js.map +1 -0
  106. package/src/lib/components/menu.d.ts +45 -0
  107. package/src/lib/components/menu.js +229 -0
  108. package/src/lib/components/menu.js.map +1 -0
  109. package/src/lib/components/mui-shadow-dom.d.ts +38 -0
  110. package/src/lib/components/mui-shadow-dom.js +161 -0
  111. package/src/lib/components/mui-shadow-dom.js.map +1 -0
  112. package/src/lib/components/navigation-drawer.component.d.ts +31 -0
  113. package/src/lib/components/navigation-drawer.component.js +76 -0
  114. package/src/lib/components/navigation-drawer.component.js.map +1 -0
  115. package/src/lib/components/navigation-intent.d.ts +18 -0
  116. package/src/lib/components/navigation-intent.js +56 -0
  117. package/src/lib/components/navigation-intent.js.map +1 -0
  118. package/src/lib/components/navigation-view/index.d.ts +18 -0
  119. package/src/lib/components/navigation-view/index.js +19 -0
  120. package/src/lib/components/navigation-view/index.js.map +1 -0
  121. package/src/lib/components/navigation-view/navigation-view.d.ts +35 -0
  122. package/src/lib/components/navigation-view/navigation-view.js +175 -0
  123. package/src/lib/components/navigation-view/navigation-view.js.map +1 -0
  124. package/src/lib/components/next-link.d.ts +27 -0
  125. package/src/lib/components/next-link.js +88 -0
  126. package/src/lib/components/next-link.js.map +1 -0
  127. package/src/lib/components/popper-styled.component.d.ts +25 -0
  128. package/src/lib/components/popper-styled.component.js +129 -0
  129. package/src/lib/components/popper-styled.component.js.map +1 -0
  130. package/src/lib/components/quota-readout.component.d.ts +69 -0
  131. package/src/lib/components/quota-readout.component.js +52 -0
  132. package/src/lib/components/quota-readout.component.js.map +1 -0
  133. package/src/lib/components/resizeable-stack.d.ts +4 -0
  134. package/src/lib/components/resizeable-stack.js +23 -0
  135. package/src/lib/components/resizeable-stack.js.map +1 -0
  136. package/src/lib/components/row-actions-menu.component.d.ts +53 -0
  137. package/src/lib/components/row-actions-menu.component.js +132 -0
  138. package/src/lib/components/row-actions-menu.component.js.map +1 -0
  139. package/src/lib/components/ruler-guides.component.d.ts +35 -0
  140. package/src/lib/components/ruler-guides.component.js +166 -0
  141. package/src/lib/components/ruler-guides.component.js.map +1 -0
  142. package/src/lib/components/sandbox-frame.d.ts +42 -0
  143. package/src/lib/components/sandbox-frame.js +122 -0
  144. package/src/lib/components/sandbox-frame.js.map +1 -0
  145. package/src/lib/components/scroll-reaction.d.ts +59 -0
  146. package/src/lib/components/scroll-reaction.js +43 -0
  147. package/src/lib/components/scroll-reaction.js.map +1 -0
  148. package/src/lib/components/scroll-table.component.d.ts +124 -0
  149. package/src/lib/components/scroll-table.component.js +103 -0
  150. package/src/lib/components/scroll-table.component.js.map +1 -0
  151. package/src/lib/components/shadow-dom/index.d.ts +18 -0
  152. package/src/lib/components/shadow-dom/index.js +19 -0
  153. package/src/lib/components/shadow-dom/index.js.map +1 -0
  154. package/src/lib/components/shadow-dom/shadow-dom.d.ts +42 -0
  155. package/src/lib/components/shadow-dom/shadow-dom.js +123 -0
  156. package/src/lib/components/shadow-dom/shadow-dom.js.map +1 -0
  157. package/src/lib/components/splash-screen.d.ts +33 -0
  158. package/src/lib/components/splash-screen.js +105 -0
  159. package/src/lib/components/splash-screen.js.map +1 -0
  160. package/src/lib/components/sr-only.d.ts +20 -0
  161. package/src/lib/components/sr-only.js +25 -0
  162. package/src/lib/components/sr-only.js.map +1 -0
  163. package/src/lib/components/status-screen-plain.component.d.ts +27 -0
  164. package/src/lib/components/status-screen-plain.component.js +178 -0
  165. package/src/lib/components/status-screen-plain.component.js.map +1 -0
  166. package/src/lib/components/usage-meter.component.d.ts +30 -0
  167. package/src/lib/components/usage-meter.component.js +92 -0
  168. package/src/lib/components/usage-meter.component.js.map +1 -0
  169. package/src/lib/components/variable-text-field.component.d.ts +50 -0
  170. package/src/lib/components/variable-text-field.component.js +188 -0
  171. package/src/lib/components/variable-text-field.component.js.map +1 -0
  172. package/src/lib/components/zoomable-panning-component/index.d.ts +1 -0
  173. package/src/lib/components/zoomable-panning-component/index.js +3 -0
  174. package/src/lib/components/zoomable-panning-component/index.js.map +1 -0
  175. package/src/lib/components/zoomable-panning-component/util.d.ts +58 -0
  176. package/src/lib/components/zoomable-panning-component/util.js +114 -0
  177. package/src/lib/components/zoomable-panning-component/util.js.map +1 -0
  178. package/src/lib/components/zoomable-panning-component/zoomable-panning-component.d.ts +132 -0
  179. package/src/lib/components/zoomable-panning-component/zoomable-panning-component.js +728 -0
  180. package/src/lib/components/zoomable-panning-component/zoomable-panning-component.js.map +1 -0
  181. package/src/lib/const/aglyn-besigner-logo-full.d.ts +39 -0
  182. package/src/lib/const/aglyn-besigner-logo-full.js +146 -0
  183. package/src/lib/const/aglyn-besigner-logo-full.js.map +1 -0
  184. package/src/lib/const/aglyn-console-logo-full.d.ts +34 -0
  185. package/src/lib/const/aglyn-console-logo-full.js +142 -0
  186. package/src/lib/const/aglyn-console-logo-full.js.map +1 -0
  187. package/src/lib/const/aglyn-logo-class-keys.d.ts +30 -0
  188. package/src/lib/const/aglyn-logo-class-keys.js +32 -0
  189. package/src/lib/const/aglyn-logo-class-keys.js.map +1 -0
  190. package/src/lib/const/aglyn-logo-full.d.ts +29 -0
  191. package/src/lib/const/aglyn-logo-full.js +111 -0
  192. package/src/lib/const/aglyn-logo-full.js.map +1 -0
  193. package/src/lib/const/list-filter.d.ts +260 -0
  194. package/src/lib/const/list-filter.js +409 -0
  195. package/src/lib/const/list-filter.js.map +1 -0
  196. package/src/lib/const/prebuilt-components.d.ts +17 -0
  197. package/src/lib/const/prebuilt-components.js +22 -0
  198. package/src/lib/const/prebuilt-components.js.map +1 -0
  199. package/src/lib/const/svg-icons.d.ts +75 -0
  200. package/src/lib/const/svg-icons.js +313 -0
  201. package/src/lib/const/svg-icons.js.map +1 -0
  202. package/src/lib/const/table-pagination.d.ts +106 -0
  203. package/src/lib/const/table-pagination.js +106 -0
  204. package/src/lib/const/table-pagination.js.map +1 -0
  205. package/src/lib/contexts/confirmation.context.d.ts +996 -0
  206. package/src/lib/contexts/confirmation.context.js +49 -0
  207. package/src/lib/contexts/confirmation.context.js.map +1 -0
  208. package/src/lib/contexts/loading.context.d.ts +93 -0
  209. package/src/lib/contexts/loading.context.js +126 -0
  210. package/src/lib/contexts/loading.context.js.map +1 -0
  211. package/src/lib/hocs/create-hoc-with-context-consumer.d.ts +36 -0
  212. package/src/lib/hocs/create-hoc-with-context-consumer.js +44 -0
  213. package/src/lib/hocs/create-hoc-with-context-consumer.js.map +1 -0
  214. package/src/lib/hocs/with-hoc.d.ts +32 -0
  215. package/src/lib/hocs/with-hoc.js +37 -0
  216. package/src/lib/hocs/with-hoc.js.map +1 -0
  217. package/src/lib/hooks/mdi-icon/use-mdi-icon.d.ts +20 -0
  218. package/src/lib/hooks/mdi-icon/use-mdi-icon.js +48 -0
  219. package/src/lib/hooks/mdi-icon/use-mdi-icon.js.map +1 -0
  220. package/src/lib/hooks/mdi-icon/use-mdi-icons-fuzzy.d.ts +26 -0
  221. package/src/lib/hooks/mdi-icon/use-mdi-icons-fuzzy.js +73 -0
  222. package/src/lib/hooks/mdi-icon/use-mdi-icons-fuzzy.js.map +1 -0
  223. package/src/lib/hooks/mdi-icon/use-mdi-icons.d.ts +19 -0
  224. package/src/lib/hooks/mdi-icon/use-mdi-icons.js +49 -0
  225. package/src/lib/hooks/mdi-icon/use-mdi-icons.js.map +1 -0
  226. package/src/lib/hooks/router-events.d.ts +56 -0
  227. package/src/lib/hooks/router-events.js +88 -0
  228. package/src/lib/hooks/router-events.js.map +1 -0
  229. package/src/lib/hooks/use-async-effect.d.ts +24 -0
  230. package/src/lib/hooks/use-async-effect.js +44 -0
  231. package/src/lib/hooks/use-async-effect.js.map +1 -0
  232. package/src/lib/hooks/use-callback-param-ref.d.ts +19 -0
  233. package/src/lib/hooks/use-callback-param-ref.js +29 -0
  234. package/src/lib/hooks/use-callback-param-ref.js.map +1 -0
  235. package/src/lib/hooks/use-id.d.ts +21 -0
  236. package/src/lib/hooks/use-id.js +28 -0
  237. package/src/lib/hooks/use-id.js.map +1 -0
  238. package/src/lib/hooks/use-isomorphic-layout-effect.d.ts +19 -0
  239. package/src/lib/hooks/use-isomorphic-layout-effect.js +20 -0
  240. package/src/lib/hooks/use-isomorphic-layout-effect.js.map +1 -0
  241. package/src/lib/hooks/use-merge-refs.d.ts +38 -0
  242. package/src/lib/hooks/use-merge-refs.js +52 -0
  243. package/src/lib/hooks/use-merge-refs.js.map +1 -0
  244. package/src/lib/hooks/use-subscribable.d.ts +29 -0
  245. package/src/lib/hooks/use-subscribable.js +50 -0
  246. package/src/lib/hooks/use-subscribable.js.map +1 -0
  247. package/src/lib/types.d.ts +18 -0
  248. package/src/lib/types.js +18 -0
  249. package/src/lib/types.js.map +1 -0
  250. package/src/lib/utils/make-link-elements.d.ts +24 -0
  251. package/src/lib/utils/make-link-elements.js +32 -0
  252. package/src/lib/utils/make-link-elements.js.map +1 -0
  253. package/src/lib/utils/make-meta-elements.d.ts +24 -0
  254. package/src/lib/utils/make-meta-elements.js +32 -0
  255. package/src/lib/utils/make-meta-elements.js.map +1 -0
  256. package/src/lib/utils/scroll-overflow.d.ts +120 -0
  257. package/src/lib/utils/scroll-overflow.js +115 -0
  258. package/src/lib/utils/scroll-overflow.js.map +1 -0
  259. package/src/lib/utils/vendor.d.ts +17 -0
  260. package/src/lib/utils/vendor.js +18 -0
  261. package/src/lib/utils/vendor.js.map +1 -0
@@ -0,0 +1,90 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ 'use client';
17
+ import { _ as _extends } from "@swc/helpers/_/_extends";
18
+ import { jsx as _jsx } from "react/jsx-runtime";
19
+ import TablePagination from "@mui/material/TablePagination";
20
+ import { TABLE_PAGE_SIZE_OPTIONS, TABLE_ROWS_PER_PAGE_LABEL } from "../const/table-pagination.js";
21
+ /**
22
+ * The footer under every paginated list, whatever is behind it.
23
+ *
24
+ * The console grew four pagination grammars — a MUI X `DataGrid` footer, a
25
+ * hand-rolled `TablePagination`, a bare Previous/Next button pair, and a
26
+ * "Load more" that only ever grew — so the same act took a different control
27
+ * depending on which list a reader was standing in, and two of the four
28
+ * offered no way to change the page size at all. This is the one control.
29
+ *
30
+ * ## Counting without a count
31
+ *
32
+ * A cursor feed cannot say how many rows exist without reading them, which is
33
+ * the cost pagination is there to avoid. MUI already models this: `count={-1}`
34
+ * renders "1–10 of more than 10" and leaves Next live.
35
+ *
36
+ * The trick is the LAST page, where the total stops being unknown — once no
37
+ * further page exists, `page × pageSize + rowCount` IS the total. Handing MUI
38
+ * the real number there is what disables Next, so the control needs no
39
+ * per-version knowledge of how to reach inside and disable that button. The
40
+ * count line also stops saying "more than" at exactly the point it would
41
+ * become a lie.
42
+ *
43
+ * `DataGrid` keeps its own footer — it renders one internally and cannot be
44
+ * given this — but it is fed the same options, default and label from
45
+ * `const/table-pagination`, so the two read identically.
46
+ */ export function ListPagination(props) {
47
+ const { page, pageSize, rowCount, onPageChange, onPageSizeChange, count, hasMore, labelDisplayedRows, pageSizeOptions, disabled } = props;
48
+ const resolvedCount = count != null ? count : hasMore ? -1 : page * pageSize + rowCount;
49
+ /*==========================================
50
+ * A MENU OVER STATE THIS FOOTER DOES NOT OWN.
51
+ *
52
+ * Without `onPageSizeChange` the size menu is inert — MUI renders the
53
+ * select and nothing happens when it is used. Worse on a list whose page
54
+ * size is dictated elsewhere: the staff Users list pages at the width
55
+ * Firebase Auth is asked for, which is not one of the shared options, so
56
+ * MUI had a value with no matching item and drew the control EMPTY. A
57
+ * blank select beside a row count reads as a broken page, and the one
58
+ * thing it could not do was be used.
59
+ *
60
+ * An empty options array is how MUI is told there is no choice to offer,
61
+ * so the control is absent rather than present and dead. A caller that
62
+ * genuinely wants a fixed menu still passes `pageSizeOptions` itself.
63
+ *=========================================*/ const resolvedOptions = pageSizeOptions != null ? pageSizeOptions : onPageSizeChange ? TABLE_PAGE_SIZE_OPTIONS : [];
64
+ return /*#__PURE__*/ _jsx(TablePagination, _extends({
65
+ // These footers sit under Stacks and Lists as often as under a Table,
66
+ // and a <td> outside a <table> is invalid markup the browser reparents.
67
+ component: "div",
68
+ count: resolvedCount,
69
+ page: page,
70
+ rowsPerPage: pageSize,
71
+ onPageChange: (_event, next)=>onPageChange(next),
72
+ onRowsPerPageChange: onPageSizeChange ? (event)=>{
73
+ // Back to the first page: page 4 of a 10-row list does not
74
+ // exist once the reader asks for 50 at a time, and MUI renders
75
+ // an out-of-range page as an empty list with no explanation.
76
+ onPageSizeChange(Number(event.target.value));
77
+ onPageChange(0);
78
+ } : undefined,
79
+ rowsPerPageOptions: resolvedOptions,
80
+ labelRowsPerPage: TABLE_ROWS_PER_PAGE_LABEL
81
+ }, labelDisplayedRows ? {
82
+ labelDisplayedRows
83
+ } : {}, {
84
+ disabled: disabled
85
+ }));
86
+ }
87
+ ListPagination.displayName = 'ListPagination';
88
+ export default ListPagination;
89
+
90
+ //# sourceMappingURL=list-pagination.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/list-pagination.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport TablePagination from '@mui/material/TablePagination'\nimport type { TablePaginationProps } from '@mui/material/TablePagination'\nimport {\n TABLE_PAGE_SIZE_OPTIONS,\n TABLE_ROWS_PER_PAGE_LABEL,\n} from '../const/table-pagination'\n\nexport interface ListPaginationProps {\n /** Zero-based, like MUI's own. */\n page: number\n pageSize: number\n /** Rows rendered on the CURRENT page — not the collection's total. */\n rowCount: number\n onPageChange: (page: number) => void\n /**\n * Omit on a list whose page size is not the reader's to choose — the size\n * menu is then not rendered at all. Most lists should pass it.\n */\n onPageSizeChange?: (pageSize: number) => void\n /**\n * The collection's total, when the caller genuinely knows it — a\n * client-side list, or a server `count()`. Leave undefined for a cursor or\n * growing-window feed, where nobody knows it without paying for it.\n */\n count?: number\n /** Cursor/window feeds: whether a further page exists. */\n hasMore?: boolean\n /** Override the count line, e.g. the screens tree's \"top-level screens\". */\n labelDisplayedRows?: TablePaginationProps['labelDisplayedRows']\n pageSizeOptions?: number[]\n disabled?: boolean\n}\n\n/**\n * The footer under every paginated list, whatever is behind it.\n *\n * The console grew four pagination grammars — a MUI X `DataGrid` footer, a\n * hand-rolled `TablePagination`, a bare Previous/Next button pair, and a\n * \"Load more\" that only ever grew — so the same act took a different control\n * depending on which list a reader was standing in, and two of the four\n * offered no way to change the page size at all. This is the one control.\n *\n * ## Counting without a count\n *\n * A cursor feed cannot say how many rows exist without reading them, which is\n * the cost pagination is there to avoid. MUI already models this: `count={-1}`\n * renders \"1–10 of more than 10\" and leaves Next live.\n *\n * The trick is the LAST page, where the total stops being unknown — once no\n * further page exists, `page × pageSize + rowCount` IS the total. Handing MUI\n * the real number there is what disables Next, so the control needs no\n * per-version knowledge of how to reach inside and disable that button. The\n * count line also stops saying \"more than\" at exactly the point it would\n * become a lie.\n *\n * `DataGrid` keeps its own footer — it renders one internally and cannot be\n * given this — but it is fed the same options, default and label from\n * `const/table-pagination`, so the two read identically.\n */\nexport function ListPagination(props: ListPaginationProps) {\n const {\n page,\n pageSize,\n rowCount,\n onPageChange,\n onPageSizeChange,\n count,\n hasMore,\n labelDisplayedRows,\n pageSizeOptions,\n disabled,\n } = props\n\n const resolvedCount =\n count ?? (hasMore ? -1 : page * pageSize + rowCount)\n\n /*==========================================\n * A MENU OVER STATE THIS FOOTER DOES NOT OWN.\n *\n * Without `onPageSizeChange` the size menu is inert — MUI renders the\n * select and nothing happens when it is used. Worse on a list whose page\n * size is dictated elsewhere: the staff Users list pages at the width\n * Firebase Auth is asked for, which is not one of the shared options, so\n * MUI had a value with no matching item and drew the control EMPTY. A\n * blank select beside a row count reads as a broken page, and the one\n * thing it could not do was be used.\n *\n * An empty options array is how MUI is told there is no choice to offer,\n * so the control is absent rather than present and dead. A caller that\n * genuinely wants a fixed menu still passes `pageSizeOptions` itself.\n *=========================================*/\n const resolvedOptions =\n pageSizeOptions ??\n (onPageSizeChange ? TABLE_PAGE_SIZE_OPTIONS : [])\n\n return (\n <TablePagination\n // These footers sit under Stacks and Lists as often as under a Table,\n // and a <td> outside a <table> is invalid markup the browser reparents.\n component=\"div\"\n count={resolvedCount}\n page={page}\n rowsPerPage={pageSize}\n onPageChange={(_event, next) => onPageChange(next)}\n onRowsPerPageChange={\n onPageSizeChange\n ? (event) => {\n // Back to the first page: page 4 of a 10-row list does not\n // exist once the reader asks for 50 at a time, and MUI renders\n // an out-of-range page as an empty list with no explanation.\n onPageSizeChange(Number(event.target.value))\n onPageChange(0)\n }\n : undefined\n }\n rowsPerPageOptions={resolvedOptions}\n labelRowsPerPage={TABLE_ROWS_PER_PAGE_LABEL}\n {...(labelDisplayedRows ? { labelDisplayedRows } : {})}\n disabled={disabled}\n />\n )\n}\nListPagination.displayName = 'ListPagination'\n\nexport default ListPagination\n"],"names":["TablePagination","TABLE_PAGE_SIZE_OPTIONS","TABLE_ROWS_PER_PAGE_LABEL","ListPagination","props","page","pageSize","rowCount","onPageChange","onPageSizeChange","count","hasMore","labelDisplayedRows","pageSizeOptions","disabled","resolvedCount","resolvedOptions","component","rowsPerPage","_event","next","onRowsPerPageChange","event","Number","target","value","undefined","rowsPerPageOptions","labelRowsPerPage","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;;AAEA,OAAOA,qBAAqB,gCAA+B;AAE3D,SACEC,uBAAuB,EACvBC,yBAAyB,QACpB,+BAA2B;AA4BlC;;;;;;;;;;;;;;;;;;;;;;;;;CAyBC,GACD,OAAO,SAASC,eAAeC,KAA0B;IACvD,MAAM,EACJC,IAAI,EACJC,QAAQ,EACRC,QAAQ,EACRC,YAAY,EACZC,gBAAgB,EAChBC,KAAK,EACLC,OAAO,EACPC,kBAAkB,EAClBC,eAAe,EACfC,QAAQ,EACT,GAAGV;IAEJ,MAAMW,gBACJL,gBAAAA,QAAUC,UAAU,CAAC,IAAIN,OAAOC,WAAWC;IAE7C;;;;;;;;;;;;;;6CAc2C,GAC3C,MAAMS,kBACJH,0BAAAA,kBACCJ,mBAAmBR,0BAA0B,EAAE;IAElD,qBACE,KAACD;QACC,sEAAsE;QACtE,wEAAwE;QACxEiB,WAAU;QACVP,OAAOK;QACPV,MAAMA;QACNa,aAAaZ;QACbE,cAAc,CAACW,QAAQC,OAASZ,aAAaY;QAC7CC,qBACEZ,mBACI,CAACa;YACC,2DAA2D;YAC3D,+DAA+D;YAC/D,6DAA6D;YAC7Db,iBAAiBc,OAAOD,MAAME,MAAM,CAACC,KAAK;YAC1CjB,aAAa;QACf,IACAkB;QAENC,oBAAoBX;QACpBY,kBAAkB1B;OACbU,qBAAqB;QAAEA;IAAmB,IAAI,CAAC;QACpDE,UAAUA;;AAGhB;AACAX,eAAe0B,WAAW,GAAG;AAE7B,eAAe1B,eAAc"}
@@ -0,0 +1,155 @@
1
+ import { type DataTableProps } from './data-table.component';
2
+ import type { GridColDef } from '@mui/x-data-grid';
3
+ import type { ReactNode } from 'react';
4
+ import { type RowActionsMenuItem } from './row-actions-menu.component';
5
+ /**
6
+ * ONE row grammar for every artifact list (AGL-2501).
7
+ *
8
+ *
9
+ * They did. Three of the four are `DataTableComponent`, but each declared its
10
+ * own column set, its own action arrangement and its own row-click, and the
11
+ * fourth — screens — is a hand-rolled tree because it has to be: drag to
12
+ * reorder, expand to nest, no grid can do that. So "the same table" cannot
13
+ * literally be one component for all four, and pretending otherwise would mean
14
+ * either losing the hierarchy or bolting a tree onto a grid.
15
+ *
16
+ * What IS shared is the row GRAMMAR, and that is what actually differed on
17
+ * screen. Every artifact row now reads the same way:
18
+ *
19
+ * ```
20
+ * [ drag · expand ] name id description updated created [ ⇗ ⋮ ]
21
+ * screens only quick menu
22
+ * ```
23
+ *
24
+ * - **The row opens the detail view.** Clicking anywhere that is not a control
25
+ * navigates. It is the primary action on every one of these lists and it was
26
+ * previously a link buried in one column.
27
+ * - **Rows are NOT selectable.** The grid lists shipped with selection on, so
28
+ * a click both navigated AND tinted the row, and the footer counted "1 row
29
+ * selected" for a selection nothing could act on. A selection with no bulk
30
+ * action is a state the reader has to dismiss and cannot use.
31
+ * - **Exactly one quick action, then the menu.** Everything else moves behind
32
+ * the overflow — a delete sitting inline is one mis-click from the row's own
33
+ * open handler, which is the argument AGL-701 already made for components and
34
+ * never carried to the rest.
35
+ *
36
+ * The quick action is the one thing worth a direct click on that kind of
37
+ * artifact: **Open live page** for a screen, **Preview** for anything that has
38
+ * no address of its own. It is the only per-kind variation in the trailing
39
+ * cluster, and it is chosen by the caller rather than inferred here.
40
+ *
41
+ * A screen is the only artifact of the four with a route the public can reach,
42
+ * so it is the only one whose quick action says "live". Layouts, components
43
+ * and templates render inside something else and have no address to open, so
44
+ * theirs is a **Preview** into the console's own canvas render.
45
+ *
46
+ * The quick action is ALSO the menu's first entry — see
47
+ * {@link quickActionMenuItem}. The icon alone is a glyph with a tooltip; the
48
+ * menu is where every action on the row is spelled out, and an action missing
49
+ * from it reads as an action the row does not have.
50
+ */
51
+ /**
52
+ * The single trailing icon beside the overflow menu.
53
+ *
54
+ * Three shapes, because the destinations genuinely differ: an EXTERNAL live
55
+ * page (new tab), an IN-APP preview route, and a plain handler for the rare
56
+ * action that opens a dialog. `unavailableReason` is the fourth state and the
57
+ * one most easily got wrong — a screen with no single live page (a collection
58
+ * template renders under routes it does not own) must still show the control,
59
+ * disabled, saying why. Hiding it would read as the feature being absent.
60
+ */
61
+ export interface ListQuickAction {
62
+ /** `mdi` icon path. */
63
+ icon: string;
64
+ /** Accessible name; also the tooltip when the action is unavailable. */
65
+ label: string;
66
+ /** A live, external URL — opened in a new tab. */
67
+ href?: string;
68
+ /** An in-app route — a normal client navigation. */
69
+ to?: string;
70
+ onClick?: () => void;
71
+ /**
72
+ * Why this row cannot use the action. Renders it DISABLED with the reason as
73
+ * its tooltip, rather than removing it — an absent control and an
74
+ * inapplicable one look identical, and only one of them is honest.
75
+ */
76
+ unavailableReason?: string;
77
+ }
78
+ export interface ListRowActionsProps {
79
+ /** The artifact's name — every control is labelled with it, because these
80
+ * Repeat once per row and "More actions" alone says nothing about which. */
81
+ label: string;
82
+ quick?: ListQuickAction | null;
83
+ items: RowActionsMenuItem[];
84
+ }
85
+ /** The trailing cluster: one quick action, then the overflow menu. */
86
+ export declare function ListRowActions(props: ListRowActionsProps): import("react").JSX.Element;
87
+ export declare namespace ListRowActions {
88
+ var displayName: string;
89
+ }
90
+ /** The field `listActionsColumn` draws, which a row click never opens through. */
91
+ export declare const LIST_ACTIONS_FIELD = "actions";
92
+ /**
93
+ * The trailing ACTIONS column, identical on every grid list.
94
+ *
95
+ * Deliberately NOT MUI's `type: 'actions'`. That type renders each
96
+ * `GridActionsCellItem` as its own icon and moves the ones marked `showInMenu`
97
+ * into a menu it owns — which is how the three lists ended up with two, three
98
+ * and five inline icons respectively, each a different width, and how the
99
+ * screens table (which cannot use it at all) grew a second implementation.
100
+ * One `renderCell` gives every list the same cluster and the same width.
101
+ */
102
+ export declare function listActionsColumn(render: (row: any) => ReactNode, options?: {
103
+ width?: number;
104
+ }): GridColDef;
105
+ /**
106
+ * Row selection, opted into by a list that has something to DO with a
107
+ * selection (AGL-2595).
108
+ *
109
+ * Controlled, and in the caller's vocabulary — an array of `$id`s in, an
110
+ * array out — rather than MUI's own model. The grid's model is a
111
+ * `{ type, ids: Set }` whose `exclude` form appears the moment the header
112
+ * checkbox is ticked, and a caller that had to fold "everything except
113
+ * these" back into "these" would do it wrong on the page boundary; the
114
+ * table holds the rows and does the fold once, here.
115
+ */
116
+ export interface ListTableSelection {
117
+ /** The `$id`s currently selected; ids not in `rows` are ignored. */
118
+ selected: readonly string[];
119
+ /** Every change, as the full new selection. */
120
+ onChange: (ids: string[]) => void;
121
+ }
122
+ export interface ListTableProps extends DataTableProps {
123
+ /** Row click → the artifact's detail view. */
124
+ onOpen?: (id: string, row: any) => void;
125
+ /**
126
+ * The toolbar's free-text search box.
127
+ *
128
+ * Defaults to shown where the GRID answers it, which is client filtering.
129
+ * Under `filterMode="server"` the grid applies no filter at all and the
130
+ * model goes to the caller, so the box defaults to hidden: a list whose
131
+ * handler reads only the column filter would otherwise offer a search that
132
+ * narrows nothing, which reads as "no match" rather than "not supported".
133
+ * Pass it on a server-filtered list whose handler reads `quickFilterValues`.
134
+ */
135
+ quickFilter?: boolean;
136
+ /**
137
+ * Present → a checkbox column and a controlled selection. Absent → the
138
+ * navigation-only grid every list had before, checkbox column and all.
139
+ * The row click keeps opening the record either way: a checkbox is the
140
+ * only thing that selects, so the two gestures cannot collide.
141
+ */
142
+ selectable?: ListTableSelection;
143
+ }
144
+ /**
145
+ * The grid every FLAT artifact list uses — layouts, components, templates.
146
+ *
147
+ * Screens is the deliberate exception and keeps its own tree; it adopts
148
+ * {@link ListRowActions} so the two still read alike, which is the part a
149
+ * reader actually compares.
150
+ */
151
+ export declare function ListTable(props: ListTableProps): import("react").JSX.Element;
152
+ export declare namespace ListTable {
153
+ var displayName: string;
154
+ }
155
+ export default ListTable;
@@ -0,0 +1,369 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ 'use client';
17
+ import { _ as _extends } from "@swc/helpers/_/_extends";
18
+ import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
19
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
20
+ import { AppLink } from "./app-link.js";
21
+ import { MdiIcon } from "./mdi-icon/mdi-icon.js";
22
+ import { DataTableComponent } from "./data-table.component.js";
23
+ import { IconButton, Stack, Tooltip } from "@mui/material";
24
+ import RowActionsMenu from "./row-actions-menu.component.js";
25
+ import { TABLE_PAGE_SIZE_DEFAULT, TABLE_PAGE_SIZE_OPTIONS, TABLE_ROWS_PER_PAGE_LABEL } from "../const/table-pagination.js";
26
+ /**
27
+ * The quick action, restated as the menu's first entry.
28
+ *
29
+ * The icon and the menu are two ways into ONE action, not two features: the
30
+ * icon is a bare glyph, so a reader who does not recognize it has the overflow
31
+ * as the place every action is named. Deriving the item from the same
32
+ * {@link ListQuickAction} is what keeps the two in step — availability,
33
+ * destination and the reason it is refused are read once and cannot drift.
34
+ */ function quickActionMenuItem(quick) {
35
+ var _quick_href;
36
+ return {
37
+ key: 'quick',
38
+ label: quick.label,
39
+ icon: /*#__PURE__*/ _jsx(MdiIcon, {
40
+ path: quick.icon,
41
+ size: 0.8
42
+ }),
43
+ // `href` is off-site and opens a new tab; `to` is an in-app route.
44
+ href: (_quick_href = quick.href) != null ? _quick_href : quick.to,
45
+ external: Boolean(quick.href),
46
+ onClick: quick.href || quick.to ? undefined : quick.onClick,
47
+ disabled: Boolean(quick.unavailableReason),
48
+ disabledReason: quick.unavailableReason
49
+ };
50
+ }
51
+ /** The trailing cluster: one quick action, then the overflow menu. */ export function ListRowActions(props) {
52
+ const { label, quick, items } = props;
53
+ const menuItems = quick ? [
54
+ quickActionMenuItem(quick),
55
+ ...items
56
+ ] : items;
57
+ return /*#__PURE__*/ _jsxs(Stack, {
58
+ direction: "row",
59
+ spacing: 0.5,
60
+ /*
61
+ `height: '100%'` is what actually centres these (AGL-2501). A DataGrid
62
+ cell is a flex box, but `renderCell` content is auto-height inside it —
63
+ so at the taller `TABLE_ROW_HEIGHT` these icons ride at the top of the
64
+ row while the text beside them is centred. `alignItems` alone cannot
65
+ fix it: there is no spare height to distribute until the child claims
66
+ the row.
67
+ */ sx: {
68
+ height: '100%',
69
+ alignItems: 'center',
70
+ justifyContent: 'flex-end'
71
+ },
72
+ // The row's own click opens the detail view; without this every control
73
+ // in here would navigate out from under the thing it just opened.
74
+ onClick: (event)=>event.stopPropagation(),
75
+ children: [
76
+ quick ? /*#__PURE__*/ _jsx(ListQuickButton, {
77
+ label: label,
78
+ action: quick
79
+ }) : null,
80
+ /*#__PURE__*/ _jsx(RowActionsMenu, {
81
+ label: label,
82
+ items: menuItems
83
+ })
84
+ ]
85
+ });
86
+ }
87
+ ListRowActions.displayName = 'ListRowActions';
88
+ function ListQuickButton(props) {
89
+ const { label, action } = props;
90
+ const icon = /*#__PURE__*/ _jsx(MdiIcon, {
91
+ path: action.icon,
92
+ size: 0.8
93
+ });
94
+ const name = `${action.label} — ${label}`;
95
+ if (action.unavailableReason) {
96
+ return /*#__PURE__*/ _jsx(Tooltip, {
97
+ title: action.unavailableReason,
98
+ children: /*#__PURE__*/ _jsx("span", {
99
+ children: /*#__PURE__*/ _jsx(IconButton, {
100
+ size: "small",
101
+ "aria-label": name,
102
+ disabled: true,
103
+ children: icon
104
+ })
105
+ })
106
+ });
107
+ }
108
+ if (action.href) {
109
+ return /*#__PURE__*/ _jsx(Tooltip, {
110
+ title: action.label,
111
+ children: /*#__PURE__*/ _jsx(AppLink, {
112
+ componentVariant: "icon-button",
113
+ size: "small",
114
+ "aria-label": name,
115
+ href: action.href,
116
+ target: "_blank",
117
+ rel: "noreferrer",
118
+ children: icon
119
+ })
120
+ });
121
+ }
122
+ if (action.to) {
123
+ return /*#__PURE__*/ _jsx(Tooltip, {
124
+ title: action.label,
125
+ children: /*#__PURE__*/ _jsx(AppLink, {
126
+ componentVariant: "icon-button",
127
+ size: "small",
128
+ "aria-label": name,
129
+ href: action.to,
130
+ children: icon
131
+ })
132
+ });
133
+ }
134
+ return /*#__PURE__*/ _jsx(Tooltip, {
135
+ title: action.label,
136
+ children: /*#__PURE__*/ _jsx(IconButton, {
137
+ size: "small",
138
+ "aria-label": name,
139
+ onClick: action.onClick,
140
+ children: icon
141
+ })
142
+ });
143
+ }
144
+ /** The field `listActionsColumn` draws, which a row click never opens through. */ export const LIST_ACTIONS_FIELD = 'actions';
145
+ /**
146
+ * The trailing ACTIONS column, identical on every grid list.
147
+ *
148
+ * Deliberately NOT MUI's `type: 'actions'`. That type renders each
149
+ * `GridActionsCellItem` as its own icon and moves the ones marked `showInMenu`
150
+ * into a menu it owns — which is how the three lists ended up with two, three
151
+ * and five inline icons respectively, each a different width, and how the
152
+ * screens table (which cannot use it at all) grew a second implementation.
153
+ * One `renderCell` gives every list the same cluster and the same width.
154
+ */ export function listActionsColumn(render, options = {}) {
155
+ var _options_width;
156
+ return {
157
+ field: LIST_ACTIONS_FIELD,
158
+ headerName: 'Actions',
159
+ width: (_options_width = options.width) != null ? _options_width : 110,
160
+ align: 'right',
161
+ headerAlign: 'right',
162
+ sortable: false,
163
+ filterable: false,
164
+ hideable: false,
165
+ disableColumnMenu: true,
166
+ renderCell: ({ row })=>render(row)
167
+ };
168
+ }
169
+ /**
170
+ * The grid every FLAT artifact list uses — layouts, components, templates.
171
+ *
172
+ * Screens is the deliberate exception and keeps its own tree; it adopts
173
+ * {@link ListRowActions} so the two still read alike, which is the part a
174
+ * reader actually compares.
175
+ */ export function ListTable(props) {
176
+ var _ref;
177
+ const { onOpen, sx, initialState, hideFooter, rows, selectable, quickFilter, slotProps } = props, rest = _object_without_properties_loose(props, [
178
+ "onOpen",
179
+ "sx",
180
+ "initialState",
181
+ "hideFooter",
182
+ "rows",
183
+ "selectable",
184
+ "quickFilter",
185
+ "slotProps"
186
+ ]);
187
+ const showQuickFilter = quickFilter != null ? quickFilter : rest.filterMode !== 'server';
188
+ /*==========================================
189
+ * SELECTION IS OPT-IN, AND NAVIGATION-ONLY IS THE DEFAULT.
190
+ *
191
+ * Without `selectable`, the three properties that make a row a NAVIGATION
192
+ * target rather than a selectable record: `disableRowSelectionOnClick`
193
+ * alone is not enough — it stops the click selecting, and leaves the
194
+ * checkbox column and the "n rows selected" footer behind.
195
+ *
196
+ * With it, the grid's model is built from the caller's id list on every
197
+ * render and folded back into one on every change. MUI's model since v8 is
198
+ * `{ type: 'include' | 'exclude', ids }`, and `exclude` is what the header
199
+ * checkbox produces — "everything but these" — so the fold has to consult
200
+ * the rows the grid was given, which is why it lives here and not in the
201
+ * caller. `disableRowSelectionOnClick` stays on in this branch too: a row
202
+ * click still opens the record, and only the checkbox selects.
203
+ *=========================================*/ const selection = selectable ? {
204
+ rowSelection: true,
205
+ checkboxSelection: true,
206
+ rowSelectionModel: {
207
+ type: 'include',
208
+ ids: new Set(selectable.selected)
209
+ },
210
+ onRowSelectionModelChange: (model)=>{
211
+ const all = (rows != null ? rows : []).map((row)=>String(row.$id));
212
+ selectable.onChange(model.type === 'include' ? all.filter((id)=>model.ids.has(id)) : all.filter((id)=>!model.ids.has(id)));
213
+ }
214
+ } : {
215
+ rowSelection: false,
216
+ checkboxSelection: false
217
+ };
218
+ /*==========================================
219
+ * A HIDDEN FOOTER STILL PAGED THE ROWS.
220
+ *
221
+ * `hideFooter` is how a caller says "something else owns the page" — a
222
+ * server-paged staff list, a cursor feed, a card whose `ListPagination`
223
+ * sits under the grid. It hides the CONTROL and nothing else: the free
224
+ * DataGrid always paginates, so the grid went on slicing at the shared
225
+ * default and rows eleven onward were drawn by nothing and reachable by
226
+ * nothing. The outer footer then described the rows it was HANDED, so it
227
+ * reported a page two rows longer than the one on screen and offered no
228
+ * way to see the difference.
229
+ *
230
+ * Eight lists pass `hideFooter`, and every one of them was losing rows past
231
+ * the tenth. It went unnoticed because a list has to hold more than ten
232
+ * rows to show a symptom, and most of these do not yet.
233
+ *
234
+ * So when the footer is hidden the grid takes ONE page as tall as the rows
235
+ * it was given. CONTROLLED rather than `initialState`, because a
236
+ * server-paged list hands over a different number of rows on every page and
237
+ * initial state is read once. A floor of one because MUI rejects a page
238
+ * size of zero, and an empty grid has nothing to slice anyway.
239
+ *=========================================*/ const rowCount = (_ref = rows == null ? void 0 : rows.length) != null ? _ref : 0;
240
+ const unpaged = hideFooter ? {
241
+ paginationModel: {
242
+ page: 0,
243
+ pageSize: Math.max(rowCount, 1)
244
+ },
245
+ // A controlled model with no handler logs a MUI warning, and the
246
+ // grid must not move off page zero in any case: the page is not
247
+ // this component's to change while somebody else owns the footer.
248
+ onPaginationModelChange: ()=>undefined,
249
+ // Keeps the size out of the "not preset in pageSizeOptions" warning.
250
+ // Nothing renders it — the footer carrying the menu is hidden.
251
+ pageSizeOptions: [
252
+ Math.max(rowCount, 1)
253
+ ]
254
+ } : {};
255
+ return /*#__PURE__*/ _jsx(DataTableComponent, _extends({
256
+ getRowId: (row)=>row.$id
257
+ }, selection, {
258
+ disableRowSelectionOnClick: true,
259
+ onRowClick: onOpen ? ({ id, row }, event)=>{
260
+ var _target_closest;
261
+ /*
262
+ * A press anywhere in the actions cell is aimed at the actions.
263
+ * `ListRowActions` stops its own clicks, but the cell is wider
264
+ * and taller than the cluster, and a press on the padding
265
+ * beside the menu would otherwise open the record from under
266
+ * the reader.
267
+ */ const target = event.target;
268
+ if (target == null ? void 0 : (_target_closest = target.closest) == null ? void 0 : _target_closest.call(target, `[data-field="${LIST_ACTIONS_FIELD}"]`)) return;
269
+ onOpen(String(id), row);
270
+ } : undefined,
271
+ /*
272
+ * The list GROWS; the PAGE scrolls.
273
+ *
274
+ * `DataTableComponent` gives its wrapper a fixed `height: 400`, which
275
+ * is right for a grid sitting in a pane of its own and wrong for a
276
+ * card in a column of cards: the table got its own scrollbar, the card
277
+ * stopped at 400px whatever it held, and the last row was cut through
278
+ * the middle. Two scroll regions on one page is the thing to avoid —
279
+ * a reader scrolling the page expects the page to move.
280
+ *
281
+ * `autoHeight` sizes the grid to its rows; clearing the wrapper's
282
+ * height is what lets the card follow it. Caller `sx` is spread after,
283
+ * so a list that genuinely wants a viewport can still take one.
284
+ */ autoHeight: true,
285
+ sx: [
286
+ {
287
+ height: 'auto'
288
+ },
289
+ {
290
+ '& .MuiDataGrid-row': {
291
+ cursor: onOpen ? 'pointer' : 'default'
292
+ }
293
+ },
294
+ /*
295
+ A cell whose content is taller than one line sets the row's height,
296
+ and every OTHER cell then draws its content at the top of it — so a
297
+ two-line date column leaves the counts beside it riding high while
298
+ `ListRowActions`, which claims `height: '100%'` for itself, sits
299
+ centred. One row, three vertical positions.
300
+
301
+ Centring the cell itself fixes every column at once, including the
302
+ ones a caller renders with a bare `<Typography>`; `alignItems`
303
+ alone cannot, because an auto-height child has no spare height to
304
+ distribute until something claims the row. `justifyContent` is
305
+ deliberately not set here — a column's own `align` is what decides
306
+ its horizontal placement, and overriding it would silently undo
307
+ every right-aligned figure.
308
+ */ {
309
+ '& .MuiDataGrid-cell': {
310
+ display: 'flex',
311
+ alignItems: 'center'
312
+ }
313
+ },
314
+ ...Array.isArray(sx) ? sx : sx ? [
315
+ sx
316
+ ] : []
317
+ ],
318
+ /*
319
+ * The column menu can hide a column; only the toolbar can bring it
320
+ * back.
321
+ *
322
+ * Every column here is hideable, `Manage columns` lives in the toolbar,
323
+ * and the toolbar was off — so hiding the last column left a grid with
324
+ * no columns and no control that could restore one. Not a rare misuse
325
+ * either: the per-column menu offers `Hide column` on every column, and
326
+ * the way out was never on screen.
327
+ *
328
+ * The Actions column is the reason the grid was not left completely
329
+ * blank — `listActionsColumn` marks it `hideable: false` — and "one
330
+ * unhideable column" is not a recovery path.
331
+ */ showToolbar: true,
332
+ pagination: true,
333
+ // The console's ONE footer (AGL-2501): same options, same default, same
334
+ // label.
335
+ pageSizeOptions: TABLE_PAGE_SIZE_OPTIONS,
336
+ /*
337
+ * MERGED, not replaced. `initialState` used to ride in through `rest`,
338
+ * so a caller that set anything in it — a column visibility model, a
339
+ * sort — silently dropped the shared page size along with it. The two
340
+ * keys a caller is likely to set are spread individually so that a page
341
+ * size and a hidden column can coexist.
342
+ */ initialState: _extends({}, initialState, {
343
+ pagination: _extends({
344
+ paginationModel: {
345
+ pageSize: TABLE_PAGE_SIZE_DEFAULT
346
+ }
347
+ }, initialState == null ? void 0 : initialState.pagination),
348
+ columns: _extends({}, initialState == null ? void 0 : initialState.columns)
349
+ }),
350
+ /*
351
+ * MERGED with the caller's, for the reason `initialState` is: a caller
352
+ * setting one slot's props must not drop the shared footer label or the
353
+ * search box's filter-mode default along with the object they live in.
354
+ */ slotProps: _extends({}, slotProps, {
355
+ toolbar: _extends({
356
+ showQuickFilter
357
+ }, slotProps == null ? void 0 : slotProps.toolbar),
358
+ pagination: _extends({
359
+ labelRowsPerPage: TABLE_ROWS_PER_PAGE_LABEL
360
+ }, slotProps == null ? void 0 : slotProps.pagination)
361
+ }),
362
+ rows: rows,
363
+ hideFooter: hideFooter
364
+ }, rest, unpaged));
365
+ }
366
+ ListTable.displayName = 'ListTable';
367
+ export default ListTable;
368
+
369
+ //# sourceMappingURL=list-table.component.js.map