@12-apps/ui 6.52.1 → 6.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (298) hide show
  1. package/components-catalog.md +1 -1
  2. package/dist/_internal/components/data-display/AlertDialog/AlertDialog.js +2 -1
  3. package/dist/_internal/components/data-display/AlertDialog/AlertDialog.parts.js +9 -0
  4. package/dist/_internal/components/data-display/AlertDialog/AlertDialog.parts.js.map +1 -0
  5. package/dist/_internal/components/data-display/Avatar/Avatar.js +3 -3
  6. package/dist/_internal/components/data-display/Avatar/Avatar.view.js +2 -2
  7. package/dist/_internal/components/data-display/CardKit/use-remove-confirm.js +7 -6
  8. package/dist/_internal/components/data-display/CardKit/use-row-confirm.js +7 -6
  9. package/dist/_internal/components/data-display/Chart/SpecChart.js +3 -3
  10. package/dist/_internal/components/data-display/Chart/chart-spec.js +2 -2
  11. package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +24 -24
  12. package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +33 -32
  13. package/dist/_internal/components/data-display/DataViews/ManageViewsDialog.js +7 -6
  14. package/dist/_internal/components/data-display/DataViews/base-list-card-geometry.js +4 -4
  15. package/dist/_internal/components/data-display/DataViews/base-list-card-slots.js +3 -3
  16. package/dist/_internal/components/data-display/DataViews/base-list-card.js +6 -6
  17. package/dist/_internal/components/data-display/DataViews/data-views-category-pill.js +6 -6
  18. package/dist/_internal/components/data-display/DataViews/data-views-display-panel.js +2 -2
  19. package/dist/_internal/components/data-display/DataViews/data-views-filter-panel.js +9 -9
  20. package/dist/_internal/components/data-display/DataViews/data-views-grid-bodies.js +3 -3
  21. package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +21 -21
  22. package/dist/_internal/components/data-display/DataViews/data-views-inline-bar.js +11 -11
  23. package/dist/_internal/components/data-display/DataViews/data-views-more-fields.js +9 -9
  24. package/dist/_internal/components/data-display/DataViews/data-views-more-filters.js +10 -10
  25. package/dist/_internal/components/data-display/DataViews/data-views-range-pill.js +2 -2
  26. package/dist/_internal/components/data-display/DataViews/data-views-shell-toolbar.js +6 -6
  27. package/dist/_internal/components/data-display/DataViews/data-views-table-parts.js +9 -8
  28. package/dist/_internal/components/data-display/DataViews/data-views-toolbar.js +5 -5
  29. package/dist/_internal/components/data-display/DataViews/list-card-rails.js +2 -2
  30. package/dist/_internal/components/data-display/DataViews/use-data-views-state.js +2 -2
  31. package/dist/_internal/components/data-display/FleetMap/FleetBody.js +4 -4
  32. package/dist/_internal/components/data-display/FleetMap/FleetCanvas.js +3 -3
  33. package/dist/_internal/components/data-display/FleetMap/FleetMap.fixtures.js +2 -2
  34. package/dist/_internal/components/data-display/FleetMap/FleetMap.js +5 -5
  35. package/dist/_internal/components/data-display/HoverCard/HoverCard.js +2 -2
  36. package/dist/_internal/components/data-display/InteractiveTooltip/InteractiveTooltip.hooks.js +3 -1
  37. package/dist/_internal/components/data-display/InteractiveTooltip/InteractiveTooltip.js +2 -2
  38. package/dist/_internal/components/data-display/Lightbox/Lightbox.js +3 -3
  39. package/dist/_internal/components/data-display/MapPreview/MapPreview.js +2 -2
  40. package/dist/_internal/components/data-display/Progress/Progress.js +2 -2
  41. package/dist/_internal/components/data-display/Sheet/Sheet.hooks.js +2 -2
  42. package/dist/_internal/components/data-display/Sheet/Sheet.js +4 -4
  43. package/dist/_internal/components/data-display/index.js +29 -28
  44. package/dist/_internal/components/feedback/ConfirmAction/ConfirmAction.js +4 -3
  45. package/dist/_internal/components/feedback/ConfirmAction/ConfirmAction.parts.js +3 -2
  46. package/dist/_internal/components/feedback/ConfirmAction/ConfirmButton.js +5 -4
  47. package/dist/_internal/components/feedback/ConfirmAction/with-confirmation.js +4 -3
  48. package/dist/_internal/components/feedback/index.js +8 -7
  49. package/dist/_internal/components/form/AddressAutocomplete/AddressAutocomplete.hooks.js +2 -2
  50. package/dist/_internal/components/form/AddressAutocomplete/AddressAutocomplete.js +5 -5
  51. package/dist/_internal/components/form/Autocomplete/Autocomplete.js +2 -2
  52. package/dist/_internal/components/form/Calendar/Calendar.hooks.js +2 -2
  53. package/dist/_internal/components/form/Calendar/Calendar.js +3 -3
  54. package/dist/_internal/components/form/CategorySelect/CategoryPanel.js +1 -1
  55. package/dist/_internal/components/form/CategorySelect/CategorySelect.js +4 -4
  56. package/dist/_internal/components/form/Command/Command.js +3 -3
  57. package/dist/_internal/components/form/DateRangePicker/DateRangePicker.js +5 -5
  58. package/dist/_internal/components/form/UploadButton/UploadButton.js +2 -2
  59. package/dist/_internal/components/form/index.js +22 -22
  60. package/dist/_internal/components/form/total-form/Fields/CategoryField.js +5 -5
  61. package/dist/_internal/components/form/total-form/Fields/index.js +9 -9
  62. package/dist/_internal/components/index.js +72 -70
  63. package/dist/_internal/components/layout/ScrollArea/ScrollArea.js +2 -2
  64. package/dist/_internal/components/layout/SettingCard/SettingCard.js +9 -4
  65. package/dist/_internal/components/layout/SettingCard/SettingCard.metrics.js +1 -1
  66. package/dist/_internal/components/layout/SettingCard/SettingCard.parts.js +3 -3
  67. package/dist/_internal/components/layout/SettingCard/SettingCard.styles.js +6 -2
  68. package/dist/_internal/components/layout/SettingCard/SettingCard.summary.js +63 -0
  69. package/dist/_internal/components/layout/SettingCard/SettingCard.summary.js.map +1 -0
  70. package/dist/_internal/components/layout/SettingCard/SettingGrid.js +4 -4
  71. package/dist/_internal/components/layout/SettingCard/SettingGroup.js +10 -5
  72. package/dist/_internal/components/layout/SettingCard/SettingSwitch.js +9 -4
  73. package/dist/_internal/components/layout/SettingCard/SettingToggle.js +10 -5
  74. package/dist/_internal/components/layout/index.js +18 -13
  75. package/dist/_internal/components/navigation/AppHeader/AppHeader.details.js +5 -5
  76. package/dist/_internal/components/navigation/index.js +5 -5
  77. package/dist/_internal/en-US.data-display.js +2 -2
  78. package/dist/_internal/en-US.layout.js +1 -1
  79. package/dist/_internal/pt-BR.data-display.js +2 -2
  80. package/dist/_internal/pt-BR.layout.js +1 -1
  81. package/dist/_internal/user-avatar/user-avatar.js +4 -4
  82. package/dist/charts.js +6 -6
  83. package/dist/{chunk-GXQDWHPN.js → chunk-2CJZLL5Y.js} +2 -2
  84. package/dist/{chunk-57VL5UX7.js → chunk-2JTZWQ25.js} +6 -4
  85. package/dist/chunk-2JTZWQ25.js.map +1 -0
  86. package/dist/{chunk-STTULW2K.js → chunk-2KVWOTEQ.js} +5 -5
  87. package/dist/{chunk-ISW5K72V.js → chunk-2ZRZTGWP.js} +5 -5
  88. package/dist/{chunk-QOLIBVGS.js → chunk-3CIIB74Y.js} +2 -2
  89. package/dist/{chunk-33L26P4J.js → chunk-3ZKGNEP2.js} +5 -3
  90. package/dist/{chunk-33L26P4J.js.map → chunk-3ZKGNEP2.js.map} +1 -1
  91. package/dist/{chunk-2OTBMU5Z.js → chunk-44LYXLW7.js} +7 -7
  92. package/dist/{chunk-OG6LYQ7C.js → chunk-4PFKMNLP.js} +8 -68
  93. package/dist/chunk-4PFKMNLP.js.map +1 -0
  94. package/dist/{chunk-LYVTJLCF.js → chunk-56JF5PZK.js} +4 -4
  95. package/dist/{chunk-5KGABAQB.js → chunk-5752357K.js} +4 -4
  96. package/dist/{chunk-SPZAEMGW.js → chunk-5WX6U34F.js} +4 -4
  97. package/dist/{chunk-QHXMNSOZ.js → chunk-6L6VXRLJ.js} +2 -2
  98. package/dist/{chunk-VVFASSFY.js → chunk-6VGB4OX2.js} +3 -3
  99. package/dist/{chunk-FRP7NM6X.js → chunk-6WZUKV55.js} +2 -2
  100. package/dist/{chunk-QEINKMMX.js → chunk-7C763T3K.js} +2 -2
  101. package/dist/{chunk-PARTZ7XI.js → chunk-7JKDB5J5.js} +4 -4
  102. package/dist/{chunk-G5XHAN56.js → chunk-7WWPKA7Y.js} +3 -3
  103. package/dist/{chunk-3U7WKBMH.js → chunk-AA2X5GOT.js} +5 -3
  104. package/dist/{chunk-3U7WKBMH.js.map → chunk-AA2X5GOT.js.map} +1 -1
  105. package/dist/{chunk-QYV7KLEN.js → chunk-ASGSC5UA.js} +5 -5
  106. package/dist/{chunk-7GQ2ZZBQ.js → chunk-BCTRC6AR.js} +2 -2
  107. package/dist/{chunk-XSHWEUDB.js → chunk-BE5Z36XZ.js} +4 -4
  108. package/dist/{chunk-IC7GHPMK.js → chunk-BFRVMCQM.js} +7 -2
  109. package/dist/chunk-BFRVMCQM.js.map +1 -0
  110. package/dist/{chunk-PM7SI4YT.js → chunk-BJOKL5PQ.js} +5 -5
  111. package/dist/{chunk-PGPPN63I.js → chunk-EMEXXAQI.js} +2 -2
  112. package/dist/{chunk-JUHNEYCH.js → chunk-GCH7CLM4.js} +2 -2
  113. package/dist/{chunk-R6SBP5M5.js → chunk-GOWBYHYW.js} +4 -4
  114. package/dist/{chunk-LZQQ4JXY.js → chunk-HGVPPJKE.js} +8 -8
  115. package/dist/{chunk-HCEJT65A.js → chunk-HKD4TDZP.js} +2 -2
  116. package/dist/{chunk-XNBX3M35.js → chunk-HLCEKWFS.js} +4 -4
  117. package/dist/{chunk-4MGFUPQT.js → chunk-HOJL2GKW.js} +4 -4
  118. package/dist/{chunk-V5ZLUJV7.js → chunk-HRMB72E4.js} +2 -2
  119. package/dist/{chunk-3GVMUASU.js → chunk-HV7HIMMY.js} +2 -2
  120. package/dist/{chunk-CSDVRHUX.js → chunk-HWBKMUMV.js} +4 -4
  121. package/dist/{chunk-KN3WYEH2.js → chunk-IA6F7DU6.js} +4 -4
  122. package/dist/{chunk-BE5FGUJS.js → chunk-IM5SR7G2.js} +2 -2
  123. package/dist/chunk-IQQX3NDO.js +96 -0
  124. package/dist/chunk-IQQX3NDO.js.map +1 -0
  125. package/dist/{chunk-PJVDIUT2.js → chunk-IRNKHHQM.js} +3 -3
  126. package/dist/{chunk-4XET5MWR.js → chunk-KKE4SHRS.js} +2 -2
  127. package/dist/{chunk-ZTTFLIPH.js → chunk-L624DFJV.js} +2 -2
  128. package/dist/{chunk-OYT7YXQL.js → chunk-MGPN5TZE.js} +5 -5
  129. package/dist/{chunk-ERY6D2OV.js → chunk-MWPXKZ7O.js} +4 -4
  130. package/dist/{chunk-SCCE6VWY.js → chunk-N2Z7NHD5.js} +2 -2
  131. package/dist/chunk-N4R6T5K7.js +95 -0
  132. package/dist/chunk-N4R6T5K7.js.map +1 -0
  133. package/dist/{chunk-GNHXFJRR.js → chunk-N6EEY7V3.js} +2 -2
  134. package/dist/{chunk-OEBHWQSX.js → chunk-OESAYTNG.js} +9 -4
  135. package/dist/chunk-OESAYTNG.js.map +1 -0
  136. package/dist/{chunk-4WCDMCIS.js → chunk-PI3GPLE2.js} +2 -2
  137. package/dist/{chunk-XAUKQZJK.js → chunk-QX4LMVL2.js} +2 -2
  138. package/dist/{chunk-S5UY5U73.js → chunk-QYJ25FWM.js} +20 -2
  139. package/dist/{chunk-S5UY5U73.js.map → chunk-QYJ25FWM.js.map} +1 -1
  140. package/dist/{chunk-6PYX6V3R.js → chunk-RJXVVLBO.js} +4 -4
  141. package/dist/{chunk-FRCBJLV5.js → chunk-RKKYSSAV.js} +5 -5
  142. package/dist/{chunk-WF7BZT6V.js → chunk-RR6BIHFX.js} +2 -2
  143. package/dist/{chunk-NGAU6PNB.js → chunk-RRVQVQF7.js} +5 -5
  144. package/dist/{chunk-FWPFCK4D.js → chunk-S6G3CJFP.js} +2 -2
  145. package/dist/{chunk-F33YKDO2.js → chunk-TEST2NBS.js} +5 -5
  146. package/dist/{chunk-BJZOBG24.js → chunk-UJHXEOU3.js} +2 -2
  147. package/dist/{chunk-NKJSYZEU.js → chunk-V32626FV.js} +4 -4
  148. package/dist/{chunk-MLDA44NW.js → chunk-VGXSPUTD.js} +3 -3
  149. package/dist/{chunk-U4QUDFPJ.js → chunk-VKVOP4OK.js} +2 -2
  150. package/dist/{chunk-CTXF22BU.js → chunk-VODKYDC4.js} +5 -5
  151. package/dist/{chunk-DWJH3KXN.js → chunk-WAKGVAOB.js} +4 -4
  152. package/dist/{chunk-3DO5AJCG.js → chunk-WE2LNTR6.js} +12 -5
  153. package/dist/chunk-WE2LNTR6.js.map +1 -0
  154. package/dist/{chunk-SZA44EFA.js → chunk-WOEVBEGJ.js} +4 -4
  155. package/dist/{chunk-EOTV5BLM.js → chunk-WOP2DRMC.js} +2 -2
  156. package/dist/{chunk-E6JRPGMN.js → chunk-X3DVZNZH.js} +2 -2
  157. package/dist/{chunk-MLQYIJTO.js → chunk-XM7QCNZQ.js} +9 -3
  158. package/dist/chunk-XM7QCNZQ.js.map +1 -0
  159. package/dist/{chunk-P35CTP6L.js → chunk-Y3WB66XT.js} +7 -7
  160. package/dist/{chunk-DI46ZEWP.js → chunk-Y5QDXG5N.js} +20 -4
  161. package/dist/chunk-Y5QDXG5N.js.map +1 -0
  162. package/dist/{chunk-TNQDSTIA.js → chunk-Y6C4MYZE.js} +7 -7
  163. package/dist/{chunk-TBZKUZNW.js → chunk-ZPWU7Z6O.js} +3 -3
  164. package/dist/{chunk-QQSRZUT4.js → chunk-ZXEDKRRT.js} +4 -4
  165. package/dist/data-display/AlertDialog.js +2 -1
  166. package/dist/data-display/Avatar.js +3 -3
  167. package/dist/data-display/CardKit.js +14 -13
  168. package/dist/data-display/Chart.js +6 -6
  169. package/dist/data-display/DataViews.js +42 -41
  170. package/dist/data-display/FleetMap.js +5 -5
  171. package/dist/data-display/HoverCard.js +2 -2
  172. package/dist/data-display/InteractiveTooltip.js +2 -2
  173. package/dist/data-display/Lightbox.js +3 -3
  174. package/dist/data-display/MapPreview.js +2 -2
  175. package/dist/data-display/Progress.js +2 -2
  176. package/dist/data-display/Sheet.js +4 -4
  177. package/dist/en-US.js +2 -2
  178. package/dist/feedback/ConfirmAction.js +8 -7
  179. package/dist/form/AddressAutocomplete.js +5 -5
  180. package/dist/form/Autocomplete.js +2 -2
  181. package/dist/form/Calendar.js +3 -3
  182. package/dist/form/CategorySelect.js +4 -4
  183. package/dist/form/Command.js +3 -3
  184. package/dist/form/DateRangePicker.js +10 -10
  185. package/dist/form/UploadButton.js +2 -2
  186. package/dist/form/total-form.js +7 -7
  187. package/dist/layout/ContentToolbar.js +3 -3
  188. package/dist/layout/ScrollArea.js +2 -2
  189. package/dist/layout/SettingCard.js +13 -8
  190. package/dist/locales.js +4 -4
  191. package/dist/navigation/AppHeader.js +5 -5
  192. package/dist/pt-BR.js +2 -2
  193. package/dist/types/components/data-display/AlertDialog/AlertDialog.d.ts.map +1 -1
  194. package/dist/types/components/data-display/AlertDialog/AlertDialog.parts.d.ts +13 -0
  195. package/dist/types/components/data-display/AlertDialog/AlertDialog.parts.d.ts.map +1 -0
  196. package/dist/types/components/data-display/AlertDialog/AlertDialog.types.d.ts +16 -3
  197. package/dist/types/components/data-display/AlertDialog/AlertDialog.types.d.ts.map +1 -1
  198. package/dist/types/components/data-display/InteractiveTooltip/InteractiveTooltip.d.ts.map +1 -1
  199. package/dist/types/components/data-display/InteractiveTooltip/InteractiveTooltip.hooks.d.ts +18 -0
  200. package/dist/types/components/data-display/InteractiveTooltip/InteractiveTooltip.hooks.d.ts.map +1 -1
  201. package/dist/types/components/layout/SettingCard/SettingCard.d.ts.map +1 -1
  202. package/dist/types/components/layout/SettingCard/SettingCard.metrics.d.ts +5 -0
  203. package/dist/types/components/layout/SettingCard/SettingCard.metrics.d.ts.map +1 -1
  204. package/dist/types/components/layout/SettingCard/SettingCard.parts.d.ts +2 -0
  205. package/dist/types/components/layout/SettingCard/SettingCard.parts.d.ts.map +1 -1
  206. package/dist/types/components/layout/SettingCard/SettingCard.styles.d.ts +9 -2
  207. package/dist/types/components/layout/SettingCard/SettingCard.styles.d.ts.map +1 -1
  208. package/dist/types/components/layout/SettingCard/SettingCard.summary.d.ts +33 -0
  209. package/dist/types/components/layout/SettingCard/SettingCard.summary.d.ts.map +1 -0
  210. package/dist/types/components/layout/SettingCard/SettingSwitch.d.ts.map +1 -1
  211. package/dist/types/copy/layout.d.ts +8 -0
  212. package/dist/types/copy/layout.d.ts.map +1 -1
  213. package/dist/types/en-US.layout.d.ts.map +1 -1
  214. package/dist/types/pt-BR.layout.d.ts.map +1 -1
  215. package/dist/user-avatar.js +4 -4
  216. package/package.json +1 -1
  217. package/src/components/data-display/AlertDialog/AlertDialog.md +30 -0
  218. package/src/components/data-display/AlertDialog/AlertDialog.parts.tsx +180 -0
  219. package/src/components/data-display/AlertDialog/AlertDialog.tsx +5 -85
  220. package/src/components/data-display/AlertDialog/AlertDialog.types.ts +17 -3
  221. package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.hooks.ts +36 -0
  222. package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.tsx +7 -2
  223. package/src/components/layout/SettingCard/SettingCard.md +1 -1
  224. package/src/components/layout/SettingCard/SettingCard.metrics.ts +5 -0
  225. package/src/components/layout/SettingCard/SettingCard.parts.tsx +4 -0
  226. package/src/components/layout/SettingCard/SettingCard.styles.ts +17 -5
  227. package/src/components/layout/SettingCard/SettingCard.summary.tsx +100 -0
  228. package/src/components/layout/SettingCard/SettingCard.tsx +6 -2
  229. package/src/components/layout/SettingCard/SettingSwitch.tsx +11 -2
  230. package/src/components/layout/SettingCard/SettingToggle.md +1 -1
  231. package/src/copy/layout.ts +8 -0
  232. package/src/en-US.layout.ts +2 -0
  233. package/src/pt-BR.layout.ts +2 -0
  234. package/dist/chunk-3DO5AJCG.js.map +0 -1
  235. package/dist/chunk-57VL5UX7.js.map +0 -1
  236. package/dist/chunk-DI46ZEWP.js.map +0 -1
  237. package/dist/chunk-IC7GHPMK.js.map +0 -1
  238. package/dist/chunk-MLQYIJTO.js.map +0 -1
  239. package/dist/chunk-OEBHWQSX.js.map +0 -1
  240. package/dist/chunk-OG6LYQ7C.js.map +0 -1
  241. /package/dist/{chunk-GXQDWHPN.js.map → chunk-2CJZLL5Y.js.map} +0 -0
  242. /package/dist/{chunk-STTULW2K.js.map → chunk-2KVWOTEQ.js.map} +0 -0
  243. /package/dist/{chunk-ISW5K72V.js.map → chunk-2ZRZTGWP.js.map} +0 -0
  244. /package/dist/{chunk-QOLIBVGS.js.map → chunk-3CIIB74Y.js.map} +0 -0
  245. /package/dist/{chunk-2OTBMU5Z.js.map → chunk-44LYXLW7.js.map} +0 -0
  246. /package/dist/{chunk-LYVTJLCF.js.map → chunk-56JF5PZK.js.map} +0 -0
  247. /package/dist/{chunk-5KGABAQB.js.map → chunk-5752357K.js.map} +0 -0
  248. /package/dist/{chunk-SPZAEMGW.js.map → chunk-5WX6U34F.js.map} +0 -0
  249. /package/dist/{chunk-QHXMNSOZ.js.map → chunk-6L6VXRLJ.js.map} +0 -0
  250. /package/dist/{chunk-VVFASSFY.js.map → chunk-6VGB4OX2.js.map} +0 -0
  251. /package/dist/{chunk-FRP7NM6X.js.map → chunk-6WZUKV55.js.map} +0 -0
  252. /package/dist/{chunk-QEINKMMX.js.map → chunk-7C763T3K.js.map} +0 -0
  253. /package/dist/{chunk-PARTZ7XI.js.map → chunk-7JKDB5J5.js.map} +0 -0
  254. /package/dist/{chunk-G5XHAN56.js.map → chunk-7WWPKA7Y.js.map} +0 -0
  255. /package/dist/{chunk-QYV7KLEN.js.map → chunk-ASGSC5UA.js.map} +0 -0
  256. /package/dist/{chunk-7GQ2ZZBQ.js.map → chunk-BCTRC6AR.js.map} +0 -0
  257. /package/dist/{chunk-XSHWEUDB.js.map → chunk-BE5Z36XZ.js.map} +0 -0
  258. /package/dist/{chunk-PM7SI4YT.js.map → chunk-BJOKL5PQ.js.map} +0 -0
  259. /package/dist/{chunk-PGPPN63I.js.map → chunk-EMEXXAQI.js.map} +0 -0
  260. /package/dist/{chunk-JUHNEYCH.js.map → chunk-GCH7CLM4.js.map} +0 -0
  261. /package/dist/{chunk-R6SBP5M5.js.map → chunk-GOWBYHYW.js.map} +0 -0
  262. /package/dist/{chunk-LZQQ4JXY.js.map → chunk-HGVPPJKE.js.map} +0 -0
  263. /package/dist/{chunk-HCEJT65A.js.map → chunk-HKD4TDZP.js.map} +0 -0
  264. /package/dist/{chunk-XNBX3M35.js.map → chunk-HLCEKWFS.js.map} +0 -0
  265. /package/dist/{chunk-4MGFUPQT.js.map → chunk-HOJL2GKW.js.map} +0 -0
  266. /package/dist/{chunk-V5ZLUJV7.js.map → chunk-HRMB72E4.js.map} +0 -0
  267. /package/dist/{chunk-3GVMUASU.js.map → chunk-HV7HIMMY.js.map} +0 -0
  268. /package/dist/{chunk-CSDVRHUX.js.map → chunk-HWBKMUMV.js.map} +0 -0
  269. /package/dist/{chunk-KN3WYEH2.js.map → chunk-IA6F7DU6.js.map} +0 -0
  270. /package/dist/{chunk-BE5FGUJS.js.map → chunk-IM5SR7G2.js.map} +0 -0
  271. /package/dist/{chunk-PJVDIUT2.js.map → chunk-IRNKHHQM.js.map} +0 -0
  272. /package/dist/{chunk-4XET5MWR.js.map → chunk-KKE4SHRS.js.map} +0 -0
  273. /package/dist/{chunk-ZTTFLIPH.js.map → chunk-L624DFJV.js.map} +0 -0
  274. /package/dist/{chunk-OYT7YXQL.js.map → chunk-MGPN5TZE.js.map} +0 -0
  275. /package/dist/{chunk-ERY6D2OV.js.map → chunk-MWPXKZ7O.js.map} +0 -0
  276. /package/dist/{chunk-SCCE6VWY.js.map → chunk-N2Z7NHD5.js.map} +0 -0
  277. /package/dist/{chunk-GNHXFJRR.js.map → chunk-N6EEY7V3.js.map} +0 -0
  278. /package/dist/{chunk-4WCDMCIS.js.map → chunk-PI3GPLE2.js.map} +0 -0
  279. /package/dist/{chunk-XAUKQZJK.js.map → chunk-QX4LMVL2.js.map} +0 -0
  280. /package/dist/{chunk-6PYX6V3R.js.map → chunk-RJXVVLBO.js.map} +0 -0
  281. /package/dist/{chunk-FRCBJLV5.js.map → chunk-RKKYSSAV.js.map} +0 -0
  282. /package/dist/{chunk-WF7BZT6V.js.map → chunk-RR6BIHFX.js.map} +0 -0
  283. /package/dist/{chunk-NGAU6PNB.js.map → chunk-RRVQVQF7.js.map} +0 -0
  284. /package/dist/{chunk-FWPFCK4D.js.map → chunk-S6G3CJFP.js.map} +0 -0
  285. /package/dist/{chunk-F33YKDO2.js.map → chunk-TEST2NBS.js.map} +0 -0
  286. /package/dist/{chunk-BJZOBG24.js.map → chunk-UJHXEOU3.js.map} +0 -0
  287. /package/dist/{chunk-NKJSYZEU.js.map → chunk-V32626FV.js.map} +0 -0
  288. /package/dist/{chunk-MLDA44NW.js.map → chunk-VGXSPUTD.js.map} +0 -0
  289. /package/dist/{chunk-U4QUDFPJ.js.map → chunk-VKVOP4OK.js.map} +0 -0
  290. /package/dist/{chunk-CTXF22BU.js.map → chunk-VODKYDC4.js.map} +0 -0
  291. /package/dist/{chunk-DWJH3KXN.js.map → chunk-WAKGVAOB.js.map} +0 -0
  292. /package/dist/{chunk-SZA44EFA.js.map → chunk-WOEVBEGJ.js.map} +0 -0
  293. /package/dist/{chunk-EOTV5BLM.js.map → chunk-WOP2DRMC.js.map} +0 -0
  294. /package/dist/{chunk-E6JRPGMN.js.map → chunk-X3DVZNZH.js.map} +0 -0
  295. /package/dist/{chunk-P35CTP6L.js.map → chunk-Y3WB66XT.js.map} +0 -0
  296. /package/dist/{chunk-TNQDSTIA.js.map → chunk-Y6C4MYZE.js.map} +0 -0
  297. /package/dist/{chunk-TBZKUZNW.js.map → chunk-ZPWU7Z6O.js.map} +0 -0
  298. /package/dist/{chunk-QQSRZUT4.js.map → chunk-ZXEDKRRT.js.map} +0 -0
@@ -28,6 +28,8 @@ interface HeaderProps {
28
28
  trailing?: React.ReactNode;
29
29
  /** Renders the title as a `<label>` for this control instead of a heading. */
30
30
  labelFor?: string;
31
+ /** Beside the title, after the status pill — the [i] while the summary is cut. */
32
+ info?: React.ReactNode;
31
33
  dataTestId?: string;
32
34
  }
33
35
 
@@ -46,6 +48,7 @@ export const SettingHeader: React.FC<HeaderProps> = ({
46
48
  status,
47
49
  trailing,
48
50
  labelFor,
51
+ info,
49
52
  dataTestId,
50
53
  }) => {
51
54
  const theme = useTheme();
@@ -75,6 +78,7 @@ export const SettingHeader: React.FC<HeaderProps> = ({
75
78
  dataTestId={partTestId(dataTestId, 'status')}
76
79
  />
77
80
  )}
81
+ {info}
78
82
  </Box>
79
83
  {trailing}
80
84
  </Box>
@@ -78,17 +78,29 @@ export const titleStyles = (theme: Theme): CSSObject => ({
78
78
  overflowWrap: 'anywhere',
79
79
  });
80
80
 
81
- /** The one line a closed card shows. Long values end in an ellipsis, not a second line. */
81
+ /** The most lines a card's summary shows before the rest goes behind the [i]. */
82
+ export const SUMMARY_MAX_LINES = 2;
83
+
84
+ /**
85
+ * Two lines at most, cut with an ellipsis. Visual only: the whole sentence stays
86
+ * in the DOM, so a switch that is `aria-describedby` it still reads all of it.
87
+ */
88
+ export const clampStyles: CSSObject = {
89
+ display: '-webkit-box',
90
+ WebkitLineClamp: SUMMARY_MAX_LINES,
91
+ WebkitBoxOrient: 'vertical',
92
+ overflow: 'hidden',
93
+ };
94
+
95
+ /** A closed card's value: two lines at most, the rest behind the [i]. */
82
96
  export const summaryStyles = (theme: Theme): CSSObject => ({
83
97
  ...theme.typography.body2,
84
98
  color: theme.palette.text.secondary,
85
99
  margin: 0,
86
- overflow: 'hidden',
87
- textOverflow: 'ellipsis',
88
- whiteSpace: 'nowrap',
100
+ ...clampStyles,
89
101
  });
90
102
 
91
- /** A switch card's explanation, which may wrap: it is read, not scanned. */
103
+ /** A switch card's explanation; `SettingSwitchBlock` clamps it (see `clampStyles`). */
92
104
  export const descriptionStyles = (theme: Theme): CSSObject => ({
93
105
  ...theme.typography.body2,
94
106
  color: theme.palette.text.secondary,
@@ -0,0 +1,100 @@
1
+ import Box from '@mui/material/Box/index.js';
2
+ import { useTheme } from '@mui/material/styles/index.js';
3
+ import React, { useCallback, useLayoutEffect, useState } from 'react';
4
+
5
+ import { Icon } from '../../../icons';
6
+ import { rem } from '../../../tokens/relative';
7
+ import { InteractiveTooltip } from '../../data-display/InteractiveTooltip';
8
+
9
+ import { SETTING_CARD } from './SettingCard.metrics';
10
+ import { partTestId } from './SettingCard.parts';
11
+
12
+ /**
13
+ * Whether a clamped element is hiding text — measured, never guessed from the
14
+ * string's length, because what fits depends on the width the card is GIVEN.
15
+ * Re-measured whenever the element resizes, so a card that widens drops its [i].
16
+ */
17
+ export const useClamped = (content?: unknown): { ref: (node: HTMLElement | null) => void; clamped: boolean } => {
18
+ const [node, setNode] = useState<HTMLElement | null>(null);
19
+ const [clamped, setClamped] = useState(false);
20
+ const ref = useCallback((next: HTMLElement | null) => setNode(next), []);
21
+
22
+ useLayoutEffect(() => {
23
+ if (!node) return undefined;
24
+ const measure = (): void => setClamped(node.scrollHeight > node.clientHeight + 1);
25
+ measure();
26
+ if (typeof ResizeObserver === 'undefined') return undefined;
27
+ const observer = new ResizeObserver(measure);
28
+ observer.observe(node);
29
+ return () => observer.disconnect();
30
+ // `content` too: a summary that grows from two lines to three inside the
31
+ // same clamped height fires no resize, so the text changing re-measures.
32
+ }, [node, content]);
33
+
34
+ return { ref, clamped };
35
+ };
36
+
37
+ /**
38
+ * The [i] beside a card's title while its summary is cut: hover shows the whole
39
+ * text, a click or tap pins it — so it works on a phone, where there is no hover.
40
+ */
41
+ export const SummaryInfo: React.FC<{ label: string; summary: React.ReactNode; dataTestId?: string }> = ({
42
+ label,
43
+ summary,
44
+ dataTestId,
45
+ }) => {
46
+ const theme = useTheme();
47
+ return (
48
+ <InteractiveTooltip
49
+ variant="light"
50
+ size="sm"
51
+ maxWidth={SETTING_CARD.infoMaxWidth}
52
+ hoverContent={summary}
53
+ pinnedContent={summary}
54
+ dataTestId={partTestId(dataTestId, 'info')}
55
+ >
56
+ <Box
57
+ component="button"
58
+ type="button"
59
+ aria-label={label}
60
+ sx={{
61
+ display: 'inline-flex',
62
+ alignItems: 'center',
63
+ justifyContent: 'center',
64
+ padding: 0,
65
+ border: 0,
66
+ background: 'none',
67
+ color: theme.palette.text.secondary,
68
+ cursor: 'pointer',
69
+ borderRadius: '50%',
70
+ '&:focus-visible': {
71
+ outline: `${rem(theme, SETTING_CARD.infoFocusRingWidth)} solid ${theme.palette.primary.main}`,
72
+ outlineOffset: rem(theme, SETTING_CARD.infoFocusRingOffset),
73
+ },
74
+ }}
75
+ >
76
+ <Icon name="InfoOutlined" size="xs" />
77
+ </Box>
78
+ </InteractiveTooltip>
79
+ );
80
+ };
81
+
82
+ /**
83
+ * The summary's measuring ref, and the [i] for the header while it is cut —
84
+ * `null` when there is no summary, it fits, or `show` is false (an open card).
85
+ */
86
+ export const useSummaryInfo = ({
87
+ summary,
88
+ show = true,
89
+ label,
90
+ dataTestId,
91
+ }: {
92
+ summary: React.ReactNode;
93
+ show?: boolean;
94
+ label: string;
95
+ dataTestId?: string;
96
+ }): { ref: (node: HTMLElement | null) => void; info: React.ReactNode } => {
97
+ const { ref, clamped } = useClamped(summary);
98
+ const visible = show && clamped && summary != null;
99
+ return { ref, info: visible ? <SummaryInfo label={label} summary={summary} dataTestId={dataTestId} /> : null };
100
+ };
@@ -7,6 +7,7 @@ import { Button } from '../../form/Button';
7
7
  import { useSettingCard } from './SettingCard.hooks';
8
8
  import { LearnMore, PendingSpinner, SaveError, SettingHeader, partTestId } from './SettingCard.parts';
9
9
  import { SETTING_CARD_OPEN_ATTR, actionsStyles, summaryStyles, surfaceStyles, withCallerSx } from './SettingCard.styles';
10
+ import { useSummaryInfo } from './SettingCard.summary';
10
11
  import type { SettingCardCopy, SettingCardProps } from './SettingCard.types';
11
12
 
12
13
  interface OpenBodyProps {
@@ -82,7 +83,8 @@ const OpenBody: React.FC<OpenBodyProps> = ({
82
83
  /**
83
84
  * A setting, summarised while closed and edited in place.
84
85
  *
85
- * Closed: title, status pill, a one-line summary and Edit. Edit opens the card
86
+ * Closed: title, status pill, a summary of at most two lines (an [i] beside the
87
+ * title holds the rest) and Edit. Edit opens the card
86
88
  * where it is — no dialog, no route — around the host's form, a "learn more"
87
89
  * disclosure and Cancel / Save. Save may be async: the card holds its saving
88
90
  * state while the promise is pending, closes when it resolves, and stays open
@@ -134,6 +136,7 @@ export const SettingCard = forwardRef<HTMLElement, SettingCardProps>(function Se
134
136
  const titleId = `${baseId}-title`;
135
137
  const card = useSettingCard(props);
136
138
  const { open } = card;
139
+ const clamp = useSummaryInfo({ summary, show: !open, label: copy.moreInfo ?? title, dataTestId });
137
140
 
138
141
  return (
139
142
  <Box
@@ -153,6 +156,7 @@ export const SettingCard = forwardRef<HTMLElement, SettingCardProps>(function Se
153
156
  headingLevel={headingLevel}
154
157
  icon={icon}
155
158
  status={status}
159
+ info={clamp.info}
156
160
  trailing={
157
161
  open ? null : (
158
162
  <EditTrigger
@@ -169,7 +173,7 @@ export const SettingCard = forwardRef<HTMLElement, SettingCardProps>(function Se
169
173
  dataTestId={dataTestId}
170
174
  />
171
175
  {!open && summary != null && (
172
- <Box component="p" sx={summaryStyles} data-testid={partTestId(dataTestId, 'summary')}>
176
+ <Box component="p" ref={clamp.ref} sx={summaryStyles} data-testid={partTestId(dataTestId, 'summary')}>
173
177
  {summary}
174
178
  </Box>
175
179
  )}
@@ -7,7 +7,8 @@ import { SR_ONLY_SX } from '../../form/Label/Label.styles';
7
7
 
8
8
  import { useAsyncSwitch } from './SettingCard.hooks';
9
9
  import { PendingSpinner, SaveError, SettingHeader, partTestId } from './SettingCard.parts';
10
- import { descriptionStyles } from './SettingCard.styles';
10
+ import { clampStyles, descriptionStyles } from './SettingCard.styles';
11
+ import { useSummaryInfo } from './SettingCard.summary';
11
12
  import type { SettingToggleProps } from './SettingCard.types';
12
13
 
13
14
  /** Everything the switch-driven cards share, minus the surface each draws around it. */
@@ -46,6 +47,7 @@ export const SettingSwitchBlock: React.FC<
46
47
  SettingSwitchBlockProps & { ids: SettingSwitchIds; state: ReturnType<typeof useAsyncSwitch> }
47
48
  > = ({ title, headingLevel = 'h3', icon, summary, copy, disabled, dataTestId, ids, state }) => {
48
49
  const theme = useTheme();
50
+ const clamp = useSummaryInfo({ summary, label: copy.moreInfo ?? title, dataTestId });
49
51
  const { shown, saving, error, flip } = state;
50
52
  const describedBy = [summary != null ? ids.summaryId : null, error ? ids.errorId : null]
51
53
  .filter(Boolean)
@@ -76,10 +78,17 @@ export const SettingSwitchBlock: React.FC<
76
78
  icon={icon}
77
79
  labelFor={ids.inputId}
78
80
  trailing={control}
81
+ info={clamp.info}
79
82
  dataTestId={dataTestId}
80
83
  />
81
84
  {summary != null && (
82
- <Box component="p" id={ids.summaryId} sx={descriptionStyles(theme)} data-testid={partTestId(dataTestId, 'summary')}>
85
+ <Box
86
+ component="p"
87
+ ref={clamp.ref}
88
+ id={ids.summaryId}
89
+ sx={{ ...descriptionStyles(theme), ...clampStyles }}
90
+ data-testid={partTestId(dataTestId, 'summary')}
91
+ >
83
92
  {summary}
84
93
  </Box>
85
94
  )}
@@ -28,7 +28,7 @@ import { SettingToggle } from '@12-apps/ui/layout/SettingCard';
28
28
  | `title` | `string` | **required** | The switch's `<label>` — its accessible name, and a tap target far larger than the track. |
29
29
  | `checked` | `boolean` | **required** | The persisted value. |
30
30
  | `onChange` | `(checked: boolean) => void \| Promise<unknown>` | **required** | Persist a flip. See below. |
31
- | `summary` | `ReactNode` | — | Explanation under the title; the switch is `aria-describedby` it. |
31
+ | `summary` | `ReactNode` | — | Explanation under the title; the switch is `aria-describedby` it. Two lines at most — while it is cut, an [i] beside the title shows the rest. The whole text stays in the DOM, so the description a screen reader hears is complete. |
32
32
  | `variant` | `'card' \| 'row'` | `'card'` | `row` drops the surface — for a dependent row inside a [`SettingGroup`](./SettingGroup.md). |
33
33
  | `disabled` | `boolean` | `false` | Disables the switch. Also disabled inside a `SettingGroup` whose main switch is off. |
34
34
  | `formatError` | `(error: unknown) => string \| undefined` | — | The sentence for a rejected save; `undefined` falls back to `copy.saveFailed`. |
@@ -33,6 +33,12 @@ export interface SettingCardCopy {
33
33
  learnMore: string;
34
34
  /** Shown when the save rejected and the host's `formatError` gave no sentence of its own. */
35
35
  saveFailed: string;
36
+ /**
37
+ * The accessible name of the [i] beside the title while the summary is cut to
38
+ * two lines. Optional so a host's own copy object keeps compiling; without it
39
+ * the [i] is named after the card's title.
40
+ */
41
+ moreInfo?: string;
36
42
  }
37
43
 
38
44
  /**
@@ -44,4 +50,6 @@ export interface SettingSwitchCopy {
44
50
  saving: string;
45
51
  /** Shown when the save rejected and the host's `formatError` gave no sentence of its own. */
46
52
  saveFailed: string;
53
+ /** The [i]'s accessible name — see `SettingCardCopy.moreInfo`. */
54
+ moreInfo?: string;
47
55
  }
@@ -23,9 +23,11 @@ export const EN_US_SETTING_CARD_COPY: SettingCardCopy = {
23
23
  saving: "Saving…",
24
24
  learnMore: "Learn more",
25
25
  saveFailed: "Could not save. Please try again.",
26
+ moreInfo: "Show the full text",
26
27
  };
27
28
 
28
29
  export const EN_US_SETTING_SWITCH_COPY: SettingSwitchCopy = {
29
30
  saving: "Saving…",
30
31
  saveFailed: "Could not save. Please try again.",
32
+ moreInfo: "Show the full text",
31
33
  };
@@ -23,9 +23,11 @@ export const PT_BR_SETTING_CARD_COPY: SettingCardCopy = {
23
23
  saving: "Salvando…",
24
24
  learnMore: "Saiba mais",
25
25
  saveFailed: "Não foi possível salvar. Tente novamente.",
26
+ moreInfo: "Ver o texto inteiro",
26
27
  };
27
28
 
28
29
  export const PT_BR_SETTING_SWITCH_COPY: SettingSwitchCopy = {
29
30
  saving: "Salvando…",
30
31
  saveFailed: "Não foi possível salvar. Tente novamente.",
32
+ moreInfo: "Ver o texto inteiro",
31
33
  };
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/layout/SettingCard/SettingCard.styles.ts"],"sourcesContent":["import type { CSSObject, SxProps, Theme } from '@mui/material/styles/index.js';\n\nimport { rem } from '../../../tokens/relative';\nimport { CARD_BORDER_WIDTH, CARD_RADIUS_UNITS } from '../Card/Card.metrics';\n\nimport { SETTING_CARD, SETTING_GROUP_INACTIVE_OPACITY } from './SettingCard.metrics';\n\n/**\n * The attribute an open `SettingCard` carries, which `SettingGrid` reads to\n * give it the whole row. An attribute rather than a class so a host's wrapper\n * around the card can be matched with `:has()` as well.\n */\nexport const SETTING_CARD_OPEN_ATTR = 'data-setting-card-open';\n\n/** `sx` as MUI documents it for composition: the component's own first, the caller's after. */\nexport const withCallerSx = (\n own: SxProps<Theme>,\n sx: SxProps<Theme> | undefined,\n): SxProps<Theme> => [own, ...(Array.isArray(sx) ? sx : [sx])] as SxProps<Theme>;\n\n/**\n * The card surface — `Card`'s outlined hairline and medium radius, so a\n * settings screen and a content screen are drawn with one kit.\n *\n * `height: 100%` is what turns the grid's per-row stretch into equal-height\n * cards: a grid item stretches, but a card that sized itself to its content\n * would not fill the item it sits in.\n *\n * `gridColumn: 1 / -1` while open is the full-row span. It lives on the card,\n * not only in the grid's CSS, so it also holds when the card sits in a host's\n * own grid. Outside a grid the property does nothing.\n */\nexport const surfaceStyles = (theme: Theme, open: boolean): CSSObject => ({\n boxSizing: 'border-box',\n height: '100%',\n minWidth: 0,\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(1.5),\n padding: theme.spacing(2.5),\n backgroundColor: theme.palette.background.paper,\n border: `${CARD_BORDER_WIDTH}px solid ${open ? theme.palette.primary.main : theme.palette.divider}`,\n borderRadius: theme.spacing(CARD_RADIUS_UNITS.lg),\n boxShadow: open ? theme.shadows[4] : 'none',\n transition: theme.transitions.create(['border-color', 'box-shadow'], {\n duration: theme.transitions.duration.short,\n }),\n ...(open ? { gridColumn: '1 / -1' } : {}),\n});\n\n/** A `row` toggle: the card's content with none of its surface. */\nexport const flatStyles = (theme: Theme): CSSObject => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(0.5),\n padding: theme.spacing(1.25, 0),\n minWidth: 0,\n});\n\nexport const headerStyles = (theme: Theme): CSSObject => ({\n display: 'flex',\n alignItems: 'center',\n gap: rem(theme, SETTING_CARD.iconGap),\n minWidth: 0,\n});\n\n/**\n * The title names its colour rather than inheriting it: a card rendered under\n * a theme other than the page's (a dark panel on a light page) would otherwise\n * take the page's text colour onto its own surface.\n */\nexport const titleStyles = (theme: Theme): CSSObject => ({\n ...theme.typography.subtitle1,\n fontWeight: theme.typography.fontWeightMedium,\n color: theme.palette.text.primary,\n margin: 0,\n minWidth: 0,\n overflowWrap: 'anywhere',\n});\n\n/** The one line a closed card shows. Long values end in an ellipsis, not a second line. */\nexport const summaryStyles = (theme: Theme): CSSObject => ({\n ...theme.typography.body2,\n color: theme.palette.text.secondary,\n margin: 0,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n});\n\n/** A switch card's explanation, which may wrap: it is read, not scanned. */\nexport const descriptionStyles = (theme: Theme): CSSObject => ({\n ...theme.typography.body2,\n color: theme.palette.text.secondary,\n margin: 0,\n});\n\n/** The inactive group's hint: a glyph and the sentence, so it does not read as a second summary. */\nexport const hintStyles = (theme: Theme): CSSObject => ({\n ...descriptionStyles(theme),\n display: 'flex',\n alignItems: 'flex-start',\n gap: theme.spacing(1),\n // Centre the 16px glyph on the first 20px line; later lines wrap under the text.\n '& > svg': { flexShrink: 0, marginTop: rem(theme, 2) },\n});\n\nexport const errorStyles = (theme: Theme): CSSObject => ({\n ...theme.typography.body2,\n color: theme.palette.error.main,\n margin: 0,\n});\n\nexport const actionsStyles = (theme: Theme): CSSObject => ({\n display: 'flex',\n flexWrap: 'wrap',\n justifyContent: 'flex-end',\n gap: theme.spacing(1),\n marginTop: 'auto',\n});\n\nexport const iconStyles = (theme: Theme): CSSObject => ({\n display: 'inline-flex',\n flexShrink: 0,\n color: theme.palette.text.secondary,\n});\n\n/**\n * A group's dependent rows: indented under the main switch, with a rule down\n * their left edge so the \"belongs to\" reads without words. While the main\n * switch is off they fade — and `inert` (set by the component) is what makes\n * them unreachable; opacity alone would only make them look it.\n */\nexport const dependentsStyles = (theme: Theme, active: boolean): CSSObject => ({\n display: 'flex',\n flexDirection: 'column',\n marginLeft: rem(theme, SETTING_CARD.groupIndent / 2),\n paddingLeft: rem(theme, SETTING_CARD.groupIndent / 2),\n borderLeft: `${rem(theme, SETTING_CARD.groupRuleWidth)} solid ${theme.palette.divider}`,\n opacity: active ? 1 : SETTING_GROUP_INACTIVE_OPACITY,\n transition: theme.transitions.create('opacity', { duration: theme.transitions.duration.short }),\n});\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/layout/SettingCard/SettingCard.parts.tsx"],"sourcesContent":["import Box from '@mui/material/Box/index.js';\nimport CircularProgress from '@mui/material/CircularProgress/index.js';\nimport { useTheme } from '@mui/material/styles/index.js';\nimport React, { useId, useState } from 'react';\n\nimport { Icon } from '../../../icons';\nimport { rem } from '../../../tokens/relative';\nimport { Chip } from '../../data-display/Chip';\nimport { Button } from '../../form/Button';\nimport { BUTTON_SIZES } from '../../form/Button/Button.metrics';\nimport { Collapsible } from '../Collapsible';\n\nimport { SETTING_CARD } from './SettingCard.metrics';\nimport { errorStyles, headerStyles, iconStyles, titleStyles } from './SettingCard.styles';\nimport type { SettingHeadingLevel, SettingStatus } from './SettingCard.types';\n\n/** `<root>-<part>` when the host gave a root test id, else nothing. */\nexport const partTestId = (root: string | undefined, part: string): string | undefined =>\n root ? `${root}-${part}` : undefined;\n\ninterface HeaderProps {\n titleId: string;\n title: string;\n headingLevel: SettingHeadingLevel;\n icon?: React.ReactNode;\n status?: SettingStatus;\n /** Rendered at the row's far end — the Edit trigger, or a switch. */\n trailing?: React.ReactNode;\n /** Renders the title as a `<label>` for this control instead of a heading. */\n labelFor?: string;\n dataTestId?: string;\n}\n\n/**\n * Icon, title, status pill, and whatever the row ends with.\n *\n * A switch card's title is the switch's `<label>`, so the words are both its\n * accessible name and a tap target far larger than the track. An editable\n * card's title is a heading, so the page outline lists every setting.\n */\nexport const SettingHeader: React.FC<HeaderProps> = ({\n titleId,\n title,\n headingLevel,\n icon,\n status,\n trailing,\n labelFor,\n dataTestId,\n}) => {\n const theme = useTheme();\n return (\n <Box sx={headerStyles(theme)}>\n {icon && (\n <Box component=\"span\" aria-hidden sx={iconStyles(theme)}>\n {icon}\n </Box>\n )}\n <Box sx={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: 1, minWidth: 0, flex: 1 }}>\n <Box\n component={labelFor ? 'label' : headingLevel}\n id={titleId}\n htmlFor={labelFor}\n sx={{ ...titleStyles(theme), ...(labelFor ? { cursor: 'pointer' } : {}) }}\n data-testid={partTestId(dataTestId, 'title')}\n >\n {title}\n </Box>\n {status && (\n <Chip\n label={status.label}\n color={status.color ?? 'neutral'}\n size=\"sm\"\n variant=\"outlined\"\n dataTestId={partTestId(dataTestId, 'status')}\n />\n )}\n </Box>\n {trailing}\n </Box>\n );\n};\n\n/**\n * The failure line. `role=\"alert\"` so it is announced the moment it appears,\n * without anyone having to move focus to find it.\n */\nexport const SaveError: React.FC<{ id: string; message: string | null; dataTestId?: string }> = ({\n id,\n message,\n dataTestId,\n}) => {\n const theme = useTheme();\n if (!message) return null;\n return (\n <Box component=\"p\" id={id} role=\"alert\" sx={errorStyles(theme)} data-testid={partTestId(dataTestId, 'error')}>\n {message}\n </Box>\n );\n};\n\n/** The spinner that rides beside a pending control; decorative — the words are announced separately. */\nexport const PendingSpinner: React.FC<{ dataTestId?: string }> = ({ dataTestId }) => {\n const theme = useTheme();\n return (\n <CircularProgress\n size={rem(theme, SETTING_CARD.spinnerSize)}\n color=\"inherit\"\n aria-hidden\n data-testid={partTestId(dataTestId, 'saving')}\n />\n );\n};\n\n/**\n * The \"learn more\" disclosure: a text button that owns `aria-expanded`, and\n * the collapsible region it controls. Closed by default — it is the longer\n * explanation, and the form is what the reader came for.\n */\nexport const LearnMore: React.FC<{\n label: string;\n children: React.ReactNode;\n dataTestId?: string;\n}> = ({ label, children, dataTestId }) => {\n const [expanded, setExpanded] = useState(false);\n const regionId = useId();\n const theme = useTheme();\n return (\n // Pulled out by the button's own padding, so the words line up with the form above.\n <Box sx={{ marginLeft: `-${rem(theme, BUTTON_SIZES.sm.paddingHorizontal)}` }}>\n <Button\n variant=\"text\"\n size=\"sm\"\n aria-expanded={expanded}\n aria-controls={regionId}\n onClick={() => setExpanded((was) => !was)}\n icon={\n <Box\n component=\"span\"\n sx={{\n display: 'inline-flex',\n transform: expanded ? 'rotate(180deg)' : 'none',\n transition: theme.transitions.create('transform'),\n }}\n >\n <Icon name=\"ExpandMore\" size=\"xs\" />\n </Box>\n }\n iconPosition=\"right\"\n dataTestId={partTestId(dataTestId, 'learn-more')}\n >\n {label}\n </Button>\n {/* Kept mounted so `aria-controls` always names an element that exists. */}\n <Collapsible open={expanded} keepMounted sx={{ marginLeft: rem(theme, BUTTON_SIZES.sm.paddingHorizontal) }} dataTestId={partTestId(dataTestId, 'learn-more-content')}>\n <Box id={regionId} sx={{ ...theme.typography.body2, color: 'text.secondary', pt: 1 }}>\n {children}\n </Box>\n </Collapsible>\n </Box>\n );\n};\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/layout/SettingCard/SettingSwitch.tsx"],"sourcesContent":["import Box from '@mui/material/Box/index.js';\nimport { useTheme } from '@mui/material/styles/index.js';\nimport React, { useId } from 'react';\n\nimport { Switch } from '../../form/Switch';\nimport { SR_ONLY_SX } from '../../form/Label/Label.styles';\n\nimport { useAsyncSwitch } from './SettingCard.hooks';\nimport { PendingSpinner, SaveError, SettingHeader, partTestId } from './SettingCard.parts';\nimport { descriptionStyles } from './SettingCard.styles';\nimport type { SettingToggleProps } from './SettingCard.types';\n\n/** Everything the switch-driven cards share, minus the surface each draws around it. */\nexport type SettingSwitchBlockProps = Pick<\n SettingToggleProps,\n 'title' | 'headingLevel' | 'icon' | 'summary' | 'checked' | 'onChange' | 'copy' | 'formatError' | 'dataTestId'\n> & { disabled: boolean };\n\n/** The ids one switch block wires its label, description and failure line with. */\nexport interface SettingSwitchIds {\n titleId: string;\n inputId: string;\n summaryId: string;\n errorId: string;\n}\n\nexport const useSettingSwitchIds = (): SettingSwitchIds => {\n const base = useId();\n return {\n titleId: `${base}-title`,\n inputId: `${base}-switch`,\n summaryId: `${base}-summary`,\n errorId: `${base}-error`,\n };\n};\n\n/**\n * Title-as-label, the switch, its explanation and the failure line.\n *\n * The switch is never `disabled` while it saves, for the reason Save is not\n * (`SettingCard.tsx`): a disabled control drops keyboard focus. It says\n * `aria-busy` instead, ignores flips until the save settles (see\n * `useAsyncSwitch`), shows a spinner, and a polite live region says the words.\n */\nexport const SettingSwitchBlock: React.FC<\n SettingSwitchBlockProps & { ids: SettingSwitchIds; state: ReturnType<typeof useAsyncSwitch> }\n> = ({ title, headingLevel = 'h3', icon, summary, copy, disabled, dataTestId, ids, state }) => {\n const theme = useTheme();\n const { shown, saving, error, flip } = state;\n const describedBy = [summary != null ? ids.summaryId : null, error ? ids.errorId : null]\n .filter(Boolean)\n .join(' ');\n\n const control = (\n <Box sx={{ display: 'inline-flex', alignItems: 'center', gap: 1, flexShrink: 0 }}>\n {saving && <PendingSpinner dataTestId={dataTestId} />}\n <Switch\n id={ids.inputId}\n checked={shown}\n onChange={(event) => void flip(event.target.checked)}\n disabled={disabled}\n error={Boolean(error)}\n aria-describedby={describedBy || undefined}\n inputProps={{ role: 'switch', 'aria-busy': saving }}\n dataTestId={partTestId(dataTestId, 'switch')}\n />\n </Box>\n );\n\n return (\n <>\n <SettingHeader\n titleId={ids.titleId}\n title={title}\n headingLevel={headingLevel}\n icon={icon}\n labelFor={ids.inputId}\n trailing={control}\n dataTestId={dataTestId}\n />\n {summary != null && (\n <Box component=\"p\" id={ids.summaryId} sx={descriptionStyles(theme)} data-testid={partTestId(dataTestId, 'summary')}>\n {summary}\n </Box>\n )}\n <SaveError id={ids.errorId} message={error} dataTestId={dataTestId} />\n <Box role=\"status\" aria-live=\"polite\" sx={SR_ONLY_SX}>\n {saving ? copy.saving : ''}\n </Box>\n </>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA,OAAO,SAAS;AAChB,SAAS,gBAAgB;AACzB,SAAgB,aAAa;AAoDzB,SAgBA,UAfa,KADb;AA5BG,IAAM,sBAAsB,MAAwB;AACzD,QAAM,OAAO,MAAM;AACnB,SAAO;AAAA,IACL,SAAS,GAAG,IAAI;AAAA,IAChB,SAAS,GAAG,IAAI;AAAA,IAChB,WAAW,GAAG,IAAI;AAAA,IAClB,SAAS,GAAG,IAAI;AAAA,EAClB;AACF;AAUO,IAAM,qBAET,CAAC,EAAE,OAAO,eAAe,MAAM,MAAM,SAAS,MAAM,UAAU,YAAY,KAAK,MAAM,MAAM;AAC7F,QAAM,QAAQ,SAAS;AACvB,QAAM,EAAE,OAAO,QAAQ,OAAO,KAAK,IAAI;AACvC,QAAM,cAAc,CAAC,WAAW,OAAO,IAAI,YAAY,MAAM,QAAQ,IAAI,UAAU,IAAI,EACpF,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,QAAM,UACJ,qBAAC,OAAI,IAAI,EAAE,SAAS,eAAe,YAAY,UAAU,KAAK,GAAG,YAAY,EAAE,GAC5E;AAAA,cAAU,oBAAC,kBAAe,YAAwB;AAAA,IACnD;AAAA,MAAC;AAAA;AAAA,QACC,IAAI,IAAI;AAAA,QACR,SAAS;AAAA,QACT,UAAU,CAAC,UAAU,KAAK,KAAK,MAAM,OAAO,OAAO;AAAA,QACnD;AAAA,QACA,OAAO,QAAQ,KAAK;AAAA,QACpB,oBAAkB,eAAe;AAAA,QACjC,YAAY,EAAE,MAAM,UAAU,aAAa,OAAO;AAAA,QAClD,YAAY,WAAW,YAAY,QAAQ;AAAA;AAAA,IAC7C;AAAA,KACF;AAGF,SACE,iCACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,SAAS,IAAI;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAU,IAAI;AAAA,QACd,UAAU;AAAA,QACV;AAAA;AAAA,IACF;AAAA,IACC,WAAW,QACV,oBAAC,OAAI,WAAU,KAAI,IAAI,IAAI,WAAW,IAAI,kBAAkB,KAAK,GAAG,eAAa,WAAW,YAAY,SAAS,GAC9G,mBACH;AAAA,IAEF,oBAAC,aAAU,IAAI,IAAI,SAAS,SAAS,OAAO,YAAwB;AAAA,IACpE,oBAAC,OAAI,MAAK,UAAS,aAAU,UAAS,IAAI,YACvC,mBAAS,KAAK,SAAS,IAC1B;AAAA,KACF;AAEJ;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/layout/SettingCard/SettingCard.metrics.ts"],"sourcesContent":["/**\n * The setting-card family's lengths, in design px. The web reads every one\n * through `rem(theme, n)`, so they scale with the host's type scale.\n */\nexport const SETTING_CARD = {\n /** Between the icon and the title. */\n iconGap: 12,\n /** The spinner beside a switch while its flip is saving. */\n spinnerSize: 16,\n /** How far a group's dependent rows sit in from its main switch. */\n groupIndent: 24,\n /** The rule down the left of a group's dependent rows. */\n groupRuleWidth: 2,\n /** The narrowest a grid column gets by default. */\n gridMinColumnWidth: 320,\n} as const;\n\n/** The grid's default gap, in theme SPACING units (not px): what `sx`'s `gap: 2` means. */\nexport const SETTING_GRID_GAP_UNITS = 2;\n\n/** How faded a group's dependent rows are while the main switch is off. */\nexport const SETTING_GROUP_INACTIVE_OPACITY = 0.5;\n"],"mappings":";AAIO,IAAM,eAAe;AAAA;AAAA,EAE1B,SAAS;AAAA;AAAA,EAET,aAAa;AAAA;AAAA,EAEb,aAAa;AAAA;AAAA,EAEb,gBAAgB;AAAA;AAAA,EAEhB,oBAAoB;AACtB;AAGO,IAAM,yBAAyB;AAG/B,IAAM,iCAAiC;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/data-display/InteractiveTooltip/InteractiveTooltip.tsx"],"sourcesContent":["import MuiTooltip from '@mui/material/Tooltip/index.js';\nimport { styled } from '@mui/material/styles/index.js';\nimport React from 'react';\n\nimport { resolveTooltipProps, usePinnedTooltip } from './InteractiveTooltip.hooks';\nimport {\n arrowColor,\n emphasisStyles,\n getSizeStyles,\n tooltipCap,\n variantStyles,\n} from './InteractiveTooltip.styles';\nimport type { InteractiveTooltipProps } from './InteractiveTooltip.types';\n\nconst StyledTooltip = styled(MuiTooltip, {\n shouldForwardProp: (prop) =>\n !['customVariant', 'customSize', 'glow', 'pulse'].includes(prop as string),\n})<{\n customVariant?: string;\n customSize?: string;\n glow?: boolean;\n pulse?: boolean;\n}>(({ theme, customVariant, customSize, glow, pulse }) => {\n const sizeStyles = getSizeStyles(customSize);\n\n return {\n '& .MuiTooltip-tooltip': {\n borderRadius: theme.spacing(1),\n fontSize: sizeStyles.fontSize(theme),\n padding: sizeStyles.padding(theme),\n fontWeight: 500,\n transition: 'all 0.3s ease',\n position: 'relative',\n overflow: 'hidden',\n ...variantStyles(theme, customVariant),\n ...emphasisStyles(theme, glow, pulse),\n },\n\n '& .MuiTooltip-arrow': {\n color: arrowColor(theme, customVariant),\n },\n };\n});\n\nexport const InteractiveTooltip = React.forwardRef<HTMLDivElement, InteractiveTooltipProps>(\n (rawProps, ref) => {\n const {\n variant,\n size,\n glow,\n pulse,\n maxWidth,\n dataTestId,\n hoverContent,\n pinnedContent,\n clickable,\n onPin,\n onUnpin,\n className,\n children,\n ...props\n } = resolveTooltipProps(rawProps);\n\n const { isPinned, isControlledOpen, wrapperRef, handleClick } = usePinnedTooltip({\n clickable,\n onPin,\n onUnpin,\n });\n\n // Determine which content to show\n const tooltipContent = isPinned ? pinnedContent : hoverContent;\n\n // Child with click handler and ref\n const childElement = children as React.ReactElement<{\n onClick?: (e: React.MouseEvent) => void;\n 'data-testid'?: string;\n }>;\n\n const childWithProps = React.cloneElement(childElement, {\n onClick: (e: React.MouseEvent) => {\n handleClick(e);\n // Call original onClick if it exists\n childElement.props.onClick?.(e);\n },\n 'data-testid': dataTestId ? `${dataTestId}-trigger` : undefined,\n });\n\n return (\n <div ref={wrapperRef} className={className}>\n <StyledTooltip\n ref={ref}\n customVariant={variant}\n customSize={size}\n glow={glow}\n pulse={pulse}\n title={tooltipContent}\n open={isPinned ? isControlledOpen : undefined}\n enterDelay={isPinned ? 0 : 100}\n leaveDelay={0}\n disableHoverListener={isPinned}\n disableFocusListener={isPinned}\n disableTouchListener={isPinned}\n slotProps={{\n tooltip: {\n sx: { maxWidth: tooltipCap(maxWidth) },\n role: 'tooltip',\n ...(dataTestId && { 'data-testid': `${dataTestId}-content` }),\n },\n }}\n {...props}\n >\n {childWithProps}\n </StyledTooltip>\n </div>\n );\n },\n);\n\nInteractiveTooltip.displayName = 'InteractiveTooltip';\n"],"mappings":";;;;;;;;;;;;;AAAA,OAAO,gBAAgB;AACvB,SAAS,cAAc;AACvB,OAAO,WAAW;AAuFV;AA3ER,IAAM,gBAAgB,OAAO,YAAY;AAAA,EACvC,mBAAmB,CAAC,SAClB,CAAC,CAAC,iBAAiB,cAAc,QAAQ,OAAO,EAAE,SAAS,IAAc;AAC7E,CAAC,EAKE,CAAC,EAAE,OAAO,eAAe,YAAY,MAAM,MAAM,MAAM;AACxD,QAAM,aAAa,cAAc,UAAU;AAE3C,SAAO;AAAA,IACL,yBAAyB;AAAA,MACvB,cAAc,MAAM,QAAQ,CAAC;AAAA,MAC7B,UAAU,WAAW,SAAS,KAAK;AAAA,MACnC,SAAS,WAAW,QAAQ,KAAK;AAAA,MACjC,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,UAAU;AAAA,MACV,GAAG,cAAc,OAAO,aAAa;AAAA,MACrC,GAAG,eAAe,OAAO,MAAM,KAAK;AAAA,IACtC;AAAA,IAEA,uBAAuB;AAAA,MACrB,OAAO,WAAW,OAAO,aAAa;AAAA,IACxC;AAAA,EACF;AACF,CAAC;AAEM,IAAM,qBAAqB,MAAM;AAAA,EACtC,CAAC,UAAU,QAAQ;AACjB,UAAM;AAAA,MACJ;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,GAAG;AAAA,IACL,IAAI,oBAAoB,QAAQ;AAEhC,UAAM,EAAE,UAAU,kBAAkB,YAAY,YAAY,IAAI,iBAAiB;AAAA,MAC/E;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAGD,UAAM,iBAAiB,WAAW,gBAAgB;AAGlD,UAAM,eAAe;AAKrB,UAAM,iBAAiB,MAAM,aAAa,cAAc;AAAA,MACtD,SAAS,CAAC,MAAwB;AAChC,oBAAY,CAAC;AAEb,qBAAa,MAAM,UAAU,CAAC;AAAA,MAChC;AAAA,MACA,eAAe,aAAa,GAAG,UAAU,aAAa;AAAA,IACxD,CAAC;AAED,WACE,oBAAC,SAAI,KAAK,YAAY,WACpB;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,eAAe;AAAA,QACf,YAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,MAAM,WAAW,mBAAmB;AAAA,QACpC,YAAY,WAAW,IAAI;AAAA,QAC3B,YAAY;AAAA,QACZ,sBAAsB;AAAA,QACtB,sBAAsB;AAAA,QACtB,sBAAsB;AAAA,QACtB,WAAW;AAAA,UACT,SAAS;AAAA,YACP,IAAI,EAAE,UAAU,WAAW,QAAQ,EAAE;AAAA,YACrC,MAAM;AAAA,YACN,GAAI,cAAc,EAAE,eAAe,GAAG,UAAU,WAAW;AAAA,UAC7D;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEH;AAAA;AAAA,IACH,GACF;AAAA,EAEJ;AACF;AAEA,mBAAmB,cAAc;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/layout/SettingCard/SettingCard.tsx"],"sourcesContent":["import Box from '@mui/material/Box/index.js';\nimport React, { forwardRef, useId } from 'react';\n\nimport { Icon } from '../../../icons';\nimport { Button } from '../../form/Button';\n\nimport { useSettingCard } from './SettingCard.hooks';\nimport { LearnMore, PendingSpinner, SaveError, SettingHeader, partTestId } from './SettingCard.parts';\nimport { SETTING_CARD_OPEN_ATTR, actionsStyles, summaryStyles, surfaceStyles, withCallerSx } from './SettingCard.styles';\nimport type { SettingCardCopy, SettingCardProps } from './SettingCard.types';\n\ninterface OpenBodyProps {\n bodyRef: React.RefObject<HTMLDivElement | null>;\n titleId: string;\n errorId: string;\n copy: SettingCardCopy;\n learnMore?: React.ReactNode;\n children: React.ReactNode;\n saving: boolean;\n error: string | null;\n saveDisabled: boolean;\n onSave: () => void;\n onCancel: () => void;\n dataTestId?: string;\n}\n\n/**\n * The open card: the host's form, the disclosure, the failure line, and the\n * two actions.\n *\n * Save is NOT `disabled` while it saves — it is `aria-disabled` and ignores\n * the click. A disabled button drops the focus it holds, so a keyboard user\n * who pressed Save would land on `<body>` and, if the save then failed, have\n * to find their way back to the form from the top of the page.\n */\nconst OpenBody: React.FC<OpenBodyProps> = ({\n bodyRef, titleId, errorId, copy, learnMore, children, saving, error, saveDisabled, onSave, onCancel, dataTestId,\n}) => {\n const onKeyDown = (event: React.KeyboardEvent) => {\n if (event.key !== 'Escape') return;\n event.stopPropagation();\n onCancel();\n };\n\n return (\n <Box\n ref={bodyRef}\n role=\"group\"\n aria-labelledby={titleId}\n onKeyDown={onKeyDown}\n sx={{ display: 'flex', flexDirection: 'column', gap: 2, flex: 1 }}\n data-testid={partTestId(dataTestId, 'body')}\n >\n <Box>{children}</Box>\n {learnMore && (\n <LearnMore label={copy.learnMore} dataTestId={dataTestId}>\n {learnMore}\n </LearnMore>\n )}\n <SaveError id={errorId} message={error} dataTestId={dataTestId} />\n <Box sx={(theme) => actionsStyles(theme)}>\n <Button variant=\"ghost\" color=\"neutral\" onClick={onCancel} disabled={saving} dataTestId={partTestId(dataTestId, 'cancel')}>\n {copy.cancel}\n </Button>\n <Button\n variant=\"solid\"\n onClick={onSave}\n disabled={saveDisabled}\n aria-disabled={saving || undefined}\n aria-describedby={error ? errorId : undefined}\n icon={saving ? <PendingSpinner dataTestId={dataTestId} /> : undefined}\n iconPosition=\"left\"\n dataTestId={partTestId(dataTestId, 'save')}\n >\n {saving ? copy.saving : copy.save}\n </Button>\n </Box>\n </Box>\n );\n};\n\n/**\n * A setting, summarised while closed and edited in place.\n *\n * Closed: title, status pill, a one-line summary and Edit. Edit opens the card\n * where it is — no dialog, no route — around the host's form, a \"learn more\"\n * disclosure and Cancel / Save. Save may be async: the card holds its saving\n * state while the promise is pending, closes when it resolves, and stays open\n * with the error when it rejects. Focus moves into the card as it opens and\n * back to Edit as it closes.\n */\ninterface EditTriggerProps {\n triggerRef: React.RefObject<HTMLButtonElement | null>;\n id: string;\n titleId: string;\n label: string;\n disabled: boolean;\n onOpen: () => void;\n dataTestId?: string;\n}\n\n/** Edit. Its accessible name is \"Edit\" AND the card's title, so a grid of them is not a list of \"Edit, Edit, Edit\". */\nconst EditTrigger: React.FC<EditTriggerProps> = ({ triggerRef, id, titleId, label, disabled, onOpen, dataTestId }) => (\n <Button\n ref={triggerRef}\n id={id}\n variant=\"outline\"\n color=\"neutral\"\n size=\"sm\"\n icon={<Icon name=\"Edit\" size=\"xs\" />}\n iconPosition=\"left\"\n disabled={disabled}\n aria-labelledby={`${id} ${titleId}`}\n onClick={onOpen}\n dataTestId={partTestId(dataTestId, 'edit')}\n >\n {label}\n </Button>\n);\n\n/**\n * A setting, summarised while closed and edited in place.\n *\n * Closed: title, status pill, a one-line summary and Edit. Edit opens the card\n * where it is — no dialog, no route — around the host's form, a \"learn more\"\n * disclosure and Cancel / Save. Save may be async: the card holds its saving\n * state while the promise is pending, closes when it resolves, and stays open\n * with the error when it rejects. Focus moves into the card as it opens and\n * back to Edit as it closes.\n */\nexport const SettingCard = forwardRef<HTMLElement, SettingCardProps>(function SettingCard(props, ref) {\n const { title, headingLevel = 'h3', icon, status, summary, children, learnMore, copy, dataTestId, className, sx } = props;\n const baseId = useId();\n const titleId = `${baseId}-title`;\n const card = useSettingCard(props);\n const { open } = card;\n\n return (\n <Box\n component=\"section\"\n ref={ref}\n aria-labelledby={titleId}\n aria-busy={card.saving || undefined}\n data-state={open ? 'open' : 'closed'}\n {...{ [SETTING_CARD_OPEN_ATTR]: open ? '' : undefined }}\n data-testid={dataTestId}\n className={className}\n sx={withCallerSx((theme) => surfaceStyles(theme, open), sx)}\n >\n <SettingHeader\n titleId={titleId}\n title={title}\n headingLevel={headingLevel}\n icon={icon}\n status={status}\n trailing={\n open ? null : (\n <EditTrigger\n triggerRef={card.editRef}\n id={`${baseId}-edit`}\n titleId={titleId}\n label={copy.edit}\n disabled={card.disabled}\n onOpen={card.openCard}\n dataTestId={dataTestId}\n />\n )\n }\n dataTestId={dataTestId}\n />\n {!open && summary != null && (\n <Box component=\"p\" sx={summaryStyles} data-testid={partTestId(dataTestId, 'summary')}>\n {summary}\n </Box>\n )}\n {open && (\n <OpenBody\n bodyRef={card.bodyRef}\n titleId={titleId}\n errorId={`${baseId}-error`}\n copy={copy}\n learnMore={learnMore}\n saving={card.saving}\n error={card.error}\n saveDisabled={card.saveDisabled}\n onSave={card.save}\n onCancel={card.cancel}\n dataTestId={dataTestId}\n >\n {children}\n </OpenBody>\n )}\n </Box>\n );\n});\n\nSettingCard.displayName = 'SettingCard';\n"],"mappings":"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","names":["SettingCard"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/data-display/AlertDialog/AlertDialog.tsx"],"sourcesContent":["import Close from '@mui/icons-material/Close';\nimport Error from '@mui/icons-material/Error';\nimport Info from '@mui/icons-material/Info';\nimport type { ButtonProps } from '@mui/material/Button/index.js';\nimport Button from '@mui/material/Button/index.js';\nimport CircularProgress from '@mui/material/CircularProgress/index.js';\nimport Dialog from '@mui/material/Dialog/index.js';\nimport DialogActions from '@mui/material/DialogActions/index.js';\nimport DialogContent from '@mui/material/DialogContent/index.js';\nimport DialogContentText from '@mui/material/DialogContentText/index.js';\nimport DialogTitle from '@mui/material/DialogTitle/index.js';\nimport IconButton from '@mui/material/IconButton/index.js';\nimport Typography from '@mui/material/Typography/index.js';\nimport { alpha, keyframes, styled, useTheme } from '@mui/material/styles/index.js';\nimport type { Theme } from '@mui/material/styles/index.js';\nimport React from 'react';\n\nimport { neutralTones } from '../../../tokens/ink';\n\nimport type { AlertDialogProps } from './AlertDialog.types';\nimport { rem, rems } from '../../../tokens/relative';\n\n// Define pulse animation\nconst pulseAnimation = (theme: Theme) => keyframes`\n 0% {\n box-shadow: 0 0 0 0 currentColor;\n opacity: 1;\n }\n 70% {\n box-shadow: 0 0 0 ${rem(theme, 15)} currentColor;\n opacity: 0;\n }\n 100% {\n box-shadow: 0 0 0 0 currentColor;\n opacity: 0;\n }\n`;\n\nconst StyledDialog = styled(Dialog, {\n shouldForwardProp: (prop) => \n !['customVariant', 'glow', 'pulse'].includes(prop as string),\n})<{ \n customVariant?: string; \n glow?: boolean; \n pulse?: boolean; \n}>(({ theme, customVariant, glow, pulse }) => ({\n '& .MuiDialog-paper': {\n borderRadius: theme.spacing(2),\n transition: 'all 0.3s ease',\n position: 'relative',\n overflow: 'hidden',\n\n // Variant styles\n ...(customVariant === 'default' && {\n backgroundColor: theme.palette.background.paper,\n border: `1px solid ${alpha(theme.palette.divider, 0.2)}`,\n }),\n\n // The error tint is LAYERED over the paper, not used as the background\n // itself: `alpha(error, 0.05)` alone leaves the panel 95% transparent, so\n // the page behind it showed straight through the question and its buttons.\n // A confirm nobody can read is the one dialog that must never be hard to\n // read. Same tint, opaque base.\n ...(customVariant === 'destructive' && {\n backgroundColor: theme.palette.background.paper,\n backgroundImage: `linear-gradient(${alpha(theme.palette.error.main, 0.05)}, ${alpha(\n theme.palette.error.main,\n 0.05,\n )})`,\n border: `1px solid ${alpha(theme.palette.error.main, 0.2)}`,\n }),\n\n ...(customVariant === 'glass' && {\n backgroundColor: alpha(theme.palette.background.paper, 0.1),\n backdropFilter: `blur(${rem(theme, 20)})`,\n border: `1px solid ${alpha(theme.palette.divider, 0.2)}`,\n }),\n\n // Glow effect\n ...(glow && !pulse && {\n boxShadow: `0 0 ${rems(theme, 30, 10)} ${alpha(theme.palette.primary.main, 0.3)} !important`,\n filter: 'brightness(1.05)',\n }),\n\n // Pulse animation\n ...(pulse && !glow && {\n position: 'relative',\n '&::after': {\n content: '\"\"',\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n borderRadius: 'inherit',\n backgroundColor: theme.palette.primary.main,\n opacity: 0.1,\n animation: `${pulseAnimation(theme)} 2s infinite`,\n pointerEvents: 'none',\n zIndex: -1,\n },\n }),\n\n // Both glow and pulse\n ...(glow && pulse && {\n position: 'relative',\n boxShadow: `0 0 ${rems(theme, 30, 10)} ${alpha(theme.palette.primary.main, 0.3)} !important`,\n filter: 'brightness(1.05)',\n '&::after': {\n content: '\"\"',\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n borderRadius: 'inherit',\n backgroundColor: theme.palette.primary.main,\n opacity: 0.1,\n animation: `${pulseAnimation(theme)} 2s infinite`,\n pointerEvents: 'none',\n zIndex: -1,\n },\n }),\n },\n}));\n\nconst StyledDialogTitle = styled(DialogTitle)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1.5),\n paddingRight: theme.spacing(6), // Space for close button\n '& .MuiTypography-root': {\n fontWeight: 600,\n fontSize: rem(theme, 20),\n },\n}));\n\nconst StyledDialogContent = styled(DialogContent)(({ theme }) => ({\n paddingTop: theme.spacing(1),\n paddingBottom: theme.spacing(2),\n}));\n\nconst StyledDialogActions = styled(DialogActions)(({ theme }) => ({\n padding: theme.spacing(2, 3, 3, 3),\n gap: theme.spacing(1),\n}));\n\nconst CloseButton = styled(IconButton)(({ theme }) => ({\n position: 'absolute',\n right: theme.spacing(1),\n top: theme.spacing(1),\n color: neutralTones(theme).muted,\n}));\n\n/**\n * Per-variant lookups, hoisted out of the render function. They depend on\n * nothing but their arguments, so keeping them at module scope means they are\n * not rebuilt on every render — and it keeps the component's own branch count\n * inside the repo's complexity budget.\n */\nconst variantIcon = (\n variant: AlertDialogProps['variant'],\n icon: AlertDialogProps['icon'],\n): React.ReactNode => {\n if (icon) return icon;\n return variant === 'destructive' ? <Error color=\"error\" /> : <Info color=\"primary\" />;\n};\n\n/**\n * Ids for the two elements that give the dialog its accessible name and\n * description. Derived from the test id so they are stable and unique per\n * dialog without a generated id that would change on every render.\n */\nconst titleId = (dataTestId: string): string => `${dataTestId}-title`;\nconst descriptionId = (dataTestId: string): string => `${dataTestId}-description`;\n\n/**\n * `alertdialog`, not `dialog`.\n *\n * This component interrupts what the operator was doing and will not go away\n * until they answer — which is exactly the distinction the two roles draw, and\n * it is what makes a screen reader announce the message itself on open rather\n * than just the dialog's name. MUI hardcodes `role=\"dialog\"` on the paper, so\n * it has to be overridden through the paper slot.\n */\nconst ALERT_ROLE = 'alertdialog';\n\n/**\n * The paper slot's a11y props: the role, plus the name and description wired to\n * the elements that actually carry them, so the announcement is the QUESTION\n * rather than the word \"dialog\".\n *\n * Both references are conditional — pointing `aria-labelledby` at an element\n * that was never rendered leaves a dangling id, which screen readers treat as\n * no name at all, i.e. worse than omitting it.\n */\nfunction ariaSlotProps(\n dataTestId: string,\n title: AlertDialogProps['title'],\n description: AlertDialogProps['description'],\n): { paper: Record<string, string> } {\n return {\n paper: {\n role: ALERT_ROLE,\n ...(title ? { 'aria-labelledby': titleId(dataTestId) } : {}),\n ...(description ? { 'aria-describedby': descriptionId(dataTestId) } : {}),\n },\n };\n}\n\n/** Both variants render a filled confirm; only the colour distinguishes them. */\nconst CONFIRM_BUTTON_VARIANT: ButtonProps['variant'] = 'contained';\nconst confirmButtonColor = (variant: AlertDialogProps['variant']): 'error' | 'primary' =>\n variant === 'destructive' ? 'error' : 'primary';\n\n/** Title row: the variant icon (unless explicitly suppressed with `null`) + the title. */\nfunction AlertDialogHeader({\n title,\n icon,\n variant,\n dataTestId,\n}: {\n title: AlertDialogProps['title'];\n icon: AlertDialogProps['icon'];\n variant: AlertDialogProps['variant'];\n dataTestId: string;\n}): React.ReactElement | null {\n if (!title) return null;\n return (\n <StyledDialogTitle id={titleId(dataTestId)} data-testid={`${dataTestId}-title`}>\n {icon !== null && (\n <span data-testid={`${dataTestId}-icon`}>{variantIcon(variant, icon)}</span>\n )}\n <Typography variant=\"h6\" component=\"span\">\n {title}\n </Typography>\n </StyledDialogTitle>\n );\n}\n\n/** Action row: the optional cancel button and the (variant-coloured) confirm. */\nfunction AlertDialogFooter({\n variant,\n cancelText = 'Cancel',\n confirmText = 'Confirm',\n showCancel = true,\n loading = false,\n confirmDisabled = false,\n initialFocus = 'confirm',\n onCancel,\n onConfirm,\n dataTestId,\n}: Pick<\n AlertDialogProps,\n | 'variant'\n | 'cancelText'\n | 'confirmText'\n | 'showCancel'\n | 'loading'\n | 'confirmDisabled'\n | 'initialFocus'\n> & {\n onCancel: () => void;\n onConfirm: () => void;\n dataTestId: string;\n}): React.ReactElement {\n const theme = useTheme();\n return (\n <StyledDialogActions data-testid={`${dataTestId}-actions`}>\n {showCancel && (\n <Button\n onClick={onCancel}\n variant=\"outlined\"\n color=\"inherit\"\n disabled={loading}\n autoFocus={initialFocus === 'cancel'}\n data-testid={`${dataTestId}-cancel-button`}\n >\n {cancelText}\n </Button>\n )}\n <Button\n onClick={onConfirm}\n variant={CONFIRM_BUTTON_VARIANT}\n color={confirmButtonColor(variant)}\n disabled={confirmDisabled || loading}\n startIcon={\n loading ? (\n <CircularProgress\n size={rem(theme, 16)}\n color=\"inherit\"\n data-testid={`${dataTestId}-loading-spinner`}\n />\n ) : undefined\n }\n autoFocus={initialFocus !== 'cancel'}\n data-testid={`${dataTestId}-confirm-button`}\n >\n {confirmText}\n </Button>\n </StyledDialogActions>\n );\n}\n\nexport const AlertDialog = React.forwardRef<HTMLDivElement, AlertDialogProps>(\n ({\n variant = 'default',\n glow = false,\n pulse = false,\n title,\n description,\n icon,\n cancelText,\n confirmText,\n onCancel,\n onConfirm,\n showCancel,\n loading,\n confirmDisabled,\n initialFocus,\n children,\n onClose,\n 'data-testid': dataTestId = 'alert-dialog',\n ...props\n }, ref) => {\n const handleCancel = () => {\n onCancel?.();\n onClose?.({}, 'backdropClick');\n };\n\n return (\n <StyledDialog\n ref={ref}\n customVariant={variant}\n glow={glow}\n pulse={pulse}\n onClose={onClose}\n data-testid={dataTestId}\n slotProps={ariaSlotProps(dataTestId, title, description)}\n {...props}\n >\n <CloseButton\n aria-label=\"close\"\n onClick={handleCancel}\n size=\"small\"\n data-testid={`${dataTestId}-close-button`}\n >\n <Close />\n </CloseButton>\n\n <AlertDialogHeader\n title={title}\n icon={icon}\n variant={variant}\n dataTestId={dataTestId}\n />\n\n <StyledDialogContent data-testid={`${dataTestId}-content`}>\n {description && (\n <DialogContentText\n id={descriptionId(dataTestId)}\n data-testid={`${dataTestId}-description`}\n >\n {description}\n </DialogContentText>\n )}\n {children}\n </StyledDialogContent>\n\n <AlertDialogFooter\n variant={variant}\n cancelText={cancelText}\n confirmText={confirmText}\n showCancel={showCancel}\n loading={loading}\n confirmDisabled={confirmDisabled}\n initialFocus={initialFocus}\n onCancel={handleCancel}\n onConfirm={() => onConfirm?.()}\n dataTestId={dataTestId}\n />\n </StyledDialog>\n );\n }\n);\n\nAlertDialog.displayName = 'AlertDialog';"],"mappings":"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","names":[]}