@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,86 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface CardColumnsProps {
3
+ /** The cards, in reading order. */
4
+ items: Array<{
5
+ key?: string;
6
+ children: ReactNode;
7
+ }>;
8
+ /**
9
+ * Columns at the wide breakpoint. Always one below `md`.
10
+ *
11
+ * Two is right far more often than it looks, and a third column is not a
12
+ * free improvement: multicol may not REORDER, so one card taller than its
13
+ * share of the flow strands the columns after it. Measured while this
14
+ * component was briefly tried on the screen version view — five cards, one
15
+ * of them 764px — Chrome balanced three columns to 988/764/278px, 932px of
16
+ * raggedness, against 210px at two. More columns means less room to even
17
+ * them out. Raise this only against a measurement.
18
+ *
19
+ * When a page genuinely wants columns of DIFFERENT widths, this is the wrong
20
+ * component: multicol cannot span. `GridItems masonry` can, and that is what
21
+ * the screen version view ended up using.
22
+ */
23
+ columns?: number;
24
+ /** Gutter, in theme spacing units. */
25
+ spacing?: number;
26
+ }
27
+ /**
28
+ * A BALANCED multi-column card flow for a page of cards (AGL-2486).
29
+ *
30
+ * ## The bug it was built for
31
+ *
32
+ * The staff org detail page laid twelve cards out as six rigid rows of two. Every
33
+ * item in a flex row is as tall as the tallest one in it, so `Effective
34
+ * entitlements` — a long table — made its whole row entitlements-tall and
35
+ * left the area beside it dead. On a real org the hole was most of a screen,
36
+ * and `Metered usage`, the card sitting in it, was pushed to the bottom of
37
+ * that void with nothing above it.
38
+ *
39
+ * ## Why not `GridItems masonry`
40
+ *
41
+ * `GridItems` carries a `masonry` mode, and it is the only one of the two that
42
+ * can SPAN — a full-width item is a band of its own there, and a band whose
43
+ * cards declare different widths lays them out as the widths ask, which is the
44
+ * billing page's top row (`md: 4` beside `md: 8`). Multicol can do neither.
45
+ *
46
+ * Where the two overlap is a run of cards that all declare the SAME width, and
47
+ * there they fill their columns by different rules. `GridItems` fans such a
48
+ * band across the columns it asked for round-robin, so the nth card lands in
49
+ * column `n % count`: distribution by COUNT, and a row-major reading order —
50
+ * card 0 top-left, card 1 top-RIGHT. Multicol lets the browser place the
51
+ * fragmentation breaks to equalize the column heights: distribution by HEIGHT,
52
+ * and a column-major reading order — card 0 top-left, card 1 BELOW it.
53
+ *
54
+ * Neither is better in general. Round-robin gives an even card count and can
55
+ * still leave the columns ragged at the bottom when the cards weigh very
56
+ * different amounts; balancing evens the bottoms out and gives up the
57
+ * left-to-right sweep. Pick by which of the two a page's reader would notice:
58
+ * cards whose heights come from data — a funnel with a row per stage, a table
59
+ * with a row per owner — are the case for balancing, which is why the CRM
60
+ * report page uses this one. `/[orgSlug]/billing` uses both, masonry for the
61
+ * band whose cards differ in width and this for the run whose cards do not.
62
+ *
63
+ * ## What this does instead
64
+ *
65
+ * CSS multi-column. The browser is told the column count and left to place
66
+ * the fragmentation breaks, which is the one mechanism that BALANCES: column
67
+ * heights come out near-equal by construction, whatever the cards weigh
68
+ * today, because `column-fill: balance` is the default and the browser
69
+ * re-solves it on every layout.
70
+ *
71
+ * That is deliberately not a measured layout. A JS masonry assigns each card
72
+ * a row span from its measured height, and the span is only right until the
73
+ * content changes size — a span that is too small does not leave a gap, it
74
+ * places the next card UNDERNEATH the one before it. Overlapping cards are a
75
+ * far worse defect than the hole this exists to close, and they appear
76
+ * exactly when measurement is least reliable: data still arriving, images
77
+ * still decoding. Here nothing claims a height on any card's behalf, so
78
+ * nothing can go stale and nothing can overlap.
79
+ *
80
+ * `break-inside: avoid` on each item is what keeps a card whole rather than
81
+ * split across the column boundary; without it multicol would happily saw a
82
+ * table in half. Below `md` the count drops to one and the cards read in
83
+ * their authored order, which is the same collapse the flex grid had.
84
+ */
85
+ export declare function CardColumns({ items, columns, spacing, }: CardColumnsProps): import("react").JSX.Element;
86
+ export default CardColumns;
@@ -0,0 +1,148 @@
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 { jsx as _jsx } from "react/jsx-runtime";
18
+ import { Box } from "@mui/material";
19
+ import { EMPTY_FRAME_SELECTOR } from "./grid-items.js";
20
+ /**
21
+ * A BALANCED multi-column card flow for a page of cards (AGL-2486).
22
+ *
23
+ * ## The bug it was built for
24
+ *
25
+ * The staff org detail page laid twelve cards out as six rigid rows of two. Every
26
+ * item in a flex row is as tall as the tallest one in it, so `Effective
27
+ * entitlements` — a long table — made its whole row entitlements-tall and
28
+ * left the area beside it dead. On a real org the hole was most of a screen,
29
+ * and `Metered usage`, the card sitting in it, was pushed to the bottom of
30
+ * that void with nothing above it.
31
+ *
32
+ * ## Why not `GridItems masonry`
33
+ *
34
+ * `GridItems` carries a `masonry` mode, and it is the only one of the two that
35
+ * can SPAN — a full-width item is a band of its own there, and a band whose
36
+ * cards declare different widths lays them out as the widths ask, which is the
37
+ * billing page's top row (`md: 4` beside `md: 8`). Multicol can do neither.
38
+ *
39
+ * Where the two overlap is a run of cards that all declare the SAME width, and
40
+ * there they fill their columns by different rules. `GridItems` fans such a
41
+ * band across the columns it asked for round-robin, so the nth card lands in
42
+ * column `n % count`: distribution by COUNT, and a row-major reading order —
43
+ * card 0 top-left, card 1 top-RIGHT. Multicol lets the browser place the
44
+ * fragmentation breaks to equalize the column heights: distribution by HEIGHT,
45
+ * and a column-major reading order — card 0 top-left, card 1 BELOW it.
46
+ *
47
+ * Neither is better in general. Round-robin gives an even card count and can
48
+ * still leave the columns ragged at the bottom when the cards weigh very
49
+ * different amounts; balancing evens the bottoms out and gives up the
50
+ * left-to-right sweep. Pick by which of the two a page's reader would notice:
51
+ * cards whose heights come from data — a funnel with a row per stage, a table
52
+ * with a row per owner — are the case for balancing, which is why the CRM
53
+ * report page uses this one. `/[orgSlug]/billing` uses both, masonry for the
54
+ * band whose cards differ in width and this for the run whose cards do not.
55
+ *
56
+ * ## What this does instead
57
+ *
58
+ * CSS multi-column. The browser is told the column count and left to place
59
+ * the fragmentation breaks, which is the one mechanism that BALANCES: column
60
+ * heights come out near-equal by construction, whatever the cards weigh
61
+ * today, because `column-fill: balance` is the default and the browser
62
+ * re-solves it on every layout.
63
+ *
64
+ * That is deliberately not a measured layout. A JS masonry assigns each card
65
+ * a row span from its measured height, and the span is only right until the
66
+ * content changes size — a span that is too small does not leave a gap, it
67
+ * places the next card UNDERNEATH the one before it. Overlapping cards are a
68
+ * far worse defect than the hole this exists to close, and they appear
69
+ * exactly when measurement is least reliable: data still arriving, images
70
+ * still decoding. Here nothing claims a height on any card's behalf, so
71
+ * nothing can go stale and nothing can overlap.
72
+ *
73
+ * `break-inside: avoid` on each item is what keeps a card whole rather than
74
+ * split across the column boundary; without it multicol would happily saw a
75
+ * table in half. Below `md` the count drops to one and the cards read in
76
+ * their authored order, which is the same collapse the flex grid had.
77
+ */ export function CardColumns({ items, columns = 2, spacing = 3 }) {
78
+ return(// The run's own box, which ends at its last card (AGL-3059). Every column
79
+ // of the flow inside ends in one gutter (below), which would otherwise
80
+ // sit under the run as a gap of its own and double the space to whatever
81
+ // follows: a grid band's gap, a Stack's spacing. Multicol cannot say which
82
+ // card ends a column, so the flow gives that gutter back with a negative
83
+ // bottom margin, and this box contains it: a block formatting context
84
+ // ends at its last child's margin edge. The margin sits on the flow, not
85
+ // on this box, because a `Stack` parent resets its children's margins.
86
+ /*#__PURE__*/ _jsx(Box, {
87
+ sx: {
88
+ display: 'flow-root'
89
+ },
90
+ children: /*#__PURE__*/ _jsx(Box, {
91
+ sx: {
92
+ columnCount: {
93
+ xs: 1,
94
+ md: columns
95
+ },
96
+ columnGap: spacing,
97
+ mb: -spacing,
98
+ // A card is never sawn across the boundary. The `-webkit-` and legacy
99
+ // page-break aliases are still what older WebKit reads.
100
+ '& > *': {
101
+ breakInside: 'avoid',
102
+ WebkitColumnBreakInside: 'avoid',
103
+ pageBreakInside: 'avoid',
104
+ // The gutter BETWEEN stacked cards. A multicol child cannot use
105
+ // the parent's row gap — there are no rows — so the spacing is its
106
+ // own. Padding, not a margin: a margin at the foot of a column is
107
+ // truncated at the column break, so only the LAST column would end
108
+ // in a gutter, and the negative margin above would pull what
109
+ // follows up against a first column taller than the last. Padding
110
+ // stays with its card, so every column ends in exactly one.
111
+ pb: spacing,
112
+ // Multicol boxes are fragment containers; a card that establishes
113
+ // its own block formatting context is the reliably-measured one.
114
+ display: 'block',
115
+ // A wide child (a table, a long unbroken id) must not push the
116
+ // column track past the edge.
117
+ minWidth: 0
118
+ },
119
+ // A card that renders NOTHING must not weigh on the balance. A plugin
120
+ // widget slot renders nothing when no plugin is entitled for it,
121
+ // leaving a wrapper that carries only its gutter — which multicol
122
+ // counts as real content and balances the columns around. `:empty`
123
+ // is exact here: the wrapper has no element and no text node in that
124
+ // case and only in that case.
125
+ // More specific than the `& > *` above (`:empty` adds a class-level
126
+ // component), so `display: none` wins over `display: block`.
127
+ '& > *:empty': {
128
+ display: 'none'
129
+ },
130
+ // A wrapper whose one element is a marked frame with nothing drawn
131
+ // in it weighs the same (AGL-3050): a widget zone whose widgets all
132
+ // rendered nothing is that frame.
133
+ [`& > *:has(> ${EMPTY_FRAME_SELECTOR})`]: {
134
+ display: 'none'
135
+ }
136
+ },
137
+ children: items.map((item, index)=>{
138
+ var _item_key;
139
+ return /*#__PURE__*/ _jsx(Box, {
140
+ children: item.children
141
+ }, (_item_key = item.key) != null ? _item_key : index);
142
+ })
143
+ })
144
+ }));
145
+ }
146
+ export default CardColumns;
147
+
148
+ //# sourceMappingURL=card-columns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/card-columns.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 { Box } from '@mui/material'\nimport type { ReactNode } from 'react'\nimport { EMPTY_FRAME_SELECTOR } from './grid-items'\n\nexport interface CardColumnsProps {\n /** The cards, in reading order. */\n items: Array<{ key?: string; children: ReactNode }>\n /**\n * Columns at the wide breakpoint. Always one below `md`.\n *\n * Two is right far more often than it looks, and a third column is not a\n * free improvement: multicol may not REORDER, so one card taller than its\n * share of the flow strands the columns after it. Measured while this\n * component was briefly tried on the screen version view — five cards, one\n * of them 764px — Chrome balanced three columns to 988/764/278px, 932px of\n * raggedness, against 210px at two. More columns means less room to even\n * them out. Raise this only against a measurement.\n *\n * When a page genuinely wants columns of DIFFERENT widths, this is the wrong\n * component: multicol cannot span. `GridItems masonry` can, and that is what\n * the screen version view ended up using.\n */\n columns?: number\n /** Gutter, in theme spacing units. */\n spacing?: number\n}\n\n/**\n * A BALANCED multi-column card flow for a page of cards (AGL-2486).\n *\n * ## The bug it was built for\n *\n * The staff org detail page laid twelve cards out as six rigid rows of two. Every\n * item in a flex row is as tall as the tallest one in it, so `Effective\n * entitlements` — a long table — made its whole row entitlements-tall and\n * left the area beside it dead. On a real org the hole was most of a screen,\n * and `Metered usage`, the card sitting in it, was pushed to the bottom of\n * that void with nothing above it.\n *\n * ## Why not `GridItems masonry`\n *\n * `GridItems` carries a `masonry` mode, and it is the only one of the two that\n * can SPAN — a full-width item is a band of its own there, and a band whose\n * cards declare different widths lays them out as the widths ask, which is the\n * billing page's top row (`md: 4` beside `md: 8`). Multicol can do neither.\n *\n * Where the two overlap is a run of cards that all declare the SAME width, and\n * there they fill their columns by different rules. `GridItems` fans such a\n * band across the columns it asked for round-robin, so the nth card lands in\n * column `n % count`: distribution by COUNT, and a row-major reading order —\n * card 0 top-left, card 1 top-RIGHT. Multicol lets the browser place the\n * fragmentation breaks to equalize the column heights: distribution by HEIGHT,\n * and a column-major reading order — card 0 top-left, card 1 BELOW it.\n *\n * Neither is better in general. Round-robin gives an even card count and can\n * still leave the columns ragged at the bottom when the cards weigh very\n * different amounts; balancing evens the bottoms out and gives up the\n * left-to-right sweep. Pick by which of the two a page's reader would notice:\n * cards whose heights come from data — a funnel with a row per stage, a table\n * with a row per owner — are the case for balancing, which is why the CRM\n * report page uses this one. `/[orgSlug]/billing` uses both, masonry for the\n * band whose cards differ in width and this for the run whose cards do not.\n *\n * ## What this does instead\n *\n * CSS multi-column. The browser is told the column count and left to place\n * the fragmentation breaks, which is the one mechanism that BALANCES: column\n * heights come out near-equal by construction, whatever the cards weigh\n * today, because `column-fill: balance` is the default and the browser\n * re-solves it on every layout.\n *\n * That is deliberately not a measured layout. A JS masonry assigns each card\n * a row span from its measured height, and the span is only right until the\n * content changes size — a span that is too small does not leave a gap, it\n * places the next card UNDERNEATH the one before it. Overlapping cards are a\n * far worse defect than the hole this exists to close, and they appear\n * exactly when measurement is least reliable: data still arriving, images\n * still decoding. Here nothing claims a height on any card's behalf, so\n * nothing can go stale and nothing can overlap.\n *\n * `break-inside: avoid` on each item is what keeps a card whole rather than\n * split across the column boundary; without it multicol would happily saw a\n * table in half. Below `md` the count drops to one and the cards read in\n * their authored order, which is the same collapse the flex grid had.\n */\nexport function CardColumns({\n items,\n columns = 2,\n spacing = 3,\n}: CardColumnsProps) {\n return (\n // The run's own box, which ends at its last card (AGL-3059). Every column\n // of the flow inside ends in one gutter (below), which would otherwise\n // sit under the run as a gap of its own and double the space to whatever\n // follows: a grid band's gap, a Stack's spacing. Multicol cannot say which\n // card ends a column, so the flow gives that gutter back with a negative\n // bottom margin, and this box contains it: a block formatting context\n // ends at its last child's margin edge. The margin sits on the flow, not\n // on this box, because a `Stack` parent resets its children's margins.\n <Box sx={{ display: 'flow-root' }}>\n <Box\n sx={{\n columnCount: { xs: 1, md: columns },\n columnGap: spacing,\n mb: -spacing,\n // A card is never sawn across the boundary. The `-webkit-` and legacy\n // page-break aliases are still what older WebKit reads.\n '& > *': {\n breakInside: 'avoid',\n WebkitColumnBreakInside: 'avoid',\n pageBreakInside: 'avoid',\n // The gutter BETWEEN stacked cards. A multicol child cannot use\n // the parent's row gap — there are no rows — so the spacing is its\n // own. Padding, not a margin: a margin at the foot of a column is\n // truncated at the column break, so only the LAST column would end\n // in a gutter, and the negative margin above would pull what\n // follows up against a first column taller than the last. Padding\n // stays with its card, so every column ends in exactly one.\n pb: spacing,\n // Multicol boxes are fragment containers; a card that establishes\n // its own block formatting context is the reliably-measured one.\n display: 'block',\n // A wide child (a table, a long unbroken id) must not push the\n // column track past the edge.\n minWidth: 0,\n },\n // A card that renders NOTHING must not weigh on the balance. A plugin\n // widget slot renders nothing when no plugin is entitled for it,\n // leaving a wrapper that carries only its gutter — which multicol\n // counts as real content and balances the columns around. `:empty`\n // is exact here: the wrapper has no element and no text node in that\n // case and only in that case.\n // More specific than the `& > *` above (`:empty` adds a class-level\n // component), so `display: none` wins over `display: block`.\n '& > *:empty': { display: 'none' },\n // A wrapper whose one element is a marked frame with nothing drawn\n // in it weighs the same (AGL-3050): a widget zone whose widgets all\n // rendered nothing is that frame.\n [`& > *:has(> ${EMPTY_FRAME_SELECTOR})`]: { display: 'none' },\n }}\n >\n {items.map((item, index) => (\n <Box key={item.key ?? index}>{item.children}</Box>\n ))}\n </Box>\n </Box>\n )\n}\n\nexport default CardColumns\n"],"names":["Box","EMPTY_FRAME_SELECTOR","CardColumns","items","columns","spacing","sx","display","columnCount","xs","md","columnGap","mb","breakInside","WebkitColumnBreakInside","pageBreakInside","pb","minWidth","map","item","index","children","key"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAEA,SAASA,GAAG,QAAQ,gBAAe;AAEnC,SAASC,oBAAoB,QAAQ,kBAAc;AAyBnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyDC,GACD,OAAO,SAASC,YAAY,EAC1BC,KAAK,EACLC,UAAU,CAAC,EACXC,UAAU,CAAC,EACM;IACjB,OACE,0EAA0E;IAC1E,uEAAuE;IACvE,yEAAyE;IACzE,2EAA2E;IAC3E,yEAAyE;IACzE,sEAAsE;IACtE,yEAAyE;IACzE,uEAAuE;kBACvE,KAACL;QAAIM,IAAI;YAAEC,SAAS;QAAY;kBAC9B,cAAA,KAACP;YACCM,IAAI;gBACFE,aAAa;oBAAEC,IAAI;oBAAGC,IAAIN;gBAAQ;gBAClCO,WAAWN;gBACXO,IAAI,CAACP;gBACL,sEAAsE;gBACtE,wDAAwD;gBACxD,SAAS;oBACPQ,aAAa;oBACbC,yBAAyB;oBACzBC,iBAAiB;oBACjB,gEAAgE;oBAChE,mEAAmE;oBACnE,kEAAkE;oBAClE,mEAAmE;oBACnE,6DAA6D;oBAC7D,kEAAkE;oBAClE,4DAA4D;oBAC5DC,IAAIX;oBACJ,kEAAkE;oBAClE,iEAAiE;oBACjEE,SAAS;oBACT,+DAA+D;oBAC/D,8BAA8B;oBAC9BU,UAAU;gBACZ;gBACA,sEAAsE;gBACtE,iEAAiE;gBACjE,kEAAkE;gBAClE,mEAAmE;gBACnE,qEAAqE;gBACrE,8BAA8B;gBAC9B,oEAAoE;gBACpE,6DAA6D;gBAC7D,eAAe;oBAAEV,SAAS;gBAAO;gBACjC,mEAAmE;gBACnE,oEAAoE;gBACpE,kCAAkC;gBAClC,CAAC,CAAC,YAAY,EAAEN,qBAAqB,CAAC,CAAC,CAAC,EAAE;oBAAEM,SAAS;gBAAO;YAC9D;sBAECJ,MAAMe,GAAG,CAAC,CAACC,MAAMC;oBACND;qCAAV,KAACnB;8BAA6BmB,KAAKE,QAAQ;oBAAjCF,YAAAA,KAAKG,GAAG,YAARH,YAAYC;;;;AAKhC;AAEA,eAAelB,YAAW"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 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 HelpTipContent } from './help-tip.component';
18
+ import { type CardActionsProps, type CardContentProps, type CardHeaderProps, type CardProps } from '@mui/material';
19
+ export interface CardDisplayProps extends CardProps {
20
+ contentGutterX?: boolean;
21
+ contentGutterY?: boolean;
22
+ contentBordered?: 'all' | 'top' | 'bottom' | undefined;
23
+ headerCentered?: boolean;
24
+ header?: JSX.Children;
25
+ subheader?: JSX.Children;
26
+ actions?: JSX.Children;
27
+ disableContentWrapper?: boolean;
28
+ /** Contextual help affordance rendered beside the header title (AGL-601). */
29
+ help?: HelpTipContent;
30
+ HeaderProps?: CardHeaderProps;
31
+ ContentProps?: CardContentProps;
32
+ ActionProps?: CardActionsProps;
33
+ }
34
+ declare const CardDisplay: import("react").ForwardRefExoticComponent<Omit<CardDisplayProps, "ref"> & import("react").RefAttributes<any>>;
35
+ export { CardDisplay };
36
+ export default CardDisplay;
@@ -0,0 +1,158 @@
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 2022 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 { ErrorBoundaryComponent } from "./error-boundary.component.js";
20
+ import { HelpTip } from "./help-tip.component.js";
21
+ import { generateComponentClassKeys, styled } from "@aglyn/shared-ui-theme";
22
+ import { Box, Card as MuiCard, CardActions as MuiCardActions, CardContent as MuiCardContent, CardHeader as MuiCardHeader } from "@mui/material";
23
+ import clsx from "clsx";
24
+ import { forwardRef } from "react";
25
+ const classKeys = generateComponentClassKeys('CardDisplay', [
26
+ 'contentGutterX',
27
+ 'contentGutterY',
28
+ 'headerCentered',
29
+ 'headerBordered',
30
+ 'actionsBordered'
31
+ ]);
32
+ const Card = styled(MuiCard)(({ theme })=>{
33
+ const tv = theme.vars || theme;
34
+ return {
35
+ '.MuiCardContent-root': {
36
+ padding: 0,
37
+ borderWidth: 0,
38
+ borderStyle: 'solid',
39
+ borderColor: tv.palette.divider,
40
+ ':last-of-type': {
41
+ paddingBottom: 'initial'
42
+ }
43
+ },
44
+ '.MuiCardHeader-root': {
45
+ fontWeight: theme.typography.fontWeightBold
46
+ },
47
+ [`&.${classKeys.contentGutterX}`]: {
48
+ '.MuiCardContent-root': {
49
+ paddingLeft: theme.spacing(2),
50
+ paddingRight: theme.spacing(2),
51
+ [theme.breakpoints.up('md')]: {
52
+ paddingLeft: theme.spacing(2),
53
+ paddingRight: theme.spacing(2)
54
+ }
55
+ }
56
+ },
57
+ [`&.${classKeys.contentGutterY}`]: {
58
+ '.MuiCardContent-root': {
59
+ paddingTop: theme.spacing(2),
60
+ paddingBottom: theme.spacing(2)
61
+ }
62
+ },
63
+ [`&.${classKeys.headerCentered}`]: {
64
+ '.MuiCardHeader-root': {
65
+ marginBottom: theme.spacing(-1),
66
+ alignSelf: 'center'
67
+ }
68
+ },
69
+ [`&.${classKeys.headerBordered}`]: {
70
+ '.MuiCardContent-root': {
71
+ borderTopWidth: 1
72
+ }
73
+ },
74
+ [`&.${classKeys.actionsBordered}`]: {
75
+ '.MuiCardContent-root': {
76
+ borderBottomWidth: 1
77
+ }
78
+ }
79
+ };
80
+ });
81
+ const CardDisplay = /*#__PURE__*/ forwardRef((props, ref)=>{
82
+ var _help_title;
83
+ const { actions, classes, children, className, header, subheader, disableContentWrapper, help, ActionProps, HeaderProps, ContentProps, contentGutterX, contentGutterY, headerCentered, contentBordered } = props, rest = _object_without_properties_loose(props, [
84
+ "actions",
85
+ "classes",
86
+ "children",
87
+ "className",
88
+ "header",
89
+ "subheader",
90
+ "disableContentWrapper",
91
+ "help",
92
+ "ActionProps",
93
+ "HeaderProps",
94
+ "ContentProps",
95
+ "contentGutterX",
96
+ "contentGutterY",
97
+ "headerCentered",
98
+ "contentBordered"
99
+ ]);
100
+ const headerTitle = help && header != null ? /*#__PURE__*/ _jsxs(Box, {
101
+ component: "span",
102
+ sx: {
103
+ display: 'inline-flex',
104
+ alignItems: 'center',
105
+ gap: 0.5
106
+ },
107
+ children: [
108
+ header,
109
+ /*#__PURE__*/ _jsx(HelpTip, _extends({}, help, {
110
+ title: (_help_title = help.title) != null ? _help_title : typeof header === 'string' ? header : undefined,
111
+ sx: {
112
+ fontSize: '0.8em',
113
+ my: -0.5
114
+ }
115
+ }))
116
+ ]
117
+ }) : header;
118
+ const allBordered = contentBordered === 'all';
119
+ const headerBordered = contentBordered === 'top';
120
+ const actionsBordered = contentBordered === 'bottom';
121
+ const cardClassName = clsx({
122
+ [classKeys.contentGutterX]: Boolean(contentGutterX),
123
+ [classKeys.contentGutterY]: Boolean(contentGutterY),
124
+ [classKeys.headerBordered]: Boolean(allBordered || headerBordered),
125
+ [classKeys.actionsBordered]: Boolean(allBordered || actionsBordered),
126
+ [classKeys.headerCentered]: Boolean(headerCentered)
127
+ }, className);
128
+ return /*#__PURE__*/ _jsx(Card, _extends({
129
+ ref: ref,
130
+ className: cardClassName
131
+ }, rest, {
132
+ children: /*#__PURE__*/ _jsxs(ErrorBoundaryComponent, {
133
+ children: [
134
+ header || HeaderProps || subheader ? /*#__PURE__*/ _jsx(MuiCardHeader, _extends({
135
+ title: headerTitle,
136
+ subheader: subheader,
137
+ slotProps: {
138
+ title: {
139
+ variant: 'h6',
140
+ component: 'div'
141
+ }
142
+ }
143
+ }, HeaderProps)) : null,
144
+ disableContentWrapper ? children : children || ContentProps ? /*#__PURE__*/ _jsx(MuiCardContent, _extends({}, ContentProps, {
145
+ children: (ContentProps == null ? void 0 : ContentProps.children) || children
146
+ })) : null,
147
+ actions || ActionProps ? /*#__PURE__*/ _jsx(MuiCardActions, _extends({}, ActionProps, {
148
+ children: (ActionProps == null ? void 0 : ActionProps.children) || actions
149
+ })) : null
150
+ ]
151
+ })
152
+ }));
153
+ });
154
+ CardDisplay.displayName = 'CardDisplayComponent';
155
+ export { CardDisplay };
156
+ export default CardDisplay;
157
+
158
+ //# sourceMappingURL=card-display.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/card-display.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2022 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 { ErrorBoundaryComponent } from './error-boundary.component'\nimport { HelpTip, type HelpTipContent } from './help-tip.component'\nimport { generateComponentClassKeys, styled } from '@aglyn/shared-ui-theme'\nimport {\n Box,\n Card as MuiCard,\n CardActions as MuiCardActions,\n type CardActionsProps,\n CardContent as MuiCardContent,\n type CardContentProps,\n CardHeader as MuiCardHeader,\n type CardHeaderProps,\n type CardProps,\n} from '@mui/material'\nimport clsx from 'clsx'\nimport { forwardRef } from 'react'\n\nconst classKeys = generateComponentClassKeys('CardDisplay', [\n 'contentGutterX',\n 'contentGutterY',\n 'headerCentered',\n 'headerBordered',\n 'actionsBordered',\n])\n\nconst Card = styled(MuiCard)(({ theme }) => {\n const tv = (theme as any).vars || theme\n return {\n '.MuiCardContent-root': {\n padding: 0,\n borderWidth: 0,\n borderStyle: 'solid',\n borderColor: tv.palette.divider,\n ':last-of-type': {\n paddingBottom: 'initial',\n },\n },\n '.MuiCardHeader-root': {\n fontWeight: theme.typography.fontWeightBold,\n },\n [`&.${classKeys.contentGutterX}`]: {\n '.MuiCardContent-root': {\n paddingLeft: theme.spacing(2),\n paddingRight: theme.spacing(2),\n [theme.breakpoints.up('md')]: {\n paddingLeft: theme.spacing(2),\n paddingRight: theme.spacing(2),\n },\n },\n },\n [`&.${classKeys.contentGutterY}`]: {\n '.MuiCardContent-root': {\n paddingTop: theme.spacing(2),\n paddingBottom: theme.spacing(2),\n },\n },\n [`&.${classKeys.headerCentered}`]: {\n '.MuiCardHeader-root': {\n marginBottom: theme.spacing(-1),\n alignSelf: 'center',\n },\n },\n [`&.${classKeys.headerBordered}`]: {\n '.MuiCardContent-root': {\n borderTopWidth: 1,\n },\n },\n [`&.${classKeys.actionsBordered}`]: {\n '.MuiCardContent-root': {\n borderBottomWidth: 1,\n },\n },\n }\n})\n\nexport interface CardDisplayProps extends CardProps {\n contentGutterX?: boolean\n contentGutterY?: boolean\n contentBordered?: 'all' | 'top' | 'bottom' | undefined\n headerCentered?: boolean\n header?: JSX.Children\n subheader?: JSX.Children\n actions?: JSX.Children\n disableContentWrapper?: boolean\n /** Contextual help affordance rendered beside the header title (AGL-601). */\n help?: HelpTipContent\n HeaderProps?: CardHeaderProps\n ContentProps?: CardContentProps\n ActionProps?: CardActionsProps\n}\n\nconst CardDisplay = forwardRef<any, CardDisplayProps>((props, ref) => {\n const {\n actions,\n classes,\n children,\n className,\n header,\n subheader,\n disableContentWrapper,\n help,\n ActionProps,\n HeaderProps,\n ContentProps,\n contentGutterX,\n contentGutterY,\n headerCentered,\n contentBordered,\n ...rest\n } = props\n\n const headerTitle =\n help && header != null ? (\n <Box\n component=\"span\"\n sx={{ display: 'inline-flex', alignItems: 'center', gap: 0.5 }}\n >\n {header}\n <HelpTip\n {...help}\n title={help.title ?? (typeof header === 'string' ? header : undefined)}\n sx={{ fontSize: '0.8em', my: -0.5 }}\n />\n </Box>\n ) : (\n header\n )\n\n const allBordered = contentBordered === 'all'\n const headerBordered = contentBordered === 'top'\n const actionsBordered = contentBordered === 'bottom'\n\n const cardClassName = clsx(\n {\n [classKeys.contentGutterX]: Boolean(contentGutterX),\n [classKeys.contentGutterY]: Boolean(contentGutterY),\n [classKeys.headerBordered]: Boolean(allBordered || headerBordered),\n [classKeys.actionsBordered]: Boolean(allBordered || actionsBordered),\n [classKeys.headerCentered]: Boolean(headerCentered),\n },\n className,\n )\n\n return (\n <Card ref={ref} className={cardClassName} {...rest}>\n <ErrorBoundaryComponent>\n {header || HeaderProps || subheader ? (\n <MuiCardHeader\n title={headerTitle}\n subheader={subheader}\n slotProps={{ title: { variant: 'h6', component: 'div' } }}\n {...HeaderProps}\n />\n ) : null}\n {disableContentWrapper ? (\n children\n ) : children || ContentProps ? (\n <MuiCardContent {...ContentProps}>\n {ContentProps?.children || children}\n </MuiCardContent>\n ) : null}\n {actions || ActionProps ? (\n <MuiCardActions {...ActionProps}>\n {ActionProps?.children || actions}\n </MuiCardActions>\n ) : null}\n </ErrorBoundaryComponent>\n </Card>\n )\n})\n\nCardDisplay.displayName = 'CardDisplayComponent'\n\nexport { CardDisplay }\nexport default CardDisplay\n"],"names":["ErrorBoundaryComponent","HelpTip","generateComponentClassKeys","styled","Box","Card","MuiCard","CardActions","MuiCardActions","CardContent","MuiCardContent","CardHeader","MuiCardHeader","clsx","forwardRef","classKeys","theme","tv","vars","padding","borderWidth","borderStyle","borderColor","palette","divider","paddingBottom","fontWeight","typography","fontWeightBold","contentGutterX","paddingLeft","spacing","paddingRight","breakpoints","up","contentGutterY","paddingTop","headerCentered","marginBottom","alignSelf","headerBordered","borderTopWidth","actionsBordered","borderBottomWidth","CardDisplay","props","ref","help","actions","classes","children","className","header","subheader","disableContentWrapper","ActionProps","HeaderProps","ContentProps","contentBordered","rest","headerTitle","component","sx","display","alignItems","gap","title","undefined","fontSize","my","allBordered","cardClassName","Boolean","slotProps","variant","displayName"],"mappings":"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"}
@@ -0,0 +1,35 @@
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 CardActionAreaProps as MuiCardActionAreaProps, type CardProps as MuiCardProps, type TypographyProps } from '@mui/material';
18
+ import type { ComponentProps } from 'react';
19
+ import type { GridListItemData } from './grid-list';
20
+ declare const CardBox: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
21
+ export interface CardListItemProps extends Omit<Partial<MuiCardProps>, 'children'> {
22
+ item: GridListItemData;
23
+ children?: JSX.Children | ((props: {
24
+ item: GridListItemData;
25
+ selected: boolean;
26
+ }) => JSX.Children);
27
+ label?: JSX.Children;
28
+ selected?: boolean;
29
+ CardActionAreaProps?: Partial<MuiCardActionAreaProps>;
30
+ WrapperBoxProps?: Partial<ComponentProps<typeof CardBox>>;
31
+ ContentBoxProps?: Partial<ComponentProps<typeof CardBox>>;
32
+ LabelTypographyProps?: Partial<TypographyProps>;
33
+ }
34
+ export declare const CardListItem: import("react").ForwardRefExoticComponent<Omit<CardListItemProps, "ref"> & import("react").RefAttributes<any>>;
35
+ export default CardListItem;
@@ -0,0 +1,137 @@
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 2026 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 { generateComponentClassKeys, styled } from "@aglyn/shared-ui-theme";
20
+ import { Box, Card as MuiCard, Typography } from "@mui/material";
21
+ import clsx from "clsx";
22
+ import { forwardRef } from "react";
23
+ import ChildrenFunctionProp from "./children-function-prop.js";
24
+ const cardClasses = generateComponentClassKeys('CardListItem', [
25
+ 'actionArea',
26
+ 'selected',
27
+ 'aspectContainer',
28
+ 'wrapper',
29
+ 'content',
30
+ 'label'
31
+ ]);
32
+ const CardBox = styled('div')({});
33
+ const Card = styled(MuiCard)(({ theme })=>{
34
+ const tv = theme.vars || theme;
35
+ return {
36
+ // The selected treatment used to hang off `.CardListItem-actionArea`, a
37
+ // class this component has never rendered — so `selected` set a class and
38
+ // painted NOTHING, which is why the icon picker read as unresponsive and
39
+ // invited repeat clicking (AGL-2486). It lives on the card itself now,
40
+ // where there is always an element to carry it.
41
+ [`&.${cardClasses.selected}`]: {
42
+ backgroundColor: tv.palette.primary.main,
43
+ color: tv.palette.primary.contrastText,
44
+ outline: `2px solid ${tv.palette.primary.main}`,
45
+ outlineOffset: 1,
46
+ [`.${cardClasses.actionArea}`]: {
47
+ backgroundColor: tv.palette.primary.main,
48
+ color: tv.palette.primary.contrastText
49
+ }
50
+ },
51
+ [`.${cardClasses.aspectContainer}`]: {
52
+ height: 0,
53
+ position: 'relative',
54
+ paddingTop: `${3 / 4 * 100}%`
55
+ },
56
+ [`.${cardClasses.wrapper}`]: {
57
+ position: 'absolute',
58
+ left: 0,
59
+ top: 0,
60
+ width: '100%',
61
+ height: '100%'
62
+ },
63
+ [`.${cardClasses.content}`]: {
64
+ width: '100%',
65
+ height: '100%',
66
+ display: 'flex',
67
+ textAlign: 'center',
68
+ alignItems: 'center',
69
+ flexDirection: 'column',
70
+ justifyContent: 'space-evenly',
71
+ padding: 0.5
72
+ },
73
+ [`.${cardClasses.label}`]: {
74
+ lineHeight: 1.43,
75
+ fontSize: theme.typography.pxToRem(10),
76
+ textTransform: 'uppercase'
77
+ }
78
+ };
79
+ });
80
+ export const CardListItem = /*#__PURE__*/ forwardRef(function RefRenderFn(props, ref) {
81
+ const { className, children, selected, item, label, CardActionAreaProps, WrapperBoxProps, ContentBoxProps, LabelTypographyProps } = props, rest = _object_without_properties_loose(props, [
82
+ "className",
83
+ "children",
84
+ "selected",
85
+ "item",
86
+ "label",
87
+ "CardActionAreaProps",
88
+ "WrapperBoxProps",
89
+ "ContentBoxProps",
90
+ "LabelTypographyProps"
91
+ ]);
92
+ const isSelected = Boolean(selected);
93
+ return /*#__PURE__*/ _jsx(Card, _extends({
94
+ ref: ref,
95
+ className: clsx({
96
+ [cardClasses.selected]: isSelected
97
+ }, className)
98
+ }, rest, {
99
+ children: /*#__PURE__*/ _jsx(Box, {
100
+ className: clsx(cardClasses.aspectContainer, CardActionAreaProps == null ? void 0 : CardActionAreaProps.className),
101
+ children: /*#__PURE__*/ _jsx(Box, _extends({}, WrapperBoxProps, {
102
+ className: clsx(cardClasses.wrapper, WrapperBoxProps == null ? void 0 : WrapperBoxProps.className),
103
+ children: /*#__PURE__*/ _jsxs(Box, _extends({}, ContentBoxProps, {
104
+ className: clsx(cardClasses.content, ContentBoxProps == null ? void 0 : ContentBoxProps.className),
105
+ children: [
106
+ /*#__PURE__*/ _jsx(ChildrenFunctionProp, {
107
+ childrenProp: children,
108
+ args: {
109
+ item,
110
+ selected: isSelected
111
+ }
112
+ }),
113
+ label && /*#__PURE__*/ _jsx(Typography, _extends({
114
+ component: "span",
115
+ variant: "subtitle2"
116
+ }, LabelTypographyProps, {
117
+ className: clsx(cardClasses.label, LabelTypographyProps == null ? void 0 : LabelTypographyProps.className),
118
+ sx: [
119
+ {
120
+ display: "block"
121
+ },
122
+ ...Array.isArray(LabelTypographyProps == null ? void 0 : LabelTypographyProps.sx) ? LabelTypographyProps.sx : [
123
+ LabelTypographyProps == null ? void 0 : LabelTypographyProps.sx
124
+ ]
125
+ ],
126
+ children: label
127
+ }))
128
+ ]
129
+ }))
130
+ }))
131
+ })
132
+ }));
133
+ });
134
+ CardListItem.displayName = 'CardListItem';
135
+ export default CardListItem;
136
+
137
+ //# sourceMappingURL=card-list-item.js.map