@12-apps/ui 6.89.2 → 6.91.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 +2 -2
- package/dist/_internal/components/data-display/Alert/Alert.js +3 -3
- package/dist/_internal/components/data-display/AsyncStateContainer/AsyncStateContainer.js +3 -3
- package/dist/_internal/components/data-display/Avatar/Avatar.js +3 -3
- 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 +5 -4
- package/dist/_internal/components/data-display/Carousel/Carousel.parts.js +3 -2
- package/dist/_internal/components/data-display/Chart/Chart.js +5 -5
- package/dist/_internal/components/data-display/Chart/SpecChart.js +8 -8
- package/dist/_internal/components/data-display/Chart/chart-context.js +2 -2
- package/dist/_internal/components/data-display/Chart/chart-renderers.js +4 -4
- package/dist/_internal/components/data-display/Chart/chart-spec.js +2 -2
- package/dist/_internal/components/data-display/Chip/Chip.js +3 -3
- package/dist/_internal/components/data-display/Chip/Chip.styles.js +2 -2
- package/dist/_internal/components/data-display/DataGrid/DataGrid.js +2 -2
- package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +56 -31
- package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +64 -39
- package/dist/_internal/components/data-display/DataViews/base-list-card-geometry.js +6 -6
- package/dist/_internal/components/data-display/DataViews/base-list-card-layout.js +7 -7
- package/dist/_internal/components/data-display/DataViews/base-list-card-slots.js +5 -5
- package/dist/_internal/components/data-display/DataViews/base-list-card.js +9 -9
- 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 +8 -8
- package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +53 -28
- package/dist/_internal/components/data-display/DataViews/data-views-inline-bar.js +36 -11
- 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-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 +5 -5
- package/dist/_internal/components/data-display/DataViews/data-views-toolbar.js +2 -2
- package/dist/_internal/components/data-display/DataViews/list-card-rails.js +4 -4
- package/dist/_internal/components/data-display/DataViews/use-data-views-state.js +2 -2
- package/dist/_internal/components/data-display/EmptyState/EmptyState.js +2 -2
- package/dist/_internal/components/data-display/FleetMap/FleetBody.js +13 -12
- package/dist/_internal/components/data-display/FleetMap/FleetCanvas.js +12 -11
- 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 +15 -15
- package/dist/_internal/components/data-display/InteractiveTooltip/InteractiveTooltip.js +2 -2
- package/dist/_internal/components/data-display/Lightbox/Lightbox.js +7 -7
- package/dist/_internal/components/data-display/Lightbox/LightboxControls.js +2 -2
- package/dist/_internal/components/data-display/Lightbox/LightboxOverlay.js +3 -3
- package/dist/_internal/components/data-display/Lightbox/LightboxThumbnails.js +2 -2
- package/dist/_internal/components/data-display/MapPreview/MapControlBar.js +4 -3
- package/dist/_internal/components/data-display/MapPreview/MapLayers.js +6 -5
- package/dist/_internal/components/data-display/MapPreview/MapMarkers.js +5 -4
- package/dist/_internal/components/data-display/MapPreview/MapPreview.helpers.js +3 -2
- package/dist/_internal/components/data-display/MapPreview/MapPreview.js +11 -10
- package/dist/_internal/components/data-display/RegionMap/RegionMap.hooks.js +2 -1
- package/dist/_internal/components/data-display/RegionMap/RegionMap.js +4 -3
- package/dist/_internal/components/data-display/RegionMap/RegionMap.view.js +19 -0
- package/dist/_internal/components/data-display/RegionMap/RegionMap.view.js.map +1 -0
- package/dist/_internal/components/data-display/RegionMap/RegionMapDrawing.js +1 -1
- package/dist/_internal/components/data-display/SectionOnboarding/SectionOnboarding.js +3 -3
- package/dist/_internal/components/data-display/index.js +67 -61
- 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 +102 -96
- package/dist/_internal/components/layout/SettingCard/SettingCard.js +8 -8
- package/dist/_internal/components/layout/SettingCard/SettingCard.parts.js +4 -4
- package/dist/_internal/components/layout/SettingCard/SettingCard.summary.js +7 -7
- package/dist/_internal/components/layout/SettingCard/SettingGrid.js +5 -5
- package/dist/_internal/components/layout/SettingCard/SettingGroup.js +9 -9
- package/dist/_internal/components/layout/SettingCard/SettingSwitch.js +8 -8
- package/dist/_internal/components/layout/SettingCard/SettingToggle.js +9 -9
- package/dist/_internal/components/layout/index.js +12 -12
- 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 +4 -4
- 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-K2VDRODL.js → chunk-3IDL7NK7.js} +2 -2
- package/dist/{chunk-6ATXOJVQ.js → chunk-3JZ3KEQQ.js} +4 -4
- package/dist/{chunk-XHIBFBNP.js → chunk-3ZRK3BRN.js} +4 -2
- package/dist/chunk-3ZRK3BRN.js.map +1 -0
- package/dist/{chunk-EOIRU62W.js → chunk-42D7KBDH.js} +2 -2
- package/dist/{chunk-LXIPBHNJ.js → chunk-42TOCPXB.js} +5 -5
- package/dist/{chunk-WAO7UQRS.js → chunk-4KWDNGMA.js} +3 -3
- package/dist/{chunk-X5OGIT2F.js → chunk-4L54KUZV.js} +22 -4
- package/dist/chunk-4L54KUZV.js.map +1 -0
- package/dist/{chunk-JIEVKHOH.js → chunk-4QR7LM5F.js} +2 -2
- package/dist/{chunk-WJMSND5Q.js → chunk-5E2CRRD4.js} +5 -5
- package/dist/{chunk-ZDAAHCIS.js → chunk-5HADIIWN.js} +3 -3
- package/dist/{chunk-BP3ZKIPE.js → chunk-64UNVW6D.js} +4 -4
- 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-7F6D73NL.js → chunk-76DX2IMH.js} +2 -2
- package/dist/chunk-7CUZTWKW.js +52 -0
- package/dist/chunk-7CUZTWKW.js.map +1 -0
- package/dist/{chunk-5RSK5M6M.js → chunk-7NP2JHGM.js} +63 -126
- package/dist/chunk-7NP2JHGM.js.map +1 -0
- package/dist/{chunk-YNZUYZ2O.js → chunk-A3DDEKLV.js} +2 -2
- package/dist/{chunk-FEKWKWGK.js → chunk-ARGVUTTL.js} +15 -1
- package/dist/chunk-ARGVUTTL.js.map +1 -0
- package/dist/{chunk-BMTIBQQC.js → chunk-BBBHPK2Q.js} +6 -6
- package/dist/{chunk-DYHOBKPU.js → chunk-BLZDSCIZ.js} +6 -6
- package/dist/{chunk-EUR2ORTN.js → chunk-CSJ7WNXU.js} +2 -2
- package/dist/{chunk-OWRQOYUE.js → chunk-DA3D5X5Z.js} +5 -5
- package/dist/{chunk-LV6AD6XC.js → chunk-DBI6AMNY.js} +4 -4
- package/dist/{chunk-3YFDGFEK.js → chunk-DVX4HDNP.js} +2 -2
- package/dist/chunk-DY2I6LMX.js +1 -0
- package/dist/chunk-DY2I6LMX.js.map +1 -0
- package/dist/{chunk-QKOJ4637.js → chunk-E6K2UZGR.js} +3 -3
- package/dist/{chunk-7XSCEHGA.js → chunk-EOQ6EKTS.js} +7 -7
- package/dist/chunk-FORAVDJF.js +164 -0
- package/dist/chunk-FORAVDJF.js.map +1 -0
- package/dist/chunk-FWAY2SAI.js +72 -0
- package/dist/chunk-FWAY2SAI.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-GMRQPNG3.js → chunk-G2NVBCF7.js} +20 -25
- package/dist/chunk-G2NVBCF7.js.map +1 -0
- package/dist/{chunk-Z5WUSI47.js → chunk-G3JFESKD.js} +6 -6
- package/dist/{chunk-3EIRRLCQ.js → chunk-HC6OZ7QK.js} +2 -2
- package/dist/{chunk-SKIAWOUC.js → chunk-HOPRZEBM.js} +3 -3
- package/dist/{chunk-OBA75Y5O.js → chunk-HS662RLW.js} +61 -33
- package/dist/chunk-HS662RLW.js.map +1 -0
- package/dist/{chunk-O63ZROSY.js → chunk-IWSTMVCA.js} +7 -7
- 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-TZC6KIK2.js → chunk-JG733RMP.js} +5 -5
- package/dist/{chunk-CW5Z67NA.js → chunk-JH2XLVWM.js} +2 -2
- package/dist/{chunk-TYXFFNPM.js → chunk-JKZPGCN7.js} +11 -11
- package/dist/{chunk-QRRWLLXW.js → chunk-JN2IANXD.js} +3 -3
- package/dist/{chunk-HQCZT6TO.js → chunk-JVOEVTCZ.js} +5 -5
- package/dist/{chunk-GBB23QLL.js → chunk-KJKD6Y6V.js} +3 -3
- package/dist/{chunk-XLU5WFSY.js → chunk-L3PDY7CJ.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-AMLHEKSV.js → chunk-M3XJVD5G.js} +5 -5
- 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-CJUK32UH.js → chunk-MYTV353T.js} +5 -5
- package/dist/{chunk-BO6MT2S2.js → chunk-MZAYIG2I.js} +7 -6
- package/dist/chunk-MZAYIG2I.js.map +1 -0
- package/dist/{chunk-AKE6KVQG.js → chunk-NGXL4R54.js} +5 -1
- package/dist/chunk-NGXL4R54.js.map +1 -0
- package/dist/{chunk-BEHT4IHH.js → chunk-NKEFH3RS.js} +6 -6
- package/dist/{chunk-NI67M453.js → chunk-PGANINQD.js} +5 -5
- package/dist/{chunk-RCTHCXS6.js → chunk-PJNIJIE6.js} +2 -2
- package/dist/{chunk-E2UOEI7N.js → chunk-Q3SILZTQ.js} +2 -2
- package/dist/{chunk-SB2SEGR6.js → chunk-QHIWV55K.js} +3 -3
- package/dist/{chunk-DHAXUVMR.js → chunk-QN7FVZQD.js} +4 -4
- 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-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-X2GWR75Q.js → chunk-TSEBMVYY.js} +3 -3
- package/dist/{chunk-OKRITX4S.js → chunk-U2AEM3K4.js} +7 -7
- package/dist/{chunk-EXVCVXFX.js → chunk-U2QXQ7D4.js} +6 -6
- package/dist/{chunk-K6FCSB6T.js → chunk-U2SAW6DH.js} +2 -2
- package/dist/{chunk-DAHSKQBV.js → chunk-UMOHHWXY.js} +2 -2
- package/dist/{chunk-YDIC6LSP.js → chunk-VCQFDQM3.js} +27 -7
- package/dist/chunk-VCQFDQM3.js.map +1 -0
- package/dist/{chunk-P772HCHI.js → chunk-W676GY42.js} +4 -4
- package/dist/{chunk-BAQ3ITZV.js → chunk-WCF56ZCD.js} +2 -2
- package/dist/{chunk-6D5AMANO.js → chunk-WH3LUOCQ.js} +2 -2
- package/dist/{chunk-T2G4LDU5.js → chunk-WLLUARTC.js} +2 -2
- package/dist/{chunk-5BVAUUWL.js → chunk-X37NTEVS.js} +2 -2
- package/dist/{chunk-5KK3I42O.js → chunk-XILMDEGZ.js} +13 -10
- package/dist/chunk-XILMDEGZ.js.map +1 -0
- package/dist/{chunk-MW7P2C2C.js → chunk-YGQM6GFQ.js} +2 -2
- package/dist/{chunk-WW3F7DCX.js → chunk-Z2WZDVGG.js} +2 -2
- package/dist/{chunk-WNNA6YYE.js → chunk-Z7T4EFEC.js} +7 -4
- package/dist/chunk-Z7T4EFEC.js.map +1 -0
- package/dist/{chunk-LOLYBFYY.js → chunk-ZCNR4DN5.js} +5 -5
- package/dist/{chunk-COKPPU42.js → chunk-ZIHSCBMN.js} +12 -12
- package/dist/data-display/Alert.js +3 -3
- package/dist/data-display/AsyncStateContainer.js +3 -3
- package/dist/data-display/Avatar.js +3 -3
- package/dist/data-display/CardKit.js +15 -15
- package/dist/data-display/Carousel.js +5 -4
- package/dist/data-display/Chart.js +11 -11
- package/dist/data-display/Chip.js +3 -3
- package/dist/data-display/DataGrid.js +2 -2
- package/dist/data-display/DataViews.js +75 -50
- package/dist/data-display/DayRuler.js +4 -4
- package/dist/data-display/EmptyState.js +2 -2
- package/dist/data-display/FleetMap.js +15 -15
- package/dist/data-display/InteractiveTooltip.js +2 -2
- package/dist/data-display/Lightbox.js +7 -7
- package/dist/data-display/MapPreview.js +11 -10
- package/dist/data-display/RegionMap.js +11 -5
- package/dist/data-display/SectionOnboarding.js +3 -3
- 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/layout/SettingCard.js +12 -12
- 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/LazyImage/LazyImage.hooks.d.ts +1 -1
- package/dist/types/components/data-display/RegionMap/RegionMap.d.ts +4 -1
- package/dist/types/components/data-display/RegionMap/RegionMap.d.ts.map +1 -1
- package/dist/types/components/data-display/RegionMap/RegionMap.hooks.d.ts +4 -2
- package/dist/types/components/data-display/RegionMap/RegionMap.hooks.d.ts.map +1 -1
- package/dist/types/components/data-display/RegionMap/RegionMap.types.d.ts +40 -0
- package/dist/types/components/data-display/RegionMap/RegionMap.types.d.ts.map +1 -1
- package/dist/types/components/data-display/RegionMap/RegionMap.view.d.ts +36 -0
- package/dist/types/components/data-display/RegionMap/RegionMap.view.d.ts.map +1 -0
- package/dist/types/components/data-display/RegionMap/RegionMapDrawing.d.ts +4 -1
- package/dist/types/components/data-display/RegionMap/RegionMapDrawing.d.ts.map +1 -1
- package/dist/types/components/data-display/RegionMap/index.d.ts +3 -2
- package/dist/types/components/data-display/RegionMap/index.d.ts.map +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 +4 -4
- 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/RegionMap/RegionMap.hooks.ts +24 -33
- package/src/components/data-display/RegionMap/RegionMap.md +27 -0
- package/src/components/data-display/RegionMap/RegionMap.tsx +7 -1
- package/src/components/data-display/RegionMap/RegionMap.types.ts +41 -0
- package/src/components/data-display/RegionMap/RegionMap.view.ts +105 -0
- package/src/components/data-display/RegionMap/RegionMapDrawing.tsx +11 -0
- package/src/components/data-display/RegionMap/index.ts +5 -1
- package/src/components/data-display/RegionMap/tests.md +10 -2
- 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-ACFKPE2T.js +0 -1
- package/dist/chunk-AKE6KVQG.js.map +0 -1
- package/dist/chunk-BO6MT2S2.js.map +0 -1
- package/dist/chunk-FEKWKWGK.js.map +0 -1
- package/dist/chunk-FJ3UZ4RC.js.map +0 -1
- package/dist/chunk-GMRQPNG3.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-WNNA6YYE.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-ACFKPE2T.js.map → _internal/components/data-display/DataViews/data-views-range-bounds.js.map} +0 -0
- /package/dist/{chunk-K2VDRODL.js.map → chunk-3IDL7NK7.js.map} +0 -0
- /package/dist/{chunk-6ATXOJVQ.js.map → chunk-3JZ3KEQQ.js.map} +0 -0
- /package/dist/{chunk-EOIRU62W.js.map → chunk-42D7KBDH.js.map} +0 -0
- /package/dist/{chunk-LXIPBHNJ.js.map → chunk-42TOCPXB.js.map} +0 -0
- /package/dist/{chunk-WAO7UQRS.js.map → chunk-4KWDNGMA.js.map} +0 -0
- /package/dist/{chunk-JIEVKHOH.js.map → chunk-4QR7LM5F.js.map} +0 -0
- /package/dist/{chunk-WJMSND5Q.js.map → chunk-5E2CRRD4.js.map} +0 -0
- /package/dist/{chunk-ZDAAHCIS.js.map → chunk-5HADIIWN.js.map} +0 -0
- /package/dist/{chunk-BP3ZKIPE.js.map → chunk-64UNVW6D.js.map} +0 -0
- /package/dist/{chunk-6WHIJPEF.js.map → chunk-6PU5P7QT.js.map} +0 -0
- /package/dist/{chunk-7F6D73NL.js.map → chunk-76DX2IMH.js.map} +0 -0
- /package/dist/{chunk-YNZUYZ2O.js.map → chunk-A3DDEKLV.js.map} +0 -0
- /package/dist/{chunk-BMTIBQQC.js.map → chunk-BBBHPK2Q.js.map} +0 -0
- /package/dist/{chunk-DYHOBKPU.js.map → chunk-BLZDSCIZ.js.map} +0 -0
- /package/dist/{chunk-EUR2ORTN.js.map → chunk-CSJ7WNXU.js.map} +0 -0
- /package/dist/{chunk-OWRQOYUE.js.map → chunk-DA3D5X5Z.js.map} +0 -0
- /package/dist/{chunk-LV6AD6XC.js.map → chunk-DBI6AMNY.js.map} +0 -0
- /package/dist/{chunk-3YFDGFEK.js.map → chunk-DVX4HDNP.js.map} +0 -0
- /package/dist/{chunk-QKOJ4637.js.map → chunk-E6K2UZGR.js.map} +0 -0
- /package/dist/{chunk-7XSCEHGA.js.map → chunk-EOQ6EKTS.js.map} +0 -0
- /package/dist/{chunk-Z5WUSI47.js.map → chunk-G3JFESKD.js.map} +0 -0
- /package/dist/{chunk-3EIRRLCQ.js.map → chunk-HC6OZ7QK.js.map} +0 -0
- /package/dist/{chunk-SKIAWOUC.js.map → chunk-HOPRZEBM.js.map} +0 -0
- /package/dist/{chunk-O63ZROSY.js.map → chunk-IWSTMVCA.js.map} +0 -0
- /package/dist/{chunk-7QKIL5YF.js.map → chunk-J2GDA64N.js.map} +0 -0
- /package/dist/{chunk-TZC6KIK2.js.map → chunk-JG733RMP.js.map} +0 -0
- /package/dist/{chunk-CW5Z67NA.js.map → chunk-JH2XLVWM.js.map} +0 -0
- /package/dist/{chunk-TYXFFNPM.js.map → chunk-JKZPGCN7.js.map} +0 -0
- /package/dist/{chunk-QRRWLLXW.js.map → chunk-JN2IANXD.js.map} +0 -0
- /package/dist/{chunk-HQCZT6TO.js.map → chunk-JVOEVTCZ.js.map} +0 -0
- /package/dist/{chunk-GBB23QLL.js.map → chunk-KJKD6Y6V.js.map} +0 -0
- /package/dist/{chunk-XLU5WFSY.js.map → chunk-L3PDY7CJ.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-AMLHEKSV.js.map → chunk-M3XJVD5G.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-CJUK32UH.js.map → chunk-MYTV353T.js.map} +0 -0
- /package/dist/{chunk-BEHT4IHH.js.map → chunk-NKEFH3RS.js.map} +0 -0
- /package/dist/{chunk-NI67M453.js.map → chunk-PGANINQD.js.map} +0 -0
- /package/dist/{chunk-RCTHCXS6.js.map → chunk-PJNIJIE6.js.map} +0 -0
- /package/dist/{chunk-E2UOEI7N.js.map → chunk-Q3SILZTQ.js.map} +0 -0
- /package/dist/{chunk-SB2SEGR6.js.map → chunk-QHIWV55K.js.map} +0 -0
- /package/dist/{chunk-DHAXUVMR.js.map → chunk-QN7FVZQD.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-U2ILXZDG.js.map → chunk-TB5CRHTF.js.map} +0 -0
- /package/dist/{chunk-X2GWR75Q.js.map → chunk-TSEBMVYY.js.map} +0 -0
- /package/dist/{chunk-OKRITX4S.js.map → chunk-U2AEM3K4.js.map} +0 -0
- /package/dist/{chunk-EXVCVXFX.js.map → chunk-U2QXQ7D4.js.map} +0 -0
- /package/dist/{chunk-K6FCSB6T.js.map → chunk-U2SAW6DH.js.map} +0 -0
- /package/dist/{chunk-DAHSKQBV.js.map → chunk-UMOHHWXY.js.map} +0 -0
- /package/dist/{chunk-P772HCHI.js.map → chunk-W676GY42.js.map} +0 -0
- /package/dist/{chunk-BAQ3ITZV.js.map → chunk-WCF56ZCD.js.map} +0 -0
- /package/dist/{chunk-6D5AMANO.js.map → chunk-WH3LUOCQ.js.map} +0 -0
- /package/dist/{chunk-T2G4LDU5.js.map → chunk-WLLUARTC.js.map} +0 -0
- /package/dist/{chunk-5BVAUUWL.js.map → chunk-X37NTEVS.js.map} +0 -0
- /package/dist/{chunk-MW7P2C2C.js.map → chunk-YGQM6GFQ.js.map} +0 -0
- /package/dist/{chunk-WW3F7DCX.js.map → chunk-Z2WZDVGG.js.map} +0 -0
- /package/dist/{chunk-LOLYBFYY.js.map → chunk-ZCNR4DN5.js.map} +0 -0
- /package/dist/{chunk-COKPPU42.js.map → chunk-ZIHSCBMN.js.map} +0 -0
|
@@ -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
|
}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The `De`/`Até` pair of a range filter, its preset chips, the line under it
|
|
5
|
+
* and — for a day range — the calendar under that (FUT-4144). Shared by the
|
|
6
|
+
* pill's popover, the slide-in panel and the "Mais" sheet, so the three cannot
|
|
7
|
+
* drift on what a bound accepts or how it clears.
|
|
8
|
+
*/
|
|
9
|
+
import Box from '@mui/material/Box/index.js';
|
|
10
|
+
import Typography from '@mui/material/Typography/index.js';
|
|
11
|
+
import React, { useState } from 'react';
|
|
12
|
+
|
|
13
|
+
import { useDataViewsCopy } from './data-views-copy-context';
|
|
14
|
+
import { DayBoundInput } from './data-views-day-input';
|
|
15
|
+
import { NumberBoundInput } from './data-views-number-input';
|
|
16
|
+
import { RangePresets } from './data-views-preset-chips';
|
|
17
|
+
import { DayRangeCalendar } from './data-views-range-calendar';
|
|
18
|
+
import { presetsFor } from './data-views-range-presets';
|
|
19
|
+
import { useOutsideResetKey } from './data-views-range-reset';
|
|
20
|
+
import { isRangeInverted } from './data-views-range-values';
|
|
21
|
+
import type { RangeFieldConfig, RangeValue } from './data-views-types';
|
|
22
|
+
import { sxRem } from '../../../tokens/relative';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* One end of the range. A day keeps its `AAAA-MM-DD` string verbatim (the form
|
|
26
|
+
* both the field and the backend speak) and is typed through the masked
|
|
27
|
+
* `dd/mm/aaaa` field rather than a native date input — see
|
|
28
|
+
* {@link DayBoundInput} for why. A number parses, and an unparseable/blank
|
|
29
|
+
* entry CLEARS the bound rather than writing `NaN`.
|
|
30
|
+
*/
|
|
31
|
+
function BoundField<T extends Record<string, unknown>>({
|
|
32
|
+
field,
|
|
33
|
+
label,
|
|
34
|
+
value,
|
|
35
|
+
onChange,
|
|
36
|
+
testId,
|
|
37
|
+
fill,
|
|
38
|
+
}: {
|
|
39
|
+
field: RangeFieldConfig<T>;
|
|
40
|
+
label: string;
|
|
41
|
+
value: number | string | undefined;
|
|
42
|
+
onChange: (bound: number | string | undefined) => void;
|
|
43
|
+
testId: string;
|
|
44
|
+
/** A number box takes its cell's width; a day box always does. */
|
|
45
|
+
fill: boolean;
|
|
46
|
+
}): React.JSX.Element {
|
|
47
|
+
const copy = useDataViewsCopy();
|
|
48
|
+
if (field.kind === 'day') {
|
|
49
|
+
return (
|
|
50
|
+
<DayBoundInput
|
|
51
|
+
fill
|
|
52
|
+
mask={copy.filters.dayMask}
|
|
53
|
+
invalidMessage={copy.filters.dayInvalid}
|
|
54
|
+
label={label}
|
|
55
|
+
value={value == null ? undefined : String(value)}
|
|
56
|
+
onChange={onChange}
|
|
57
|
+
testId={testId}
|
|
58
|
+
/>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
return (
|
|
62
|
+
<NumberBoundInput
|
|
63
|
+
fill={fill}
|
|
64
|
+
label={label}
|
|
65
|
+
value={value}
|
|
66
|
+
unit={field.unit}
|
|
67
|
+
onChange={onChange}
|
|
68
|
+
testId={testId}
|
|
69
|
+
/>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
/** One box of the pair: an equal share of the row for a day, as it was for a number. */
|
|
75
|
+
function BoundCell({ grow, children }: { grow: boolean; children: React.ReactNode }): React.JSX.Element {
|
|
76
|
+
if (!grow) return <>{children}</>;
|
|
77
|
+
return <Box sx={{ flex: '1 1 0', minWidth: 0 }}>{children}</Box>;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The line under the pair: why an inverted window matches nothing, or — for a
|
|
82
|
+
* day range — that BOTH days are in the result. Saying so is FUT-668's other
|
|
83
|
+
* half: the bounds compare as ISO strings precisely so `até` keeps its whole
|
|
84
|
+
* day, and nothing on screen would otherwise tell the merchant that.
|
|
85
|
+
*/
|
|
86
|
+
function RangeNote({
|
|
87
|
+
day,
|
|
88
|
+
inverted,
|
|
89
|
+
testId,
|
|
90
|
+
}: {
|
|
91
|
+
day: boolean;
|
|
92
|
+
inverted: boolean;
|
|
93
|
+
testId: string;
|
|
94
|
+
}): React.JSX.Element | null {
|
|
95
|
+
const copy = useDataViewsCopy();
|
|
96
|
+
if (inverted) {
|
|
97
|
+
return (
|
|
98
|
+
<Typography
|
|
99
|
+
component="p"
|
|
100
|
+
data-testid={`${testId}-inverted`}
|
|
101
|
+
sx={{ mt: 0.75, fontSize: sxRem(12), color: 'error.main' }}
|
|
102
|
+
>
|
|
103
|
+
{copy.filters.rangeInvalid}
|
|
104
|
+
</Typography>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
if (!day) return null;
|
|
108
|
+
return (
|
|
109
|
+
<Typography
|
|
110
|
+
component="p"
|
|
111
|
+
data-testid={`${testId}-inclusive`}
|
|
112
|
+
// `text.secondary`, not `disabled`: the note is read, and disabled grey
|
|
113
|
+
// at 12px is 2.68:1 (FUT-4144 UI review).
|
|
114
|
+
sx={{ mt: { xs: 0.25, sm: 0.75 }, fontSize: sxRem(12), color: 'text.secondary' }}
|
|
115
|
+
>
|
|
116
|
+
{copy.filters.rangeInclusiveNote}
|
|
117
|
+
</Typography>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Props of {@link RangeBounds}. */
|
|
122
|
+
interface RangeBoundsProps<T extends Record<string, unknown>> {
|
|
123
|
+
field: RangeFieldConfig<T>;
|
|
124
|
+
value: RangeValue;
|
|
125
|
+
onChange: (range: RangeValue) => void;
|
|
126
|
+
testId: string;
|
|
127
|
+
/**
|
|
128
|
+
* Months the day calendar shows side by side (FUT-4144). Two where the
|
|
129
|
+
* popover has the room; one, with the month/year selectors, on a phone and
|
|
130
|
+
* in the panels.
|
|
131
|
+
*/
|
|
132
|
+
calendarMonths?: 1 | 2;
|
|
133
|
+
/**
|
|
134
|
+
* Whether the day calendar is mounted. A host that keeps the pair mounted
|
|
135
|
+
* while hidden (the slide-in panel) passes its open state, so a closed panel
|
|
136
|
+
* holds no calendar of its own.
|
|
137
|
+
*/
|
|
138
|
+
showCalendar?: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* A NUMBER pair splits the row equally too, as a day pair always does. Set
|
|
141
|
+
* by the panels, whose width is the row's; the pill's popover sizes itself to
|
|
142
|
+
* its content and keeps the boxes' own width.
|
|
143
|
+
*/
|
|
144
|
+
fillRow?: boolean;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* The `De`/`Até` pair for a range — shared by the pill's popover and the
|
|
149
|
+
* slide-in panel's day fields, so the two surfaces cannot drift on what a bound
|
|
150
|
+
* accepts or how it clears.
|
|
151
|
+
*/
|
|
152
|
+
export function RangeBounds<T extends Record<string, unknown>>({
|
|
153
|
+
field,
|
|
154
|
+
value,
|
|
155
|
+
onChange,
|
|
156
|
+
testId,
|
|
157
|
+
calendarMonths = 1,
|
|
158
|
+
showCalendar = true,
|
|
159
|
+
fillRow = false,
|
|
160
|
+
}: RangeBoundsProps<T>): React.JSX.Element {
|
|
161
|
+
const copy = useDataViewsCopy();
|
|
162
|
+
const { key, emitted } = useOutsideResetKey(value);
|
|
163
|
+
// Moves the calendar to a TYPED day. A typed write is the fields' own, so
|
|
164
|
+
// the outside key above does not see it; a tap on the calendar moves
|
|
165
|
+
// neither, which is what keeps it still under the finger.
|
|
166
|
+
const [typed, setTyped] = useState(0);
|
|
167
|
+
const typedChange = (range: RangeValue) => {
|
|
168
|
+
setTyped((n) => n + 1);
|
|
169
|
+
onChange(emitted(range));
|
|
170
|
+
};
|
|
171
|
+
const day = field.kind === 'day';
|
|
172
|
+
return (
|
|
173
|
+
<Box data-testid={`${testId}-panel`}>
|
|
174
|
+
{/* Above the inputs, not below: the presets are the answer for most
|
|
175
|
+
merchants, and the two date pickers are the escape hatch. */}
|
|
176
|
+
<Box sx={{ '&:not(:empty)': { mb: { xs: 1, sm: 1.5 } } }}>
|
|
177
|
+
<RangePresets presets={presetsFor(field, copy)} value={value} onChange={onChange} testId={testId} />
|
|
178
|
+
</Box>
|
|
179
|
+
{/* Top-aligned: a day that does not exist grows ITS field by a message
|
|
180
|
+
line, and centring would push the other box half a line down. The two
|
|
181
|
+
boxes are one height, so with no message this is the same row. */}
|
|
182
|
+
<Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 1.5 }}>
|
|
183
|
+
{/* A day pair shares the row equally, so it spans the calendar under
|
|
184
|
+
it; a number pair keeps its own widths. */}
|
|
185
|
+
<BoundCell grow={day || fillRow}>
|
|
186
|
+
<BoundField
|
|
187
|
+
key={`min-${key}`}
|
|
188
|
+
field={field}
|
|
189
|
+
label={copy.filters.rangeStart}
|
|
190
|
+
value={value.min}
|
|
191
|
+
onChange={(min) => typedChange({ ...value, min })}
|
|
192
|
+
testId={`${testId}-min`}
|
|
193
|
+
fill={fillRow}
|
|
194
|
+
/>
|
|
195
|
+
</BoundCell>
|
|
196
|
+
<BoundCell grow={day || fillRow}>
|
|
197
|
+
<BoundField
|
|
198
|
+
key={`max-${key}`}
|
|
199
|
+
field={field}
|
|
200
|
+
label={copy.filters.rangeEnd}
|
|
201
|
+
value={value.max}
|
|
202
|
+
onChange={(max) => typedChange({ ...value, max })}
|
|
203
|
+
testId={`${testId}-max`}
|
|
204
|
+
fill={fillRow}
|
|
205
|
+
/>
|
|
206
|
+
</BoundCell>
|
|
207
|
+
</Box>
|
|
208
|
+
<RangeNote day={day} inverted={isRangeInverted(value)} testId={testId} />
|
|
209
|
+
{/* Under the boxes and the note, with no button to reach it: the typed
|
|
210
|
+
path stays as short as it was, and a period is two taps (FUT-4144). */}
|
|
211
|
+
{day && showCalendar && (
|
|
212
|
+
<DayRangeCalendar
|
|
213
|
+
fieldLabel={field.label}
|
|
214
|
+
value={value}
|
|
215
|
+
onChange={(range) => onChange(emitted(range))}
|
|
216
|
+
months={calendarMonths}
|
|
217
|
+
viewKey={`${key}-${typed}`}
|
|
218
|
+
testId={testId}
|
|
219
|
+
/>
|
|
220
|
+
)}
|
|
221
|
+
</Box>
|
|
222
|
+
);
|
|
223
|
+
}
|