@12-apps/ui 6.26.0 → 6.27.1

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 (493) hide show
  1. package/dist/_internal/components/data-display/Alert/Alert.js +4 -4
  2. package/dist/_internal/components/data-display/Alert/Alert.metrics.js +2 -2
  3. package/dist/_internal/components/data-display/Alert/Alert.styles.js +3 -3
  4. package/dist/_internal/components/data-display/Avatar/Avatar.js +3 -3
  5. package/dist/_internal/components/data-display/Avatar/Avatar.view.js +2 -2
  6. package/dist/_internal/components/data-display/Badge/Badge.animations.js +3 -3
  7. package/dist/_internal/components/data-display/Badge/Badge.js +7 -7
  8. package/dist/_internal/components/data-display/Badge/Badge.metrics.js +2 -2
  9. package/dist/_internal/components/data-display/Badge/Badge.styles.js +5 -5
  10. package/dist/_internal/components/data-display/Badge/Badge.variants.js +3 -3
  11. package/dist/_internal/components/data-display/Badge/BadgeContent.js +6 -6
  12. package/dist/_internal/components/data-display/Banner/Banner.js +4 -4
  13. package/dist/_internal/components/data-display/Banner/Banner.styles.js +3 -3
  14. package/dist/_internal/components/data-display/CardKit/CardKebab.js +4 -4
  15. package/dist/_internal/components/data-display/CardKit/card-actions-context.js +5 -5
  16. package/dist/_internal/components/data-display/CardKit/use-remove-confirm.js +9 -9
  17. package/dist/_internal/components/data-display/CardKit/use-row-confirm.js +4 -4
  18. package/dist/_internal/components/data-display/Carousel/Carousel.chrome.js +1 -1
  19. package/dist/_internal/components/data-display/Carousel/Carousel.js +1 -1
  20. package/dist/_internal/components/data-display/Carousel/Carousel.parts.js +1 -1
  21. package/dist/_internal/components/data-display/Carousel/Carousel.styles.js +1 -1
  22. package/dist/_internal/components/data-display/Chart/Chart.js +5 -5
  23. package/dist/_internal/components/data-display/Chart/SpecChart.js +6 -6
  24. package/dist/_internal/components/data-display/Chart/chart-context.js +3 -3
  25. package/dist/_internal/components/data-display/Chart/chart-internals.js +1 -1
  26. package/dist/_internal/components/data-display/Chart/chart-renderers.js +4 -4
  27. package/dist/_internal/components/data-display/DataViews/DataViewsBoard.js +4 -4
  28. package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +37 -37
  29. package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +54 -53
  30. package/dist/_internal/components/data-display/DataViews/DeleteViewDialog.js +6 -6
  31. package/dist/_internal/components/data-display/DataViews/ManageViewsDialog.js +7 -7
  32. package/dist/_internal/components/data-display/DataViews/SaveViewModal.js +12 -11
  33. package/dist/_internal/components/data-display/DataViews/base-card.js +9 -9
  34. package/dist/_internal/components/data-display/DataViews/base-list-card-geometry.js +12 -12
  35. package/dist/_internal/components/data-display/DataViews/base-list-card-gutters.js +3 -3
  36. package/dist/_internal/components/data-display/DataViews/base-list-card-slots.js +8 -8
  37. package/dist/_internal/components/data-display/DataViews/base-list-card.js +16 -16
  38. package/dist/_internal/components/data-display/DataViews/card-surface.js +4 -4
  39. package/dist/_internal/components/data-display/DataViews/data-views-category-pill.js +5 -5
  40. package/dist/_internal/components/data-display/DataViews/data-views-columns-tab.js +4 -4
  41. package/dist/_internal/components/data-display/DataViews/data-views-columns.js +5 -5
  42. package/dist/_internal/components/data-display/DataViews/data-views-display-panel.js +11 -11
  43. package/dist/_internal/components/data-display/DataViews/data-views-display-tabs.js +6 -6
  44. package/dist/_internal/components/data-display/DataViews/data-views-empty.js +6 -6
  45. package/dist/_internal/components/data-display/DataViews/data-views-export.js +6 -6
  46. package/dist/_internal/components/data-display/DataViews/data-views-filter-panel.js +6 -6
  47. package/dist/_internal/components/data-display/DataViews/data-views-grid-bodies.js +12 -12
  48. package/dist/_internal/components/data-display/DataViews/data-views-grid-helpers.js +4 -4
  49. package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +34 -34
  50. package/dist/_internal/components/data-display/DataViews/data-views-header-row.js +4 -4
  51. package/dist/_internal/components/data-display/DataViews/data-views-inline-bar.js +13 -13
  52. package/dist/_internal/components/data-display/DataViews/data-views-layout-context.js +2 -2
  53. package/dist/_internal/components/data-display/DataViews/data-views-more-fields.js +4 -4
  54. package/dist/_internal/components/data-display/DataViews/data-views-more-filters.js +7 -7
  55. package/dist/_internal/components/data-display/DataViews/data-views-scope-tabs.js +3 -3
  56. package/dist/_internal/components/data-display/DataViews/data-views-select-all-strip.js +6 -6
  57. package/dist/_internal/components/data-display/DataViews/data-views-shell-toolbar.js +15 -15
  58. package/dist/_internal/components/data-display/DataViews/data-views-table-parts.js +18 -17
  59. package/dist/_internal/components/data-display/DataViews/data-views-toolbar.js +14 -14
  60. package/dist/_internal/components/data-display/DataViews/data-views-view-nav.js +6 -6
  61. package/dist/_internal/components/data-display/DataViews/list-card-rails.js +3 -3
  62. package/dist/_internal/components/data-display/DataViews/save-view-preview.js +4 -4
  63. package/dist/_internal/components/data-display/DataViews/use-data-views-state.js +7 -7
  64. package/dist/_internal/components/data-display/DataViews/use-saved-views-controller.js +2 -2
  65. package/dist/_internal/components/data-display/DescriptionItem/DescriptionItem.js +4 -4
  66. package/dist/_internal/components/data-display/FleetMap/FleetBody.js +11 -11
  67. package/dist/_internal/components/data-display/FleetMap/FleetCanvas.js +8 -8
  68. package/dist/_internal/components/data-display/FleetMap/FleetMap.js +13 -13
  69. package/dist/_internal/components/data-display/FleetMap/FleetRoster.js +2 -2
  70. package/dist/_internal/components/data-display/Lightbox/Lightbox.js +1 -1
  71. package/dist/_internal/components/data-display/MapPreview/MapDecorations.js +2 -2
  72. package/dist/_internal/components/data-display/MapPreview/MapPreview.hooks.js +2 -2
  73. package/dist/_internal/components/data-display/MapPreview/MapPreview.js +7 -7
  74. package/dist/_internal/components/data-display/MapPreview/MapTiles.js +2 -2
  75. package/dist/_internal/components/data-display/MapPreview/StaticMapView.js +4 -4
  76. package/dist/_internal/components/data-display/MapPreview/useMapPreview.js +3 -3
  77. package/dist/_internal/components/data-display/Progress/Progress.js +4 -4
  78. package/dist/_internal/components/data-display/Progress/Progress.metrics.js +2 -2
  79. package/dist/_internal/components/data-display/Progress/Progress.styles.js +3 -3
  80. package/dist/_internal/components/data-display/Sheet/Sheet.body.js +1 -1
  81. package/dist/_internal/components/data-display/Sheet/Sheet.js +4 -4
  82. package/dist/_internal/components/data-display/Sheet/Sheet.styles.js +1 -1
  83. package/dist/_internal/components/data-display/Table/Table.js +2 -2
  84. package/dist/_internal/components/data-display/index.js +43 -43
  85. package/dist/_internal/components/feedback/ConfirmAction/ConfirmButton.js +4 -4
  86. package/dist/_internal/components/feedback/index.js +4 -4
  87. package/dist/_internal/components/form/AddressAutocomplete/AddressAutocomplete.hooks.js +2 -2
  88. package/dist/_internal/components/form/AddressAutocomplete/AddressAutocomplete.js +5 -5
  89. package/dist/_internal/components/form/Autocomplete/Autocomplete.js +2 -2
  90. package/dist/_internal/components/form/Button/Button.js +3 -3
  91. package/dist/_internal/components/form/Button/Button.styles.js +2 -2
  92. package/dist/_internal/components/form/Calendar/Calendar.hooks.js +2 -2
  93. package/dist/_internal/components/form/Calendar/Calendar.js +3 -3
  94. package/dist/_internal/components/form/CategorySelect/CategoryPanel.js +1 -1
  95. package/dist/_internal/components/form/CategorySelect/CategorySelect.js +4 -4
  96. package/dist/_internal/components/form/Checkbox/Checkbox.js +2 -2
  97. package/dist/_internal/components/form/Command/Command.js +4 -4
  98. package/dist/_internal/components/form/Command/Command.styles.js +1 -1
  99. package/dist/_internal/components/form/DateRangePicker/DateRangePicker.js +5 -5
  100. package/dist/_internal/components/form/Label/Label.js +1 -1
  101. package/dist/_internal/components/form/Label/Label.styles.js +1 -1
  102. package/dist/_internal/components/form/Menubar/Menubar.item.js +1 -1
  103. package/dist/_internal/components/form/Menubar/Menubar.js +1 -1
  104. package/dist/_internal/components/form/Menubar/Menubar.styles.js +1 -1
  105. package/dist/_internal/components/form/Menubar/Menubar.toolbar.js +1 -1
  106. package/dist/_internal/components/form/PhoneInput/PhoneInput.hooks.js +2 -2
  107. package/dist/_internal/components/form/PhoneInput/PhoneInput.js +3 -3
  108. package/dist/_internal/components/form/RichTextEditor/RichTextEditor.js +2 -2
  109. package/dist/_internal/components/form/Switch/Switch.ids.js +8 -0
  110. package/dist/_internal/components/form/Switch/Switch.ids.js.map +1 -0
  111. package/dist/_internal/components/form/Switch/Switch.js +6 -5
  112. package/dist/_internal/components/form/Switch/Switch.metrics.js +5 -1
  113. package/dist/_internal/components/form/Switch/Switch.parts.js +6 -8
  114. package/dist/_internal/components/form/Switch/Switch.styles.js +5 -3
  115. package/dist/_internal/components/form/index.js +34 -33
  116. package/dist/_internal/components/form/total-form/Fields/CategoryField.js +5 -5
  117. package/dist/_internal/components/form/total-form/Fields/index.js +6 -6
  118. package/dist/_internal/components/form/total-form/SubmitButton.js +4 -4
  119. package/dist/_internal/components/index.js +83 -82
  120. package/dist/_internal/components/layout/Box/Box.js +4 -4
  121. package/dist/_internal/components/layout/Stack/Stack.js +5 -5
  122. package/dist/_internal/components/navigation/AppHeader/AppHeader.details.js +7 -7
  123. package/dist/_internal/components/navigation/AppHeader/AppHeader.identity.js +1 -1
  124. package/dist/_internal/components/navigation/Tabs/Tabs.js +1 -1
  125. package/dist/_internal/components/navigation/index.js +8 -8
  126. package/dist/_internal/components/typography/Heading/Heading.js +4 -4
  127. package/dist/_internal/components/typography/Heading/Heading.metrics.js +2 -2
  128. package/dist/_internal/components/typography/Heading/Heading.styles.js +3 -3
  129. package/dist/_internal/components/typography/Paragraph/Paragraph.js +2 -2
  130. package/dist/_internal/components/typography/Text/Text.js +3 -3
  131. package/dist/_internal/components/typography/Text/Text.metrics.js +2 -2
  132. package/dist/_internal/components/typography/index.js +7 -7
  133. package/dist/_internal/icons/Icon.js +4 -4
  134. package/dist/_internal/provider/UiProvider.js +3 -3
  135. package/dist/_internal/provider/mui-bridge.js +2 -2
  136. package/dist/_internal/provider/use-ui-theme.js +3 -3
  137. package/dist/_internal/social-login-button/social-login-button.js +9 -9
  138. package/dist/_internal/tokens/theme.js +3 -1
  139. package/dist/_internal/user-avatar/user-avatar.js +8 -8
  140. package/dist/charts.js +6 -6
  141. package/dist/{chunk-2GI7ANEL.js → chunk-22X7TT6Z.js} +4 -4
  142. package/dist/{chunk-WR5JFDQ5.js → chunk-27BL3DNT.js} +8 -8
  143. package/dist/{chunk-E55CJV65.js → chunk-2KVQIGVE.js} +2 -2
  144. package/dist/{chunk-BB2OUERT.js → chunk-2LSCK45B.js} +7 -4
  145. package/dist/chunk-2LSCK45B.js.map +1 -0
  146. package/dist/{chunk-W3FAKT3D.js → chunk-2SWQ6HIK.js} +4 -4
  147. package/dist/{chunk-ISW5K72V.js → chunk-2ZRZTGWP.js} +5 -5
  148. package/dist/{chunk-I5SBTNV2.js → chunk-3GB6KWHH.js} +2 -2
  149. package/dist/{chunk-ZEG2LNBY.js → chunk-3PJLT5FX.js} +2 -2
  150. package/dist/{chunk-CXLAJZSE.js → chunk-3VZT2FAI.js} +3 -3
  151. package/dist/{chunk-MLCFODJO.js → chunk-3W2IS5RH.js} +5 -1
  152. package/dist/{chunk-MLCFODJO.js.map → chunk-3W2IS5RH.js.map} +1 -1
  153. package/dist/{chunk-PFDM2OIP.js → chunk-45OHGD2B.js} +4 -4
  154. package/dist/{chunk-BH5BXLGI.js → chunk-4A2Q22HO.js} +3 -3
  155. package/dist/{chunk-46UPILLK.js → chunk-4ETQRBZC.js} +4 -4
  156. package/dist/{chunk-TWY5FOBY.js → chunk-5QUSX3TC.js} +5 -5
  157. package/dist/{chunk-AVGTTWTE.js → chunk-65DLYC4S.js} +4 -4
  158. package/dist/{chunk-TVPPA4RD.js → chunk-65METCKT.js} +16 -16
  159. package/dist/{chunk-OQFSYMHJ.js → chunk-67ALTEWH.js} +2 -2
  160. package/dist/{chunk-OGGHD64H.js → chunk-6SK3MTYJ.js} +2 -2
  161. package/dist/{chunk-OE2ZVL67.js → chunk-6VHCSPKK.js} +3 -3
  162. package/dist/{chunk-WAPJ2DL3.js → chunk-72T5PAW7.js} +4 -4
  163. package/dist/{chunk-SLVQ33AN.js → chunk-77DF5LKI.js} +2 -2
  164. package/dist/{chunk-7KWBGMQC.js → chunk-77OXG6DH.js} +5 -5
  165. package/dist/{chunk-Y3KRUT7O.js → chunk-7AIHK2XM.js} +2 -2
  166. package/dist/{chunk-MHV5Y5MR.js → chunk-7KEGJH3Q.js} +3 -3
  167. package/dist/{chunk-KMXAPYU2.js → chunk-7NEUPEV5.js} +2 -2
  168. package/dist/{chunk-67L7HMEP.js → chunk-7Z2AQEC5.js} +2 -2
  169. package/dist/{chunk-PQECNGDE.js → chunk-AGYGNNOM.js} +2 -2
  170. package/dist/{chunk-ZTF5C2GA.js → chunk-B5SW7I5W.js} +2 -2
  171. package/dist/{chunk-TXHJX2NG.js → chunk-BGYLL467.js} +4 -4
  172. package/dist/{chunk-R7R3LOKW.js → chunk-CA7TA36R.js} +2 -2
  173. package/dist/{chunk-FPFUXRD2.js → chunk-CKJI7JO5.js} +2 -2
  174. package/dist/{chunk-HMV4QMXS.js → chunk-CMN26J5Y.js} +4 -4
  175. package/dist/{chunk-KVEHH4SA.js → chunk-DB2MAYPK.js} +2 -2
  176. package/dist/{chunk-2ECT4IY2.js → chunk-DIHVWBQV.js} +36 -17
  177. package/dist/chunk-DIHVWBQV.js.map +1 -0
  178. package/dist/{chunk-V4FKHLEB.js → chunk-DTIB5KWP.js} +3 -3
  179. package/dist/{chunk-MESRKY67.js → chunk-DW6GBMLQ.js} +3 -3
  180. package/dist/{chunk-JO6BBSGY.js → chunk-DWJBOR47.js} +3 -3
  181. package/dist/{chunk-YW5T6KZ5.js → chunk-DYESJJ3Q.js} +9 -9
  182. package/dist/{chunk-TZDDL3DR.js → chunk-ECMJ5VPW.js} +2 -2
  183. package/dist/{chunk-OH3YGJT5.js → chunk-EMNGIYH6.js} +5 -5
  184. package/dist/{chunk-CZJLWCEG.js → chunk-EPNCYUQ7.js} +4 -4
  185. package/dist/{chunk-JZXWCEH5.js → chunk-EQA4VQEO.js} +2 -2
  186. package/dist/{chunk-3N6EK6K5.js → chunk-ERX4XIYC.js} +2 -2
  187. package/dist/{chunk-TTLI6PF7.js → chunk-FF3R67WD.js} +5 -5
  188. package/dist/{chunk-4Y6SPFKW.js → chunk-FOF2RAVQ.js} +4 -4
  189. package/dist/{chunk-KLREH4X6.js → chunk-G2JPUHEJ.js} +2 -2
  190. package/dist/{chunk-BBC4KT5G.js → chunk-G76H5PEM.js} +20 -2
  191. package/dist/chunk-G76H5PEM.js.map +1 -0
  192. package/dist/{chunk-4J5EN4FQ.js → chunk-GBX5ACPF.js} +5 -5
  193. package/dist/{chunk-ZZMZF7PZ.js → chunk-GQJ4NCZ6.js} +3 -3
  194. package/dist/{chunk-IPVYEPXO.js → chunk-GSTRPZS4.js} +5 -5
  195. package/dist/{chunk-HFXTAEYY.js → chunk-GTLJYAEG.js} +2 -2
  196. package/dist/{chunk-M4LFDGI6.js → chunk-GYQT47YZ.js} +2 -2
  197. package/dist/{chunk-JSH3HFDQ.js → chunk-H3BQFEN5.js} +2 -2
  198. package/dist/{chunk-OV4WREMW.js → chunk-HKB5C2KY.js} +7 -7
  199. package/dist/{chunk-BLBOYCOV.js → chunk-HKV4MQ2W.js} +5 -5
  200. package/dist/{chunk-4MGFUPQT.js → chunk-HOJL2GKW.js} +4 -4
  201. package/dist/{chunk-HR7YTBR7.js → chunk-IASDP44E.js} +4 -4
  202. package/dist/{chunk-YMRI5QKG.js → chunk-IV5QQLCS.js} +2 -2
  203. package/dist/{chunk-JUHUKZGU.js → chunk-JD3D6Y4U.js} +2 -2
  204. package/dist/{chunk-FR67FG2U.js → chunk-JFRKBSWI.js} +35 -25
  205. package/dist/chunk-JFRKBSWI.js.map +1 -0
  206. package/dist/{chunk-AXTLFK4T.js → chunk-KAV63FBG.js} +2 -2
  207. package/dist/{chunk-2PBGVMM2.js → chunk-KOFO6QZY.js} +2 -2
  208. package/dist/{chunk-RP5FK3SO.js → chunk-L7LCSZ3H.js} +3 -3
  209. package/dist/{chunk-MNXVXW4T.js → chunk-L7S6N67X.js} +2 -2
  210. package/dist/{chunk-JXPHU3K5.js → chunk-LGJ2H4AH.js} +5 -5
  211. package/dist/{chunk-W4YWU7LQ.js → chunk-LO2B7FDQ.js} +2 -2
  212. package/dist/{chunk-PWR7K5OP.js → chunk-LV4UTYAD.js} +2 -2
  213. package/dist/{chunk-OG2FP6SE.js → chunk-M4NFXC5R.js} +4 -4
  214. package/dist/{chunk-ZPIMPOHV.js → chunk-M7E66OSC.js} +4 -4
  215. package/dist/{chunk-OGGPQVIG.js → chunk-MDTSMJ7C.js} +3 -3
  216. package/dist/{chunk-YDI6IJ6F.js → chunk-MI2MVH3I.js} +4 -4
  217. package/dist/{chunk-UIZH4DAE.js → chunk-MQPT254A.js} +4 -4
  218. package/dist/{chunk-EWT3WMVY.js → chunk-MYH7VISV.js} +5 -5
  219. package/dist/{chunk-7NSX7A5H.js → chunk-N5PY7IXI.js} +3 -3
  220. package/dist/{chunk-BHIGHSXA.js → chunk-NNXZ5RK5.js} +4 -4
  221. package/dist/{chunk-EQ7PWGBN.js → chunk-O7HLQTB7.js} +3 -3
  222. package/dist/{chunk-DW5FRWRQ.js → chunk-OAWEUKUC.js} +2 -2
  223. package/dist/{chunk-O4VCZTK4.js → chunk-OGHW7RQC.js} +2 -2
  224. package/dist/{chunk-XR6WBW23.js → chunk-OVGASVPW.js} +2 -2
  225. package/dist/{chunk-HEBQS7QP.js → chunk-OXYR2HVK.js} +3 -3
  226. package/dist/{chunk-TNVO2DTB.js → chunk-P7FQUGED.js} +5 -5
  227. package/dist/{chunk-343TTIHD.js → chunk-PENJBKPH.js} +3 -3
  228. package/dist/{chunk-2RQINU5T.js → chunk-PKFFJAQ6.js} +2 -2
  229. package/dist/{chunk-M4LQRQFL.js → chunk-PW2WLDX3.js} +2 -2
  230. package/dist/{chunk-WRDPWEIC.js → chunk-Q3GSDSK2.js} +6 -6
  231. package/dist/{chunk-VNTOBLIB.js → chunk-Q3OFOOO7.js} +2 -2
  232. package/dist/{chunk-GGI7GM5O.js → chunk-QE2C35TO.js} +4 -4
  233. package/dist/{chunk-NQN5Z36J.js → chunk-QLI7ES7Z.js} +10 -1
  234. package/dist/chunk-QLI7ES7Z.js.map +1 -0
  235. package/dist/{chunk-CT5K725B.js → chunk-QQLGSMGE.js} +2 -2
  236. package/dist/{chunk-7MN6I5NK.js → chunk-QXFPTRHB.js} +3 -3
  237. package/dist/{chunk-CZPU5TW3.js → chunk-RFZU5BTG.js} +2 -2
  238. package/dist/{chunk-JB67KPGM.js → chunk-RRO2EOJB.js} +4 -4
  239. package/dist/{chunk-MZQTHSLN.js → chunk-S7HRED4D.js} +2 -2
  240. package/dist/{chunk-NYEA7JAI.js → chunk-SC72DRTX.js} +6 -6
  241. package/dist/{chunk-JWW2Z3RH.js → chunk-SMZBGHR2.js} +7 -7
  242. package/dist/{chunk-EZSEAYYT.js → chunk-SSWZHR46.js} +5 -5
  243. package/dist/{chunk-NA7MIEG6.js → chunk-SZETT7QV.js} +2 -2
  244. package/dist/chunk-SZS7VZJN.js +25 -0
  245. package/dist/chunk-SZS7VZJN.js.map +1 -0
  246. package/dist/{chunk-2HPP6RVC.js → chunk-TQOPF7LD.js} +2 -2
  247. package/dist/{chunk-OLVZ6TOV.js → chunk-TUO47RL2.js} +4 -4
  248. package/dist/{chunk-N5IVVLTH.js → chunk-UG76BO5K.js} +79 -19
  249. package/dist/chunk-UG76BO5K.js.map +1 -0
  250. package/dist/{chunk-4IVDVZZ2.js → chunk-UGL6SJN6.js} +3 -3
  251. package/dist/{chunk-QJRDDVZ2.js → chunk-V5P5Q6HM.js} +3 -3
  252. package/dist/{chunk-73NJCGQG.js → chunk-VIK3HAUQ.js} +2 -2
  253. package/dist/{chunk-7LCXGJN5.js → chunk-VK4ULJFH.js} +2 -2
  254. package/dist/{chunk-QYNCPS5W.js → chunk-WBKWIFXA.js} +6 -6
  255. package/dist/{chunk-X4Z62ZQY.js → chunk-WETAIIKC.js} +2 -2
  256. package/dist/{chunk-GMTM6EN7.js → chunk-WKF54CCK.js} +7 -7
  257. package/dist/{chunk-KT6HWAEN.js → chunk-WZUNBSS7.js} +2 -2
  258. package/dist/{chunk-Y2B3I3IH.js → chunk-X5RDHO6G.js} +2 -2
  259. package/dist/{chunk-TXKZEKJN.js → chunk-XNOSTV5F.js} +2 -2
  260. package/dist/{chunk-7JXLGOM2.js → chunk-Y55ILY2F.js} +3 -3
  261. package/dist/{chunk-HI2OFZSZ.js → chunk-YPILHGEO.js} +2 -2
  262. package/dist/{chunk-V3PLFYKO.js → chunk-ZAJO2B75.js} +2 -2
  263. package/dist/data-display/Alert.js +4 -4
  264. package/dist/data-display/Avatar.js +3 -3
  265. package/dist/data-display/Badge.js +7 -7
  266. package/dist/data-display/Banner.js +4 -4
  267. package/dist/data-display/CardKit.js +13 -13
  268. package/dist/data-display/Carousel.js +1 -1
  269. package/dist/data-display/Chart.js +6 -6
  270. package/dist/data-display/DataViews.js +68 -67
  271. package/dist/data-display/DescriptionItem.js +4 -4
  272. package/dist/data-display/FleetMap.js +13 -13
  273. package/dist/data-display/Lightbox.js +1 -1
  274. package/dist/data-display/MapPreview.js +7 -7
  275. package/dist/data-display/Progress.js +4 -4
  276. package/dist/data-display/Sheet.js +4 -4
  277. package/dist/data-display/Table.js +2 -2
  278. package/dist/feedback/ConfirmAction.js +4 -4
  279. package/dist/form/AddressAutocomplete.js +5 -5
  280. package/dist/form/Autocomplete.js +2 -2
  281. package/dist/form/Button.js +3 -3
  282. package/dist/form/Calendar.js +3 -3
  283. package/dist/form/CategorySelect.js +4 -4
  284. package/dist/form/Checkbox.js +2 -2
  285. package/dist/form/Command.js +4 -4
  286. package/dist/form/DateRangePicker.js +10 -10
  287. package/dist/form/Label.js +1 -1
  288. package/dist/form/Menubar.js +1 -1
  289. package/dist/form/PhoneInput.js +3 -3
  290. package/dist/form/RichTextEditor.js +2 -2
  291. package/dist/form/Switch.js +6 -5
  292. package/dist/form/total-form.js +10 -10
  293. package/dist/icons.js +4 -4
  294. package/dist/layout/Box.js +4 -4
  295. package/dist/layout/Stack.js +5 -5
  296. package/dist/native/chunks/{chunk-2R2R35C5.js → chunk-2SBTJSQE.js} +5 -5
  297. package/dist/native/chunks/{chunk-WL5LXVCK.js → chunk-6L4UZBQP.js} +3 -3
  298. package/dist/native/chunks/{chunk-LEMMXZFN.js → chunk-MP3UDWTT.js} +10 -1
  299. package/dist/native/chunks/{chunk-LEMMXZFN.js.map → chunk-MP3UDWTT.js.map} +1 -1
  300. package/dist/native/chunks/{chunk-GW7TQ7HO.js → chunk-QEQZ5AF6.js} +3 -3
  301. package/dist/native/chunks/{chunk-7LTVGW23.js → chunk-UII3IFLP.js} +2 -2
  302. package/dist/native/chunks/{chunk-75JQYVDZ.js → chunk-UYREIOEM.js} +2 -2
  303. package/dist/native/chunks/{chunk-GWGIWQO7.js → chunk-XI7HTAVN.js} +2 -2
  304. package/dist/native/chunks/{chunk-QYUD3S6F.js → chunk-ZOP7UAZK.js} +2 -2
  305. package/dist/native/data-display/Alert.js +3 -3
  306. package/dist/native/data-display/Avatar.js +3 -3
  307. package/dist/native/data-display/Badge.js +3 -3
  308. package/dist/native/data-display/Chip.js +3 -3
  309. package/dist/native/data-display/EmptyState.js +5 -5
  310. package/dist/native/data-display/ErrorState.js +4 -4
  311. package/dist/native/data-display/FleetMap.js +6 -6
  312. package/dist/native/data-display/LoadingState.js +2 -2
  313. package/dist/native/data-display/Progress.js +2 -2
  314. package/dist/native/feedback/Dialog.js +3 -3
  315. package/dist/native/form/Button.js +3 -3
  316. package/dist/native/form/Checkbox.js +3 -3
  317. package/dist/native/form/Input.js +3 -3
  318. package/dist/native/form/Select.js +4 -4
  319. package/dist/native/form/Switch.js +26 -8
  320. package/dist/native/form/Switch.js.map +1 -1
  321. package/dist/native/icons.js +3 -3
  322. package/dist/native/layout/Box.js +3 -3
  323. package/dist/native/layout/Card.js +2 -2
  324. package/dist/native/layout/Container.js +2 -2
  325. package/dist/native/layout/Skeleton.js +3 -3
  326. package/dist/native/layout/Spacer.js +2 -2
  327. package/dist/native/layout/Stack.js +3 -3
  328. package/dist/native/provider.js +2 -2
  329. package/dist/native/tokens.js +3 -1
  330. package/dist/native/typography/Heading.js +2 -2
  331. package/dist/native/typography/Paragraph.js +2 -2
  332. package/dist/native/typography/Text.js +2 -2
  333. package/dist/navigation/AppHeader.js +7 -7
  334. package/dist/navigation/Tabs.js +1 -1
  335. package/dist/provider.js +4 -4
  336. package/dist/social-login-button.js +9 -9
  337. package/dist/tokens.js +3 -1
  338. package/dist/types/components/form/Button/Button.styles.d.ts.map +1 -1
  339. package/dist/types/components/form/Switch/Switch.d.ts.map +1 -1
  340. package/dist/types/components/form/Switch/Switch.ids.d.ts +42 -0
  341. package/dist/types/components/form/Switch/Switch.ids.d.ts.map +1 -0
  342. package/dist/types/components/form/Switch/Switch.metrics.d.ts +19 -0
  343. package/dist/types/components/form/Switch/Switch.metrics.d.ts.map +1 -1
  344. package/dist/types/components/form/Switch/Switch.parts.d.ts +31 -11
  345. package/dist/types/components/form/Switch/Switch.parts.d.ts.map +1 -1
  346. package/dist/types/components/form/Switch/Switch.styles.d.ts +6 -0
  347. package/dist/types/components/form/Switch/Switch.styles.d.ts.map +1 -1
  348. package/dist/types/components/navigation/Tabs/Tabs.d.ts.map +1 -1
  349. package/dist/types/tokens/theme.d.ts +38 -0
  350. package/dist/types/tokens/theme.d.ts.map +1 -1
  351. package/dist/types-native/components/form/Switch/Switch.look.native.d.ts +26 -2
  352. package/dist/types-native/components/form/Switch/Switch.look.native.d.ts.map +1 -1
  353. package/dist/types-native/components/form/Switch/Switch.metrics.d.ts +19 -0
  354. package/dist/types-native/components/form/Switch/Switch.metrics.d.ts.map +1 -1
  355. package/dist/types-native/components/form/Switch/Switch.native.d.ts.map +1 -1
  356. package/dist/types-native/tokens/theme.d.ts +38 -0
  357. package/dist/types-native/tokens/theme.d.ts.map +1 -1
  358. package/dist/typography/Heading.js +4 -4
  359. package/dist/typography/Paragraph.js +2 -2
  360. package/dist/typography/Text.js +3 -3
  361. package/dist/user-avatar.js +8 -8
  362. package/package.json +1 -1
  363. package/src/components/form/Button/Button.md +8 -0
  364. package/src/components/form/Button/Button.styles.ts +24 -3
  365. package/src/components/form/Switch/Switch.ids.ts +63 -0
  366. package/src/components/form/Switch/Switch.look.native.ts +45 -2
  367. package/src/components/form/Switch/Switch.md +34 -9
  368. package/src/components/form/Switch/Switch.metrics.ts +21 -0
  369. package/src/components/form/Switch/Switch.native.tsx +19 -6
  370. package/src/components/form/Switch/Switch.parts.tsx +150 -17
  371. package/src/components/form/Switch/Switch.styles.ts +59 -6
  372. package/src/components/form/Switch/Switch.tsx +32 -30
  373. package/src/components/navigation/Tabs/Tabs.tsx +46 -1
  374. package/src/tokens/theme.ts +50 -0
  375. package/dist/chunk-2ECT4IY2.js.map +0 -1
  376. package/dist/chunk-BB2OUERT.js.map +0 -1
  377. package/dist/chunk-BBC4KT5G.js.map +0 -1
  378. package/dist/chunk-FR67FG2U.js.map +0 -1
  379. package/dist/chunk-N5IVVLTH.js.map +0 -1
  380. package/dist/chunk-NQN5Z36J.js.map +0 -1
  381. /package/dist/{chunk-2GI7ANEL.js.map → chunk-22X7TT6Z.js.map} +0 -0
  382. /package/dist/{chunk-WR5JFDQ5.js.map → chunk-27BL3DNT.js.map} +0 -0
  383. /package/dist/{chunk-E55CJV65.js.map → chunk-2KVQIGVE.js.map} +0 -0
  384. /package/dist/{chunk-W3FAKT3D.js.map → chunk-2SWQ6HIK.js.map} +0 -0
  385. /package/dist/{chunk-ISW5K72V.js.map → chunk-2ZRZTGWP.js.map} +0 -0
  386. /package/dist/{chunk-I5SBTNV2.js.map → chunk-3GB6KWHH.js.map} +0 -0
  387. /package/dist/{chunk-ZEG2LNBY.js.map → chunk-3PJLT5FX.js.map} +0 -0
  388. /package/dist/{chunk-CXLAJZSE.js.map → chunk-3VZT2FAI.js.map} +0 -0
  389. /package/dist/{chunk-PFDM2OIP.js.map → chunk-45OHGD2B.js.map} +0 -0
  390. /package/dist/{chunk-BH5BXLGI.js.map → chunk-4A2Q22HO.js.map} +0 -0
  391. /package/dist/{chunk-46UPILLK.js.map → chunk-4ETQRBZC.js.map} +0 -0
  392. /package/dist/{chunk-TWY5FOBY.js.map → chunk-5QUSX3TC.js.map} +0 -0
  393. /package/dist/{chunk-AVGTTWTE.js.map → chunk-65DLYC4S.js.map} +0 -0
  394. /package/dist/{chunk-TVPPA4RD.js.map → chunk-65METCKT.js.map} +0 -0
  395. /package/dist/{chunk-OQFSYMHJ.js.map → chunk-67ALTEWH.js.map} +0 -0
  396. /package/dist/{chunk-OGGHD64H.js.map → chunk-6SK3MTYJ.js.map} +0 -0
  397. /package/dist/{chunk-OE2ZVL67.js.map → chunk-6VHCSPKK.js.map} +0 -0
  398. /package/dist/{chunk-WAPJ2DL3.js.map → chunk-72T5PAW7.js.map} +0 -0
  399. /package/dist/{chunk-SLVQ33AN.js.map → chunk-77DF5LKI.js.map} +0 -0
  400. /package/dist/{chunk-7KWBGMQC.js.map → chunk-77OXG6DH.js.map} +0 -0
  401. /package/dist/{chunk-Y3KRUT7O.js.map → chunk-7AIHK2XM.js.map} +0 -0
  402. /package/dist/{chunk-MHV5Y5MR.js.map → chunk-7KEGJH3Q.js.map} +0 -0
  403. /package/dist/{chunk-KMXAPYU2.js.map → chunk-7NEUPEV5.js.map} +0 -0
  404. /package/dist/{chunk-67L7HMEP.js.map → chunk-7Z2AQEC5.js.map} +0 -0
  405. /package/dist/{chunk-PQECNGDE.js.map → chunk-AGYGNNOM.js.map} +0 -0
  406. /package/dist/{chunk-ZTF5C2GA.js.map → chunk-B5SW7I5W.js.map} +0 -0
  407. /package/dist/{chunk-TXHJX2NG.js.map → chunk-BGYLL467.js.map} +0 -0
  408. /package/dist/{chunk-R7R3LOKW.js.map → chunk-CA7TA36R.js.map} +0 -0
  409. /package/dist/{chunk-FPFUXRD2.js.map → chunk-CKJI7JO5.js.map} +0 -0
  410. /package/dist/{chunk-HMV4QMXS.js.map → chunk-CMN26J5Y.js.map} +0 -0
  411. /package/dist/{chunk-KVEHH4SA.js.map → chunk-DB2MAYPK.js.map} +0 -0
  412. /package/dist/{chunk-V4FKHLEB.js.map → chunk-DTIB5KWP.js.map} +0 -0
  413. /package/dist/{chunk-MESRKY67.js.map → chunk-DW6GBMLQ.js.map} +0 -0
  414. /package/dist/{chunk-JO6BBSGY.js.map → chunk-DWJBOR47.js.map} +0 -0
  415. /package/dist/{chunk-YW5T6KZ5.js.map → chunk-DYESJJ3Q.js.map} +0 -0
  416. /package/dist/{chunk-TZDDL3DR.js.map → chunk-ECMJ5VPW.js.map} +0 -0
  417. /package/dist/{chunk-OH3YGJT5.js.map → chunk-EMNGIYH6.js.map} +0 -0
  418. /package/dist/{chunk-CZJLWCEG.js.map → chunk-EPNCYUQ7.js.map} +0 -0
  419. /package/dist/{chunk-JZXWCEH5.js.map → chunk-EQA4VQEO.js.map} +0 -0
  420. /package/dist/{chunk-3N6EK6K5.js.map → chunk-ERX4XIYC.js.map} +0 -0
  421. /package/dist/{chunk-TTLI6PF7.js.map → chunk-FF3R67WD.js.map} +0 -0
  422. /package/dist/{chunk-4Y6SPFKW.js.map → chunk-FOF2RAVQ.js.map} +0 -0
  423. /package/dist/{chunk-KLREH4X6.js.map → chunk-G2JPUHEJ.js.map} +0 -0
  424. /package/dist/{chunk-4J5EN4FQ.js.map → chunk-GBX5ACPF.js.map} +0 -0
  425. /package/dist/{chunk-ZZMZF7PZ.js.map → chunk-GQJ4NCZ6.js.map} +0 -0
  426. /package/dist/{chunk-IPVYEPXO.js.map → chunk-GSTRPZS4.js.map} +0 -0
  427. /package/dist/{chunk-HFXTAEYY.js.map → chunk-GTLJYAEG.js.map} +0 -0
  428. /package/dist/{chunk-M4LFDGI6.js.map → chunk-GYQT47YZ.js.map} +0 -0
  429. /package/dist/{chunk-JSH3HFDQ.js.map → chunk-H3BQFEN5.js.map} +0 -0
  430. /package/dist/{chunk-OV4WREMW.js.map → chunk-HKB5C2KY.js.map} +0 -0
  431. /package/dist/{chunk-BLBOYCOV.js.map → chunk-HKV4MQ2W.js.map} +0 -0
  432. /package/dist/{chunk-4MGFUPQT.js.map → chunk-HOJL2GKW.js.map} +0 -0
  433. /package/dist/{chunk-HR7YTBR7.js.map → chunk-IASDP44E.js.map} +0 -0
  434. /package/dist/{chunk-YMRI5QKG.js.map → chunk-IV5QQLCS.js.map} +0 -0
  435. /package/dist/{chunk-JUHUKZGU.js.map → chunk-JD3D6Y4U.js.map} +0 -0
  436. /package/dist/{chunk-AXTLFK4T.js.map → chunk-KAV63FBG.js.map} +0 -0
  437. /package/dist/{chunk-2PBGVMM2.js.map → chunk-KOFO6QZY.js.map} +0 -0
  438. /package/dist/{chunk-RP5FK3SO.js.map → chunk-L7LCSZ3H.js.map} +0 -0
  439. /package/dist/{chunk-MNXVXW4T.js.map → chunk-L7S6N67X.js.map} +0 -0
  440. /package/dist/{chunk-JXPHU3K5.js.map → chunk-LGJ2H4AH.js.map} +0 -0
  441. /package/dist/{chunk-W4YWU7LQ.js.map → chunk-LO2B7FDQ.js.map} +0 -0
  442. /package/dist/{chunk-PWR7K5OP.js.map → chunk-LV4UTYAD.js.map} +0 -0
  443. /package/dist/{chunk-OG2FP6SE.js.map → chunk-M4NFXC5R.js.map} +0 -0
  444. /package/dist/{chunk-ZPIMPOHV.js.map → chunk-M7E66OSC.js.map} +0 -0
  445. /package/dist/{chunk-OGGPQVIG.js.map → chunk-MDTSMJ7C.js.map} +0 -0
  446. /package/dist/{chunk-YDI6IJ6F.js.map → chunk-MI2MVH3I.js.map} +0 -0
  447. /package/dist/{chunk-UIZH4DAE.js.map → chunk-MQPT254A.js.map} +0 -0
  448. /package/dist/{chunk-EWT3WMVY.js.map → chunk-MYH7VISV.js.map} +0 -0
  449. /package/dist/{chunk-7NSX7A5H.js.map → chunk-N5PY7IXI.js.map} +0 -0
  450. /package/dist/{chunk-BHIGHSXA.js.map → chunk-NNXZ5RK5.js.map} +0 -0
  451. /package/dist/{chunk-EQ7PWGBN.js.map → chunk-O7HLQTB7.js.map} +0 -0
  452. /package/dist/{chunk-DW5FRWRQ.js.map → chunk-OAWEUKUC.js.map} +0 -0
  453. /package/dist/{chunk-O4VCZTK4.js.map → chunk-OGHW7RQC.js.map} +0 -0
  454. /package/dist/{chunk-XR6WBW23.js.map → chunk-OVGASVPW.js.map} +0 -0
  455. /package/dist/{chunk-HEBQS7QP.js.map → chunk-OXYR2HVK.js.map} +0 -0
  456. /package/dist/{chunk-TNVO2DTB.js.map → chunk-P7FQUGED.js.map} +0 -0
  457. /package/dist/{chunk-343TTIHD.js.map → chunk-PENJBKPH.js.map} +0 -0
  458. /package/dist/{chunk-2RQINU5T.js.map → chunk-PKFFJAQ6.js.map} +0 -0
  459. /package/dist/{chunk-M4LQRQFL.js.map → chunk-PW2WLDX3.js.map} +0 -0
  460. /package/dist/{chunk-WRDPWEIC.js.map → chunk-Q3GSDSK2.js.map} +0 -0
  461. /package/dist/{chunk-VNTOBLIB.js.map → chunk-Q3OFOOO7.js.map} +0 -0
  462. /package/dist/{chunk-GGI7GM5O.js.map → chunk-QE2C35TO.js.map} +0 -0
  463. /package/dist/{chunk-CT5K725B.js.map → chunk-QQLGSMGE.js.map} +0 -0
  464. /package/dist/{chunk-7MN6I5NK.js.map → chunk-QXFPTRHB.js.map} +0 -0
  465. /package/dist/{chunk-CZPU5TW3.js.map → chunk-RFZU5BTG.js.map} +0 -0
  466. /package/dist/{chunk-JB67KPGM.js.map → chunk-RRO2EOJB.js.map} +0 -0
  467. /package/dist/{chunk-MZQTHSLN.js.map → chunk-S7HRED4D.js.map} +0 -0
  468. /package/dist/{chunk-NYEA7JAI.js.map → chunk-SC72DRTX.js.map} +0 -0
  469. /package/dist/{chunk-JWW2Z3RH.js.map → chunk-SMZBGHR2.js.map} +0 -0
  470. /package/dist/{chunk-EZSEAYYT.js.map → chunk-SSWZHR46.js.map} +0 -0
  471. /package/dist/{chunk-NA7MIEG6.js.map → chunk-SZETT7QV.js.map} +0 -0
  472. /package/dist/{chunk-2HPP6RVC.js.map → chunk-TQOPF7LD.js.map} +0 -0
  473. /package/dist/{chunk-OLVZ6TOV.js.map → chunk-TUO47RL2.js.map} +0 -0
  474. /package/dist/{chunk-4IVDVZZ2.js.map → chunk-UGL6SJN6.js.map} +0 -0
  475. /package/dist/{chunk-QJRDDVZ2.js.map → chunk-V5P5Q6HM.js.map} +0 -0
  476. /package/dist/{chunk-73NJCGQG.js.map → chunk-VIK3HAUQ.js.map} +0 -0
  477. /package/dist/{chunk-7LCXGJN5.js.map → chunk-VK4ULJFH.js.map} +0 -0
  478. /package/dist/{chunk-QYNCPS5W.js.map → chunk-WBKWIFXA.js.map} +0 -0
  479. /package/dist/{chunk-X4Z62ZQY.js.map → chunk-WETAIIKC.js.map} +0 -0
  480. /package/dist/{chunk-GMTM6EN7.js.map → chunk-WKF54CCK.js.map} +0 -0
  481. /package/dist/{chunk-KT6HWAEN.js.map → chunk-WZUNBSS7.js.map} +0 -0
  482. /package/dist/{chunk-Y2B3I3IH.js.map → chunk-X5RDHO6G.js.map} +0 -0
  483. /package/dist/{chunk-TXKZEKJN.js.map → chunk-XNOSTV5F.js.map} +0 -0
  484. /package/dist/{chunk-7JXLGOM2.js.map → chunk-Y55ILY2F.js.map} +0 -0
  485. /package/dist/{chunk-HI2OFZSZ.js.map → chunk-YPILHGEO.js.map} +0 -0
  486. /package/dist/{chunk-V3PLFYKO.js.map → chunk-ZAJO2B75.js.map} +0 -0
  487. /package/dist/native/chunks/{chunk-2R2R35C5.js.map → chunk-2SBTJSQE.js.map} +0 -0
  488. /package/dist/native/chunks/{chunk-WL5LXVCK.js.map → chunk-6L4UZBQP.js.map} +0 -0
  489. /package/dist/native/chunks/{chunk-GW7TQ7HO.js.map → chunk-QEQZ5AF6.js.map} +0 -0
  490. /package/dist/native/chunks/{chunk-7LTVGW23.js.map → chunk-UII3IFLP.js.map} +0 -0
  491. /package/dist/native/chunks/{chunk-75JQYVDZ.js.map → chunk-UYREIOEM.js.map} +0 -0
  492. /package/dist/native/chunks/{chunk-GWGIWQO7.js.map → chunk-XI7HTAVN.js.map} +0 -0
  493. /package/dist/native/chunks/{chunk-QYUD3S6F.js.map → chunk-ZOP7UAZK.js.map} +0 -0
@@ -26,6 +26,7 @@ import {
26
26
  SWITCH_RIPPLE,
27
27
  SWITCH_SPINNER,
28
28
  SWITCH_TRANSITION,
29
+ RESTING_THUMB,
29
30
  THUMB_ELEVATION,
30
31
  THUMB_RADIUS,
31
32
  TRACK_LABEL,
@@ -41,7 +42,7 @@ import {
41
42
  } from './Switch.metrics';
42
43
  import type { SwitchVariant } from './Switch.base';
43
44
 
44
- import { px } from '../../../tokens/theme';
45
+ import { inkOver, px } from '../../../tokens/theme';
45
46
  import type { ColorValue, SizeValue } from '../../../tokens/vocabulary';
46
47
 
47
48
  // Every number below comes from `./Switch.metrics`, which the native renderer
@@ -125,6 +126,32 @@ const rippleOverlay = (palette: ColorPalette): CSSObject => ({
125
126
  pointerEvents: 'none',
126
127
  });
127
128
 
129
+ /**
130
+ * The ink on the CHECKED track — the thumb, the `on` wording and any on-icon
131
+ * (FUT-1924).
132
+ *
133
+ * All three stated `#fff`, and the checked track is `palette.main`: the one
134
+ * surface in this component the TENANT picks. A store with a pale brand got a
135
+ * white thumb on a pale green bar, which does not read as a knob at all — the
136
+ * switch looks OFF while it is on, so this is a state a user misreads rather
137
+ * than a colour they dislike.
138
+ *
139
+ * The `gradient` flag paints the track `light → main → dark`, so the fills the
140
+ * thumb travels over are handed over together and {@link inkOver} takes the
141
+ * worst of them.
142
+ *
143
+ * The RESTING track is not here on purpose: it is `theme.palette.action.disabled`
144
+ * washed over the page, which no tenant chooses, and a white thumb on it is the
145
+ * conventional look in both modes.
146
+ */
147
+ const checkedInk = (flags: SwitchFlags, palette: ColorPalette): string => {
148
+ const fills = flags.gradient
149
+ ? [palette.light || palette.main, palette.main, palette.dark || palette.main]
150
+ : [palette.main];
151
+
152
+ return inkOver(fills, palette.contrastText || NEUTRAL_CONTRAST);
153
+ };
154
+
128
155
  /** The checked track: the filled bar behind the thumb once the switch is on. */
129
156
  const checkedTrack = (flags: SwitchFlags, palette: ColorPalette): CSSObject => ({
130
157
  backgroundColor: palette.main,
@@ -170,9 +197,12 @@ const switchBaseSx = (
170
197
  // The thumb travels the track minus its own width and both paddings; the
171
198
  // iOS look insets differently, so it gets its own distance.
172
199
  transform: `translateX(${width - thumbSize - padding * 2}px)`,
173
- color: '#fff',
200
+ color: checkedInk(flags, palette),
174
201
  '& .MuiSwitch-thumb': {
175
202
  animation: flags.loading ? 'none' : `${bounceAnimation} ${seconds(SWITCH_TRANSITION.ms)} ease-out`,
203
+ // `glass` draws its own translucent thumb and means to show the track
204
+ // through it, so it keeps the fill it chose.
205
+ ...(flags.glass ? {} : { backgroundColor: checkedInk(flags, palette) }),
176
206
  },
177
207
  '& + .MuiSwitch-track': checkedTrack(flags, palette),
178
208
  '&.Mui-disabled + .MuiSwitch-track': { opacity: DISABLED.checkedTrackOpacity },
@@ -197,7 +227,9 @@ const thumbSx = (
197
227
  width: thumbSize,
198
228
  height: thumbSize,
199
229
  borderRadius: THUMB_RADIUS[look](thumbSize),
200
- backgroundColor: '#fff',
230
+ // `.Mui-checked` above replaces this for the brand-filled track; see
231
+ // {@link RESTING_THUMB} for why the resting one stays white.
232
+ backgroundColor: RESTING_THUMB,
201
233
  boxShadow: thumbShadow(theme, look),
202
234
  transition: `all ${seconds(SWITCH_TRANSITION.ms)} ${SWITCH_TRANSITION.easing}`,
203
235
  position: 'relative',
@@ -239,7 +271,13 @@ const thumbSx = (
239
271
  });
240
272
 
241
273
  /** The on/off wording the `label` variant prints inside the track. */
242
- const trackLabels = (theme: Theme, onText?: string, offText?: string): CSSObject => ({
274
+ const trackLabels = (
275
+ theme: Theme,
276
+ flags: SwitchFlags,
277
+ palette: ColorPalette,
278
+ onText?: string,
279
+ offText?: string,
280
+ ): CSSObject => ({
243
281
  display: 'flex',
244
282
  alignItems: 'center',
245
283
  justifyContent: 'space-between',
@@ -258,7 +296,13 @@ const trackLabels = (theme: Theme, onText?: string, offText?: string): CSSObject
258
296
  zIndex: 1,
259
297
  },
260
298
  ...(onText && {
261
- '&::before': { content: `"${onText}"`, left: theme.spacing(TRACK_LABEL.insetUnits), color: '#fff' },
299
+ '&::before': {
300
+ content: `"${onText}"`,
301
+ left: theme.spacing(TRACK_LABEL.insetUnits),
302
+ // The `on` word sits at the end the thumb travels TO, which is the
303
+ // filled half of the track once checked.
304
+ color: checkedInk(flags, palette),
305
+ },
262
306
  }),
263
307
  ...(offText && {
264
308
  '&::after': {
@@ -297,10 +341,19 @@ const trackSx = (
297
341
  !glass && {
298
342
  background: `linear-gradient(${SWITCH_GRADIENT.resting.angleDeg}deg, ${alpha(palette.light || palette.main, SWITCH_GRADIENT.resting.lightAlpha)}, ${alpha(palette.main, SWITCH_GRADIENT.resting.mainAlpha)})`,
299
343
  }),
300
- ...(showsTrackLabels(customVariant, onText, offText) && trackLabels(theme, onText, offText)),
344
+ ...(showsTrackLabels(customVariant, onText, offText) &&
345
+ trackLabels(theme, flags, palette, onText, offText)),
301
346
  };
302
347
  };
303
348
 
349
+ /**
350
+ * The same checked-track ink, for the two ICONS the control overlays on the
351
+ * track — which are drawn as components rather than styles, so they cannot
352
+ * reach {@link checkedInk} directly.
353
+ */
354
+ export const onTrackInk = (theme: Theme, flags: SwitchFlags): string =>
355
+ checkedInk(flags, getColorFromTheme(theme, flags.customColor ?? 'primary'));
356
+
304
357
  export const switchSx = (theme: Theme, flags: SwitchFlags): CSSObject => {
305
358
  const palette = getColorFromTheme(theme, flags.customColor ?? 'primary');
306
359
  const geometry = geometryOf(flags.customSize, flags.trackWidth, flags.trackHeight);
@@ -1,15 +1,11 @@
1
1
  import Box from '@mui/material/Box/index.js';
2
- import React, { forwardRef } from 'react';
2
+ import React, { forwardRef, useId } from 'react';
3
3
 
4
4
  import { splitTestId } from '../../../platform/test-id';
5
5
  import { withDefaults } from '../../../utils/withDefaults';
6
6
 
7
- import {
8
- LabelContainer,
9
- SwitchControl,
10
- SwitchHelper,
11
- SwitchLabel,
12
- } from './Switch.parts';
7
+ import { switchIds } from './Switch.ids';
8
+ import { SwitchControl, SwitchHelper, SwitchRow } from './Switch.parts';
13
9
  import type { SwitchProps } from './Switch.types';
14
10
 
15
11
  const DEFAULTS = {
@@ -34,12 +30,24 @@ export const Switch = forwardRef<HTMLButtonElement, SwitchProps>((props, ref) =>
34
30
  variant, color, size, label, description, glow, glass, gradient, labelPosition,
35
31
  onIcon, offIcon, onText, offText, error, helperText, trackWidth, trackHeight,
36
32
  checked, onChange, animated, loading, ripple, pulse,
33
+ id, inputProps,
37
34
  ...others
38
35
  } = withDefaults(props, DEFAULTS) as ResolvedProps;
39
36
 
40
37
  const { testId: dataTestId, rest } = splitTestId(others);
41
38
  const containerTestId = dataTestId ? `${dataTestId}-container` : 'switch-container';
42
39
 
40
+ // The input needs an id for the label to point at, and the caller usually has
41
+ // no reason to invent one — see {@link switchIds} for the precedence.
42
+ const { inputId, descriptionId, helperId, describedBy } = switchIds({
43
+ generated: useId(),
44
+ id,
45
+ inputProps,
46
+ description,
47
+ helperText,
48
+ callerDescribedBy: rest['aria-describedby'],
49
+ });
50
+
43
51
  const control = (
44
52
  <SwitchControl
45
53
  customVariant={variant}
@@ -63,36 +71,30 @@ export const Switch = forwardRef<HTMLButtonElement, SwitchProps>((props, ref) =>
63
71
  size={size}
64
72
  dataTestId={dataTestId}
65
73
  switchRef={ref}
74
+ inputId={inputId}
75
+ inputProps={inputProps}
76
+ describedBy={describedBy}
66
77
  rest={rest}
67
78
  />
68
79
  );
69
80
 
70
- const helper = <SwitchHelper helperText={helperText} error={error} dataTestId={dataTestId} />;
71
-
72
- if (!label) {
73
- return (
74
- <Box data-testid={containerTestId}>
75
- {control}
76
- {helper}
77
- </Box>
78
- );
79
- }
81
+ const helper = (
82
+ <SwitchHelper helperText={helperText} error={error} dataTestId={dataTestId} id={helperId} />
83
+ );
80
84
 
81
85
  return (
82
86
  <Box data-testid={containerTestId}>
83
- <LabelContainer labelPosition={labelPosition} error={error}>
84
- {labelPosition === 'start' && control}
85
-
86
- <SwitchLabel
87
- label={label}
88
- description={description}
89
- error={error}
90
- dataTestId={dataTestId}
91
- />
92
-
93
- {labelPosition !== 'start' && control}
94
- </LabelContainer>
95
-
87
+ <SwitchRow
88
+ label={label}
89
+ description={description}
90
+ labelPosition={labelPosition}
91
+ error={error}
92
+ dataTestId={dataTestId}
93
+ htmlFor={inputId}
94
+ descriptionId={descriptionId}
95
+ disabled={Boolean(rest.disabled) || loading}
96
+ control={control}
97
+ />
96
98
  {helper}
97
99
  </Box>
98
100
  );
@@ -59,6 +59,47 @@ const TABS_DEFAULTS: Partial<TabsProps> = {
59
59
  disabled: false,
60
60
  loading: false };
61
61
 
62
+ /**
63
+ * The props this component OWNS and MUI's `Tabs` does not understand (12-86).
64
+ *
65
+ * `rest` below is spread onto the DOM node, so anything left in it that React
66
+ * cannot place on an element is reported — five `does not recognize the … prop`
67
+ * warnings and three `Received false for a non-boolean attribute`, on every
68
+ * render, in the browser console and in every host's jsdom output.
69
+ *
70
+ * An explicit list rather than `Object.keys(TABS_DEFAULTS)`, because the two
71
+ * sets differ in both directions: `items`, `closeTabLabel`, `tabPanelProps` and
72
+ * `loadingComponent` have no default and still must not reach the DOM, while
73
+ * `orientation`, `centered` and `indicatorColor` are real MUI props that must.
74
+ * An omission rather than more destructuring, so a prop added to `TabsProps`
75
+ * costs a line here instead of an unused `_name` binding.
76
+ *
77
+ * Deliberately NOT here: `onFocus` and `onBlur`. They are ordinary DOM handlers
78
+ * that reach the element through `rest` and nowhere else, so listing them would
79
+ * silently stop them working.
80
+ */
81
+ const OWN_PROPS = new Set<string>([
82
+ 'items',
83
+ 'closeTabLabel',
84
+ 'color',
85
+ 'size',
86
+ 'fullWidth',
87
+ 'scrollable',
88
+ 'scrollButtons',
89
+ 'sticky',
90
+ 'stickyOffset',
91
+ 'animateContent',
92
+ 'animationDuration',
93
+ 'persistContent',
94
+ 'tabPanelProps',
95
+ 'loading',
96
+ 'loadingComponent',
97
+ ]);
98
+
99
+ /** `props` with every {@link OWN_PROPS} key dropped — what is left is passthrough. */
100
+ const domPassthrough = (props: Record<string, unknown>): Record<string, unknown> =>
101
+ Object.fromEntries(Object.entries(props).filter(([key]) => !OWN_PROPS.has(key)));
102
+
62
103
  // Strips explicitly-undefined props before the merge, so `prop={undefined}`
63
104
  // still falls back to the default as a destructuring default would.
64
105
  const definedProps = (props: TabsProps): Partial<TabsProps> =>
@@ -251,7 +292,11 @@ export const Tabs = React.forwardRef<HTMLDivElement, TabsProps>(
251
292
  <Box className={className} ref={ref} data-testid={dataTestId || 'tabs'}>
252
293
  <TabsBar
253
294
  {...resolved}
254
- rest={rest as unknown as Record<string, unknown>}
295
+ // The destructuring above drops the props this component USES;
296
+ // `domPassthrough` drops the ones it merely OWNS. Both have to go:
297
+ // `rest` is spread onto the DOM node, and the second group is where
298
+ // 12-86's warnings came from.
299
+ rest={domPassthrough(rest as unknown as Record<string, unknown>)}
255
300
  onChange={handleChange}
256
301
  onCloseTab={handleTabClose}
257
302
  />
@@ -218,6 +218,56 @@ export function contrastText(background: string): string {
218
218
  : DARK_TEXT_PRIMARY;
219
219
  }
220
220
 
221
+ /**
222
+ * The ink that reads on EVERY one of these fills (FUT-1924).
223
+ *
224
+ * {@link contrastText} answers for one fill, which is all MUI's `augmentColor`
225
+ * ever needs: a solid button is a single flat colour. Two components paint the
226
+ * label over something that is not one colour — `Button`'s `gradient` variant
227
+ * runs between two stops, and `Switch`'s thumb travels the whole length of a
228
+ * checked track — and both of them stated `#fff` outright instead, which is
229
+ * white-on-pale the moment a white-labelled host hands the library a pale
230
+ * brand. Audited across the library, those two were the only places a hardcoded
231
+ * white sat over a surface the TENANT chooses.
232
+ *
233
+ * **This deliberately does not follow `contrastText`'s rule.** MUI's is a
234
+ * threshold that PREFERS white — white wherever white clears 3:1 — which is a
235
+ * brand-feel decision, and it is kept for every existing caller so nothing
236
+ * already legible moves. Here the fills can disagree: over MUI's own success
237
+ * pair white is 2.78:1 on `#4caf50` and dark ink 2.66:1 on `#1b5e20`, so
238
+ * neither meets any threshold and asking whether one does is the wrong
239
+ * question. The answer is whichever ink has the better WORST case across the
240
+ * fills — which is also not what either fill says on its own, since
241
+ * `contrastText('#4caf50')` is dark ink.
242
+ *
243
+ * A gradient wide enough that neither ink clears 4.5:1 anywhere is a palette
244
+ * problem this cannot fix — it returns the less bad ink and does not pretend
245
+ * otherwise.
246
+ *
247
+ * `Math.min` is the claim, and it is worth knowing that no test can prove it
248
+ * against `Math.max` today: the two candidate inks sit at opposite ends of the
249
+ * luminance range, so ranking them by their best fill and by their worst gives
250
+ * the same winner for every possible pair (checked exhaustively). Worst case is
251
+ * still what this MEANS, and the moment a third ink or one that is not an
252
+ * extreme is offered, the two stop agreeing.
253
+ *
254
+ * `fallback` is returned when a fill cannot be decomposed: {@link getContrastRatio}
255
+ * throws on a format it does not know, and a throw inside an emotion style
256
+ * function takes the render down with it.
257
+ */
258
+ export function inkOver(fills: readonly string[], fallback: string): string {
259
+ try {
260
+ const worstCase = (ink: string): number =>
261
+ Math.min(...fills.map((fill) => getContrastRatio(ink, fill)));
262
+
263
+ return worstCase(LIGHT_TEXT_PRIMARY) >= worstCase(DARK_TEXT_PRIMARY)
264
+ ? LIGHT_TEXT_PRIMARY
265
+ : DARK_TEXT_PRIMARY;
266
+ } catch {
267
+ return fallback;
268
+ }
269
+ }
270
+
221
271
  /**
222
272
  * MUI's `augmentColor` for a custom colour: derive whatever shade the seed
223
273
  * left out. `light` is one tonal offset up, `dark` one and a half down.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/form/Switch/Switch.styles.ts"],"sourcesContent":["import { alpha } from '@mui/material/styles/index.js';\nimport type { CSSObject, Theme } from '@mui/material/styles/index.js';\n\nimport {\n bounceAnimation,\n glowAnimation,\n pulseAnimation,\n rippleAnimation,\n shimmerAnimation,\n spinAnimation,\n} from './Switch.animations';\nimport {\n DISABLED,\n IOS_BASE_OFFSET,\n IOS_THUMB_SHADOW,\n IOS_TRAVEL_INSET,\n SWITCH_GLASS,\n SWITCH_GLOW,\n NEUTRAL_CONTRAST,\n NEUTRAL_FALLBACK,\n NEUTRAL_GREY,\n SWITCH_FOCUS_RING,\n SWITCH_GRADIENT,\n SWITCH_HOVER,\n SWITCH_PULSE,\n SWITCH_RIPPLE,\n SWITCH_SPINNER,\n SWITCH_TRANSITION,\n THUMB_ELEVATION,\n THUMB_RADIUS,\n TRACK_LABEL,\n TRACK_RADIUS,\n geometryOf,\n iosTrackShadow,\n lookOf,\n seconds,\n showsTrackLabels,\n trackColor,\n type SwitchGeometry,\n type SwitchLook,\n} from './Switch.metrics';\nimport type { SwitchVariant } from './Switch.base';\n\nimport { px } from '../../../tokens/theme';\nimport type { ColorValue, SizeValue } from '../../../tokens/vocabulary';\n\n// Every number below comes from `./Switch.metrics`, which the native renderer\n// reads too — see its header. The palette and the shadows stay on the MUI\n// theme so a host that re-themes either keeps moving the web.\ninterface ColorPalette {\n main: string;\n dark?: string;\n light?: string;\n contrastText?: string;\n}\n\n/** `neutral` is not a MUI palette entry, so it is built from the grey ramp. */\nconst neutralPalette = (theme: Theme): ColorPalette => ({\n main: theme.palette.grey?.[NEUTRAL_GREY.main] || NEUTRAL_FALLBACK.main,\n dark: theme.palette.grey?.[NEUTRAL_GREY.dark] || NEUTRAL_FALLBACK.dark,\n light: theme.palette.grey?.[NEUTRAL_GREY.light] || NEUTRAL_FALLBACK.light,\n contrastText: NEUTRAL_CONTRAST,\n});\n\n/**\n * Resolves a colour name to a full palette, filling any step the theme leaves\n * out from `main` and then from the primary palette. `danger` is this\n * component's name for the error palette; the rest map straight through.\n */\nconst getColorFromTheme = (theme: Theme, color: string): ColorPalette => {\n if (color === 'neutral') {\n return neutralPalette(theme);\n }\n\n const colorMap: Record<string, ColorPalette | undefined> = {\n primary: theme.palette.primary,\n secondary: theme.palette.secondary,\n success: theme.palette.success,\n warning: theme.palette.warning,\n info: theme.palette.info,\n danger: theme.palette.error,\n };\n const palette = colorMap[color] ?? theme.palette.primary;\n const { primary } = theme.palette;\n\n return {\n main: palette.main || primary.main,\n dark: palette.dark || palette.main || primary.dark,\n light: palette.light || palette.main || primary.light,\n contrastText: palette.contrastText || NEUTRAL_CONTRAST,\n };\n};\n\nexport interface SwitchFlags {\n customVariant?: SwitchVariant;\n customColor?: ColorValue;\n customSize?: SizeValue;\n glow?: boolean;\n glass?: boolean;\n gradient?: boolean;\n trackWidth?: number;\n trackHeight?: number;\n onText?: string;\n offText?: string;\n loading?: boolean;\n ripple?: boolean;\n pulse?: boolean;\n}\n\nconst thumbShadow = (theme: Theme, look: SwitchLook): string =>\n look === 'ios' ? IOS_THUMB_SHADOW : (theme.shadows[THUMB_ELEVATION[look]] ?? 'none');\n\n/** The ripple that expands from the thumb on hover. */\nconst rippleOverlay = (palette: ColorPalette): CSSObject => ({\n content: '\"\"',\n position: 'absolute',\n top: '50%',\n left: '50%',\n width: '100%',\n height: '100%',\n borderRadius: '50%',\n background: alpha(palette.main, SWITCH_RIPPLE.alpha),\n animation: `${rippleAnimation} ${seconds(SWITCH_RIPPLE.ms)} ease-out`,\n transform: 'translate(-50%, -50%)',\n pointerEvents: 'none',\n});\n\n/** The checked track: the filled bar behind the thumb once the switch is on. */\nconst checkedTrack = (flags: SwitchFlags, palette: ColorPalette): CSSObject => ({\n backgroundColor: palette.main,\n opacity: 1,\n border: 0,\n position: 'relative',\n overflow: 'hidden',\n ...(flags.glow && {\n animation: `${glowAnimation} ${seconds(SWITCH_GLOW.ms)} ease-in-out infinite`,\n boxShadow: `0 0 ${SWITCH_GLOW.blur}px ${alpha(palette.main, SWITCH_GLOW.alpha)}, inset 0 0 ${SWITCH_GLOW.insetBlur}px ${alpha(palette.main, SWITCH_GLOW.insetAlpha)}`,\n }),\n ...(flags.gradient && {\n background: `linear-gradient(${SWITCH_GRADIENT.checked.angleDeg}deg, ${palette.light || palette.main} ${SWITCH_GRADIENT.checked.stops[0]}%, ${palette.main} ${SWITCH_GRADIENT.checked.stops[1]}%, ${palette.dark || palette.main} ${SWITCH_GRADIENT.checked.stops[2]}%)`,\n backgroundSize: '200% 100%',\n animation: `${shimmerAnimation} ${seconds(SWITCH_GRADIENT.shimmerMs)} ease infinite`,\n }),\n});\n\nconst switchBaseSx = (\n theme: Theme,\n flags: SwitchFlags,\n palette: ColorPalette,\n geometry: SwitchGeometry,\n look: SwitchLook,\n): CSSObject => {\n const { width, thumbSize, padding } = geometry;\n const isIos = look === 'ios';\n\n return {\n padding,\n margin: 0,\n transitionDuration: `${SWITCH_TRANSITION.ms}ms`,\n transitionTimingFunction: SWITCH_TRANSITION.easing,\n ...(isIos && { transform: `translateX(${IOS_BASE_OFFSET}px)` }),\n '&:hover': {\n '& .MuiSwitch-thumb': {\n transform: flags.loading ? 'none' : `scale(${SWITCH_HOVER.thumbScale})`,\n boxShadow: `${theme.shadows[SWITCH_HOVER.elevation]}, 0 0 ${SWITCH_HOVER.blur}px ${alpha(palette.main, SWITCH_HOVER.alpha)}`,\n },\n ...(flags.ripple && { '&::after': rippleOverlay(palette) }),\n },\n '&.Mui-checked': {\n // The thumb travels the track minus its own width and both paddings; the\n // iOS look insets differently, so it gets its own distance.\n transform: `translateX(${width - thumbSize - padding * 2}px)`,\n color: '#fff',\n '& .MuiSwitch-thumb': {\n animation: flags.loading ? 'none' : `${bounceAnimation} ${seconds(SWITCH_TRANSITION.ms)} ease-out`,\n },\n '& + .MuiSwitch-track': checkedTrack(flags, palette),\n '&.Mui-disabled + .MuiSwitch-track': { opacity: DISABLED.checkedTrackOpacity },\n ...(isIos && { transform: `translateX(${width - thumbSize - IOS_TRAVEL_INSET}px)` }),\n },\n '&.Mui-focusVisible .MuiSwitch-thumb': {\n color: palette.main,\n border: `${SWITCH_FOCUS_RING.width}px solid ${alpha(palette.main, SWITCH_FOCUS_RING.alpha)}`,\n },\n '&.Mui-disabled .MuiSwitch-thumb': { color: theme.palette.grey[DISABLED.thumbGrey] },\n '&.Mui-disabled + .MuiSwitch-track': { opacity: DISABLED.trackOpacity },\n };\n};\n\nconst thumbSx = (\n theme: Theme,\n flags: SwitchFlags,\n palette: ColorPalette,\n thumbSize: number,\n look: SwitchLook,\n): CSSObject => ({\n width: thumbSize,\n height: thumbSize,\n borderRadius: THUMB_RADIUS[look](thumbSize),\n backgroundColor: '#fff',\n boxShadow: thumbShadow(theme, look),\n transition: `all ${seconds(SWITCH_TRANSITION.ms)} ${SWITCH_TRANSITION.easing}`,\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n ...(flags.glass && {\n backgroundColor: alpha(theme.palette.background.paper, SWITCH_GLASS.thumbAlpha),\n backdropFilter: `blur(${SWITCH_GLASS.thumbBlur}px)`,\n border: `1px solid ${alpha(theme.palette.divider, SWITCH_GLASS.borderAlpha)}`,\n }),\n ...(flags.pulse && { animation: `${pulseAnimation} ${seconds(SWITCH_PULSE.ms)} ease-in-out infinite` }),\n ...(flags.loading && {\n // A spinner drawn inside the thumb rather than over the whole control.\n '&::after': {\n content: '\"\"',\n position: 'absolute',\n width: thumbSize * SWITCH_SPINNER.sizeRatio,\n height: thumbSize * SWITCH_SPINNER.sizeRatio,\n border: `${SWITCH_SPINNER.borderWidth}px solid ${palette.main}`,\n borderTop: `${SWITCH_SPINNER.borderWidth}px solid transparent`,\n borderRadius: '50%',\n animation: `${spinAnimation} ${seconds(SWITCH_SPINNER.ms)} linear infinite`,\n },\n }),\n ...(look === 'material' && {\n '&::before': {\n content: '\"\"',\n position: 'absolute',\n width: '100%',\n height: '100%',\n borderRadius: 'inherit',\n backgroundColor: palette.main,\n opacity: 0,\n transform: 'scale(0)',\n transition: 'all 0.3s ease',\n },\n }),\n});\n\n/** The on/off wording the `label` variant prints inside the track. */\nconst trackLabels = (theme: Theme, onText?: string, offText?: string): CSSObject => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingLeft: theme.spacing(TRACK_LABEL.insetUnits),\n paddingRight: theme.spacing(TRACK_LABEL.insetUnits),\n fontSize: px(TRACK_LABEL.fontSize),\n fontWeight: TRACK_LABEL.fontWeight,\n color: theme.palette.text.secondary,\n '&::before, &::after': {\n content: '\"\"',\n position: 'absolute',\n fontSize: px(TRACK_LABEL.fontSize),\n fontWeight: TRACK_LABEL.fontWeight,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 1,\n },\n ...(onText && {\n '&::before': { content: `\"${onText}\"`, left: theme.spacing(TRACK_LABEL.insetUnits), color: '#fff' },\n }),\n ...(offText && {\n '&::after': {\n content: `\"${offText}\"`,\n right: theme.spacing(TRACK_LABEL.insetUnits),\n color: theme.palette.text.secondary,\n },\n }),\n});\n\nconst trackSx = (\n theme: Theme,\n flags: SwitchFlags,\n palette: ColorPalette,\n height: number,\n look: SwitchLook,\n): CSSObject => {\n const { glass, gradient, onText, offText, customVariant } = flags;\n\n return {\n borderRadius: TRACK_RADIUS[look](height),\n backgroundColor: trackColor(\n { black: theme.palette.common.black, disabled: theme.palette.action.disabled },\n look,\n ),\n opacity: 1,\n transition: `all ${seconds(SWITCH_TRANSITION.ms)} ${SWITCH_TRANSITION.easing}`,\n position: 'relative',\n boxShadow: look === 'ios' ? iosTrackShadow() : 'none',\n ...(glass && {\n backgroundColor: alpha(theme.palette.background.paper, SWITCH_GLASS.trackAlpha),\n backdropFilter: `blur(${SWITCH_GLASS.trackBlur}px)`,\n border: `1px solid ${alpha(theme.palette.divider, SWITCH_GLASS.borderAlpha)}`,\n }),\n ...(gradient &&\n !glass && {\n background: `linear-gradient(${SWITCH_GRADIENT.resting.angleDeg}deg, ${alpha(palette.light || palette.main, SWITCH_GRADIENT.resting.lightAlpha)}, ${alpha(palette.main, SWITCH_GRADIENT.resting.mainAlpha)})`,\n }),\n ...(showsTrackLabels(customVariant, onText, offText) && trackLabels(theme, onText, offText)),\n };\n};\n\nexport const switchSx = (theme: Theme, flags: SwitchFlags): CSSObject => {\n const palette = getColorFromTheme(theme, flags.customColor ?? 'primary');\n const geometry = geometryOf(flags.customSize, flags.trackWidth, flags.trackHeight);\n const look = lookOf(flags.customVariant);\n\n return {\n width: geometry.width,\n height: geometry.height,\n padding: 0,\n overflow: 'visible',\n '& .MuiSwitch-switchBase': switchBaseSx(theme, flags, palette, geometry, look),\n '& .MuiSwitch-thumb': thumbSx(theme, flags, palette, geometry.thumbSize, look),\n '& .MuiSwitch-track': trackSx(theme, flags, palette, geometry.height, look),\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,aAAa;AAyDtB,IAAM,iBAAiB,CAAC,WAAgC;AAAA,EACtD,MAAM,MAAM,QAAQ,OAAO,aAAa,IAAI,KAAK,iBAAiB;AAAA,EAClE,MAAM,MAAM,QAAQ,OAAO,aAAa,IAAI,KAAK,iBAAiB;AAAA,EAClE,OAAO,MAAM,QAAQ,OAAO,aAAa,KAAK,KAAK,iBAAiB;AAAA,EACpE,cAAc;AAChB;AAOA,IAAM,oBAAoB,CAAC,OAAc,UAAgC;AACvE,MAAI,UAAU,WAAW;AACvB,WAAO,eAAe,KAAK;AAAA,EAC7B;AAEA,QAAM,WAAqD;AAAA,IACzD,SAAS,MAAM,QAAQ;AAAA,IACvB,WAAW,MAAM,QAAQ;AAAA,IACzB,SAAS,MAAM,QAAQ;AAAA,IACvB,SAAS,MAAM,QAAQ;AAAA,IACvB,MAAM,MAAM,QAAQ;AAAA,IACpB,QAAQ,MAAM,QAAQ;AAAA,EACxB;AACA,QAAM,UAAU,SAAS,KAAK,KAAK,MAAM,QAAQ;AACjD,QAAM,EAAE,QAAQ,IAAI,MAAM;AAE1B,SAAO;AAAA,IACL,MAAM,QAAQ,QAAQ,QAAQ;AAAA,IAC9B,MAAM,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ;AAAA,IAC9C,OAAO,QAAQ,SAAS,QAAQ,QAAQ,QAAQ;AAAA,IAChD,cAAc,QAAQ,gBAAgB;AAAA,EACxC;AACF;AAkBA,IAAM,cAAc,CAAC,OAAc,SACjC,SAAS,QAAQ,mBAAoB,MAAM,QAAQ,gBAAgB,IAAI,CAAC,KAAK;AAG/E,IAAM,gBAAgB,CAAC,aAAsC;AAAA,EAC3D,SAAS;AAAA,EACT,UAAU;AAAA,EACV,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,YAAY,MAAM,QAAQ,MAAM,cAAc,KAAK;AAAA,EACnD,WAAW,GAAG,eAAe,IAAI,QAAQ,cAAc,EAAE,CAAC;AAAA,EAC1D,WAAW;AAAA,EACX,eAAe;AACjB;AAGA,IAAM,eAAe,CAAC,OAAoB,aAAsC;AAAA,EAC9E,iBAAiB,QAAQ;AAAA,EACzB,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,UAAU;AAAA,EACV,GAAI,MAAM,QAAQ;AAAA,IAChB,WAAW,GAAG,aAAa,IAAI,QAAQ,YAAY,EAAE,CAAC;AAAA,IACtD,WAAW,OAAO,YAAY,IAAI,MAAM,MAAM,QAAQ,MAAM,YAAY,KAAK,CAAC,eAAe,YAAY,SAAS,MAAM,MAAM,QAAQ,MAAM,YAAY,UAAU,CAAC;AAAA,EACrK;AAAA,EACA,GAAI,MAAM,YAAY;AAAA,IACpB,YAAY,mBAAmB,gBAAgB,QAAQ,QAAQ,QAAQ,QAAQ,SAAS,QAAQ,IAAI,IAAI,gBAAgB,QAAQ,MAAM,CAAC,CAAC,MAAM,QAAQ,IAAI,IAAI,gBAAgB,QAAQ,MAAM,CAAC,CAAC,MAAM,QAAQ,QAAQ,QAAQ,IAAI,IAAI,gBAAgB,QAAQ,MAAM,CAAC,CAAC;AAAA,IACpQ,gBAAgB;AAAA,IAChB,WAAW,GAAG,gBAAgB,IAAI,QAAQ,gBAAgB,SAAS,CAAC;AAAA,EACtE;AACF;AAEA,IAAM,eAAe,CACnB,OACA,OACA,SACA,UACA,SACc;AACd,QAAM,EAAE,OAAO,WAAW,QAAQ,IAAI;AACtC,QAAM,QAAQ,SAAS;AAEvB,SAAO;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,IACR,oBAAoB,GAAG,kBAAkB,EAAE;AAAA,IAC3C,0BAA0B,kBAAkB;AAAA,IAC5C,GAAI,SAAS,EAAE,WAAW,cAAc,eAAe,MAAM;AAAA,IAC7D,WAAW;AAAA,MACT,sBAAsB;AAAA,QACpB,WAAW,MAAM,UAAU,SAAS,SAAS,aAAa,UAAU;AAAA,QACpE,WAAW,GAAG,MAAM,QAAQ,aAAa,SAAS,CAAC,SAAS,aAAa,IAAI,MAAM,MAAM,QAAQ,MAAM,aAAa,KAAK,CAAC;AAAA,MAC5H;AAAA,MACA,GAAI,MAAM,UAAU,EAAE,YAAY,cAAc,OAAO,EAAE;AAAA,IAC3D;AAAA,IACA,iBAAiB;AAAA;AAAA;AAAA,MAGf,WAAW,cAAc,QAAQ,YAAY,UAAU,CAAC;AAAA,MACxD,OAAO;AAAA,MACP,sBAAsB;AAAA,QACpB,WAAW,MAAM,UAAU,SAAS,GAAG,eAAe,IAAI,QAAQ,kBAAkB,EAAE,CAAC;AAAA,MACzF;AAAA,MACA,wBAAwB,aAAa,OAAO,OAAO;AAAA,MACnD,qCAAqC,EAAE,SAAS,SAAS,oBAAoB;AAAA,MAC7E,GAAI,SAAS,EAAE,WAAW,cAAc,QAAQ,YAAY,gBAAgB,MAAM;AAAA,IACpF;AAAA,IACA,uCAAuC;AAAA,MACrC,OAAO,QAAQ;AAAA,MACf,QAAQ,GAAG,kBAAkB,KAAK,YAAY,MAAM,QAAQ,MAAM,kBAAkB,KAAK,CAAC;AAAA,IAC5F;AAAA,IACA,mCAAmC,EAAE,OAAO,MAAM,QAAQ,KAAK,SAAS,SAAS,EAAE;AAAA,IACnF,qCAAqC,EAAE,SAAS,SAAS,aAAa;AAAA,EACxE;AACF;AAEA,IAAM,UAAU,CACd,OACA,OACA,SACA,WACA,UACe;AAAA,EACf,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,cAAc,aAAa,IAAI,EAAE,SAAS;AAAA,EAC1C,iBAAiB;AAAA,EACjB,WAAW,YAAY,OAAO,IAAI;AAAA,EAClC,YAAY,OAAO,QAAQ,kBAAkB,EAAE,CAAC,IAAI,kBAAkB,MAAM;AAAA,EAC5E,UAAU;AAAA,EACV,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,GAAI,MAAM,SAAS;AAAA,IACjB,iBAAiB,MAAM,MAAM,QAAQ,WAAW,OAAO,aAAa,UAAU;AAAA,IAC9E,gBAAgB,QAAQ,aAAa,SAAS;AAAA,IAC9C,QAAQ,aAAa,MAAM,MAAM,QAAQ,SAAS,aAAa,WAAW,CAAC;AAAA,EAC7E;AAAA,EACA,GAAI,MAAM,SAAS,EAAE,WAAW,GAAG,cAAc,IAAI,QAAQ,aAAa,EAAE,CAAC,wBAAwB;AAAA,EACrG,GAAI,MAAM,WAAW;AAAA;AAAA,IAEnB,YAAY;AAAA,MACV,SAAS;AAAA,MACT,UAAU;AAAA,MACV,OAAO,YAAY,eAAe;AAAA,MAClC,QAAQ,YAAY,eAAe;AAAA,MACnC,QAAQ,GAAG,eAAe,WAAW,YAAY,QAAQ,IAAI;AAAA,MAC7D,WAAW,GAAG,eAAe,WAAW;AAAA,MACxC,cAAc;AAAA,MACd,WAAW,GAAG,aAAa,IAAI,QAAQ,eAAe,EAAE,CAAC;AAAA,IAC3D;AAAA,EACF;AAAA,EACA,GAAI,SAAS,cAAc;AAAA,IACzB,aAAa;AAAA,MACX,SAAS;AAAA,MACT,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,iBAAiB,QAAQ;AAAA,MACzB,SAAS;AAAA,MACT,WAAW;AAAA,MACX,YAAY;AAAA,IACd;AAAA,EACF;AACF;AAGA,IAAM,cAAc,CAAC,OAAc,QAAiB,aAAiC;AAAA,EACnF,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,aAAa,MAAM,QAAQ,YAAY,UAAU;AAAA,EACjD,cAAc,MAAM,QAAQ,YAAY,UAAU;AAAA,EAClD,UAAU,GAAG,YAAY,QAAQ;AAAA,EACjC,YAAY,YAAY;AAAA,EACxB,OAAO,MAAM,QAAQ,KAAK;AAAA,EAC1B,uBAAuB;AAAA,IACrB,SAAS;AAAA,IACT,UAAU;AAAA,IACV,UAAU,GAAG,YAAY,QAAQ;AAAA,IACjC,YAAY,YAAY;AAAA,IACxB,KAAK;AAAA,IACL,WAAW;AAAA,IACX,QAAQ;AAAA,EACV;AAAA,EACA,GAAI,UAAU;AAAA,IACZ,aAAa,EAAE,SAAS,IAAI,MAAM,KAAK,MAAM,MAAM,QAAQ,YAAY,UAAU,GAAG,OAAO,OAAO;AAAA,EACpG;AAAA,EACA,GAAI,WAAW;AAAA,IACb,YAAY;AAAA,MACV,SAAS,IAAI,OAAO;AAAA,MACpB,OAAO,MAAM,QAAQ,YAAY,UAAU;AAAA,MAC3C,OAAO,MAAM,QAAQ,KAAK;AAAA,IAC5B;AAAA,EACF;AACF;AAEA,IAAM,UAAU,CACd,OACA,OACA,SACA,QACA,SACc;AACd,QAAM,EAAE,OAAO,UAAU,QAAQ,SAAS,cAAc,IAAI;AAE5D,SAAO;AAAA,IACL,cAAc,aAAa,IAAI,EAAE,MAAM;AAAA,IACvC,iBAAiB;AAAA,MACf,EAAE,OAAO,MAAM,QAAQ,OAAO,OAAO,UAAU,MAAM,QAAQ,OAAO,SAAS;AAAA,MAC7E;AAAA,IACF;AAAA,IACA,SAAS;AAAA,IACT,YAAY,OAAO,QAAQ,kBAAkB,EAAE,CAAC,IAAI,kBAAkB,MAAM;AAAA,IAC5E,UAAU;AAAA,IACV,WAAW,SAAS,QAAQ,eAAe,IAAI;AAAA,IAC/C,GAAI,SAAS;AAAA,MACX,iBAAiB,MAAM,MAAM,QAAQ,WAAW,OAAO,aAAa,UAAU;AAAA,MAC9E,gBAAgB,QAAQ,aAAa,SAAS;AAAA,MAC9C,QAAQ,aAAa,MAAM,MAAM,QAAQ,SAAS,aAAa,WAAW,CAAC;AAAA,IAC7E;AAAA,IACA,GAAI,YACF,CAAC,SAAS;AAAA,MACR,YAAY,mBAAmB,gBAAgB,QAAQ,QAAQ,QAAQ,MAAM,QAAQ,SAAS,QAAQ,MAAM,gBAAgB,QAAQ,UAAU,CAAC,KAAK,MAAM,QAAQ,MAAM,gBAAgB,QAAQ,SAAS,CAAC;AAAA,IAC5M;AAAA,IACF,GAAI,iBAAiB,eAAe,QAAQ,OAAO,KAAK,YAAY,OAAO,QAAQ,OAAO;AAAA,EAC5F;AACF;AAEO,IAAM,WAAW,CAAC,OAAc,UAAkC;AACvE,QAAM,UAAU,kBAAkB,OAAO,MAAM,eAAe,SAAS;AACvE,QAAM,WAAW,WAAW,MAAM,YAAY,MAAM,YAAY,MAAM,WAAW;AACjF,QAAM,OAAO,OAAO,MAAM,aAAa;AAEvC,SAAO;AAAA,IACL,OAAO,SAAS;AAAA,IAChB,QAAQ,SAAS;AAAA,IACjB,SAAS;AAAA,IACT,UAAU;AAAA,IACV,2BAA2B,aAAa,OAAO,OAAO,SAAS,UAAU,IAAI;AAAA,IAC7E,sBAAsB,QAAQ,OAAO,OAAO,SAAS,SAAS,WAAW,IAAI;AAAA,IAC7E,sBAAsB,QAAQ,OAAO,OAAO,SAAS,SAAS,QAAQ,IAAI;AAAA,EAC5E;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/form/Button/Button.styles.ts"],"sourcesContent":["import { alpha, darken, keyframes, lighten } from '@mui/material/styles/index.js';\nimport type { CSSObject, Theme } from '@mui/material/styles/index.js';\n\nimport { BUTTON_SIZES, ICON_ONLY_PADDING as ICON_ONLY_PADDING_PX } from './Button.metrics';\nimport { px } from '../../../tokens/theme';\n\n// Define pulse animation globally\nconst pulseAnimation = keyframes`\n 0% {\n box-shadow: 0 0 0 0 currentColor;\n opacity: 1;\n }\n 70% {\n box-shadow: 0 0 0 15px currentColor;\n opacity: 0;\n }\n 100% {\n box-shadow: 0 0 0 0 currentColor;\n opacity: 0;\n }\n`;\n\ninterface ColorPalette {\n main: string;\n dark: string;\n light: string;\n contrastText: string;\n}\n\nconst shade = (\n palette: ColorPalette | undefined,\n key: 'dark' | 'light',\n fallback: ColorPalette,\n): string => palette?.[key] || palette?.main || fallback[key];\n\n/** `neutral` has no MUI palette entry, so its four shades come from grey. */\nconst neutralPalette = (theme: Theme): ColorPalette => ({\n main: theme.palette.grey?.[700] || '#616161',\n dark: theme.palette.grey?.[800] || '#424242',\n light: theme.palette.grey?.[500] || '#9e9e9e',\n contrastText: '#fff',\n});\n\nexport const getColorFromTheme = (theme: Theme, color: string): ColorPalette => {\n if (color === 'neutral') return neutralPalette(theme);\n\n const colorMap: Record<string, ColorPalette> = {\n primary: theme.palette.primary as ColorPalette,\n secondary: theme.palette.secondary as ColorPalette,\n success: theme.palette.success as ColorPalette,\n warning: theme.palette.warning as ColorPalette,\n info: theme.palette.info as ColorPalette,\n danger: theme.palette.error as ColorPalette,\n };\n\n const fallback = theme.palette.primary as ColorPalette;\n const palette = colorMap[color] || fallback;\n\n // Ensure palette has required properties\n return {\n main: palette?.main || fallback.main,\n dark: shade(palette, 'dark', fallback),\n light: shade(palette, 'light', fallback),\n contrastText: palette?.contrastText || '#fff',\n };\n};\n\n// Derived from `Button.metrics.ts`, which the native `Button` reads too — one\n// table, so a size cannot differ between the renderers.\nconst SIZE_MAP: Record<string, CSSObject> = Object.fromEntries(\n Object.entries(BUTTON_SIZES).map(([size, m]) => [\n size,\n { padding: `${m.paddingVertical}px ${m.paddingHorizontal}px`, fontSize: px(m.fontSize) },\n ]),\n);\n\n/** What an unrecognised size falls back to, named so indexing can never be undefined. */\nconst DEFAULT_SIZE: CSSObject = SIZE_MAP.md as CSSObject;\n\n/**\n * A BUTTON THAT IS ONLY AN ICON IS SQUARE.\n *\n * MUI puts a 64px `min-width` on every button, which is right for a label and\n * wrong for a glyph: three dots in a 64px slab reads as a button that failed to\n * load its text, and at the end of a dense row it claims space the row needs.\n * The horizontal padding goes too — a square of padding round a square glyph —\n * and so does the gap MUI reserves beside a start/end icon, since there is\n * nothing on the other side of it.\n *\n * Derived, not declared: a button with an `icon` and no children can only be an\n * icon button, so no consumer has to opt in and none can forget to.\n */\nconst ICON_ONLY_PADDING: Record<string, string> = Object.fromEntries(\n Object.entries(ICON_ONLY_PADDING_PX).map(([size, padding]) => [size, `${padding}px`]),\n);\n\nconst iconOnlySize = (size: string): CSSObject => ({\n minWidth: 0,\n padding: ICON_ONLY_PADDING[size] ?? ICON_ONLY_PADDING.md,\n fontSize: SIZE_MAP[size]?.fontSize ?? DEFAULT_SIZE.fontSize,\n '& .MuiButton-startIcon, & .MuiButton-endIcon': { margin: 0 },\n});\n\n/** The size styles for a button, square when it carries nothing but an icon. */\nexport const buttonSize = (size: string, iconOnly: boolean): CSSObject =>\n iconOnly ? iconOnlySize(size) : (SIZE_MAP[size] ?? DEFAULT_SIZE);\n\n/**\n * MUI centres icons with a negative margin that fights our own padding, so the\n * flex alignment is restated here rather than fought with `!important`.\n */\nexport const iconAlignmentStyles = (theme: Theme): CSSObject => ({\n '& .MuiButton-startIcon, & .MuiButton-endIcon': {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n margin: 0,\n verticalAlign: 'middle',\n '& > *': {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 0,\n },\n },\n '& .MuiButton-startIcon': {\n marginRight: theme.spacing(0.5),\n },\n '& .MuiButton-endIcon': {\n marginLeft: theme.spacing(0.5),\n },\n});\n\n// Gradients run between two related hues; the named colours pick a specific pair,\n// anything else runs from its own main to its own dark.\nconst GRADIENT_PAIRS: Record<string, (theme: Theme) => [string, string]> = {\n primary: (theme) => [theme.palette.primary.main, theme.palette.secondary.main],\n secondary: (theme) => [theme.palette.secondary.main, theme.palette.primary.main],\n success: (theme) => [theme.palette.success.light, theme.palette.success.dark],\n warning: (theme) => [theme.palette.warning.light, theme.palette.warning.dark],\n danger: (theme) => [theme.palette.error.light, theme.palette.error.dark],\n};\n\nconst gradientFor = (theme: Theme, color: string, palette: ColorPalette): string => {\n const [from, to] = GRADIENT_PAIRS[color]?.(theme) ?? [palette.main, palette.dark];\n return `linear-gradient(135deg, ${from} 0%, ${to} 100%)`;\n};\n\n/**\n * The label colour for the two variants that paint no background of their own.\n *\n * `ghost` and `text` used `palette.main` directly, which is the same mistake\n * the Alert made with its body text: a palette's `main` is chosen to sit UNDER\n * white — it is the fill of a solid button — and it is not chosen to be read AS\n * text. `#6366F1`, the default primary, is 3.6:1 on white and worse on any\n * tinted surface, so a \"Cancelar\" or an \"Agora não\" placed on a coloured panel\n * turned into a smudge. That is precisely where these two variants belong: they\n * exist to be the quiet option NEXT to a solid one, so they are the buttons\n * most likely to be sitting on something other than plain paper.\n *\n * One step darker (lighter, on a dark theme) keeps the hue the caller asked for\n * and buys the contrast back. `main` still drives the hover wash and every\n * bordered variant, so nothing that was already legible moves.\n */\nconst quietInk = (theme: Theme, palette: ColorPalette): string =>\n theme.palette.mode === 'dark' ? lighten(palette.main, 0.35) : darken(palette.main, 0.3);\n\nconst VARIANT_STYLES: Record<\n string,\n (theme: Theme, palette: ColorPalette, color: string) => CSSObject\n> = {\n solid: (theme, palette) => ({\n backgroundColor: palette.main,\n color: palette.contrastText || '#fff',\n '&:hover': {\n backgroundColor: palette.dark,\n transform: 'translateY(-2px)',\n boxShadow: theme.shadows[8],\n },\n }),\n outline: (_theme, palette) => ({\n backgroundColor: 'transparent',\n color: palette.main,\n border: `1px solid ${palette.main}`,\n '&:hover': {\n backgroundColor: alpha(palette.main, 0.1),\n borderColor: palette.dark,\n },\n }),\n ghost: (theme, palette) => ({\n backgroundColor: 'transparent',\n color: quietInk(theme, palette),\n '&:hover': {\n backgroundColor: alpha(palette.main, 0.1),\n },\n }),\n text: (theme, palette) => ({\n backgroundColor: 'transparent',\n color: quietInk(theme, palette),\n border: `none`,\n '&:hover': {\n backgroundColor: alpha(palette.main, 0.1),\n },\n '&.active': {\n backgroundColor: alpha(palette.main, 0.1),\n color: quietInk(theme, palette),\n },\n }),\n glass: (theme, palette) => ({\n backgroundColor: alpha(theme.palette.background.paper, 0.1),\n backdropFilter: 'blur(20px)',\n border: `1px solid ${alpha(theme.palette.divider, 0.2)}`,\n color: palette.main,\n '&:hover': {\n backgroundColor: alpha(theme.palette.background.paper, 0.2),\n transform: 'translateY(-2px)',\n },\n }),\n gradient: (theme, palette, color) => ({\n background: gradientFor(theme, color, palette),\n color: '#fff',\n '&:hover': {\n filter: 'brightness(1.1)',\n transform: 'translateY(-2px)',\n boxShadow: theme.shadows[12],\n },\n }),\n};\n\nexport const buttonVariantStyles = (\n theme: Theme,\n variant: string | undefined,\n palette: ColorPalette,\n color: string,\n): CSSObject => VARIANT_STYLES[variant ?? '']?.(theme, palette, color) ?? {};\n\n// Glow effect - applied with !important to override variant shadows\nconst glowStyles = (palette: ColorPalette): CSSObject => ({\n boxShadow: `0 0 20px 5px ${alpha(palette.main, 0.6)}, 0 0 40px 10px ${alpha(palette.main, 0.3)} !important`,\n filter: 'brightness(1.05)',\n '&:hover': {\n boxShadow: `0 0 25px 8px ${alpha(palette.main, 0.7)}, 0 0 50px 15px ${alpha(palette.main, 0.4)} !important`,\n filter: 'brightness(1.1)',\n transform: 'translateY(-2px) scale(1.02)',\n },\n});\n\n// Pulse animation using pseudo-element\nconst pulseStyles = (palette: ColorPalette): CSSObject => ({\n position: 'relative',\n overflow: 'visible',\n '&::after': {\n content: '\"\"',\n position: 'absolute',\n top: '50%',\n left: '50%',\n width: '100%',\n height: '100%',\n borderRadius: 'inherit',\n transform: 'translate(-50%, -50%)',\n backgroundColor: palette.main,\n opacity: 0.3,\n animation: `${pulseAnimation} 2s infinite`,\n pointerEvents: 'none',\n zIndex: -1,\n },\n});\n\n/**\n * glow and pulse are independent flags. The three combinations used to be spelled\n * out one by one, but each is just the union of whichever flags are set.\n */\nexport const buttonEmphasisStyles = (\n palette: ColorPalette,\n glow?: boolean,\n pulse?: boolean,\n): CSSObject => ({\n ...(glow ? glowStyles(palette) : {}),\n ...(pulse ? pulseStyles(palette) : {}),\n});\n"],"mappings":"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","names":["ICON_ONLY_PADDING"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/navigation/Tabs/Tabs.tsx"],"sourcesContent":["import Close from '@mui/icons-material/Close';\nimport Badge from '@mui/material/Badge/index.js';\nimport Box from '@mui/material/Box/index.js';\nimport Divider from '@mui/material/Divider/index.js';\nimport MuiTab from '@mui/material/Tab/index.js';\nimport MuiTabs from '@mui/material/Tabs/index.js';\nimport { alpha, styled } from '@mui/material/styles/index.js';\nimport React from 'react';\n\nimport { CustomTabPanel } from './TabsPanel';\nimport { tabsRootStyles } from './Tabs.styles';\nimport type { TabItem, TabsProps } from './Tabs.types';\n\nconst StyledTabs = styled(MuiTabs, {\n shouldForwardProp: (prop) => !['customVariant', 'size', 'showDividers'].includes(prop as string) })<{ customVariant?: string; size?: string; showDividers?: boolean }>(\n ({ theme, customVariant, size, showDividers }) => ({\n ...tabsRootStyles({ theme, customVariant, size, showDividers }) }),\n);\n\nconst CloseButton = styled(Box)(({ theme }) => ({\n marginLeft: theme.spacing(0.5),\n padding: theme.spacing(0.25),\n width: 20,\n height: 20,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n borderRadius: '50%',\n color: theme.palette.action.active,\n '&:hover': {\n backgroundColor: alpha(theme.palette.error.main, 0.1),\n color: theme.palette.error.main } }));\n\nconst BadgeWrapper = styled(Badge)(() => ({\n '& .MuiBadge-badge': {\n right: -6,\n top: 4,\n fontSize: '0.75rem',\n minWidth: 16,\n height: 16,\n padding: 0 } }));\n\nconst TABS_DEFAULTS: Partial<TabsProps> = {\n variant: 'default',\n size: 'md',\n color: 'primary',\n fullWidth: false,\n orientation: 'horizontal',\n showDividers: false,\n centered: false,\n scrollable: false,\n scrollButtons: 'auto',\n sticky: false,\n stickyOffset: 0,\n animateContent: false,\n animationDuration: 300,\n persistContent: false,\n disabled: false,\n loading: false };\n\n// Strips explicitly-undefined props before the merge, so `prop={undefined}`\n// still falls back to the default as a destructuring default would.\nconst definedProps = (props: TabsProps): Partial<TabsProps> =>\n Object.fromEntries(\n Object.entries(props).filter(([, value]) => value !== undefined),\n ) as Partial<TabsProps>;\n\n// Once the row is scrollable every accepted scrollButtons value ends up as\n// MUI's 'auto'. That is exactly what the previous nested ternary did — it mapped\n// 'on'/'off'/'desktop' to 'auto', and its remaining branch could only ever be\n// 'auto' anyway — so the behaviour is preserved here rather than quietly\n// changed. Worth knowing that scrollButtons=\"off\" therefore still shows buttons.\nconst resolveScrollButtons = (scrollable?: boolean): 'auto' | false =>\n scrollable ? 'auto' : false;\n\nconst buildTabsSx = ({\n fullWidth,\n sticky,\n stickyOffset,\n indicatorColor,\n disabled }: {\n fullWidth?: boolean;\n sticky?: boolean;\n stickyOffset?: number;\n indicatorColor?: string;\n disabled?: boolean;\n}) => ({\n ...(fullWidth && { width: '100%' }),\n // Pin the tab list while panels scroll beneath it. Opaque background + bottom\n // divider so scrolled content does not show through.\n ...(sticky && {\n position: 'sticky',\n top: stickyOffset,\n zIndex: 2,\n backgroundColor: 'background.default',\n borderBottom: 1,\n borderColor: 'divider' }),\n ...(indicatorColor && {\n '& .MuiTabs-indicator': { backgroundColor: indicatorColor } }),\n ...(disabled && { opacity: 0.6, pointerEvents: 'none' }) });\n\n// A tab's label: icon, text, optional close affordance, optionally badged.\nconst TabLabel: React.FC<{\n item: TabItem;\n closeTabLabel: string;\n onClose: (event: React.MouseEvent | React.KeyboardEvent, tabId: string) => void;\n}> = ({ item, closeTabLabel, onClose }) => {\n const content = (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n {item.icon}\n <span>{item.label}</span>\n {item.closable && (\n <CloseButton\n onClick={(e) => onClose(e, item.id)}\n role=\"button\"\n tabIndex={0}\n aria-label={closeTabLabel}\n onKeyDown={(e) => {\n if (e.key !== 'Enter' && e.key !== ' ') return;\n onClose(e, item.id);\n }}\n >\n <Close fontSize=\"inherit\" />\n </CloseButton>\n )}\n </Box>\n );\n\n if (item.badge === undefined) return content;\n\n return (\n <BadgeWrapper badgeContent={item.badge} color=\"error\">\n {content}\n </BadgeWrapper>\n );\n};\n\ntype ResolvedTabs = TabsProps;\n\n// The tab strip. Kept in this file because StyledTabs cannot cross a module\n// boundary (TS2742).\nconst TabsBar: React.FC<\n ResolvedTabs & {\n rest: Record<string, unknown>;\n onChange: (event: React.SyntheticEvent, newValue: string) => void;\n onCloseTab: (event: React.MouseEvent | React.KeyboardEvent, tabId: string) => void;\n }\n> = ({ rest, items, value, onChange, onCloseTab, dataTestId, ...p }) => (\n <StyledTabs\n {...rest}\n value={value}\n onChange={onChange}\n customVariant={p.variant}\n size={p.size}\n showDividers={p.showDividers}\n orientation={p.orientation}\n centered={p.centered}\n // MUI only scrolls when its own `variant` is `scrollable`; map our\n // `scrollable` flag onto it so overflowing tab rows actually scroll.\n variant={p.scrollable ? 'scrollable' : 'standard'}\n data-testid={dataTestId ? `${dataTestId}-list` : 'tabs-list'}\n scrollButtons={resolveScrollButtons(p.scrollable)}\n allowScrollButtonsMobile={p.scrollable}\n textColor={p.color}\n indicatorColor={p.color}\n sx={buildTabsSx({\n fullWidth: p.fullWidth,\n sticky: p.sticky,\n stickyOffset: p.stickyOffset,\n indicatorColor: p.indicatorColor,\n disabled: p.disabled })}\n >\n {items.map((item, index) => (\n <MuiTab\n key={item.id}\n value={item.id}\n label={<TabLabel closeTabLabel={p.closeTabLabel} item={item} onClose={onCloseTab} />}\n disabled={item.disabled || p.disabled}\n className={item.className}\n id={`tab-${item.id}`}\n aria-controls={`tabpanel-${item.id}`}\n aria-disabled={item.disabled || p.disabled}\n data-testid={dataTestId ? `${dataTestId}-tab-${index}` : `tabs-tab-${index}`}\n />\n ))}\n </StyledTabs>\n);\n\nconst TabsPanels: React.FC<ResolvedTabs> = ({\n items,\n value,\n variant,\n animateContent,\n animationDuration,\n persistContent,\n loading,\n loadingComponent,\n tabPanelProps,\n dataTestId }) => (\n <Box sx={{ mt: variant === 'enclosed' ? 0 : 2 }}>\n {items.map((item, index) => (\n <CustomTabPanel\n key={item.id}\n id={item.id}\n value={value}\n animate={animateContent}\n animationDuration={animationDuration}\n persist={persistContent}\n loading={loading}\n loadingComponent={loadingComponent}\n className={tabPanelProps?.className}\n dataTestId={dataTestId}\n index={index}\n >\n {item.content}\n </CustomTabPanel>\n ))}\n </Box>\n);\n\nexport const Tabs = React.forwardRef<HTMLDivElement, TabsProps>(\n (tabsProps, ref) => {\n const resolved = { ...TABS_DEFAULTS, ...definedProps(tabsProps) } as TabsProps;\n const {\n // Destructured only to keep it OUT of `rest`, which is spread onto the\n // DOM node — `{...resolved}` below is what actually carries it to\n // `TabsBar`. Same reason as `value` on the next line.\n closeTabLabel: _closeTabLabel,\n value: _value,\n onChange,\n onTabClose,\n className,\n disabled,\n showDividers,\n variant,\n dataTestId,\n ...rest\n } = resolved;\n\n const handleChange = (event: React.SyntheticEvent, newValue: string) => {\n if (!disabled) onChange(event, newValue);\n };\n\n const handleTabClose = (event: React.MouseEvent | React.KeyboardEvent, tabId: string) => {\n event.stopPropagation();\n onTabClose?.(tabId);\n };\n\n return (\n <Box className={className} ref={ref} data-testid={dataTestId || 'tabs'}>\n <TabsBar\n {...resolved}\n rest={rest as unknown as Record<string, unknown>}\n onChange={handleChange}\n onCloseTab={handleTabClose}\n />\n\n {showDividers && variant !== 'enclosed' && <Divider />}\n\n <TabsPanels {...resolved} />\n </Box>\n );\n },\n);\n\nTabs.displayName = 'Tabs';\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/form/Switch/Switch.tsx"],"sourcesContent":["import Box from '@mui/material/Box/index.js';\nimport React, { forwardRef } from 'react';\n\nimport { splitTestId } from '../../../platform/test-id';\nimport { withDefaults } from '../../../utils/withDefaults';\n\nimport {\n LabelContainer,\n SwitchControl,\n SwitchHelper,\n SwitchLabel,\n} from './Switch.parts';\nimport type { SwitchProps } from './Switch.types';\n\nconst DEFAULTS = {\n variant: 'default',\n color: 'primary',\n size: 'md',\n glow: false,\n glass: false,\n gradient: false,\n labelPosition: 'end',\n error: false,\n animated: true,\n loading: false,\n ripple: false,\n pulse: false,\n} satisfies Partial<SwitchProps>;\n\ntype ResolvedProps = SwitchProps & Required<Pick<SwitchProps, keyof typeof DEFAULTS>>;\n\nexport const Switch = forwardRef<HTMLButtonElement, SwitchProps>((props, ref) => {\n const {\n variant, color, size, label, description, glow, glass, gradient, labelPosition,\n onIcon, offIcon, onText, offText, error, helperText, trackWidth, trackHeight,\n checked, onChange, animated, loading, ripple, pulse,\n ...others\n } = withDefaults(props, DEFAULTS) as ResolvedProps;\n\n const { testId: dataTestId, rest } = splitTestId(others);\n const containerTestId = dataTestId ? `${dataTestId}-container` : 'switch-container';\n\n const control = (\n <SwitchControl\n customVariant={variant}\n customColor={color}\n customSize={size}\n glow={glow}\n glass={glass}\n gradient={gradient}\n trackWidth={trackWidth}\n trackHeight={trackHeight}\n onText={onText}\n offText={offText}\n loading={loading}\n ripple={ripple}\n pulse={pulse}\n checked={checked}\n onChange={onChange}\n onIcon={onIcon}\n offIcon={offIcon}\n animated={animated}\n size={size}\n dataTestId={dataTestId}\n switchRef={ref}\n rest={rest}\n />\n );\n\n const helper = <SwitchHelper helperText={helperText} error={error} dataTestId={dataTestId} />;\n\n if (!label) {\n return (\n <Box data-testid={containerTestId}>\n {control}\n {helper}\n </Box>\n );\n }\n\n return (\n <Box data-testid={containerTestId}>\n <LabelContainer labelPosition={labelPosition} error={error}>\n {labelPosition === 'start' && control}\n\n <SwitchLabel\n label={label}\n description={description}\n error={error}\n dataTestId={dataTestId}\n />\n\n {labelPosition !== 'start' && control}\n </LabelContainer>\n\n {helper}\n </Box>\n );\n});\n\nSwitch.displayName = 'Switch';\n"],"mappings":";;;;;;;;;;;;;;AAAA,OAAO,SAAS;AAChB,SAAgB,kBAAkB;AA0C9B,cA8BE,YA9BF;AA7BJ,IAAM,WAAW;AAAA,EACf,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,UAAU;AAAA,EACV,eAAe;AAAA,EACf,OAAO;AAAA,EACP,UAAU;AAAA,EACV,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,OAAO;AACT;AAIO,IAAM,SAAS,WAA2C,CAAC,OAAO,QAAQ;AAC/E,QAAM;AAAA,IACJ;AAAA,IAAS;AAAA,IAAO;AAAA,IAAM;AAAA,IAAO;AAAA,IAAa;AAAA,IAAM;AAAA,IAAO;AAAA,IAAU;AAAA,IACjE;AAAA,IAAQ;AAAA,IAAS;AAAA,IAAQ;AAAA,IAAS;AAAA,IAAO;AAAA,IAAY;AAAA,IAAY;AAAA,IACjE;AAAA,IAAS;AAAA,IAAU;AAAA,IAAU;AAAA,IAAS;AAAA,IAAQ;AAAA,IAC9C,GAAG;AAAA,EACL,IAAI,aAAa,OAAO,QAAQ;AAEhC,QAAM,EAAE,QAAQ,YAAY,KAAK,IAAI,YAAY,MAAM;AACvD,QAAM,kBAAkB,aAAa,GAAG,UAAU,eAAe;AAEjE,QAAM,UACJ;AAAA,IAAC;AAAA;AAAA,MACC,eAAe;AAAA,MACf,aAAa;AAAA,MACb,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX;AAAA;AAAA,EACF;AAGF,QAAM,SAAS,oBAAC,gBAAa,YAAwB,OAAc,YAAwB;AAE3F,MAAI,CAAC,OAAO;AACV,WACE,qBAAC,OAAI,eAAa,iBACf;AAAA;AAAA,MACA;AAAA,OACH;AAAA,EAEJ;AAEA,SACE,qBAAC,OAAI,eAAa,iBAChB;AAAA,yBAAC,kBAAe,eAA8B,OAC3C;AAAA,wBAAkB,WAAW;AAAA,MAE9B;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,MACF;AAAA,MAEC,kBAAkB,WAAW;AAAA,OAChC;AAAA,IAEC;AAAA,KACH;AAEJ,CAAC;AAED,OAAO,cAAc;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/form/Switch/Switch.parts.tsx"],"sourcesContent":["import Box from '@mui/material/Box/index.js';\nimport FormHelperText from '@mui/material/FormHelperText/index.js';\nimport MuiSwitch from '@mui/material/Switch/index.js';\nimport Typography from '@mui/material/Typography/index.js';\nimport { styled } from '@mui/material/styles/index.js';\nimport React from 'react';\n\nimport { LABEL_GAP_UNITS, SWITCH_ICON_SIZES } from './Switch.metrics';\nimport { switchSx } from './Switch.styles';\nimport type { SwitchFlags } from './Switch.styles';\nimport type { SwitchProps } from './Switch.types';\nimport type { SizeValue } from '../../../tokens/vocabulary';\n\nconst StyledSwitch = styled(MuiSwitch, {\n shouldForwardProp: (prop) =>\n ![\n 'customVariant',\n 'customColor',\n 'customSize',\n 'glow',\n 'glass',\n 'gradient',\n 'trackWidth',\n 'trackHeight',\n 'onText',\n 'offText',\n 'loading',\n 'ripple',\n 'pulse',\n ].includes(prop as string),\n})<SwitchFlags>(({ theme, ...flags }) => ({ ...switchSx(theme, flags) }));\n\n/**\n * A top or bottom label stacks and aligns to the start; start/end sit the label\n * beside the control and centre it.\n */\nconst StyledLabelContainer = styled(Box, {\n shouldForwardProp: (prop) => !['labelPosition', 'error'].includes(prop as string),\n})<{ labelPosition?: string; error?: boolean }>(({ theme, labelPosition, error }) => {\n const stacked = labelPosition === 'top' || labelPosition === 'bottom';\n\n return {\n display: 'flex',\n alignItems: stacked ? 'flex-start' : 'center',\n flexDirection:\n labelPosition === 'top' ? 'column' : labelPosition === 'bottom' ? 'column-reverse' : 'row',\n gap: theme.spacing(stacked ? LABEL_GAP_UNITS.stacked : LABEL_GAP_UNITS.beside),\n width: '100%',\n ...(error && { '& .MuiTypography-root': { color: theme.palette.error.main } }),\n };\n});\n\n/**\n * A plain wrapper over the styled row. Exporting the styled component itself\n * needs a @mui/system reference tsc calls unportable (TS2742).\n */\nexport const LabelContainer: React.FC<{\n labelPosition?: string;\n error?: boolean;\n children: React.ReactNode;\n}> = ({ labelPosition, error, children }) => (\n <StyledLabelContainer labelPosition={labelPosition} error={error}>\n {children}\n </StyledLabelContainer>\n);\n\nexport interface SwitchIconProps {\n icon: React.ReactNode;\n /** True when this icon is the one the current state should show. */\n shown: boolean;\n animated: boolean;\n size: string;\n side: 'on' | 'off';\n}\n\n/**\n * One of the two icons overlaid on the track. The on icon slides to the left\n * edge when checked and the off icon to the right when unchecked; they are\n * mirror images, so they share this component rather than being written twice.\n */\nexport const SwitchIcon: React.FC<SwitchIconProps> = ({ icon, shown, animated, size, side }) => {\n const isOn = side === 'on';\n const translate = isOn ? 'translate(-50%, -50%)' : 'translate(50%, -50%)';\n\n return (\n <Box\n sx={{\n position: 'absolute',\n top: '50%',\n ...(isOn ? { left: shown ? 4 : '50%' } : { right: shown ? 4 : '50%' }),\n transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\n opacity: shown ? 1 : 0,\n transform: `${translate} scale(${shown && animated ? 1 : 0.8})`,\n pointerEvents: 'none',\n zIndex: 2,\n color: isOn ? '#fff' : 'text.secondary',\n fontSize: SWITCH_ICON_SIZES[size as SizeValue] ?? SWITCH_ICON_SIZES.md,\n }}\n >\n {icon}\n </Box>\n );\n};\n\nexport interface SwitchControlProps extends SwitchFlags {\n checked?: boolean;\n onChange?: SwitchProps['onChange'];\n onIcon?: React.ReactNode;\n offIcon?: React.ReactNode;\n animated: boolean;\n size: string;\n dataTestId?: string;\n switchRef?: React.Ref<HTMLButtonElement>;\n rest: Record<string, unknown>;\n}\n\n/** The control itself: the track, and the two icons that may sit over it. */\nexport const SwitchControl: React.FC<SwitchControlProps> = ({\n checked,\n onChange,\n onIcon,\n offIcon,\n animated,\n size,\n dataTestId,\n switchRef,\n rest,\n ...flags\n}) => {\n const props = rest as Record<string, unknown> & {\n disabled?: boolean;\n inputProps?: React.InputHTMLAttributes<HTMLInputElement>;\n };\n\n return (\n <Box sx={{ position: 'relative', display: 'inline-flex' }}>\n <StyledSwitch\n ref={switchRef}\n {...flags}\n checked={checked}\n onChange={onChange}\n disabled={Boolean(flags.loading) || props.disabled}\n inputProps={\n {\n 'aria-label': props['aria-label'],\n 'aria-describedby': props['aria-describedby'],\n ...props.inputProps,\n 'data-testid': dataTestId || 'switch',\n } as React.InputHTMLAttributes<HTMLInputElement>\n }\n {...props}\n />\n\n {onIcon && (\n <SwitchIcon\n icon={onIcon}\n shown={Boolean(checked)}\n animated={animated}\n size={size}\n side=\"on\"\n />\n )}\n {offIcon && (\n <SwitchIcon\n icon={offIcon}\n shown={!checked}\n animated={animated}\n size={size}\n side=\"off\"\n />\n )}\n </Box>\n );\n};\n\nexport const SwitchHelper: React.FC<{\n helperText?: React.ReactNode;\n error?: boolean;\n dataTestId?: string;\n}> = ({ helperText, error, dataTestId }) =>\n helperText ? (\n <FormHelperText\n error={error}\n sx={{ mt: 1 }}\n data-testid={dataTestId ? `${dataTestId}-helper` : 'switch-helper'}\n >\n {helperText}\n </FormHelperText>\n ) : null;\n\nexport const SwitchLabel: React.FC<{\n label: React.ReactNode;\n description?: React.ReactNode;\n error?: boolean;\n dataTestId?: string;\n}> = ({ label, description, error, dataTestId }) => (\n <Box sx={{ flex: 1 }}>\n <Typography\n variant=\"body2\"\n fontWeight={500}\n color={error ? 'error.main' : 'text.primary'}\n data-testid={dataTestId ? `${dataTestId}-label` : 'switch-label'}\n >\n {label}\n </Typography>\n {description && (\n <Typography\n variant=\"caption\"\n color={error ? 'error.main' : 'text.secondary'}\n sx={{ display: 'block', mt: 0.5 }}\n >\n {description}\n </Typography>\n )}\n </Box>\n);\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/tokens/theme.ts"],"sourcesContent":["import { darken, getContrastRatio, lighten } from './color';\nimport { cssLengthToPx, cssTrackingToEm } from './css-units';\nimport { HEADING_SCALE, type HeadingLevel } from './heading-scale';\n\nimport type { SizeValue } from './vocabulary';\n\n/**\n * THE THEME BOTH RENDERERS READ.\n *\n * On the web every component styles itself from MUI's `Theme`, which is built\n * by the host (`@12-apps/app-shell`'s `createAppTheme` in the origin apps) and\n * reaches a component through emotion's context. React Native has no emotion,\n * no CSS and no MUI, so a native `Button` needs the same decisions — the\n * palette, the spacing unit, the radius, the type scale — from somewhere that\n * does not import a renderer.\n *\n * This is that somewhere. `UiTheme` is a plain object of numbers and colour\n * strings. `createUiTheme` derives it the way MUI's `createPalette` derives its\n * own: a `light` shade is `lighten(main, 0.2)`, a `dark` shade `darken(main,\n * 0.3)`, `contrastText` flips at a 3:1 ratio against `rgba(0, 0, 0, 0.87)`.\n * Same seeds in, same shades out, on both sides — that is the whole basis for\n * a native button being the web button's colour and not a near miss.\n *\n * Numbers are in px on the web and dp on native; both are the CSS-pixel unit\n * a design is drawn in, so a `fontSize: 16` here IS `1rem` in a web style\n * and `16` in a `StyleSheet`. The web components keep their `rem` strings and\n * derive them from these numbers where the two meet (see `px()` below and the\n * `*.metrics.ts` file beside each ported component).\n *\n * `danger` and `neutral` are this package's names (see `./scales`); `danger`\n * is MUI's `error` and `neutral` is drawn from the grey ramp the way\n * `Button.styles.ts` has always drawn it.\n */\n\nexport type UiThemeMode = 'light' | 'dark';\n\nexport interface UiPaletteColor {\n main: string;\n light: string;\n dark: string;\n contrastText: string;\n}\n\nexport type UiGreyStep = 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;\n\nexport interface UiPalette {\n mode: UiThemeMode;\n primary: UiPaletteColor;\n secondary: UiPaletteColor;\n success: UiPaletteColor;\n warning: UiPaletteColor;\n info: UiPaletteColor;\n danger: UiPaletteColor;\n neutral: UiPaletteColor;\n text: { primary: string; secondary: string; disabled: string };\n background: { default: string; paper: string };\n divider: string;\n action: {\n active: string;\n hover: string;\n selected: string;\n disabled: string;\n disabledBackground: string;\n focus: string;\n };\n grey: Record<UiGreyStep, string>;\n}\n\n/** One step of the body scale: `fontSize` in px, `lineHeight` as a ratio. */\nexport interface UiTypeStep {\n fontSize: number;\n lineHeight: number;\n}\n\nexport type UiFontWeight = 'light' | 'normal' | 'medium' | 'semibold' | 'bold';\n\nexport interface UiHeadingStep extends UiTypeStep {\n /** In em, so it scales with the step. `undefined` is \"normal\". */\n letterSpacing?: number;\n normalWeight: number;\n}\n\nexport interface UiTypography {\n /**\n * Native has no fallback stacks: a font is either installed and named, or\n * `undefined` and the platform's own. The web default is MUI's Roboto stack.\n */\n fontFamily: string | undefined;\n monospaceFontFamily: string | undefined;\n sizes: Record<SizeValue, UiTypeStep>;\n weights: Record<UiFontWeight, number>;\n heading: Record<HeadingLevel, UiHeadingStep>;\n}\n\nexport interface UiTheme {\n mode: UiThemeMode;\n palette: UiPalette;\n /** MUI's `theme.spacing(n)`: `n` units of {@link UiTheme.spacingUnit}, in px. */\n spacing: (units: number) => number;\n spacingUnit: number;\n /** `md` is MUI's `shape.borderRadius`; the others are its halves and doubles. */\n radius: { sm: number; md: number; lg: number; xl: number; full: number };\n typography: UiTypography;\n zIndex: { appBar: number; drawer: number; modal: number; snackbar: number; tooltip: number };\n}\n\n/** A seed for one palette slot: a hex `main`, or any subset of the four shades. */\nexport type UiPaletteSeed = string | Partial<UiPaletteColor>;\n\nexport interface UiThemeOptions {\n mode?: UiThemeMode;\n palette?: Partial<{\n primary: UiPaletteSeed;\n secondary: UiPaletteSeed;\n success: UiPaletteSeed;\n warning: UiPaletteSeed;\n info: UiPaletteSeed;\n danger: UiPaletteSeed;\n background: Partial<UiPalette['background']>;\n }>;\n typography?: Partial<Pick<UiTypography, 'fontFamily' | 'monospaceFontFamily'>>;\n spacingUnit?: number;\n}\n\nconst ROOT_FONT_PX = 16;\n\n/** The px value as the rem string the web components write. */\nexport const px = (value: number): string => `${value / ROOT_FONT_PX}rem`;\n\n/** MUI's `createPalette` defaults, exactly. */\nconst TONAL_OFFSET = 0.2;\nconst CONTRAST_THRESHOLD = 3;\nconst DARK_TEXT_PRIMARY = 'rgba(0, 0, 0, 0.87)';\nconst LIGHT_TEXT_PRIMARY = '#fff';\n\nexport const GREY: Record<UiGreyStep, string> = {\n 50: '#fafafa',\n 100: '#f5f5f5',\n 200: '#eeeeee',\n 300: '#e0e0e0',\n 400: '#bdbdbd',\n 500: '#9e9e9e',\n 600: '#757575',\n 700: '#616161',\n 800: '#424242',\n 900: '#212121',\n};\n\n/**\n * The platform's own seeds. The pair `@12-apps/ui`'s Storybook preview and\n * `@12-apps/app-shell`'s `DEFAULT_THEME_TOKENS` both carry — keep the three in\n * step if the design tokens change.\n */\nexport const DEFAULT_BRAND: Record<UiThemeMode, { primary: string; secondary: string }> = {\n light: { primary: '#6366F1', secondary: '#8B5CF6' },\n dark: { primary: '#818CF8', secondary: '#A78BFA' },\n};\n\n/** MUI's semantic defaults per mode. These are declared shades, not derived. */\nconst SEMANTIC_DEFAULTS: Record<\n UiThemeMode,\n Record<'success' | 'warning' | 'info' | 'danger', UiPaletteColor>\n> = {\n light: {\n success: { main: '#2e7d32', light: '#4caf50', dark: '#1b5e20', contrastText: '#fff' },\n warning: { main: '#ed6c02', light: '#ff9800', dark: '#e65100', contrastText: '#fff' },\n info: { main: '#0288d1', light: '#03a9f4', dark: '#01579b', contrastText: '#fff' },\n danger: { main: '#d32f2f', light: '#ef5350', dark: '#c62828', contrastText: '#fff' },\n },\n dark: {\n success: { main: '#66bb6a', light: '#81c784', dark: '#388e3c', contrastText: DARK_TEXT_PRIMARY },\n warning: { main: '#ffa726', light: '#ffb74d', dark: '#f57c00', contrastText: DARK_TEXT_PRIMARY },\n info: { main: '#29b6f6', light: '#4fc3f7', dark: '#0288d1', contrastText: DARK_TEXT_PRIMARY },\n danger: { main: '#f44336', light: '#e57373', dark: '#d32f2f', contrastText: '#fff' },\n },\n};\n\nconst MODE_DEFAULTS: Record<\n UiThemeMode,\n Pick<UiPalette, 'text' | 'background' | 'divider' | 'action'>\n> = {\n light: {\n text: { primary: DARK_TEXT_PRIMARY, secondary: 'rgba(0, 0, 0, 0.6)', disabled: 'rgba(0, 0, 0, 0.38)' },\n background: { default: '#fff', paper: '#fff' },\n divider: 'rgba(0, 0, 0, 0.12)',\n action: {\n active: 'rgba(0, 0, 0, 0.54)',\n hover: 'rgba(0, 0, 0, 0.04)',\n selected: 'rgba(0, 0, 0, 0.08)',\n disabled: 'rgba(0, 0, 0, 0.26)',\n disabledBackground: 'rgba(0, 0, 0, 0.12)',\n focus: 'rgba(0, 0, 0, 0.12)',\n },\n },\n dark: {\n text: { primary: '#fff', secondary: 'rgba(255, 255, 255, 0.7)', disabled: 'rgba(255, 255, 255, 0.5)' },\n background: { default: '#121212', paper: '#121212' },\n divider: 'rgba(255, 255, 255, 0.12)',\n action: {\n active: '#fff',\n hover: 'rgba(255, 255, 255, 0.08)',\n selected: 'rgba(255, 255, 255, 0.16)',\n disabled: 'rgba(255, 255, 255, 0.3)',\n disabledBackground: 'rgba(255, 255, 255, 0.12)',\n focus: 'rgba(255, 255, 255, 0.12)',\n },\n },\n};\n\n/**\n * MUI's `getContrastText`: white where white reads at 3:1 on the colour, the\n * light mode's dark ink otherwise. (MUI's source spells the white as the DARK\n * palette's `text.primary`, which is what made it easy to read backwards.)\n */\nexport function contrastText(background: string): string {\n return getContrastRatio(background, LIGHT_TEXT_PRIMARY) >= CONTRAST_THRESHOLD\n ? LIGHT_TEXT_PRIMARY\n : DARK_TEXT_PRIMARY;\n}\n\n/**\n * MUI's `augmentColor` for a custom colour: derive whatever shade the seed\n * left out. `light` is one tonal offset up, `dark` one and a half down.\n */\nexport function augmentColor(seed: UiPaletteSeed): UiPaletteColor {\n const partial = typeof seed === 'string' ? { main: seed } : seed;\n const main = partial.main ?? partial.light ?? partial.dark;\n if (!main) {\n throw new Error('@12-apps/ui: a palette seed needs at least a `main` colour.');\n }\n return {\n main,\n light: partial.light ?? lighten(main, TONAL_OFFSET),\n dark: partial.dark ?? darken(main, TONAL_OFFSET * 1.5),\n contrastText: partial.contrastText ?? contrastText(main),\n };\n}\n\nconst semantic = (\n mode: UiThemeMode,\n key: 'success' | 'warning' | 'info' | 'danger',\n seed: UiPaletteSeed | undefined,\n): UiPaletteColor => (seed === undefined ? SEMANTIC_DEFAULTS[mode][key] : augmentColor(seed));\n\n/** `neutral` as `accentFor` in `./scales` has always drawn it: three greys and white. */\nexport const NEUTRAL: UiPaletteColor = {\n main: GREY[600],\n light: GREY[400],\n dark: GREY[800],\n contrastText: '#fff',\n};\n\n/** The body scale `Text` renders, in px. `Text.tsx`'s rem map is this, divided by 16. */\nexport const TYPE_SIZES: Record<SizeValue, UiTypeStep> = {\n xs: { fontSize: 12, lineHeight: 1.2 },\n sm: { fontSize: 14, lineHeight: 1.3 },\n md: { fontSize: 16, lineHeight: 1.5 },\n lg: { fontSize: 18, lineHeight: 1.4 },\n xl: { fontSize: 20, lineHeight: 1.3 },\n};\n\nexport const FONT_WEIGHTS: Record<UiFontWeight, number> = {\n light: 300,\n normal: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n};\n\n// `HEADING_SCALE` speaks CSS, this theme speaks numbers; `./css-units` is the\n// one place that conversion is written.\nconst HEADING_STEPS = Object.fromEntries(\n Object.entries(HEADING_SCALE).map(([level, metrics]) => [\n level,\n {\n fontSize: cssLengthToPx(metrics.fontSize, ROOT_FONT_PX),\n lineHeight: metrics.lineHeight,\n letterSpacing: cssTrackingToEm(metrics.letterSpacing),\n normalWeight: metrics.normalWeight,\n },\n ]),\n) as Record<HeadingLevel, UiHeadingStep>;\n\nexport const WEB_FONT_FAMILY = '\"Roboto\", \"Helvetica\", \"Arial\", sans-serif';\nexport const WEB_MONOSPACE_FONT_FAMILY = 'Monaco, Menlo, \"Ubuntu Mono\", \"Courier New\", monospace';\n\n/**\n * Build the theme. Every field is derived here so a host that changes one\n * seed gets every dependent shade recomputed, on both renderers, identically.\n */\nexport function createUiTheme(options: UiThemeOptions = {}): UiTheme {\n const mode = options.mode ?? 'light';\n const seeds = options.palette ?? {};\n const brand = DEFAULT_BRAND[mode];\n const defaults = MODE_DEFAULTS[mode];\n const spacingUnit = options.spacingUnit ?? 8;\n\n const palette: UiPalette = {\n mode,\n primary: augmentColor(seeds.primary ?? brand.primary),\n secondary: augmentColor(seeds.secondary ?? brand.secondary),\n success: semantic(mode, 'success', seeds.success),\n warning: semantic(mode, 'warning', seeds.warning),\n info: semantic(mode, 'info', seeds.info),\n danger: semantic(mode, 'danger', seeds.danger),\n neutral: NEUTRAL,\n text: defaults.text,\n background: { ...defaults.background, ...seeds.background },\n divider: defaults.divider,\n action: defaults.action,\n grey: GREY,\n };\n\n return {\n mode,\n palette,\n spacing: (units: number) => units * spacingUnit,\n spacingUnit,\n radius: { sm: 2, md: 4, lg: 8, xl: 16, full: 9999 },\n typography: {\n fontFamily: options.typography?.fontFamily,\n monospaceFontFamily: options.typography?.monospaceFontFamily,\n sizes: TYPE_SIZES,\n weights: FONT_WEIGHTS,\n heading: HEADING_STEPS,\n },\n zIndex: { appBar: 1100, drawer: 1200, modal: 1300, snackbar: 1400, tooltip: 1500 },\n };\n}\n\n/** The palette slot a house colour name resolves to. */\nexport type UiPaletteKey = 'primary' | 'secondary' | 'success' | 'warning' | 'info' | 'danger' | 'neutral';\n\nexport const DEFAULT_UI_THEME: UiTheme = createUiTheme();\n"],"mappings":"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","names":[]}