@12-apps/ui 6.38.0 → 6.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (324) hide show
  1. package/dist/_internal/components/data-display/DataGrid/DataGrid.body.js +3 -2
  2. package/dist/_internal/components/data-display/DataGrid/DataGrid.cells.js +2 -1
  3. package/dist/_internal/components/data-display/DataGrid/DataGrid.js +4 -4
  4. package/dist/_internal/components/data-display/DataGrid/DataGrid.model.js +2 -1
  5. package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +19 -19
  6. package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +26 -26
  7. package/dist/_internal/components/data-display/DataViews/SaveViewModal.js +5 -5
  8. package/dist/_internal/components/data-display/DataViews/base-list-card-geometry.js +4 -4
  9. package/dist/_internal/components/data-display/DataViews/base-list-card-slots.js +3 -3
  10. package/dist/_internal/components/data-display/DataViews/base-list-card.js +5 -5
  11. package/dist/_internal/components/data-display/DataViews/data-views-columns.js +2 -2
  12. package/dist/_internal/components/data-display/DataViews/data-views-display-panel.js +3 -3
  13. package/dist/_internal/components/data-display/DataViews/data-views-display-tabs.js +2 -2
  14. package/dist/_internal/components/data-display/DataViews/data-views-grid-bodies.js +8 -8
  15. package/dist/_internal/components/data-display/DataViews/data-views-grid-helpers.js +1 -1
  16. package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +16 -16
  17. package/dist/_internal/components/data-display/DataViews/data-views-layout-context.js +1 -1
  18. package/dist/_internal/components/data-display/DataViews/data-views-overflow-costs.js +4 -3
  19. package/dist/_internal/components/data-display/DataViews/data-views-overflow.js +3 -2
  20. package/dist/_internal/components/data-display/DataViews/data-views-scope-tabs.js +2 -2
  21. package/dist/_internal/components/data-display/DataViews/data-views-shell-toolbar.js +6 -6
  22. package/dist/_internal/components/data-display/DataViews/data-views-table-parts.js +6 -6
  23. package/dist/_internal/components/data-display/DataViews/data-views-toolbar.js +5 -5
  24. package/dist/_internal/components/data-display/DataViews/list-card-rails.js +2 -2
  25. package/dist/_internal/components/data-display/DataViews/use-data-views-state.js +3 -3
  26. package/dist/_internal/components/data-display/FleetMap/FleetBody.js +9 -9
  27. package/dist/_internal/components/data-display/FleetMap/FleetCanvas.js +8 -8
  28. package/dist/_internal/components/data-display/FleetMap/FleetMap.js +10 -10
  29. package/dist/_internal/components/data-display/MapPreview/MapDecorations.js +2 -2
  30. package/dist/_internal/components/data-display/MapPreview/MapPreview.hooks.js +2 -2
  31. package/dist/_internal/components/data-display/MapPreview/MapPreview.js +7 -7
  32. package/dist/_internal/components/data-display/MapPreview/MapTiles.js +2 -2
  33. package/dist/_internal/components/data-display/MapPreview/StaticMapView.js +4 -4
  34. package/dist/_internal/components/data-display/MapPreview/mapProjection.js +3 -3
  35. package/dist/_internal/components/data-display/MapPreview/useMapPreview.js +3 -3
  36. package/dist/_internal/components/data-display/Table/Table.helpers.js +5 -3
  37. package/dist/_internal/components/data-display/Table/Table.hooks.js +2 -1
  38. package/dist/_internal/components/data-display/Table/Table.js +4 -4
  39. package/dist/_internal/components/data-display/Table/TableParts.hooks.js +4 -2
  40. package/dist/_internal/components/data-display/Table/TableParts.js +4 -2
  41. package/dist/_internal/components/data-display/index.js +18 -18
  42. package/dist/_internal/components/form/Calendar/Calendar.js +5 -4
  43. package/dist/_internal/components/form/Calendar/CalendarDay.js +2 -1
  44. package/dist/_internal/components/form/Calendar/CalendarDayCell.js +3 -2
  45. package/dist/_internal/components/form/Calendar/CalendarMonth.js +4 -3
  46. package/dist/_internal/components/form/DateRangePicker/DateRangePicker.js +5 -5
  47. package/dist/_internal/components/form/Switch/Switch.js +4 -4
  48. package/dist/_internal/components/form/Switch/Switch.metrics.js +5 -1
  49. package/dist/_internal/components/form/Switch/Switch.parts.js +3 -3
  50. package/dist/_internal/components/form/Switch/Switch.styles.js +2 -2
  51. package/dist/_internal/components/form/index.js +9 -9
  52. package/dist/_internal/components/index.js +37 -37
  53. package/dist/_internal/components/layout/CardGrid/CardGrid.js +2 -1
  54. package/dist/_internal/components/layout/Resizable/Resizable.helpers.js +8 -3
  55. package/dist/_internal/components/layout/Resizable/Resizable.hooks.js +3 -2
  56. package/dist/_internal/components/layout/Resizable/Resizable.js +4 -3
  57. package/dist/_internal/components/layout/ScrollArea/ScrollArea.helpers.js +1 -1
  58. package/dist/_internal/components/layout/ScrollArea/ScrollArea.js +2 -2
  59. package/dist/_internal/components/layout/index.js +5 -5
  60. package/dist/_internal/components/utility/InfiniteScroll/InfiniteScroll.hooks.js +1 -1
  61. package/dist/_internal/components/utility/InfiniteScroll/InfiniteScroll.js +4 -3
  62. package/dist/_internal/components/utility/InfiniteScroll/InfiniteScroll.parts.js +2 -1
  63. package/dist/_internal/components/utility/VirtualList/VirtualList.hooks.js +6 -3
  64. package/dist/_internal/components/utility/VirtualList/VirtualList.js +3 -2
  65. package/dist/_internal/components/utility/index.js +5 -5
  66. package/dist/{chunk-J2DAQQQH.js → chunk-222HN7GK.js} +33 -64
  67. package/dist/chunk-222HN7GK.js.map +1 -0
  68. package/dist/{chunk-MR2HKBHS.js → chunk-27LOJVR3.js} +2 -2
  69. package/dist/{chunk-S3D5VBHW.js → chunk-3YOXVNO4.js} +7 -7
  70. package/dist/{chunk-CZIX4BW2.js → chunk-4ALF5PB5.js} +3 -3
  71. package/dist/{chunk-XJPJ6ESI.js → chunk-4OAKGKK5.js} +3 -3
  72. package/dist/{chunk-4CHROSWR.js → chunk-5ETBB2DG.js} +2 -2
  73. package/dist/{chunk-ATSHKSSD.js → chunk-5KNDAC24.js} +20 -7
  74. package/dist/chunk-5KNDAC24.js.map +1 -0
  75. package/dist/{chunk-ULTOQ6ZV.js → chunk-5LWB4BYX.js} +80 -89
  76. package/dist/chunk-5LWB4BYX.js.map +1 -0
  77. package/dist/{chunk-46UPILLK.js → chunk-5NT2M2JI.js} +2 -2
  78. package/dist/{chunk-H5BEWPEY.js → chunk-6N2EDWMG.js} +2 -2
  79. package/dist/{chunk-GJQYM3PM.js → chunk-6PU3JYVY.js} +2 -2
  80. package/dist/{chunk-PUBPZOQJ.js → chunk-AG3DY5TH.js} +8 -5
  81. package/dist/chunk-AG3DY5TH.js.map +1 -0
  82. package/dist/{chunk-PPRV4LTM.js → chunk-BWHOCNGW.js} +4 -4
  83. package/dist/chunk-BWHOCNGW.js.map +1 -0
  84. package/dist/{chunk-TUBCN4DJ.js → chunk-CB6DTWD5.js} +7 -7
  85. package/dist/chunk-CB6DTWD5.js.map +1 -0
  86. package/dist/{chunk-ZAY6OA6F.js → chunk-D4FZ3ANG.js} +15 -5
  87. package/dist/chunk-D4FZ3ANG.js.map +1 -0
  88. package/dist/{chunk-Y7F5JBAT.js → chunk-DDRKYNPB.js} +2 -2
  89. package/dist/{chunk-DLJGBJZW.js → chunk-DGMDQHMI.js} +16 -9
  90. package/dist/chunk-DGMDQHMI.js.map +1 -0
  91. package/dist/{chunk-IAGOUTI6.js → chunk-DNT5PZLF.js} +21 -12
  92. package/dist/chunk-DNT5PZLF.js.map +1 -0
  93. package/dist/{chunk-DZA7RSLX.js → chunk-DVSO3EG6.js} +19 -11
  94. package/dist/chunk-DVSO3EG6.js.map +1 -0
  95. package/dist/{chunk-OS6KPL4D.js → chunk-EHYI2WCJ.js} +4 -4
  96. package/dist/{chunk-NB3FGWU4.js → chunk-EQXIW5MQ.js} +2 -2
  97. package/dist/{chunk-C66RGVAS.js → chunk-ERY6D2OV.js} +6 -4
  98. package/dist/chunk-ERY6D2OV.js.map +1 -0
  99. package/dist/{chunk-M2JTIH5M.js → chunk-F44R7US6.js} +2 -2
  100. package/dist/{chunk-AROBXRC5.js → chunk-F7JTIHV5.js} +18 -7
  101. package/dist/chunk-F7JTIHV5.js.map +1 -0
  102. package/dist/{chunk-XJJXBUPN.js → chunk-FX26DAFF.js} +2 -2
  103. package/dist/{chunk-R6SN73RX.js → chunk-GLHNMTP6.js} +7 -7
  104. package/dist/{chunk-YU26GBNX.js → chunk-H3AQQOTI.js} +9 -4
  105. package/dist/chunk-H3AQQOTI.js.map +1 -0
  106. package/dist/{chunk-HTZNB6IV.js → chunk-H5ZTIELC.js} +23 -8
  107. package/dist/chunk-H5ZTIELC.js.map +1 -0
  108. package/dist/{chunk-GSFNH4C5.js → chunk-HBP2OU4Q.js} +15 -8
  109. package/dist/chunk-HBP2OU4Q.js.map +1 -0
  110. package/dist/{chunk-I4QA2F4L.js → chunk-HBRQPG7H.js} +5 -5
  111. package/dist/{chunk-HGMBY5LP.js → chunk-HQWJUHR4.js} +18 -11
  112. package/dist/chunk-HQWJUHR4.js.map +1 -0
  113. package/dist/{chunk-CNQUCNEA.js → chunk-I3F4C5SS.js} +3 -3
  114. package/dist/{chunk-UFJYJHQI.js → chunk-J5VWGQSR.js} +2 -2
  115. package/dist/{chunk-MTFCPPZ5.js → chunk-JWZJSXI5.js} +3 -2
  116. package/dist/chunk-JWZJSXI5.js.map +1 -0
  117. package/dist/{chunk-4JFL62K3.js → chunk-K7FSTB2K.js} +3 -3
  118. package/dist/{chunk-FFCJ7NR2.js → chunk-KRQUPE4K.js} +4 -4
  119. package/dist/{chunk-2OYFTSG4.js → chunk-KXLUMEDX.js} +2 -2
  120. package/dist/{chunk-DVAAUWTC.js → chunk-LCHCE2G5.js} +2 -2
  121. package/dist/{chunk-G4HBNILE.js → chunk-LEHMWJNZ.js} +3 -3
  122. package/dist/{chunk-P6TNXBDA.js → chunk-MYKWJCR7.js} +9 -9
  123. package/dist/chunk-MYKWJCR7.js.map +1 -0
  124. package/dist/{chunk-TQ6FPOPD.js → chunk-ODW2D5PN.js} +39 -30
  125. package/dist/chunk-ODW2D5PN.js.map +1 -0
  126. package/dist/{chunk-RZYSKQTS.js → chunk-PCBZYORN.js} +3 -3
  127. package/dist/{chunk-5OBXEMQO.js → chunk-PRIBOWX4.js} +3 -3
  128. package/dist/{chunk-F42MJOHM.js → chunk-PVM7XTLZ.js} +64 -62
  129. package/dist/chunk-PVM7XTLZ.js.map +1 -0
  130. package/dist/{chunk-3TDVGZZN.js → chunk-QBTBRJ2Q.js} +37 -13
  131. package/dist/chunk-QBTBRJ2Q.js.map +1 -0
  132. package/dist/{chunk-2WFDHFK4.js → chunk-QNCWSDXE.js} +26 -11
  133. package/dist/chunk-QNCWSDXE.js.map +1 -0
  134. package/dist/{chunk-PQECNGDE.js → chunk-QSRZOXQI.js} +2 -2
  135. package/dist/{chunk-RHIDWUK7.js → chunk-QUWK7SYN.js} +1 -2
  136. package/dist/chunk-QUWK7SYN.js.map +1 -0
  137. package/dist/{chunk-UN5INW6K.js → chunk-R53ZOW4B.js} +8 -4
  138. package/dist/chunk-R53ZOW4B.js.map +1 -0
  139. package/dist/{chunk-DCJSHYE5.js → chunk-RSDYS5B3.js} +4 -4
  140. package/dist/{chunk-N5GVW6RO.js → chunk-S6IWKDWT.js} +2 -2
  141. package/dist/{chunk-TKC6WHGB.js → chunk-SBIZXZPP.js} +2 -2
  142. package/dist/{chunk-D5SZXH7Q.js → chunk-TNBJ4DK4.js} +7 -3
  143. package/dist/chunk-TNBJ4DK4.js.map +1 -0
  144. package/dist/{chunk-PMOEG36E.js → chunk-XZJM6EPC.js} +8 -6
  145. package/dist/chunk-XZJM6EPC.js.map +1 -0
  146. package/dist/{chunk-QF6LTUCE.js → chunk-Y2X7LYIN.js} +4 -4
  147. package/dist/chunk-Y2X7LYIN.js.map +1 -0
  148. package/dist/{chunk-UEVHI62V.js → chunk-YCCY77W5.js} +2 -2
  149. package/dist/{chunk-DF4K5XVW.js → chunk-YZVR5ROE.js} +14 -6
  150. package/dist/chunk-YZVR5ROE.js.map +1 -0
  151. package/dist/{chunk-AUSUCZYR.js → chunk-ZBVU2YWV.js} +5 -5
  152. package/dist/chunk-ZBVU2YWV.js.map +1 -0
  153. package/dist/{chunk-VZIB5W5L.js → chunk-ZGCPDA3F.js} +2 -2
  154. package/dist/data-display/DataGrid.js +4 -4
  155. package/dist/data-display/DataViews.js +29 -29
  156. package/dist/data-display/FleetMap.js +10 -10
  157. package/dist/data-display/MapPreview.js +7 -7
  158. package/dist/data-display/Table.js +4 -4
  159. package/dist/form/Calendar.js +5 -4
  160. package/dist/form/DateRangePicker.js +5 -5
  161. package/dist/form/Switch.js +4 -4
  162. package/dist/layout/CardGrid.js +2 -1
  163. package/dist/layout/Resizable.js +4 -3
  164. package/dist/layout/ScrollArea.js +2 -2
  165. package/dist/native/form/Switch.js +3 -1
  166. package/dist/native/form/Switch.js.map +1 -1
  167. package/dist/types/components/data-display/DataGrid/DataGrid.body.d.ts.map +1 -1
  168. package/dist/types/components/data-display/DataGrid/DataGrid.cells.d.ts +4 -2
  169. package/dist/types/components/data-display/DataGrid/DataGrid.cells.d.ts.map +1 -1
  170. package/dist/types/components/data-display/DataGrid/DataGrid.model.d.ts +7 -1
  171. package/dist/types/components/data-display/DataGrid/DataGrid.model.d.ts.map +1 -1
  172. package/dist/types/components/data-display/DataGrid/DataGrid.types.d.ts +10 -4
  173. package/dist/types/components/data-display/DataGrid/DataGrid.types.d.ts.map +1 -1
  174. package/dist/types/components/data-display/DataViews/data-views-columns.d.ts.map +1 -1
  175. package/dist/types/components/data-display/DataViews/data-views-grid-helpers.d.ts +2 -0
  176. package/dist/types/components/data-display/DataViews/data-views-grid-helpers.d.ts.map +1 -1
  177. package/dist/types/components/data-display/DataViews/data-views-layout-context.d.ts +7 -3
  178. package/dist/types/components/data-display/DataViews/data-views-layout-context.d.ts.map +1 -1
  179. package/dist/types/components/data-display/DataViews/data-views-overflow-costs.d.ts +19 -9
  180. package/dist/types/components/data-display/DataViews/data-views-overflow-costs.d.ts.map +1 -1
  181. package/dist/types/components/data-display/DataViews/data-views-overflow.d.ts.map +1 -1
  182. package/dist/types/components/data-display/MapPreview/MapTiles.d.ts.map +1 -1
  183. package/dist/types/components/data-display/MapPreview/mapProjection.d.ts +6 -1
  184. package/dist/types/components/data-display/MapPreview/mapProjection.d.ts.map +1 -1
  185. package/dist/types/components/data-display/Table/Table.helpers.d.ts +6 -0
  186. package/dist/types/components/data-display/Table/Table.helpers.d.ts.map +1 -1
  187. package/dist/types/components/data-display/Table/Table.hooks.d.ts +9 -1
  188. package/dist/types/components/data-display/Table/Table.hooks.d.ts.map +1 -1
  189. package/dist/types/components/data-display/Table/Table.types.d.ts +6 -2
  190. package/dist/types/components/data-display/Table/Table.types.d.ts.map +1 -1
  191. package/dist/types/components/data-display/Table/TableParts.d.ts +2 -0
  192. package/dist/types/components/data-display/Table/TableParts.d.ts.map +1 -1
  193. package/dist/types/components/form/Calendar/Calendar.d.ts.map +1 -1
  194. package/dist/types/components/form/Calendar/CalendarDay.d.ts.map +1 -1
  195. package/dist/types/components/form/Calendar/CalendarMonth.d.ts.map +1 -1
  196. package/dist/types/components/form/Switch/Switch.metrics.d.ts +13 -3
  197. package/dist/types/components/form/Switch/Switch.metrics.d.ts.map +1 -1
  198. package/dist/types/components/form/Switch/Switch.styles.d.ts.map +1 -1
  199. package/dist/types/components/layout/CardGrid/CardGrid.d.ts +9 -7
  200. package/dist/types/components/layout/CardGrid/CardGrid.d.ts.map +1 -1
  201. package/dist/types/components/layout/Resizable/Resizable.d.ts.map +1 -1
  202. package/dist/types/components/layout/Resizable/Resizable.helpers.d.ts +21 -9
  203. package/dist/types/components/layout/Resizable/Resizable.helpers.d.ts.map +1 -1
  204. package/dist/types/components/layout/Resizable/Resizable.hooks.d.ts +13 -3
  205. package/dist/types/components/layout/Resizable/Resizable.hooks.d.ts.map +1 -1
  206. package/dist/types/components/layout/Resizable/Resizable.types.d.ts +10 -0
  207. package/dist/types/components/layout/Resizable/Resizable.types.d.ts.map +1 -1
  208. package/dist/types/components/layout/ScrollArea/ScrollArea.d.ts.map +1 -1
  209. package/dist/types/components/layout/ScrollArea/ScrollArea.helpers.d.ts +1 -1
  210. package/dist/types/components/layout/ScrollArea/ScrollArea.helpers.d.ts.map +1 -1
  211. package/dist/types/components/layout/ScrollArea/ScrollArea.types.d.ts +4 -1
  212. package/dist/types/components/layout/ScrollArea/ScrollArea.types.d.ts.map +1 -1
  213. package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.d.ts.map +1 -1
  214. package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.hooks.d.ts +3 -2
  215. package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.hooks.d.ts.map +1 -1
  216. package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.parts.d.ts +3 -2
  217. package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.parts.d.ts.map +1 -1
  218. package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.types.d.ts +9 -0
  219. package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.types.d.ts.map +1 -1
  220. package/dist/types/components/utility/VirtualList/VirtualList.d.ts.map +1 -1
  221. package/dist/types/components/utility/VirtualList/VirtualList.hooks.d.ts +24 -28
  222. package/dist/types/components/utility/VirtualList/VirtualList.hooks.d.ts.map +1 -1
  223. package/dist/types/components/utility/VirtualList/VirtualList.types.d.ts +17 -0
  224. package/dist/types/components/utility/VirtualList/VirtualList.types.d.ts.map +1 -1
  225. package/dist/types-native/components/form/Switch/Switch.metrics.d.ts +13 -3
  226. package/dist/types-native/components/form/Switch/Switch.metrics.d.ts.map +1 -1
  227. package/dist/utility/InfiniteScroll.js +4 -3
  228. package/dist/utility/VirtualList.js +3 -2
  229. package/package.json +1 -1
  230. package/src/components/data-display/DataGrid/DataGrid.body.tsx +27 -7
  231. package/src/components/data-display/DataGrid/DataGrid.cells.tsx +33 -9
  232. package/src/components/data-display/DataGrid/DataGrid.model.ts +24 -11
  233. package/src/components/data-display/DataGrid/DataGrid.types.ts +12 -6
  234. package/src/components/data-display/DataViews/data-views-columns.ts +14 -3
  235. package/src/components/data-display/DataViews/data-views-grid-helpers.tsx +5 -3
  236. package/src/components/data-display/DataViews/data-views-layout-context.tsx +12 -9
  237. package/src/components/data-display/DataViews/data-views-overflow-costs.ts +32 -14
  238. package/src/components/data-display/DataViews/data-views-overflow.ts +40 -26
  239. package/src/components/data-display/MapPreview/MapTiles.tsx +16 -9
  240. package/src/components/data-display/MapPreview/mapProjection.ts +10 -5
  241. package/src/components/data-display/Table/Table.helpers.ts +7 -1
  242. package/src/components/data-display/Table/Table.hooks.ts +16 -5
  243. package/src/components/data-display/Table/Table.types.ts +6 -2
  244. package/src/components/data-display/Table/TableParts.tsx +38 -42
  245. package/src/components/form/Calendar/Calendar.tsx +4 -2
  246. package/src/components/form/Calendar/CalendarDay.tsx +6 -3
  247. package/src/components/form/Calendar/CalendarMonth.tsx +6 -3
  248. package/src/components/form/Switch/Switch.metrics.ts +19 -5
  249. package/src/components/form/Switch/Switch.styles.ts +5 -3
  250. package/src/components/layout/CardGrid/CardGrid.tsx +37 -24
  251. package/src/components/layout/Resizable/Resizable.helpers.ts +43 -21
  252. package/src/components/layout/Resizable/Resizable.hooks.ts +17 -9
  253. package/src/components/layout/Resizable/Resizable.md +9 -5
  254. package/src/components/layout/Resizable/Resizable.tsx +20 -8
  255. package/src/components/layout/Resizable/Resizable.types.ts +10 -0
  256. package/src/components/layout/ScrollArea/ScrollArea.helpers.ts +0 -2
  257. package/src/components/layout/ScrollArea/ScrollArea.tsx +5 -3
  258. package/src/components/layout/ScrollArea/ScrollArea.types.ts +4 -1
  259. package/src/components/utility/InfiniteScroll/InfiniteScroll.hooks.ts +5 -4
  260. package/src/components/utility/InfiniteScroll/InfiniteScroll.parts.tsx +29 -12
  261. package/src/components/utility/InfiniteScroll/InfiniteScroll.tsx +11 -5
  262. package/src/components/utility/InfiniteScroll/InfiniteScroll.types.ts +10 -2
  263. package/src/components/utility/VirtualList/VirtualList.hooks.ts +101 -112
  264. package/src/components/utility/VirtualList/VirtualList.tsx +36 -65
  265. package/src/components/utility/VirtualList/VirtualList.types.ts +20 -3
  266. package/dist/chunk-2WFDHFK4.js.map +0 -1
  267. package/dist/chunk-3TDVGZZN.js.map +0 -1
  268. package/dist/chunk-AROBXRC5.js.map +0 -1
  269. package/dist/chunk-ATSHKSSD.js.map +0 -1
  270. package/dist/chunk-AUSUCZYR.js.map +0 -1
  271. package/dist/chunk-C66RGVAS.js.map +0 -1
  272. package/dist/chunk-D5SZXH7Q.js.map +0 -1
  273. package/dist/chunk-DF4K5XVW.js.map +0 -1
  274. package/dist/chunk-DLJGBJZW.js.map +0 -1
  275. package/dist/chunk-DZA7RSLX.js.map +0 -1
  276. package/dist/chunk-F42MJOHM.js.map +0 -1
  277. package/dist/chunk-GSFNH4C5.js.map +0 -1
  278. package/dist/chunk-HGMBY5LP.js.map +0 -1
  279. package/dist/chunk-HTZNB6IV.js.map +0 -1
  280. package/dist/chunk-IAGOUTI6.js.map +0 -1
  281. package/dist/chunk-J2DAQQQH.js.map +0 -1
  282. package/dist/chunk-MTFCPPZ5.js.map +0 -1
  283. package/dist/chunk-P6TNXBDA.js.map +0 -1
  284. package/dist/chunk-PMOEG36E.js.map +0 -1
  285. package/dist/chunk-PPRV4LTM.js.map +0 -1
  286. package/dist/chunk-PUBPZOQJ.js.map +0 -1
  287. package/dist/chunk-QF6LTUCE.js.map +0 -1
  288. package/dist/chunk-RHIDWUK7.js.map +0 -1
  289. package/dist/chunk-TQ6FPOPD.js.map +0 -1
  290. package/dist/chunk-TUBCN4DJ.js.map +0 -1
  291. package/dist/chunk-ULTOQ6ZV.js.map +0 -1
  292. package/dist/chunk-UN5INW6K.js.map +0 -1
  293. package/dist/chunk-YU26GBNX.js.map +0 -1
  294. package/dist/chunk-ZAY6OA6F.js.map +0 -1
  295. /package/dist/{chunk-MR2HKBHS.js.map → chunk-27LOJVR3.js.map} +0 -0
  296. /package/dist/{chunk-S3D5VBHW.js.map → chunk-3YOXVNO4.js.map} +0 -0
  297. /package/dist/{chunk-CZIX4BW2.js.map → chunk-4ALF5PB5.js.map} +0 -0
  298. /package/dist/{chunk-XJPJ6ESI.js.map → chunk-4OAKGKK5.js.map} +0 -0
  299. /package/dist/{chunk-4CHROSWR.js.map → chunk-5ETBB2DG.js.map} +0 -0
  300. /package/dist/{chunk-46UPILLK.js.map → chunk-5NT2M2JI.js.map} +0 -0
  301. /package/dist/{chunk-H5BEWPEY.js.map → chunk-6N2EDWMG.js.map} +0 -0
  302. /package/dist/{chunk-GJQYM3PM.js.map → chunk-6PU3JYVY.js.map} +0 -0
  303. /package/dist/{chunk-Y7F5JBAT.js.map → chunk-DDRKYNPB.js.map} +0 -0
  304. /package/dist/{chunk-OS6KPL4D.js.map → chunk-EHYI2WCJ.js.map} +0 -0
  305. /package/dist/{chunk-NB3FGWU4.js.map → chunk-EQXIW5MQ.js.map} +0 -0
  306. /package/dist/{chunk-M2JTIH5M.js.map → chunk-F44R7US6.js.map} +0 -0
  307. /package/dist/{chunk-XJJXBUPN.js.map → chunk-FX26DAFF.js.map} +0 -0
  308. /package/dist/{chunk-R6SN73RX.js.map → chunk-GLHNMTP6.js.map} +0 -0
  309. /package/dist/{chunk-I4QA2F4L.js.map → chunk-HBRQPG7H.js.map} +0 -0
  310. /package/dist/{chunk-CNQUCNEA.js.map → chunk-I3F4C5SS.js.map} +0 -0
  311. /package/dist/{chunk-UFJYJHQI.js.map → chunk-J5VWGQSR.js.map} +0 -0
  312. /package/dist/{chunk-4JFL62K3.js.map → chunk-K7FSTB2K.js.map} +0 -0
  313. /package/dist/{chunk-FFCJ7NR2.js.map → chunk-KRQUPE4K.js.map} +0 -0
  314. /package/dist/{chunk-2OYFTSG4.js.map → chunk-KXLUMEDX.js.map} +0 -0
  315. /package/dist/{chunk-DVAAUWTC.js.map → chunk-LCHCE2G5.js.map} +0 -0
  316. /package/dist/{chunk-G4HBNILE.js.map → chunk-LEHMWJNZ.js.map} +0 -0
  317. /package/dist/{chunk-RZYSKQTS.js.map → chunk-PCBZYORN.js.map} +0 -0
  318. /package/dist/{chunk-5OBXEMQO.js.map → chunk-PRIBOWX4.js.map} +0 -0
  319. /package/dist/{chunk-PQECNGDE.js.map → chunk-QSRZOXQI.js.map} +0 -0
  320. /package/dist/{chunk-DCJSHYE5.js.map → chunk-RSDYS5B3.js.map} +0 -0
  321. /package/dist/{chunk-N5GVW6RO.js.map → chunk-S6IWKDWT.js.map} +0 -0
  322. /package/dist/{chunk-TKC6WHGB.js.map → chunk-SBIZXZPP.js.map} +0 -0
  323. /package/dist/{chunk-UEVHI62V.js.map → chunk-YCCY77W5.js.map} +0 -0
  324. /package/dist/{chunk-VZIB5W5L.js.map → chunk-ZGCPDA3F.js.map} +0 -0
@@ -1,18 +1,21 @@
1
- import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
1
+ import { useTheme, type Theme } from '@mui/material/styles/index.js';
2
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
3
+
4
+ import { rem, remPx } from '../../../tokens/relative';
2
5
 
3
6
  import type { VirtualGridProps, VirtualListProps } from './VirtualList.types';
4
7
 
5
8
  type ScrollEvent = React.UIEvent<HTMLDivElement> | Event;
6
9
  type ListItems = VirtualListProps['items'];
7
10
  type ListVariant = NonNullable<VirtualListProps['variant']>;
8
- type ItemHeight = (index: number) => number;
11
+ type ItemSize = (index: number) => number;
9
12
 
10
13
  // Handles both React synthetic events and native DOM events, since the same
11
14
  // handler serves an internal onScroll and an external container's listener.
12
15
  const scrollOffsets = (event: ScrollEvent) => {
13
16
  const target = (event as React.UIEvent<HTMLDivElement>).currentTarget || (event as Event).target;
14
17
  const element = target as HTMLElement;
15
- return { top: element.scrollTop, left: element.scrollLeft };
18
+ return { scrollTop: element.scrollTop, scrollLeft: element.scrollLeft };
16
19
  };
17
20
 
18
21
  /**
@@ -47,7 +50,7 @@ const useScrollTop = (
47
50
 
48
51
  const handleScroll = useCallback(
49
52
  (event: ScrollEvent) => {
50
- const { top, left } = scrollOffsets(event);
53
+ const { scrollTop: top, scrollLeft: left } = scrollOffsets(event);
51
54
  setScrollTop(top);
52
55
  report(top, left);
53
56
  },
@@ -59,63 +62,60 @@ const useScrollTop = (
59
62
  return { scrollTop, handleScroll };
60
63
  };
61
64
 
62
- interface HeightArgs {
63
- items: ListItems;
64
- variant: ListVariant;
65
- itemHeight: number;
66
- estimatedItemHeight: number;
67
- }
68
65
 
69
66
  /**
70
- * Fixed lists know every height up front. Variable ones prefer the item's own
71
- * declared height, fall back to a measurement taken on a previous render, and
72
- * only then guess.
67
+ * A `width` prop as CSS. `sx` reads a number of 1 or less as a fraction of the
68
+ * parent, and that stays so; a larger number is design px, through the type
69
+ * scale; a string is as given.
73
70
  */
74
- const useItemHeight = ({
75
- items,
76
- variant,
77
- itemHeight,
78
- estimatedItemHeight,
79
- }: HeightArgs): ItemHeight => {
80
- const measured = useRef<Map<number, number>>(new Map());
81
-
82
- return useCallback(
83
- (index: number): number => {
84
- if (variant !== 'variable') {
85
- return itemHeight;
86
- }
87
-
88
- return items[index]?.height || measured.current.get(index) || estimatedItemHeight;
89
- },
90
- [variant, itemHeight, estimatedItemHeight, items],
91
- );
71
+ export const widthCss = (theme: Theme, width: number | string): string => {
72
+ if (typeof width !== 'number') return width;
73
+ return width <= 1 && width !== 0 ? `${width * 100}%` : rem(theme, width);
92
74
  };
93
75
 
94
- const useTotalHeight = (
76
+ /** Every item's height, its offset from the top, and their sum — all in DESIGN px. */
77
+ interface DesignHeights {
78
+ size: ItemSize;
79
+ offset: ItemSize;
80
+ total: number;
81
+ }
82
+
83
+ /**
84
+ * Fixed lists know every height up front; variable ones take the item's own
85
+ * declared height and otherwise the estimate.
86
+ *
87
+ * Kept in the caller's DESIGN px on purpose: the CSS draws a height with `rem`
88
+ * and the range maths reads it through `remPx`, so the two are one number at
89
+ * any type scale — never a row drawn at one pitch and positioned at another.
90
+ */
91
+ const useDesignHeights = (
95
92
  items: ListItems,
96
93
  variant: ListVariant,
97
- itemHeight: number,
98
- getItemHeight: ItemHeight,
99
- ) =>
94
+ fixed: number,
95
+ estimated: number,
96
+ ): DesignHeights =>
100
97
  useMemo(() => {
101
- if (variant === 'fixed') {
102
- return items.length * itemHeight;
98
+ if (variant !== 'variable') {
99
+ return { size: () => fixed, offset: (index) => index * fixed, total: items.length * fixed };
103
100
  }
104
101
 
105
- let sum = 0;
102
+ const size = (index: number): number => items[index]?.height || estimated;
103
+ // Running sums, so an offset is a lookup rather than a walk from the top.
104
+ const starts = [0];
106
105
  for (let i = 0; i < items.length; i++) {
107
- sum += getItemHeight(i);
106
+ starts.push((starts[i] ?? 0) + size(i));
108
107
  }
109
- return sum;
110
- }, [items.length, variant, itemHeight, getItemHeight]);
108
+ return { size, offset: (index) => starts[index] ?? 0, total: starts[items.length] ?? 0 };
109
+ }, [items, variant, fixed, estimated]);
111
110
 
111
+ /** The range maths' inputs, in the px the scroll offset is measured in. */
112
112
  interface RangeArgs {
113
113
  count: number;
114
114
  scrollTop: number;
115
115
  height: number;
116
116
  overscan: number;
117
117
  itemHeight: number;
118
- getItemHeight: ItemHeight;
118
+ getItemHeight: ItemSize;
119
119
  }
120
120
 
121
121
  // Walks forward accumulating heights until it passes the viewport's top edge, then
@@ -155,56 +155,38 @@ const fixedRange = ({ count, scrollTop, height, overscan, itemHeight }: RangeArg
155
155
  endIndex: Math.min(count - 1, Math.ceil((scrollTop + height) / itemHeight) + overscan),
156
156
  });
157
157
 
158
- const useItemOffset = (
159
- variant: ListVariant,
160
- itemHeight: number,
161
- getItemHeight: ItemHeight,
162
- ): ItemHeight =>
163
- useCallback(
164
- (index: number): number => {
165
- if (variant === 'fixed') {
166
- return index * itemHeight;
167
- }
168
-
169
- let offset = 0;
170
- for (let i = 0; i < index; i++) {
171
- offset += getItemHeight(i);
172
- }
173
- return offset;
174
- },
175
- [variant, itemHeight, getItemHeight],
176
- );
177
-
178
- interface ListArgs {
179
- items: ListItems;
180
- variant: ListVariant;
181
- height: number;
182
- itemHeight: number;
183
- estimatedItemHeight: number;
184
- overscan: number;
185
- onScroll: VirtualListProps['onScroll'];
186
- scrollContainerRef: VirtualListProps['scrollContainerRef'];
187
- }
188
-
158
+ /**
159
+ * `height`, `itemHeight`, `estimatedItemHeight` and an item's own `height` are
160
+ * design px. The range is computed in the px `scrollTop` is measured in
161
+ * (`remPx`), the viewport and the scroll content are drawn in `rem`, and each
162
+ * item's `top`/`height` is the `remPx` of its design offset and height.
163
+ */
189
164
  export const useVirtualList = ({
190
165
  items,
191
- variant,
166
+ variant = 'fixed',
192
167
  height,
193
168
  itemHeight,
194
169
  estimatedItemHeight,
195
- overscan,
170
+ overscan = 5,
196
171
  onScroll,
197
172
  scrollContainerRef,
198
- }: ListArgs) => {
199
- const getItemHeight = useItemHeight({ items, variant, itemHeight, estimatedItemHeight });
200
- const getItemOffset = useItemOffset(variant, itemHeight, getItemHeight);
201
- const totalHeight = useTotalHeight(items, variant, itemHeight, getItemHeight);
173
+ }: VirtualListProps) => {
174
+ const theme = useTheme();
175
+ // 40 design px when the caller does not size a row.
176
+ const design = useDesignHeights(items, variant, itemHeight ?? 40, estimatedItemHeight ?? 40);
202
177
 
203
178
  const report = useCallback((top: number) => onScroll?.(top), [onScroll]);
204
179
  const { scrollTop, handleScroll } = useScrollTop(scrollContainerRef, report);
205
180
 
206
181
  const visibleItems = useMemo(() => {
207
- const args = { count: items.length, scrollTop, height, overscan, itemHeight, getItemHeight };
182
+ const args = {
183
+ count: items.length,
184
+ scrollTop,
185
+ height: remPx(theme, height),
186
+ overscan,
187
+ itemHeight: remPx(theme, design.size(0)),
188
+ getItemHeight: (index: number) => remPx(theme, design.size(index)),
189
+ };
208
190
  const { startIndex, endIndex } = variant === 'fixed' ? fixedRange(args) : variableRange(args);
209
191
  const result = [];
210
192
 
@@ -217,33 +199,26 @@ export const useVirtualList = ({
217
199
  index: i,
218
200
  style: {
219
201
  position: 'absolute' as const,
220
- top: getItemOffset(i),
202
+ top: remPx(theme, design.offset(i)),
221
203
  left: 0,
222
204
  width: '100%',
223
- height: getItemHeight(i),
205
+ height: remPx(theme, design.size(i)),
224
206
  },
225
207
  });
226
208
  }
227
209
 
228
210
  return result;
229
- }, [items, scrollTop, height, overscan, variant, itemHeight, getItemOffset, getItemHeight]);
230
-
231
- return { totalHeight, visibleItems, handleScroll };
211
+ }, [items, scrollTop, height, overscan, variant, design, theme]);
212
+
213
+ return {
214
+ totalHeight: rem(theme, design.total),
215
+ viewportHeight: rem(theme, height),
216
+ visibleItems,
217
+ handleScroll,
218
+ };
232
219
  };
233
220
 
234
- interface GridArgs {
235
- items: VirtualGridProps['items'];
236
- height: number;
237
- width: number | string;
238
- columnCount: number;
239
- rowHeight: number;
240
- columnWidth?: number;
241
- gap: number;
242
- overscan: number;
243
- onScroll: VirtualGridProps['onScroll'];
244
- scrollContainerRef: VirtualGridProps['scrollContainerRef'];
245
- }
246
-
221
+ /** The column width in DESIGN px: the caller's, or an even share of a numeric width. */
247
222
  const useColumnWidth = (
248
223
  columnWidth: number | undefined,
249
224
  width: number | string,
@@ -257,21 +232,26 @@ const useColumnWidth = (
257
232
  return (containerWidth - (columnCount - 1) * gap) / columnCount;
258
233
  }, [columnWidth, width, columnCount, gap]);
259
234
 
235
+ /**
236
+ * `height`, `rowHeight`, `columnWidth` and `gap` are design px: the range and
237
+ * every cell's box are computed through `remPx`, the viewport and the content
238
+ * are drawn through `rem`.
239
+ */
260
240
  export const useVirtualGrid = ({
261
241
  items,
262
242
  height,
263
- width,
243
+ width = '100%',
264
244
  columnCount,
265
245
  rowHeight,
266
246
  columnWidth,
267
- gap,
268
- overscan,
247
+ gap = 0,
248
+ overscan = 5,
269
249
  onScroll,
270
250
  scrollContainerRef,
271
- }: GridArgs) => {
251
+ }: VirtualGridProps) => {
252
+ const theme = useTheme();
272
253
  const rowCount = Math.ceil(items.length / columnCount);
273
- const totalHeight = rowCount * (rowHeight + gap) - gap;
274
- const computedColumnWidth = useColumnWidth(columnWidth, width, columnCount, gap);
254
+ const designColumn = useColumnWidth(columnWidth, width, columnCount, gap);
275
255
 
276
256
  const report = useCallback(
277
257
  (top: number, left: number) => onScroll?.(top, left),
@@ -280,9 +260,13 @@ export const useVirtualGrid = ({
280
260
  const { scrollTop, handleScroll } = useScrollTop(scrollContainerRef, report);
281
261
 
282
262
  const visibleItems = useMemo(() => {
283
- const pitch = rowHeight + gap;
263
+ const pitch = remPx(theme, rowHeight + gap);
264
+ const stride = remPx(theme, designColumn + gap);
284
265
  const startRow = Math.max(0, Math.floor(scrollTop / pitch) - overscan);
285
- const endRow = Math.min(rowCount - 1, Math.ceil((scrollTop + height) / pitch) + overscan);
266
+ const endRow = Math.min(
267
+ rowCount - 1,
268
+ Math.ceil((scrollTop + remPx(theme, height)) / pitch) + overscan,
269
+ );
286
270
 
287
271
  // Rows are contiguous in `items`, so the visible block is one index range
288
272
  // rather than a row loop wrapping a column loop.
@@ -305,15 +289,20 @@ export const useVirtualGrid = ({
305
289
  style: {
306
290
  position: 'absolute' as const,
307
291
  top: rowIndex * pitch,
308
- left: columnIndex * (computedColumnWidth + gap),
309
- width: computedColumnWidth,
310
- height: rowHeight,
292
+ left: columnIndex * stride,
293
+ width: remPx(theme, designColumn),
294
+ height: remPx(theme, rowHeight),
311
295
  },
312
296
  });
313
297
  }
314
298
 
315
299
  return result;
316
- }, [items, scrollTop, height, overscan, rowCount, columnCount, rowHeight, gap, computedColumnWidth]);
317
-
318
- return { totalHeight, visibleItems, handleScroll };
300
+ }, [items, scrollTop, height, overscan, rowCount, columnCount, rowHeight, gap, designColumn, theme]);
301
+
302
+ return {
303
+ totalHeight: rem(theme, rowCount * (rowHeight + gap) - gap),
304
+ viewportHeight: rem(theme, height),
305
+ visibleItems,
306
+ handleScroll,
307
+ };
319
308
  };
@@ -1,15 +1,19 @@
1
1
  import Box from '@mui/material/Box/index.js';
2
+ import { useTheme } from '@mui/material/styles/index.js';
2
3
  import React, { useRef } from 'react';
3
4
 
4
- import { useVirtualGrid, useVirtualList } from './VirtualList.hooks';
5
+ import { useVirtualGrid, useVirtualList, widthCss } from './VirtualList.hooks';
5
6
  import type { VirtualGridProps, VirtualListProps } from './VirtualList.types';
6
7
 
7
8
  interface ContainerProps {
8
9
  children: React.ReactNode;
9
10
  role: 'list' | 'grid';
10
- totalHeight: number;
11
- height: number;
12
- width: number | string;
11
+ /** The scroll content's height, as CSS. */
12
+ totalHeight: string;
13
+ /** The viewport's height, as CSS. */
14
+ height: string;
15
+ /** The viewport's width, as CSS. */
16
+ width: string;
13
17
  disableInternalScroll: boolean;
14
18
  onScroll: (event: React.UIEvent<HTMLDivElement>) => void;
15
19
  className?: string;
@@ -64,40 +68,25 @@ const VirtualContainer: React.FC<ContainerProps> = ({
64
68
  );
65
69
  };
66
70
 
67
- export const VirtualList: React.FC<VirtualListProps> = ({
68
- items,
69
- variant = 'fixed',
70
- height,
71
- width = '100%',
72
- itemHeight = 40,
73
- estimatedItemHeight = 40,
74
- overscan = 5,
75
- renderItem,
76
- onScroll,
77
- className,
78
- style,
79
- 'data-testid': dataTestId,
80
- 'aria-label': ariaLabel,
81
- scrollContainerRef,
82
- disableInternalScroll = false,
83
- }) => {
84
- const { totalHeight, visibleItems, handleScroll } = useVirtualList({
85
- items,
86
- variant,
87
- height,
88
- itemHeight,
89
- estimatedItemHeight,
90
- overscan,
91
- onScroll,
92
- scrollContainerRef,
93
- });
71
+ export const VirtualList: React.FC<VirtualListProps> = (props) => {
72
+ const {
73
+ width = '100%',
74
+ renderItem,
75
+ className,
76
+ style,
77
+ 'data-testid': dataTestId,
78
+ 'aria-label': ariaLabel,
79
+ disableInternalScroll = false,
80
+ } = props;
81
+ const theme = useTheme();
82
+ const { totalHeight, viewportHeight, visibleItems, handleScroll } = useVirtualList(props);
94
83
 
95
84
  return (
96
85
  <VirtualContainer
97
86
  role="list"
98
87
  totalHeight={totalHeight}
99
- height={height}
100
- width={width}
88
+ height={viewportHeight}
89
+ width={widthCss(theme, width)}
101
90
  disableInternalScroll={disableInternalScroll}
102
91
  onScroll={handleScroll}
103
92
  className={className}
@@ -112,43 +101,25 @@ export const VirtualList: React.FC<VirtualListProps> = ({
112
101
  );
113
102
  };
114
103
 
115
- export const VirtualGrid: React.FC<VirtualGridProps> = ({
116
- items,
117
- height,
118
- width = '100%',
119
- columnCount,
120
- rowHeight,
121
- columnWidth,
122
- gap = 0,
123
- overscan = 5,
124
- renderItem,
125
- onScroll,
126
- className,
127
- style,
128
- 'data-testid': dataTestId,
129
- 'aria-label': ariaLabel,
130
- scrollContainerRef,
131
- disableInternalScroll = false,
132
- }) => {
133
- const { totalHeight, visibleItems, handleScroll } = useVirtualGrid({
134
- items,
135
- height,
136
- width,
137
- columnCount,
138
- rowHeight,
139
- columnWidth,
140
- gap,
141
- overscan,
142
- onScroll,
143
- scrollContainerRef,
144
- });
104
+ export const VirtualGrid: React.FC<VirtualGridProps> = (props) => {
105
+ const {
106
+ width = '100%',
107
+ renderItem,
108
+ className,
109
+ style,
110
+ 'data-testid': dataTestId,
111
+ 'aria-label': ariaLabel,
112
+ disableInternalScroll = false,
113
+ } = props;
114
+ const theme = useTheme();
115
+ const { totalHeight, viewportHeight, visibleItems, handleScroll } = useVirtualGrid(props);
145
116
 
146
117
  return (
147
118
  <VirtualContainer
148
119
  role="grid"
149
120
  totalHeight={totalHeight}
150
- height={height}
151
- width={width}
121
+ height={viewportHeight}
122
+ width={widthCss(theme, width)}
152
123
  disableInternalScroll={disableInternalScroll}
153
124
  onScroll={handleScroll}
154
125
  className={className}
@@ -4,17 +4,25 @@ export type VirtualListVariant = 'fixed' | 'variable' | 'grid';
4
4
 
5
5
  export interface VirtualListItem {
6
6
  id: string | number;
7
- height?: number; // For variable height items
7
+ /** This item's own height, for a `variable` list — design px, scaled with the theme's type scale. */
8
+ height?: number;
8
9
  data?: unknown;
9
10
  }
10
11
 
11
12
  export interface VirtualListProps {
12
13
  items: VirtualListItem[];
13
14
  variant?: VirtualListVariant;
15
+ /** The viewport's height — design px, scaled with the theme's type scale. */
14
16
  height: number;
17
+ /**
18
+ * The viewport's width. A number of 1 or less is a fraction of the parent (as
19
+ * in `sx`); a larger number is design px, scaled with the theme's type scale; a string is used as given.
20
+ */
15
21
  width?: number | string;
16
- itemHeight?: number; // For fixed height items
17
- estimatedItemHeight?: number; // For variable height items
22
+ /** Every row's height in a `fixed` list (default 40) — design px, scaled with the theme's type scale. */
23
+ itemHeight?: number;
24
+ /** The height assumed for a `variable` item that declares none (default 40) — design px, scaled with the theme's type scale. */
25
+ estimatedItemHeight?: number;
18
26
  overscan?: number; // Number of items to render outside visible area
19
27
  renderItem: (params: { item: VirtualListItem; index: number; style: CSSProperties }) => ReactNode;
20
28
  onScroll?: (scrollTop: number) => void;
@@ -30,11 +38,20 @@ export interface VirtualListProps {
30
38
 
31
39
  export interface VirtualGridProps {
32
40
  items: VirtualListItem[];
41
+ /** The viewport's height — design px, scaled with the theme's type scale. */
33
42
  height: number;
43
+ /**
44
+ * The viewport's width. A number of 1 or less is a fraction of the parent (as
45
+ * in `sx`); a larger number is design px, scaled with the theme's type scale, and also what an unset
46
+ * `columnWidth` is shared out of; a string is used as given.
47
+ */
34
48
  width?: number | string;
35
49
  columnCount: number;
50
+ /** Every row's height — design px, scaled with the theme's type scale. */
36
51
  rowHeight: number;
52
+ /** Every column's width — design px, scaled with the theme's type scale. */
37
53
  columnWidth?: number;
54
+ /** The space between two rows and between two columns — design px, scaled with the theme's type scale. */
38
55
  gap?: number;
39
56
  overscan?: number;
40
57
  renderItem: (params: {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/layout/CardGrid/CardGrid.tsx"],"sourcesContent":["import { Children, type CSSProperties, type ReactNode, type Ref } from \"react\";\n\nimport { cn } from \"../../../utils/cn\";\n\n/**\n * How the grid turns surplus row space into layout:\n *\n * - `\"fixed\"` — every column is exactly `cardWidth` px; leftover row space is\n * spread as even gutters (`justify-content: space-around`). Cards never resize;\n * the column count changes with the viewport. This is the original tabwoah\n * card-grid behavior.\n * - `\"fluid\"` — every column is *at least* `cardWidth` px and stretches (`1fr`)\n * to fill the row, so cards grow to use the whole width. A lone card stays\n * left-aligned at a single track's width rather than stretching edge to edge.\n * - `\"scroll\"` — a single row that scrolls horizontally, with fluid-width cards\n * sized from the container so that exactly {@link SCROLL_VISIBLE_CARDS} cards\n * plus a {@link SCROLL_PEEK_WIDTH}px sliver of the next one fit on screen (up\n * to `maxCardWidth`, past which more cards simply fit). The sliver is the\n * point: it makes the rail visibly continue past the fold, so the row reads as\n * swipeable instead of as a finished pair of cards. Wrapping is off; the row\n * overflows on the x and scroll-snaps to each card's start so a swipe lands on\n * a clean card boundary.\n */\nexport type CardGridVariant = \"fixed\" | \"fluid\" | \"scroll\";\n\n/** The grid gap, in px — mirrors the `gap: 1rem` below, for the scroll math. */\nconst GRID_GAP = 16;\n\n/** `scroll`: how many WHOLE cards the rail commits to showing at once. */\nconst SCROLL_VISIBLE_CARDS = 2;\n\n/**\n * `scroll`: px of the next card left visible past the last whole one — the\n * \"there's more, swipe\" hint. Wide enough to read as a clipped card (rounded\n * edge + a slice of its photo) rather than as a rendering glitch.\n */\nconst SCROLL_PEEK_WIDTH = 28;\n\n/**\n * The `scroll` track width: the widest a card can be while the container still\n * shows `SCROLL_VISIBLE_CARDS` of them plus the peek — or, when there is nothing\n * to scroll to, while the cards still divide the row evenly. Capped at `max` so\n * a desktop-width rail packs in more cards instead of inflating them.\n *\n * The container (`100%`) has to cover, in the overflow case: N cards, the N gaps\n * that follow them (one between each pair, one before the peeked card), and the\n * peek. With no overflow there are only N-1 gaps and no peek.\n */\nfunction scrollTrackWidth(count: number, max: number): string {\n const tracks = Math.max(1, Math.min(count, SCROLL_VISIBLE_CARDS));\n const overflows = count > tracks;\n const gaps = overflows ? tracks : tracks - 1;\n const reserved = gaps * GRID_GAP + (overflows ? SCROLL_PEEK_WIDTH : 0);\n return `min(${max}px, calc((100% - ${reserved}px) / ${tracks}))`;\n}\n\ninterface CardGridProps {\n /**\n * `\"fixed\"`: the exact column width in px. `\"fluid\"`: the minimum column width\n * (columns grow from here). `\"scroll\"`: only seeds the default `maxCardWidth`\n * — a scroll track has no minimum, because a minimum is exactly what would\n * break the \"two cards plus a peek\" promise on a narrow phone.\n */\n cardWidth: number;\n /**\n * `\"scroll\"` only: the maximum fluid card width in px. Defaults to\n * `1.6 × cardWidth`.\n */\n maxCardWidth?: number;\n /** Layout behavior — see {@link CardGridVariant}. Defaults to `\"fixed\"`. */\n variant?: CardGridVariant;\n /** Additional classes appended to the default grid container */\n className?: string;\n /** `data-testid` for the grid container */\n gridTestId?: string;\n /** Ref forwarded to the grid container (used by `useMaxRowsHeight` clipping). */\n containerRef?: Ref<HTMLDivElement>;\n children: ReactNode;\n}\n\n/**\n * Shared grid container for card layouts. Renders responsive columns via CSS\n * grid, in one of three variants (see {@link CardGridVariant}).\n *\n * Ported from the tabwoah card grid (the `\"fixed\"` variant is verbatim). The one\n * adaptation: that app is Tailwind (`className=\"grid gap-4 pb-0.5\"`); this one\n * has no Tailwind, so those three utilities (display:grid, gap 1rem,\n * padding-bottom 2px) live in `style`.\n */\nexport function CardGrid({\n cardWidth,\n maxCardWidth,\n variant = \"fixed\",\n className,\n gridTestId,\n containerRef,\n children,\n}: CardGridProps) {\n const style: CSSProperties = {\n display: \"grid\",\n gap: \"1rem\",\n paddingBottom: \"2px\",\n };\n\n if (variant === \"scroll\") {\n const max = maxCardWidth ?? Math.round(cardWidth * 1.6);\n // One row, laid out as implicit columns, that scrolls sideways. Each column\n // is derived from the container so two whole cards plus a peek of the third\n // always fit (see `scrollTrackWidth`). Scroll-snap makes a swipe settle on a\n // card boundary instead of drifting mid-card.\n style.gridAutoFlow = \"column\";\n style.gridAutoColumns = scrollTrackWidth(Children.count(children), max);\n style.overflowX = \"auto\";\n style.overflowY = \"hidden\";\n style.scrollSnapType = \"x mandatory\";\n } else if (variant === \"fluid\") {\n style.gridTemplateColumns = `repeat(auto-fill, minmax(${cardWidth}px, 1fr))`;\n } else {\n style.gridTemplateColumns = `repeat(auto-fill, ${cardWidth}px)`;\n // `space-around` only distributes leftover width in the fixed variant; the\n // fluid variant consumes it via `1fr` and scroll overflows instead.\n style.justifyContent = \"space-around\";\n }\n\n // In the scroll variant each card is a snap target, so a swipe aligns to its\n // start. The snap-align sits on a wrapper (the grid item) so callers' children\n // stay untouched; the other variants render children directly.\n const content =\n variant === \"scroll\"\n ? Children.map(children, (child) => (\n <div style={{ scrollSnapAlign: \"start\" }}>{child}</div>\n ))\n : children;\n\n return (\n <div ref={containerRef} className={cn(className)} style={style} data-testid={gridTestId}>\n {content}\n </div>\n );\n}\n"],"mappings":";;;;;AAAA,SAAS,gBAA8D;AAkI7D;AAxGV,IAAM,WAAW;AAGjB,IAAM,uBAAuB;AAO7B,IAAM,oBAAoB;AAY1B,SAAS,iBAAiB,OAAe,KAAqB;AAC5D,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,oBAAoB,CAAC;AAChE,QAAM,YAAY,QAAQ;AAC1B,QAAM,OAAO,YAAY,SAAS,SAAS;AAC3C,QAAM,WAAW,OAAO,YAAY,YAAY,oBAAoB;AACpE,SAAO,OAAO,GAAG,oBAAoB,QAAQ,SAAS,MAAM;AAC9D;AAmCO,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAkB;AAChB,QAAM,QAAuB;AAAA,IAC3B,SAAS;AAAA,IACT,KAAK;AAAA,IACL,eAAe;AAAA,EACjB;AAEA,MAAI,YAAY,UAAU;AACxB,UAAM,MAAM,gBAAgB,KAAK,MAAM,YAAY,GAAG;AAKtD,UAAM,eAAe;AACrB,UAAM,kBAAkB,iBAAiB,SAAS,MAAM,QAAQ,GAAG,GAAG;AACtE,UAAM,YAAY;AAClB,UAAM,YAAY;AAClB,UAAM,iBAAiB;AAAA,EACzB,WAAW,YAAY,SAAS;AAC9B,UAAM,sBAAsB,4BAA4B,SAAS;AAAA,EACnE,OAAO;AACL,UAAM,sBAAsB,qBAAqB,SAAS;AAG1D,UAAM,iBAAiB;AAAA,EACzB;AAKA,QAAM,UACJ,YAAY,WACR,SAAS,IAAI,UAAU,CAAC,UACtB,oBAAC,SAAI,OAAO,EAAE,iBAAiB,QAAQ,GAAI,iBAAM,CAClD,IACD;AAEN,SACE,oBAAC,SAAI,KAAK,cAAc,WAAW,GAAG,SAAS,GAAG,OAAc,eAAa,YAC1E,mBACH;AAEJ;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/layout/Resizable/Resizable.helpers.ts"],"sourcesContent":["import type { Theme } from '@mui/material/styles/index.js';\n\nimport type { ResizableProps, ResizableVariant, ResizeHandle } from './Resizable.types';\n\nexport interface Axis {\n min: number;\n max: number;\n}\n\nexport interface Bounds {\n width: Axis;\n height: Axis;\n}\n\nexport const defaultHandles = (variant: ResizableVariant): ResizeHandle[] => {\n switch (variant) {\n case 'horizontal':\n return ['right'];\n case 'vertical':\n return ['bottom'];\n default:\n return ['right', 'bottom', 'bottomRight'];\n }\n};\n\nconst HORIZONTAL_GROW: readonly ResizeHandle[] = ['right', 'topRight', 'bottomRight'];\nconst HORIZONTAL_SHRINK: readonly ResizeHandle[] = ['left', 'topLeft', 'bottomLeft'];\nconst VERTICAL_GROW: readonly ResizeHandle[] = ['bottom', 'bottomLeft', 'bottomRight'];\nconst VERTICAL_SHRINK: readonly ResizeHandle[] = ['top', 'topLeft', 'topRight'];\n\nconst clamp = (value: number, { min, max }: Axis): number =>\n Math.max(min, Math.min(max, value));\n\n/**\n * A handle on the right or bottom edge grows the box by the drag distance; one on\n * the left or top shrinks it by the same amount, because the opposite edge is\n * what stays put. A handle on neither edge of this axis leaves it alone.\n */\nconst alongAxis = (\n handle: ResizeHandle,\n grow: readonly ResizeHandle[],\n shrink: readonly ResizeHandle[],\n start: number,\n delta: number,\n bounds: Axis,\n): number => {\n if (grow.includes(handle)) return clamp(start + delta, bounds);\n if (shrink.includes(handle)) return clamp(start - delta, bounds);\n return start;\n};\n\nexport const resizedTo = (\n handle: ResizeHandle,\n delta: { x: number; y: number },\n start: { width: number; height: number },\n bounds: Bounds,\n) => ({\n width: alongAxis(handle, HORIZONTAL_GROW, HORIZONTAL_SHRINK, start.width, delta.x, bounds.width),\n height: alongAxis(\n handle,\n VERTICAL_GROW,\n VERTICAL_SHRINK,\n start.height,\n delta.y,\n bounds.height,\n ),\n});\n\nexport const handleStyle = (theme: Theme, handle: ResizeHandle, active: boolean) => {\n const baseStyle = {\n position: 'absolute' as const,\n backgroundColor: theme.palette.primary.main,\n opacity: 0,\n transition: theme.transitions.create('opacity'),\n '&:hover': {\n opacity: 0.3,\n },\n ...(active ? { opacity: 0.5 } : {}),\n };\n\n switch (handle) {\n case 'right':\n return { ...baseStyle, top: 0, right: -2, width: 4, height: '100%', cursor: 'ew-resize' };\n case 'bottom':\n return { ...baseStyle, bottom: -2, left: 0, width: '100%', height: 4, cursor: 'ns-resize' };\n case 'bottomRight':\n return {\n ...baseStyle,\n bottom: -2,\n right: -2,\n width: 8,\n height: 8,\n cursor: 'nw-resize',\n borderRadius: '50%',\n };\n default:\n return baseStyle;\n }\n};\n\ntype ResizableDefaultedKeys =\n | 'variant'\n | 'width'\n | 'height'\n | 'minWidth'\n | 'maxWidth'\n | 'minHeight'\n | 'maxHeight'\n | 'disabled';\n\ntype ResolvedResizableProps = ResizableProps &\n Required<Pick<ResizableProps, ResizableDefaultedKeys>>;\n\nconst RESIZABLE_DEFAULTS: Pick<ResizableProps, ResizableDefaultedKeys> = {\n variant: 'both',\n width: 200,\n height: 200,\n minWidth: 50,\n maxWidth: 1000,\n minHeight: 50,\n maxHeight: 1000,\n disabled: false,\n};\n\n// Strips explicitly-undefined props before the merge, so `minWidth={undefined}`\n// still falls back to the default exactly as a destructuring default would.\nconst definedProps = (props: ResizableProps): Partial<ResizableProps> =>\n Object.fromEntries(\n Object.entries(props).filter(([, value]) => value !== undefined),\n ) as Partial<ResizableProps>;\n\nexport const resolveResizableProps = (props: ResizableProps): ResolvedResizableProps =>\n ({ ...RESIZABLE_DEFAULTS, ...definedProps(props) }) as ResolvedResizableProps;\n"],"mappings":";AAcO,IAAM,iBAAiB,CAAC,YAA8C;AAC3E,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO,CAAC,OAAO;AAAA,IACjB,KAAK;AACH,aAAO,CAAC,QAAQ;AAAA,IAClB;AACE,aAAO,CAAC,SAAS,UAAU,aAAa;AAAA,EAC5C;AACF;AAEA,IAAM,kBAA2C,CAAC,SAAS,YAAY,aAAa;AACpF,IAAM,oBAA6C,CAAC,QAAQ,WAAW,YAAY;AACnF,IAAM,gBAAyC,CAAC,UAAU,cAAc,aAAa;AACrF,IAAM,kBAA2C,CAAC,OAAO,WAAW,UAAU;AAE9E,IAAM,QAAQ,CAAC,OAAe,EAAE,KAAK,IAAI,MACvC,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,CAAC;AAOpC,IAAM,YAAY,CAChB,QACA,MACA,QACA,OACA,OACA,WACW;AACX,MAAI,KAAK,SAAS,MAAM,EAAG,QAAO,MAAM,QAAQ,OAAO,MAAM;AAC7D,MAAI,OAAO,SAAS,MAAM,EAAG,QAAO,MAAM,QAAQ,OAAO,MAAM;AAC/D,SAAO;AACT;AAEO,IAAM,YAAY,CACvB,QACA,OACA,OACA,YACI;AAAA,EACJ,OAAO,UAAU,QAAQ,iBAAiB,mBAAmB,MAAM,OAAO,MAAM,GAAG,OAAO,KAAK;AAAA,EAC/F,QAAQ;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AACF;AAEO,IAAM,cAAc,CAAC,OAAc,QAAsB,WAAoB;AAClF,QAAM,YAAY;AAAA,IAChB,UAAU;AAAA,IACV,iBAAiB,MAAM,QAAQ,QAAQ;AAAA,IACvC,SAAS;AAAA,IACT,YAAY,MAAM,YAAY,OAAO,SAAS;AAAA,IAC9C,WAAW;AAAA,MACT,SAAS;AAAA,IACX;AAAA,IACA,GAAI,SAAS,EAAE,SAAS,IAAI,IAAI,CAAC;AAAA,EACnC;AAEA,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,EAAE,GAAG,WAAW,KAAK,GAAG,OAAO,IAAI,OAAO,GAAG,QAAQ,QAAQ,QAAQ,YAAY;AAAA,IAC1F,KAAK;AACH,aAAO,EAAE,GAAG,WAAW,QAAQ,IAAI,MAAM,GAAG,OAAO,QAAQ,QAAQ,GAAG,QAAQ,YAAY;AAAA,IAC5F,KAAK;AACH,aAAO;AAAA,QACL,GAAG;AAAA,QACH,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,cAAc;AAAA,MAChB;AAAA,IACF;AACE,aAAO;AAAA,EACX;AACF;AAeA,IAAM,qBAAmE;AAAA,EACvE,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,UAAU;AAAA,EACV,WAAW;AAAA,EACX,WAAW;AAAA,EACX,UAAU;AACZ;AAIA,IAAM,eAAe,CAAC,UACpB,OAAO;AAAA,EACL,OAAO,QAAQ,KAAK,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,UAAU,MAAS;AACjE;AAEK,IAAM,wBAAwB,CAAC,WACnC,EAAE,GAAG,oBAAoB,GAAG,aAAa,KAAK,EAAE;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/data-display/DataGrid/DataGrid.cells.tsx"],"sourcesContent":["/**\n * The DataGrid's cell and row renderers.\n *\n * Components rather than closures over the grid's scope: as inline `render*`\n * functions they could reach every piece of the component's state, which is how\n * the body grew past 700 lines. Each one now states exactly what it needs.\n */\nimport ArrowDownward from '@mui/icons-material/ArrowDownward';\nimport ArrowUpward from '@mui/icons-material/ArrowUpward';\nimport ExpandLess from '@mui/icons-material/ExpandLess';\nimport ExpandMore from '@mui/icons-material/ExpandMore';\nimport UnfoldMore from '@mui/icons-material/UnfoldMore';\nimport Button from '@mui/material/Button/index.js';\nimport Checkbox from '@mui/material/Checkbox/index.js';\nimport IconButton from '@mui/material/IconButton/index.js';\nimport TableCell from '@mui/material/TableCell/index.js';\nimport TableRow from '@mui/material/TableRow/index.js';\nimport Typography from '@mui/material/Typography/index.js';\nimport { useTheme } from '@mui/material/styles/index.js';\nimport React from 'react';\n\nimport { cellValue } from './DataGrid.rows';\nimport type { DataGridModel } from './DataGrid.model';\nimport type { DataGridProps, GridColumn, GridSort } from './DataGrid.types';\n\n/** The glyph for a column's current sort state — unsorted included. */\nfunction SortIcon({ dir }: { dir: GridSort['dir'] | undefined }): React.JSX.Element {\n if (!dir) return <UnfoldMore fontSize=\"small\" sx={{ opacity: 0.5 }} />;\n return dir === 'asc' ? <ArrowUpward fontSize=\"small\" /> : <ArrowDownward fontSize=\"small\" />;\n}\n\n/** `aria-sort`'s three values, which are not the same words as `SortDirection`. */\nfunction ariaSort(dir: GridSort['dir'] | undefined): 'none' | 'ascending' | 'descending' {\n if (!dir) return 'none';\n return dir === 'asc' ? 'ascending' : 'descending';\n}\n\nexport interface HeaderCellProps<T extends Record<string, unknown>> {\n column: GridColumn<T>;\n sort: GridSort | undefined;\n sortable: boolean;\n stickyHeader: boolean;\n headerHeight: number;\n onSort: (columnId: string) => void;\n}\n\nexport function HeaderCell<T extends Record<string, unknown>>({\n column,\n sort,\n sortable,\n stickyHeader,\n headerHeight,\n onSort,\n}: HeaderCellProps<T>): React.JSX.Element {\n const theme = useTheme();\n const content = column.headerCell ? column.headerCell(column) : column.header;\n return (\n <TableCell\n data-slot=\"header-cell\"\n data-sort={sort?.dir ?? 'none'}\n sx={{\n position: stickyHeader ? 'sticky' : 'static',\n top: 0,\n zIndex: 1,\n backgroundColor: theme.palette.background.paper,\n borderBottom: `1px solid ${theme.palette.divider}`,\n height: headerHeight,\n minWidth: column.minWidth,\n maxWidth: column.maxWidth,\n width: column.width,\n }}\n role=\"columnheader\"\n aria-sort={ariaSort(sort?.dir)}\n >\n {sortable ? (\n <Button\n onClick={() => onSort(column.id)}\n sx={{\n justifyContent: 'flex-start',\n textTransform: 'none',\n fontWeight: 500,\n color: 'inherit',\n p: 0,\n minWidth: 0,\n '&:hover': { backgroundColor: 'transparent', opacity: 0.8 },\n }}\n endIcon={<SortIcon dir={sort?.dir} />}\n aria-label={column.ariaLabel ?? `Sort by ${String(column.header)}`}\n >\n {content}\n </Button>\n ) : (\n <Typography variant=\"subtitle2\" fontWeight={500}>\n {content}\n </Typography>\n )}\n </TableCell>\n );\n}\n\nexport interface DataCellProps<T extends Record<string, unknown>> {\n row: T;\n rowIndex: number;\n rowId: string | number;\n column: GridColumn<T>;\n rowHeight: number;\n editing: NonNullable<DataGridProps<T>['editing']>;\n model: Pick<DataGridModel<T>, 'editingCell' | 'setEditingCell'>;\n}\n\nexport function DataCell<T extends Record<string, unknown>>({\n row,\n rowIndex,\n rowId,\n column,\n rowHeight,\n editing,\n model,\n}: DataCellProps<T>): React.JSX.Element {\n const value = cellValue(row, column);\n const isEditing =\n model.editingCell?.rowId === rowId && model.editingCell?.colId === column.id;\n const content = column.cell\n ? column.cell({ value, row, rowIndex, col: column })\n : String(value ?? '');\n return (\n <TableCell\n data-slot=\"cell\"\n data-col-id={column.id}\n data-editing={isEditing}\n sx={{\n minWidth: column.minWidth,\n maxWidth: column.maxWidth,\n width: column.width,\n height: rowHeight,\n }}\n role=\"gridcell\"\n tabIndex={-1}\n >\n {isEditing && column.editor\n ? column.editor({\n value,\n row,\n onChange: () => undefined,\n commit: () => {\n editing.onEditCommit?.({ rowId, colId: column.id, value, row });\n model.setEditingCell(null);\n },\n cancel: () => model.setEditingCell(null),\n })\n : content}\n </TableCell>\n );\n}\n\nexport interface GridRowProps<T extends Record<string, unknown>> {\n row: T;\n index: number;\n rowId: string | number;\n isSelected: boolean;\n isExpanded: boolean;\n totalColumns: number;\n model: DataGridModel<T>;\n props: DataGridProps<T>;\n}\n\n/** The leading checkbox / chevron cells, which exist only for enabled features. */\nfunction RowControls<T extends Record<string, unknown>>({\n row,\n index,\n rowId,\n isSelected,\n isExpanded,\n model,\n props,\n}: GridRowProps<T>): React.JSX.Element {\n const { selection = { mode: 'none' }, expansion } = props;\n return (\n <>\n {selection.mode !== 'none' && (\n <TableCell padding=\"checkbox\">\n <Checkbox\n checked={isSelected}\n onChange={(event) => model.onToggleRow(rowId, event.target.checked)}\n inputProps={{ 'aria-label': `Select row ${index + 1}` }}\n />\n </TableCell>\n )}\n {expansion && (\n <TableCell padding=\"checkbox\">\n {expansion.isRowExpandable?.(row) === false ? null : (\n <IconButton\n size=\"small\"\n // Stopped so a host that opens the record on a row click does not\n // ALSO open it here: the chevron is its own control.\n onClick={(event) => {\n event.stopPropagation();\n model.onToggleExpansion(rowId);\n }}\n aria-expanded={isExpanded}\n aria-label={\n isExpanded\n ? (expansion.collapseLabel ?? 'Collapse row')\n : (expansion.expandLabel ?? 'Expand row')\n }\n data-slot=\"expand-toggle\"\n >\n {isExpanded ? <ExpandLess /> : <ExpandMore />}\n </IconButton>\n )}\n </TableCell>\n )}\n </>\n );\n}\n\nexport function GridRow<T extends Record<string, unknown>>(\n rowProps: GridRowProps<T>,\n): React.JSX.Element {\n const { row, index, rowId, isSelected, isExpanded, totalColumns, model, props } = rowProps;\n const theme = useTheme();\n const expansion = props.expansion;\n return (\n <React.Fragment>\n <TableRow\n data-slot=\"row\"\n data-selected={isSelected}\n data-expanded={isExpanded}\n sx={{\n '&:hover': { backgroundColor: theme.palette.action.hover },\n ...(isSelected && { backgroundColor: theme.palette.action.selected }),\n height: model.rowHeight,\n }}\n role=\"row\"\n aria-selected={isSelected}\n >\n <RowControls {...rowProps} />\n {model.visibleColumns.map((column) => (\n <DataCell\n key={column.id}\n row={row}\n rowIndex={index}\n rowId={rowId}\n column={column}\n rowHeight={model.rowHeight}\n editing={props.editing ?? { mode: 'none' }}\n model={model}\n />\n ))}\n </TableRow>\n {expansion && isExpanded && expansion.isRowExpandable?.(row) !== false && (\n <TableRow data-slot=\"row-detail\">\n <TableCell colSpan={totalColumns}>{expansion.render(row, index)}</TableCell>\n </TableRow>\n )}\n </React.Fragment>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/utility/InfiniteScroll/InfiniteScroll.parts.tsx"],"sourcesContent":["import Alert from '@mui/material/Alert/index.js';\nimport Box from '@mui/material/Box/index.js';\nimport CircularProgress from '@mui/material/CircularProgress/index.js';\nimport Typography from '@mui/material/Typography/index.js';\nimport React from 'react';\n\nimport type { InfiniteScrollProps } from './InfiniteScroll.types';\n\ntype Variant = NonNullable<InfiniteScrollProps['variant']>;\n\nconst CENTERED = {\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n p: 2,\n} as const;\n\nexport const DefaultLoader: React.FC<{ loadingText: string }> = ({ loadingText }) => (\n <Box sx={CENTERED}>\n <CircularProgress size={24} />\n <Typography variant=\"body2\" sx={{ ml: 1 }}>\n {loadingText}\n </Typography>\n </Box>\n);\n\nexport const DefaultEndMessage: React.FC<{ endText: string }> = ({ endText }) => (\n <Box sx={CENTERED}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {endText}\n </Typography>\n </Box>\n);\n\nexport const DefaultError: React.FC<{ error: Error }> = ({ error }) => (\n <Alert severity=\"error\" sx={{ m: 2 }}>\n {error.message || 'An error occurred while loading more items'}\n </Alert>\n);\n\n/**\n * `horizontal` scrolls along a row; `reverse` stacks bottom-up, for a chat log\n * that loads older messages as you scroll away from the newest.\n */\nexport const containerStyles = (variant: Variant, width?: number | string) => {\n const horizontal = variant === 'horizontal';\n const base = {\n width: horizontal ? width || '100%' : '100%',\n height: horizontal ? '100%' : 'auto',\n overflowX: horizontal ? 'auto' : 'hidden',\n overflowY: horizontal ? 'hidden' : 'visible',\n display: 'flex',\n flexDirection: horizontal ? 'row' : 'column',\n };\n\n return variant === 'reverse' ? { ...base, flexDirection: 'column-reverse' } : base;\n};\n"],"mappings":";AAAA,OAAO,WAAW;AAClB,OAAO,SAAS;AAChB,OAAO,sBAAsB;AAC7B,OAAO,gBAAgB;AAerB,SACE,KADF;AARF,IAAM,WAAW;AAAA,EACf,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,GAAG;AACL;AAEO,IAAM,gBAAmD,CAAC,EAAE,YAAY,MAC7E,qBAAC,OAAI,IAAI,UACP;AAAA,sBAAC,oBAAiB,MAAM,IAAI;AAAA,EAC5B,oBAAC,cAAW,SAAQ,SAAQ,IAAI,EAAE,IAAI,EAAE,GACrC,uBACH;AAAA,GACF;AAGK,IAAM,oBAAmD,CAAC,EAAE,QAAQ,MACzE,oBAAC,OAAI,IAAI,UACP,8BAAC,cAAW,SAAQ,SAAQ,OAAM,kBAC/B,mBACH,GACF;AAGK,IAAM,eAA2C,CAAC,EAAE,MAAM,MAC/D,oBAAC,SAAM,UAAS,SAAQ,IAAI,EAAE,GAAG,EAAE,GAChC,gBAAM,WAAW,8CACpB;AAOK,IAAM,kBAAkB,CAAC,SAAkB,UAA4B;AAC5E,QAAM,aAAa,YAAY;AAC/B,QAAM,OAAO;AAAA,IACX,OAAO,aAAa,SAAS,SAAS;AAAA,IACtC,QAAQ,aAAa,SAAS;AAAA,IAC9B,WAAW,aAAa,SAAS;AAAA,IACjC,WAAW,aAAa,WAAW;AAAA,IACnC,SAAS;AAAA,IACT,eAAe,aAAa,QAAQ;AAAA,EACtC;AAEA,SAAO,YAAY,YAAY,EAAE,GAAG,MAAM,eAAe,iBAAiB,IAAI;AAChF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/form/Switch/Switch.styles.ts"],"sourcesContent":["import { alpha } from '@mui/material/styles/index.js';\nimport type { CSSObject, Theme } from '@mui/material/styles/index.js';\n\nimport {\n bounceAnimation,\n glowAnimation,\n pulseAnimation,\n rippleAnimation,\n shimmerAnimation,\n spinAnimation,\n} from './Switch.animations';\nimport {\n DISABLED,\n IOS_BASE_OFFSET,\n IOS_THUMB_SHADOW,\n IOS_TRAVEL_INSET,\n SWITCH_GLASS,\n SWITCH_GLOW,\n NEUTRAL_CONTRAST,\n SWITCH_FOCUS_RING,\n SWITCH_GRADIENT,\n SWITCH_HOVER,\n SWITCH_PULSE,\n SWITCH_RIPPLE,\n SWITCH_SPINNER,\n SWITCH_TRANSITION,\n RESTING_THUMB,\n THUMB_ELEVATION,\n THUMB_RADIUS,\n TRACK_LABEL,\n TRACK_RADIUS,\n geometryOf,\n iosTrackShadow,\n lookOf,\n seconds,\n showsTrackLabels,\n trackColor,\n type SwitchGeometry,\n type SwitchLook,\n} from './Switch.metrics';\nimport type { SwitchVariant } from './Switch.base';\n\nimport { absoluteInk, controlNeutral, neutralTones } from '../../../tokens/ink';\nimport { rem } from '../../../tokens/relative';\nimport { inkOver } from '../../../tokens/theme';\nimport type { ColorValue, SizeValue } from '../../../tokens/vocabulary';\n\n// Every number below comes from `./Switch.metrics`, which the native renderer\n// reads too — see its header. The palette and the shadows stay on the MUI\n// theme so a host that re-themes either keeps moving the web.\ninterface ColorPalette {\n main: string;\n dark?: string;\n light?: string;\n contrastText?: string;\n}\n\n/** `neutral` is not a MUI palette entry, so it is the controls' neutral tone. */\nconst neutralPalette = (theme: Theme): ColorPalette => controlNeutral(theme);\n\n/**\n * Resolves a colour name to a full palette, filling any step the theme leaves\n * out from `main` and then from the primary palette. `danger` is this\n * component's name for the error palette; the rest map straight through.\n */\nconst getColorFromTheme = (theme: Theme, color: string): ColorPalette => {\n if (color === 'neutral') {\n return neutralPalette(theme);\n }\n\n const colorMap: Record<string, ColorPalette | undefined> = {\n primary: theme.palette.primary,\n secondary: theme.palette.secondary,\n success: theme.palette.success,\n warning: theme.palette.warning,\n info: theme.palette.info,\n danger: theme.palette.error,\n };\n const palette = colorMap[color] ?? theme.palette.primary;\n const { primary } = theme.palette;\n\n return {\n main: palette.main || primary.main,\n dark: palette.dark || palette.main || primary.dark,\n light: palette.light || palette.main || primary.light,\n contrastText: palette.contrastText || NEUTRAL_CONTRAST,\n };\n};\n\nexport interface SwitchFlags {\n customVariant?: SwitchVariant;\n customColor?: ColorValue;\n customSize?: SizeValue;\n glow?: boolean;\n glass?: boolean;\n gradient?: boolean;\n trackWidth?: number;\n trackHeight?: number;\n onText?: string;\n offText?: string;\n loading?: boolean;\n ripple?: boolean;\n pulse?: boolean;\n}\n\n/** A metrics radius on the web: its px through the type scale, a percentage as-is. */\nconst lengthOrPercent = (theme: Theme, value: number | string): string =>\n typeof value === 'number' ? rem(theme, value) : value;\n\nconst thumbShadow = (theme: Theme, look: SwitchLook): string =>\n look === 'ios' ? IOS_THUMB_SHADOW : (theme.shadows[THUMB_ELEVATION[look]] ?? 'none');\n\n/** The ripple that expands from the thumb on hover. */\nconst rippleOverlay = (palette: ColorPalette): CSSObject => ({\n content: '\"\"',\n position: 'absolute',\n top: '50%',\n left: '50%',\n width: '100%',\n height: '100%',\n borderRadius: '50%',\n background: alpha(palette.main, SWITCH_RIPPLE.alpha),\n animation: `${rippleAnimation} ${seconds(SWITCH_RIPPLE.ms)} ease-out`,\n transform: 'translate(-50%, -50%)',\n pointerEvents: 'none',\n});\n\n/**\n * The ink on the CHECKED track — the thumb, the `on` wording and any on-icon\n * (FUT-1924).\n *\n * All three stated `#fff`, and the checked track is `palette.main`: the one\n * surface in this component the TENANT picks. A store with a pale brand got a\n * white thumb on a pale green bar, which does not read as a knob at all — the\n * switch looks OFF while it is on, so this is a state a user misreads rather\n * than a colour they dislike.\n *\n * The `gradient` flag paints the track `light → main → dark`, so the fills the\n * thumb travels over are handed over together and {@link inkOver} takes the\n * worst of them.\n *\n * The RESTING track is not here on purpose: it is `theme.palette.action.disabled`\n * washed over the page, which no tenant chooses, and a white thumb on it is the\n * conventional look in both modes.\n */\nconst checkedInk = (flags: SwitchFlags, palette: ColorPalette): string => {\n const fills = flags.gradient\n ? [palette.light || palette.main, palette.main, palette.dark || palette.main]\n : [palette.main];\n\n return inkOver(fills, palette.contrastText || NEUTRAL_CONTRAST);\n};\n\n/** The checked track: the filled bar behind the thumb once the switch is on. */\nconst checkedTrack = (theme: Theme, flags: SwitchFlags, palette: ColorPalette): CSSObject => ({\n backgroundColor: palette.main,\n opacity: 1,\n border: 0,\n position: 'relative',\n overflow: 'hidden',\n ...(flags.glow && {\n animation: `${glowAnimation(theme)} ${seconds(SWITCH_GLOW.ms)} ease-in-out infinite`,\n boxShadow: `0 0 ${rem(theme, SWITCH_GLOW.blur)} ${alpha(palette.main, SWITCH_GLOW.alpha)}, inset 0 0 ${rem(theme, SWITCH_GLOW.insetBlur)} ${alpha(palette.main, SWITCH_GLOW.insetAlpha)}`,\n }),\n ...(flags.gradient && {\n background: `linear-gradient(${SWITCH_GRADIENT.checked.angleDeg}deg, ${palette.light || palette.main} ${SWITCH_GRADIENT.checked.stops[0]}%, ${palette.main} ${SWITCH_GRADIENT.checked.stops[1]}%, ${palette.dark || palette.main} ${SWITCH_GRADIENT.checked.stops[2]}%)`,\n backgroundSize: '200% 100%',\n animation: `${shimmerAnimation} ${seconds(SWITCH_GRADIENT.shimmerMs)} ease infinite`,\n }),\n});\n\nconst switchBaseSx = (\n theme: Theme,\n flags: SwitchFlags,\n palette: ColorPalette,\n geometry: SwitchGeometry,\n look: SwitchLook,\n): CSSObject => {\n const { width, thumbSize, padding } = geometry;\n const isIos = look === 'ios';\n\n return {\n padding: rem(theme, padding),\n margin: 0,\n transitionDuration: `${SWITCH_TRANSITION.ms}ms`,\n transitionTimingFunction: SWITCH_TRANSITION.easing,\n ...(isIos && { transform: `translateX(${rem(theme, IOS_BASE_OFFSET)})` }),\n '&:hover': {\n '& .MuiSwitch-thumb': {\n transform: flags.loading ? 'none' : `scale(${SWITCH_HOVER.thumbScale})`,\n boxShadow: `${theme.shadows[SWITCH_HOVER.elevation]}, 0 0 ${rem(theme, SWITCH_HOVER.blur)} ${alpha(palette.main, SWITCH_HOVER.alpha)}`,\n },\n ...(flags.ripple && { '&::after': rippleOverlay(palette) }),\n },\n '&.Mui-checked': {\n // The thumb travels the track minus its own width and both paddings; the\n // iOS look insets differently, so it gets its own distance.\n transform: `translateX(${rem(theme, width - thumbSize - padding * 2)})`,\n color: checkedInk(flags, palette),\n '& .MuiSwitch-thumb': {\n animation: flags.loading ? 'none' : `${bounceAnimation} ${seconds(SWITCH_TRANSITION.ms)} ease-out`,\n /*\n GLASS KEEPS ITS WASH AND GAINS AN OUTLINE (FUT-2067).\n\n It used to keep the wash and nothing else, on the argument that a\n translucent thumb MEANS to show the track through itself, so painting\n it opaque would be repainting the variant rather than fixing it. The\n first half of that is still true and this still does not touch the\n fill. The second half was doing more work than the number supports:\n `SWITCH_GLASS.thumbAlpha` is **0.9**, so nine parts in ten of the knob\n are `background.paper` and one part is the track. On a pale brand that\n composites to within about 1.1:1 of the bar it is sitting on — the\n same \"reads as OFF while it is on\" state FUT-1924 exists for, in the\n one variant whose own argument points AT the tenant-controlled\n surface.\n\n So the separation moves to the EDGE, which is the thing a glass\n surface is allowed to have. The colour is {@link checkedInk} — the\n same derivation the opaque thumb gets, so there is one rule for \"what\n reads on this track\" rather than two — at full strength rather than\n the `divider` hairline at `borderAlpha` 0.2 the resting thumb wears,\n which on a pale track is not an outline at all.\n\n Checked only. The resting track is `action.disabled` washed over the\n page, which no tenant chooses, so the quiet hairline stays right\n there — the same split {@link checkedInk}'s own docblock makes.\n */\n ...(flags.glass\n ? { borderColor: checkedInk(flags, palette) }\n : { backgroundColor: checkedInk(flags, palette) }),\n },\n '& + .MuiSwitch-track': checkedTrack(theme, flags, palette),\n '&.Mui-disabled + .MuiSwitch-track': { opacity: DISABLED.checkedTrackOpacity },\n ...(isIos && { transform: `translateX(${rem(theme, width - thumbSize - IOS_TRAVEL_INSET)})` }),\n },\n '&.Mui-focusVisible .MuiSwitch-thumb': {\n color: palette.main,\n border: `${rem(theme, SWITCH_FOCUS_RING.width)} solid ${alpha(palette.main, SWITCH_FOCUS_RING.alpha)}`,\n },\n '&.Mui-disabled .MuiSwitch-thumb': { color: neutralTones(theme).surface },\n '&.Mui-disabled + .MuiSwitch-track': { opacity: DISABLED.trackOpacity },\n };\n};\n\nconst thumbSx = (\n theme: Theme,\n flags: SwitchFlags,\n palette: ColorPalette,\n thumbSize: number,\n look: SwitchLook,\n): CSSObject => ({\n width: rem(theme, thumbSize),\n height: rem(theme, thumbSize),\n borderRadius: lengthOrPercent(theme, THUMB_RADIUS[look](thumbSize)),\n // `.Mui-checked` above replaces this for the brand-filled track; see\n // {@link RESTING_THUMB} for why the resting one stays white.\n backgroundColor: RESTING_THUMB,\n boxShadow: thumbShadow(theme, look),\n transition: `all ${seconds(SWITCH_TRANSITION.ms)} ${SWITCH_TRANSITION.easing}`,\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n ...(flags.glass && {\n backgroundColor: alpha(theme.palette.background.paper, SWITCH_GLASS.thumbAlpha),\n backdropFilter: `blur(${rem(theme, SWITCH_GLASS.thumbBlur)})`,\n border: `1px solid ${alpha(theme.palette.divider, SWITCH_GLASS.borderAlpha)}`,\n }),\n ...(flags.pulse && { animation: `${pulseAnimation} ${seconds(SWITCH_PULSE.ms)} ease-in-out infinite` }),\n ...(flags.loading && {\n // A spinner drawn inside the thumb rather than over the whole control.\n '&::after': {\n content: '\"\"',\n position: 'absolute',\n width: rem(theme, thumbSize * SWITCH_SPINNER.sizeRatio),\n height: rem(theme, thumbSize * SWITCH_SPINNER.sizeRatio),\n border: `${rem(theme, SWITCH_SPINNER.borderWidth)} solid ${palette.main}`,\n borderTop: `${rem(theme, SWITCH_SPINNER.borderWidth)} solid transparent`,\n borderRadius: '50%',\n animation: `${spinAnimation} ${seconds(SWITCH_SPINNER.ms)} linear infinite`,\n },\n }),\n ...(look === 'material' && {\n '&::before': {\n content: '\"\"',\n position: 'absolute',\n width: '100%',\n height: '100%',\n borderRadius: 'inherit',\n backgroundColor: palette.main,\n opacity: 0,\n transform: 'scale(0)',\n transition: 'all 0.3s ease',\n },\n }),\n});\n\n/** The on/off wording the `label` variant prints inside the track. */\nconst trackLabels = (\n theme: Theme,\n flags: SwitchFlags,\n palette: ColorPalette,\n onText?: string,\n offText?: string,\n): CSSObject => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingLeft: theme.spacing(TRACK_LABEL.insetUnits),\n paddingRight: theme.spacing(TRACK_LABEL.insetUnits),\n fontSize: rem(theme, TRACK_LABEL.fontSize),\n fontWeight: TRACK_LABEL.fontWeight,\n color: theme.palette.text.secondary,\n '&::before, &::after': {\n content: '\"\"',\n position: 'absolute',\n fontSize: rem(theme, TRACK_LABEL.fontSize),\n fontWeight: TRACK_LABEL.fontWeight,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 1,\n },\n ...(onText && {\n '&::before': {\n content: `\"${onText}\"`,\n left: theme.spacing(TRACK_LABEL.insetUnits),\n // The `on` word sits at the end the thumb travels TO, which is the\n // filled half of the track once checked.\n color: checkedInk(flags, palette),\n },\n }),\n ...(offText && {\n '&::after': {\n content: `\"${offText}\"`,\n right: theme.spacing(TRACK_LABEL.insetUnits),\n color: theme.palette.text.secondary,\n },\n }),\n});\n\nconst trackSx = (\n theme: Theme,\n flags: SwitchFlags,\n palette: ColorPalette,\n height: number,\n look: SwitchLook,\n): CSSObject => {\n const { glass, gradient, onText, offText, customVariant } = flags;\n\n return {\n borderRadius: rem(theme, TRACK_RADIUS[look](height)),\n backgroundColor: trackColor(\n { black: absoluteInk(theme).black, disabled: theme.palette.action.disabled },\n look,\n ),\n opacity: 1,\n transition: `all ${seconds(SWITCH_TRANSITION.ms)} ${SWITCH_TRANSITION.easing}`,\n position: 'relative',\n boxShadow: look === 'ios' ? iosTrackShadow() : 'none',\n ...(glass && {\n backgroundColor: alpha(theme.palette.background.paper, SWITCH_GLASS.trackAlpha),\n backdropFilter: `blur(${rem(theme, SWITCH_GLASS.trackBlur)})`,\n border: `1px solid ${alpha(theme.palette.divider, SWITCH_GLASS.borderAlpha)}`,\n }),\n ...(gradient &&\n !glass && {\n background: `linear-gradient(${SWITCH_GRADIENT.resting.angleDeg}deg, ${alpha(palette.light || palette.main, SWITCH_GRADIENT.resting.lightAlpha)}, ${alpha(palette.main, SWITCH_GRADIENT.resting.mainAlpha)})`,\n }),\n ...(showsTrackLabels(customVariant, onText, offText) &&\n trackLabels(theme, flags, palette, onText, offText)),\n };\n};\n\n/**\n * The same checked-track ink, for the two ICONS the control overlays on the\n * track — which are drawn as components rather than styles, so they cannot\n * reach {@link checkedInk} directly.\n */\nexport const onTrackInk = (theme: Theme, flags: SwitchFlags): string =>\n checkedInk(flags, getColorFromTheme(theme, flags.customColor ?? 'primary'));\n\nexport const switchSx = (theme: Theme, flags: SwitchFlags): CSSObject => {\n const palette = getColorFromTheme(theme, flags.customColor ?? 'primary');\n const geometry = geometryOf(flags.customSize, flags.trackWidth, flags.trackHeight);\n const look = lookOf(flags.customVariant);\n\n return {\n width: rem(theme, geometry.width),\n height: rem(theme, geometry.height),\n padding: 0,\n overflow: 'visible',\n '& .MuiSwitch-switchBase': switchBaseSx(theme, flags, palette, geometry, look),\n '& .MuiSwitch-thumb': thumbSx(theme, flags, palette, geometry.thumbSize, look),\n '& .MuiSwitch-track': trackSx(theme, flags, palette, geometry.height, look),\n };\n};\n"],"mappings":"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","names":[]}