@12-apps/ui 6.89.1 → 6.90.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 (288) hide show
  1. package/components-catalog.md +1 -1
  2. package/dist/_internal/components/data-display/Alert/Alert.js +3 -3
  3. package/dist/_internal/components/data-display/Avatar/Avatar.js +4 -4
  4. package/dist/_internal/components/data-display/Avatar/Avatar.view.js +2 -2
  5. package/dist/_internal/components/data-display/CardKit/card-actions-context.js +4 -4
  6. package/dist/_internal/components/data-display/CardKit/use-remove-confirm.js +5 -5
  7. package/dist/_internal/components/data-display/Carousel/Carousel.chrome.js +4 -3
  8. package/dist/_internal/components/data-display/Carousel/Carousel.js +6 -5
  9. package/dist/_internal/components/data-display/Carousel/Carousel.parts.js +3 -2
  10. package/dist/_internal/components/data-display/Chart/Chart.js +3 -3
  11. package/dist/_internal/components/data-display/Chart/SpecChart.js +6 -6
  12. package/dist/_internal/components/data-display/Chart/chart-renderers.js +2 -2
  13. package/dist/_internal/components/data-display/Chart/chart-spec.js +2 -2
  14. package/dist/_internal/components/data-display/DataGrid/DataGrid.js +2 -2
  15. package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +48 -23
  16. package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +53 -28
  17. package/dist/_internal/components/data-display/DataViews/base-list-card-geometry.js +1 -1
  18. package/dist/_internal/components/data-display/DataViews/base-list-card-layout.js +1 -1
  19. package/dist/_internal/components/data-display/DataViews/base-list-card.js +3 -3
  20. package/dist/_internal/components/data-display/DataViews/data-views-bar-controls.js +5 -3
  21. package/dist/_internal/components/data-display/DataViews/data-views-day-input.js +1 -1
  22. package/dist/_internal/components/data-display/DataViews/data-views-filter-panel.js +31 -6
  23. package/dist/_internal/components/data-display/DataViews/data-views-grid-bodies.js +3 -3
  24. package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +47 -22
  25. package/dist/_internal/components/data-display/DataViews/data-views-inline-bar.js +37 -12
  26. package/dist/_internal/components/data-display/DataViews/data-views-more-fields.js +32 -7
  27. package/dist/_internal/components/data-display/DataViews/data-views-more-filters.js +33 -8
  28. package/dist/_internal/components/data-display/DataViews/data-views-number-input.js +1 -1
  29. package/dist/_internal/components/data-display/DataViews/data-views-preset-chips.js +10 -3
  30. package/dist/_internal/components/data-display/DataViews/data-views-range-bounds.js +47 -0
  31. package/dist/_internal/components/data-display/DataViews/data-views-range-bounds.js.map +1 -0
  32. package/dist/_internal/components/data-display/DataViews/data-views-range-calendar.js +36 -0
  33. package/dist/_internal/components/data-display/DataViews/data-views-range-calendar.js.map +1 -0
  34. package/dist/_internal/components/data-display/DataViews/data-views-range-pill.js +32 -6
  35. package/dist/_internal/components/data-display/DataViews/data-views-range-summary.js +12 -0
  36. package/dist/_internal/components/data-display/DataViews/data-views-range-summary.js.map +1 -0
  37. package/dist/_internal/components/data-display/DataViews/data-views-shell-toolbar.js +3 -3
  38. package/dist/_internal/components/data-display/DataViews/data-views-still-anchor.js +9 -0
  39. package/dist/_internal/components/data-display/DataViews/data-views-still-anchor.js.map +1 -0
  40. package/dist/_internal/components/data-display/DataViews/data-views-table-parts.js +4 -4
  41. package/dist/_internal/components/data-display/DataViews/data-views-toolbar.js +2 -2
  42. package/dist/_internal/components/data-display/DayRuler/DayRuler.js +3 -3
  43. package/dist/_internal/components/data-display/DayRuler/DayRuler.parts.js +2 -2
  44. package/dist/_internal/components/data-display/DayRuler/DayRuler.styles.js +3 -1
  45. package/dist/_internal/components/data-display/FleetMap/FleetBody.js +9 -8
  46. package/dist/_internal/components/data-display/FleetMap/FleetCanvas.js +8 -7
  47. package/dist/_internal/components/data-display/FleetMap/FleetMap.fixtures.js +2 -1
  48. package/dist/_internal/components/data-display/FleetMap/FleetMap.fixtures.js.map +1 -1
  49. package/dist/_internal/components/data-display/FleetMap/FleetMap.js +9 -9
  50. package/dist/_internal/components/data-display/MapPreview/MapControlBar.js +4 -3
  51. package/dist/_internal/components/data-display/MapPreview/MapLayers.js +5 -4
  52. package/dist/_internal/components/data-display/MapPreview/MapMarkers.js +4 -3
  53. package/dist/_internal/components/data-display/MapPreview/MapPreview.helpers.js +3 -2
  54. package/dist/_internal/components/data-display/MapPreview/MapPreview.js +7 -6
  55. package/dist/_internal/components/data-display/index.js +38 -38
  56. package/dist/_internal/components/feedback/NotificationStatusNotice/NotificationStatusNotice.js +4 -4
  57. package/dist/_internal/components/feedback/SequenceResolver/SequenceResolver.js +6 -6
  58. package/dist/_internal/components/feedback/SequenceResolver/SequenceResolver.overview.js +5 -5
  59. package/dist/_internal/components/feedback/SequenceResolver/SequenceResolver.parts.js +4 -4
  60. package/dist/_internal/components/feedback/index.js +7 -7
  61. package/dist/_internal/components/form/Calendar/Calendar.js +5 -5
  62. package/dist/_internal/components/form/Calendar/CalendarDay.js +1 -1
  63. package/dist/_internal/components/form/Calendar/CalendarDayCell.js +2 -2
  64. package/dist/_internal/components/form/Calendar/CalendarMonth.js +3 -3
  65. package/dist/_internal/components/form/Calendar/CalendarSelectorsMonth.js +4 -4
  66. package/dist/_internal/components/form/DateRangePicker/DateRangePicker.hooks.js +3 -3
  67. package/dist/_internal/components/form/DateRangePicker/DateRangePicker.js +10 -10
  68. package/dist/_internal/components/form/DateRangePicker/DateRangePicker.range.js +2 -2
  69. package/dist/_internal/components/form/DateRangePicker/DateRangePickerFields.js +3 -3
  70. package/dist/_internal/components/form/index.js +24 -24
  71. package/dist/_internal/components/index.js +66 -66
  72. package/dist/_internal/en-US.data-display.js +2 -1
  73. package/dist/_internal/pt-BR.data-display.js +2 -1
  74. package/dist/_internal/user-avatar/user-avatar.js +5 -5
  75. package/dist/charts.js +11 -11
  76. package/dist/{chunk-FJ3UZ4RC.js → chunk-2FKWKLSC.js} +5 -3
  77. package/dist/chunk-2FKWKLSC.js.map +1 -0
  78. package/dist/{chunk-BO6MT2S2.js → chunk-3HZKUN5J.js} +7 -6
  79. package/dist/chunk-3HZKUN5J.js.map +1 -0
  80. package/dist/{chunk-TYXFFNPM.js → chunk-3OTGREQG.js} +10 -10
  81. package/dist/{chunk-BEHT4IHH.js → chunk-3X2MA47R.js} +2 -2
  82. package/dist/{chunk-XHIBFBNP.js → chunk-3ZRK3BRN.js} +4 -2
  83. package/dist/chunk-3ZRK3BRN.js.map +1 -0
  84. package/dist/{chunk-X5OGIT2F.js → chunk-4L54KUZV.js} +22 -4
  85. package/dist/chunk-4L54KUZV.js.map +1 -0
  86. package/dist/{chunk-TRYR424I.js → chunk-6LOWZCH7.js} +15 -1
  87. package/dist/chunk-6LOWZCH7.js.map +1 -0
  88. package/dist/{chunk-6WHIJPEF.js → chunk-6PU5P7QT.js} +2 -2
  89. package/dist/chunk-7CUZTWKW.js +52 -0
  90. package/dist/chunk-7CUZTWKW.js.map +1 -0
  91. package/dist/{chunk-JIEVKHOH.js → chunk-7YJYIMWP.js} +7 -7
  92. package/dist/{chunk-YNZUYZ2O.js → chunk-A3DDEKLV.js} +2 -2
  93. package/dist/{chunk-KHREN7Y7.js → chunk-ACM3HHZY.js} +2 -2
  94. package/dist/{chunk-FEKWKWGK.js → chunk-ARGVUTTL.js} +15 -1
  95. package/dist/chunk-ARGVUTTL.js.map +1 -0
  96. package/dist/{chunk-DYHOBKPU.js → chunk-BLZDSCIZ.js} +6 -6
  97. package/dist/{chunk-E2UOEI7N.js → chunk-BV2LOTMC.js} +2 -2
  98. package/dist/{chunk-O63ZROSY.js → chunk-BZBLPXV7.js} +4 -4
  99. package/dist/{chunk-OKRITX4S.js → chunk-CJ6XXM4X.js} +4 -4
  100. package/dist/{chunk-LV6AD6XC.js → chunk-DBI6AMNY.js} +4 -4
  101. package/dist/{chunk-QRRWLLXW.js → chunk-DSBC6O46.js} +2 -2
  102. package/dist/{chunk-3YFDGFEK.js → chunk-DVX4HDNP.js} +2 -2
  103. package/dist/{chunk-CJUK32UH.js → chunk-EEO7M5GU.js} +2 -2
  104. package/dist/{chunk-7XSCEHGA.js → chunk-EOQ6EKTS.js} +7 -7
  105. package/dist/{chunk-5RSK5M6M.js → chunk-FI2CQOGC.js} +63 -126
  106. package/dist/chunk-FI2CQOGC.js.map +1 -0
  107. package/dist/{chunk-Q2ERGAQO.js → chunk-FYAW5GBF.js} +33 -6
  108. package/dist/chunk-FYAW5GBF.js.map +1 -0
  109. package/dist/{chunk-EOJSA2EK.js → chunk-G2PVUPE7.js} +26 -18
  110. package/dist/chunk-G2PVUPE7.js.map +1 -0
  111. package/dist/{chunk-AMLHEKSV.js → chunk-HI7JPDD6.js} +5 -5
  112. package/dist/{chunk-2H6SCVLD.js → chunk-HMEGQKNQ.js} +3 -3
  113. package/dist/chunk-J2AVWIMM.js +60 -0
  114. package/dist/chunk-J2AVWIMM.js.map +1 -0
  115. package/dist/{chunk-7QKIL5YF.js → chunk-J2GDA64N.js} +4 -4
  116. package/dist/{chunk-BAQ3ITZV.js → chunk-JFD742C3.js} +2 -2
  117. package/dist/{chunk-OBA75Y5O.js → chunk-JHWEL4NX.js} +61 -33
  118. package/dist/chunk-JHWEL4NX.js.map +1 -0
  119. package/dist/{chunk-HQCZT6TO.js → chunk-JVOEVTCZ.js} +5 -5
  120. package/dist/{chunk-WAO7UQRS.js → chunk-KANCE4MS.js} +3 -3
  121. package/dist/{chunk-XLU5WFSY.js → chunk-KRBPWTXW.js} +2 -2
  122. package/dist/{chunk-S6D7NOV7.js → chunk-L6JAALMX.js} +3 -3
  123. package/dist/{chunk-72HOUWAW.js → chunk-L6YTVXGN.js} +5 -3
  124. package/dist/{chunk-72HOUWAW.js.map → chunk-L6YTVXGN.js.map} +1 -1
  125. package/dist/chunk-LZNUBQ5I.js +181 -0
  126. package/dist/chunk-LZNUBQ5I.js.map +1 -0
  127. package/dist/{chunk-BECKKDYG.js → chunk-M2M4IDFU.js} +2 -2
  128. package/dist/{chunk-CSGBHYW6.js → chunk-M5Y42AZ4.js} +2 -2
  129. package/dist/chunk-MICX23P4.js +122 -0
  130. package/dist/chunk-MICX23P4.js.map +1 -0
  131. package/dist/{chunk-5CP5Z3YU.js → chunk-MPWA55CF.js} +4 -4
  132. package/dist/{chunk-5KK3I42O.js → chunk-NK6O4NE4.js} +13 -10
  133. package/dist/chunk-NK6O4NE4.js.map +1 -0
  134. package/dist/{chunk-RCTHCXS6.js → chunk-PJNIJIE6.js} +2 -2
  135. package/dist/{chunk-6ATXOJVQ.js → chunk-QADTI63U.js} +4 -4
  136. package/dist/{chunk-MW7P2C2C.js → chunk-QAEO52Z4.js} +2 -2
  137. package/dist/{chunk-5S5K73I6.js → chunk-QSOCOXVL.js} +3 -3
  138. package/dist/{chunk-NQCTANF3.js → chunk-QVDEGBME.js} +7 -7
  139. package/dist/{chunk-BQBEN44R.js → chunk-RDCIST7P.js} +2 -2
  140. package/dist/{chunk-HUXAIQC5.js → chunk-RZ3P4X2I.js} +2 -2
  141. package/dist/{chunk-WJMSND5Q.js → chunk-SCXVTNLE.js} +2 -2
  142. package/dist/{chunk-K6FCSB6T.js → chunk-SK2CTB3O.js} +6 -6
  143. package/dist/{chunk-QLJU7UUI.js → chunk-T7OIVPCO.js} +38 -3
  144. package/dist/chunk-T7OIVPCO.js.map +1 -0
  145. package/dist/{chunk-U2ILXZDG.js → chunk-TB5CRHTF.js} +2 -2
  146. package/dist/{chunk-SB2SEGR6.js → chunk-TIM4PXWN.js} +3 -3
  147. package/dist/{chunk-YDIC6LSP.js → chunk-VCQFDQM3.js} +27 -7
  148. package/dist/chunk-VCQFDQM3.js.map +1 -0
  149. package/dist/chunk-VIMMEADQ.js +164 -0
  150. package/dist/chunk-VIMMEADQ.js.map +1 -0
  151. package/dist/{chunk-6D5AMANO.js → chunk-WH3LUOCQ.js} +2 -2
  152. package/dist/{chunk-OWRQOYUE.js → chunk-WWR6APJR.js} +2 -2
  153. package/dist/{chunk-5BVAUUWL.js → chunk-X37NTEVS.js} +2 -2
  154. package/dist/{chunk-WW3F7DCX.js → chunk-Z2WZDVGG.js} +2 -2
  155. package/dist/{chunk-EXVCVXFX.js → chunk-ZH6NYB6Y.js} +3 -3
  156. package/dist/data-display/Alert.js +3 -3
  157. package/dist/data-display/Avatar.js +4 -4
  158. package/dist/data-display/CardKit.js +11 -11
  159. package/dist/data-display/Carousel.js +6 -5
  160. package/dist/data-display/Chart.js +11 -11
  161. package/dist/data-display/DataGrid.js +2 -2
  162. package/dist/data-display/DataViews.js +60 -35
  163. package/dist/data-display/DayRuler.js +3 -3
  164. package/dist/data-display/FleetMap.js +9 -9
  165. package/dist/data-display/MapPreview.js +7 -6
  166. package/dist/en-US.js +1 -1
  167. package/dist/feedback/NotificationStatusNotice.js +4 -4
  168. package/dist/feedback/SequenceResolver.js +6 -6
  169. package/dist/form/Calendar.js +5 -5
  170. package/dist/form/DateRangePicker.js +10 -10
  171. package/dist/locales.js +5 -5
  172. package/dist/pt-BR.js +1 -1
  173. package/dist/types/components/data-display/DataViews/data-views-bar-controls.d.ts +15 -1
  174. package/dist/types/components/data-display/DataViews/data-views-bar-controls.d.ts.map +1 -1
  175. package/dist/types/components/data-display/DataViews/data-views-copy.d.ts +35 -0
  176. package/dist/types/components/data-display/DataViews/data-views-copy.d.ts.map +1 -1
  177. package/dist/types/components/data-display/DataViews/data-views-day-input.d.ts +7 -1
  178. package/dist/types/components/data-display/DataViews/data-views-day-input.d.ts.map +1 -1
  179. package/dist/types/components/data-display/DataViews/data-views-more-fields.d.ts.map +1 -1
  180. package/dist/types/components/data-display/DataViews/data-views-more-filters.d.ts +5 -3
  181. package/dist/types/components/data-display/DataViews/data-views-more-filters.d.ts.map +1 -1
  182. package/dist/types/components/data-display/DataViews/data-views-number-input.d.ts +10 -2
  183. package/dist/types/components/data-display/DataViews/data-views-number-input.d.ts.map +1 -1
  184. package/dist/types/components/data-display/DataViews/data-views-preset-chips.d.ts +10 -0
  185. package/dist/types/components/data-display/DataViews/data-views-preset-chips.d.ts.map +1 -1
  186. package/dist/types/components/data-display/DataViews/data-views-range-bounds.d.ts +35 -0
  187. package/dist/types/components/data-display/DataViews/data-views-range-bounds.d.ts.map +1 -0
  188. package/dist/types/components/data-display/DataViews/data-views-range-calendar.d.ts +35 -0
  189. package/dist/types/components/data-display/DataViews/data-views-range-calendar.d.ts.map +1 -0
  190. package/dist/types/components/data-display/DataViews/data-views-range-pill.d.ts +2 -11
  191. package/dist/types/components/data-display/DataViews/data-views-range-pill.d.ts.map +1 -1
  192. package/dist/types/components/data-display/DataViews/data-views-range-summary.d.ts +21 -0
  193. package/dist/types/components/data-display/DataViews/data-views-range-summary.d.ts.map +1 -0
  194. package/dist/types/components/data-display/DataViews/data-views-still-anchor.d.ts +45 -0
  195. package/dist/types/components/data-display/DataViews/data-views-still-anchor.d.ts.map +1 -0
  196. package/dist/types/components/data-display/DayRuler/DayRuler.styles.d.ts +6 -1
  197. package/dist/types/components/data-display/DayRuler/DayRuler.styles.d.ts.map +1 -1
  198. package/dist/types/components/data-display/LazyImage/LazyImage.hooks.d.ts +1 -1
  199. package/dist/types/components/form/Calendar/Calendar.d.ts.map +1 -1
  200. package/dist/types/components/form/Calendar/CalendarDay.d.ts +2 -0
  201. package/dist/types/components/form/Calendar/CalendarDay.d.ts.map +1 -1
  202. package/dist/types/components/form/Calendar/CalendarDayCell.d.ts +2 -0
  203. package/dist/types/components/form/Calendar/CalendarDayCell.d.ts.map +1 -1
  204. package/dist/types/components/form/Calendar/CalendarMonth.d.ts +5 -0
  205. package/dist/types/components/form/Calendar/CalendarMonth.d.ts.map +1 -1
  206. package/dist/types/en-US.data-display.d.ts.map +1 -1
  207. package/dist/types/pt-BR.data-display.d.ts.map +1 -1
  208. package/dist/user-avatar.js +5 -5
  209. package/package.json +1 -1
  210. package/src/components/data-display/DataViews/RESPONSIVE-BEHAVIOUR.md +59 -0
  211. package/src/components/data-display/DataViews/data-views-bar-controls.tsx +56 -1
  212. package/src/components/data-display/DataViews/data-views-copy.ts +36 -0
  213. package/src/components/data-display/DataViews/data-views-day-input.tsx +9 -1
  214. package/src/components/data-display/DataViews/data-views-inline-bar.tsx +5 -3
  215. package/src/components/data-display/DataViews/data-views-more-fields.tsx +1 -0
  216. package/src/components/data-display/DataViews/data-views-more-filters.tsx +82 -29
  217. package/src/components/data-display/DataViews/data-views-number-input.tsx +19 -9
  218. package/src/components/data-display/DataViews/data-views-preset-chips.tsx +165 -16
  219. package/src/components/data-display/DataViews/data-views-range-bounds.tsx +223 -0
  220. package/src/components/data-display/DataViews/data-views-range-calendar.tsx +185 -0
  221. package/src/components/data-display/DataViews/data-views-range-pill.tsx +71 -154
  222. package/src/components/data-display/DataViews/data-views-range-summary.tsx +66 -0
  223. package/src/components/data-display/DataViews/data-views-still-anchor.ts +93 -0
  224. package/src/components/data-display/DayRuler/DayRuler.styles.ts +29 -16
  225. package/src/components/form/Calendar/Calendar.md +17 -2
  226. package/src/components/form/Calendar/Calendar.tsx +56 -3
  227. package/src/components/form/Calendar/CalendarDay.tsx +33 -3
  228. package/src/components/form/Calendar/CalendarDayCell.tsx +4 -0
  229. package/src/components/form/Calendar/CalendarMonth.tsx +27 -5
  230. package/src/en-US.data-display.ts +12 -0
  231. package/src/pt-BR.data-display.ts +12 -0
  232. package/dist/chunk-5KK3I42O.js.map +0 -1
  233. package/dist/chunk-5RSK5M6M.js.map +0 -1
  234. package/dist/chunk-7D7CJRL7.js +0 -78
  235. package/dist/chunk-7D7CJRL7.js.map +0 -1
  236. package/dist/chunk-BO6MT2S2.js.map +0 -1
  237. package/dist/chunk-EOJSA2EK.js.map +0 -1
  238. package/dist/chunk-FEKWKWGK.js.map +0 -1
  239. package/dist/chunk-FJ3UZ4RC.js.map +0 -1
  240. package/dist/chunk-OBA75Y5O.js.map +0 -1
  241. package/dist/chunk-Q2ERGAQO.js.map +0 -1
  242. package/dist/chunk-QLJU7UUI.js.map +0 -1
  243. package/dist/chunk-TRYR424I.js.map +0 -1
  244. package/dist/chunk-X5OGIT2F.js.map +0 -1
  245. package/dist/chunk-XHIBFBNP.js.map +0 -1
  246. package/dist/chunk-YDIC6LSP.js.map +0 -1
  247. /package/dist/{chunk-TYXFFNPM.js.map → chunk-3OTGREQG.js.map} +0 -0
  248. /package/dist/{chunk-BEHT4IHH.js.map → chunk-3X2MA47R.js.map} +0 -0
  249. /package/dist/{chunk-6WHIJPEF.js.map → chunk-6PU5P7QT.js.map} +0 -0
  250. /package/dist/{chunk-JIEVKHOH.js.map → chunk-7YJYIMWP.js.map} +0 -0
  251. /package/dist/{chunk-YNZUYZ2O.js.map → chunk-A3DDEKLV.js.map} +0 -0
  252. /package/dist/{chunk-KHREN7Y7.js.map → chunk-ACM3HHZY.js.map} +0 -0
  253. /package/dist/{chunk-DYHOBKPU.js.map → chunk-BLZDSCIZ.js.map} +0 -0
  254. /package/dist/{chunk-E2UOEI7N.js.map → chunk-BV2LOTMC.js.map} +0 -0
  255. /package/dist/{chunk-O63ZROSY.js.map → chunk-BZBLPXV7.js.map} +0 -0
  256. /package/dist/{chunk-OKRITX4S.js.map → chunk-CJ6XXM4X.js.map} +0 -0
  257. /package/dist/{chunk-LV6AD6XC.js.map → chunk-DBI6AMNY.js.map} +0 -0
  258. /package/dist/{chunk-QRRWLLXW.js.map → chunk-DSBC6O46.js.map} +0 -0
  259. /package/dist/{chunk-3YFDGFEK.js.map → chunk-DVX4HDNP.js.map} +0 -0
  260. /package/dist/{chunk-CJUK32UH.js.map → chunk-EEO7M5GU.js.map} +0 -0
  261. /package/dist/{chunk-7XSCEHGA.js.map → chunk-EOQ6EKTS.js.map} +0 -0
  262. /package/dist/{chunk-AMLHEKSV.js.map → chunk-HI7JPDD6.js.map} +0 -0
  263. /package/dist/{chunk-2H6SCVLD.js.map → chunk-HMEGQKNQ.js.map} +0 -0
  264. /package/dist/{chunk-7QKIL5YF.js.map → chunk-J2GDA64N.js.map} +0 -0
  265. /package/dist/{chunk-BAQ3ITZV.js.map → chunk-JFD742C3.js.map} +0 -0
  266. /package/dist/{chunk-HQCZT6TO.js.map → chunk-JVOEVTCZ.js.map} +0 -0
  267. /package/dist/{chunk-WAO7UQRS.js.map → chunk-KANCE4MS.js.map} +0 -0
  268. /package/dist/{chunk-XLU5WFSY.js.map → chunk-KRBPWTXW.js.map} +0 -0
  269. /package/dist/{chunk-S6D7NOV7.js.map → chunk-L6JAALMX.js.map} +0 -0
  270. /package/dist/{chunk-BECKKDYG.js.map → chunk-M2M4IDFU.js.map} +0 -0
  271. /package/dist/{chunk-CSGBHYW6.js.map → chunk-M5Y42AZ4.js.map} +0 -0
  272. /package/dist/{chunk-5CP5Z3YU.js.map → chunk-MPWA55CF.js.map} +0 -0
  273. /package/dist/{chunk-RCTHCXS6.js.map → chunk-PJNIJIE6.js.map} +0 -0
  274. /package/dist/{chunk-6ATXOJVQ.js.map → chunk-QADTI63U.js.map} +0 -0
  275. /package/dist/{chunk-MW7P2C2C.js.map → chunk-QAEO52Z4.js.map} +0 -0
  276. /package/dist/{chunk-5S5K73I6.js.map → chunk-QSOCOXVL.js.map} +0 -0
  277. /package/dist/{chunk-NQCTANF3.js.map → chunk-QVDEGBME.js.map} +0 -0
  278. /package/dist/{chunk-BQBEN44R.js.map → chunk-RDCIST7P.js.map} +0 -0
  279. /package/dist/{chunk-HUXAIQC5.js.map → chunk-RZ3P4X2I.js.map} +0 -0
  280. /package/dist/{chunk-WJMSND5Q.js.map → chunk-SCXVTNLE.js.map} +0 -0
  281. /package/dist/{chunk-K6FCSB6T.js.map → chunk-SK2CTB3O.js.map} +0 -0
  282. /package/dist/{chunk-U2ILXZDG.js.map → chunk-TB5CRHTF.js.map} +0 -0
  283. /package/dist/{chunk-SB2SEGR6.js.map → chunk-TIM4PXWN.js.map} +0 -0
  284. /package/dist/{chunk-6D5AMANO.js.map → chunk-WH3LUOCQ.js.map} +0 -0
  285. /package/dist/{chunk-OWRQOYUE.js.map → chunk-WWR6APJR.js.map} +0 -0
  286. /package/dist/{chunk-5BVAUUWL.js.map → chunk-X37NTEVS.js.map} +0 -0
  287. /package/dist/{chunk-WW3F7DCX.js.map → chunk-Z2WZDVGG.js.map} +0 -0
  288. /package/dist/{chunk-EXVCVXFX.js.map → chunk-ZH6NYB6Y.js.map} +0 -0
@@ -1,4 +1,5 @@
1
1
  import type { CategorySelectCopy, ConfirmActionCopy, DataGridCopy, TableFilterCopy } from "../../../copy";
2
+ import type { CalendarLabels } from "../../../copy/labels";
2
3
  import type { SavedViewsLabels } from "../../layout/ContentToolbar/ContentToolbar.types";
3
4
  /**
4
5
  * Every word the DataViews family renders, as REQUIRED host config (FUT-760).
@@ -180,6 +181,24 @@ export interface DataViewsGridCopy extends DataGridCopy {
180
181
  sortDescending: string;
181
182
  }
182
183
 
184
+ /**
185
+ * The words of the range calendar a day filter shows under its typed boxes.
186
+ * Month names, weekday initials and each day's spoken name come from `Intl` in
187
+ * `locale`; only the sentences below are copy.
188
+ */
189
+ export interface DataViewsDayCalendarCopy {
190
+ /** BCP-47 tag the calendar names its months and days in. */
191
+ locale: string;
192
+ /** The calendar's accessible name, from the filter's own label ("Data"). */
193
+ label(fieldLabel: string): string;
194
+ /** Under the calendar while no day, or a whole period, is chosen. */
195
+ pickStart: string;
196
+ /** Under the calendar once the first day is chosen and the last is not. */
197
+ pickEnd: string;
198
+ /** The month/year caption's names — `UI_LABELS[locale].calendar`. */
199
+ caption: CalendarLabels;
200
+ }
201
+
183
202
  export interface DataViewsFiltersCopy {
184
203
  moreFilters(count: number): string;
185
204
  moreFiltersApplied(count: number, appliedCount: number): string;
@@ -212,8 +231,25 @@ export interface DataViewsFiltersCopy {
212
231
  * list read like an answer to a date nobody could have meant (FUT-4144).
213
232
  */
214
233
  dayInvalid: string;
234
+ /**
235
+ * The range calendar under a day range's `De`/`Até` boxes (FUT-4144). Optional
236
+ * so a host that builds its own copy keeps compiling; without it the calendar
237
+ * speaks the en-US pack's words.
238
+ */
239
+ dayCalendar?: DataViewsDayCalendarCopy;
215
240
  /** Drop every applied filter, spelled out in the panel where there is room. */
216
241
  clearAllFilters: string;
242
+ /**
243
+ * The presets asked as a select, where the row is too narrow for them as
244
+ * one line of equal parts (ADR 0190, FUT-4144). Optional: a host copy
245
+ * without it gets the en-US pack's words.
246
+ */
247
+ presetSelect?: {
248
+ /** The select's label. */
249
+ label: string;
250
+ /** The empty option: no preset — picking it clears an applied one. */
251
+ none: string;
252
+ };
217
253
  /** The day-range presets' labels, keyed by preset id. */
218
254
  rangePresets: Readonly<Record<string, string>>;
219
255
  scopesLabel: string;
@@ -239,6 +239,12 @@ interface DayBoundInputProps {
239
239
  * impossible day is still never written, and blur still snaps back.
240
240
  */
241
241
  invalidMessage?: string;
242
+ /**
243
+ * Take the width of the box it sits in rather than its own 165px. Set where
244
+ * the pair stands over the range calendar, so the two boxes span the
245
+ * calendar's width instead of leaving a gap beside them (FUT-4144).
246
+ */
247
+ fill?: boolean;
242
248
  }
243
249
 
244
250
  /** What {@link useDayText} hands the field: its text, its verdict and its handlers. */
@@ -326,6 +332,7 @@ export function DayBoundInput({
326
332
  describedBy,
327
333
  mask,
328
334
  invalidMessage,
335
+ fill = false,
329
336
  }: DayBoundInputProps): React.JSX.Element {
330
337
  const id = useId();
331
338
  const { text, impossible, handleChange, handlePaste, handleBlur } = useDayText(
@@ -351,7 +358,8 @@ export function DayBoundInput({
351
358
  // The placeholder occupies the space an un-shrunk label would render into.
352
359
  InputLabelProps={{ shrink: true }}
353
360
  inputProps={dayInputProps(testId, [impossible ? `${id}-helper-text` : undefined, describedBy])}
354
- sx={[{ width: sxRem(165) }, fieldTextFieldStyles]}
361
+ fullWidth={fill}
362
+ sx={[{ width: fill ? '100%' : sxRem(165) }, fieldTextFieldStyles]}
355
363
  />
356
364
  );
357
365
  }
@@ -19,7 +19,7 @@ import Box from "@mui/material/Box/index.js";
19
19
  import { useState } from "react";
20
20
 
21
21
 
22
- import { ClearAllControl, CloseSearchControl } from "./data-views-bar-controls";
22
+ import { ClearAllControl, CloseSearchControl, useBarFrozen } from "./data-views-bar-controls";
23
23
  import type { GridFilterPanelProps } from "./data-views-filter-panel";
24
24
  import { MoreFilters } from "./data-views-more-filters";
25
25
  import type { OverflowField, OverflowSplit } from "./data-views-overflow";
@@ -324,13 +324,14 @@ function FilterSlots<T extends Record<string, unknown>>({
324
324
  clearAllHidden: boolean;
325
325
  testIdPrefix: string;
326
326
  }): React.JSX.Element {
327
+ const clear = useBarFrozen(onControlOpenChange);
327
328
  return (
328
329
  <>
329
330
  {inline.map((field) => (
330
331
  <InlineControl
331
332
  key={field.id}
332
333
  field={field}
333
- onOpenChange={onControlOpenChange}
334
+ onOpenChange={clear.onOpenChange}
334
335
  pills={pills}
335
336
  ranges={ranges}
336
337
  onTogglePill={onTogglePill}
@@ -342,7 +343,7 @@ function FilterSlots<T extends Record<string, unknown>>({
342
343
  ))}
343
344
  <MoreFilters
344
345
  clearKey={clearKey}
345
- onOpenChange={onControlOpenChange}
346
+ onOpenChange={clear.onOpenChange}
346
347
  onClearAll={onClearAll}
347
348
  anyApplied={activeFilterCount > 0}
348
349
  compact={compactControls}
@@ -358,6 +359,7 @@ function FilterSlots<T extends Record<string, unknown>>({
358
359
  <ClearAllControl
359
360
  onClearAll={onClearAll}
360
361
  compact={compactControls}
362
+ frozen={clear.frozen}
361
363
  testIdPrefix={testIdPrefix}
362
364
  />
363
365
  )}
@@ -185,6 +185,7 @@ function OverflowRange<T extends Record<string, unknown>>({
185
185
  value={value}
186
186
  onChange={onChange}
187
187
  testId={`${testIdPrefix}-more-${field.id}`}
188
+ fillRow
188
189
  />
189
190
  );
190
191
  }
@@ -8,8 +8,9 @@ import KeyboardArrowDownRoundedIcon from "@mui/icons-material/KeyboardArrowDownR
8
8
  // which. On a phone, where both are icon-only, they were indistinguishable.
9
9
  import FilterAltRoundedIcon from "@mui/icons-material/FilterAltRounded";
10
10
  import Popover from "@mui/material/Popover/index.js";
11
- import type { Theme } from "@mui/material/styles/index.js";
12
- import { useState } from "react";
11
+ import { useTheme, type Theme } from "@mui/material/styles/index.js";
12
+ import useMediaQuery from "@mui/material/useMediaQuery/index.js";
13
+
13
14
 
14
15
  import { useDataViewsCopy } from "./data-views-copy-context";
15
16
  import { Button } from "../../form/Button";
@@ -17,8 +18,9 @@ import { Box } from "../../../mui/Box";
17
18
  import { Text } from "../../typography/Text";
18
19
 
19
20
  import { fieldClearing, MoreGroup, MoreQuick, type MoreFieldProps } from "./data-views-more-fields";
21
+ import { useStillAnchor } from "./data-views-still-anchor";
20
22
  import type { OverflowField } from "./data-views-overflow";
21
- import { rem, sxRem } from "../../../tokens/relative";
23
+ import { rem, remPx, sxRem } from "../../../tokens/relative";
22
24
 
23
25
  /**
24
26
  * "MAIS" — the filter overflow: its trigger, its panel and its footer. What
@@ -151,18 +153,32 @@ function MoreHeading(): React.JSX.Element {
151
153
  function MoreFooter({
152
154
  onClearAll,
153
155
  testIdPrefix,
156
+ reserved = false,
154
157
  }: {
155
158
  onClearAll: () => void;
156
159
  testIdPrefix: string;
160
+ /**
161
+ * Hold the footer's height with nothing in it. A panel holding a day range
162
+ * keeps the row while nothing is applied, so the first tap on its calendar
163
+ * does not grow the panel by a row and move its top under the finger
164
+ * (FUT-4144 UI review).
165
+ */
166
+ reserved?: boolean;
157
167
  }): React.JSX.Element {
158
168
  const copy = useDataViewsCopy();
159
169
  return (
160
- <Box sx={{ px: 1.5, py: 1, borderTop: 1, borderColor: "divider" }}>
170
+ <Box
171
+ aria-hidden={reserved || undefined}
172
+ // Held, the row is blank — no rule over it either, or it reads as an
173
+ // empty bordered row.
174
+ sx={{ px: 1.5, py: 1, borderTop: 1, borderColor: reserved ? "transparent" : "divider", visibility: reserved ? "hidden" : undefined }}
175
+ >
161
176
  <Box
162
177
  component="button"
163
178
  type="button"
164
- onClick={onClearAll}
165
- data-testid={`${testIdPrefix}-more-clear-all`}
179
+ onClick={reserved ? undefined : onClearAll}
180
+ tabIndex={reserved ? -1 : undefined}
181
+ data-testid={reserved ? undefined : `${testIdPrefix}-more-clear-all`}
166
182
  sx={{
167
183
  width: "100%",
168
184
  border: 0,
@@ -200,16 +216,39 @@ function MoreFields<T extends Record<string, unknown>>({
200
216
  );
201
217
  }
202
218
 
203
- /** The overflow trigger + panel. Renders nothing when everything fits. */
204
- export function MoreFilters<T extends Record<string, unknown>>({
205
- fields,
206
- onOpenChange,
207
- onClearAll,
208
- anyApplied,
209
- compact = false,
210
- clearKey,
211
- ...rest
212
- }: MoreFiltersProps<T> & {
219
+ /**
220
+ * The panel is a column: heading, the fields' scroller, footer. Its height is
221
+ * the screen's, not a fixed 320px — at 390×844 that cap scrolled a day range's
222
+ * month caption and weekday row out of view after the first tap, and a typed
223
+ * day's refusal out of sight of its box (FUT-4144 UI review). MUI moves the
224
+ * panel up when it is taller than the room under its trigger.
225
+ */
226
+ const COLUMN_SX = { display: "flex", flexDirection: "column" } as const;
227
+
228
+ /**
229
+ * 320, not 300: inside 12px of padding a day range's month then has the 280px
230
+ * its seven 40px columns need and its month/year caption one row (FUT-4144).
231
+ */
232
+ const PAPER_SX = (theme: Theme) => ({
233
+ ...COLUMN_SX,
234
+ width: rem(theme, 320),
235
+ maxWidth: `calc(100vw - ${rem(theme, 32)})`,
236
+ });
237
+
238
+ /**
239
+ * Below `sm` the panel takes the screen's width less 8px each side, so a day
240
+ * range's calendar gets the 280px its seven 40px columns need (it had 264 at
241
+ * 320 and 276 at 390, so every day was a 34-36px target).
242
+ */
243
+ const PHONE_PAPER_SX = (theme: Theme) => ({
244
+ ...COLUMN_SX,
245
+ width: `calc(100vw - ${rem(theme, 16)})`,
246
+ maxWidth: `calc(100vw - ${rem(theme, 16)})`,
247
+ maxHeight: `calc(100% - ${rem(theme, 16)})`,
248
+ });
249
+
250
+ /** Props of {@link MoreFilters}. */
251
+ interface MoreFiltersPanelProps<T extends Record<string, unknown>> extends MoreFiltersProps<T> {
213
252
  /** Changes on every clear-all; the fields here are keyed on it (FUT-4144). */
214
253
  clearKey?: number;
215
254
  /** Icon only — the same rung that strips Exibir/Exportar. */
@@ -227,9 +266,23 @@ export function MoreFilters<T extends Record<string, unknown>>({
227
266
  * got as far as "1" and then had nowhere to go.
228
267
  */
229
268
  onOpenChange?: (open: boolean) => void;
230
- }): React.JSX.Element | null {
231
- const [anchor, setAnchor] = useState<HTMLElement | null>(null);
269
+ }
270
+
271
+ /** The overflow trigger + panel. Renders nothing when everything fits. */
272
+ export function MoreFilters<T extends Record<string, unknown>>({
273
+ fields,
274
+ onOpenChange,
275
+ onClearAll,
276
+ anyApplied,
277
+ compact = false,
278
+ clearKey,
279
+ ...rest
280
+ }: MoreFiltersPanelProps<T>): React.JSX.Element | null {
281
+ const still = useStillAnchor();
282
+ const theme = useTheme();
283
+ const phone = useMediaQuery(theme.breakpoints.down("sm"));
232
284
  if (fields.length === 0) return null;
285
+ const holdsDayRange = fields.some((field) => field.range?.kind === "day");
233
286
  return (
234
287
  <>
235
288
  <MoreTrigger
@@ -248,32 +301,32 @@ export function MoreFilters<T extends Record<string, unknown>>({
248
301
  }
249
302
  compact={compact}
250
303
  onOpen={(element) => {
251
- setAnchor(element);
304
+ still.open(element);
252
305
  onOpenChange?.(true);
253
306
  }}
254
307
  testIdPrefix={rest.testIdPrefix}
255
308
  />
256
309
  <Popover
257
- open={Boolean(anchor)}
258
- anchorEl={anchor}
310
+ {...still.popoverProps}
259
311
  onClose={() => {
260
- setAnchor(null);
312
+ still.close();
261
313
  onOpenChange?.(false);
262
314
  }}
263
- anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
264
- slotProps={{ paper: { sx: { width: sxRem(300), maxWidth: (theme: Theme) => `calc(100vw - ${rem(theme, 32)})` } } }}
315
+ // Below `sm`, 8px from the screen's edges instead of 16.
316
+ marginThreshold={phone ? remPx(theme, 8) : undefined}
317
+ slotProps={{ paper: { ref: still.paperRef, sx: phone ? PHONE_PAPER_SX : PAPER_SX } }}
265
318
  >
266
- <Box data-testid={`${rest.testIdPrefix}-more-panel`}>
319
+ <Box data-testid={`${rest.testIdPrefix}-more-panel`} sx={{ ...COLUMN_SX, flex: "1 1 auto", minHeight: 0 }}>
267
320
  <MoreHeading />
268
- {/* overflowX hidden, not auto: this panel is a fixed 300px and its
321
+ {/* overflowX hidden, not auto: this panel is a fixed width and its
269
322
  contents are told to shrink into it. A horizontal scrollbar here
270
323
  means something refused to, which is a bug to fix rather than a
271
324
  scrollbar to live with. */}
272
- <Box sx={{ maxHeight: sxRem(320), overflowY: "auto", overflowX: "hidden", p: 1.5, minWidth: 0 }}>
325
+ <Box sx={{ flex: "1 1 auto", minHeight: 0, overflowY: "auto", overflowX: "hidden", p: { xs: 1, sm: 1.5 }, minWidth: 0 }}>
273
326
  <MoreFields key={clearKey} fields={fields} {...rest} />
274
327
  </Box>
275
- {anyApplied && (
276
- <MoreFooter onClearAll={onClearAll} testIdPrefix={rest.testIdPrefix} />
328
+ {(anyApplied || holdsDayRange) && (
329
+ <MoreFooter onClearAll={onClearAll} testIdPrefix={rest.testIdPrefix} reserved={!anyApplied} />
277
330
  )}
278
331
  </Box>
279
332
  </Popover>
@@ -91,13 +91,8 @@ function boundAsNumber(amount: number | string | undefined): number | undefined
91
91
  * One end of a numeric range. The BOUND stays a plain `number` — nothing
92
92
  * downstream learns that the typing surface changed.
93
93
  */
94
- export function NumberBoundInput({
95
- label,
96
- value,
97
- unit,
98
- onChange,
99
- testId,
100
- }: {
94
+ /** Props of {@link NumberBoundInput}. */
95
+ interface NumberBoundInputProps {
101
96
  label: string;
102
97
  /** The applied bound. A range restored from the URL hands this over as a string. */
103
98
  value: number | string | undefined;
@@ -105,7 +100,21 @@ export function NumberBoundInput({
105
100
  unit?: string;
106
101
  onChange: (bound: number | undefined) => void;
107
102
  testId: string;
108
- }): React.JSX.Element {
103
+ /**
104
+ * Take the width of the cell it sits in rather than its own 140px, so a
105
+ * pair in a panel splits the row equally (FUT-4144 UI review round 2).
106
+ */
107
+ fill?: boolean;
108
+ }
109
+
110
+ export function NumberBoundInput({
111
+ label,
112
+ value,
113
+ unit,
114
+ onChange,
115
+ testId,
116
+ fill = false,
117
+ }: NumberBoundInputProps): React.JSX.Element {
109
118
  const applied = boundAsNumber(value);
110
119
  const [text, setText] = useState(() => formatPtBrNumber(value));
111
120
 
@@ -164,7 +173,8 @@ export function NumberBoundInput({
164
173
  }
165
174
  : undefined
166
175
  }
167
- sx={[{ width: sxRem(140) }, fieldTextFieldStyles]}
176
+ fullWidth={fill}
177
+ sx={[{ width: fill ? '100%' : sxRem(140) }, fieldTextFieldStyles]}
168
178
  />
169
179
  );
170
180
  }
@@ -11,9 +11,20 @@
11
11
  * Clicking an active preset CLEARS it. A chip that reads as pressed and does
12
12
  * nothing when pressed again is a dead control, and the alternative — hunting
13
13
  * for the pill's ✕ — is the gesture this row exists to remove.
14
+ *
15
+ * ONE LINE at every width (ADR 0190 in the host, FUT-4144): the presets are
16
+ * the options of one question, and as wrapping chips "Este ano" fell onto a
17
+ * second line at 320, 390 and 600, where it read as a second question. Where
18
+ * the row is wide enough they are a segmented control of equal parts; where it
19
+ * is not, the same question is a select.
14
20
  */
15
21
  import Box from "@mui/material/Box/index.js";
22
+ import TextField from "@mui/material/TextField/index.js";
23
+ import { useTheme } from "@mui/material/styles/index.js";
24
+ import React, { useLayoutEffect, useRef, useState, type RefObject } from "react";
16
25
 
26
+ import { EN_US_DATA_VIEWS_COPY } from "../../../en-US.data-display";
27
+ import { useDataViewsCopy } from "./data-views-copy-context";
17
28
  import { isPresetActive, resolvePreset } from "./data-views-range-presets";
18
29
  import type { RangePreset, RangeValue } from "./data-views-types";
19
30
  import { sxRem } from "../../../tokens/relative";
@@ -51,6 +62,9 @@ function PresetChip({
51
62
  fontSize: sxRem(12),
52
63
  fontWeight: 600,
53
64
  whiteSpace: "nowrap",
65
+ overflow: "hidden",
66
+ textOverflow: "ellipsis",
67
+ minWidth: 0,
54
68
  "&:hover": { borderColor: active ? "primary.main" : "text.primary" },
55
69
  }}
56
70
  >
@@ -59,6 +73,115 @@ function PresetChip({
59
73
  );
60
74
  }
61
75
 
76
+ /** The chip look, for the hidden row that measures each label at its natural width. */
77
+ const MEASURE_SX = {
78
+ display: "inline-block",
79
+ px: 1.25,
80
+ border: 1,
81
+ font: "inherit",
82
+ fontSize: sxRem(12),
83
+ fontWeight: 600,
84
+ whiteSpace: "nowrap",
85
+ } as const;
86
+
87
+ /**
88
+ * Whether `count` equal parts, each as wide as the widest label, fit `width`
89
+ * with `gap` between them. Unmeasured (`null`: the server, jsdom) counts as
90
+ * fitting, so the row renders the buttons it always rendered.
91
+ */
92
+ export function presetsFitOneLine(width: number | null, widest: number, count: number, gap: number): boolean {
93
+ if (width === null) return true;
94
+ return widest * count + gap * (count - 1) <= width;
95
+ }
96
+
97
+ /** The element's own width as it changes; `null` until measured, or where nothing can measure. */
98
+ function useElementWidth(ref: RefObject<HTMLElement | null>): number | null {
99
+ const [width, setWidth] = useState<number | null>(null);
100
+ useLayoutEffect(() => {
101
+ const element = ref.current;
102
+ if (element === null || typeof ResizeObserver === "undefined") return undefined;
103
+ const observer = new ResizeObserver((entries) => {
104
+ const measured = entries[0]?.contentRect.width;
105
+ if (measured !== undefined && measured > 0) setWidth(measured);
106
+ });
107
+ observer.observe(element);
108
+ return () => observer.disconnect();
109
+ }, [ref]);
110
+ return width;
111
+ }
112
+
113
+ /**
114
+ * The widest label at the chip's own type, padding and border, read off the
115
+ * hidden measuring row.
116
+ *
117
+ * `offsetWidth`, the LAYOUT width, never the bounding box: a popover grows in
118
+ * from 75% scale, and a box read during that transition is a quarter short —
119
+ * which judged "Acima de R$ 10" to fit a third of the "Mais" panel and cut it
120
+ * to "Acima de …" (FUT-4144 UI review round 2). Measured again when the row's
121
+ * width changes and once the web fonts have loaded, since a fallback face is
122
+ * narrower than the one the parts will be drawn in.
123
+ */
124
+ function useWidestLabel(ref: RefObject<HTMLElement | null>, labels: string, width: number | null): number {
125
+ const [widest, setWidest] = useState(0);
126
+ useLayoutEffect(() => {
127
+ const measure = (): void => {
128
+ const spans = ref.current?.querySelectorAll<HTMLElement>("[data-preset-measure]") ?? [];
129
+ // +1: `offsetWidth` rounds, so a label laid out at 80.4px reads 80 and
130
+ // would be judged to fit half a pixel short, behind an ellipsis.
131
+ setWidest(Math.max(0, ...Array.from(spans, (span) => span.offsetWidth + 1)));
132
+ };
133
+ measure();
134
+ let live = true;
135
+ void document.fonts?.ready.then(() => {
136
+ if (live) measure();
137
+ });
138
+ return () => {
139
+ live = false;
140
+ };
141
+ }, [ref, labels, width]);
142
+ return widest;
143
+ }
144
+
145
+ /** The same question as a select, for a row too narrow for its parts. */
146
+ function PresetSelect({
147
+ presets,
148
+ value,
149
+ onChange,
150
+ testId,
151
+ }: {
152
+ presets: RangePreset[];
153
+ value: RangeValue;
154
+ onChange: (range: RangeValue) => void;
155
+ testId: string;
156
+ }): React.JSX.Element {
157
+ const copy = useDataViewsCopy().filters.presetSelect ?? EN_US_DATA_VIEWS_COPY.filters.presetSelect;
158
+ const active = presets.find((preset) => isPresetActive(preset, value))?.id ?? "";
159
+ return (
160
+ <TextField
161
+ select
162
+ size="small"
163
+ fullWidth
164
+ label={copy?.label}
165
+ value={active}
166
+ onChange={(event) => {
167
+ const picked = presets.find((preset) => preset.id === event.target.value);
168
+ // "None" is the select's way of tapping the active chip again.
169
+ onChange(picked ? resolvePreset(picked) : {});
170
+ }}
171
+ SelectProps={{ native: true }}
172
+ InputLabelProps={{ shrink: true }}
173
+ inputProps={{ "data-testid": `${testId}-presets-select` }}
174
+ >
175
+ <option value="">{copy?.none}</option>
176
+ {presets.map((preset) => (
177
+ <option key={preset.id} value={preset.id}>
178
+ {preset.label}
179
+ </option>
180
+ ))}
181
+ </TextField>
182
+ );
183
+ }
184
+
62
185
  /**
63
186
  * The preset row. Renders nothing when a field declares none, so a numeric
64
187
  * range without host-configured windows keeps the popover it had.
@@ -66,6 +189,9 @@ function PresetChip({
66
189
  * Carries no outer margin — the three surfaces that host it (the pill's
67
190
  * popover, the slide-in panel, the "Mais" overflow) each sit it in a different
68
191
  * stack, and a baked-in margin would be wrong in two of them.
192
+ *
193
+ * What is measured is the row's OWN width, not the window's: the same row
194
+ * lives in a 670px popover, a 300px panel and a phone-wide sheet.
69
195
  */
70
196
  export function RangePresets({
71
197
  presets,
@@ -78,24 +204,47 @@ export function RangePresets({
78
204
  onChange: (range: RangeValue) => void;
79
205
  testId: string;
80
206
  }): React.JSX.Element | null {
207
+ const theme = useTheme();
208
+ const box = useRef<HTMLDivElement>(null);
209
+ const width = useElementWidth(box);
210
+ const widest = useWidestLabel(box, presets.map((preset) => preset.label).join("|"), width);
81
211
  if (presets.length === 0) return null;
212
+ const fits = presetsFitOneLine(width, widest, presets.length, parseFloat(theme.spacing(0.75)));
82
213
  return (
83
- <Box
84
- data-testid={`${testId}-presets`}
85
- sx={{ display: "flex", flexWrap: "wrap", gap: 0.75 }}
86
- >
87
- {presets.map((preset) => {
88
- const active = isPresetActive(preset, value);
89
- return (
90
- <PresetChip
91
- key={preset.id}
92
- preset={preset}
93
- active={active}
94
- onSelect={() => onChange(active ? {} : resolvePreset(preset))}
95
- testId={`${testId}-preset-${preset.id}`}
96
- />
97
- );
98
- })}
214
+ <Box ref={box} sx={{ position: "relative", minWidth: 0 }}>
215
+ <Box
216
+ aria-hidden="true"
217
+ sx={{ position: "absolute", top: 0, left: 0, width: "max-content", height: 0, overflow: "hidden", visibility: "hidden" }}
218
+ >
219
+ {presets.map((preset) => (
220
+ <Box key={preset.id} component="span" data-preset-measure="" sx={MEASURE_SX}>
221
+ {preset.label}
222
+ </Box>
223
+ ))}
224
+ </Box>
225
+ {fits ? (
226
+ <Box
227
+ data-testid={`${testId}-presets`}
228
+ sx={{ display: "grid", gridTemplateColumns: `repeat(${presets.length}, minmax(0, 1fr))`, gap: 0.75 }}
229
+ >
230
+ {presets.map((preset) => {
231
+ const active = isPresetActive(preset, value);
232
+ return (
233
+ <PresetChip
234
+ key={preset.id}
235
+ preset={preset}
236
+ active={active}
237
+ onSelect={() => onChange(active ? {} : resolvePreset(preset))}
238
+ testId={`${testId}-preset-${preset.id}`}
239
+ />
240
+ );
241
+ })}
242
+ </Box>
243
+ ) : (
244
+ <Box data-testid={`${testId}-presets`}>
245
+ <PresetSelect presets={presets} value={value} onChange={onChange} testId={testId} />
246
+ </Box>
247
+ )}
99
248
  </Box>
100
249
  );
101
250
  }