@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 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/list-table.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 { AppLink } from './app-link'\nimport { MdiIcon } from './mdi-icon/mdi-icon'\nimport {\n DataTableComponent,\n type DataTableProps,\n} from './data-table.component'\nimport { IconButton, Stack, Tooltip } from '@mui/material'\nimport type { GridColDef } from '@mui/x-data-grid'\nimport type { ReactNode } from 'react'\nimport RowActionsMenu, {\n type RowActionsMenuItem,\n} from './row-actions-menu.component'\nimport {\n TABLE_PAGE_SIZE_DEFAULT,\n TABLE_PAGE_SIZE_OPTIONS,\n TABLE_ROWS_PER_PAGE_LABEL,\n} from '../const/table-pagination'\n\n/**\n * ONE row grammar for every artifact list (AGL-2501).\n *\n *\n * They did. Three of the four are `DataTableComponent`, but each declared its\n * own column set, its own action arrangement and its own row-click, and the\n * fourth — screens — is a hand-rolled tree because it has to be: drag to\n * reorder, expand to nest, no grid can do that. So \"the same table\" cannot\n * literally be one component for all four, and pretending otherwise would mean\n * either losing the hierarchy or bolting a tree onto a grid.\n *\n * What IS shared is the row GRAMMAR, and that is what actually differed on\n * screen. Every artifact row now reads the same way:\n *\n * ```\n * [ drag · expand ] name id description updated created [ ⇗ ⋮ ]\n * screens only quick menu\n * ```\n *\n * - **The row opens the detail view.** Clicking anywhere that is not a control\n * navigates. It is the primary action on every one of these lists and it was\n * previously a link buried in one column.\n * - **Rows are NOT selectable.** The grid lists shipped with selection on, so\n * a click both navigated AND tinted the row, and the footer counted \"1 row\n * selected\" for a selection nothing could act on. A selection with no bulk\n * action is a state the reader has to dismiss and cannot use.\n * - **Exactly one quick action, then the menu.** Everything else moves behind\n * the overflow — a delete sitting inline is one mis-click from the row's own\n * open handler, which is the argument AGL-701 already made for components and\n * never carried to the rest.\n *\n * The quick action is the one thing worth a direct click on that kind of\n * artifact: **Open live page** for a screen, **Preview** for anything that has\n * no address of its own. It is the only per-kind variation in the trailing\n * cluster, and it is chosen by the caller rather than inferred here.\n *\n * A screen is the only artifact of the four with a route the public can reach,\n * so it is the only one whose quick action says \"live\". Layouts, components\n * and templates render inside something else and have no address to open, so\n * theirs is a **Preview** into the console's own canvas render.\n *\n * The quick action is ALSO the menu's first entry — see\n * {@link quickActionMenuItem}. The icon alone is a glyph with a tooltip; the\n * menu is where every action on the row is spelled out, and an action missing\n * from it reads as an action the row does not have.\n */\n\n/**\n * The single trailing icon beside the overflow menu.\n *\n * Three shapes, because the destinations genuinely differ: an EXTERNAL live\n * page (new tab), an IN-APP preview route, and a plain handler for the rare\n * action that opens a dialog. `unavailableReason` is the fourth state and the\n * one most easily got wrong — a screen with no single live page (a collection\n * template renders under routes it does not own) must still show the control,\n * disabled, saying why. Hiding it would read as the feature being absent.\n */\nexport interface ListQuickAction {\n /** `mdi` icon path. */\n icon: string\n /** Accessible name; also the tooltip when the action is unavailable. */\n label: string\n /** A live, external URL — opened in a new tab. */\n href?: string\n /** An in-app route — a normal client navigation. */\n to?: string\n onClick?: () => void\n /**\n * Why this row cannot use the action. Renders it DISABLED with the reason as\n * its tooltip, rather than removing it — an absent control and an\n * inapplicable one look identical, and only one of them is honest.\n */\n unavailableReason?: string\n}\n\nexport interface ListRowActionsProps {\n /** The artifact's name — every control is labelled with it, because these\n * Repeat once per row and \"More actions\" alone says nothing about which. */\n label: string\n quick?: ListQuickAction | null\n items: RowActionsMenuItem[]\n}\n\n/**\n * The quick action, restated as the menu's first entry.\n *\n * The icon and the menu are two ways into ONE action, not two features: the\n * icon is a bare glyph, so a reader who does not recognize it has the overflow\n * as the place every action is named. Deriving the item from the same\n * {@link ListQuickAction} is what keeps the two in step — availability,\n * destination and the reason it is refused are read once and cannot drift.\n */\nfunction quickActionMenuItem(\n quick: ListQuickAction,\n): RowActionsMenuItem {\n return {\n key: 'quick',\n label: quick.label,\n icon: <MdiIcon path={quick.icon} size={0.8} />,\n // `href` is off-site and opens a new tab; `to` is an in-app route.\n href: quick.href ?? quick.to,\n external: Boolean(quick.href),\n onClick: quick.href || quick.to ? undefined : quick.onClick,\n disabled: Boolean(quick.unavailableReason),\n disabledReason: quick.unavailableReason,\n }\n}\n\n/** The trailing cluster: one quick action, then the overflow menu. */\nexport function ListRowActions(props: ListRowActionsProps) {\n const { label, quick, items } = props\n const menuItems = quick ? [quickActionMenuItem(quick), ...items] : items\n return (\n <Stack\n direction=\"row\"\n spacing={0.5}\n /*\n `height: '100%'` is what actually centres these (AGL-2501). A DataGrid\n cell is a flex box, but `renderCell` content is auto-height inside it —\n so at the taller `TABLE_ROW_HEIGHT` these icons ride at the top of the\n row while the text beside them is centred. `alignItems` alone cannot\n fix it: there is no spare height to distribute until the child claims\n the row.\n */\n sx={{\n height: '100%',\n alignItems: 'center',\n justifyContent: 'flex-end',\n }}\n // The row's own click opens the detail view; without this every control\n // in here would navigate out from under the thing it just opened.\n onClick={(event) => event.stopPropagation()}\n >\n {quick ? <ListQuickButton label={label} action={quick} /> : null}\n <RowActionsMenu label={label} items={menuItems} />\n </Stack>\n )\n}\nListRowActions.displayName = 'ListRowActions'\n\nfunction ListQuickButton(props: {\n label: string\n action: ListQuickAction\n}) {\n const { label, action } = props\n const icon = <MdiIcon path={action.icon} size={0.8} />\n const name = `${action.label} — ${label}`\n\n if (action.unavailableReason) {\n return (\n <Tooltip title={action.unavailableReason}>\n {/* span: a disabled button emits no events, so the tooltip needs a\n wrapper that does. */}\n <span>\n <IconButton size=\"small\" aria-label={name} disabled>\n {icon}\n </IconButton>\n </span>\n </Tooltip>\n )\n }\n if (action.href) {\n return (\n <Tooltip title={action.label}>\n <AppLink\n componentVariant=\"icon-button\"\n size=\"small\"\n aria-label={name}\n href={action.href}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {icon}\n </AppLink>\n </Tooltip>\n )\n }\n if (action.to) {\n return (\n <Tooltip title={action.label}>\n <AppLink\n componentVariant=\"icon-button\"\n size=\"small\"\n aria-label={name}\n href={action.to}\n >\n {icon}\n </AppLink>\n </Tooltip>\n )\n }\n return (\n <Tooltip title={action.label}>\n <IconButton size=\"small\" aria-label={name} onClick={action.onClick}>\n {icon}\n </IconButton>\n </Tooltip>\n )\n}\n\n/** The field `listActionsColumn` draws, which a row click never opens through. */\nexport const LIST_ACTIONS_FIELD = 'actions'\n\n/**\n * The trailing ACTIONS column, identical on every grid list.\n *\n * Deliberately NOT MUI's `type: 'actions'`. That type renders each\n * `GridActionsCellItem` as its own icon and moves the ones marked `showInMenu`\n * into a menu it owns — which is how the three lists ended up with two, three\n * and five inline icons respectively, each a different width, and how the\n * screens table (which cannot use it at all) grew a second implementation.\n * One `renderCell` gives every list the same cluster and the same width.\n */\nexport function listActionsColumn(\n render: (row: any) => ReactNode,\n options: { width?: number } = {},\n): GridColDef {\n return {\n field: LIST_ACTIONS_FIELD,\n headerName: 'Actions',\n width: options.width ?? 110,\n align: 'right',\n headerAlign: 'right',\n sortable: false,\n filterable: false,\n hideable: false,\n disableColumnMenu: true,\n renderCell: ({ row }: any) => render(row),\n }\n}\n\n/**\n * Row selection, opted into by a list that has something to DO with a\n * selection (AGL-2595).\n *\n * Controlled, and in the caller's vocabulary — an array of `$id`s in, an\n * array out — rather than MUI's own model. The grid's model is a\n * `{ type, ids: Set }` whose `exclude` form appears the moment the header\n * checkbox is ticked, and a caller that had to fold \"everything except\n * these\" back into \"these\" would do it wrong on the page boundary; the\n * table holds the rows and does the fold once, here.\n */\nexport interface ListTableSelection {\n /** The `$id`s currently selected; ids not in `rows` are ignored. */\n selected: readonly string[]\n /** Every change, as the full new selection. */\n onChange: (ids: string[]) => void\n}\n\nexport interface ListTableProps extends DataTableProps {\n /** Row click → the artifact's detail view. */\n onOpen?: (id: string, row: any) => void\n /**\n * The toolbar's free-text search box.\n *\n * Defaults to shown where the GRID answers it, which is client filtering.\n * Under `filterMode=\"server\"` the grid applies no filter at all and the\n * model goes to the caller, so the box defaults to hidden: a list whose\n * handler reads only the column filter would otherwise offer a search that\n * narrows nothing, which reads as \"no match\" rather than \"not supported\".\n * Pass it on a server-filtered list whose handler reads `quickFilterValues`.\n */\n quickFilter?: boolean\n /**\n * Present → a checkbox column and a controlled selection. Absent → the\n * navigation-only grid every list had before, checkbox column and all.\n * The row click keeps opening the record either way: a checkbox is the\n * only thing that selects, so the two gestures cannot collide.\n */\n selectable?: ListTableSelection\n}\n\n/**\n * The grid every FLAT artifact list uses — layouts, components, templates.\n *\n * Screens is the deliberate exception and keeps its own tree; it adopts\n * {@link ListRowActions} so the two still read alike, which is the part a\n * reader actually compares.\n */\nexport function ListTable(props: ListTableProps) {\n const {\n onOpen,\n sx,\n initialState,\n hideFooter,\n rows,\n selectable,\n quickFilter,\n slotProps,\n ...rest\n } = props\n const showQuickFilter = quickFilter ?? rest.filterMode !== 'server'\n /*==========================================\n * SELECTION IS OPT-IN, AND NAVIGATION-ONLY IS THE DEFAULT.\n *\n * Without `selectable`, the three properties that make a row a NAVIGATION\n * target rather than a selectable record: `disableRowSelectionOnClick`\n * alone is not enough — it stops the click selecting, and leaves the\n * checkbox column and the \"n rows selected\" footer behind.\n *\n * With it, the grid's model is built from the caller's id list on every\n * render and folded back into one on every change. MUI's model since v8 is\n * `{ type: 'include' | 'exclude', ids }`, and `exclude` is what the header\n * checkbox produces — \"everything but these\" — so the fold has to consult\n * the rows the grid was given, which is why it lives here and not in the\n * caller. `disableRowSelectionOnClick` stays on in this branch too: a row\n * click still opens the record, and only the checkbox selects.\n *=========================================*/\n const selection = selectable\n ? {\n rowSelection: true,\n checkboxSelection: true,\n rowSelectionModel: {\n type: 'include' as const,\n ids: new Set<string>(selectable.selected),\n },\n onRowSelectionModelChange: (model: {\n type: 'include' | 'exclude'\n ids: Set<unknown>\n }) => {\n const all = (rows ?? []).map((row: any) => String(row.$id))\n selectable.onChange(\n model.type === 'include'\n ? all.filter((id) => model.ids.has(id))\n : all.filter((id) => !model.ids.has(id)),\n )\n },\n }\n : { rowSelection: false, checkboxSelection: false }\n /*==========================================\n * A HIDDEN FOOTER STILL PAGED THE ROWS.\n *\n * `hideFooter` is how a caller says \"something else owns the page\" — a\n * server-paged staff list, a cursor feed, a card whose `ListPagination`\n * sits under the grid. It hides the CONTROL and nothing else: the free\n * DataGrid always paginates, so the grid went on slicing at the shared\n * default and rows eleven onward were drawn by nothing and reachable by\n * nothing. The outer footer then described the rows it was HANDED, so it\n * reported a page two rows longer than the one on screen and offered no\n * way to see the difference.\n *\n * Eight lists pass `hideFooter`, and every one of them was losing rows past\n * the tenth. It went unnoticed because a list has to hold more than ten\n * rows to show a symptom, and most of these do not yet.\n *\n * So when the footer is hidden the grid takes ONE page as tall as the rows\n * it was given. CONTROLLED rather than `initialState`, because a\n * server-paged list hands over a different number of rows on every page and\n * initial state is read once. A floor of one because MUI rejects a page\n * size of zero, and an empty grid has nothing to slice anyway.\n *=========================================*/\n const rowCount = rows?.length ?? 0\n const unpaged = hideFooter\n ? {\n paginationModel: { page: 0, pageSize: Math.max(rowCount, 1) },\n // A controlled model with no handler logs a MUI warning, and the\n // grid must not move off page zero in any case: the page is not\n // this component's to change while somebody else owns the footer.\n onPaginationModelChange: () => undefined,\n // Keeps the size out of the \"not preset in pageSizeOptions\" warning.\n // Nothing renders it — the footer carrying the menu is hidden.\n pageSizeOptions: [Math.max(rowCount, 1)],\n }\n : {}\n return (\n <DataTableComponent\n getRowId={(row: any) => row.$id}\n {...selection}\n disableRowSelectionOnClick\n onRowClick={\n onOpen\n ? ({ id, row }, event) => {\n /*\n * A press anywhere in the actions cell is aimed at the actions.\n * `ListRowActions` stops its own clicks, but the cell is wider\n * and taller than the cluster, and a press on the padding\n * beside the menu would otherwise open the record from under\n * the reader.\n */\n const target = event.target as Element | null\n if (target?.closest?.(`[data-field=\"${LIST_ACTIONS_FIELD}\"]`)) return\n onOpen(String(id), row)\n }\n : undefined\n }\n /*\n * The list GROWS; the PAGE scrolls.\n *\n * `DataTableComponent` gives its wrapper a fixed `height: 400`, which\n * is right for a grid sitting in a pane of its own and wrong for a\n * card in a column of cards: the table got its own scrollbar, the card\n * stopped at 400px whatever it held, and the last row was cut through\n * the middle. Two scroll regions on one page is the thing to avoid —\n * a reader scrolling the page expects the page to move.\n *\n * `autoHeight` sizes the grid to its rows; clearing the wrapper's\n * height is what lets the card follow it. Caller `sx` is spread after,\n * so a list that genuinely wants a viewport can still take one.\n */\n autoHeight\n sx={[\n { height: 'auto' },\n { '& .MuiDataGrid-row': { cursor: onOpen ? 'pointer' : 'default' } },\n /*\n A cell whose content is taller than one line sets the row's height,\n and every OTHER cell then draws its content at the top of it — so a\n two-line date column leaves the counts beside it riding high while\n `ListRowActions`, which claims `height: '100%'` for itself, sits\n centred. One row, three vertical positions.\n\n Centring the cell itself fixes every column at once, including the\n ones a caller renders with a bare `<Typography>`; `alignItems`\n alone cannot, because an auto-height child has no spare height to\n distribute until something claims the row. `justifyContent` is\n deliberately not set here — a column's own `align` is what decides\n its horizontal placement, and overriding it would silently undo\n every right-aligned figure.\n */\n {\n '& .MuiDataGrid-cell': {\n display: 'flex',\n alignItems: 'center',\n },\n },\n ...(Array.isArray(sx) ? sx : sx ? [sx] : []),\n ]}\n /*\n * The column menu can hide a column; only the toolbar can bring it\n * back.\n *\n * Every column here is hideable, `Manage columns` lives in the toolbar,\n * and the toolbar was off — so hiding the last column left a grid with\n * no columns and no control that could restore one. Not a rare misuse\n * either: the per-column menu offers `Hide column` on every column, and\n * the way out was never on screen.\n *\n * The Actions column is the reason the grid was not left completely\n * blank — `listActionsColumn` marks it `hideable: false` — and \"one\n * unhideable column\" is not a recovery path.\n */\n showToolbar\n pagination\n // The console's ONE footer (AGL-2501): same options, same default, same\n // label.\n pageSizeOptions={TABLE_PAGE_SIZE_OPTIONS}\n /*\n * MERGED, not replaced. `initialState` used to ride in through `rest`,\n * so a caller that set anything in it — a column visibility model, a\n * sort — silently dropped the shared page size along with it. The two\n * keys a caller is likely to set are spread individually so that a page\n * size and a hidden column can coexist.\n */\n initialState={{\n ...initialState,\n pagination: {\n paginationModel: { pageSize: TABLE_PAGE_SIZE_DEFAULT },\n ...initialState?.pagination,\n },\n columns: { ...initialState?.columns },\n }}\n /*\n * MERGED with the caller's, for the reason `initialState` is: a caller\n * setting one slot's props must not drop the shared footer label or the\n * search box's filter-mode default along with the object they live in.\n */\n slotProps={{\n ...slotProps,\n toolbar: { showQuickFilter, ...slotProps?.toolbar },\n pagination: {\n labelRowsPerPage: TABLE_ROWS_PER_PAGE_LABEL,\n ...slotProps?.pagination,\n },\n }}\n rows={rows}\n hideFooter={hideFooter}\n {...rest}\n /*\n * AFTER `rest`, deliberately. \"The footer is hidden, so every row I was\n * handed is on screen\" is an invariant of this component, not a default\n * a call site may talk it out of — a caller that could re-slice here\n * would reintroduce exactly the rows nobody can reach.\n */\n {...unpaged}\n />\n )\n}\nListTable.displayName = 'ListTable'\n\nexport default ListTable\n"],"names":["AppLink","MdiIcon","DataTableComponent","IconButton","Stack","Tooltip","RowActionsMenu","TABLE_PAGE_SIZE_DEFAULT","TABLE_PAGE_SIZE_OPTIONS","TABLE_ROWS_PER_PAGE_LABEL","quickActionMenuItem","quick","key","label","icon","path","size","href","to","external","Boolean","onClick","undefined","disabled","unavailableReason","disabledReason","ListRowActions","props","items","menuItems","direction","spacing","sx","height","alignItems","justifyContent","event","stopPropagation","ListQuickButton","action","displayName","name","title","span","aria-label","componentVariant","target","rel","LIST_ACTIONS_FIELD","listActionsColumn","render","options","field","headerName","width","align","headerAlign","sortable","filterable","hideable","disableColumnMenu","renderCell","row","ListTable","onOpen","initialState","hideFooter","rows","selectable","quickFilter","slotProps","rest","showQuickFilter","filterMode","selection","rowSelection","checkboxSelection","rowSelectionModel","type","ids","Set","selected","onRowSelectionModelChange","model","all","map","String","$id","onChange","filter","id","has","rowCount","length","unpaged","paginationModel","page","pageSize","Math","max","onPaginationModelChange","pageSizeOptions","getRowId","disableRowSelectionOnClick","onRowClick","closest","autoHeight","cursor","display","Array","isArray","showToolbar","pagination","columns","toolbar","labelRowsPerPage"],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type LoadingModalProps } from './loading-modal';
3
+ /**
4
+ * The loading overlay host, for the App Router.
5
+ *
6
+ * A Pages Router sibling stood beside this one until AGL-2706, wiring
7
+ * `RouterLoading` on `router.events` — an API the App Router does not have,
8
+ * from a `next/router` module that throws when it is imported there. Nothing
9
+ * had rendered it since the app moved, and a `next/router` import inside a
10
+ * shared library is reachable by anything that ever names the file, so it is
11
+ * gone rather than kept for a router this repo no longer serves.
12
+ *
13
+ * Navigation intent no longer comes from a link-click heuristic. Every
14
+ * `<Link>` (through {@link NextLink}) renders a `LinkNavigationReporter` that
15
+ * drives this overlay off the link's real navigation transition
16
+ * (`useLinkStatus`) — so the overlay stays up until the destination route is
17
+ * genuinely ready, instead of settling on URL commit (AGL-459 originally
18
+ * settled on `usePathname`/`useSearchParams`, which fired before a slow
19
+ * segment finished fetching/compiling and flashed the modal away early).
20
+ *
21
+ * Dropping `useSearchParams` from this host also removes the ISR/SSG
22
+ * `BAILOUT_TO_CLIENT_SIDE_RENDERING` hazard it once needed a Suspense
23
+ * boundary to contain (AGL-594). Imperative `useLoading().queueLoading()`
24
+ * calls still render the modal.
25
+ */
26
+ export interface LoadingLayoutAppComponentProps extends Omit<Partial<LoadingModalProps>, 'children'> {
27
+ /** Per-site branding for the overlay (AGL-594) — see LoadingModal. */
28
+ brandLogoUrl?: string;
29
+ brandName?: string;
30
+ /** Any renderable children — the tenant layout passes a ReactNode. */
31
+ children?: ReactNode;
32
+ }
33
+ declare const LoadingLayoutAppComponent: import("react").ForwardRefExoticComponent<Omit<LoadingLayoutAppComponentProps, "ref"> & import("react").RefAttributes<any>>;
34
+ export { LoadingLayoutAppComponent };
35
+ export default LoadingLayoutAppComponent;
@@ -0,0 +1,42 @@
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, Fragment as _Fragment } from "react/jsx-runtime";
20
+ import { forwardRef } from "react";
21
+ import { LoadingProviderComponent } from "../contexts/loading.context.js";
22
+ import { LoadingModal } from "./loading-modal.js";
23
+ const LoadingLayoutAppComponent = /*#__PURE__*/ forwardRef((props, ref)=>{
24
+ const { children } = props, rest = _object_without_properties_loose(props, [
25
+ "children"
26
+ ]);
27
+ return /*#__PURE__*/ _jsx(LoadingProviderComponent, {
28
+ children: /*#__PURE__*/ _jsx(LoadingModal, _extends({
29
+ ref: ref
30
+ }, rest, {
31
+ children: /*#__PURE__*/ _jsx(_Fragment, {
32
+ children: children
33
+ })
34
+ }))
35
+ });
36
+ });
37
+ LoadingLayoutAppComponent.displayName = 'LoadingLayoutAppComponent';
38
+ LoadingLayoutAppComponent.aglyn = true;
39
+ export { LoadingLayoutAppComponent };
40
+ export default LoadingLayoutAppComponent;
41
+
42
+ //# sourceMappingURL=loading-layout-app.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/loading-layout-app.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 { forwardRef, type ReactNode } from 'react'\nimport { LoadingProviderComponent } from '../contexts/loading.context'\nimport { LoadingModal, type LoadingModalProps } from './loading-modal'\n\n/**\n * The loading overlay host, for the App Router.\n *\n * A Pages Router sibling stood beside this one until AGL-2706, wiring\n * `RouterLoading` on `router.events` — an API the App Router does not have,\n * from a `next/router` module that throws when it is imported there. Nothing\n * had rendered it since the app moved, and a `next/router` import inside a\n * shared library is reachable by anything that ever names the file, so it is\n * gone rather than kept for a router this repo no longer serves.\n *\n * Navigation intent no longer comes from a link-click heuristic. Every\n * `<Link>` (through {@link NextLink}) renders a `LinkNavigationReporter` that\n * drives this overlay off the link's real navigation transition\n * (`useLinkStatus`) — so the overlay stays up until the destination route is\n * genuinely ready, instead of settling on URL commit (AGL-459 originally\n * settled on `usePathname`/`useSearchParams`, which fired before a slow\n * segment finished fetching/compiling and flashed the modal away early).\n *\n * Dropping `useSearchParams` from this host also removes the ISR/SSG\n * `BAILOUT_TO_CLIENT_SIDE_RENDERING` hazard it once needed a Suspense\n * boundary to contain (AGL-594). Imperative `useLoading().queueLoading()`\n * calls still render the modal.\n */\nexport interface LoadingLayoutAppComponentProps\n extends Omit<Partial<LoadingModalProps>, 'children'> {\n /** Per-site branding for the overlay (AGL-594) — see LoadingModal. */\n brandLogoUrl?: string\n brandName?: string\n /** Any renderable children — the tenant layout passes a ReactNode. */\n children?: ReactNode\n}\n\nconst LoadingLayoutAppComponent = forwardRef<\n any,\n LoadingLayoutAppComponentProps\n>(\n (props, ref) => {\n const { children, ...rest } = props\n\n return (\n <LoadingProviderComponent>\n <LoadingModal ref={ref} {...rest}>\n {/* Fragment keeps LoadingModal's single-ReactElement child contract\n (children is a ReactNode — string/array otherwise won't type). */}\n <>{children}</>\n </LoadingModal>\n </LoadingProviderComponent>\n )\n },\n)\nLoadingLayoutAppComponent.displayName = 'LoadingLayoutAppComponent'\nLoadingLayoutAppComponent.aglyn = true\n\nexport { LoadingLayoutAppComponent }\nexport default LoadingLayoutAppComponent\n"],"names":["forwardRef","LoadingProviderComponent","LoadingModal","LoadingLayoutAppComponent","props","ref","children","rest","displayName","aglyn"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;;;AAEA,SAASA,UAAU,QAAwB,QAAO;AAClD,SAASC,wBAAwB,QAAQ,iCAA6B;AACtE,SAASC,YAAY,QAAgC,qBAAiB;AAkCtE,MAAMC,0CAA4BH,WAIhC,CAACI,OAAOC;IACN,MAAM,EAAEC,QAAQ,EAAW,GAAGF,OAATG,wCAASH;;;IAE9B,qBACE,KAACH;kBACC,cAAA,KAACC;YAAaG,KAAKA;WAASE;sBAG1B,cAAA;0BAAGD;;;;AAIX;AAEFH,0BAA0BK,WAAW,GAAG;AACxCL,0BAA0BM,KAAK,GAAG;AAElC,SAASN,yBAAyB,GAAE;AACpC,eAAeA,0BAAyB"}
@@ -0,0 +1,30 @@
1
+ import { type ModalProps } from '@mui/material';
2
+ export interface LoadingModalOverlayProps extends Partial<ModalProps> {
3
+ /** Whether the overlay is showing; drives MUI's enter/exit transition. */
4
+ open?: boolean;
5
+ /**
6
+ * Brand the overlay for a tenant site (AGL-594): a site logo image
7
+ * replaces the Aglyn logo in the bottom slot; with only a name, the
8
+ * site name renders as text. Without either, the Aglyn logo shows —
9
+ * the console's own look.
10
+ */
11
+ brandLogoUrl?: string;
12
+ brandName?: string;
13
+ }
14
+ /**
15
+ * The overlay itself: the scrim, the two progress indicators and the brand
16
+ * slot (AGL-594).
17
+ *
18
+ * A module of its own so {@link LoadingModal} can reach it through
19
+ * `next/dynamic` (AGL-2706). Everything here draws only while a navigation is
20
+ * in flight, and everything here is expensive to carry until then: MUI's
21
+ * `Modal` pulls `ModalManager`, `FocusTrap`, `Backdrop` and `Fade`,
22
+ * `CircularProgress` pulls the transition helpers, and `AglynLogoFull` is
23
+ * 6 KB of inline path data — the platform's mark, which on a white-labelled
24
+ * customer site is the one brand that must never be in the first paint.
25
+ *
26
+ * The layout above keeps `children` outside this file, so nothing a visitor
27
+ * reads depends on this chunk having arrived.
28
+ */
29
+ export declare const LoadingModalOverlay: import("react").ForwardRefExoticComponent<Omit<LoadingModalOverlayProps, "ref"> & import("react").RefAttributes<any>>;
30
+ export default LoadingModalOverlay;
@@ -0,0 +1,156 @@
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 { Box, CircularProgress, LinearProgress, Modal, Stack, styled, Typography } from "@mui/material";
21
+ import { alpha } from "@mui/material/styles";
22
+ import { forwardRef } from "react";
23
+ import { AglynLogoFull } from "../const/aglyn-logo-full.js";
24
+ import LoadingTextComponent from "./loading-text.component.js";
25
+ const LoadingOverlayModal = styled(Modal)(({ theme })=>{
26
+ // The overlay has two homes. The console's theme is built with
27
+ // `cssVariables`, so `theme.vars` carries a `*Channel` triplet for every
28
+ // palette color and `rgba(var(--…Channel) / a)` stays bound to the
29
+ // variable: it follows a scheme switch without a re-render. A published
30
+ // site renders under a plain `createTheme()` — no `vars`, no channel
31
+ // triplets — where that template would spell `rgba(undefined / a)`, an
32
+ // invalid declaration the browser drops. There the tint is composed from
33
+ // the literal palette value instead.
34
+ const backdropTint = theme.vars ? `rgba(${theme.vars.palette.background.paperChannel} / 0.48)` : alpha(theme.palette.background.paper, 0.48);
35
+ const progressTint = theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / 0.86)` : alpha(theme.palette.primary.main, 0.86);
36
+ return {
37
+ zIndex: theme.zIndex.max,
38
+ color: (theme.vars || theme).palette.text.primary,
39
+ ['& .MuiBackdrop-root']: {
40
+ backdropFilter: 'blur(5px)',
41
+ backgroundColor: backdropTint
42
+ },
43
+ ['& .wrapper']: {
44
+ position: 'absolute',
45
+ top: 0,
46
+ right: 0,
47
+ bottom: 0,
48
+ left: 0,
49
+ height: '100%',
50
+ width: '100%',
51
+ flexDirection: 'column',
52
+ display: 'flex',
53
+ alignItems: 'center',
54
+ justifyContent: 'center'
55
+ },
56
+ ['& .progress-bar-top']: {
57
+ position: 'absolute',
58
+ top: 0,
59
+ left: 0,
60
+ backgroundColor: progressTint,
61
+ width: '100%'
62
+ },
63
+ ['& .status-text']: {
64
+ fontWeight: theme.typography.fontWeightBold
65
+ }
66
+ };
67
+ });
68
+ /**
69
+ * The overlay itself: the scrim, the two progress indicators and the brand
70
+ * slot (AGL-594).
71
+ *
72
+ * A module of its own so {@link LoadingModal} can reach it through
73
+ * `next/dynamic` (AGL-2706). Everything here draws only while a navigation is
74
+ * in flight, and everything here is expensive to carry until then: MUI's
75
+ * `Modal` pulls `ModalManager`, `FocusTrap`, `Backdrop` and `Fade`,
76
+ * `CircularProgress` pulls the transition helpers, and `AglynLogoFull` is
77
+ * 6 KB of inline path data — the platform's mark, which on a white-labelled
78
+ * customer site is the one brand that must never be in the first paint.
79
+ *
80
+ * The layout above keeps `children` outside this file, so nothing a visitor
81
+ * reads depends on this chunk having arrived.
82
+ */ export const LoadingModalOverlay = /*#__PURE__*/ forwardRef((props, ref)=>{
83
+ const { open, brandLogoUrl, brandName } = props, rest = _object_without_properties_loose(props, [
84
+ "open",
85
+ "brandLogoUrl",
86
+ "brandName"
87
+ ]);
88
+ const brandSlotSx = {
89
+ m: '0 auto',
90
+ position: 'absolute',
91
+ bottom: (theme)=>theme.spacing(2)
92
+ };
93
+ return /*#__PURE__*/ _jsx(LoadingOverlayModal, _extends({
94
+ ref: ref,
95
+ open: Boolean(open),
96
+ closeAfterTransition: true
97
+ }, rest, {
98
+ children: /*#__PURE__*/ _jsxs("div", {
99
+ className: "wrapper",
100
+ children: [
101
+ /*#__PURE__*/ _jsx(LinearProgress, {
102
+ color: "primary",
103
+ className: "progress-bar-top"
104
+ }),
105
+ /*#__PURE__*/ _jsx(Stack, {
106
+ direction: "column",
107
+ spacing: 2,
108
+ sx: {
109
+ justifyContent: 'center',
110
+ alignItems: 'center',
111
+ flexGrow: 1
112
+ },
113
+ children: /*#__PURE__*/ _jsxs("div", {
114
+ children: [
115
+ /*#__PURE__*/ _jsx(CircularProgress, {
116
+ color: "primary"
117
+ }),
118
+ /*#__PURE__*/ _jsx(LoadingTextComponent, {
119
+ variant: "overline",
120
+ className: "status-text",
121
+ sx: {
122
+ ml: -0.5
123
+ },
124
+ children: "Loading"
125
+ })
126
+ ]
127
+ })
128
+ }),
129
+ brandLogoUrl ? /*#__PURE__*/ _jsx(Box, {
130
+ component: "img",
131
+ src: brandLogoUrl,
132
+ alt: brandName || 'Site logo',
133
+ sx: _extends({}, brandSlotSx, {
134
+ maxHeight: 48,
135
+ maxWidth: 200,
136
+ objectFit: 'contain'
137
+ })
138
+ }) : brandName ? /*#__PURE__*/ _jsx(Typography, {
139
+ variant: "h6",
140
+ sx: _extends({}, brandSlotSx, {
141
+ fontWeight: 600
142
+ }),
143
+ children: brandName
144
+ }) : /*#__PURE__*/ _jsx(AglynLogoFull, {
145
+ sx: _extends({}, brandSlotSx, {
146
+ fontSize: 100
147
+ })
148
+ })
149
+ ]
150
+ })
151
+ }));
152
+ });
153
+ LoadingModalOverlay.displayName = 'LoadingModalOverlay';
154
+ export default LoadingModalOverlay;
155
+
156
+ //# sourceMappingURL=loading-modal-overlay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/loading-modal-overlay.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 {\n Box,\n CircularProgress,\n LinearProgress,\n Modal,\n type ModalProps,\n Stack,\n styled,\n Typography,\n} from '@mui/material'\nimport { alpha } from '@mui/material/styles'\nimport { forwardRef } from 'react'\nimport { AglynLogoFull } from '../const/aglyn-logo-full'\nimport LoadingTextComponent from './loading-text.component'\n\nconst LoadingOverlayModal = styled(Modal)(({ theme }) => {\n // The overlay has two homes. The console's theme is built with\n // `cssVariables`, so `theme.vars` carries a `*Channel` triplet for every\n // palette color and `rgba(var(--…Channel) / a)` stays bound to the\n // variable: it follows a scheme switch without a re-render. A published\n // site renders under a plain `createTheme()` — no `vars`, no channel\n // triplets — where that template would spell `rgba(undefined / a)`, an\n // invalid declaration the browser drops. There the tint is composed from\n // the literal palette value instead.\n const backdropTint = theme.vars\n ? `rgba(${theme.vars.palette.background.paperChannel} / 0.48)`\n : alpha(theme.palette.background.paper, 0.48)\n const progressTint = theme.vars\n ? `rgba(${theme.vars.palette.primary.mainChannel} / 0.86)`\n : alpha(theme.palette.primary.main, 0.86)\n\n return {\n zIndex: theme.zIndex.max,\n color: (theme.vars || theme).palette.text.primary,\n\n ['& .MuiBackdrop-root']: {\n backdropFilter: 'blur(5px)',\n backgroundColor: backdropTint,\n },\n ['& .wrapper']: {\n position: 'absolute',\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n height: '100%',\n width: '100%',\n flexDirection: 'column',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n ['& .progress-bar-top']: {\n position: 'absolute',\n top: 0,\n left: 0,\n backgroundColor: progressTint,\n width: '100%',\n },\n ['& .status-text']: {\n fontWeight: theme.typography.fontWeightBold,\n },\n }\n})\n\nexport interface LoadingModalOverlayProps extends Partial<ModalProps> {\n /** Whether the overlay is showing; drives MUI's enter/exit transition. */\n open?: boolean\n /**\n * Brand the overlay for a tenant site (AGL-594): a site logo image\n * replaces the Aglyn logo in the bottom slot; with only a name, the\n * site name renders as text. Without either, the Aglyn logo shows —\n * the console's own look.\n */\n brandLogoUrl?: string\n brandName?: string\n}\n\n/**\n * The overlay itself: the scrim, the two progress indicators and the brand\n * slot (AGL-594).\n *\n * A module of its own so {@link LoadingModal} can reach it through\n * `next/dynamic` (AGL-2706). Everything here draws only while a navigation is\n * in flight, and everything here is expensive to carry until then: MUI's\n * `Modal` pulls `ModalManager`, `FocusTrap`, `Backdrop` and `Fade`,\n * `CircularProgress` pulls the transition helpers, and `AglynLogoFull` is\n * 6 KB of inline path data — the platform's mark, which on a white-labelled\n * customer site is the one brand that must never be in the first paint.\n *\n * The layout above keeps `children` outside this file, so nothing a visitor\n * reads depends on this chunk having arrived.\n */\nexport const LoadingModalOverlay = forwardRef<any, LoadingModalOverlayProps>(\n (props, ref) => {\n const { open, brandLogoUrl, brandName, ...rest } = props\n\n const brandSlotSx = {\n m: '0 auto',\n position: 'absolute',\n bottom: (theme: any) => theme.spacing(2),\n } as const\n\n return (\n <LoadingOverlayModal\n ref={ref}\n open={Boolean(open)}\n closeAfterTransition\n {...rest}\n >\n <div className=\"wrapper\">\n <LinearProgress color=\"primary\" className=\"progress-bar-top\" />\n <Stack\n direction=\"column\"\n spacing={2}\n sx={{\n justifyContent: 'center',\n alignItems: 'center',\n flexGrow: 1,\n }}\n >\n <div>\n <CircularProgress color=\"primary\" />\n <LoadingTextComponent\n variant=\"overline\"\n className=\"status-text\"\n sx={{ ml: -0.5 }}\n >\n Loading\n </LoadingTextComponent>\n </div>\n </Stack>\n {brandLogoUrl ? (\n <Box\n component=\"img\"\n src={brandLogoUrl}\n alt={brandName || 'Site logo'}\n sx={{\n ...brandSlotSx,\n maxHeight: 48,\n maxWidth: 200,\n objectFit: 'contain',\n }}\n />\n ) : brandName ? (\n <Typography variant=\"h6\" sx={{ ...brandSlotSx, fontWeight: 600 }}>\n {brandName}\n </Typography>\n ) : (\n <AglynLogoFull sx={{ ...brandSlotSx, fontSize: 100 }} />\n )}\n </div>\n </LoadingOverlayModal>\n )\n },\n)\nLoadingModalOverlay.displayName = 'LoadingModalOverlay'\n\nexport default LoadingModalOverlay\n"],"names":["Box","CircularProgress","LinearProgress","Modal","Stack","styled","Typography","alpha","forwardRef","AglynLogoFull","LoadingTextComponent","LoadingOverlayModal","theme","backdropTint","vars","palette","background","paperChannel","paper","progressTint","primary","mainChannel","main","zIndex","max","color","text","backdropFilter","backgroundColor","position","top","right","bottom","left","height","width","flexDirection","display","alignItems","justifyContent","fontWeight","typography","fontWeightBold","LoadingModalOverlay","props","ref","open","brandLogoUrl","brandName","rest","brandSlotSx","m","spacing","Boolean","closeAfterTransition","div","className","direction","sx","flexGrow","variant","ml","component","src","alt","maxHeight","maxWidth","objectFit","fontSize","displayName"],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { LoadingModalOverlayProps } from './loading-modal-overlay';
2
+ export type LoadingModalProps = LoadingModalOverlayProps;
3
+ /**
4
+ * The navigation overlay's mount point (AGL-594), wrapping the app's content.
5
+ *
6
+ * `children` render unconditionally and OUTSIDE the overlay, so what a
7
+ * visitor reads never waits on it. The overlay itself lives in its own module
8
+ * and arrives through `next/dynamic` (AGL-2706): MUI's `Modal` — with
9
+ * `ModalManager`, `FocusTrap`, `Backdrop` and `Fade` behind it — plus
10
+ * `LinearProgress`, `CircularProgress` and the 6 KB inline `AglynLogoFull`
11
+ * were first-paint weight in both apps for a scrim that draws only while a
12
+ * navigation is in flight, and never at all on a visit with no navigation.
13
+ *
14
+ * Once it has been shown it STAYS mounted, so `closeAfterTransition` still
15
+ * has a component to run its exit against; unmounting on close would cut the
16
+ * fade-out instead of playing it.
17
+ */
18
+ export declare const LoadingModal: import("react").ForwardRefExoticComponent<Omit<LoadingModalOverlayProps, "ref"> & import("react").RefAttributes<any>>;
19
+ export default LoadingModal;
@@ -0,0 +1,113 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2024 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, Fragment as _Fragment } from "react/jsx-runtime";
20
+ import dynamic from "next/dynamic";
21
+ import { forwardRef, Fragment, useEffect, useState } from "react";
22
+ import { LoadingContext } from "../contexts/loading.context.js";
23
+ import { onFirstNavigationIntent } from "./navigation-intent.js";
24
+ /**
25
+ * The overlay's own loader, kept beside the `dynamic()` that wraps it so the
26
+ * warm-up below and the render path fetch the same module.
27
+ */ const importOverlay = ()=>import("./loading-modal-overlay.js");
28
+ const LoadingOverlay = dynamic(importOverlay, {
29
+ ssr: false
30
+ });
31
+ /**
32
+ * Warms the overlay chunk the first time a visitor reaches for a link.
33
+ *
34
+ * The overlay covers a slow navigation, so fetching it only at the click that
35
+ * starts one would put a request in front of the very thing it exists to
36
+ * cover. It must therefore arrive early — but "early" is not "always". An
37
+ * unconditional warm-up fetches the chunk, and every chunk behind it, on every
38
+ * page view, including the majority that navigate nowhere; deferring a module
39
+ * and then fetching it anyway moves bytes off first paint without taking them
40
+ * off the wire, and adds a round trip doing it. Metered per page view, that
41
+ * costs the same as never having deferred it.
42
+ *
43
+ * Best-effort, because the render below fetches the module on demand
44
+ * regardless.
45
+ */ function useOverlayWarmUp() {
46
+ useEffect(()=>onFirstNavigationIntent(()=>{
47
+ void importOverlay().catch(()=>undefined);
48
+ }), []);
49
+ }
50
+ /**
51
+ * The navigation overlay's mount point (AGL-594), wrapping the app's content.
52
+ *
53
+ * `children` render unconditionally and OUTSIDE the overlay, so what a
54
+ * visitor reads never waits on it. The overlay itself lives in its own module
55
+ * and arrives through `next/dynamic` (AGL-2706): MUI's `Modal` — with
56
+ * `ModalManager`, `FocusTrap`, `Backdrop` and `Fade` behind it — plus
57
+ * `LinearProgress`, `CircularProgress` and the 6 KB inline `AglynLogoFull`
58
+ * were first-paint weight in both apps for a scrim that draws only while a
59
+ * navigation is in flight, and never at all on a visit with no navigation.
60
+ *
61
+ * Once it has been shown it STAYS mounted, so `closeAfterTransition` still
62
+ * has a component to run its exit against; unmounting on close would cut the
63
+ * fade-out instead of playing it.
64
+ */ export const LoadingModal = /*#__PURE__*/ forwardRef((props, ref)=>{
65
+ const { open, children } = props, rest = _object_without_properties_loose(props, [
66
+ "open",
67
+ "children"
68
+ ]);
69
+ const [everShown, setEverShown] = useState(false);
70
+ useOverlayWarmUp();
71
+ return /*#__PURE__*/ _jsx(LoadingContext.Consumer, {
72
+ children: ({ loading })=>{
73
+ const isOpen = Boolean(open || loading);
74
+ return /*#__PURE__*/ _jsxs(Fragment, {
75
+ children: [
76
+ children,
77
+ /*#__PURE__*/ _jsx(OverlaySlot, {
78
+ isOpen: isOpen,
79
+ everShown: everShown,
80
+ onShown: setEverShown,
81
+ children: /*#__PURE__*/ _jsx(LoadingOverlay, _extends({
82
+ ref: ref,
83
+ open: isOpen
84
+ }, rest))
85
+ })
86
+ ]
87
+ });
88
+ }
89
+ });
90
+ });
91
+ LoadingModal.displayName = 'LoadingModal';
92
+ /**
93
+ * Holds the overlay off the tree until it is first asked for.
94
+ *
95
+ * A component rather than a branch in the render prop above: the "has it ever
96
+ * opened" latch has to be a hook, and the render prop of a context consumer
97
+ * is not a place hooks may be called.
98
+ */ function OverlaySlot({ isOpen, everShown, onShown, children }) {
99
+ useEffect(()=>{
100
+ if (isOpen && !everShown) onShown(true);
101
+ }, [
102
+ isOpen,
103
+ everShown,
104
+ onShown
105
+ ]);
106
+ if (!isOpen && !everShown) return null;
107
+ return /*#__PURE__*/ _jsx(_Fragment, {
108
+ children: children
109
+ });
110
+ }
111
+ export default LoadingModal;
112
+
113
+ //# sourceMappingURL=loading-modal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/loading-modal.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2024 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 dynamic from 'next/dynamic'\nimport { forwardRef, Fragment, useEffect, useState } from 'react'\nimport { LoadingContext } from '../contexts/loading.context'\nimport { onFirstNavigationIntent } from './navigation-intent'\nimport type { LoadingModalOverlayProps } from './loading-modal-overlay'\n\n/**\n * The overlay's own loader, kept beside the `dynamic()` that wraps it so the\n * warm-up below and the render path fetch the same module.\n */\nconst importOverlay = () => import('./loading-modal-overlay')\n\nconst LoadingOverlay = dynamic(importOverlay, { ssr: false })\n\nexport type LoadingModalProps = LoadingModalOverlayProps\n\n/**\n * Warms the overlay chunk the first time a visitor reaches for a link.\n *\n * The overlay covers a slow navigation, so fetching it only at the click that\n * starts one would put a request in front of the very thing it exists to\n * cover. It must therefore arrive early — but \"early\" is not \"always\". An\n * unconditional warm-up fetches the chunk, and every chunk behind it, on every\n * page view, including the majority that navigate nowhere; deferring a module\n * and then fetching it anyway moves bytes off first paint without taking them\n * off the wire, and adds a round trip doing it. Metered per page view, that\n * costs the same as never having deferred it.\n *\n * Best-effort, because the render below fetches the module on demand\n * regardless.\n */\nfunction useOverlayWarmUp(): void {\n useEffect(\n () =>\n onFirstNavigationIntent(() => {\n void importOverlay().catch(() => undefined)\n }),\n [],\n )\n}\n\n/**\n * The navigation overlay's mount point (AGL-594), wrapping the app's content.\n *\n * `children` render unconditionally and OUTSIDE the overlay, so what a\n * visitor reads never waits on it. The overlay itself lives in its own module\n * and arrives through `next/dynamic` (AGL-2706): MUI's `Modal` — with\n * `ModalManager`, `FocusTrap`, `Backdrop` and `Fade` behind it — plus\n * `LinearProgress`, `CircularProgress` and the 6 KB inline `AglynLogoFull`\n * were first-paint weight in both apps for a scrim that draws only while a\n * navigation is in flight, and never at all on a visit with no navigation.\n *\n * Once it has been shown it STAYS mounted, so `closeAfterTransition` still\n * has a component to run its exit against; unmounting on close would cut the\n * fade-out instead of playing it.\n */\nexport const LoadingModal = forwardRef<any, LoadingModalProps>((props, ref) => {\n const { open, children, ...rest } = props\n const [everShown, setEverShown] = useState(false)\n useOverlayWarmUp()\n\n return (\n <LoadingContext.Consumer>\n {({ loading }) => {\n const isOpen = Boolean(open || loading)\n\n return (\n <Fragment>\n {children}\n <OverlaySlot\n isOpen={isOpen}\n everShown={everShown}\n onShown={setEverShown}\n >\n <LoadingOverlay ref={ref} open={isOpen} {...rest} />\n </OverlaySlot>\n </Fragment>\n )\n }}\n </LoadingContext.Consumer>\n )\n})\nLoadingModal.displayName = 'LoadingModal'\n\n/**\n * Holds the overlay off the tree until it is first asked for.\n *\n * A component rather than a branch in the render prop above: the \"has it ever\n * opened\" latch has to be a hook, and the render prop of a context consumer\n * is not a place hooks may be called.\n */\nfunction OverlaySlot({\n isOpen,\n everShown,\n onShown,\n children,\n}: {\n isOpen: boolean\n everShown: boolean\n onShown: (shown: true) => void\n children: React.ReactNode\n}) {\n useEffect(() => {\n if (isOpen && !everShown) onShown(true)\n }, [isOpen, everShown, onShown])\n if (!isOpen && !everShown) return null\n return <>{children}</>\n}\n\nexport default LoadingModal\n"],"names":["dynamic","forwardRef","Fragment","useEffect","useState","LoadingContext","onFirstNavigationIntent","importOverlay","LoadingOverlay","ssr","useOverlayWarmUp","catch","undefined","LoadingModal","props","ref","open","children","rest","everShown","setEverShown","Consumer","loading","isOpen","Boolean","OverlaySlot","onShown","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;;;AAEA,OAAOA,aAAa,eAAc;AAClC,SAASC,UAAU,EAAEC,QAAQ,EAAEC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AACjE,SAASC,cAAc,QAAQ,iCAA6B;AAC5D,SAASC,uBAAuB,QAAQ,yBAAqB;AAG7D;;;CAGC,GACD,MAAMC,gBAAgB,IAAM,MAAM,CAAC;AAEnC,MAAMC,iBAAiBR,QAAQO,eAAe;IAAEE,KAAK;AAAM;AAI3D;;;;;;;;;;;;;;CAcC,GACD,SAASC;IACPP,UACE,IACEG,wBAAwB;YACtB,KAAKC,gBAAgBI,KAAK,CAAC,IAAMC;QACnC,IACF,EAAE;AAEN;AAEA;;;;;;;;;;;;;;CAcC,GACD,OAAO,MAAMC,6BAAeZ,WAAmC,CAACa,OAAOC;IACrE,MAAM,EAAEC,IAAI,EAAEC,QAAQ,EAAW,GAAGH,OAATI,wCAASJ;;;;IACpC,MAAM,CAACK,WAAWC,aAAa,GAAGhB,SAAS;IAC3CM;IAEA,qBACE,KAACL,eAAegB,QAAQ;kBACrB,CAAC,EAAEC,OAAO,EAAE;YACX,MAAMC,SAASC,QAAQR,QAAQM;YAE/B,qBACE,MAACpB;;oBACEe;kCACD,KAACQ;wBACCF,QAAQA;wBACRJ,WAAWA;wBACXO,SAASN;kCAET,cAAA,KAACZ;4BAAeO,KAAKA;4BAAKC,MAAMO;2BAAYL;;;;QAIpD;;AAGN,GAAE;AACFL,aAAac,WAAW,GAAG;AAE3B;;;;;;CAMC,GACD,SAASF,YAAY,EACnBF,MAAM,EACNJ,SAAS,EACTO,OAAO,EACPT,QAAQ,EAMT;IACCd,UAAU;QACR,IAAIoB,UAAU,CAACJ,WAAWO,QAAQ;IACpC,GAAG;QAACH;QAAQJ;QAAWO;KAAQ;IAC/B,IAAI,CAACH,UAAU,CAACJ,WAAW,OAAO;IAClC,qBAAO;kBAAGF;;AACZ;AAEA,eAAeJ,aAAY"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 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
+ */
17
+ import { type TypographyProps } from '@mui/material';
18
+ export interface LoadingTextProps extends TypographyProps<'div'> {
19
+ }
20
+ export declare const LoadingTextComponent: import("react").ForwardRefExoticComponent<Omit<LoadingTextProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
21
+ export default LoadingTextComponent;
@@ -0,0 +1,40 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
3
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
+ /**
5
+ * @license
6
+ * Copyright 2023 Aglyn LLC
7
+ *
8
+ * Licensed under the Apache License, Version 2.0 (the "License");
9
+ * you may not use this file except in compliance with the License.
10
+ * You may obtain a copy of the License at
11
+ *
12
+ * http://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * Unless required by applicable law or agreed to in writing, software
15
+ * distributed under the License is distributed on an "AS IS" BASIS,
16
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ * See the License for the specific language governing permissions and
18
+ * limitations under the License.
19
+ */ import { Typography } from "@mui/material";
20
+ import { forwardRef } from "react";
21
+ import EllipsisPulseComponent from "./ellipsis-pulse.component.js";
22
+ export const LoadingTextComponent = /*#__PURE__*/ forwardRef((props, ref)=>{
23
+ const { children } = props, rest = _object_without_properties_loose(props, [
24
+ "children"
25
+ ]);
26
+ return /*#__PURE__*/ _jsxs(Typography, _extends({
27
+ ref: ref,
28
+ component: "div"
29
+ }, rest, {
30
+ children: [
31
+ children,
32
+ " ",
33
+ /*#__PURE__*/ _jsx(EllipsisPulseComponent, {})
34
+ ]
35
+ }));
36
+ });
37
+ LoadingTextComponent.displayName = 'LoadingTextComponent';
38
+ export default LoadingTextComponent;
39
+
40
+ //# sourceMappingURL=loading-text.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/loading-text.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2023 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\nimport { Typography, type TypographyProps } from '@mui/material'\nimport { forwardRef } from 'react'\nimport EllipsisPulseComponent from './ellipsis-pulse.component'\n\nexport interface LoadingTextProps extends TypographyProps<'div'> {}\n\nexport const LoadingTextComponent = forwardRef<\n HTMLDivElement,\n LoadingTextProps\n>((props, ref) => {\n const { children, ...rest } = props\n\n return (\n <Typography ref={ref} component=\"div\" {...rest}>\n {children} <EllipsisPulseComponent />\n </Typography>\n )\n})\nLoadingTextComponent.displayName = 'LoadingTextComponent'\n\nexport default LoadingTextComponent\n"],"names":["Typography","forwardRef","EllipsisPulseComponent","LoadingTextComponent","props","ref","children","rest","component","displayName"],"mappings":";;;AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,UAAU,QAA8B,gBAAe;AAChE,SAASC,UAAU,QAAQ,QAAO;AAClC,OAAOC,4BAA4B,gCAA4B;AAI/D,OAAO,MAAMC,qCAAuBF,WAGlC,CAACG,OAAOC;IACR,MAAM,EAAEC,QAAQ,EAAW,GAAGF,OAATG,wCAASH;;;IAE9B,qBACE,MAACJ;QAAWK,KAAKA;QAAKG,WAAU;OAAUD;;YACvCD;YAAS;0BAAC,KAACJ;;;AAGlB,GAAE;AACFC,qBAAqBM,WAAW,GAAG;AAEnC,eAAeN,qBAAoB"}
@@ -0,0 +1,2 @@
1
+ export { default } from './mdi-icon';
2
+ export * from './mdi-icon';
@@ -0,0 +1,4 @@
1
+ export { default } from "./mdi-icon.js";
2
+ export * from "./mdi-icon.js";
3
+
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../../libs/shared/ui/jsx/src/lib/components/mdi-icon/index.ts"],"sourcesContent":["export { default } from './mdi-icon'\nexport * from './mdi-icon'\n"],"names":["default"],"mappings":"AAAA,SAASA,OAAO,QAAQ,gBAAY;AACpC,cAAc,gBAAY"}
@@ -0,0 +1,31 @@
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
+ */
17
+ import { type SvgIconProps } from '@mui/material';
18
+ import { type ReactElement } from 'react';
19
+ import { type MdIconProps } from './md-icon';
20
+ export interface MdIconStackProps extends SvgIconProps {
21
+ children: ReactElement<MdIconProps>[] | ReactElement<MdIconProps>;
22
+ title?: string | null;
23
+ description?: string | null;
24
+ size?: number | string | null;
25
+ horizontal?: boolean | null;
26
+ vertical?: boolean | null;
27
+ rotate?: number | null;
28
+ spin?: boolean | number | null;
29
+ }
30
+ export declare const MdIconStack: import("react").ForwardRefExoticComponent<Omit<MdIconStackProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
31
+ export default MdIconStack;