@12-apps/ui 6.52.1 → 6.53.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 (260) hide show
  1. package/components-catalog.md +1 -1
  2. package/dist/_internal/components/data-display/Avatar/Avatar.js +3 -3
  3. package/dist/_internal/components/data-display/Avatar/Avatar.view.js +2 -2
  4. package/dist/_internal/components/data-display/CardKit/use-remove-confirm.js +1 -1
  5. package/dist/_internal/components/data-display/CardKit/use-row-confirm.js +1 -1
  6. package/dist/_internal/components/data-display/Chart/SpecChart.js +3 -3
  7. package/dist/_internal/components/data-display/Chart/chart-spec.js +2 -2
  8. package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +24 -24
  9. package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +26 -26
  10. package/dist/_internal/components/data-display/DataViews/ManageViewsDialog.js +1 -1
  11. package/dist/_internal/components/data-display/DataViews/base-list-card-geometry.js +4 -4
  12. package/dist/_internal/components/data-display/DataViews/base-list-card-slots.js +3 -3
  13. package/dist/_internal/components/data-display/DataViews/base-list-card.js +6 -6
  14. package/dist/_internal/components/data-display/DataViews/data-views-category-pill.js +6 -6
  15. package/dist/_internal/components/data-display/DataViews/data-views-display-panel.js +2 -2
  16. package/dist/_internal/components/data-display/DataViews/data-views-filter-panel.js +9 -9
  17. package/dist/_internal/components/data-display/DataViews/data-views-grid-bodies.js +3 -3
  18. package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +21 -21
  19. package/dist/_internal/components/data-display/DataViews/data-views-inline-bar.js +11 -11
  20. package/dist/_internal/components/data-display/DataViews/data-views-more-fields.js +9 -9
  21. package/dist/_internal/components/data-display/DataViews/data-views-more-filters.js +10 -10
  22. package/dist/_internal/components/data-display/DataViews/data-views-range-pill.js +2 -2
  23. package/dist/_internal/components/data-display/DataViews/data-views-shell-toolbar.js +6 -6
  24. package/dist/_internal/components/data-display/DataViews/data-views-table-parts.js +2 -2
  25. package/dist/_internal/components/data-display/DataViews/data-views-toolbar.js +5 -5
  26. package/dist/_internal/components/data-display/DataViews/list-card-rails.js +2 -2
  27. package/dist/_internal/components/data-display/DataViews/use-data-views-state.js +2 -2
  28. package/dist/_internal/components/data-display/FleetMap/FleetBody.js +4 -4
  29. package/dist/_internal/components/data-display/FleetMap/FleetCanvas.js +3 -3
  30. package/dist/_internal/components/data-display/FleetMap/FleetMap.fixtures.js +2 -2
  31. package/dist/_internal/components/data-display/FleetMap/FleetMap.js +5 -5
  32. package/dist/_internal/components/data-display/HoverCard/HoverCard.js +2 -2
  33. package/dist/_internal/components/data-display/InteractiveTooltip/InteractiveTooltip.hooks.js +3 -1
  34. package/dist/_internal/components/data-display/InteractiveTooltip/InteractiveTooltip.js +2 -2
  35. package/dist/_internal/components/data-display/Lightbox/Lightbox.js +3 -3
  36. package/dist/_internal/components/data-display/MapPreview/MapPreview.js +2 -2
  37. package/dist/_internal/components/data-display/Progress/Progress.js +2 -2
  38. package/dist/_internal/components/data-display/Sheet/Sheet.hooks.js +2 -2
  39. package/dist/_internal/components/data-display/Sheet/Sheet.js +4 -4
  40. package/dist/_internal/components/data-display/index.js +27 -27
  41. package/dist/_internal/components/feedback/index.js +3 -3
  42. package/dist/_internal/components/form/AddressAutocomplete/AddressAutocomplete.hooks.js +2 -2
  43. package/dist/_internal/components/form/AddressAutocomplete/AddressAutocomplete.js +5 -5
  44. package/dist/_internal/components/form/Autocomplete/Autocomplete.js +2 -2
  45. package/dist/_internal/components/form/Calendar/Calendar.hooks.js +2 -2
  46. package/dist/_internal/components/form/Calendar/Calendar.js +3 -3
  47. package/dist/_internal/components/form/CategorySelect/CategoryPanel.js +1 -1
  48. package/dist/_internal/components/form/CategorySelect/CategorySelect.js +4 -4
  49. package/dist/_internal/components/form/Command/Command.js +3 -3
  50. package/dist/_internal/components/form/DateRangePicker/DateRangePicker.js +5 -5
  51. package/dist/_internal/components/form/UploadButton/UploadButton.js +2 -2
  52. package/dist/_internal/components/form/index.js +22 -22
  53. package/dist/_internal/components/form/total-form/Fields/CategoryField.js +5 -5
  54. package/dist/_internal/components/form/total-form/Fields/index.js +9 -9
  55. package/dist/_internal/components/index.js +67 -66
  56. package/dist/_internal/components/layout/ScrollArea/ScrollArea.js +2 -2
  57. package/dist/_internal/components/layout/SettingCard/SettingCard.js +9 -4
  58. package/dist/_internal/components/layout/SettingCard/SettingCard.metrics.js +1 -1
  59. package/dist/_internal/components/layout/SettingCard/SettingCard.parts.js +3 -3
  60. package/dist/_internal/components/layout/SettingCard/SettingCard.styles.js +6 -2
  61. package/dist/_internal/components/layout/SettingCard/SettingCard.summary.js +63 -0
  62. package/dist/_internal/components/layout/SettingCard/SettingCard.summary.js.map +1 -0
  63. package/dist/_internal/components/layout/SettingCard/SettingGrid.js +4 -4
  64. package/dist/_internal/components/layout/SettingCard/SettingGroup.js +10 -5
  65. package/dist/_internal/components/layout/SettingCard/SettingSwitch.js +9 -4
  66. package/dist/_internal/components/layout/SettingCard/SettingToggle.js +10 -5
  67. package/dist/_internal/components/layout/index.js +18 -13
  68. package/dist/_internal/components/navigation/AppHeader/AppHeader.details.js +5 -5
  69. package/dist/_internal/components/navigation/index.js +5 -5
  70. package/dist/_internal/en-US.data-display.js +2 -2
  71. package/dist/_internal/en-US.layout.js +1 -1
  72. package/dist/_internal/pt-BR.data-display.js +2 -2
  73. package/dist/_internal/pt-BR.layout.js +1 -1
  74. package/dist/_internal/user-avatar/user-avatar.js +4 -4
  75. package/dist/charts.js +6 -6
  76. package/dist/{chunk-GXQDWHPN.js → chunk-2CJZLL5Y.js} +2 -2
  77. package/dist/{chunk-57VL5UX7.js → chunk-2JTZWQ25.js} +6 -4
  78. package/dist/chunk-2JTZWQ25.js.map +1 -0
  79. package/dist/{chunk-STTULW2K.js → chunk-2KVWOTEQ.js} +5 -5
  80. package/dist/{chunk-ISW5K72V.js → chunk-2ZRZTGWP.js} +5 -5
  81. package/dist/{chunk-33L26P4J.js → chunk-3ZKGNEP2.js} +5 -3
  82. package/dist/{chunk-33L26P4J.js.map → chunk-3ZKGNEP2.js.map} +1 -1
  83. package/dist/{chunk-2OTBMU5Z.js → chunk-44LYXLW7.js} +7 -7
  84. package/dist/{chunk-LYVTJLCF.js → chunk-56JF5PZK.js} +4 -4
  85. package/dist/{chunk-5KGABAQB.js → chunk-5752357K.js} +4 -4
  86. package/dist/{chunk-SPZAEMGW.js → chunk-5WX6U34F.js} +4 -4
  87. package/dist/{chunk-QHXMNSOZ.js → chunk-6L6VXRLJ.js} +2 -2
  88. package/dist/{chunk-VVFASSFY.js → chunk-6VGB4OX2.js} +3 -3
  89. package/dist/{chunk-FRP7NM6X.js → chunk-6WZUKV55.js} +2 -2
  90. package/dist/{chunk-QEINKMMX.js → chunk-7C763T3K.js} +2 -2
  91. package/dist/{chunk-PARTZ7XI.js → chunk-7JKDB5J5.js} +4 -4
  92. package/dist/{chunk-3U7WKBMH.js → chunk-AA2X5GOT.js} +5 -3
  93. package/dist/{chunk-3U7WKBMH.js.map → chunk-AA2X5GOT.js.map} +1 -1
  94. package/dist/{chunk-QYV7KLEN.js → chunk-ASGSC5UA.js} +5 -5
  95. package/dist/{chunk-7GQ2ZZBQ.js → chunk-BCTRC6AR.js} +2 -2
  96. package/dist/{chunk-XSHWEUDB.js → chunk-BE5Z36XZ.js} +4 -4
  97. package/dist/{chunk-IC7GHPMK.js → chunk-BFRVMCQM.js} +7 -2
  98. package/dist/chunk-BFRVMCQM.js.map +1 -0
  99. package/dist/{chunk-PM7SI4YT.js → chunk-BJOKL5PQ.js} +5 -5
  100. package/dist/{chunk-PGPPN63I.js → chunk-EMEXXAQI.js} +2 -2
  101. package/dist/{chunk-R6SBP5M5.js → chunk-GOWBYHYW.js} +4 -4
  102. package/dist/{chunk-LZQQ4JXY.js → chunk-HGVPPJKE.js} +8 -8
  103. package/dist/{chunk-XNBX3M35.js → chunk-HLCEKWFS.js} +4 -4
  104. package/dist/{chunk-4MGFUPQT.js → chunk-HOJL2GKW.js} +4 -4
  105. package/dist/{chunk-V5ZLUJV7.js → chunk-HRMB72E4.js} +2 -2
  106. package/dist/{chunk-CSDVRHUX.js → chunk-HWBKMUMV.js} +4 -4
  107. package/dist/{chunk-KN3WYEH2.js → chunk-IA6F7DU6.js} +4 -4
  108. package/dist/{chunk-BE5FGUJS.js → chunk-IM5SR7G2.js} +2 -2
  109. package/dist/{chunk-PJVDIUT2.js → chunk-IRNKHHQM.js} +3 -3
  110. package/dist/{chunk-4XET5MWR.js → chunk-KKE4SHRS.js} +2 -2
  111. package/dist/{chunk-ZTTFLIPH.js → chunk-L624DFJV.js} +2 -2
  112. package/dist/{chunk-OYT7YXQL.js → chunk-MGPN5TZE.js} +5 -5
  113. package/dist/{chunk-ERY6D2OV.js → chunk-MWPXKZ7O.js} +4 -4
  114. package/dist/{chunk-SCCE6VWY.js → chunk-N2Z7NHD5.js} +2 -2
  115. package/dist/chunk-N4R6T5K7.js +95 -0
  116. package/dist/chunk-N4R6T5K7.js.map +1 -0
  117. package/dist/{chunk-GNHXFJRR.js → chunk-N6EEY7V3.js} +2 -2
  118. package/dist/{chunk-OEBHWQSX.js → chunk-OESAYTNG.js} +9 -4
  119. package/dist/chunk-OESAYTNG.js.map +1 -0
  120. package/dist/{chunk-G5XHAN56.js → chunk-OT3KFZRE.js} +2 -2
  121. package/dist/{chunk-XAUKQZJK.js → chunk-QX4LMVL2.js} +2 -2
  122. package/dist/{chunk-S5UY5U73.js → chunk-QYJ25FWM.js} +20 -2
  123. package/dist/{chunk-S5UY5U73.js.map → chunk-QYJ25FWM.js.map} +1 -1
  124. package/dist/{chunk-6PYX6V3R.js → chunk-RJXVVLBO.js} +4 -4
  125. package/dist/{chunk-FRCBJLV5.js → chunk-RKKYSSAV.js} +5 -5
  126. package/dist/{chunk-WF7BZT6V.js → chunk-RR6BIHFX.js} +2 -2
  127. package/dist/{chunk-NGAU6PNB.js → chunk-RRVQVQF7.js} +5 -5
  128. package/dist/{chunk-F33YKDO2.js → chunk-TEST2NBS.js} +5 -5
  129. package/dist/{chunk-NKJSYZEU.js → chunk-V32626FV.js} +4 -4
  130. package/dist/{chunk-MLDA44NW.js → chunk-VGXSPUTD.js} +3 -3
  131. package/dist/{chunk-CTXF22BU.js → chunk-VODKYDC4.js} +5 -5
  132. package/dist/{chunk-DWJH3KXN.js → chunk-WAKGVAOB.js} +4 -4
  133. package/dist/{chunk-3DO5AJCG.js → chunk-WE2LNTR6.js} +12 -5
  134. package/dist/chunk-WE2LNTR6.js.map +1 -0
  135. package/dist/{chunk-SZA44EFA.js → chunk-WOEVBEGJ.js} +4 -4
  136. package/dist/{chunk-EOTV5BLM.js → chunk-WOP2DRMC.js} +2 -2
  137. package/dist/{chunk-E6JRPGMN.js → chunk-X3DVZNZH.js} +2 -2
  138. package/dist/{chunk-MLQYIJTO.js → chunk-XM7QCNZQ.js} +9 -3
  139. package/dist/chunk-XM7QCNZQ.js.map +1 -0
  140. package/dist/{chunk-P35CTP6L.js → chunk-Y3WB66XT.js} +7 -7
  141. package/dist/{chunk-DI46ZEWP.js → chunk-Y5QDXG5N.js} +20 -4
  142. package/dist/chunk-Y5QDXG5N.js.map +1 -0
  143. package/dist/{chunk-TNQDSTIA.js → chunk-Y6C4MYZE.js} +7 -7
  144. package/dist/{chunk-TBZKUZNW.js → chunk-ZPWU7Z6O.js} +3 -3
  145. package/dist/{chunk-QQSRZUT4.js → chunk-ZXEDKRRT.js} +4 -4
  146. package/dist/data-display/Avatar.js +3 -3
  147. package/dist/data-display/CardKit.js +8 -8
  148. package/dist/data-display/Chart.js +6 -6
  149. package/dist/data-display/DataViews.js +35 -35
  150. package/dist/data-display/FleetMap.js +5 -5
  151. package/dist/data-display/HoverCard.js +2 -2
  152. package/dist/data-display/InteractiveTooltip.js +2 -2
  153. package/dist/data-display/Lightbox.js +3 -3
  154. package/dist/data-display/MapPreview.js +2 -2
  155. package/dist/data-display/Progress.js +2 -2
  156. package/dist/data-display/Sheet.js +4 -4
  157. package/dist/en-US.js +2 -2
  158. package/dist/feedback/ConfirmAction.js +3 -3
  159. package/dist/form/AddressAutocomplete.js +5 -5
  160. package/dist/form/Autocomplete.js +2 -2
  161. package/dist/form/Calendar.js +3 -3
  162. package/dist/form/CategorySelect.js +4 -4
  163. package/dist/form/Command.js +3 -3
  164. package/dist/form/DateRangePicker.js +10 -10
  165. package/dist/form/UploadButton.js +2 -2
  166. package/dist/form/total-form.js +7 -7
  167. package/dist/layout/ContentToolbar.js +3 -3
  168. package/dist/layout/ScrollArea.js +2 -2
  169. package/dist/layout/SettingCard.js +13 -8
  170. package/dist/locales.js +4 -4
  171. package/dist/navigation/AppHeader.js +5 -5
  172. package/dist/pt-BR.js +2 -2
  173. package/dist/types/components/data-display/InteractiveTooltip/InteractiveTooltip.d.ts.map +1 -1
  174. package/dist/types/components/data-display/InteractiveTooltip/InteractiveTooltip.hooks.d.ts +18 -0
  175. package/dist/types/components/data-display/InteractiveTooltip/InteractiveTooltip.hooks.d.ts.map +1 -1
  176. package/dist/types/components/layout/SettingCard/SettingCard.d.ts.map +1 -1
  177. package/dist/types/components/layout/SettingCard/SettingCard.metrics.d.ts +5 -0
  178. package/dist/types/components/layout/SettingCard/SettingCard.metrics.d.ts.map +1 -1
  179. package/dist/types/components/layout/SettingCard/SettingCard.parts.d.ts +2 -0
  180. package/dist/types/components/layout/SettingCard/SettingCard.parts.d.ts.map +1 -1
  181. package/dist/types/components/layout/SettingCard/SettingCard.styles.d.ts +9 -2
  182. package/dist/types/components/layout/SettingCard/SettingCard.styles.d.ts.map +1 -1
  183. package/dist/types/components/layout/SettingCard/SettingCard.summary.d.ts +33 -0
  184. package/dist/types/components/layout/SettingCard/SettingCard.summary.d.ts.map +1 -0
  185. package/dist/types/components/layout/SettingCard/SettingSwitch.d.ts.map +1 -1
  186. package/dist/types/copy/layout.d.ts +8 -0
  187. package/dist/types/copy/layout.d.ts.map +1 -1
  188. package/dist/types/en-US.layout.d.ts.map +1 -1
  189. package/dist/types/pt-BR.layout.d.ts.map +1 -1
  190. package/dist/user-avatar.js +4 -4
  191. package/package.json +1 -1
  192. package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.hooks.ts +36 -0
  193. package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.tsx +7 -2
  194. package/src/components/layout/SettingCard/SettingCard.md +1 -1
  195. package/src/components/layout/SettingCard/SettingCard.metrics.ts +5 -0
  196. package/src/components/layout/SettingCard/SettingCard.parts.tsx +4 -0
  197. package/src/components/layout/SettingCard/SettingCard.styles.ts +17 -5
  198. package/src/components/layout/SettingCard/SettingCard.summary.tsx +100 -0
  199. package/src/components/layout/SettingCard/SettingCard.tsx +6 -2
  200. package/src/components/layout/SettingCard/SettingSwitch.tsx +11 -2
  201. package/src/components/layout/SettingCard/SettingToggle.md +1 -1
  202. package/src/copy/layout.ts +8 -0
  203. package/src/en-US.layout.ts +2 -0
  204. package/src/pt-BR.layout.ts +2 -0
  205. package/dist/chunk-3DO5AJCG.js.map +0 -1
  206. package/dist/chunk-57VL5UX7.js.map +0 -1
  207. package/dist/chunk-DI46ZEWP.js.map +0 -1
  208. package/dist/chunk-IC7GHPMK.js.map +0 -1
  209. package/dist/chunk-MLQYIJTO.js.map +0 -1
  210. package/dist/chunk-OEBHWQSX.js.map +0 -1
  211. /package/dist/{chunk-GXQDWHPN.js.map → chunk-2CJZLL5Y.js.map} +0 -0
  212. /package/dist/{chunk-STTULW2K.js.map → chunk-2KVWOTEQ.js.map} +0 -0
  213. /package/dist/{chunk-ISW5K72V.js.map → chunk-2ZRZTGWP.js.map} +0 -0
  214. /package/dist/{chunk-2OTBMU5Z.js.map → chunk-44LYXLW7.js.map} +0 -0
  215. /package/dist/{chunk-LYVTJLCF.js.map → chunk-56JF5PZK.js.map} +0 -0
  216. /package/dist/{chunk-5KGABAQB.js.map → chunk-5752357K.js.map} +0 -0
  217. /package/dist/{chunk-SPZAEMGW.js.map → chunk-5WX6U34F.js.map} +0 -0
  218. /package/dist/{chunk-QHXMNSOZ.js.map → chunk-6L6VXRLJ.js.map} +0 -0
  219. /package/dist/{chunk-VVFASSFY.js.map → chunk-6VGB4OX2.js.map} +0 -0
  220. /package/dist/{chunk-FRP7NM6X.js.map → chunk-6WZUKV55.js.map} +0 -0
  221. /package/dist/{chunk-QEINKMMX.js.map → chunk-7C763T3K.js.map} +0 -0
  222. /package/dist/{chunk-PARTZ7XI.js.map → chunk-7JKDB5J5.js.map} +0 -0
  223. /package/dist/{chunk-QYV7KLEN.js.map → chunk-ASGSC5UA.js.map} +0 -0
  224. /package/dist/{chunk-7GQ2ZZBQ.js.map → chunk-BCTRC6AR.js.map} +0 -0
  225. /package/dist/{chunk-XSHWEUDB.js.map → chunk-BE5Z36XZ.js.map} +0 -0
  226. /package/dist/{chunk-PM7SI4YT.js.map → chunk-BJOKL5PQ.js.map} +0 -0
  227. /package/dist/{chunk-PGPPN63I.js.map → chunk-EMEXXAQI.js.map} +0 -0
  228. /package/dist/{chunk-R6SBP5M5.js.map → chunk-GOWBYHYW.js.map} +0 -0
  229. /package/dist/{chunk-LZQQ4JXY.js.map → chunk-HGVPPJKE.js.map} +0 -0
  230. /package/dist/{chunk-XNBX3M35.js.map → chunk-HLCEKWFS.js.map} +0 -0
  231. /package/dist/{chunk-4MGFUPQT.js.map → chunk-HOJL2GKW.js.map} +0 -0
  232. /package/dist/{chunk-V5ZLUJV7.js.map → chunk-HRMB72E4.js.map} +0 -0
  233. /package/dist/{chunk-CSDVRHUX.js.map → chunk-HWBKMUMV.js.map} +0 -0
  234. /package/dist/{chunk-KN3WYEH2.js.map → chunk-IA6F7DU6.js.map} +0 -0
  235. /package/dist/{chunk-BE5FGUJS.js.map → chunk-IM5SR7G2.js.map} +0 -0
  236. /package/dist/{chunk-PJVDIUT2.js.map → chunk-IRNKHHQM.js.map} +0 -0
  237. /package/dist/{chunk-4XET5MWR.js.map → chunk-KKE4SHRS.js.map} +0 -0
  238. /package/dist/{chunk-ZTTFLIPH.js.map → chunk-L624DFJV.js.map} +0 -0
  239. /package/dist/{chunk-OYT7YXQL.js.map → chunk-MGPN5TZE.js.map} +0 -0
  240. /package/dist/{chunk-ERY6D2OV.js.map → chunk-MWPXKZ7O.js.map} +0 -0
  241. /package/dist/{chunk-SCCE6VWY.js.map → chunk-N2Z7NHD5.js.map} +0 -0
  242. /package/dist/{chunk-GNHXFJRR.js.map → chunk-N6EEY7V3.js.map} +0 -0
  243. /package/dist/{chunk-G5XHAN56.js.map → chunk-OT3KFZRE.js.map} +0 -0
  244. /package/dist/{chunk-XAUKQZJK.js.map → chunk-QX4LMVL2.js.map} +0 -0
  245. /package/dist/{chunk-6PYX6V3R.js.map → chunk-RJXVVLBO.js.map} +0 -0
  246. /package/dist/{chunk-FRCBJLV5.js.map → chunk-RKKYSSAV.js.map} +0 -0
  247. /package/dist/{chunk-WF7BZT6V.js.map → chunk-RR6BIHFX.js.map} +0 -0
  248. /package/dist/{chunk-NGAU6PNB.js.map → chunk-RRVQVQF7.js.map} +0 -0
  249. /package/dist/{chunk-F33YKDO2.js.map → chunk-TEST2NBS.js.map} +0 -0
  250. /package/dist/{chunk-NKJSYZEU.js.map → chunk-V32626FV.js.map} +0 -0
  251. /package/dist/{chunk-MLDA44NW.js.map → chunk-VGXSPUTD.js.map} +0 -0
  252. /package/dist/{chunk-CTXF22BU.js.map → chunk-VODKYDC4.js.map} +0 -0
  253. /package/dist/{chunk-DWJH3KXN.js.map → chunk-WAKGVAOB.js.map} +0 -0
  254. /package/dist/{chunk-SZA44EFA.js.map → chunk-WOEVBEGJ.js.map} +0 -0
  255. /package/dist/{chunk-EOTV5BLM.js.map → chunk-WOP2DRMC.js.map} +0 -0
  256. /package/dist/{chunk-E6JRPGMN.js.map → chunk-X3DVZNZH.js.map} +0 -0
  257. /package/dist/{chunk-P35CTP6L.js.map → chunk-Y3WB66XT.js.map} +0 -0
  258. /package/dist/{chunk-TNQDSTIA.js.map → chunk-Y6C4MYZE.js.map} +0 -0
  259. /package/dist/{chunk-TBZKUZNW.js.map → chunk-ZPWU7Z6O.js.map} +0 -0
  260. /package/dist/{chunk-QQSRZUT4.js.map → chunk-ZXEDKRRT.js.map} +0 -0
@@ -9,7 +9,7 @@ import {
9
9
  } from "../chunk-AH4XGLE2.js";
10
10
  import {
11
11
  AppHeaderDetails
12
- } from "../chunk-FRP7NM6X.js";
12
+ } from "../chunk-6WZUKV55.js";
13
13
  import {
14
14
  AppHeaderBrand
15
15
  } from "../chunk-GWFAINQ7.js";
@@ -18,13 +18,13 @@ import {
18
18
  highlightOf,
19
19
  initialsOf
20
20
  } from "../chunk-IQU4HKND.js";
21
- import "../chunk-LZQQ4JXY.js";
22
- import "../chunk-TBDAH7WC.js";
23
- import "../chunk-LYVTJLCF.js";
24
- import "../chunk-CRN4KKNI.js";
21
+ import "../chunk-HGVPPJKE.js";
25
22
  import "../chunk-3U3H3BZM.js";
23
+ import "../chunk-TBDAH7WC.js";
26
24
  import "../chunk-FPVYD7BO.js";
25
+ import "../chunk-56JF5PZK.js";
27
26
  import "../chunk-IM4DMKH4.js";
27
+ import "../chunk-CRN4KKNI.js";
28
28
  import "../chunk-MQ277OLB.js";
29
29
  import "../chunk-ST7B54JN.js";
30
30
  import "../chunk-Z2JH5KW5.js";
package/dist/pt-BR.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  PT_BR_LIGHTBOX_COPY,
8
8
  PT_BR_MAP_PREVIEW_COPY,
9
9
  PT_BR_TIMING_DIAGRAM_COPY
10
- } from "./chunk-V5ZLUJV7.js";
10
+ } from "./chunk-HRMB72E4.js";
11
11
  import {
12
12
  PT_BR_INSTALL_PROMPT_COPY,
13
13
  PT_BR_USER_AVATAR_COPY
@@ -28,7 +28,7 @@ import {
28
28
  PT_BR_SETTING_CARD_COPY,
29
29
  PT_BR_SETTING_SWITCH_COPY,
30
30
  PT_BR_TABLE_FILTER_COPY
31
- } from "./chunk-33L26P4J.js";
31
+ } from "./chunk-3ZKGNEP2.js";
32
32
  import {
33
33
  PT_BR_ADDRESS_AUTOCOMPLETE_COPY,
34
34
  PT_BR_AUTOCOMPLETE_COPY,
@@ -1 +1 @@
1
- {"version":3,"file":"InteractiveTooltip.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/InteractiveTooltip/InteractiveTooltip.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAU1B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAgC1E,eAAO,MAAM,kBAAkB,6GAwE9B,CAAC"}
1
+ {"version":3,"file":"InteractiveTooltip.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/InteractiveTooltip/InteractiveTooltip.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAU1B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAgC1E,eAAO,MAAM,kBAAkB,6GA6E9B,CAAC"}
@@ -19,5 +19,23 @@ export declare const usePinnedTooltip: ({ clickable, onPin, onUnpin }: PinOption
19
19
  wrapperRef: React.RefObject<HTMLDivElement | null>;
20
20
  handleClick: (e: React.MouseEvent) => void;
21
21
  };
22
+ type OnOpen = NonNullable<InteractiveTooltipProps['onOpen']>;
23
+ type OnClose = NonNullable<InteractiveTooltipProps['onClose']>;
24
+ /**
25
+ * The hover half of the tooltip's open state, so the MUI Tooltip is controlled
26
+ * from its first render (FUT-3013). It used to receive `open={undefined}` while
27
+ * hovering and a boolean once pinned, which MUI reports as a component switching
28
+ * from uncontrolled to controlled on the first click. The caller's own
29
+ * onOpen/onClose still run.
30
+ *
31
+ * Unpinning also closes it: the hover listeners are off while pinned, so a
32
+ * hover state left `true` from before the pin would otherwise keep the tooltip
33
+ * open after the click outside that unpinned it.
34
+ */
35
+ export declare const useHoverOpen: (isPinned: boolean, onOpen?: OnOpen, onClose?: OnClose) => {
36
+ open: boolean;
37
+ onOpen: OnOpen;
38
+ onClose: OnClose;
39
+ };
22
40
  export {};
23
41
  //# sourceMappingURL=InteractiveTooltip.hooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"InteractiveTooltip.hooks.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/InteractiveTooltip/InteractiveTooltip.hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAExE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAG1E,KAAK,oBAAoB,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,WAAW,CAAC;AAEhF,KAAK,oBAAoB,GAAG,uBAAuB,GACjD,QAAQ,CAAC,IAAI,CAAC,uBAAuB,EAAE,oBAAoB,CAAC,CAAC,CAAC;AAiBhE,eAAO,MAAM,mBAAmB,GAC9B,OAAO,uBAAuB,KAC7B,oBACwE,CAAC;AAE5E,UAAU,UAAU;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,+BAA+B,UAAU;;;;qBAkClE,KAAK,CAAC,UAAU;CAuBvB,CAAC"}
1
+ {"version":3,"file":"InteractiveTooltip.hooks.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/InteractiveTooltip/InteractiveTooltip.hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAExE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAG1E,KAAK,oBAAoB,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,WAAW,CAAC;AAEhF,KAAK,oBAAoB,GAAG,uBAAuB,GACjD,QAAQ,CAAC,IAAI,CAAC,uBAAuB,EAAE,oBAAoB,CAAC,CAAC,CAAC;AAiBhE,eAAO,MAAM,mBAAmB,GAC9B,OAAO,uBAAuB,KAC7B,oBACwE,CAAC;AAE5E,UAAU,UAAU;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,+BAA+B,UAAU;;;;qBAkClE,KAAK,CAAC,UAAU;CAuBvB,CAAC;AAEF,KAAK,MAAM,GAAG,WAAW,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC7D,KAAK,OAAO,GAAG,WAAW,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAC;AAE/D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,GACvB,UAAU,OAAO,EACjB,SAAS,MAAM,EACf,UAAU,OAAO,KAChB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAgBnD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SettingCard.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/SettingCard/SettingCard.tsx"],"names":[],"mappings":"AACA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAQjD,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AA+G7E;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,sFAgEtB,CAAC"}
1
+ {"version":3,"file":"SettingCard.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/SettingCard/SettingCard.tsx"],"names":[],"mappings":"AACA,OAAO,KAA4B,MAAM,OAAO,CAAC;AASjD,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAgH7E;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,sFAkEtB,CAAC"}
@@ -13,6 +13,11 @@ export declare const SETTING_CARD: {
13
13
  readonly groupRuleWidth: 2;
14
14
  /** The narrowest a grid column gets by default. */
15
15
  readonly gridMinColumnWidth: 320;
16
+ /** The widest the [i]'s full-summary tooltip gets. */
17
+ readonly infoMaxWidth: 360;
18
+ /** The [i]'s keyboard focus ring: its width, and its gap from the glyph. */
19
+ readonly infoFocusRingWidth: 2;
20
+ readonly infoFocusRingOffset: 2;
16
21
  };
17
22
  /** The grid's default gap, in theme SPACING units (not px): what `sx`'s `gap: 2` means. */
18
23
  export declare const SETTING_GRID_GAP_UNITS = 2;
@@ -1 +1 @@
1
- {"version":3,"file":"SettingCard.metrics.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/SettingCard/SettingCard.metrics.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,YAAY;IACvB,sCAAsC;;IAEtC,4DAA4D;;IAE5D,oEAAoE;;IAEpE,0DAA0D;;IAE1D,mDAAmD;;CAE3C,CAAC;AAEX,2FAA2F;AAC3F,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,2EAA2E;AAC3E,eAAO,MAAM,8BAA8B,MAAM,CAAC"}
1
+ {"version":3,"file":"SettingCard.metrics.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/SettingCard/SettingCard.metrics.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,YAAY;IACvB,sCAAsC;;IAEtC,4DAA4D;;IAE5D,oEAAoE;;IAEpE,0DAA0D;;IAE1D,mDAAmD;;IAEnD,sDAAsD;;IAEtD,4EAA4E;;;CAGpE,CAAC;AAEX,2FAA2F;AAC3F,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,2EAA2E;AAC3E,eAAO,MAAM,8BAA8B,MAAM,CAAC"}
@@ -12,6 +12,8 @@ interface HeaderProps {
12
12
  trailing?: React.ReactNode;
13
13
  /** Renders the title as a `<label>` for this control instead of a heading. */
14
14
  labelFor?: string;
15
+ /** Beside the title, after the status pill — the [i] while the summary is cut. */
16
+ info?: React.ReactNode;
15
17
  dataTestId?: string;
16
18
  }
17
19
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"SettingCard.parts.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/SettingCard/SettingCard.parts.tsx"],"names":[],"mappings":"AAGA,OAAO,KAA0B,MAAM,OAAO,CAAC;AAW/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE9E,uEAAuE;AACvE,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,GAAG,SAAS,EAAE,MAAM,MAAM,KAAG,MAAM,GAAG,SACvC,CAAC;AAEvC,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,mBAAmB,CAAC;IAClC,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAyC/C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAY3F,CAAC;AAEF,wGAAwG;AACxG,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAU5D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAsCA,CAAC"}
1
+ {"version":3,"file":"SettingCard.parts.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/SettingCard/SettingCard.parts.tsx"],"names":[],"mappings":"AAGA,OAAO,KAA0B,MAAM,OAAO,CAAC;AAW/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE9E,uEAAuE;AACvE,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,GAAG,SAAS,EAAE,MAAM,MAAM,KAAG,MAAM,GAAG,SACvC,CAAC;AAEvC,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,mBAAmB,CAAC;IAClC,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CA2C/C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAY3F,CAAC;AAEF,wGAAwG;AACxG,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAU5D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAsCA,CAAC"}
@@ -29,9 +29,16 @@ export declare const headerStyles: (theme: Theme) => CSSObject;
29
29
  * take the page's text colour onto its own surface.
30
30
  */
31
31
  export declare const titleStyles: (theme: Theme) => CSSObject;
32
- /** The one line a closed card shows. Long values end in an ellipsis, not a second line. */
32
+ /** The most lines a card's summary shows before the rest goes behind the [i]. */
33
+ export declare const SUMMARY_MAX_LINES = 2;
34
+ /**
35
+ * Two lines at most, cut with an ellipsis. Visual only: the whole sentence stays
36
+ * in the DOM, so a switch that is `aria-describedby` it still reads all of it.
37
+ */
38
+ export declare const clampStyles: CSSObject;
39
+ /** A closed card's value: two lines at most, the rest behind the [i]. */
33
40
  export declare const summaryStyles: (theme: Theme) => CSSObject;
34
- /** A switch card's explanation, which may wrap: it is read, not scanned. */
41
+ /** A switch card's explanation; `SettingSwitchBlock` clamps it (see `clampStyles`). */
35
42
  export declare const descriptionStyles: (theme: Theme) => CSSObject;
36
43
  /** The inactive group's hint: a glyph and the sentence, so it does not read as a second summary. */
37
44
  export declare const hintStyles: (theme: Theme) => CSSObject;
@@ -1 +1 @@
1
- {"version":3,"file":"SettingCard.styles.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/SettingCard/SettingCard.styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAO/E;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAE/D,+FAA+F;AAC/F,eAAO,MAAM,YAAY,GACvB,KAAK,OAAO,CAAC,KAAK,CAAC,EACnB,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,SAAS,KAC7B,OAAO,CAAC,KAAK,CAAgE,CAAC;AAEjF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,KAAK,EAAE,MAAM,OAAO,KAAG,SAgB1D,CAAC;AAEH,mEAAmE;AACnE,eAAO,MAAM,UAAU,GAAI,OAAO,KAAK,KAAG,SAMxC,CAAC;AAEH,eAAO,MAAM,YAAY,GAAI,OAAO,KAAK,KAAG,SAK1C,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,OAAO,KAAK,KAAG,SAOzC,CAAC;AAEH,2FAA2F;AAC3F,eAAO,MAAM,aAAa,GAAI,OAAO,KAAK,KAAG,SAO3C,CAAC;AAEH,4EAA4E;AAC5E,eAAO,MAAM,iBAAiB,GAAI,OAAO,KAAK,KAAG,SAI/C,CAAC;AAEH,oGAAoG;AACpG,eAAO,MAAM,UAAU,GAAI,OAAO,KAAK,KAAG,SAOxC,CAAC;AAEH,eAAO,MAAM,WAAW,GAAI,OAAO,KAAK,KAAG,SAIzC,CAAC;AAEH,eAAO,MAAM,aAAa,GAAI,OAAO,KAAK,KAAG,SAM3C,CAAC;AAEH,eAAO,MAAM,UAAU,GAAI,OAAO,KAAK,KAAG,SAIxC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,KAAK,EAAE,QAAQ,OAAO,KAAG,SAQ/D,CAAC"}
1
+ {"version":3,"file":"SettingCard.styles.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/SettingCard/SettingCard.styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAO/E;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAE/D,+FAA+F;AAC/F,eAAO,MAAM,YAAY,GACvB,KAAK,OAAO,CAAC,KAAK,CAAC,EACnB,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,SAAS,KAC7B,OAAO,CAAC,KAAK,CAAgE,CAAC;AAEjF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,KAAK,EAAE,MAAM,OAAO,KAAG,SAgB1D,CAAC;AAEH,mEAAmE;AACnE,eAAO,MAAM,UAAU,GAAI,OAAO,KAAK,KAAG,SAMxC,CAAC;AAEH,eAAO,MAAM,YAAY,GAAI,OAAO,KAAK,KAAG,SAK1C,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,OAAO,KAAK,KAAG,SAOzC,CAAC;AAEH,iFAAiF;AACjF,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,SAKzB,CAAC;AAEF,yEAAyE;AACzE,eAAO,MAAM,aAAa,GAAI,OAAO,KAAK,KAAG,SAK3C,CAAC;AAEH,uFAAuF;AACvF,eAAO,MAAM,iBAAiB,GAAI,OAAO,KAAK,KAAG,SAI/C,CAAC;AAEH,oGAAoG;AACpG,eAAO,MAAM,UAAU,GAAI,OAAO,KAAK,KAAG,SAOxC,CAAC;AAEH,eAAO,MAAM,WAAW,GAAI,OAAO,KAAK,KAAG,SAIzC,CAAC;AAEH,eAAO,MAAM,aAAa,GAAI,OAAO,KAAK,KAAG,SAM3C,CAAC;AAEH,eAAO,MAAM,UAAU,GAAI,OAAO,KAAK,KAAG,SAIxC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,KAAK,EAAE,QAAQ,OAAO,KAAG,SAQ/D,CAAC"}
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ /**
3
+ * Whether a clamped element is hiding text — measured, never guessed from the
4
+ * string's length, because what fits depends on the width the card is GIVEN.
5
+ * Re-measured whenever the element resizes, so a card that widens drops its [i].
6
+ */
7
+ export declare const useClamped: (content?: unknown) => {
8
+ ref: (node: HTMLElement | null) => void;
9
+ clamped: boolean;
10
+ };
11
+ /**
12
+ * The [i] beside a card's title while its summary is cut: hover shows the whole
13
+ * text, a click or tap pins it — so it works on a phone, where there is no hover.
14
+ */
15
+ export declare const SummaryInfo: React.FC<{
16
+ label: string;
17
+ summary: React.ReactNode;
18
+ dataTestId?: string;
19
+ }>;
20
+ /**
21
+ * The summary's measuring ref, and the [i] for the header while it is cut —
22
+ * `null` when there is no summary, it fits, or `show` is false (an open card).
23
+ */
24
+ export declare const useSummaryInfo: ({ summary, show, label, dataTestId, }: {
25
+ summary: React.ReactNode;
26
+ show?: boolean;
27
+ label: string;
28
+ dataTestId?: string;
29
+ }) => {
30
+ ref: (node: HTMLElement | null) => void;
31
+ info: React.ReactNode;
32
+ };
33
+ //# sourceMappingURL=SettingCard.summary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SettingCard.summary.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/SettingCard/SettingCard.summary.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAStE;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,UAAU,OAAO,KAAG;IAAE,GAAG,EAAE,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAkBzG,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAuClG,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,uCAK5B;IACD,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,KAAG;IAAE,GAAG,EAAE,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IAAC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAA;CAInE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SettingSwitch.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/SettingCard/SettingSwitch.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAgB,MAAM,OAAO,CAAC;AAKrC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,wFAAwF;AACxF,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,kBAAkB,EAClB,OAAO,GAAG,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,aAAa,GAAG,YAAY,CAC/G,GAAG;IAAE,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC;AAE1B,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,mBAAmB,QAAO,gBAQtC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CACvC,uBAAuB,GAAG;IAAE,GAAG,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAA;CAAE,CA8C9F,CAAC"}
1
+ {"version":3,"file":"SettingSwitch.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/SettingCard/SettingSwitch.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAgB,MAAM,OAAO,CAAC;AAKrC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,wFAAwF;AACxF,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,kBAAkB,EAClB,OAAO,GAAG,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,aAAa,GAAG,YAAY,CAC/G,GAAG;IAAE,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC;AAE1B,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,mBAAmB,QAAO,gBAQtC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CACvC,uBAAuB,GAAG;IAAE,GAAG,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAA;CAAE,CAsD9F,CAAC"}
@@ -31,6 +31,12 @@ export interface SettingCardCopy {
31
31
  learnMore: string;
32
32
  /** Shown when the save rejected and the host's `formatError` gave no sentence of its own. */
33
33
  saveFailed: string;
34
+ /**
35
+ * The accessible name of the [i] beside the title while the summary is cut to
36
+ * two lines. Optional so a host's own copy object keeps compiling; without it
37
+ * the [i] is named after the card's title.
38
+ */
39
+ moreInfo?: string;
34
40
  }
35
41
  /**
36
42
  * What a switch that saves the moment it flips says about that save — shared
@@ -41,5 +47,7 @@ export interface SettingSwitchCopy {
41
47
  saving: string;
42
48
  /** Shown when the save rejected and the host's `formatError` gave no sentence of its own. */
43
49
  saveFailed: string;
50
+ /** The [i]'s accessible name — see `SettingCardCopy.moreInfo`. */
51
+ moreInfo?: string;
44
52
  }
45
53
  //# sourceMappingURL=layout.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/copy/layout.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,eAAe;IAC9B,kEAAkE;IAClE,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,YAAY,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,oFAAoF;IACpF,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,0FAA0F;IAC1F,MAAM,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,6FAA6F;IAC7F,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,UAAU,EAAE,MAAM,CAAC;CACpB"}
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/copy/layout.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,eAAe;IAC9B,kEAAkE;IAClE,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,YAAY,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,oFAAoF;IACpF,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,0FAA0F;IAC1F,MAAM,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,6FAA6F;IAC7F,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,UAAU,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"en-US.layout.d.ts","sourceRoot":"","sources":["../../src/en-US.layout.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,eAAe,EAChB,MAAM,QAAQ,CAAC;AAEhB,eAAO,MAAM,uBAAuB,EAAE,eAMrC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,eAOrC,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,iBAGvC,CAAC"}
1
+ {"version":3,"file":"en-US.layout.d.ts","sourceRoot":"","sources":["../../src/en-US.layout.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,eAAe,EAChB,MAAM,QAAQ,CAAC;AAEhB,eAAO,MAAM,uBAAuB,EAAE,eAMrC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,eAQrC,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,iBAIvC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"pt-BR.layout.d.ts","sourceRoot":"","sources":["../../src/pt-BR.layout.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,eAAe,EAChB,MAAM,QAAQ,CAAC;AAEhB,eAAO,MAAM,uBAAuB,EAAE,eAMrC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,eAOrC,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,iBAGvC,CAAC"}
1
+ {"version":3,"file":"pt-BR.layout.d.ts","sourceRoot":"","sources":["../../src/pt-BR.layout.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,eAAe,EAChB,MAAM,QAAQ,CAAC;AAEhB,eAAO,MAAM,uBAAuB,EAAE,eAMrC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,eAQrC,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,iBAIvC,CAAC"}
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  UserAvatar,
3
3
  UserMenu
4
- } from "./chunk-EOTV5BLM.js";
4
+ } from "./chunk-WOP2DRMC.js";
5
5
  import "./chunk-UDQSIRAP.js";
6
- import "./chunk-PGPPN63I.js";
7
- import "./chunk-TNQDSTIA.js";
6
+ import "./chunk-EMEXXAQI.js";
7
+ import "./chunk-Y6C4MYZE.js";
8
+ import "./chunk-MTEQEPNY.js";
8
9
  import "./chunk-6ZZGK5DT.js";
9
10
  import "./chunk-3ZVUNSFF.js";
10
- import "./chunk-MTEQEPNY.js";
11
11
  import "./chunk-VUHLNYAE.js";
12
12
  import "./chunk-2GSIEDGN.js";
13
13
  import "./chunk-WN5PNP6F.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@12-apps/ui",
3
- "version": "6.52.1",
3
+ "version": "6.53.0",
4
4
  "license": "MIT",
5
5
  "packageManager": "pnpm@10.34.5",
6
6
  "type": "module",
@@ -97,3 +97,39 @@ export const usePinnedTooltip = ({ clickable, onPin, onUnpin }: PinOptions) => {
97
97
 
98
98
  return { isPinned, isControlledOpen, wrapperRef, handleClick };
99
99
  };
100
+
101
+ type OnOpen = NonNullable<InteractiveTooltipProps['onOpen']>;
102
+ type OnClose = NonNullable<InteractiveTooltipProps['onClose']>;
103
+
104
+ /**
105
+ * The hover half of the tooltip's open state, so the MUI Tooltip is controlled
106
+ * from its first render (FUT-3013). It used to receive `open={undefined}` while
107
+ * hovering and a boolean once pinned, which MUI reports as a component switching
108
+ * from uncontrolled to controlled on the first click. The caller's own
109
+ * onOpen/onClose still run.
110
+ *
111
+ * Unpinning also closes it: the hover listeners are off while pinned, so a
112
+ * hover state left `true` from before the pin would otherwise keep the tooltip
113
+ * open after the click outside that unpinned it.
114
+ */
115
+ export const useHoverOpen = (
116
+ isPinned: boolean,
117
+ onOpen?: OnOpen,
118
+ onClose?: OnClose,
119
+ ): { open: boolean; onOpen: OnOpen; onClose: OnClose } => {
120
+ const [open, setOpen] = useState(false);
121
+ useEffect(() => {
122
+ if (!isPinned) setOpen(false);
123
+ }, [isPinned]);
124
+ return {
125
+ open,
126
+ onOpen: (event) => {
127
+ setOpen(true);
128
+ onOpen?.(event);
129
+ },
130
+ onClose: (event) => {
131
+ setOpen(false);
132
+ onClose?.(event);
133
+ },
134
+ };
135
+ };
@@ -2,7 +2,7 @@ import MuiTooltip from '@mui/material/Tooltip/index.js';
2
2
  import { styled } from '@mui/material/styles/index.js';
3
3
  import React from 'react';
4
4
 
5
- import { resolveTooltipProps, usePinnedTooltip } from './InteractiveTooltip.hooks';
5
+ import { resolveTooltipProps, useHoverOpen, usePinnedTooltip } from './InteractiveTooltip.hooks';
6
6
  import {
7
7
  arrowColor,
8
8
  emphasisStyles,
@@ -58,6 +58,8 @@ export const InteractiveTooltip = React.forwardRef<HTMLDivElement, InteractiveTo
58
58
  onUnpin,
59
59
  className,
60
60
  children,
61
+ onOpen,
62
+ onClose,
61
63
  ...props
62
64
  } = resolveTooltipProps(rawProps);
63
65
 
@@ -66,6 +68,7 @@ export const InteractiveTooltip = React.forwardRef<HTMLDivElement, InteractiveTo
66
68
  onPin,
67
69
  onUnpin,
68
70
  });
71
+ const hover = useHoverOpen(isPinned, onOpen, onClose);
69
72
 
70
73
  // Determine which content to show
71
74
  const tooltipContent = isPinned ? pinnedContent : hoverContent;
@@ -94,7 +97,9 @@ export const InteractiveTooltip = React.forwardRef<HTMLDivElement, InteractiveTo
94
97
  glow={glow}
95
98
  pulse={pulse}
96
99
  title={tooltipContent}
97
- open={isPinned ? isControlledOpen : undefined}
100
+ open={isPinned ? isControlledOpen : hover.open}
101
+ onOpen={hover.onOpen}
102
+ onClose={hover.onClose}
98
103
  enterDelay={isPinned ? 0 : 100}
99
104
  leaveDelay={0}
100
105
  disableHoverListener={isPinned}
@@ -51,7 +51,7 @@ const [draft, setDraft] = useState<number | null>(saved);
51
51
  | `title` | `string` | **required** | The setting's name. A heading, and the accessible name of the card's region. |
52
52
  | `onSave` | `() => void \| Promise<unknown>` | **required** | Persist the draft. See *Saving* below. |
53
53
  | `children` | `ReactNode` | **required** | The form. Rendered only while open. |
54
- | `summary` | `ReactNode` | — | The one line a closed card shows. Ends in an ellipsis rather than wrapping. |
54
+ | `summary` | `ReactNode` | — | What a closed card shows under its title: two lines at most, then an ellipsis. While it is cut, an [i] beside the title shows the whole text (hover, or a click/tap that pins it). |
55
55
  | `status` | `{ label: string; color?: ColorValue }` | — | The pill beside the title. `label` is always shown, so colour never carries the meaning alone. |
56
56
  | `learnMore` | `ReactNode` | — | Longer explanation behind a disclosure in the open card. Omit for no disclosure. |
57
57
  | `onCancel` | `() => void` | — | The card closed without saving. Reset the host's draft here. |
@@ -13,6 +13,11 @@ export const SETTING_CARD = {
13
13
  groupRuleWidth: 2,
14
14
  /** The narrowest a grid column gets by default. */
15
15
  gridMinColumnWidth: 320,
16
+ /** The widest the [i]'s full-summary tooltip gets. */
17
+ infoMaxWidth: 360,
18
+ /** The [i]'s keyboard focus ring: its width, and its gap from the glyph. */
19
+ infoFocusRingWidth: 2,
20
+ infoFocusRingOffset: 2,
16
21
  } as const;
17
22
 
18
23
  /** The grid's default gap, in theme SPACING units (not px): what `sx`'s `gap: 2` means. */
@@ -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`. |