@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
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The range calendar under a day filter's `De`/`Até` boxes (FUT-4144).
|
|
5
|
+
*
|
|
6
|
+
* The owner picked it ALWAYS OPEN (option B of the prototype): a period is
|
|
7
|
+
* three taps — open the filter, the first day, the last day — against five for
|
|
8
|
+
* a calendar button in each box and four for a link to a separate sheet. It
|
|
9
|
+
* sits BELOW the boxes, with no button of its own, so the typed path is not one
|
|
10
|
+
* keystroke longer than it was.
|
|
11
|
+
*
|
|
12
|
+
* The boxes and the calendar are two views of ONE range: a tap writes the
|
|
13
|
+
* boxes, a typed day moves and repaints the calendar, an impossible typed day
|
|
14
|
+
* (which writes nothing) leaves it alone, and "Limpar" empties both.
|
|
15
|
+
*
|
|
16
|
+
* It is `Calendar` in `selectionMode="range"`, the same one `DateRangePicker`
|
|
17
|
+
* mounts — not a second calendar. Its own rule picks the period: the first tap
|
|
18
|
+
* starts it, the second closes it, and a second tap BEFORE the first swaps the
|
|
19
|
+
* two, so the boxes never show a period backwards.
|
|
20
|
+
*/
|
|
21
|
+
import Box from '@mui/material/Box/index.js';
|
|
22
|
+
import Typography from '@mui/material/Typography/index.js';
|
|
23
|
+
import React from 'react';
|
|
24
|
+
|
|
25
|
+
import { EN_US_DATA_VIEWS_COPY } from '../../../en-US.data-display';
|
|
26
|
+
import type { Theme } from '@mui/material/styles/index.js';
|
|
27
|
+
import { rem, sxRem } from '../../../tokens/relative';
|
|
28
|
+
import { Calendar, type DateRange } from '../../form/Calendar';
|
|
29
|
+
import { toDayString, toLocalDay } from '../../form/DateRangePicker/DateRangePicker.dates';
|
|
30
|
+
import type { DataViewsDayCalendarCopy } from './data-views-copy';
|
|
31
|
+
import { useDataViewsCopy } from './data-views-copy-context';
|
|
32
|
+
import type { RangeValue } from './data-views-types';
|
|
33
|
+
|
|
34
|
+
const CALENDAR_CLASS = 'data-views-range-calendar';
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* `Calendar` draws its own `Paper` with 24px of padding and a shadow. Inside
|
|
38
|
+
* the filter's popover that reads as a card inside a card, so the inner frame
|
|
39
|
+
* is flattened through the class hook the component offers for this — the
|
|
40
|
+
* same thing `DateRangePicker` does.
|
|
41
|
+
*/
|
|
42
|
+
const ROOT_SX = (theme: Theme) => ({
|
|
43
|
+
mt: { xs: 1, sm: 1.5 },
|
|
44
|
+
// Below `sm` the caption and the weekday row give up their bottom margins,
|
|
45
|
+
// so the whole popover fits a 320×568 screen under its pill (FUT-4144).
|
|
46
|
+
'& :has(> * > [data-testid="calendar-month-select"])': { mb: { xs: 0.5, sm: 2 } },
|
|
47
|
+
'& :has(> [role="columnheader"])': { mb: { xs: 0, sm: 1 } },
|
|
48
|
+
'& [role="columnheader"]': { height: { xs: rem(theme, 24), sm: rem(theme, 32) } },
|
|
49
|
+
// The days carry no column gap of their own (`Calendar`, FUT-4162), so the
|
|
50
|
+
// seven columns are what a day's 40px target is carved from below `sm`; the
|
|
51
|
+
// range band and its round endpoints are the Calendar's, untouched here.
|
|
52
|
+
// The month/year caption on ONE row at 320: the selectors give up the slack
|
|
53
|
+
// around their text before the arrows are pushed onto a second row.
|
|
54
|
+
'& [data-testid="calendar-month-select"], & [data-testid="calendar-year-select"]': { px: 0.5, minWidth: 0 },
|
|
55
|
+
[`& .${CALENDAR_CLASS}`]: {
|
|
56
|
+
p: 0,
|
|
57
|
+
boxShadow: 'none',
|
|
58
|
+
backgroundColor: 'transparent',
|
|
59
|
+
backgroundImage: 'none',
|
|
60
|
+
// A tapped day already rings itself; the whole grid framed in the primary
|
|
61
|
+
// colour after every tap is noise in a popover. The frame stays for the
|
|
62
|
+
// keyboard reaching the grid itself.
|
|
63
|
+
'&:focus-within': { outline: 'none' },
|
|
64
|
+
'&:focus-visible': {
|
|
65
|
+
outline: (theme: Theme) => `${rem(theme, 2)} solid`,
|
|
66
|
+
outlineColor: 'primary.main',
|
|
67
|
+
outlineOffset: sxRem(2),
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
/** The two ends of a range, as `Calendar` reads them. */
|
|
73
|
+
function rangeOf(value: RangeValue): DateRange {
|
|
74
|
+
return {
|
|
75
|
+
start: toLocalDay(typeof value.min === 'string' ? value.min : null),
|
|
76
|
+
end: toLocalDay(typeof value.max === 'string' ? value.max : null),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* What a tap on the calendar makes of the range.
|
|
82
|
+
*
|
|
83
|
+
* `Calendar` reports the period it holds after the tap: a fresh start (`end`
|
|
84
|
+
* null) or a closed one, already in order. The one case it cannot see is a
|
|
85
|
+
* range with only `Até` — typed, or left by a saved view — where its first tap
|
|
86
|
+
* would drop that `Até`. A first day on or before it keeps it, so "até 15/10"
|
|
87
|
+
* plus one tap on the 3rd is 03/10–15/10, as the prototype does.
|
|
88
|
+
*/
|
|
89
|
+
export function rangeFromCalendar(previous: RangeValue, picked: DateRange): RangeValue {
|
|
90
|
+
const min = dayOf(picked.start);
|
|
91
|
+
const max = dayOf(picked.end) ?? keptEnd(previous, min);
|
|
92
|
+
return { ...(min ? { min } : {}), ...(max ? { max } : {}) };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const dayOf = (date: Date | null | undefined): string | undefined => (date ? toDayString(date) : undefined);
|
|
96
|
+
|
|
97
|
+
/** The `Até` of a range that has ONLY one, when the new first day is on or before it. */
|
|
98
|
+
function keptEnd(previous: RangeValue, min: string | undefined): string | undefined {
|
|
99
|
+
if (previous.min != null || typeof previous.max !== 'string') return undefined;
|
|
100
|
+
return min && min <= previous.max ? previous.max : undefined;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* The month the calendar opens on while `De` is empty. With `De` set it opens
|
|
105
|
+
* on De's month, which `Calendar` does by itself.
|
|
106
|
+
*
|
|
107
|
+
* With two months the current month sits on the RIGHT (setembro | outubro), so
|
|
108
|
+
* the days a filter usually asks about — the ones just past — are on screen;
|
|
109
|
+
* with only `Até` set, its month takes that place.
|
|
110
|
+
*/
|
|
111
|
+
function openingMonth(value: RangeValue, months: number): Date | undefined {
|
|
112
|
+
const end = toLocalDay(typeof value.max === 'string' ? value.max : null);
|
|
113
|
+
const anchor = end ?? new Date();
|
|
114
|
+
return new Date(anchor.getFullYear(), anchor.getMonth() - (months > 1 ? 1 : 0), 1);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** Props of {@link DayRangeCalendar}. */
|
|
118
|
+
export interface DayRangeCalendarProps {
|
|
119
|
+
/** The filter's own label ("Data"), which names the calendar. */
|
|
120
|
+
fieldLabel: string;
|
|
121
|
+
value: RangeValue;
|
|
122
|
+
/** Called with the range a tap leaves; never for a typed day. */
|
|
123
|
+
onChange: (range: RangeValue) => void;
|
|
124
|
+
/**
|
|
125
|
+
* Months side by side. Two read as a period at a glance where there is room;
|
|
126
|
+
* one, with the month/year selectors, where there is not.
|
|
127
|
+
*/
|
|
128
|
+
months: 1 | 2;
|
|
129
|
+
/**
|
|
130
|
+
* Changes when the range moved from OUTSIDE the calendar (typed, a preset,
|
|
131
|
+
* "Limpar"), so the calendar re-opens on it. Never for its own taps: a
|
|
132
|
+
* calendar that jumped under the finger picking in it would be unusable.
|
|
133
|
+
*/
|
|
134
|
+
viewKey: string;
|
|
135
|
+
testId: string;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function DayRangeCalendar({
|
|
139
|
+
fieldLabel,
|
|
140
|
+
value,
|
|
141
|
+
onChange,
|
|
142
|
+
months,
|
|
143
|
+
viewKey,
|
|
144
|
+
testId,
|
|
145
|
+
}: DayRangeCalendarProps): React.JSX.Element {
|
|
146
|
+
const copy: DataViewsDayCalendarCopy =
|
|
147
|
+
useDataViewsCopy().filters.dayCalendar ?? (EN_US_DATA_VIEWS_COPY.filters.dayCalendar as DataViewsDayCalendarCopy);
|
|
148
|
+
const range = rangeOf(value);
|
|
149
|
+
const pick = (picked: DateRange) => onChange(rangeFromCalendar(value, picked));
|
|
150
|
+
const waitingForEnd = Boolean(range.start && !range.end);
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<Box sx={ROOT_SX} data-testid={`${testId}-calendar`}>
|
|
154
|
+
<Calendar
|
|
155
|
+
key={viewKey}
|
|
156
|
+
ariaLabel={copy.label(fieldLabel)}
|
|
157
|
+
className={CALENDAR_CLASS}
|
|
158
|
+
selectionMode="range"
|
|
159
|
+
locale={copy.locale}
|
|
160
|
+
labels={copy.caption}
|
|
161
|
+
// Sunday first, as a pt-BR calendar reads (`D S T Q Q S S`) and as the
|
|
162
|
+
// presets' "Esta semana" counts.
|
|
163
|
+
firstDayOfWeek={0}
|
|
164
|
+
numberOfMonths={months}
|
|
165
|
+
// Side by side, a day of the next month in this one is the same day
|
|
166
|
+
// twice; one month alone keeps them, muted, as a six-week frame.
|
|
167
|
+
showOutsideDays={months === 1}
|
|
168
|
+
captionLayout={months > 1 ? 'arrows' : 'selectors'}
|
|
169
|
+
defaultMonth={openingMonth(value, months)}
|
|
170
|
+
range={range}
|
|
171
|
+
// The intermediate callback does the work: the other fires only on the
|
|
172
|
+
// tap that CLOSES a period, so the first tap would write nothing.
|
|
173
|
+
onIntermediateRangeChange={pick}
|
|
174
|
+
/>
|
|
175
|
+
<Typography
|
|
176
|
+
component="p"
|
|
177
|
+
aria-live="polite"
|
|
178
|
+
data-testid={`${testId}-calendar-hint`}
|
|
179
|
+
sx={{ mt: { xs: 0.25, sm: 1 }, fontSize: sxRem(12), color: 'text.secondary' }}
|
|
180
|
+
>
|
|
181
|
+
{waitingForEnd ? copy.pickEnd : copy.pickStart}
|
|
182
|
+
</Typography>
|
|
183
|
+
</Box>
|
|
184
|
+
);
|
|
185
|
+
}
|
|
@@ -17,14 +17,17 @@ import Box from '@mui/material/Box/index.js';
|
|
|
17
17
|
import Button from '@mui/material/Button/index.js';
|
|
18
18
|
import Popover from '@mui/material/Popover/index.js';
|
|
19
19
|
import Typography from '@mui/material/Typography/index.js';
|
|
20
|
-
import
|
|
20
|
+
import useMediaQuery from '@mui/material/useMediaQuery/index.js';
|
|
21
|
+
import { useTheme, type Theme } from '@mui/material/styles/index.js';
|
|
22
|
+
import React, { useContext } from 'react';
|
|
21
23
|
|
|
22
24
|
import { useDataViewsCopy } from "./data-views-copy-context";
|
|
23
25
|
import { TableFilter } from '../../layout/TableFilter';
|
|
24
|
-
import {
|
|
25
|
-
import { NumberBoundInput } from './data-views-number-input';
|
|
26
|
+
import { TableFilterContext } from '../../layout/TableFilter/TableFilterContext';
|
|
26
27
|
import { RangePresets } from './data-views-preset-chips';
|
|
27
|
-
import {
|
|
28
|
+
import { RangeBounds } from './data-views-range-bounds';
|
|
29
|
+
import { RangeSummary } from './data-views-range-summary';
|
|
30
|
+
import { useStillAnchor } from './data-views-still-anchor';
|
|
28
31
|
import { presetsFor } from './data-views-range-presets';
|
|
29
32
|
import {
|
|
30
33
|
isRangeInverted,
|
|
@@ -36,126 +39,10 @@ import type { RangeFieldConfig, RangeValue } from './data-views-types';
|
|
|
36
39
|
import { fieldRadiusPx } from '../../../tokens/field-radius';
|
|
37
40
|
import { fieldHeight } from '../../../tokens/field-height';
|
|
38
41
|
import { fieldEdge } from '../../../tokens/field-edge';
|
|
39
|
-
import { sxRem } from '../../../tokens/relative';
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* One end of the range. A day keeps its `AAAA-MM-DD` string verbatim (the form
|
|
45
|
-
* both the field and the backend speak) and is typed through the masked
|
|
46
|
-
* `dd/mm/aaaa` field rather than a native date input — see
|
|
47
|
-
* {@link DayBoundInput} for why. A number parses, and an unparseable/blank
|
|
48
|
-
* entry CLEARS the bound rather than writing `NaN`.
|
|
49
|
-
*/
|
|
50
|
-
function BoundField<T extends Record<string, unknown>>({
|
|
51
|
-
field,
|
|
52
|
-
label,
|
|
53
|
-
value,
|
|
54
|
-
onChange,
|
|
55
|
-
testId,
|
|
56
|
-
}: {
|
|
57
|
-
field: RangeFieldConfig<T>;
|
|
58
|
-
label: string;
|
|
59
|
-
value: number | string | undefined;
|
|
60
|
-
onChange: (bound: number | string | undefined) => void;
|
|
61
|
-
testId: string;
|
|
62
|
-
}): React.JSX.Element {
|
|
63
|
-
const copy = useDataViewsCopy();
|
|
64
|
-
if (field.kind === 'day') {
|
|
65
|
-
return (
|
|
66
|
-
<DayBoundInput
|
|
67
|
-
mask={copy.filters.dayMask}
|
|
68
|
-
invalidMessage={copy.filters.dayInvalid}
|
|
69
|
-
label={label}
|
|
70
|
-
value={value == null ? undefined : String(value)}
|
|
71
|
-
onChange={onChange}
|
|
72
|
-
testId={testId}
|
|
73
|
-
/>
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
return (
|
|
77
|
-
<NumberBoundInput
|
|
78
|
-
label={label}
|
|
79
|
-
value={value}
|
|
80
|
-
unit={field.unit}
|
|
81
|
-
onChange={onChange}
|
|
82
|
-
testId={testId}
|
|
83
|
-
/>
|
|
84
|
-
);
|
|
85
|
-
}
|
|
42
|
+
import { rem, remPx, sxRem } from '../../../tokens/relative';
|
|
86
43
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
* The `De`/`Até` pair for a range — shared by the pill's popover and the
|
|
90
|
-
* slide-in panel's day fields, so the two surfaces cannot drift on what a bound
|
|
91
|
-
* accepts or how it clears.
|
|
92
|
-
*/
|
|
93
|
-
export function RangeBounds<T extends Record<string, unknown>>({
|
|
94
|
-
field,
|
|
95
|
-
value,
|
|
96
|
-
onChange,
|
|
97
|
-
testId,
|
|
98
|
-
}: {
|
|
99
|
-
field: RangeFieldConfig<T>;
|
|
100
|
-
value: RangeValue;
|
|
101
|
-
onChange: (range: RangeValue) => void;
|
|
102
|
-
testId: string;
|
|
103
|
-
}): React.JSX.Element {
|
|
104
|
-
const copy = useDataViewsCopy();
|
|
105
|
-
const inverted = isRangeInverted(value);
|
|
106
|
-
const { key, emitted } = useOutsideResetKey(value);
|
|
107
|
-
return (
|
|
108
|
-
<Box data-testid={`${testId}-panel`}>
|
|
109
|
-
{/* Above the inputs, not below: the presets are the answer for most
|
|
110
|
-
merchants, and the two date pickers are the escape hatch. */}
|
|
111
|
-
<Box sx={{ '&:not(:empty)': { mb: 1.5 } }}>
|
|
112
|
-
<RangePresets presets={presetsFor(field, copy)} value={value} onChange={onChange} testId={testId} />
|
|
113
|
-
</Box>
|
|
114
|
-
{/* Top-aligned: a day that does not exist grows ITS field by a message
|
|
115
|
-
line, and centring would push the other box half a line down. The two
|
|
116
|
-
boxes are one height, so with no message this is the same row. */}
|
|
117
|
-
<Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 1.5 }}>
|
|
118
|
-
<BoundField
|
|
119
|
-
key={`min-${key}`}
|
|
120
|
-
field={field}
|
|
121
|
-
label={copy.filters.rangeStart}
|
|
122
|
-
value={value.min}
|
|
123
|
-
onChange={(min) => onChange(emitted({ ...value, min }))}
|
|
124
|
-
testId={`${testId}-min`}
|
|
125
|
-
/>
|
|
126
|
-
<BoundField
|
|
127
|
-
key={`max-${key}`}
|
|
128
|
-
field={field}
|
|
129
|
-
label={copy.filters.rangeEnd}
|
|
130
|
-
value={value.max}
|
|
131
|
-
onChange={(max) => onChange(emitted({ ...value, max }))}
|
|
132
|
-
testId={`${testId}-max`}
|
|
133
|
-
/>
|
|
134
|
-
</Box>
|
|
135
|
-
{inverted && (
|
|
136
|
-
<Typography
|
|
137
|
-
component="p"
|
|
138
|
-
data-testid={`${testId}-inverted`}
|
|
139
|
-
sx={{ mt: 0.75, fontSize: sxRem(12), color: 'error.main' }}
|
|
140
|
-
>
|
|
141
|
-
{copy.filters.rangeInvalid}
|
|
142
|
-
</Typography>
|
|
143
|
-
)}
|
|
144
|
-
{/* BOTH days are in the result. Saying so is FUT-668's other half: the
|
|
145
|
-
bounds compare as ISO strings precisely so `até` keeps its whole day,
|
|
146
|
-
and nothing on screen would otherwise tell the merchant that. */}
|
|
147
|
-
{field.kind === 'day' && !inverted && (
|
|
148
|
-
<Typography
|
|
149
|
-
component="p"
|
|
150
|
-
data-testid={`${testId}-inclusive`}
|
|
151
|
-
sx={{ mt: 0.75, fontSize: sxRem(12), color: 'text.disabled' }}
|
|
152
|
-
>
|
|
153
|
-
{copy.filters.rangeInclusiveNote}
|
|
154
|
-
</Typography>
|
|
155
|
-
)}
|
|
156
|
-
</Box>
|
|
157
|
-
);
|
|
158
|
-
}
|
|
44
|
+
// Re-exported: the pair moved to its own file, and its importers keep their path.
|
|
45
|
+
export { RangeBounds };
|
|
159
46
|
|
|
160
47
|
/**
|
|
161
48
|
* The pill + its popover. Bounds commit on change (the list is server-driven, so
|
|
@@ -265,6 +152,38 @@ function RangeTrigger<T extends Record<string, unknown>>({
|
|
|
265
152
|
);
|
|
266
153
|
}
|
|
267
154
|
|
|
155
|
+
/**
|
|
156
|
+
* How many months the pill's calendar shows: two from the theme's `md` up,
|
|
157
|
+
* where the popover has the ~670px they take; one below it.
|
|
158
|
+
*
|
|
159
|
+
* A media query, not an `sx` breakpoint, because it decides what to RENDER —
|
|
160
|
+
* CSS cannot un-render a second month. `up('md')` so that where nothing can be
|
|
161
|
+
* measured (a test, the server) the answer is the one month that always fits.
|
|
162
|
+
*/
|
|
163
|
+
function useCalendarMonths(): 1 | 2 {
|
|
164
|
+
const theme = useTheme();
|
|
165
|
+
return useMediaQuery(theme.breakpoints.up('md')) ? 2 : 1;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* The day popover's width. Below `sm` it takes the screen's (less the
|
|
170
|
+
* popover's own 16px margins, which its `maxWidth` already keeps), so the boxes
|
|
171
|
+
* and the month share it instead of leaving a strip of grid beside a narrow
|
|
172
|
+
* card. From `sm` to `md` it holds one month, and sized to its content the
|
|
173
|
+
* preset row alone stretched it to ~515px with the month hugging the left and
|
|
174
|
+
* a band of nothing beside it; 400 keeps the month and the boxes one width.
|
|
175
|
+
* From `md` its content — two months — sets it.
|
|
176
|
+
*/
|
|
177
|
+
const DAY_PAPER_SX = (theme: Theme) => ({
|
|
178
|
+
width: { xs: '100%', sm: rem(theme, 400), md: 'auto' },
|
|
179
|
+
// Below `sm` 8px from each edge and 8px of padding, so the month gets the
|
|
180
|
+
// 280px seven 40px day columns need: at 320 it had 256 and every day was a
|
|
181
|
+
// 33px target (FUT-4144 UI review).
|
|
182
|
+
maxWidth: { xs: `calc(100% - ${rem(theme, 16)})`, sm: `calc(100% - ${rem(theme, 32)})` },
|
|
183
|
+
p: { xs: 1, sm: 2 },
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
|
|
268
187
|
export function RangePill<T extends Record<string, unknown>>({
|
|
269
188
|
field,
|
|
270
189
|
value,
|
|
@@ -279,10 +198,11 @@ export function RangePill<T extends Record<string, unknown>>({
|
|
|
279
198
|
onOpenChange?: (open: boolean) => void;
|
|
280
199
|
testIdPrefix: string;
|
|
281
200
|
}): React.JSX.Element {
|
|
282
|
-
const
|
|
283
|
-
const [anchor, setAnchor] = useState<HTMLElement | null>(null);
|
|
284
|
-
const active = isRangeSet(value);
|
|
201
|
+
const still = useStillAnchor();
|
|
285
202
|
const testId = `${testIdPrefix}-range-${field.id}`;
|
|
203
|
+
const calendarMonths = useCalendarMonths();
|
|
204
|
+
const theme = useTheme();
|
|
205
|
+
const phone = useMediaQuery(theme.breakpoints.down('sm'));
|
|
286
206
|
return (
|
|
287
207
|
<>
|
|
288
208
|
<RangeTrigger
|
|
@@ -290,42 +210,30 @@ export function RangePill<T extends Record<string, unknown>>({
|
|
|
290
210
|
value={value}
|
|
291
211
|
onChange={onChange}
|
|
292
212
|
onOpen={(element) => {
|
|
293
|
-
|
|
213
|
+
still.open(element);
|
|
294
214
|
onOpenChange?.(true);
|
|
295
215
|
}}
|
|
296
|
-
open={Boolean(anchor)}
|
|
216
|
+
open={Boolean(still.anchor)}
|
|
297
217
|
testId={testId}
|
|
298
218
|
/>
|
|
299
219
|
<Popover
|
|
300
|
-
|
|
301
|
-
anchorEl={anchor}
|
|
220
|
+
{...still.popoverProps}
|
|
302
221
|
onClose={() => {
|
|
303
|
-
|
|
222
|
+
still.close();
|
|
304
223
|
onOpenChange?.(false);
|
|
305
224
|
}}
|
|
306
|
-
|
|
307
|
-
|
|
225
|
+
// Below `sm` a day popover keeps 8px from the screen's edges instead of 16.
|
|
226
|
+
marginThreshold={field.kind === 'day' && phone ? remPx(theme, 8) : undefined}
|
|
227
|
+
slotProps={{ paper: { ref: still.paperRef, sx: [{ p: 2, mt: 0.5 }, field.kind === 'day' && DAY_PAPER_SX] } }}
|
|
308
228
|
>
|
|
309
|
-
<RangeBounds
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
</Typography>
|
|
318
|
-
<Button
|
|
319
|
-
variant="text"
|
|
320
|
-
size="small"
|
|
321
|
-
onClick={() => onChange({})}
|
|
322
|
-
data-testid={`${testId}-clear`}
|
|
323
|
-
sx={{ textTransform: 'none' }}
|
|
324
|
-
>
|
|
325
|
-
{copy.filters.clear}
|
|
326
|
-
</Button>
|
|
327
|
-
</Box>
|
|
328
|
-
)}
|
|
229
|
+
<RangeBounds
|
|
230
|
+
field={field}
|
|
231
|
+
value={value}
|
|
232
|
+
onChange={onChange}
|
|
233
|
+
testId={testId}
|
|
234
|
+
calendarMonths={calendarMonths}
|
|
235
|
+
/>
|
|
236
|
+
<RangeSummary field={field} value={value} onClear={() => onChange({})} testId={testId} />
|
|
329
237
|
</Popover>
|
|
330
238
|
</>
|
|
331
239
|
);
|
|
@@ -349,13 +257,22 @@ export function PanelRangeField<T extends Record<string, unknown>>({
|
|
|
349
257
|
testId: string;
|
|
350
258
|
}): React.JSX.Element {
|
|
351
259
|
const copy = useDataViewsCopy();
|
|
260
|
+
// The slide-in panel stays mounted while closed; its calendar does not.
|
|
261
|
+
// Outside a `TableFilter` (the "Mais" sheet, a test) the pair is on screen.
|
|
262
|
+
const panel = useContext(TableFilterContext);
|
|
352
263
|
if (field.kind === "day") {
|
|
353
264
|
return (
|
|
354
265
|
<Box sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
|
|
355
266
|
<Typography component="span" sx={{ fontSize: sxRem(12), fontWeight: 500, color: "text.secondary" }}>
|
|
356
267
|
{field.label}
|
|
357
268
|
</Typography>
|
|
358
|
-
<RangeBounds
|
|
269
|
+
<RangeBounds
|
|
270
|
+
field={field}
|
|
271
|
+
value={value}
|
|
272
|
+
onChange={onChange}
|
|
273
|
+
testId={testId}
|
|
274
|
+
showCalendar={panel ? panel.open : true}
|
|
275
|
+
/>
|
|
359
276
|
</Box>
|
|
360
277
|
);
|
|
361
278
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import Box from '@mui/material/Box/index.js';
|
|
4
|
+
import Button from '@mui/material/Button/index.js';
|
|
5
|
+
import Typography from '@mui/material/Typography/index.js';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
|
|
8
|
+
import { useDataViewsCopy } from './data-views-copy-context';
|
|
9
|
+
import { isRangeSet, rangeChipLabel } from './data-views-range-values';
|
|
10
|
+
import type { RangeFieldConfig, RangeValue } from './data-views-types';
|
|
11
|
+
import { sxRem } from '../../../tokens/relative';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The applied window in words, and "Limpar".
|
|
15
|
+
*
|
|
16
|
+
* An inverted window is not an error the merchant must fix before the list
|
|
17
|
+
* responds — it simply matches nothing, and saying so beats an empty grid with
|
|
18
|
+
* no explanation (FUT-668).
|
|
19
|
+
*
|
|
20
|
+
* A DAY filter keeps the row's height while nothing is applied: its first tap
|
|
21
|
+
* on the calendar applies a bound, and a row appearing then grew the popover
|
|
22
|
+
* 26px and moved it 32px up at 320×568, the day under the finger with it
|
|
23
|
+
* (FUT-4144 UI review round 2). The held row is invisible and inert.
|
|
24
|
+
*/
|
|
25
|
+
export function RangeSummary<T extends Record<string, unknown>>({
|
|
26
|
+
field,
|
|
27
|
+
value,
|
|
28
|
+
onClear,
|
|
29
|
+
testId,
|
|
30
|
+
}: {
|
|
31
|
+
field: RangeFieldConfig<T>;
|
|
32
|
+
value: RangeValue;
|
|
33
|
+
onClear: () => void;
|
|
34
|
+
testId: string;
|
|
35
|
+
}): React.JSX.Element | null {
|
|
36
|
+
const copy = useDataViewsCopy();
|
|
37
|
+
const active = isRangeSet(value);
|
|
38
|
+
if (!active && field.kind !== 'day') return null;
|
|
39
|
+
return (
|
|
40
|
+
<Box
|
|
41
|
+
aria-hidden={active ? undefined : true}
|
|
42
|
+
sx={{
|
|
43
|
+
display: 'flex',
|
|
44
|
+
alignItems: 'center',
|
|
45
|
+
justifyContent: 'space-between',
|
|
46
|
+
gap: 2,
|
|
47
|
+
mt: { xs: 0.5, sm: 1.5 },
|
|
48
|
+
visibility: active ? undefined : 'hidden',
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
<Typography component="span" sx={{ fontSize: sxRem(12), color: 'text.secondary' }}>
|
|
52
|
+
{active ? rangeChipLabel(field, value) : field.label}
|
|
53
|
+
</Typography>
|
|
54
|
+
<Button
|
|
55
|
+
variant="text"
|
|
56
|
+
size="small"
|
|
57
|
+
onClick={active ? onClear : undefined}
|
|
58
|
+
tabIndex={active ? undefined : -1}
|
|
59
|
+
data-testid={active ? `${testId}-clear` : undefined}
|
|
60
|
+
sx={{ textTransform: 'none' }}
|
|
61
|
+
>
|
|
62
|
+
{copy.filters.clear}
|
|
63
|
+
</Button>
|
|
64
|
+
</Box>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import type { PopoverActions } from '@mui/material/Popover/index.js';
|
|
4
|
+
import { useCallback, useEffect, useRef, useState, type RefObject } from 'react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* What the popover hangs from: the trigger's box as it was when it opened —
|
|
8
|
+
* a MUI "virtual element", so the popover keeps its own anchor origin.
|
|
9
|
+
*/
|
|
10
|
+
interface StillElement {
|
|
11
|
+
nodeType: 1;
|
|
12
|
+
getBoundingClientRect: () => DOMRect;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const stillOf = (element: HTMLElement): StillElement => {
|
|
16
|
+
const box = element.getBoundingClientRect();
|
|
17
|
+
return { nodeType: 1, getBoundingClientRect: () => box };
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A popover that holds STILL while it is open (FUT-4144 UI review round 2).
|
|
22
|
+
*
|
|
23
|
+
* Anchored to an element, a popover follows it. A filter applied from inside
|
|
24
|
+
* one grows the toolbar a "Limpar" and a badge, the trigger moves, and the
|
|
25
|
+
* panel jumped 55px sideways under the finger that had just tapped a day. The
|
|
26
|
+
* point it hangs from is read once, when it opens — and again only when the
|
|
27
|
+
* window itself is resized, which is the one move a reader expects it to make.
|
|
28
|
+
*
|
|
29
|
+
* The other move it makes is when its own HEIGHT changes after it was placed
|
|
30
|
+
* (a preset row settling into a select once measured, a refused day's message):
|
|
31
|
+
* MUI places a popover once, so a taller one ran off a 320×568 screen. The
|
|
32
|
+
* paper's size is watched and the popover re-placed, which moves it only when
|
|
33
|
+
* its height really changed — never on a tap that leaves it the same size.
|
|
34
|
+
*
|
|
35
|
+
* Spread `popoverProps` onto a MUI `Popover` and pass `paperRef` as the paper
|
|
36
|
+
* slot's `ref`.
|
|
37
|
+
*/
|
|
38
|
+
export function useStillAnchor(): {
|
|
39
|
+
anchor: HTMLElement | null;
|
|
40
|
+
open: (element: HTMLElement) => void;
|
|
41
|
+
close: () => void;
|
|
42
|
+
paperRef: (node: HTMLDivElement | null) => void;
|
|
43
|
+
popoverProps: {
|
|
44
|
+
open: boolean;
|
|
45
|
+
anchorEl: StillElement | null;
|
|
46
|
+
anchorOrigin: { vertical: 'bottom'; horizontal: 'left' };
|
|
47
|
+
action: RefObject<PopoverActions | null>;
|
|
48
|
+
};
|
|
49
|
+
} {
|
|
50
|
+
const [anchor, setAnchor] = useState<HTMLElement | null>(null);
|
|
51
|
+
const [still, setStill] = useState<StillElement | null>(null);
|
|
52
|
+
const action = useRef<PopoverActions | null>(null);
|
|
53
|
+
const observer = useRef<ResizeObserver | null>(null);
|
|
54
|
+
const paperRef = useCallback((node: HTMLDivElement | null) => {
|
|
55
|
+
observer.current?.disconnect();
|
|
56
|
+
observer.current = null;
|
|
57
|
+
if (!node || typeof ResizeObserver === 'undefined') return;
|
|
58
|
+
let height = node.offsetHeight;
|
|
59
|
+
observer.current = new ResizeObserver(() => {
|
|
60
|
+
if (node.offsetHeight === height) return;
|
|
61
|
+
height = node.offsetHeight;
|
|
62
|
+
action.current?.updatePosition();
|
|
63
|
+
});
|
|
64
|
+
observer.current.observe(node);
|
|
65
|
+
}, []);
|
|
66
|
+
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
if (!anchor) return undefined;
|
|
69
|
+
// A trigger unmounted while its panel is open reads a zero box: keep the
|
|
70
|
+
// frozen one rather than send the panel to the corner.
|
|
71
|
+
const follow = (): void => {
|
|
72
|
+
if (anchor.isConnected) setStill(stillOf(anchor));
|
|
73
|
+
};
|
|
74
|
+
window.addEventListener('resize', follow);
|
|
75
|
+
return () => window.removeEventListener('resize', follow);
|
|
76
|
+
}, [anchor]);
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
anchor,
|
|
80
|
+
open: (element) => {
|
|
81
|
+
setStill(stillOf(element));
|
|
82
|
+
setAnchor(element);
|
|
83
|
+
},
|
|
84
|
+
close: () => setAnchor(null),
|
|
85
|
+
paperRef,
|
|
86
|
+
popoverProps: {
|
|
87
|
+
open: Boolean(anchor),
|
|
88
|
+
anchorEl: anchor ? still : null,
|
|
89
|
+
anchorOrigin: { vertical: 'bottom', horizontal: 'left' },
|
|
90
|
+
action,
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|