@12-apps/ui 6.43.0 → 6.44.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 (416) hide show
  1. package/NATIVE.md +1 -1
  2. package/dist/_internal/components/data-display/AsyncStateContainer/AsyncStateContainer.js +3 -3
  3. package/dist/_internal/components/data-display/Badge/Badge.js +6 -5
  4. package/dist/_internal/components/data-display/Badge/Badge.styles.js +4 -3
  5. package/dist/_internal/components/data-display/Badge/BadgeContent.js +5 -4
  6. package/dist/_internal/components/data-display/CardKit/use-remove-confirm.js +5 -5
  7. package/dist/_internal/components/data-display/CardKit/use-row-confirm.js +5 -5
  8. package/dist/_internal/components/data-display/Carousel/Carousel.chrome.js +5 -4
  9. package/dist/_internal/components/data-display/Carousel/Carousel.js +8 -7
  10. package/dist/_internal/components/data-display/Carousel/Carousel.parts.js +4 -3
  11. package/dist/_internal/components/data-display/Carousel/Carousel.styles.js +4 -3
  12. package/dist/_internal/components/data-display/Chart/Chart.js +7 -6
  13. package/dist/_internal/components/data-display/Chart/SpecChart.js +8 -7
  14. package/dist/_internal/components/data-display/Chart/chart-context.js +5 -4
  15. package/dist/_internal/components/data-display/Chart/chart-internals.js +4 -3
  16. package/dist/_internal/components/data-display/Chart/chart-renderers.js +6 -5
  17. package/dist/_internal/components/data-display/DataGrid/DataGrid.js +4 -3
  18. package/dist/_internal/components/data-display/DataGrid/DataGrid.model.js +3 -2
  19. package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +32 -31
  20. package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +45 -44
  21. package/dist/_internal/components/data-display/DataViews/DeleteViewDialog.js +3 -3
  22. package/dist/_internal/components/data-display/DataViews/ManageViewsDialog.js +7 -7
  23. package/dist/_internal/components/data-display/DataViews/SaveViewModal.js +3 -3
  24. package/dist/_internal/components/data-display/DataViews/base-card.js +3 -3
  25. package/dist/_internal/components/data-display/DataViews/base-list-card-geometry.js +6 -5
  26. package/dist/_internal/components/data-display/DataViews/base-list-card-gutters.js +3 -3
  27. package/dist/_internal/components/data-display/DataViews/base-list-card-slots.js +5 -4
  28. package/dist/_internal/components/data-display/DataViews/base-list-card.js +10 -9
  29. package/dist/_internal/components/data-display/DataViews/data-views-category-pill.js +8 -8
  30. package/dist/_internal/components/data-display/DataViews/data-views-display-panel.js +5 -4
  31. package/dist/_internal/components/data-display/DataViews/data-views-display-tabs.js +4 -3
  32. package/dist/_internal/components/data-display/DataViews/data-views-filter-panel.js +12 -12
  33. package/dist/_internal/components/data-display/DataViews/data-views-grid-bodies.js +8 -7
  34. package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +31 -30
  35. package/dist/_internal/components/data-display/DataViews/data-views-inline-bar.js +12 -12
  36. package/dist/_internal/components/data-display/DataViews/data-views-layout-context.js +3 -2
  37. package/dist/_internal/components/data-display/DataViews/data-views-more-fields.js +9 -9
  38. package/dist/_internal/components/data-display/DataViews/data-views-more-filters.js +10 -10
  39. package/dist/_internal/components/data-display/DataViews/data-views-scope-tabs.js +4 -3
  40. package/dist/_internal/components/data-display/DataViews/data-views-shell-toolbar.js +8 -7
  41. package/dist/_internal/components/data-display/DataViews/data-views-table-parts.js +10 -10
  42. package/dist/_internal/components/data-display/DataViews/data-views-toolbar.js +7 -6
  43. package/dist/_internal/components/data-display/DataViews/list-card-rails.js +4 -3
  44. package/dist/_internal/components/data-display/DataViews/use-saved-views-controller.js +2 -2
  45. package/dist/_internal/components/data-display/EmptyState/EmptyState.js +2 -2
  46. package/dist/_internal/components/data-display/FleetMap/FleetBody.js +5 -5
  47. package/dist/_internal/components/data-display/FleetMap/FleetCanvas.js +4 -4
  48. package/dist/_internal/components/data-display/FleetMap/FleetMap.js +13 -12
  49. package/dist/_internal/components/data-display/InteractiveTooltip/InteractiveTooltip.js +2 -2
  50. package/dist/_internal/components/data-display/Lightbox/Lightbox.js +2 -2
  51. package/dist/_internal/components/data-display/MapPreview/MapLayers.js +2 -2
  52. package/dist/_internal/components/data-display/MapPreview/MapPreview.js +3 -3
  53. package/dist/_internal/components/data-display/SectionOnboarding/SectionOnboarding.js +3 -3
  54. package/dist/_internal/components/data-display/Sheet/Sheet.body.js +3 -2
  55. package/dist/_internal/components/data-display/Sheet/Sheet.js +5 -4
  56. package/dist/_internal/components/data-display/Sheet/Sheet.styles.js +4 -3
  57. package/dist/_internal/components/data-display/Table/Table.js +4 -3
  58. package/dist/_internal/components/data-display/index.js +38 -37
  59. package/dist/_internal/components/feedback/ConfirmAction/ConfirmAction.js +2 -2
  60. package/dist/_internal/components/feedback/ConfirmAction/ConfirmButton.js +3 -3
  61. package/dist/_internal/components/feedback/ConfirmAction/with-confirmation.js +2 -2
  62. package/dist/_internal/components/feedback/Dialog/Dialog.js +2 -2
  63. package/dist/_internal/components/feedback/StackedModal/StackedModal.js +6 -6
  64. package/dist/_internal/components/feedback/index.js +14 -14
  65. package/dist/_internal/components/form/AddressAutocomplete/AddressAutocomplete.js +1 -1
  66. package/dist/_internal/components/form/AddressAutocomplete/AddressAutocompleteField.js +1 -1
  67. package/dist/_internal/components/form/Autocomplete/Autocomplete.js +3 -3
  68. package/dist/_internal/components/form/Autocomplete/useAutocomplete.js +1 -1
  69. package/dist/_internal/components/form/CategorySelect/CategoryPanel.js +3 -3
  70. package/dist/_internal/components/form/CategorySelect/CategorySelect.js +6 -6
  71. package/dist/_internal/components/form/Checkbox/Checkbox.js +2 -2
  72. package/dist/_internal/components/form/Command/Command.js +5 -4
  73. package/dist/_internal/components/form/Command/Command.styles.js +4 -3
  74. package/dist/_internal/components/form/DateRangePicker/DateRangePicker.js +2 -2
  75. package/dist/_internal/components/form/Label/Label.js +5 -4
  76. package/dist/_internal/components/form/Label/Label.styles.js +4 -3
  77. package/dist/_internal/components/form/Menubar/Menubar.item.js +5 -4
  78. package/dist/_internal/components/form/Menubar/Menubar.js +7 -6
  79. package/dist/_internal/components/form/Menubar/Menubar.styles.js +4 -3
  80. package/dist/_internal/components/form/Menubar/Menubar.toolbar.js +6 -5
  81. package/dist/_internal/components/form/UploadButton/UploadButton.js +2 -2
  82. package/dist/_internal/components/form/index.js +21 -20
  83. package/dist/_internal/components/form/total-form/Fields/CategoryField.js +7 -7
  84. package/dist/_internal/components/form/total-form/Fields/index.js +11 -11
  85. package/dist/_internal/components/index.js +100 -99
  86. package/dist/_internal/components/layout/Box/Box.js +6 -5
  87. package/dist/_internal/components/layout/ScrollArea/ScrollArea.js +2 -2
  88. package/dist/_internal/components/layout/SettingCard/SettingCard.js +8 -7
  89. package/dist/_internal/components/layout/SettingCard/SettingCard.parts.js +7 -6
  90. package/dist/_internal/components/layout/SettingCard/SettingGrid.js +8 -7
  91. package/dist/_internal/components/layout/SettingCard/SettingGroup.js +10 -9
  92. package/dist/_internal/components/layout/SettingCard/SettingSwitch.js +9 -8
  93. package/dist/_internal/components/layout/SettingCard/SettingToggle.js +10 -9
  94. package/dist/_internal/components/layout/SettingsLayout/SettingsLayout.js +4 -4
  95. package/dist/_internal/components/layout/SettingsLayout/SettingsPanel.js +3 -3
  96. package/dist/_internal/components/layout/SettingsLayout/SettingsSectionChips.js +2 -2
  97. package/dist/_internal/components/layout/SettingsLayout/SettingsSectionChips.scroll.js +1 -1
  98. package/dist/_internal/components/layout/Stack/Stack.js +7 -6
  99. package/dist/_internal/components/layout/index.js +20 -19
  100. package/dist/_internal/components/navigation/AppHeader/AppHeader.details.js +8 -7
  101. package/dist/_internal/components/navigation/AppHeader/AppHeader.identity.js +4 -3
  102. package/dist/_internal/components/navigation/CommandPalette/CommandPalette.js +2 -2
  103. package/dist/_internal/components/navigation/NavigationMenu/NavigationMegaSection.js +3 -3
  104. package/dist/_internal/components/navigation/NavigationMenu/NavigationMenu.js +5 -5
  105. package/dist/_internal/components/navigation/NavigationMenu/NavigationMenuItem.js +2 -2
  106. package/dist/_internal/components/navigation/NavigationMenu/NavigationStandardBody.js +3 -3
  107. package/dist/_internal/components/navigation/index.js +16 -15
  108. package/dist/_internal/components/utility/InfiniteScroll/InfiniteScroll.js +2 -2
  109. package/dist/_internal/components/utility/WorkflowStep/WorkflowStep.helpers.js +6 -3
  110. package/dist/_internal/components/utility/WorkflowStep/WorkflowStep.js +7 -6
  111. package/dist/_internal/components/utility/WorkflowStep/WorkflowStep.parts.js +5 -4
  112. package/dist/_internal/components/utility/WorkflowStep/WorkflowStepRow.js +6 -5
  113. package/dist/_internal/components/utility/index.js +9 -8
  114. package/dist/_internal/icons/Icon.js +6 -5
  115. package/dist/_internal/provider/UiProvider.js +5 -4
  116. package/dist/_internal/provider/mui-bridge.js +4 -3
  117. package/dist/_internal/provider/use-ui-theme.js +5 -4
  118. package/dist/_internal/tokens/density-overrides.js +11 -0
  119. package/dist/_internal/tokens/density-overrides.js.map +1 -0
  120. package/dist/_internal/tokens/density.js +3 -1
  121. package/dist/charts.js +8 -7
  122. package/dist/{chunk-DJKVSUXH.js → chunk-2GG5W6LR.js} +10 -2
  123. package/dist/chunk-2GG5W6LR.js.map +1 -0
  124. package/dist/{chunk-442FSG7G.js → chunk-3I77A65F.js} +4 -4
  125. package/dist/{chunk-R2FUQV24.js → chunk-4MGUBSAL.js} +2 -2
  126. package/dist/{chunk-YIWVHEPW.js → chunk-4T5LD2NV.js} +2 -2
  127. package/dist/{chunk-4CHYMTBT.js → chunk-4WCDMCIS.js} +4 -4
  128. package/dist/chunk-532XOWZ5.js +59 -0
  129. package/dist/chunk-532XOWZ5.js.map +1 -0
  130. package/dist/{chunk-5KGABAQB.js → chunk-5752357K.js} +4 -4
  131. package/dist/{chunk-JSGVYOMN.js → chunk-5MW7OYBM.js} +2 -2
  132. package/dist/{chunk-RWRPF24F.js → chunk-5OS5AMC2.js} +2 -2
  133. package/dist/{chunk-I6MVJWUO.js → chunk-6B3QXFF5.js} +2 -2
  134. package/dist/{chunk-MLUUF7OZ.js → chunk-6B4UTB4O.js} +2 -2
  135. package/dist/{chunk-FBUCXTA4.js → chunk-6DMUVVON.js} +2 -2
  136. package/dist/{chunk-G7RYAWPZ.js → chunk-6HTCCWUM.js} +2 -2
  137. package/dist/{chunk-77BKKPCI.js → chunk-6KLDYVRY.js} +2 -2
  138. package/dist/{chunk-6Z6PUG4C.js → chunk-6LYRFS5S.js} +5 -5
  139. package/dist/{chunk-KJID4PRD.js → chunk-6S25ZCEW.js} +34 -45
  140. package/dist/chunk-6S25ZCEW.js.map +1 -0
  141. package/dist/{chunk-K4A3JDYQ.js → chunk-6ZWOVUNB.js} +2 -2
  142. package/dist/{chunk-3RUCLKAK.js → chunk-7HZTYK7U.js} +4 -4
  143. package/dist/{chunk-BKZERHNC.js → chunk-7XDET7PL.js} +3 -3
  144. package/dist/{chunk-OD3L6GX5.js → chunk-A7OQBAR7.js} +2 -2
  145. package/dist/{chunk-2MLS6KU4.js → chunk-AEKHSORY.js} +2 -2
  146. package/dist/{chunk-5DAVXZPY.js → chunk-B2WBDMHE.js} +2 -2
  147. package/dist/{chunk-GZT7MLLO.js → chunk-B2ZITMYG.js} +2 -2
  148. package/dist/{chunk-54HTXJJ2.js → chunk-BHE44AQE.js} +2 -2
  149. package/dist/{chunk-TBMGYQJF.js → chunk-BKBELIUR.js} +2 -2
  150. package/dist/{chunk-OOB3YWPX.js → chunk-BZFRBG2H.js} +4 -4
  151. package/dist/{chunk-PICOOZLX.js → chunk-C5RTSOXD.js} +3 -3
  152. package/dist/{chunk-GO6XDMBB.js → chunk-CEJTGG6J.js} +2 -2
  153. package/dist/{chunk-ZGWEFOW6.js → chunk-CKAVTWXP.js} +4 -4
  154. package/dist/{chunk-ANYOSBNA.js → chunk-CSXK7LH7.js} +2 -2
  155. package/dist/{chunk-U6DOF5CR.js → chunk-CU7ELD43.js} +2 -2
  156. package/dist/{chunk-XO4ZUHVH.js → chunk-CYPBF3BI.js} +2 -2
  157. package/dist/{chunk-EO5IEWFI.js → chunk-DE6A46AE.js} +6 -6
  158. package/dist/{chunk-JMEPGXJG.js → chunk-DHW5UMUG.js} +2 -2
  159. package/dist/{chunk-3EPA2A4M.js → chunk-DJIFXJ4C.js} +5 -5
  160. package/dist/{chunk-CM2Q7IH3.js → chunk-DTLKF4AX.js} +6 -6
  161. package/dist/{chunk-C6JUGWAU.js → chunk-DYCTIOER.js} +4 -4
  162. package/dist/{chunk-LCWGNDTH.js → chunk-EKBUM7HK.js} +4 -4
  163. package/dist/{chunk-NYT3UVOH.js → chunk-EOEYOPOS.js} +7 -7
  164. package/dist/{chunk-7LILFS72.js → chunk-EOKPFMJD.js} +2 -2
  165. package/dist/{chunk-ZSTSISM6.js → chunk-FHWXRHMA.js} +1 -1
  166. package/dist/{chunk-ZSTSISM6.js.map → chunk-FHWXRHMA.js.map} +1 -1
  167. package/dist/{chunk-4PRZLII7.js → chunk-FOM7OMJR.js} +5 -5
  168. package/dist/{chunk-QSNLIWEB.js → chunk-FTV5R2UZ.js} +2 -2
  169. package/dist/{chunk-NDHDBOUH.js → chunk-FWPFCK4D.js} +4 -4
  170. package/dist/{chunk-ON4TRXCM.js → chunk-GHJ2FIJO.js} +3 -3
  171. package/dist/{chunk-GANW7FXQ.js → chunk-GKNMKPR6.js} +2 -2
  172. package/dist/{chunk-LGCRL7DK.js → chunk-GP4BJI3F.js} +2 -2
  173. package/dist/{chunk-652PYSML.js → chunk-HDVEE4NQ.js} +14 -6
  174. package/dist/chunk-HDVEE4NQ.js.map +1 -0
  175. package/dist/{chunk-4MKVGSHX.js → chunk-HN3PZTUK.js} +5 -5
  176. package/dist/{chunk-HBP2OU4Q.js → chunk-HNFZLXZI.js} +5 -5
  177. package/dist/{chunk-5FHPZOYK.js → chunk-HOIHO2YQ.js} +2 -2
  178. package/dist/{chunk-3AOOI2NR.js → chunk-HR7YTBR7.js} +4 -4
  179. package/dist/{chunk-PGV2FLE3.js → chunk-IG26N6J2.js} +2 -2
  180. package/dist/{chunk-G2WERTWZ.js → chunk-IGGXKT5B.js} +2 -2
  181. package/dist/{chunk-XLXMJ6X2.js → chunk-IO2X6DVH.js} +3 -3
  182. package/dist/{chunk-3CLBGHTL.js → chunk-ITBUKGG3.js} +2 -2
  183. package/dist/{chunk-6IRJAIS4.js → chunk-IXWIJCS3.js} +2 -2
  184. package/dist/{chunk-TMW7RBW7.js → chunk-J6TIK47Z.js} +2 -2
  185. package/dist/{chunk-G4TKMUOL.js → chunk-JDEKR77O.js} +7 -7
  186. package/dist/{chunk-Y2C2S4R7.js → chunk-JHW62I7Z.js} +7 -5
  187. package/dist/chunk-JHW62I7Z.js.map +1 -0
  188. package/dist/{chunk-ITFFA3H2.js → chunk-JYLBVHG2.js} +3 -3
  189. package/dist/{chunk-G7XHJPLO.js → chunk-JZ7ZRZTF.js} +4 -4
  190. package/dist/{chunk-YTVXT5TD.js → chunk-K5CCQBNN.js} +6 -6
  191. package/dist/{chunk-AOFI3GDS.js → chunk-KMC6WP66.js} +5 -5
  192. package/dist/{chunk-K62RHTFB.js → chunk-KNAWZM7F.js} +2 -2
  193. package/dist/{chunk-4Z2HIHA5.js → chunk-KRA75CKC.js} +2 -2
  194. package/dist/{chunk-RHKT2XW2.js → chunk-KUKY5GEX.js} +3 -3
  195. package/dist/{chunk-HUAQQ5ZL.js → chunk-LHHV6NXO.js} +2 -2
  196. package/dist/{chunk-BJGUDLWZ.js → chunk-LRFXCZB4.js} +2 -2
  197. package/dist/{chunk-U6W2RY3Z.js → chunk-MLQYIJTO.js} +5 -5
  198. package/dist/{chunk-GPHURU2K.js → chunk-MSAAOQAD.js} +7 -7
  199. package/dist/{chunk-3MJHHPRW.js → chunk-MVR4GURP.js} +2 -2
  200. package/dist/{chunk-PRLYYKMG.js → chunk-MW7S7WZM.js} +2 -2
  201. package/dist/{chunk-ERY6D2OV.js → chunk-MWPXKZ7O.js} +4 -4
  202. package/dist/{chunk-ZUME25DS.js → chunk-NM2FLCPV.js} +3 -3
  203. package/dist/{chunk-UP7SSTCZ.js → chunk-OAVRXSAS.js} +7 -7
  204. package/dist/{chunk-VYA4QWQL.js → chunk-PJVZY2SA.js} +2 -2
  205. package/dist/{chunk-SDBBJ6FG.js → chunk-PUYJVQ7X.js} +2 -2
  206. package/dist/{chunk-IUD6N52Q.js → chunk-PXGURBIU.js} +4 -4
  207. package/dist/{chunk-PNDYAIKM.js → chunk-Q5J37WOE.js} +2 -2
  208. package/dist/{chunk-DCT2PKMQ.js → chunk-QGB3DOMV.js} +2 -2
  209. package/dist/{chunk-GT2RCOHM.js → chunk-QLAFJZDS.js} +31 -13
  210. package/dist/chunk-QLAFJZDS.js.map +1 -0
  211. package/dist/{chunk-YGYQC7MT.js → chunk-QOLIBVGS.js} +4 -4
  212. package/dist/{chunk-TDXEO2UI.js → chunk-RJ35IXFD.js} +2 -2
  213. package/dist/{chunk-P6Q2O3TU.js → chunk-RNVR3RGV.js} +2 -2
  214. package/dist/{chunk-SNW5MJ6I.js → chunk-RPKWTFJ2.js} +2 -2
  215. package/dist/{chunk-NPPJ3IJP.js → chunk-RRAWJQIO.js} +2 -2
  216. package/dist/{chunk-H3GYVR7S.js → chunk-SM4MT4YC.js} +3 -3
  217. package/dist/{chunk-5B7BTLN4.js → chunk-SOCZLOPJ.js} +2 -2
  218. package/dist/{chunk-RXNIOPOA.js → chunk-TM5QQJTF.js} +8 -2
  219. package/dist/{chunk-RXNIOPOA.js.map → chunk-TM5QQJTF.js.map} +1 -1
  220. package/dist/{chunk-Z4O3F6KU.js → chunk-U4QUDFPJ.js} +4 -4
  221. package/dist/{chunk-KWU62UPM.js → chunk-UHGQ74E3.js} +2 -2
  222. package/dist/{chunk-Z6LTEJ7F.js → chunk-VKFZQSQC.js} +4 -4
  223. package/dist/{chunk-MBNXCCRG.js → chunk-VQUPB7F7.js} +7 -7
  224. package/dist/{chunk-CNR5RFKC.js → chunk-VVFV4MXS.js} +2 -2
  225. package/dist/{chunk-ALOUJ3CE.js → chunk-WQ3KTELX.js} +5 -5
  226. package/dist/{chunk-FY6PONLA.js → chunk-WSYPM3SR.js} +2 -2
  227. package/dist/{chunk-QMELMQPA.js → chunk-X4VWYWFK.js} +2 -2
  228. package/dist/{chunk-5PJM772Y.js → chunk-XLQYOBHP.js} +4 -4
  229. package/dist/{chunk-TCMH3FXD.js → chunk-XTDJ2D5A.js} +2 -2
  230. package/dist/{chunk-F5GXWK6B.js → chunk-Y2CMWGIU.js} +3 -3
  231. package/dist/{chunk-SJGYMI6Y.js → chunk-Y4ET3NRC.js} +2 -2
  232. package/dist/{chunk-7OO3BELX.js → chunk-Y6RSQEOU.js} +3 -2
  233. package/dist/{chunk-7OO3BELX.js.map → chunk-Y6RSQEOU.js.map} +1 -1
  234. package/dist/{chunk-FIO55AKI.js → chunk-YCHOWWRE.js} +3 -3
  235. package/dist/{chunk-MM5XSAVE.js → chunk-YDIRPKYI.js} +2 -2
  236. package/dist/{chunk-44Z72DDM.js → chunk-YF3VD2KD.js} +2 -2
  237. package/dist/{chunk-BR2T72JI.js → chunk-YWJZPN5C.js} +11 -1
  238. package/dist/chunk-YWJZPN5C.js.map +1 -0
  239. package/dist/{chunk-Z4DKVLYG.js → chunk-Z3HSRNJT.js} +4 -4
  240. package/dist/{chunk-5PTCT3LF.js → chunk-ZQ7IESR7.js} +2 -2
  241. package/dist/data-display/AsyncStateContainer.js +3 -3
  242. package/dist/data-display/Badge.js +6 -5
  243. package/dist/data-display/CardKit.js +10 -10
  244. package/dist/data-display/Carousel.js +8 -7
  245. package/dist/data-display/Chart.js +8 -7
  246. package/dist/data-display/DataGrid.js +4 -3
  247. package/dist/data-display/DataViews.js +54 -53
  248. package/dist/data-display/EmptyState.js +2 -2
  249. package/dist/data-display/FleetMap.js +13 -12
  250. package/dist/data-display/InteractiveTooltip.js +2 -2
  251. package/dist/data-display/Lightbox.js +2 -2
  252. package/dist/data-display/MapPreview.js +3 -3
  253. package/dist/data-display/SectionOnboarding.js +3 -3
  254. package/dist/data-display/Sheet.js +5 -4
  255. package/dist/data-display/Table.js +4 -3
  256. package/dist/feedback/ConfirmAction.js +6 -6
  257. package/dist/feedback/Dialog.js +2 -2
  258. package/dist/feedback/StackedModal.js +6 -6
  259. package/dist/form/AddressAutocomplete.js +1 -1
  260. package/dist/form/Autocomplete.js +3 -3
  261. package/dist/form/CategorySelect.js +6 -6
  262. package/dist/form/Checkbox.js +2 -2
  263. package/dist/form/Command.js +5 -4
  264. package/dist/form/DateRangePicker.js +2 -2
  265. package/dist/form/Label.js +5 -4
  266. package/dist/form/Menubar.js +7 -6
  267. package/dist/form/UploadButton.js +2 -2
  268. package/dist/form/total-form.js +9 -9
  269. package/dist/icons.js +6 -5
  270. package/dist/layout/Box.js +6 -5
  271. package/dist/layout/ContentToolbar.js +3 -3
  272. package/dist/layout/ScrollArea.js +2 -2
  273. package/dist/layout/SettingCard.js +15 -14
  274. package/dist/layout/SettingsLayout.js +4 -4
  275. package/dist/layout/Stack.js +7 -6
  276. package/dist/navigation/AppHeader.js +9 -8
  277. package/dist/navigation/CommandPalette.js +2 -2
  278. package/dist/navigation/NavigationMenu.js +5 -5
  279. package/dist/provider.js +6 -5
  280. package/dist/tokens.js +8 -2
  281. package/dist/types/components/form/Autocomplete/useAutocomplete.d.ts.map +1 -1
  282. package/dist/types/components/layout/SettingsLayout/SettingsSectionChips.scroll.d.ts.map +1 -1
  283. package/dist/types/components/utility/WorkflowStep/WorkflowStep.d.ts.map +1 -1
  284. package/dist/types/components/utility/WorkflowStep/WorkflowStep.helpers.d.ts +15 -0
  285. package/dist/types/components/utility/WorkflowStep/WorkflowStep.helpers.d.ts.map +1 -1
  286. package/dist/types/components/utility/WorkflowStep/WorkflowStep.parts.d.ts +7 -1
  287. package/dist/types/components/utility/WorkflowStep/WorkflowStep.parts.d.ts.map +1 -1
  288. package/dist/types/components/utility/WorkflowStep/WorkflowStep.types.d.ts +10 -0
  289. package/dist/types/components/utility/WorkflowStep/WorkflowStep.types.d.ts.map +1 -1
  290. package/dist/types/components/utility/WorkflowStep/WorkflowStepRow.d.ts.map +1 -1
  291. package/dist/types/provider/mui-bridge.d.ts.map +1 -1
  292. package/dist/types/tokens/density-overrides.d.ts +6 -0
  293. package/dist/types/tokens/density-overrides.d.ts.map +1 -0
  294. package/dist/types/tokens/density.d.ts +9 -6
  295. package/dist/types/tokens/density.d.ts.map +1 -1
  296. package/dist/types/tokens/scales.d.ts +1 -0
  297. package/dist/types/tokens/scales.d.ts.map +1 -1
  298. package/dist/utility/InfiniteScroll.js +2 -2
  299. package/dist/utility/WorkflowStep.js +7 -6
  300. package/package.json +1 -1
  301. package/src/components/form/Autocomplete/useAutocomplete.ts +17 -0
  302. package/src/components/layout/SettingsLayout/SettingsSectionChips.scroll.ts +52 -16
  303. package/src/components/utility/WorkflowStep/WorkflowStep.helpers.ts +25 -0
  304. package/src/components/utility/WorkflowStep/WorkflowStep.parts.tsx +46 -49
  305. package/src/components/utility/WorkflowStep/WorkflowStep.tsx +5 -3
  306. package/src/components/utility/WorkflowStep/WorkflowStep.types.ts +10 -0
  307. package/src/components/utility/WorkflowStep/WorkflowStepRow.tsx +1 -0
  308. package/src/provider/mui-bridge.ts +9 -4
  309. package/src/tokens/density-overrides.ts +177 -0
  310. package/src/tokens/density.ts +15 -7
  311. package/src/tokens/scales.ts +4 -0
  312. package/dist/chunk-652PYSML.js.map +0 -1
  313. package/dist/chunk-BR2T72JI.js.map +0 -1
  314. package/dist/chunk-DJKVSUXH.js.map +0 -1
  315. package/dist/chunk-GT2RCOHM.js.map +0 -1
  316. package/dist/chunk-KJID4PRD.js.map +0 -1
  317. package/dist/chunk-Y2C2S4R7.js.map +0 -1
  318. /package/dist/{chunk-442FSG7G.js.map → chunk-3I77A65F.js.map} +0 -0
  319. /package/dist/{chunk-R2FUQV24.js.map → chunk-4MGUBSAL.js.map} +0 -0
  320. /package/dist/{chunk-YIWVHEPW.js.map → chunk-4T5LD2NV.js.map} +0 -0
  321. /package/dist/{chunk-4CHYMTBT.js.map → chunk-4WCDMCIS.js.map} +0 -0
  322. /package/dist/{chunk-5KGABAQB.js.map → chunk-5752357K.js.map} +0 -0
  323. /package/dist/{chunk-JSGVYOMN.js.map → chunk-5MW7OYBM.js.map} +0 -0
  324. /package/dist/{chunk-RWRPF24F.js.map → chunk-5OS5AMC2.js.map} +0 -0
  325. /package/dist/{chunk-I6MVJWUO.js.map → chunk-6B3QXFF5.js.map} +0 -0
  326. /package/dist/{chunk-MLUUF7OZ.js.map → chunk-6B4UTB4O.js.map} +0 -0
  327. /package/dist/{chunk-FBUCXTA4.js.map → chunk-6DMUVVON.js.map} +0 -0
  328. /package/dist/{chunk-G7RYAWPZ.js.map → chunk-6HTCCWUM.js.map} +0 -0
  329. /package/dist/{chunk-77BKKPCI.js.map → chunk-6KLDYVRY.js.map} +0 -0
  330. /package/dist/{chunk-6Z6PUG4C.js.map → chunk-6LYRFS5S.js.map} +0 -0
  331. /package/dist/{chunk-K4A3JDYQ.js.map → chunk-6ZWOVUNB.js.map} +0 -0
  332. /package/dist/{chunk-3RUCLKAK.js.map → chunk-7HZTYK7U.js.map} +0 -0
  333. /package/dist/{chunk-BKZERHNC.js.map → chunk-7XDET7PL.js.map} +0 -0
  334. /package/dist/{chunk-OD3L6GX5.js.map → chunk-A7OQBAR7.js.map} +0 -0
  335. /package/dist/{chunk-2MLS6KU4.js.map → chunk-AEKHSORY.js.map} +0 -0
  336. /package/dist/{chunk-5DAVXZPY.js.map → chunk-B2WBDMHE.js.map} +0 -0
  337. /package/dist/{chunk-GZT7MLLO.js.map → chunk-B2ZITMYG.js.map} +0 -0
  338. /package/dist/{chunk-54HTXJJ2.js.map → chunk-BHE44AQE.js.map} +0 -0
  339. /package/dist/{chunk-TBMGYQJF.js.map → chunk-BKBELIUR.js.map} +0 -0
  340. /package/dist/{chunk-OOB3YWPX.js.map → chunk-BZFRBG2H.js.map} +0 -0
  341. /package/dist/{chunk-PICOOZLX.js.map → chunk-C5RTSOXD.js.map} +0 -0
  342. /package/dist/{chunk-GO6XDMBB.js.map → chunk-CEJTGG6J.js.map} +0 -0
  343. /package/dist/{chunk-ZGWEFOW6.js.map → chunk-CKAVTWXP.js.map} +0 -0
  344. /package/dist/{chunk-ANYOSBNA.js.map → chunk-CSXK7LH7.js.map} +0 -0
  345. /package/dist/{chunk-U6DOF5CR.js.map → chunk-CU7ELD43.js.map} +0 -0
  346. /package/dist/{chunk-XO4ZUHVH.js.map → chunk-CYPBF3BI.js.map} +0 -0
  347. /package/dist/{chunk-EO5IEWFI.js.map → chunk-DE6A46AE.js.map} +0 -0
  348. /package/dist/{chunk-JMEPGXJG.js.map → chunk-DHW5UMUG.js.map} +0 -0
  349. /package/dist/{chunk-3EPA2A4M.js.map → chunk-DJIFXJ4C.js.map} +0 -0
  350. /package/dist/{chunk-CM2Q7IH3.js.map → chunk-DTLKF4AX.js.map} +0 -0
  351. /package/dist/{chunk-C6JUGWAU.js.map → chunk-DYCTIOER.js.map} +0 -0
  352. /package/dist/{chunk-LCWGNDTH.js.map → chunk-EKBUM7HK.js.map} +0 -0
  353. /package/dist/{chunk-NYT3UVOH.js.map → chunk-EOEYOPOS.js.map} +0 -0
  354. /package/dist/{chunk-7LILFS72.js.map → chunk-EOKPFMJD.js.map} +0 -0
  355. /package/dist/{chunk-4PRZLII7.js.map → chunk-FOM7OMJR.js.map} +0 -0
  356. /package/dist/{chunk-QSNLIWEB.js.map → chunk-FTV5R2UZ.js.map} +0 -0
  357. /package/dist/{chunk-NDHDBOUH.js.map → chunk-FWPFCK4D.js.map} +0 -0
  358. /package/dist/{chunk-ON4TRXCM.js.map → chunk-GHJ2FIJO.js.map} +0 -0
  359. /package/dist/{chunk-GANW7FXQ.js.map → chunk-GKNMKPR6.js.map} +0 -0
  360. /package/dist/{chunk-LGCRL7DK.js.map → chunk-GP4BJI3F.js.map} +0 -0
  361. /package/dist/{chunk-4MKVGSHX.js.map → chunk-HN3PZTUK.js.map} +0 -0
  362. /package/dist/{chunk-HBP2OU4Q.js.map → chunk-HNFZLXZI.js.map} +0 -0
  363. /package/dist/{chunk-5FHPZOYK.js.map → chunk-HOIHO2YQ.js.map} +0 -0
  364. /package/dist/{chunk-3AOOI2NR.js.map → chunk-HR7YTBR7.js.map} +0 -0
  365. /package/dist/{chunk-PGV2FLE3.js.map → chunk-IG26N6J2.js.map} +0 -0
  366. /package/dist/{chunk-G2WERTWZ.js.map → chunk-IGGXKT5B.js.map} +0 -0
  367. /package/dist/{chunk-XLXMJ6X2.js.map → chunk-IO2X6DVH.js.map} +0 -0
  368. /package/dist/{chunk-3CLBGHTL.js.map → chunk-ITBUKGG3.js.map} +0 -0
  369. /package/dist/{chunk-6IRJAIS4.js.map → chunk-IXWIJCS3.js.map} +0 -0
  370. /package/dist/{chunk-TMW7RBW7.js.map → chunk-J6TIK47Z.js.map} +0 -0
  371. /package/dist/{chunk-G4TKMUOL.js.map → chunk-JDEKR77O.js.map} +0 -0
  372. /package/dist/{chunk-ITFFA3H2.js.map → chunk-JYLBVHG2.js.map} +0 -0
  373. /package/dist/{chunk-G7XHJPLO.js.map → chunk-JZ7ZRZTF.js.map} +0 -0
  374. /package/dist/{chunk-YTVXT5TD.js.map → chunk-K5CCQBNN.js.map} +0 -0
  375. /package/dist/{chunk-AOFI3GDS.js.map → chunk-KMC6WP66.js.map} +0 -0
  376. /package/dist/{chunk-K62RHTFB.js.map → chunk-KNAWZM7F.js.map} +0 -0
  377. /package/dist/{chunk-4Z2HIHA5.js.map → chunk-KRA75CKC.js.map} +0 -0
  378. /package/dist/{chunk-RHKT2XW2.js.map → chunk-KUKY5GEX.js.map} +0 -0
  379. /package/dist/{chunk-HUAQQ5ZL.js.map → chunk-LHHV6NXO.js.map} +0 -0
  380. /package/dist/{chunk-BJGUDLWZ.js.map → chunk-LRFXCZB4.js.map} +0 -0
  381. /package/dist/{chunk-U6W2RY3Z.js.map → chunk-MLQYIJTO.js.map} +0 -0
  382. /package/dist/{chunk-GPHURU2K.js.map → chunk-MSAAOQAD.js.map} +0 -0
  383. /package/dist/{chunk-3MJHHPRW.js.map → chunk-MVR4GURP.js.map} +0 -0
  384. /package/dist/{chunk-PRLYYKMG.js.map → chunk-MW7S7WZM.js.map} +0 -0
  385. /package/dist/{chunk-ERY6D2OV.js.map → chunk-MWPXKZ7O.js.map} +0 -0
  386. /package/dist/{chunk-ZUME25DS.js.map → chunk-NM2FLCPV.js.map} +0 -0
  387. /package/dist/{chunk-UP7SSTCZ.js.map → chunk-OAVRXSAS.js.map} +0 -0
  388. /package/dist/{chunk-VYA4QWQL.js.map → chunk-PJVZY2SA.js.map} +0 -0
  389. /package/dist/{chunk-SDBBJ6FG.js.map → chunk-PUYJVQ7X.js.map} +0 -0
  390. /package/dist/{chunk-IUD6N52Q.js.map → chunk-PXGURBIU.js.map} +0 -0
  391. /package/dist/{chunk-PNDYAIKM.js.map → chunk-Q5J37WOE.js.map} +0 -0
  392. /package/dist/{chunk-DCT2PKMQ.js.map → chunk-QGB3DOMV.js.map} +0 -0
  393. /package/dist/{chunk-YGYQC7MT.js.map → chunk-QOLIBVGS.js.map} +0 -0
  394. /package/dist/{chunk-TDXEO2UI.js.map → chunk-RJ35IXFD.js.map} +0 -0
  395. /package/dist/{chunk-P6Q2O3TU.js.map → chunk-RNVR3RGV.js.map} +0 -0
  396. /package/dist/{chunk-SNW5MJ6I.js.map → chunk-RPKWTFJ2.js.map} +0 -0
  397. /package/dist/{chunk-NPPJ3IJP.js.map → chunk-RRAWJQIO.js.map} +0 -0
  398. /package/dist/{chunk-H3GYVR7S.js.map → chunk-SM4MT4YC.js.map} +0 -0
  399. /package/dist/{chunk-5B7BTLN4.js.map → chunk-SOCZLOPJ.js.map} +0 -0
  400. /package/dist/{chunk-Z4O3F6KU.js.map → chunk-U4QUDFPJ.js.map} +0 -0
  401. /package/dist/{chunk-KWU62UPM.js.map → chunk-UHGQ74E3.js.map} +0 -0
  402. /package/dist/{chunk-Z6LTEJ7F.js.map → chunk-VKFZQSQC.js.map} +0 -0
  403. /package/dist/{chunk-MBNXCCRG.js.map → chunk-VQUPB7F7.js.map} +0 -0
  404. /package/dist/{chunk-CNR5RFKC.js.map → chunk-VVFV4MXS.js.map} +0 -0
  405. /package/dist/{chunk-ALOUJ3CE.js.map → chunk-WQ3KTELX.js.map} +0 -0
  406. /package/dist/{chunk-FY6PONLA.js.map → chunk-WSYPM3SR.js.map} +0 -0
  407. /package/dist/{chunk-QMELMQPA.js.map → chunk-X4VWYWFK.js.map} +0 -0
  408. /package/dist/{chunk-5PJM772Y.js.map → chunk-XLQYOBHP.js.map} +0 -0
  409. /package/dist/{chunk-TCMH3FXD.js.map → chunk-XTDJ2D5A.js.map} +0 -0
  410. /package/dist/{chunk-F5GXWK6B.js.map → chunk-Y2CMWGIU.js.map} +0 -0
  411. /package/dist/{chunk-SJGYMI6Y.js.map → chunk-Y4ET3NRC.js.map} +0 -0
  412. /package/dist/{chunk-FIO55AKI.js.map → chunk-YCHOWWRE.js.map} +0 -0
  413. /package/dist/{chunk-MM5XSAVE.js.map → chunk-YDIRPKYI.js.map} +0 -0
  414. /package/dist/{chunk-44Z72DDM.js.map → chunk-YF3VD2KD.js.map} +0 -0
  415. /package/dist/{chunk-Z4DKVLYG.js.map → chunk-Z3HSRNJT.js.map} +0 -0
  416. /package/dist/{chunk-5PTCT3LF.js.map → chunk-ZQ7IESR7.js.map} +0 -0
@@ -0,0 +1,177 @@
1
+ import { chipClasses } from '@mui/material/Chip/index.js';
2
+ import type { Components, CSSObject, Theme } from '@mui/material/styles/index.js';
3
+
4
+ import { rem } from './relative';
5
+
6
+ /** The `ownerState` fields `MuiChip`'s two styled slots (root, label) both receive. */
7
+ interface ChipOwnerStateForOverrides {
8
+ variant?: 'filled' | 'outlined';
9
+ size?: 'small' | 'medium';
10
+ }
11
+
12
+ /**
13
+ * ICONBUTTON / CHIP GEOMETRY, DENSITY-AWARE (FUT-2766).
14
+ *
15
+ * Both are MUI's own components, unwrapped: `@12-apps/ui` has no
16
+ * `components/*` subpath for `IconButton`, and its `Chip` wrapper
17
+ * (`components/data-display/Chip`) hands the drawing to `MuiChip` and adds
18
+ * only hover/selection/transition `sx` — no geometry of its own (unlike
19
+ * `Button`, which already draws every dimension through `rem()`,
20
+ * `components/form/Button/Button.styles.ts`). So both draw MUI's OWN fixed-px
21
+ * padding/height, verified against the installed `@mui/material@6.5.0` source:
22
+ *
23
+ * - `IconButton` (`node_modules/@mui/material/IconButton/IconButton.js`):
24
+ * `padding: 8` on the root (medium, the default), `padding: 5` at
25
+ * `size="small"`, `padding: 12` at `size="large"`. The icon's own `fontSize`
26
+ * is already relative (`pxToRem(18/24/28)`) — only `padding` was the gap.
27
+ * - `Chip` (`node_modules/@mui/material/Chip/Chip.js`): `height: 32` on the
28
+ * root (medium, the default), `height: 24` at `size="small"`. The label's
29
+ * own side padding is a SEPARATE slot (`name: 'MuiChip', slot: 'Label'`,
30
+ * override key `label`/`labelSmall`) at `paddingLeft`/`paddingRight: 12`
31
+ * default, `8` at `size="small"` — restated in this package's own
32
+ * `Chip.metrics.ts` (`CHIP_SIZES`), which both renderers already read.
33
+ *
34
+ * Neither dimension moved when `theme.typography.fontSize` changed (they are
35
+ * not written through `pxToRem`), so at `density: 'compact'` an
36
+ * `IconButton`/`Chip` next to a now-smaller `Button` looked unchanged — the
37
+ * visual regression FUT-2764 exists to fix. `rem(theme, px)` is the same
38
+ * helper `Button.styles.ts` already uses, so `padding`/`height` move exactly
39
+ * as far as `theme.typography.fontSize`'s coefficient does, and are
40
+ * geometry-neutral at `density: 'normal'`: `rem(theme, 8)` at the unchanged
41
+ * `fontSize: 14` renders to the same computed px as the literal `8` it
42
+ * replaces.
43
+ *
44
+ * **The OUTLINED chip's own label padding (`11`/`7`, one px tighter than
45
+ * filled's `12`/`8`) is a SEPARATE number this file must not clobber** — a
46
+ * bug an earlier revision of this file had (a `styleOverrides.label`/
47
+ * `labelSmall` of `12`/`8` unconditionally wins for EVERY variant, because
48
+ * `ChipLabel`'s own `overridesResolver` (`Chip.js`) returns
49
+ * `[styles.label, styles[label${size}]]` with no variant check at all, and
50
+ * `@mui/system`'s `createStyled` composes `styleThemeOverrides` AFTER the
51
+ * slot's own base styles/variants — so a theme `styleOverrides.label` always
52
+ * outranks `ChipLabel`'s own baked-in `{ props: { variant: 'outlined' },
53
+ * style: { paddingLeft: 11, ... } }`, at ANY density, not just a scaled one).
54
+ * Fixed by putting the outlined fix on the ROOT slot instead, as a nested
55
+ * `.MuiChip-label` selector inside `styleOverrides.root` itself, keyed on
56
+ * `ownerState.variant`/`.size` — proven correct two ways: (1) a probe render
57
+ * confirmed the naive `components.MuiChip.variants` route CANNOT reach the
58
+ * label slot at all — `createStyled`'s `skipVariantsResolver` defaults to
59
+ * `true` for every slot but `'Root'`, so a theme-level `variants` entry is
60
+ * simply never evaluated for `ChipLabel`, proven by rendering an outlined
61
+ * Chip against a `components.MuiChip.variants` entry set to an absurd
62
+ * `999px` and reading `.MuiChip-label`'s OWN computed style: still `11px`,
63
+ * untouched — while the SAME entry DOES leak onto `.MuiChip-root` (`999px`),
64
+ * confirming theme `variants` is a ROOT-slot-only mechanism for this
65
+ * component; (2) a nested `.MuiChip-label` selector written from the ROOT
66
+ * slot is a HIGHER-specificity rule (two classes, `0,2,0`) than the label's
67
+ * own single-class rule (`0,1,0`), so it wins regardless of source order —
68
+ * the same technique `ChipRoot`'s OWN style already uses for its avatar/
69
+ * icon/delete-icon sub-parts (`& .${chipClasses.avatar}`, etc., in
70
+ * `Chip.js`), and read through the SAME `chipClasses` MUI's own `Chip.js`
71
+ * generates the real DOM class from, not a hand-typed copy of it.
72
+ *
73
+ * **That same higher specificity also outranks a HOST's own theming.** A
74
+ * host writing `theme.components.MuiChip.styleOverrides.label` for its own
75
+ * reasons (`0,1,0`) does not win against the outlined rule here (`0,2,0`) —
76
+ * not a bug specific to this file, `ChipLabel`'s OWN baked-in outlined
77
+ * variant already outranked a plain `styleOverrides.label` the same way,
78
+ * before this file existed. A host that needs to change OUTLINED label
79
+ * padding specifically cannot do it through `styleOverrides.label`/
80
+ * `labelSmall` at all; it reaches it through `sx` (a per-instance override,
81
+ * highest specificity of all) or its OWN `MuiChip.styleOverrides.root`
82
+ * function written out in full — `mergeMuiComponents` replaces `root`
83
+ * WHOLESALE when both sides set it (see `./density.ts`'s own doc comment),
84
+ * so a host adding to it must restate `chipRootHeight`'s own height logic
85
+ * alongside its outlined-label change, not merely add a sibling key.
86
+ *
87
+ * The avatar/icon/delete-icon sub-slots (margins, sizes) and IconButton's
88
+ * `edge="start"`/`"end"` negative margins are DELIBERATELY untouched by this
89
+ * file — real override keys exist, but none is in the ticket's Done-when nor
90
+ * exercised by a call site this initiative is chasing, so they stay MUI's
91
+ * own literals at every density (including `compact`/`comfortable` — they do
92
+ * NOT scale here; a future ticket that needs them scaled adds its own
93
+ * override, the way `field-height.ts`'s siblings each own one slot).
94
+ *
95
+ * A host that adopts `iconButtonDensityOverrides`/`chipDensityOverrides`
96
+ * standalone (the `@12-apps/ui/tokens` export, no density channel involved)
97
+ * sees the SAME scaling from its own `typography.fontSize` alone — `rem()`
98
+ * only ever reads that one theme number, so a theme with a non-default
99
+ * `fontSize` (set directly, with no `density` in the picture at all) moves
100
+ * these numbers exactly as it moves everything else written through `rem()`.
101
+ *
102
+ * Each slot below is a MODULE-LEVEL function, not a closure built fresh inside
103
+ * `iconButtonDensityOverrides`/`chipDensityOverrides` — the same reason
104
+ * `field-height.ts`'s `restingEdge` is one: two themes built from the same
105
+ * options (the `muiThemeOptionsFrom` and `densityThemeOptions` paths, in
106
+ * particular) must compare equal, and a fresh arrow function per call would
107
+ * make them differ on nothing but identity.
108
+ */
109
+
110
+ const iconButtonRootPadding = ({ theme }: { theme: Theme }): CSSObject => ({ padding: rem(theme, 8) });
111
+ const iconButtonSmallPadding = ({ theme }: { theme: Theme }): CSSObject => ({ padding: rem(theme, 5) });
112
+ const iconButtonLargePadding = ({ theme }: { theme: Theme }): CSSObject => ({ padding: rem(theme, 12) });
113
+
114
+ /** `MuiIconButton`'s own padding, at every size MUI has. */
115
+ export function iconButtonDensityOverrides(): Components<Theme> {
116
+ return {
117
+ MuiIconButton: {
118
+ styleOverrides: {
119
+ root: iconButtonRootPadding,
120
+ sizeSmall: iconButtonSmallPadding,
121
+ sizeLarge: iconButtonLargePadding,
122
+ },
123
+ },
124
+ };
125
+ }
126
+
127
+ /** MUI's own outlined-label paddings (`ChipLabel`'s baked-in `variants`, `Chip.js`). */
128
+ const CHIP_OUTLINED_LABEL_PADDING = { medium: 11, small: 7 } as const;
129
+
130
+ const chipRootHeight = ({
131
+ theme,
132
+ ownerState,
133
+ }: {
134
+ theme: Theme;
135
+ ownerState?: ChipOwnerStateForOverrides;
136
+ }): CSSObject => {
137
+ const style: CSSObject = { height: rem(theme, 32) };
138
+ if (ownerState?.variant === 'outlined') {
139
+ const px = CHIP_OUTLINED_LABEL_PADDING[ownerState.size === 'small' ? 'small' : 'medium'];
140
+ // Higher CSS specificity than `.MuiChip-label`'s own single-class rule
141
+ // (two classes vs one) — wins over `chipLabelPadding`/`chipLabelSmallPadding`
142
+ // below regardless of stylesheet insertion order. See the module doc
143
+ // comment for why this must live here and not on the label slot itself.
144
+ // `chipClasses.label`, not a hand-typed `.MuiChip-label` string — the same
145
+ // module `Chip.js`'s own root style reads for its avatar/icon/delete-icon
146
+ // selectors, so this tracks whatever `Chip.js` itself puts on the label
147
+ // element rather than a separately-maintained copy of it. A host that
148
+ // calls `ClassNameGenerator.configure` before any `MuiChip` module loads
149
+ // renames the real class; a literal string would silently stop matching
150
+ // it, `chipClasses.label` cannot.
151
+ style[`& .${chipClasses.label}`] = { paddingLeft: rem(theme, px), paddingRight: rem(theme, px) };
152
+ }
153
+ return style;
154
+ };
155
+ const chipSmallHeight = ({ theme }: { theme: Theme }): CSSObject => ({ height: rem(theme, 24) });
156
+ const chipLabelPadding = ({ theme }: { theme: Theme }): CSSObject => ({
157
+ paddingLeft: rem(theme, 12),
158
+ paddingRight: rem(theme, 12),
159
+ });
160
+ const chipLabelSmallPadding = ({ theme }: { theme: Theme }): CSSObject => ({
161
+ paddingLeft: rem(theme, 8),
162
+ paddingRight: rem(theme, 8),
163
+ });
164
+
165
+ /** `MuiChip`'s own height (root) and label side padding (label), at both sizes MUI has. */
166
+ export function chipDensityOverrides(): Components<Theme> {
167
+ return {
168
+ MuiChip: {
169
+ styleOverrides: {
170
+ root: chipRootHeight,
171
+ sizeSmall: chipSmallHeight,
172
+ label: chipLabelPadding,
173
+ labelSmall: chipLabelSmallPadding,
174
+ },
175
+ },
176
+ };
177
+ }
@@ -9,6 +9,7 @@ import {
9
9
  type DensityLevel,
10
10
  type ResolvedDensity,
11
11
  } from './density.core';
12
+ import { chipDensityOverrides, iconButtonDensityOverrides } from './density-overrides';
12
13
  import { fieldOverrides, mergeMuiComponents } from './field-height';
13
14
  import { DEFAULT_FIELD_RADIUS } from './field-radius.core';
14
15
 
@@ -70,12 +71,15 @@ export function useDensity(): ResolvedDensity {
70
71
  * agree on the type scale and disagree on the one number three components key
71
72
  * their own layout off.
72
73
  *
73
- * `components` is the matching MUI-native override (`fieldOverrides`) for a
74
- * HOST's own bare `TextField`/`Select`, mirroring `muiThemeOptionsFrom`'s own
75
- * `components: mergeMuiComponents(fieldOverrides(...))`. It carries ONLY the
76
- * field overrides this function knows about (`MuiOutlinedInput`'s `root`,
77
- * `input` and `notchedOutline`; `MuiInputLabel`'s `outlined`) — a host with
78
- * ITS OWN overrides for OTHER components merges them in with
74
+ * `components` is the matching MUI-native override (`fieldOverrides`, plus
75
+ * FUT-2766's `iconButtonDensityOverrides`/`chipDensityOverrides`) for a HOST's
76
+ * own bare `TextField`/`Select`/`IconButton`/`Chip`, mirroring
77
+ * `muiThemeOptionsFrom`'s own `components: mergeMuiComponents(...)`. It
78
+ * carries ONLY the overrides this function knows about (`MuiOutlinedInput`'s
79
+ * `root`, `input` and `notchedOutline`; `MuiInputLabel`'s `outlined`;
80
+ * `MuiIconButton`'s `root`/`sizeSmall`/`sizeLarge`; `MuiChip`'s
81
+ * `root`/`sizeSmall`/`label`/`labelSmall`) — a host with ITS OWN overrides for
82
+ * OTHER components merges them in with
79
83
  * `mergeMuiComponents(densityThemeOptions(density).components, hostOverrides)`,
80
84
  * which keeps a component only ONE side touches untouched. For a component
81
85
  * BOTH sides style, the merge is by INNER key (`root`/`input`/…): a key only
@@ -129,6 +133,10 @@ export function densityThemeOptions(
129
133
  typography: { fontSize: densityFontSize(factor) },
130
134
  spacing: densitySpacingUnit(factor),
131
135
  fieldHeight,
132
- components: mergeMuiComponents(fieldOverrides(fieldRadius, fieldHeight)),
136
+ components: mergeMuiComponents(
137
+ fieldOverrides(fieldRadius, fieldHeight),
138
+ iconButtonDensityOverrides(),
139
+ chipDensityOverrides(),
140
+ ),
133
141
  };
134
142
  }
@@ -49,6 +49,10 @@ export {
49
49
  resolveDensityFactor,
50
50
  useDensity,
51
51
  } from './density';
52
+ // The IconButton/Chip geometry overrides density threads through both
53
+ // consumption paths (FUT-2766) — exported standalone too, for a host that
54
+ // wants JUST these two components' overrides without the rest of density.
55
+ export { chipDensityOverrides, iconButtonDensityOverrides } from './density-overrides';
52
56
 
53
57
  export interface Accent {
54
58
  main: string;
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/provider/mui-bridge.ts"],"sourcesContent":["import type { PaletteColor, Theme, ThemeOptions } from '@mui/material/styles/index.js';\n\nimport { cssLengthToPx, cssTrackingToEm } from '../tokens/css-units';\nimport { densityFontSize, resolveDensityFactor } from '../tokens/density';\nimport { resolveFieldHeight } from '../tokens/field-height.core';\nimport { fieldOverrides, mergeMuiComponents } from '../tokens/field-height';\nimport { fieldRadius } from '../tokens/field-radius';\nimport { accentFor } from '../tokens/scales';\nimport {\n FONT_WEIGHTS,\n TYPE_SIZES,\n WEB_FONT_FAMILY,\n WEB_MONOSPACE_FONT_FAMILY,\n type UiHeadingStep,\n type UiPaletteColor,\n type UiTheme,\n} from '../tokens/theme';\nimport { HEADING_LEVELS, headingMetrics, type HeadingLevel } from '../tokens/typography';\n\n/**\n * THE TWO DIRECTIONS BETWEEN MUI'S THEME AND OURS. Web only.\n *\n * `uiThemeFromMui` is how a web component — or a shared style resolver such\n * as `box-layout.ts` — reads the host's MUI theme in the neutral shape the\n * native renderer reads natively. `muiThemeOptionsFrom` is the reverse, for\n * a host that has a `UiTheme` and no MUI theme yet: `UiProvider` on the web is\n * a MUI `ThemeProvider` fed by it.\n *\n * Both are field-by-field on purpose. A spread would carry MUI's extra keys\n * across and the native side would silently depend on one.\n */\n\nconst slot = (color: PaletteColor): UiPaletteColor => ({\n main: color.main,\n light: color.light,\n dark: color.dark,\n contrastText: color.contrastText,\n});\n\nfunction headingSteps(theme: Theme): Record<HeadingLevel, UiHeadingStep> {\n return Object.fromEntries(\n HEADING_LEVELS.map((level) => {\n const metrics = headingMetrics(theme, level);\n return [\n level,\n {\n fontSize: cssLengthToPx(metrics.fontSize, 16),\n lineHeight: metrics.lineHeight,\n letterSpacing: cssTrackingToEm(metrics.letterSpacing),\n normalWeight: metrics.normalWeight,\n },\n ];\n }),\n ) as Record<HeadingLevel, UiHeadingStep>;\n}\n\n/** The host's MUI theme in the shape the native renderer reads. */\nexport function uiThemeFromMui(theme: Theme): UiTheme {\n const { palette } = theme;\n const unit = cssLengthToPx(theme.spacing(1), 8);\n const md = cssLengthToPx(theme.shape.borderRadius, 4);\n\n return {\n mode: palette.mode,\n palette: {\n mode: palette.mode,\n primary: slot(palette.primary),\n secondary: slot(palette.secondary),\n success: slot(palette.success),\n warning: slot(palette.warning),\n info: slot(palette.info),\n danger: slot(palette.error),\n neutral: accentFor(theme, 'neutral'),\n text: {\n primary: palette.text.primary,\n secondary: palette.text.secondary,\n disabled: palette.text.disabled,\n },\n background: { default: palette.background.default, paper: palette.background.paper },\n divider: palette.divider,\n action: {\n active: palette.action.active,\n hover: palette.action.hover,\n selected: palette.action.selected,\n disabled: palette.action.disabled,\n disabledBackground: palette.action.disabledBackground,\n focus: palette.action.focus,\n },\n grey: {\n 50: palette.grey[50],\n 100: palette.grey[100],\n 200: palette.grey[200],\n 300: palette.grey[300],\n 400: palette.grey[400],\n 500: palette.grey[500],\n 600: palette.grey[600],\n 700: palette.grey[700],\n 800: palette.grey[800],\n 900: palette.grey[900],\n },\n },\n spacing: (units: number) => units * unit,\n spacingUnit: unit,\n radius: { sm: md / 2, md, lg: md * 2, xl: md * 4, full: 9999, field: fieldRadius(theme) },\n fieldHeight: resolveFieldHeight(theme.fieldHeight),\n // A bare MUI theme (never built through `createUiTheme`/`muiThemeOptionsFrom`)\n // carries no `theme.density` — read back as `'normal'`, factor `1`.\n density: theme.density ?? resolveDensityFactor(),\n typography: {\n fontFamily: theme.typography.fontFamily ?? WEB_FONT_FAMILY,\n monospaceFontFamily: WEB_MONOSPACE_FONT_FAMILY,\n sizes: TYPE_SIZES,\n weights: FONT_WEIGHTS,\n heading: headingSteps(theme),\n },\n zIndex: {\n appBar: theme.zIndex.appBar,\n drawer: theme.zIndex.drawer,\n modal: theme.zIndex.modal,\n snackbar: theme.zIndex.snackbar,\n tooltip: theme.zIndex.tooltip,\n },\n };\n}\n\n/** A `UiTheme` as the options MUI's `createTheme` builds the same palette from. */\nexport function muiThemeOptionsFrom(ui: UiTheme): ThemeOptions {\n const { palette } = ui;\n return {\n palette: {\n mode: palette.mode,\n primary: { ...palette.primary },\n secondary: { ...palette.secondary },\n success: { ...palette.success },\n warning: { ...palette.warning },\n info: { ...palette.info },\n error: { ...palette.danger },\n text: { ...palette.text },\n background: { ...palette.background },\n divider: palette.divider,\n action: { ...palette.action },\n grey: { ...palette.grey },\n },\n shape: { borderRadius: ui.radius.md },\n fieldRadius: ui.radius.field,\n fieldHeight: ui.fieldHeight,\n // Additive: children 2–4 (FUT-2766–2768) each add one more source here as\n // their own geometry overrides land — this PR wires the merge helper to\n // `fieldOverrides` alone, since no geometry override exists yet.\n components: mergeMuiComponents(fieldOverrides(ui.radius.field, ui.fieldHeight)),\n spacing: ui.spacingUnit,\n density: ui.density,\n typography: {\n fontFamily: ui.typography.fontFamily ?? WEB_FONT_FAMILY,\n // MUI multiplies every `pxToRem` size by `fontSize / 14` — the lever a\n // density mode moves (`./tokens/relative.ts`). `htmlFontSize` stays\n // untouched: that is a reader's own zoom/accessibility setting, not this.\n fontSize: densityFontSize(ui.density.factor),\n },\n zIndex: { ...ui.zIndex },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,IAAM,OAAO,CAAC,WAAyC;AAAA,EACrD,MAAM,MAAM;AAAA,EACZ,OAAO,MAAM;AAAA,EACb,MAAM,MAAM;AAAA,EACZ,cAAc,MAAM;AACtB;AAEA,SAAS,aAAa,OAAmD;AACvE,SAAO,OAAO;AAAA,IACZ,eAAe,IAAI,CAAC,UAAU;AAC5B,YAAM,UAAU,eAAe,OAAO,KAAK;AAC3C,aAAO;AAAA,QACL;AAAA,QACA;AAAA,UACE,UAAU,cAAc,QAAQ,UAAU,EAAE;AAAA,UAC5C,YAAY,QAAQ;AAAA,UACpB,eAAe,gBAAgB,QAAQ,aAAa;AAAA,UACpD,cAAc,QAAQ;AAAA,QACxB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAGO,SAAS,eAAe,OAAuB;AACpD,QAAM,EAAE,QAAQ,IAAI;AACpB,QAAM,OAAO,cAAc,MAAM,QAAQ,CAAC,GAAG,CAAC;AAC9C,QAAM,KAAK,cAAc,MAAM,MAAM,cAAc,CAAC;AAEpD,SAAO;AAAA,IACL,MAAM,QAAQ;AAAA,IACd,SAAS;AAAA,MACP,MAAM,QAAQ;AAAA,MACd,SAAS,KAAK,QAAQ,OAAO;AAAA,MAC7B,WAAW,KAAK,QAAQ,SAAS;AAAA,MACjC,SAAS,KAAK,QAAQ,OAAO;AAAA,MAC7B,SAAS,KAAK,QAAQ,OAAO;AAAA,MAC7B,MAAM,KAAK,QAAQ,IAAI;AAAA,MACvB,QAAQ,KAAK,QAAQ,KAAK;AAAA,MAC1B,SAAS,UAAU,OAAO,SAAS;AAAA,MACnC,MAAM;AAAA,QACJ,SAAS,QAAQ,KAAK;AAAA,QACtB,WAAW,QAAQ,KAAK;AAAA,QACxB,UAAU,QAAQ,KAAK;AAAA,MACzB;AAAA,MACA,YAAY,EAAE,SAAS,QAAQ,WAAW,SAAS,OAAO,QAAQ,WAAW,MAAM;AAAA,MACnF,SAAS,QAAQ;AAAA,MACjB,QAAQ;AAAA,QACN,QAAQ,QAAQ,OAAO;AAAA,QACvB,OAAO,QAAQ,OAAO;AAAA,QACtB,UAAU,QAAQ,OAAO;AAAA,QACzB,UAAU,QAAQ,OAAO;AAAA,QACzB,oBAAoB,QAAQ,OAAO;AAAA,QACnC,OAAO,QAAQ,OAAO;AAAA,MACxB;AAAA,MACA,MAAM;AAAA,QACJ,IAAI,QAAQ,KAAK,EAAE;AAAA,QACnB,KAAK,QAAQ,KAAK,GAAG;AAAA,QACrB,KAAK,QAAQ,KAAK,GAAG;AAAA,QACrB,KAAK,QAAQ,KAAK,GAAG;AAAA,QACrB,KAAK,QAAQ,KAAK,GAAG;AAAA,QACrB,KAAK,QAAQ,KAAK,GAAG;AAAA,QACrB,KAAK,QAAQ,KAAK,GAAG;AAAA,QACrB,KAAK,QAAQ,KAAK,GAAG;AAAA,QACrB,KAAK,QAAQ,KAAK,GAAG;AAAA,QACrB,KAAK,QAAQ,KAAK,GAAG;AAAA,MACvB;AAAA,IACF;AAAA,IACA,SAAS,CAAC,UAAkB,QAAQ;AAAA,IACpC,aAAa;AAAA,IACb,QAAQ,EAAE,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,IAAI,KAAK,GAAG,MAAM,MAAM,OAAO,YAAY,KAAK,EAAE;AAAA,IACxF,aAAa,mBAAmB,MAAM,WAAW;AAAA;AAAA;AAAA,IAGjD,SAAS,MAAM,WAAW,qBAAqB;AAAA,IAC/C,YAAY;AAAA,MACV,YAAY,MAAM,WAAW,cAAc;AAAA,MAC3C,qBAAqB;AAAA,MACrB,OAAO;AAAA,MACP,SAAS;AAAA,MACT,SAAS,aAAa,KAAK;AAAA,IAC7B;AAAA,IACA,QAAQ;AAAA,MACN,QAAQ,MAAM,OAAO;AAAA,MACrB,QAAQ,MAAM,OAAO;AAAA,MACrB,OAAO,MAAM,OAAO;AAAA,MACpB,UAAU,MAAM,OAAO;AAAA,MACvB,SAAS,MAAM,OAAO;AAAA,IACxB;AAAA,EACF;AACF;AAGO,SAAS,oBAAoB,IAA2B;AAC7D,QAAM,EAAE,QAAQ,IAAI;AACpB,SAAO;AAAA,IACL,SAAS;AAAA,MACP,MAAM,QAAQ;AAAA,MACd,SAAS,EAAE,GAAG,QAAQ,QAAQ;AAAA,MAC9B,WAAW,EAAE,GAAG,QAAQ,UAAU;AAAA,MAClC,SAAS,EAAE,GAAG,QAAQ,QAAQ;AAAA,MAC9B,SAAS,EAAE,GAAG,QAAQ,QAAQ;AAAA,MAC9B,MAAM,EAAE,GAAG,QAAQ,KAAK;AAAA,MACxB,OAAO,EAAE,GAAG,QAAQ,OAAO;AAAA,MAC3B,MAAM,EAAE,GAAG,QAAQ,KAAK;AAAA,MACxB,YAAY,EAAE,GAAG,QAAQ,WAAW;AAAA,MACpC,SAAS,QAAQ;AAAA,MACjB,QAAQ,EAAE,GAAG,QAAQ,OAAO;AAAA,MAC5B,MAAM,EAAE,GAAG,QAAQ,KAAK;AAAA,IAC1B;AAAA,IACA,OAAO,EAAE,cAAc,GAAG,OAAO,GAAG;AAAA,IACpC,aAAa,GAAG,OAAO;AAAA,IACvB,aAAa,GAAG;AAAA;AAAA;AAAA;AAAA,IAIhB,YAAY,mBAAmB,eAAe,GAAG,OAAO,OAAO,GAAG,WAAW,CAAC;AAAA,IAC9E,SAAS,GAAG;AAAA,IACZ,SAAS,GAAG;AAAA,IACZ,YAAY;AAAA,MACV,YAAY,GAAG,WAAW,cAAc;AAAA;AAAA;AAAA;AAAA,MAIxC,UAAU,gBAAgB,GAAG,QAAQ,MAAM;AAAA,IAC7C;AAAA,IACA,QAAQ,EAAE,GAAG,GAAG,OAAO;AAAA,EACzB;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/form/Autocomplete/useAutocomplete.ts"],"sourcesContent":["import { useEffect, useId, useRef, useState } from 'react';\n\nimport {\n defaultGetKey,\n defaultGetLabel,\n defaultGetSuggestionType,\n defaultGetUrl,\n defaultOpenLink,\n filterSuggestions,\n firstGhostSuggestion,\n type MatchMode,\n} from './Autocomplete.helpers';\nimport { handleAutocompleteKey, type KeyContext } from './Autocomplete.keys';\nimport type { AutocompleteProps } from './Autocomplete.types';\n\ntype Setter<V> = React.Dispatch<React.SetStateAction<V>>;\n\n/** All mutable state + refs for one Autocomplete instance. */\ninterface AutocompleteState<T> {\n open: boolean;\n setOpen: Setter<boolean>;\n activeIndex: number;\n setActiveIndex: Setter<number>;\n ghost: string;\n setGhost: Setter<string>;\n inputValue: string;\n setInputValue: Setter<string>;\n composition: boolean;\n setComposition: Setter<boolean>;\n filteredSuggestions: T[];\n setFilteredSuggestions: Setter<T[]>;\n isInputFocused: boolean;\n setIsInputFocused: Setter<boolean>;\n justCompletedGhost: boolean;\n setJustCompletedGhost: Setter<boolean>;\n userClosedDropdown: boolean;\n setUserClosedDropdown: Setter<boolean>;\n /**\n * Mirrors `userClosedDropdown`, set synchronously wherever the state is\n * (see {@link setDeliberateClose}). An effect scheduled by one render and\n * flushed after a LATER render has already changed this flag reads a\n * stale, closed-over `userClosedDropdown` — but `.current` on a ref is\n * dereferenced live, so it always reflects the latest write regardless of\n * which render's closure is doing the reading (FUT-2780).\n */\n userClosedDropdownRef: React.RefObject<boolean>;\n inputRef: React.RefObject<HTMLInputElement | null>;\n listRef: React.RefObject<HTMLUListElement | null>;\n debounceRef: React.RefObject<number | undefined>;\n}\n\nfunction useAutocompleteState<T>(value: string, suggestions: T[]): AutocompleteState<T> {\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState(-1);\n const [ghost, setGhost] = useState('');\n const [inputValue, setInputValue] = useState(value);\n const [composition, setComposition] = useState(false);\n const [filteredSuggestions, setFilteredSuggestions] = useState<T[]>(suggestions);\n const [isInputFocused, setIsInputFocused] = useState(false);\n const [justCompletedGhost, setJustCompletedGhost] = useState(false);\n const [userClosedDropdown, setUserClosedDropdown] = useState(false);\n const userClosedDropdownRef = useRef(false);\n const inputRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLUListElement | null>(null);\n const debounceRef = useRef<number | undefined>(undefined);\n return {\n open, setOpen, activeIndex, setActiveIndex, ghost, setGhost, inputValue, setInputValue,\n composition, setComposition, filteredSuggestions, setFilteredSuggestions, isInputFocused,\n setIsInputFocused, justCompletedGhost, setJustCompletedGhost, userClosedDropdown,\n setUserClosedDropdown, userClosedDropdownRef, inputRef, listRef, debounceRef,\n };\n}\n\n/**\n * Set the \"this close was deliberate\" flag in both the ref effects read\n * synchronously (live, even from a stale closure) and the state the rest of\n * the component reads for render — every call site that touches\n * `userClosedDropdown` goes through this so the two never drift (FUT-2780).\n */\nfunction setDeliberateClose<T>(s: AutocompleteState<T>, closed: boolean): void {\n s.userClosedDropdownRef.current = closed;\n s.setUserClosedDropdown(closed);\n}\n\n// ---- effects (one tiny hook each; explicit params keep deps complete) --------\n\nfunction useValueSync(value: string, setInputValue: Setter<string>): void {\n useEffect(() => setInputValue(value), [value, setInputValue]);\n}\n\nfunction useDebounceCleanup(debounceRef: React.RefObject<number | undefined>): void {\n useEffect(\n () => () => {\n if (debounceRef.current) window.clearTimeout(debounceRef.current);\n },\n [debounceRef],\n );\n}\n\nfunction useScrollActiveIntoView(\n activeIndex: number,\n optionIdPrefix: string,\n listRef: React.RefObject<HTMLUListElement | null>,\n): void {\n useEffect(() => {\n if (activeIndex < 0 || !listRef.current) return;\n document\n .getElementById(`${optionIdPrefix}-${activeIndex}`)\n ?.scrollIntoView({ block: 'nearest' });\n }, [activeIndex, optionIdPrefix, listRef]);\n}\n\nfunction useGhostFlagReset(justCompletedGhost: boolean, setJustCompletedGhost: Setter<boolean>): void {\n useEffect(() => {\n if (!justCompletedGhost) return;\n const timer = setTimeout(() => setJustCompletedGhost(false), 50);\n return () => clearTimeout(timer);\n }, [justCompletedGhost, setJustCompletedGhost]);\n}\n\nfunction useLoadingOpen(\n isLoading: boolean,\n inputValue: string,\n disabled: boolean,\n userClosedDropdownRef: React.RefObject<boolean>,\n setOpen: Setter<boolean>,\n setActiveIndex: Setter<number>,\n): void {\n useEffect(() => {\n if (isLoading && inputValue.trim().length > 0 && !disabled && !userClosedDropdownRef.current) setOpen(true);\n if (disabled) {\n setOpen(false);\n setActiveIndex(-1);\n }\n }, [isLoading, inputValue, disabled, userClosedDropdownRef, setOpen, setActiveIndex]);\n}\n\n/** Inputs to the auto-open check, all primitive/stable so effect deps stay complete. */\ninterface AutoOpenArgs {\n inputValue: string;\n isInputFocused: boolean;\n composition: boolean;\n justCompletedGhost: boolean;\n userClosedDropdownRef: React.RefObject<boolean>;\n activeIndex: number;\n setOpen: Setter<boolean>;\n setActiveIndex: Setter<number>;\n}\n\n/** Auto-open the dropdown once local filtering has a fresh result set. */\nfunction maybeAutoOpen(a: AutoOpenArgs, hasResults: boolean): void {\n const canAutoOpen =\n a.inputValue.trim() &&\n a.isInputFocused &&\n !a.composition &&\n !a.justCompletedGhost &&\n !a.userClosedDropdownRef.current;\n if (!canAutoOpen) return;\n a.setOpen(true);\n if (hasResults && a.activeIndex === -1) a.setActiveIndex(0);\n}\n\nfunction useLocalFilter<T>(p: AutocompleteProps<T>, s: AutocompleteState<T>): void {\n const propSuggestions = p.suggestions;\n const getLabel = p.getLabel ?? defaultGetLabel;\n const matchMode: MatchMode = p.matchMode ?? 'contains';\n const async = Boolean(p.async);\n const {\n inputValue, isInputFocused, composition, justCompletedGhost, userClosedDropdown, activeIndex,\n setFilteredSuggestions, setOpen, setActiveIndex, userClosedDropdownRef,\n } = s;\n useEffect(() => {\n const suggestions = propSuggestions ?? [];\n if (async || !inputValue) {\n setFilteredSuggestions(suggestions);\n return;\n }\n const filtered = filterSuggestions(suggestions, inputValue, matchMode, getLabel);\n setFilteredSuggestions(filtered);\n maybeAutoOpen(\n { inputValue, isInputFocused, composition, justCompletedGhost, userClosedDropdownRef, activeIndex, setOpen, setActiveIndex },\n filtered.length > 0,\n );\n // `userClosedDropdown` (state) stays a dependency so this effect still\n // reruns on every change of it, same as before — only the VALUE read\n // inside `maybeAutoOpen` moved to the ref (see `userClosedDropdownRef`'s\n // doc comment).\n }, [\n propSuggestions, inputValue, async, getLabel, matchMode, isInputFocused, composition,\n justCompletedGhost, userClosedDropdown, activeIndex, setFilteredSuggestions, setOpen, setActiveIndex,\n userClosedDropdownRef,\n ]);\n}\n\nfunction useGhostText<T>(p: AutocompleteProps<T>, s: AutocompleteState<T>): void {\n const getLabel = p.getLabel ?? defaultGetLabel;\n const getType = p.getSuggestionType ?? defaultGetSuggestionType;\n const showGhost = p.showGhostText ?? true;\n const { inputValue, filteredSuggestions, isInputFocused, composition, setGhost } = s;\n useEffect(() => {\n if (!inputValue || !isInputFocused || composition || !showGhost) {\n setGhost('');\n return;\n }\n const first = firstGhostSuggestion(filteredSuggestions, inputValue, getLabel, getType);\n setGhost(first ? getLabel(first).slice(inputValue.length) : '');\n }, [inputValue, filteredSuggestions, isInputFocused, composition, showGhost, getLabel, getType, setGhost]);\n}\n\n// ---- selection (split by mode to keep each function under the complexity bar) -\n\nfunction commitMultiSelect<T>(item: T, p: AutocompleteProps<T>, s: AutocompleteState<T>, onChange: (v: string) => void): void {\n const getKey = p.getKey ?? defaultGetKey;\n const current = p.selectedItems ?? [];\n if (!current.some((sel) => getKey(sel) === getKey(item))) p.onSelectedItemsChange?.([...current, item]);\n s.setInputValue('');\n onChange('');\n setDeliberateClose(s, false);\n}\n\nfunction commitSingleSelect<T>(item: T, p: AutocompleteProps<T>, s: AutocompleteState<T>, onChange: (v: string) => void): void {\n const label = (p.getLabel ?? defaultGetLabel)(item);\n s.setInputValue(label);\n onChange(label);\n}\n\n/** Apply a pick: open a link suggestion, or commit a search one to the input. */\nfunction commitPick<T>(\n item: T,\n linkUrl: string | null,\n p: AutocompleteProps<T>,\n s: AutocompleteState<T>,\n onChange: (v: string) => void,\n): void {\n if (linkUrl !== null) (p.openLink ?? defaultOpenLink)(linkUrl, item);\n else if (p.multiple) commitMultiSelect(item, p, s, onChange);\n else commitSingleSelect(item, p, s, onChange);\n}\n\nfunction runSelectItem<T>(item: T, p: AutocompleteProps<T>, s: AutocompleteState<T>, onChange: (v: string) => void): void {\n const url = (p.getUrl ?? defaultGetUrl)(item);\n const isLink = (p.getSuggestionType ?? defaultGetSuggestionType)(item) === 'link' && Boolean(url);\n // A single-select pick (search or link) ends the current search: the list\n // stays closed until the user types again. `multiple` mode is unchanged —\n // commitMultiSelect already clears inputValue and resets the flag itself,\n // so the empty-input branch of the filter effect keeps the list closed.\n const isSingleSelectPick = isLink || !p.multiple;\n commitPick(item, isLink ? (url as string) : null, p, s, onChange);\n s.setOpen(false);\n s.setActiveIndex(-1);\n p.onSelect?.(item);\n s.inputRef.current?.focus();\n // Set LAST so a re-fired `onFocus` cannot clear the flag. The close itself\n // relies on the input never blurring during a pick (the option's\n // `onMouseDown` preventDefault, and Enter keeps focus): `onFocus` reopens a\n // non-empty input directly, without reading this flag. The REF half is set\n // in the same synchronous tick as the pick, so an effect scheduled by an\n // earlier keystroke — and still pending when this runs — reads the\n // up-to-date value instead of the one it closed over (FUT-2780).\n if (isSingleSelectPick) setDeliberateClose(s, true);\n}\n\nfunction buildKeyContext<T>(\n p: AutocompleteProps<T>,\n s: AutocompleteState<T>,\n selectItem: (item: T) => void,\n onChange: (v: string) => void,\n): KeyContext<T> {\n return {\n open: s.open, activeIndex: s.activeIndex, filteredSuggestions: s.filteredSuggestions,\n maxVisibleItems: p.maxVisibleItems ?? 10, allowFreeText: p.allowFreeText ?? true,\n inputValue: s.inputValue, ghost: s.ghost, isInputFocused: s.isInputFocused,\n multiple: Boolean(p.multiple), selectedItems: p.selectedItems ?? [],\n getLabel: p.getLabel ?? defaultGetLabel,\n getSuggestionType: p.getSuggestionType ?? defaultGetSuggestionType,\n setOpen: s.setOpen, setActiveIndex: s.setActiveIndex,\n setUserClosedDropdown: (closed: boolean) => setDeliberateClose(s, closed),\n setInputValue: s.setInputValue, setGhost: s.setGhost, setJustCompletedGhost: s.setJustCompletedGhost,\n debouncedOnChange: onChange, selectItem, onSelectedItemsChange: p.onSelectedItemsChange,\n };\n}\n\n/** The full view-model the presentational component renders. */\nexport interface AutocompleteView<T> {\n id: string;\n listId: string;\n optionIdPrefix: string;\n state: AutocompleteState<T>;\n visibleSuggestions: T[];\n activeDescendant: string | undefined;\n selectItem: (item: T) => void;\n removeSelectedItem: (item: T) => void;\n onKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void;\n onInputChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n onFocus: () => void;\n onBlur: () => void;\n onClickAway: () => void;\n}\n\n/** Wire state, effects, and (plain, per-render) handlers for the Autocomplete component. */\nexport function useAutocomplete<T>(p: AutocompleteProps<T>): AutocompleteView<T> {\n const componentId = useId();\n const id = p.id || componentId;\n const optionIdPrefix = `${id}-option`;\n const s = useAutocompleteState<T>(p.value, p.suggestions ?? []);\n\n const debouncedOnChange = (val: string): void => {\n if (s.debounceRef.current) window.clearTimeout(s.debounceRef.current);\n s.debounceRef.current = window.setTimeout(() => p.onChange(val), p.debounceMs ?? 150);\n };\n\n useValueSync(p.value, s.setInputValue);\n useDebounceCleanup(s.debounceRef);\n useScrollActiveIntoView(s.activeIndex, optionIdPrefix, s.listRef);\n useGhostFlagReset(s.justCompletedGhost, s.setJustCompletedGhost);\n useLoadingOpen(\n Boolean(p.isLoading),\n s.inputValue,\n Boolean(p.disabled),\n s.userClosedDropdownRef,\n s.setOpen,\n s.setActiveIndex,\n );\n useLocalFilter(p, s);\n useGhostText(p, s);\n\n const selectItem = (item: T): void => runSelectItem(item, p, s, debouncedOnChange);\n\n return {\n id,\n listId: `${id}-listbox`,\n optionIdPrefix,\n state: s,\n visibleSuggestions: s.filteredSuggestions.slice(0, p.maxVisibleItems ?? 10),\n activeDescendant: s.activeIndex >= 0 ? `${optionIdPrefix}-${s.activeIndex}` : undefined,\n selectItem,\n removeSelectedItem: (item: T): void => {\n const getKey = p.getKey ?? defaultGetKey;\n p.onSelectedItemsChange?.((p.selectedItems ?? []).filter((sel) => getKey(sel) !== getKey(item)));\n s.inputRef.current?.focus();\n },\n onKeyDown: (e: React.KeyboardEvent<HTMLInputElement>): void =>\n handleAutocompleteKey(e, s.composition, buildKeyContext(p, s, selectItem, debouncedOnChange)),\n onInputChange: (e: React.ChangeEvent<HTMLInputElement>): void => {\n s.setInputValue(e.target.value);\n debouncedOnChange(e.target.value);\n if (!s.open || s.filteredSuggestions.length === 0) s.setActiveIndex(-1);\n setDeliberateClose(s, false);\n },\n onFocus: (): void => {\n s.setIsInputFocused(true);\n setDeliberateClose(s, false);\n if (!s.inputValue.trim()) return;\n s.setOpen(true);\n if (s.filteredSuggestions.length > 0 && s.activeIndex === -1) s.setActiveIndex(0);\n },\n onBlur: (): void => {\n window.setTimeout(() => s.setIsInputFocused(false), 150);\n },\n onClickAway: (): void => {\n s.setOpen(false);\n s.setActiveIndex(-1);\n setDeliberateClose(s, true);\n },\n };\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/tokens/density.ts"],"sourcesContent":["import { useTheme } from '@mui/material/styles/index.js';\nimport type { ThemeOptions } from '@mui/material/styles/index.js';\n\nimport {\n densityFieldHeight,\n densityFontSize,\n densitySpacingUnit,\n resolveDensityFactor,\n type DensityLevel,\n type ResolvedDensity,\n} from './density.core';\nimport { fieldOverrides, mergeMuiComponents } from './field-height';\nimport { DEFAULT_FIELD_RADIUS } from './field-radius.core';\n\n/**\n * DENSITY ON THE WEB: the MUI theme channel, the reader, and the standalone\n * entry point for a host that never calls `createUiTheme`/`UiProvider`.\n *\n * The argument for one density knob, the factor table and its precedence are\n * in `./density.core.ts`.\n */\n\nexport {\n DEFAULT_DENSITY,\n DENSITY_FACTOR,\n densityFieldHeight,\n densityFontSize,\n densitySpacingUnit,\n resolveDensityFactor,\n type DensityLevel,\n type ResolvedDensity,\n} from './density.core';\n\ndeclare module '@mui/material/styles' {\n interface Theme {\n /** The density this theme renders at. See `@12-apps/ui/tokens`' `useDensity`. */\n density?: ResolvedDensity;\n }\n interface ThemeOptions {\n /** The density this theme renders at. See `@12-apps/ui/tokens`' `useDensity`. */\n density?: ResolvedDensity;\n }\n}\n\n/**\n * The theme's resolved density — a plain theme read, not a step-shifting\n * resolver (`size` stays hierarchy; see `./density.core.ts`). A `styleOverrides`\n * callback already gets `{ theme }` and can read `theme.density` directly;\n * this is for a component that needs the level in its own render logic\n * (`Table`/`DataGrid`/`DataViews` each read it once to source their own\n * `density` prop's default).\n *\n * Falls back to `resolveDensityFactor()` (`'normal'`, factor `1`) for a bare\n * MUI theme built without `createUiTheme`/`muiThemeOptionsFrom`.\n */\nexport function useDensity(): ResolvedDensity {\n return useTheme().density ?? resolveDensityFactor();\n}\n\n/**\n * The density factor as a MUI `ThemeOptions` fragment, for a host that builds\n * `createTheme()` directly and never calls `createUiTheme`/`UiProvider` — the\n * same precedence `resolveDensityFactor` gives `createUiTheme`, so the two\n * consumption paths agree on `typography`/`spacing`/`fieldHeight`/`components`\n * (FUT-2764's Design section), not just the first two. `fieldHeight` matters\n * on its own: `Input`/`Select`/`Button` each read `theme.fieldHeight` directly\n * (`Input.tsx`, `Select.tsx`, `Button.styles.ts`'s `buttonSize`), so a fragment\n * that carried only `typography`/`spacing` left every field standing at the\n * DEFAULT height (2.5) at every density on this path — the two paths would\n * agree on the type scale and disagree on the one number three components key\n * their own layout off.\n *\n * `components` is the matching MUI-native override (`fieldOverrides`) for a\n * HOST's own bare `TextField`/`Select`, mirroring `muiThemeOptionsFrom`'s own\n * `components: mergeMuiComponents(fieldOverrides(...))`. It carries ONLY the\n * field overrides this function knows about (`MuiOutlinedInput`'s `root`,\n * `input` and `notchedOutline`; `MuiInputLabel`'s `outlined`) — a host with\n * ITS OWN overrides for OTHER components merges them in with\n * `mergeMuiComponents(densityThemeOptions(density).components, hostOverrides)`,\n * which keeps a component only ONE side touches untouched. For a component\n * BOTH sides style, the merge is by INNER key (`root`/`input`/…): a key only\n * one side sets survives from that side, but a key BOTH set is replaced\n * WHOLESALE by whichever source is passed LAST — not deep-merged — so a host\n * wanting to ADD to, say, `MuiOutlinedInput`'s `root` alongside the radius\n * override needs to write that one key's object out in full itself.\n *\n * `fieldRadius` (3rd argument, optional) exists because density does NOT touch\n * the field's CORNER — this is only for a host that already draws its OWN,\n * non-default radius and wants `components` to match it instead of clashing;\n * it defaults\n * to the same {@link DEFAULT_FIELD_RADIUS} `createUiTheme` itself falls back\n * to when a host names no `fieldRadius`, so the two paths still agree with no\n * argument passed at all — the existing 2-argument call keeps working\n * unchanged.\n *\n * **Where to spread it — the first `createTheme()` call, not a later layering\n * one.** `createTheme(options, ...args)` (`createThemeNoVars.js`) only runs\n * `createSpacing`/`createTypography` on `options`, the FIRST argument; every\n * later argument is deep-merged onto the theme those two already built, with\n * no such reprocessing. So a host with a base theme and a SECOND, layering\n * `createTheme()` call on top of it — exactly the shape a two-theme host uses,\n * `createTheme(outer, { palette: { ... } })` — must apply density at the\n * FIRST call (where the base itself is built), never spread onto `outer` in\n * the second one:\n *\n * ```ts\n * // RIGHT — density goes into the base's OWN construction. The second,\n * // layering call is unaffected: it never restates spacing/typography/\n * // fieldHeight/components itself, so `theme.spacing`/`pxToRem`/`fieldHeight`\n * // carry over from `base` UNCHANGED, already correctly scaled.\n * const base = createTheme({ palette: { primary: { main }, ... }, ...densityThemeOptions('compact') });\n * const themed = createTheme(base, { palette: { primary: { main: brand } } });\n *\n * // WRONG — a second, layering argument onto an ALREADY-BUILT theme is\n * // deepmerged with no reprocessing: `spacing`/`typography.fontSize` would\n * // overwrite the already-resolved `theme.spacing` function/`pxToRem` ratio\n * // instead of rescaling them.\n * createTheme(outer, { ...densityThemeOptions('compact') });\n * ```\n */\nexport function densityThemeOptions(\n density: DensityLevel | number,\n factors?: Partial<Record<DensityLevel, number>>,\n fieldRadius: number = DEFAULT_FIELD_RADIUS,\n): Pick<ThemeOptions, 'typography' | 'spacing' | 'fieldHeight' | 'components'> {\n const { factor } = resolveDensityFactor(density, factors);\n const fieldHeight = densityFieldHeight(factor);\n return {\n typography: { fontSize: densityFontSize(factor) },\n spacing: densitySpacingUnit(factor),\n fieldHeight,\n components: mergeMuiComponents(fieldOverrides(fieldRadius, fieldHeight)),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;AAAA,SAAS,gBAAgB;AAuDlB,SAAS,aAA8B;AAC5C,SAAO,SAAS,EAAE,WAAW,qBAAqB;AACpD;AA+DO,SAAS,oBACd,SACA,SACA,cAAsB,sBACuD;AAC7E,QAAM,EAAE,OAAO,IAAI,qBAAqB,SAAS,OAAO;AACxD,QAAM,cAAc,mBAAmB,MAAM;AAC7C,SAAO;AAAA,IACL,YAAY,EAAE,UAAU,gBAAgB,MAAM,EAAE;AAAA,IAChD,SAAS,mBAAmB,MAAM;AAAA,IAClC;AAAA,IACA,YAAY,mBAAmB,eAAe,aAAa,WAAW,CAAC;AAAA,EACzE;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/layout/SettingsLayout/SettingsSectionChips.scroll.ts"],"sourcesContent":["/**\n * Telling the strip's own scrolls from the visitor's (FUT-2606).\n *\n * Split from `SettingsSectionChips.tsx` so the chips stay a component file and\n * the rule for \"who moved the strip\" can be read in one place.\n */\n\n/**\n * How near to where the strip aimed itself it has to come to rest for the scroll\n * to count as the strip's own. A smooth scroll lands on a device pixel, and the\n * target it was given is fractional.\n */\nconst LANDED_SLACK = 1;\n\n/**\n * Where `scrollend` is missing: how long the strip has to go without a `scroll`\n * before it counts as settled. Generous on purpose — a busy main thread can go\n * several frames between ticks of a smooth scroll, and judging one mid-flight\n * would read the strip's own animation as the visitor's. Too long only delays a\n * re-centre; too short can latch the strip for good.\n */\nconst QUIET_BEFORE_SETTLED_MS = 250;\n\n/**\n * How much `scrollLeft` has to move, tick to tick, before a `scroll` event is\n * even a CANDIDATE for arming (FUT-2775). Below this, a browser's own rounding\n * or a repeated event carrying no real motion cannot arm anything by itself.\n *\n * This alone does not stop the false latch the ticket describes: the strip's\n * own `scrollTo` produces real per-tick deltas well past this line, same as a\n * drag would. It only rules out a scroll event that moved nothing.\n */\nconst SCROLL_DELTA_EPSILON = 2;\n\n/**\n * How far a pointer or touch has to travel from where it went down before it\n * counts as having MOVED, rather than merely resting (FUT-2775). Below this,\n * an held-still finger's sub-pixel tremor does not count as a drag.\n */\nconst POINTER_MOVE_EPSILON = 2;\n\ninterface VisitorScrollWatch {\n /** True once the visitor has moved the strip themselves. */\n hasScrolled: () => boolean;\n /**\n * True while a scroll the visitor MAY be making has not come to rest yet. The\n * strip must not scroll itself under it: that would yank a drag in progress.\n */\n isUndecided: () => boolean;\n /**\n * Where the strip last aimed itself, PHYSICAL pixels (see {@link physicalScrollLeft}) —\n * direction-blind, like every other geometry read in this file. `NaN` before it has.\n */\n aimedAt: () => number;\n /**\n * The strip is about to scroll itself to `left` (physical pixels). Records the\n * aim and NOTHING\n * else: it used to disarm too, and a re-centre landing between a visitor's key\n * press (or wheel, or pan) and the first tick of the scroll it causes wiped\n * the arming — their scroll went unclaimed, read as the strip's own. Left\n * armed, the worst a stale arming does is put the strip's OWN next scroll\n * under judgement, which rests on its aim, is not latched, and disarms.\n */\n beforeOwnScroll: (left: number) => void;\n /** Called once an undecided scroll has come to rest and been judged. */\n onSettled: (listener: () => void) => void;\n detach: () => void;\n}\n\ntype Listeners = Array<[string, (event: Event) => void]>;\n\n/** A wheel's sideways travel: `deltaX`, or `deltaY` with Shift held, as browsers read it. */\nfunction horizontalDelta(event: Event): number {\n if (!(event instanceof WheelEvent)) return 0;\n return event.deltaX !== 0 ? event.deltaX : event.shiftKey ? event.deltaY : 0;\n}\n\ninterface WatchState {\n pointer: boolean;\n touch: boolean;\n nudged: boolean;\n undecided: boolean;\n scrolled: boolean;\n aimed: number;\n quiet: ReturnType<typeof setTimeout> | undefined;\n settled: () => void;\n /** `scrollLeft` as of the last `scroll` tick, updated every tick regardless of arming. */\n lastScrollLeft: number;\n /** Where a `pointerdown` on the strip landed, in viewport `clientX`. `NaN` while up. */\n pointerDownAt: number;\n /** True once that pointer has travelled past {@link POINTER_MOVE_EPSILON} from `pointerDownAt`. */\n pointerMoved: boolean;\n /** Same pair, for `touchstart`/`touchmove` — a distinct event stream on some engines. */\n touchDownAt: number;\n touchMoved: boolean;\n}\n\ntype RtlScrollType = 'default' | 'negative' | 'reverse';\n\nlet cachedRtlScrollType: RtlScrollType | undefined;\n\n/**\n * Which of the three incompatible conventions this engine reports an RTL\n * scroller's `scrollLeft` in, probed once and cached (FUT-2775).\n *\n * Per the CSSOM View spec, an RTL scroller's `scrollLeft` is `0` at its\n * (right-hand) start and goes NEGATIVE toward the end — `'negative'` below,\n * what every current evergreen engine implements. Older WebKit mirrored that\n * (`'reverse'`: `0` at the start, growing toward `+max`), and older\n * Chromium/Safari ignored `dir` altogether and kept the plain left-to-right\n * numbering (`'default'`). A hidden probe, not a version sniff, tells them\n * apart — the same technique `@mui/utils`'s `detectScrollType` uses for\n * `Tabs`; reimplemented here rather than taking a new dependency for one\n * probe.\n */\nfunction detectRtlScrollType(doc: Document): RtlScrollType {\n if (cachedRtlScrollType) return cachedRtlScrollType;\n // The exact pixel values below are the probe's mechanism, not a design size:\n // what matters is only that the INNER box is wider than the OUTER one, so the\n // outer one has something to scroll — same technique `@mui/utils` uses,\n // detached and off-screen either way.\n const probe = doc.createElement('div');\n const inner = doc.createElement('div');\n inner.style.width = '10px';\n probe.appendChild(inner);\n probe.dir = 'rtl';\n probe.style.width = '4px';\n probe.style.position = 'absolute';\n probe.style.top = '-1000px';\n probe.style.overflow = 'scroll';\n doc.body.appendChild(probe);\n let type: RtlScrollType = 'reverse';\n if (probe.scrollLeft > 0) {\n type = 'default';\n } else {\n probe.scrollLeft = 1;\n if (probe.scrollLeft === 0) type = 'negative';\n }\n doc.body.removeChild(probe);\n cachedRtlScrollType = type;\n return type;\n}\n\n/** True when the strip's own computed direction is right-to-left. */\nexport function isRtlStrip(strip: HTMLElement): boolean {\n const view = strip.ownerDocument.defaultView;\n const getComputedStyle = view?.getComputedStyle ?? globalThis.getComputedStyle;\n return getComputedStyle(strip).direction === 'rtl';\n}\n\n/**\n * `strip.scrollLeft`, renumbered so `0` is always the strip's physical LEFT\n * edge and larger is always further physically right — whatever `direction`\n * and whatever convention this engine uses to report it raw (FUT-2775).\n *\n * Every geometry read in this file (`getBoundingClientRect`) is already in\n * that same physical, direction-blind coordinate space, so this is what makes\n * `scrollLeft` combinable with it at all.\n */\nexport function physicalScrollLeft(strip: HTMLElement): number {\n const raw = strip.scrollLeft;\n if (!isRtlStrip(strip)) return raw;\n const max = strip.scrollWidth - strip.clientWidth;\n const type = detectRtlScrollType(strip.ownerDocument);\n if (type === 'negative') return raw + max;\n if (type === 'reverse') return max - raw;\n return raw;\n}\n\n/** The inverse of {@link physicalScrollLeft}: a physical offset back to this engine's raw `scrollLeft`. */\nexport function toRawScrollLeft(strip: HTMLElement, physical: number): number {\n if (!isRtlStrip(strip)) return physical;\n const max = strip.scrollWidth - strip.clientWidth;\n const type = detectRtlScrollType(strip.ownerDocument);\n if (type === 'negative') return physical - max;\n if (type === 'reverse') return max - physical;\n return physical;\n}\n\n/** Whether the strip came to rest where it last aimed itself — clamped as the browser would. */\nfunction restsOnAim(strip: HTMLElement, aimed: number): boolean {\n const reachable = Math.min(aimed, strip.scrollWidth - strip.clientWidth);\n // Written so that `NaN` — the strip never aimed — reads as \"not on aim\".\n return Math.abs(physicalScrollLeft(strip) - reachable) <= LANDED_SLACK;\n}\n\n/** The pointer/touch/keydown/wheel listeners that arm `state`, split out of `watchVisitorScroll` (line budget). */\nfunction createGestureListeners(state: WatchState): { onStrip: Listeners; onView: Listeners } {\n // `MouseEvent`, not `PointerEvent`: a real `PointerEvent` IS one (it extends\n // `MouseEvent`), so this reads `clientX` off it just the same in a browser —\n // but jsdom (this file's own test environment) has never implemented\n // `PointerEvent` at all, and the bare identifier throws a `ReferenceError`\n // the moment anything evaluates `instanceof PointerEvent`, pointer event or\n // not. Same reasoning as feature-checking `scrollTo` elsewhere in this file:\n // nothing in here is worth a crash over which constructor a probe prefers.\n const onPointerDown = (event: Event): void => {\n state.pointer = true;\n state.pointerMoved = false;\n state.pointerDownAt = event instanceof MouseEvent ? event.clientX : Number.NaN;\n };\n const onPointerMove = (event: Event): void => {\n if (!(event instanceof MouseEvent) || Number.isNaN(state.pointerDownAt)) return;\n if (Math.abs(event.clientX - state.pointerDownAt) > POINTER_MOVE_EPSILON) state.pointerMoved = true;\n };\n const onPointerUp = (): void => {\n state.pointer = false;\n state.pointerDownAt = Number.NaN;\n };\n const onTouchStart = (event: Event): void => {\n state.touch = true;\n state.touchMoved = false;\n state.touchDownAt = event instanceof TouchEvent ? (event.touches[0]?.clientX ?? Number.NaN) : Number.NaN;\n };\n const onTouchMove = (event: Event): void => {\n if (!(event instanceof TouchEvent) || Number.isNaN(state.touchDownAt)) return;\n const clientX = event.touches[0]?.clientX;\n if (clientX !== undefined && Math.abs(clientX - state.touchDownAt) > POINTER_MOVE_EPSILON) {\n state.touchMoved = true;\n }\n };\n const onTouchEnd = (): void => {\n state.touch = false;\n state.touchDownAt = Number.NaN;\n };\n const onPointerCancel = (): void => {\n state.nudged = true;\n onPointerUp();\n };\n const onKeydown = (): void => {\n state.nudged = true;\n };\n const onWheel = (event: Event): void => {\n if (horizontalDelta(event) !== 0) state.nudged = true;\n };\n return {\n onStrip: [\n ['pointerdown', onPointerDown],\n ['pointermove', onPointerMove],\n ['touchstart', onTouchStart],\n ['touchmove', onTouchMove],\n ['pointercancel', onPointerCancel],\n ['keydown', onKeydown],\n ['wheel', onWheel],\n ],\n // A gesture can END off the strip, so its end is heard on the window.\n onView: [\n ['pointerup', onPointerUp],\n ['pointercancel', onPointerUp],\n ['touchend', onTouchEnd],\n ['touchcancel', onTouchEnd],\n ],\n };\n}\n\n/**\n * Tell a scroll the VISITOR made from every other one.\n *\n * The `scroll` event cannot say: the strip's own `scrollTo` fires it, and so does\n * the browser clamping a strip whose content shrank. So a scroll is only a\n * CANDIDATE when it arrives during something only a visitor does:\n *\n * - a finger held on the strip (`touchstart` until `touchend`) — a drag;\n * - a pointer held on it (`pointerdown` until `pointerup`);\n * - a key press, a SIDEWAYS wheel, or the browser taking a pointer over to pan\n * it (`pointercancel`), each armed until the next scroll under judgement has\n * been judged — whoever's it turns out to be.\n *\n * and the verdict waits until the strip comes to REST (`scrollend`, or a quiet\n * spell where the browser has no `scrollend`): it is the visitor's only if the\n * strip rests somewhere other than where it last aimed itself.\n *\n * Judged at rest rather than per `scroll` because the strip's own smooth scroll\n * fires `scroll` for a third of a second, and a visitor who presses Tab or puts\n * a finger on a chip to scroll the PAGE in that window is not scrolling the\n * strip. Every tick of that animation used to count as theirs, the strip stopped\n * re-centring for good, and the open chip could be left clipped (FUT-2606\n * again, by another door). A visitor who really drags or wheels the strip\n * mid-animation cancels it, so the strip rests where THEY left it — and that\n * still counts. The one loss: a visitor who happens to leave it within a pixel\n * of the strip's own aim is not told apart from it, and the strip there is\n * already where it would have put itself.\n *\n * A tap is a pointer held with no scroll under it, so it never counts. A\n * vertical wheel scrolls the PAGE — the strip is `overflowY: hidden` — and is\n * not armed at all.\n */\nexport function watchVisitorScroll(strip: HTMLElement): VisitorScrollWatch {\n const view = strip.ownerDocument.defaultView;\n const hasScrollEnd = 'onscrollend' in strip;\n const state: WatchState = {\n pointer: false,\n touch: false,\n nudged: false,\n undecided: false,\n scrolled: false,\n aimed: Number.NaN,\n quiet: undefined,\n settled: () => undefined,\n lastScrollLeft: physicalScrollLeft(strip),\n pointerDownAt: Number.NaN,\n pointerMoved: false,\n touchDownAt: Number.NaN,\n touchMoved: false,\n };\n const settle = (): void => {\n // Only a scroll that was UNDER JUDGEMENT disarms. Chromium can end the\n // strip's own smooth scroll with a `scrollend` when another scroll cuts it\n // off, fired BEFORE that scroll's first `scroll` (seen with an instant one);\n // disarming there would hand the visitor's scroll to nobody.\n if (!state.undecided) return;\n state.undecided = false;\n state.nudged = false;\n if (!restsOnAim(strip, state.aimed)) state.scrolled = true;\n state.settled();\n };\n const onScroll = (): void => {\n const now = physicalScrollLeft(strip);\n const movedFarEnough = Math.abs(now - state.lastScrollLeft) > SCROLL_DELTA_EPSILON;\n state.lastScrollLeft = now;\n // Pointer/touch need BOTH signals (FUT-2775): the pointer/finger must have\n // itself MOVED since going down, AND this tick's delta must be real. Either\n // alone still latches on the other's shape — a pointer merely resting on\n // the strip while its OWN `scrollTo` produces real per-tick deltas would\n // arm under a delta-only check (`pointerMoved`/`touchMoved` rules that out);\n // a pointer that drifts a sub-epsilon amount while resting would arm under\n // a moved-only check with no delta floor (`movedFarEnough` rules that out).\n const pointerDrag = state.pointer && state.pointerMoved && movedFarEnough;\n const touchDrag = state.touch && state.touchMoved && movedFarEnough;\n // `nudged` (a keypress, a sideways wheel, the browser taking the pointer\n // over to pan) is already a discrete, one-shot gesture with no \"resting\n // pointer coincides with an unrelated animation\" shape to rule out — unlike\n // pointer/touch, requiring a delta on the SAME tick that arms it would only\n // race the strip's own scroll ending before a qualifying tick arrives (seen:\n // it broke the existing \"keeps a wheel/drag scroll\" stories against a real\n // browser's `scrollend` timing). So it arms as it always has.\n if (pointerDrag || touchDrag || state.nudged) state.undecided = true;\n if (!state.undecided || hasScrollEnd) return;\n // Every tick while undecided, armed or not: a quiet spell that began while\n // the strip was still moving would judge it mid-flight, away from its aim.\n clearTimeout(state.quiet);\n state.quiet = setTimeout(settle, QUIET_BEFORE_SETTLED_MS);\n };\n const gestures = createGestureListeners(state);\n const onStrip: Listeners = [...gestures.onStrip, ['scroll', onScroll], ['scrollend', settle]];\n const onView = gestures.onView;\n for (const [type, listener] of onStrip) strip.addEventListener(type, listener, { passive: true });\n for (const [type, listener] of onView) view?.addEventListener(type, listener, { passive: true });\n return {\n hasScrolled: () => state.scrolled,\n isUndecided: () => state.undecided,\n aimedAt: () => state.aimed,\n beforeOwnScroll: (left) => {\n state.aimed = left;\n },\n onSettled: (listener) => {\n state.settled = listener;\n },\n detach: () => {\n clearTimeout(state.quiet);\n for (const [type, listener] of onStrip) strip.removeEventListener(type, listener);\n for (const [type, listener] of onView) view?.removeEventListener(type, listener);\n },\n };\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/utility/WorkflowStep/WorkflowStep.parts.tsx"],"sourcesContent":["import Box from '@mui/material/Box/index.js';\nimport type { CSSObject, Theme } from '@mui/material/styles/index.js';\nimport { styled } from '@mui/material/styles/index.js';\nimport React, { forwardRef, useCallback } from 'react';\n\nimport type { StepColors } from './WorkflowStep.helpers';\nimport { indicatorSizeFor, stepColors, stepPalette } from './WorkflowStep.helpers';\nimport type {\n StepConnectorProps,\n StepContentProps,\n StepIndicatorProps,\n WorkflowStepProps,\n} from './WorkflowStep.types';\nimport { neutralTones } from '../../../tokens/ink';\nimport { rem } from '../../../tokens/relative';\n\n// `outlined` shows the surface through a coloured rim; the other three fill it and\n// differ only in what border they keep.\nconst indicatorVariantStyles = (\n theme: Theme,\n variant: WorkflowStepProps['variant'],\n { backgroundColor, borderColor, textColor }: StepColors,\n): CSSObject => {\n if (variant === 'outlined') {\n return {\n border: `${rem(theme, 2)} solid ${borderColor}`,\n backgroundColor: theme.palette.background.paper,\n };\n }\n\n const filled = { backgroundColor, color: textColor };\n\n switch (variant) {\n case 'filled':\n return filled;\n case 'minimal':\n return { ...filled, border: 'none' };\n case 'default':\n return { ...filled, border: `1px solid ${borderColor}` };\n default:\n return {};\n }\n};\n\nconst StepItem = styled(Box, {\n shouldForwardProp: (prop) => !['orientation', 'isLast'].includes(prop as string),\n})<{\n orientation: WorkflowStepProps['orientation'];\n isLast: boolean;\n}>(({ orientation, isLast }) => ({\n display: 'flex',\n flexDirection: orientation === 'vertical' ? 'column' : 'row',\n alignItems: orientation === 'vertical' ? 'flex-start' : 'center',\n flex: orientation === 'horizontal' && !isLast ? 1 : 'none',\n position: 'relative',\n minWidth: 0, // Allow content to shrink\n}));\n\nconst StepIndicator = styled(Box, {\n shouldForwardProp: (prop) => !['size', 'variant', 'color', 'isActive', 'isCompleted', 'isError', 'interactive', 'animated', 'disabled'].includes(prop as string),\n})<{\n size: WorkflowStepProps['size'];\n variant: WorkflowStepProps['variant'];\n color: WorkflowStepProps['color'];\n isActive: boolean;\n isCompleted: boolean;\n isError: boolean;\n interactive: boolean;\n animated: boolean;\n disabled: boolean;\n}>(({ theme, size, variant, color, isActive, isCompleted, isError, interactive, animated, disabled }) => {\n const indicatorSize = indicatorSizeFor(size);\n const palette = stepPalette(theme, color);\n const { backgroundColor, borderColor, textColor } = stepColors(theme, palette, {\n isActive,\n isCompleted,\n isError,\n variant,\n });\n\n return {\n width: rem(theme, indicatorSize),\n height: rem(theme, indicatorSize),\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: rem(theme, 12),\n fontWeight: theme.typography.fontWeightMedium,\n cursor: interactive && !disabled ? 'pointer' : 'default',\n transition: animated\n ? theme.transitions.create(['background-color', 'border-color', 'transform'], {\n duration: theme.transitions.duration.short,\n })\n : 'none',\n flexShrink: 0,\n\n ...indicatorVariantStyles(theme, variant, { backgroundColor, borderColor, textColor }),\n\n // Interactive states\n ...(interactive && !disabled && {\n '&:hover': {\n transform: 'scale(1.1)',\n boxShadow: theme.shadows[2],\n },\n '&:focus-visible': {\n outline: `${rem(theme, 2)} solid ${palette.main}`,\n outlineOffset: rem(theme, 2),\n },\n }),\n\n // Disabled state\n ...(disabled && {\n opacity: 0.5,\n cursor: 'not-allowed',\n }),\n };\n});\n\nconst StepContent = styled(Box, {\n shouldForwardProp: (prop) => !['orientation', 'interactive', 'disabled'].includes(prop as string),\n})<{\n orientation: WorkflowStepProps['orientation'];\n interactive: boolean;\n disabled: boolean;\n}>(({ theme, orientation, interactive, disabled }) => ({\n display: 'flex',\n flexDirection: 'column',\n alignItems: orientation === 'vertical' ? 'flex-start' : 'center',\n textAlign: orientation === 'vertical' ? 'left' : 'center',\n marginTop: orientation === 'vertical' ? theme.spacing(1) : theme.spacing(0.5),\n marginLeft: orientation === 'horizontal' ? theme.spacing(1) : 0,\n cursor: interactive && !disabled ? 'pointer' : 'default',\n minWidth: 0,\n flex: 1,\n\n '& .step-title': {\n fontSize: rem(theme, 14),\n fontWeight: theme.typography.fontWeightMedium,\n color: theme.palette.text.primary,\n marginBottom: theme.spacing(0.5),\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n maxWidth: '100%',\n },\n\n '& .step-description': {\n fontSize: rem(theme, 12),\n color: theme.palette.text.secondary,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n maxWidth: '100%',\n },\n\n ...(disabled && {\n opacity: 0.5,\n }),\n}));\n\nconst StepConnector = styled(Box, {\n shouldForwardProp: (prop) => !['orientation', 'isCompleted', 'color', 'variant'].includes(prop as string),\n})<{\n orientation: WorkflowStepProps['orientation'];\n isCompleted: boolean;\n color: WorkflowStepProps['color'];\n variant: WorkflowStepProps['variant'];\n}>(({ theme, orientation, isCompleted, color, variant }) => {\n const connectorColor = isCompleted ? stepPalette(theme, color).main : neutralTones(theme).track;\n\n return {\n flex: 1,\n position: 'relative',\n \n ...(orientation === 'horizontal' && {\n height: rem(theme, 2),\n backgroundColor: connectorColor,\n margin: `0 ${theme.spacing(1)}`,\n minWidth: theme.spacing(2),\n }),\n \n ...(orientation === 'vertical' && {\n width: rem(theme, 2),\n backgroundColor: connectorColor,\n minHeight: theme.spacing(3),\n marginLeft: theme.spacing(2),\n position: 'absolute',\n left: '50%',\n transform: 'translateX(-50%)',\n top: '100%',\n }),\n\n transition: theme.transitions.create('background-color', {\n duration: theme.transitions.duration.short,\n }),\n\n ...(variant === 'minimal' && {\n opacity: 0.6,\n }),\n };\n});\n\n/**\n * Individual step indicator component\n */\nconst StepIndicatorComponent = forwardRef<HTMLDivElement, StepIndicatorProps>(({\n step,\n index,\n isActive,\n isCompleted,\n isError,\n variant,\n color,\n size,\n showNumbers,\n showIcons,\n completedIcon,\n errorIcon,\n interactive,\n animated,\n disabled,\n onClick,\n 'data-testid': dataTestId,\n}, ref) => {\n const handleClick = useCallback(() => {\n if (interactive && !disabled && onClick) {\n onClick(index, step);\n }\n }, [interactive, disabled, onClick, index, step]);\n\n const handleKeyDown = useCallback((event: React.KeyboardEvent) => {\n if (interactive && !disabled && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault();\n if (onClick) {\n onClick(index, step);\n }\n }\n }, [interactive, disabled, onClick, index, step]);\n\n const renderIndicatorContent = () => {\n if (isError && errorIcon) {\n return errorIcon;\n }\n if (isCompleted && completedIcon) {\n return completedIcon;\n }\n if (showIcons && step.icon) {\n return step.icon;\n }\n if (showNumbers) {\n return index + 1;\n }\n return null;\n };\n\n return (\n <StepIndicator\n ref={ref}\n size={size}\n variant={variant}\n color={color}\n isActive={isActive}\n isCompleted={isCompleted}\n isError={isError}\n interactive={interactive}\n animated={animated}\n disabled={Boolean(disabled || step.disabled)}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n role={interactive ? 'button' : undefined}\n tabIndex={interactive && !disabled && !step.disabled ? 0 : -1}\n aria-label={`Step ${index + 1}: ${step.title}`}\n aria-current={isActive ? 'step' : undefined}\n data-testid={dataTestId}\n >\n {renderIndicatorContent()}\n </StepIndicator>\n );\n});\n\nStepIndicatorComponent.displayName = 'StepIndicator';\n\n/**\n * Step connector component\n */\nconst StepConnectorComponent = forwardRef<HTMLDivElement, StepConnectorProps>(({\n isCompleted,\n orientation,\n variant,\n color,\n 'data-testid': dataTestId,\n}, ref) => (\n <StepConnector\n ref={ref}\n orientation={orientation}\n isCompleted={isCompleted}\n color={color}\n variant={variant}\n data-testid={dataTestId}\n />\n));\n\nStepConnectorComponent.displayName = 'StepConnector';\n\n/**\n * Step content component\n */\nconst StepContentComponent = forwardRef<HTMLDivElement, StepContentProps>(({\n step,\n index,\n orientation,\n interactive,\n disabled,\n onClick,\n 'data-testid': dataTestId,\n}, ref) => {\n const handleClick = useCallback(() => {\n if (interactive && !disabled && onClick) {\n onClick(index, step);\n }\n }, [interactive, disabled, onClick, index, step]);\n\n const handleKeyDown = useCallback((event: React.KeyboardEvent) => {\n if (interactive && !disabled && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault();\n if (onClick) {\n onClick(index, step);\n }\n }\n }, [interactive, disabled, onClick, index, step]);\n\n return (\n <StepContent\n ref={ref}\n orientation={orientation}\n interactive={interactive}\n disabled={Boolean(disabled || step.disabled)}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n role={interactive ? 'button' : undefined}\n tabIndex={interactive && !disabled && !step.disabled ? 0 : -1}\n data-testid={dataTestId}\n >\n <div className=\"step-title\">{step.title}</div>\n {step.description && (\n <div className=\"step-description\">{step.description}</div>\n )}\n </StepContent>\n );\n});\n\nStepContentComponent.displayName = 'StepContent';\n\n/**\n * A plain wrapper around the styled row. Exporting the styled component itself\n * trips TS2742 — its inferred type names a pnpm-internal @mui/system path.\n */\nexport const StepItemRow: React.FC<{\n orientation: WorkflowStepProps['orientation'];\n isLast: boolean;\n children: React.ReactNode;\n}> = ({ orientation, isLast, children }) => (\n <StepItem orientation={orientation} isLast={isLast}>\n {children}\n </StepItem>\n);\n\nexport { StepConnectorComponent, StepContentComponent, StepIndicatorComponent };\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/utility/WorkflowStep/WorkflowStep.tsx"],"sourcesContent":["import Box from '@mui/material/Box/index.js';\nimport { styled } from '@mui/material/styles/index.js';\nimport React, { forwardRef, useCallback, useMemo } from 'react';\n\nimport { progressValueText, resolveWorkflowStepProps, withDerivedStatus } from './WorkflowStep.helpers';\nimport { StepRow } from './WorkflowStepRow';\nimport type { WorkflowStepItem, WorkflowStepProps } from './WorkflowStep.types';\n\n// Styled Components\nconst StepContainer = styled(Box, {\n shouldForwardProp: (prop) => !['orientation', 'variant'].includes(prop as string),\n})<{\n orientation: WorkflowStepProps['orientation'];\n variant: WorkflowStepProps['variant'];\n}>(({ theme, orientation, variant }) => ({\n display: 'flex',\n flexDirection: orientation === 'vertical' ? 'column' : 'row',\n alignItems: orientation === 'vertical' ? 'flex-start' : 'center',\n gap: orientation === 'vertical' ? theme.spacing(2) : theme.spacing(1),\n width: '100%',\n position: 'relative',\n \n // Variant-specific styles\n ...(variant === 'minimal' && {\n gap: orientation === 'vertical' ? theme.spacing(1) : theme.spacing(0.5),\n }),\n}));\n\n/**\n * WorkflowStep component for displaying multi-step workflows with visual progression\n */\nexport const WorkflowStep = forwardRef<HTMLDivElement, WorkflowStepProps>((rawProps, ref) => {\n const {\n steps,\n currentStep,\n variant,\n orientation,\n color,\n size,\n showProgress,\n animated,\n interactive,\n showNumbers,\n showIcons,\n completedIcon,\n errorIcon,\n onStepClick,\n disabled,\n className,\n style,\n 'data-testid': dataTestId,\n ...other\n } = resolveWorkflowStepProps(rawProps);\n const handleStepClick = useCallback((stepIndex: number, step: WorkflowStepItem) => {\n if (onStepClick && !disabled && !step.disabled) {\n onStepClick(stepIndex, step);\n }\n }, [onStepClick, disabled]);\n\n const stepsWithStatus = useMemo(\n () => withDerivedStatus(steps, currentStep),\n [steps, currentStep],\n );\n\n return (\n <StepContainer\n ref={ref}\n orientation={orientation}\n variant={variant}\n className={className}\n style={style}\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={steps.length - 1}\n aria-valuenow={currentStep}\n aria-valuetext={progressValueText(steps, currentStep)}\n data-testid={dataTestId}\n {...other}\n >\n {stepsWithStatus.map((step, index) => (\n <StepRow\n key={index}\n step={step}\n index={index}\n isLast={index === steps.length - 1}\n orientation={orientation}\n variant={variant}\n color={color}\n size={size}\n showNumbers={showNumbers}\n showIcons={showIcons}\n showProgress={showProgress}\n completedIcon={completedIcon}\n errorIcon={errorIcon}\n interactive={interactive}\n animated={animated}\n disabled={disabled}\n onClick={handleStepClick}\n dataTestId={dataTestId}\n />\n ))}\n </StepContainer>\n );\n});\n\nWorkflowStep.displayName = 'WorkflowStep';\n\nexport default WorkflowStep;"],"mappings":";;;;;;;;;;AAAA,OAAO,SAAS;AAChB,SAAS,cAAc;AACvB,SAAgB,YAAY,aAAa,eAAe;AA8EhD;AAvER,IAAM,gBAAgB,OAAO,KAAK;AAAA,EAChC,mBAAmB,CAAC,SAAS,CAAC,CAAC,eAAe,SAAS,EAAE,SAAS,IAAc;AAClF,CAAC,EAGE,CAAC,EAAE,OAAO,aAAa,QAAQ,OAAO;AAAA,EACvC,SAAS;AAAA,EACT,eAAe,gBAAgB,aAAa,WAAW;AAAA,EACvD,YAAY,gBAAgB,aAAa,eAAe;AAAA,EACxD,KAAK,gBAAgB,aAAa,MAAM,QAAQ,CAAC,IAAI,MAAM,QAAQ,CAAC;AAAA,EACpE,OAAO;AAAA,EACP,UAAU;AAAA;AAAA,EAGV,GAAI,YAAY,aAAa;AAAA,IAC3B,KAAK,gBAAgB,aAAa,MAAM,QAAQ,CAAC,IAAI,MAAM,QAAQ,GAAG;AAAA,EACxE;AACF,EAAE;AAKK,IAAM,eAAe,WAA8C,CAAC,UAAU,QAAQ;AAC3F,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe;AAAA,IACf,GAAG;AAAA,EACL,IAAI,yBAAyB,QAAQ;AACrC,QAAM,kBAAkB,YAAY,CAAC,WAAmB,SAA2B;AACjF,QAAI,eAAe,CAAC,YAAY,CAAC,KAAK,UAAU;AAC9C,kBAAY,WAAW,IAAI;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,aAAa,QAAQ,CAAC;AAE1B,QAAM,kBAAkB;AAAA,IACtB,MAAM,kBAAkB,OAAO,WAAW;AAAA,IAC1C,CAAC,OAAO,WAAW;AAAA,EACrB;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAK;AAAA,MACL,iBAAe;AAAA,MACf,iBAAe,MAAM,SAAS;AAAA,MAC9B,iBAAe;AAAA,MACf,kBAAgB,kBAAkB,OAAO,WAAW;AAAA,MACpD,eAAa;AAAA,MACZ,GAAG;AAAA,MAEH,0BAAgB,IAAI,CAAC,MAAM,UAC1B;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA,UACA;AAAA,UACA,QAAQ,UAAU,MAAM,SAAS;AAAA,UACjC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,SAAS;AAAA,UACT;AAAA;AAAA,QAjBK;AAAA,MAkBP,CACD;AAAA;AAAA,EACH;AAEJ,CAAC;AAED,aAAa,cAAc;AAE3B,IAAO,uBAAQ;","names":[]}