@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.
- package/components-catalog.md +1 -1
- package/dist/_internal/components/data-display/Alert/Alert.js +3 -3
- package/dist/_internal/components/data-display/Avatar/Avatar.js +4 -4
- package/dist/_internal/components/data-display/Avatar/Avatar.view.js +2 -2
- package/dist/_internal/components/data-display/CardKit/card-actions-context.js +4 -4
- package/dist/_internal/components/data-display/CardKit/use-remove-confirm.js +5 -5
- package/dist/_internal/components/data-display/Carousel/Carousel.chrome.js +4 -3
- package/dist/_internal/components/data-display/Carousel/Carousel.js +6 -5
- package/dist/_internal/components/data-display/Carousel/Carousel.parts.js +3 -2
- package/dist/_internal/components/data-display/Chart/Chart.js +3 -3
- package/dist/_internal/components/data-display/Chart/SpecChart.js +6 -6
- package/dist/_internal/components/data-display/Chart/chart-renderers.js +2 -2
- package/dist/_internal/components/data-display/Chart/chart-spec.js +2 -2
- package/dist/_internal/components/data-display/DataGrid/DataGrid.js +2 -2
- package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +48 -23
- package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +53 -28
- package/dist/_internal/components/data-display/DataViews/base-list-card-geometry.js +1 -1
- package/dist/_internal/components/data-display/DataViews/base-list-card-layout.js +1 -1
- package/dist/_internal/components/data-display/DataViews/base-list-card.js +3 -3
- package/dist/_internal/components/data-display/DataViews/data-views-bar-controls.js +5 -3
- package/dist/_internal/components/data-display/DataViews/data-views-day-input.js +1 -1
- package/dist/_internal/components/data-display/DataViews/data-views-filter-panel.js +31 -6
- package/dist/_internal/components/data-display/DataViews/data-views-grid-bodies.js +3 -3
- package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +47 -22
- package/dist/_internal/components/data-display/DataViews/data-views-inline-bar.js +37 -12
- package/dist/_internal/components/data-display/DataViews/data-views-more-fields.js +32 -7
- package/dist/_internal/components/data-display/DataViews/data-views-more-filters.js +33 -8
- package/dist/_internal/components/data-display/DataViews/data-views-number-input.js +1 -1
- package/dist/_internal/components/data-display/DataViews/data-views-preset-chips.js +10 -3
- package/dist/_internal/components/data-display/DataViews/data-views-range-bounds.js +47 -0
- package/dist/_internal/components/data-display/DataViews/data-views-range-bounds.js.map +1 -0
- package/dist/_internal/components/data-display/DataViews/data-views-range-calendar.js +36 -0
- package/dist/_internal/components/data-display/DataViews/data-views-range-calendar.js.map +1 -0
- package/dist/_internal/components/data-display/DataViews/data-views-range-pill.js +32 -6
- package/dist/_internal/components/data-display/DataViews/data-views-range-summary.js +12 -0
- package/dist/_internal/components/data-display/DataViews/data-views-range-summary.js.map +1 -0
- package/dist/_internal/components/data-display/DataViews/data-views-shell-toolbar.js +3 -3
- package/dist/_internal/components/data-display/DataViews/data-views-still-anchor.js +9 -0
- package/dist/_internal/components/data-display/DataViews/data-views-still-anchor.js.map +1 -0
- package/dist/_internal/components/data-display/DataViews/data-views-table-parts.js +4 -4
- package/dist/_internal/components/data-display/DataViews/data-views-toolbar.js +2 -2
- package/dist/_internal/components/data-display/DayRuler/DayRuler.js +3 -3
- package/dist/_internal/components/data-display/DayRuler/DayRuler.parts.js +2 -2
- package/dist/_internal/components/data-display/DayRuler/DayRuler.styles.js +3 -1
- package/dist/_internal/components/data-display/FleetMap/FleetBody.js +9 -8
- package/dist/_internal/components/data-display/FleetMap/FleetCanvas.js +8 -7
- package/dist/_internal/components/data-display/FleetMap/FleetMap.fixtures.js +2 -1
- package/dist/_internal/components/data-display/FleetMap/FleetMap.fixtures.js.map +1 -1
- package/dist/_internal/components/data-display/FleetMap/FleetMap.js +9 -9
- package/dist/_internal/components/data-display/MapPreview/MapControlBar.js +4 -3
- package/dist/_internal/components/data-display/MapPreview/MapLayers.js +5 -4
- package/dist/_internal/components/data-display/MapPreview/MapMarkers.js +4 -3
- package/dist/_internal/components/data-display/MapPreview/MapPreview.helpers.js +3 -2
- package/dist/_internal/components/data-display/MapPreview/MapPreview.js +7 -6
- package/dist/_internal/components/data-display/index.js +38 -38
- package/dist/_internal/components/feedback/NotificationStatusNotice/NotificationStatusNotice.js +4 -4
- package/dist/_internal/components/feedback/SequenceResolver/SequenceResolver.js +6 -6
- package/dist/_internal/components/feedback/SequenceResolver/SequenceResolver.overview.js +5 -5
- package/dist/_internal/components/feedback/SequenceResolver/SequenceResolver.parts.js +4 -4
- package/dist/_internal/components/feedback/index.js +7 -7
- package/dist/_internal/components/form/Calendar/Calendar.js +5 -5
- package/dist/_internal/components/form/Calendar/CalendarDay.js +1 -1
- package/dist/_internal/components/form/Calendar/CalendarDayCell.js +2 -2
- package/dist/_internal/components/form/Calendar/CalendarMonth.js +3 -3
- package/dist/_internal/components/form/Calendar/CalendarSelectorsMonth.js +4 -4
- package/dist/_internal/components/form/DateRangePicker/DateRangePicker.hooks.js +3 -3
- package/dist/_internal/components/form/DateRangePicker/DateRangePicker.js +10 -10
- package/dist/_internal/components/form/DateRangePicker/DateRangePicker.range.js +2 -2
- package/dist/_internal/components/form/DateRangePicker/DateRangePickerFields.js +3 -3
- package/dist/_internal/components/form/index.js +24 -24
- package/dist/_internal/components/index.js +66 -66
- package/dist/_internal/en-US.data-display.js +2 -1
- package/dist/_internal/pt-BR.data-display.js +2 -1
- package/dist/_internal/user-avatar/user-avatar.js +5 -5
- package/dist/charts.js +11 -11
- package/dist/{chunk-FJ3UZ4RC.js → chunk-2FKWKLSC.js} +5 -3
- package/dist/chunk-2FKWKLSC.js.map +1 -0
- package/dist/{chunk-BO6MT2S2.js → chunk-3HZKUN5J.js} +7 -6
- package/dist/chunk-3HZKUN5J.js.map +1 -0
- package/dist/{chunk-TYXFFNPM.js → chunk-3OTGREQG.js} +10 -10
- package/dist/{chunk-BEHT4IHH.js → chunk-3X2MA47R.js} +2 -2
- package/dist/{chunk-XHIBFBNP.js → chunk-3ZRK3BRN.js} +4 -2
- package/dist/chunk-3ZRK3BRN.js.map +1 -0
- package/dist/{chunk-X5OGIT2F.js → chunk-4L54KUZV.js} +22 -4
- package/dist/chunk-4L54KUZV.js.map +1 -0
- package/dist/{chunk-TRYR424I.js → chunk-6LOWZCH7.js} +15 -1
- package/dist/chunk-6LOWZCH7.js.map +1 -0
- package/dist/{chunk-6WHIJPEF.js → chunk-6PU5P7QT.js} +2 -2
- package/dist/chunk-7CUZTWKW.js +52 -0
- package/dist/chunk-7CUZTWKW.js.map +1 -0
- package/dist/{chunk-JIEVKHOH.js → chunk-7YJYIMWP.js} +7 -7
- package/dist/{chunk-YNZUYZ2O.js → chunk-A3DDEKLV.js} +2 -2
- package/dist/{chunk-KHREN7Y7.js → chunk-ACM3HHZY.js} +2 -2
- package/dist/{chunk-FEKWKWGK.js → chunk-ARGVUTTL.js} +15 -1
- package/dist/chunk-ARGVUTTL.js.map +1 -0
- package/dist/{chunk-DYHOBKPU.js → chunk-BLZDSCIZ.js} +6 -6
- package/dist/{chunk-E2UOEI7N.js → chunk-BV2LOTMC.js} +2 -2
- package/dist/{chunk-O63ZROSY.js → chunk-BZBLPXV7.js} +4 -4
- package/dist/{chunk-OKRITX4S.js → chunk-CJ6XXM4X.js} +4 -4
- package/dist/{chunk-LV6AD6XC.js → chunk-DBI6AMNY.js} +4 -4
- package/dist/{chunk-QRRWLLXW.js → chunk-DSBC6O46.js} +2 -2
- package/dist/{chunk-3YFDGFEK.js → chunk-DVX4HDNP.js} +2 -2
- package/dist/{chunk-CJUK32UH.js → chunk-EEO7M5GU.js} +2 -2
- package/dist/{chunk-7XSCEHGA.js → chunk-EOQ6EKTS.js} +7 -7
- package/dist/{chunk-5RSK5M6M.js → chunk-FI2CQOGC.js} +63 -126
- package/dist/chunk-FI2CQOGC.js.map +1 -0
- package/dist/{chunk-Q2ERGAQO.js → chunk-FYAW5GBF.js} +33 -6
- package/dist/chunk-FYAW5GBF.js.map +1 -0
- package/dist/{chunk-EOJSA2EK.js → chunk-G2PVUPE7.js} +26 -18
- package/dist/chunk-G2PVUPE7.js.map +1 -0
- package/dist/{chunk-AMLHEKSV.js → chunk-HI7JPDD6.js} +5 -5
- package/dist/{chunk-2H6SCVLD.js → chunk-HMEGQKNQ.js} +3 -3
- package/dist/chunk-J2AVWIMM.js +60 -0
- package/dist/chunk-J2AVWIMM.js.map +1 -0
- package/dist/{chunk-7QKIL5YF.js → chunk-J2GDA64N.js} +4 -4
- package/dist/{chunk-BAQ3ITZV.js → chunk-JFD742C3.js} +2 -2
- package/dist/{chunk-OBA75Y5O.js → chunk-JHWEL4NX.js} +61 -33
- package/dist/chunk-JHWEL4NX.js.map +1 -0
- package/dist/{chunk-HQCZT6TO.js → chunk-JVOEVTCZ.js} +5 -5
- package/dist/{chunk-WAO7UQRS.js → chunk-KANCE4MS.js} +3 -3
- package/dist/{chunk-XLU5WFSY.js → chunk-KRBPWTXW.js} +2 -2
- package/dist/{chunk-S6D7NOV7.js → chunk-L6JAALMX.js} +3 -3
- package/dist/{chunk-72HOUWAW.js → chunk-L6YTVXGN.js} +5 -3
- package/dist/{chunk-72HOUWAW.js.map → chunk-L6YTVXGN.js.map} +1 -1
- package/dist/chunk-LZNUBQ5I.js +181 -0
- package/dist/chunk-LZNUBQ5I.js.map +1 -0
- package/dist/{chunk-BECKKDYG.js → chunk-M2M4IDFU.js} +2 -2
- package/dist/{chunk-CSGBHYW6.js → chunk-M5Y42AZ4.js} +2 -2
- package/dist/chunk-MICX23P4.js +122 -0
- package/dist/chunk-MICX23P4.js.map +1 -0
- package/dist/{chunk-5CP5Z3YU.js → chunk-MPWA55CF.js} +4 -4
- package/dist/{chunk-5KK3I42O.js → chunk-NK6O4NE4.js} +13 -10
- package/dist/chunk-NK6O4NE4.js.map +1 -0
- package/dist/{chunk-RCTHCXS6.js → chunk-PJNIJIE6.js} +2 -2
- package/dist/{chunk-6ATXOJVQ.js → chunk-QADTI63U.js} +4 -4
- package/dist/{chunk-MW7P2C2C.js → chunk-QAEO52Z4.js} +2 -2
- package/dist/{chunk-5S5K73I6.js → chunk-QSOCOXVL.js} +3 -3
- package/dist/{chunk-NQCTANF3.js → chunk-QVDEGBME.js} +7 -7
- package/dist/{chunk-BQBEN44R.js → chunk-RDCIST7P.js} +2 -2
- package/dist/{chunk-HUXAIQC5.js → chunk-RZ3P4X2I.js} +2 -2
- package/dist/{chunk-WJMSND5Q.js → chunk-SCXVTNLE.js} +2 -2
- package/dist/{chunk-K6FCSB6T.js → chunk-SK2CTB3O.js} +6 -6
- package/dist/{chunk-QLJU7UUI.js → chunk-T7OIVPCO.js} +38 -3
- package/dist/chunk-T7OIVPCO.js.map +1 -0
- package/dist/{chunk-U2ILXZDG.js → chunk-TB5CRHTF.js} +2 -2
- package/dist/{chunk-SB2SEGR6.js → chunk-TIM4PXWN.js} +3 -3
- package/dist/{chunk-YDIC6LSP.js → chunk-VCQFDQM3.js} +27 -7
- package/dist/chunk-VCQFDQM3.js.map +1 -0
- package/dist/chunk-VIMMEADQ.js +164 -0
- package/dist/chunk-VIMMEADQ.js.map +1 -0
- package/dist/{chunk-6D5AMANO.js → chunk-WH3LUOCQ.js} +2 -2
- package/dist/{chunk-OWRQOYUE.js → chunk-WWR6APJR.js} +2 -2
- package/dist/{chunk-5BVAUUWL.js → chunk-X37NTEVS.js} +2 -2
- package/dist/{chunk-WW3F7DCX.js → chunk-Z2WZDVGG.js} +2 -2
- package/dist/{chunk-EXVCVXFX.js → chunk-ZH6NYB6Y.js} +3 -3
- package/dist/data-display/Alert.js +3 -3
- package/dist/data-display/Avatar.js +4 -4
- package/dist/data-display/CardKit.js +11 -11
- package/dist/data-display/Carousel.js +6 -5
- package/dist/data-display/Chart.js +11 -11
- package/dist/data-display/DataGrid.js +2 -2
- package/dist/data-display/DataViews.js +60 -35
- package/dist/data-display/DayRuler.js +3 -3
- package/dist/data-display/FleetMap.js +9 -9
- package/dist/data-display/MapPreview.js +7 -6
- package/dist/en-US.js +1 -1
- package/dist/feedback/NotificationStatusNotice.js +4 -4
- package/dist/feedback/SequenceResolver.js +6 -6
- package/dist/form/Calendar.js +5 -5
- package/dist/form/DateRangePicker.js +10 -10
- package/dist/locales.js +5 -5
- package/dist/pt-BR.js +1 -1
- package/dist/types/components/data-display/DataViews/data-views-bar-controls.d.ts +15 -1
- package/dist/types/components/data-display/DataViews/data-views-bar-controls.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-copy.d.ts +35 -0
- package/dist/types/components/data-display/DataViews/data-views-copy.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-day-input.d.ts +7 -1
- package/dist/types/components/data-display/DataViews/data-views-day-input.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-more-fields.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-more-filters.d.ts +5 -3
- package/dist/types/components/data-display/DataViews/data-views-more-filters.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-number-input.d.ts +10 -2
- package/dist/types/components/data-display/DataViews/data-views-number-input.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-preset-chips.d.ts +10 -0
- package/dist/types/components/data-display/DataViews/data-views-preset-chips.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-range-bounds.d.ts +35 -0
- package/dist/types/components/data-display/DataViews/data-views-range-bounds.d.ts.map +1 -0
- package/dist/types/components/data-display/DataViews/data-views-range-calendar.d.ts +35 -0
- package/dist/types/components/data-display/DataViews/data-views-range-calendar.d.ts.map +1 -0
- package/dist/types/components/data-display/DataViews/data-views-range-pill.d.ts +2 -11
- package/dist/types/components/data-display/DataViews/data-views-range-pill.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-range-summary.d.ts +21 -0
- package/dist/types/components/data-display/DataViews/data-views-range-summary.d.ts.map +1 -0
- package/dist/types/components/data-display/DataViews/data-views-still-anchor.d.ts +45 -0
- package/dist/types/components/data-display/DataViews/data-views-still-anchor.d.ts.map +1 -0
- package/dist/types/components/data-display/DayRuler/DayRuler.styles.d.ts +6 -1
- package/dist/types/components/data-display/DayRuler/DayRuler.styles.d.ts.map +1 -1
- package/dist/types/components/data-display/LazyImage/LazyImage.hooks.d.ts +1 -1
- package/dist/types/components/form/Calendar/Calendar.d.ts.map +1 -1
- package/dist/types/components/form/Calendar/CalendarDay.d.ts +2 -0
- package/dist/types/components/form/Calendar/CalendarDay.d.ts.map +1 -1
- package/dist/types/components/form/Calendar/CalendarDayCell.d.ts +2 -0
- package/dist/types/components/form/Calendar/CalendarDayCell.d.ts.map +1 -1
- package/dist/types/components/form/Calendar/CalendarMonth.d.ts +5 -0
- package/dist/types/components/form/Calendar/CalendarMonth.d.ts.map +1 -1
- package/dist/types/en-US.data-display.d.ts.map +1 -1
- package/dist/types/pt-BR.data-display.d.ts.map +1 -1
- package/dist/user-avatar.js +5 -5
- package/package.json +1 -1
- package/src/components/data-display/DataViews/RESPONSIVE-BEHAVIOUR.md +59 -0
- package/src/components/data-display/DataViews/data-views-bar-controls.tsx +56 -1
- package/src/components/data-display/DataViews/data-views-copy.ts +36 -0
- package/src/components/data-display/DataViews/data-views-day-input.tsx +9 -1
- package/src/components/data-display/DataViews/data-views-inline-bar.tsx +5 -3
- package/src/components/data-display/DataViews/data-views-more-fields.tsx +1 -0
- package/src/components/data-display/DataViews/data-views-more-filters.tsx +82 -29
- package/src/components/data-display/DataViews/data-views-number-input.tsx +19 -9
- package/src/components/data-display/DataViews/data-views-preset-chips.tsx +165 -16
- package/src/components/data-display/DataViews/data-views-range-bounds.tsx +223 -0
- package/src/components/data-display/DataViews/data-views-range-calendar.tsx +185 -0
- package/src/components/data-display/DataViews/data-views-range-pill.tsx +71 -154
- package/src/components/data-display/DataViews/data-views-range-summary.tsx +66 -0
- package/src/components/data-display/DataViews/data-views-still-anchor.ts +93 -0
- package/src/components/data-display/DayRuler/DayRuler.styles.ts +29 -16
- package/src/components/form/Calendar/Calendar.md +17 -2
- package/src/components/form/Calendar/Calendar.tsx +56 -3
- package/src/components/form/Calendar/CalendarDay.tsx +33 -3
- package/src/components/form/Calendar/CalendarDayCell.tsx +4 -0
- package/src/components/form/Calendar/CalendarMonth.tsx +27 -5
- package/src/en-US.data-display.ts +12 -0
- package/src/pt-BR.data-display.ts +12 -0
- package/dist/chunk-5KK3I42O.js.map +0 -1
- package/dist/chunk-5RSK5M6M.js.map +0 -1
- package/dist/chunk-7D7CJRL7.js +0 -78
- package/dist/chunk-7D7CJRL7.js.map +0 -1
- package/dist/chunk-BO6MT2S2.js.map +0 -1
- package/dist/chunk-EOJSA2EK.js.map +0 -1
- package/dist/chunk-FEKWKWGK.js.map +0 -1
- package/dist/chunk-FJ3UZ4RC.js.map +0 -1
- package/dist/chunk-OBA75Y5O.js.map +0 -1
- package/dist/chunk-Q2ERGAQO.js.map +0 -1
- package/dist/chunk-QLJU7UUI.js.map +0 -1
- package/dist/chunk-TRYR424I.js.map +0 -1
- package/dist/chunk-X5OGIT2F.js.map +0 -1
- package/dist/chunk-XHIBFBNP.js.map +0 -1
- package/dist/chunk-YDIC6LSP.js.map +0 -1
- /package/dist/{chunk-TYXFFNPM.js.map → chunk-3OTGREQG.js.map} +0 -0
- /package/dist/{chunk-BEHT4IHH.js.map → chunk-3X2MA47R.js.map} +0 -0
- /package/dist/{chunk-6WHIJPEF.js.map → chunk-6PU5P7QT.js.map} +0 -0
- /package/dist/{chunk-JIEVKHOH.js.map → chunk-7YJYIMWP.js.map} +0 -0
- /package/dist/{chunk-YNZUYZ2O.js.map → chunk-A3DDEKLV.js.map} +0 -0
- /package/dist/{chunk-KHREN7Y7.js.map → chunk-ACM3HHZY.js.map} +0 -0
- /package/dist/{chunk-DYHOBKPU.js.map → chunk-BLZDSCIZ.js.map} +0 -0
- /package/dist/{chunk-E2UOEI7N.js.map → chunk-BV2LOTMC.js.map} +0 -0
- /package/dist/{chunk-O63ZROSY.js.map → chunk-BZBLPXV7.js.map} +0 -0
- /package/dist/{chunk-OKRITX4S.js.map → chunk-CJ6XXM4X.js.map} +0 -0
- /package/dist/{chunk-LV6AD6XC.js.map → chunk-DBI6AMNY.js.map} +0 -0
- /package/dist/{chunk-QRRWLLXW.js.map → chunk-DSBC6O46.js.map} +0 -0
- /package/dist/{chunk-3YFDGFEK.js.map → chunk-DVX4HDNP.js.map} +0 -0
- /package/dist/{chunk-CJUK32UH.js.map → chunk-EEO7M5GU.js.map} +0 -0
- /package/dist/{chunk-7XSCEHGA.js.map → chunk-EOQ6EKTS.js.map} +0 -0
- /package/dist/{chunk-AMLHEKSV.js.map → chunk-HI7JPDD6.js.map} +0 -0
- /package/dist/{chunk-2H6SCVLD.js.map → chunk-HMEGQKNQ.js.map} +0 -0
- /package/dist/{chunk-7QKIL5YF.js.map → chunk-J2GDA64N.js.map} +0 -0
- /package/dist/{chunk-BAQ3ITZV.js.map → chunk-JFD742C3.js.map} +0 -0
- /package/dist/{chunk-HQCZT6TO.js.map → chunk-JVOEVTCZ.js.map} +0 -0
- /package/dist/{chunk-WAO7UQRS.js.map → chunk-KANCE4MS.js.map} +0 -0
- /package/dist/{chunk-XLU5WFSY.js.map → chunk-KRBPWTXW.js.map} +0 -0
- /package/dist/{chunk-S6D7NOV7.js.map → chunk-L6JAALMX.js.map} +0 -0
- /package/dist/{chunk-BECKKDYG.js.map → chunk-M2M4IDFU.js.map} +0 -0
- /package/dist/{chunk-CSGBHYW6.js.map → chunk-M5Y42AZ4.js.map} +0 -0
- /package/dist/{chunk-5CP5Z3YU.js.map → chunk-MPWA55CF.js.map} +0 -0
- /package/dist/{chunk-RCTHCXS6.js.map → chunk-PJNIJIE6.js.map} +0 -0
- /package/dist/{chunk-6ATXOJVQ.js.map → chunk-QADTI63U.js.map} +0 -0
- /package/dist/{chunk-MW7P2C2C.js.map → chunk-QAEO52Z4.js.map} +0 -0
- /package/dist/{chunk-5S5K73I6.js.map → chunk-QSOCOXVL.js.map} +0 -0
- /package/dist/{chunk-NQCTANF3.js.map → chunk-QVDEGBME.js.map} +0 -0
- /package/dist/{chunk-BQBEN44R.js.map → chunk-RDCIST7P.js.map} +0 -0
- /package/dist/{chunk-HUXAIQC5.js.map → chunk-RZ3P4X2I.js.map} +0 -0
- /package/dist/{chunk-WJMSND5Q.js.map → chunk-SCXVTNLE.js.map} +0 -0
- /package/dist/{chunk-K6FCSB6T.js.map → chunk-SK2CTB3O.js.map} +0 -0
- /package/dist/{chunk-U2ILXZDG.js.map → chunk-TB5CRHTF.js.map} +0 -0
- /package/dist/{chunk-SB2SEGR6.js.map → chunk-TIM4PXWN.js.map} +0 -0
- /package/dist/{chunk-6D5AMANO.js.map → chunk-WH3LUOCQ.js.map} +0 -0
- /package/dist/{chunk-OWRQOYUE.js.map → chunk-WWR6APJR.js.map} +0 -0
- /package/dist/{chunk-5BVAUUWL.js.map → chunk-X37NTEVS.js.map} +0 -0
- /package/dist/{chunk-WW3F7DCX.js.map → chunk-Z2WZDVGG.js.map} +0 -0
- /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
|
-
|
|
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={
|
|
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={
|
|
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
|
)}
|
|
@@ -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
|
|
12
|
-
import
|
|
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
|
|
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
|
-
|
|
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
|
-
/**
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
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
|
-
}
|
|
231
|
-
|
|
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
|
-
|
|
304
|
+
still.open(element);
|
|
252
305
|
onOpenChange?.(true);
|
|
253
306
|
}}
|
|
254
307
|
testIdPrefix={rest.testIdPrefix}
|
|
255
308
|
/>
|
|
256
309
|
<Popover
|
|
257
|
-
|
|
258
|
-
anchorEl={anchor}
|
|
310
|
+
{...still.popoverProps}
|
|
259
311
|
onClose={() => {
|
|
260
|
-
|
|
312
|
+
still.close();
|
|
261
313
|
onOpenChange?.(false);
|
|
262
314
|
}}
|
|
263
|
-
|
|
264
|
-
|
|
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
|
|
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={{
|
|
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
|
-
|
|
95
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
}
|