@12-apps/ui 6.83.0 → 6.84.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/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/Carousel/Carousel.chrome.js +3 -3
- package/dist/_internal/components/data-display/Carousel/Carousel.js +5 -5
- package/dist/_internal/components/data-display/Carousel/Carousel.parts.js +2 -2
- package/dist/_internal/components/data-display/Chart/Chart.js +3 -3
- package/dist/_internal/components/data-display/Chart/SpecChart.js +6 -6
- package/dist/_internal/components/data-display/Chart/chart-renderers.js +2 -2
- package/dist/_internal/components/data-display/Chart/chart-spec.js +2 -2
- package/dist/_internal/components/data-display/DataGrid/DataGrid.js +2 -2
- package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +20 -19
- package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +21 -20
- package/dist/_internal/components/data-display/DataViews/base-list-card.js +2 -2
- package/dist/_internal/components/data-display/DataViews/data-views-day-input.js +7 -3
- package/dist/_internal/components/data-display/DataViews/data-views-display-panel.js +2 -2
- package/dist/_internal/components/data-display/DataViews/data-views-empty.js +1 -1
- package/dist/_internal/components/data-display/DataViews/data-views-filter-panel.js +5 -4
- package/dist/_internal/components/data-display/DataViews/data-views-grid-bodies.js +3 -3
- package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +17 -16
- package/dist/_internal/components/data-display/DataViews/data-views-inline-bar.js +7 -6
- package/dist/_internal/components/data-display/DataViews/data-views-more-fields.js +5 -4
- package/dist/_internal/components/data-display/DataViews/data-views-more-filters.js +6 -5
- package/dist/_internal/components/data-display/DataViews/data-views-range-pill.js +4 -3
- package/dist/_internal/components/data-display/DataViews/data-views-range-reset.js +9 -0
- package/dist/_internal/components/data-display/DataViews/data-views-range-reset.js.map +1 -0
- package/dist/_internal/components/data-display/DataViews/data-views-shell-toolbar.js +4 -4
- package/dist/_internal/components/data-display/DataViews/data-views-toolbar.js +3 -3
- package/dist/_internal/components/data-display/DataViews/data-views-writers.js +3 -1
- package/dist/_internal/components/data-display/DataViews/use-data-views-state.js +2 -2
- package/dist/_internal/components/data-display/FleetMap/FleetBody.js +8 -8
- package/dist/_internal/components/data-display/FleetMap/FleetCanvas.js +7 -7
- package/dist/_internal/components/data-display/FleetMap/FleetMap.fixtures.js +1 -1
- package/dist/_internal/components/data-display/FleetMap/FleetMap.js +9 -9
- package/dist/_internal/components/data-display/MapPreview/MapControlBar.js +3 -3
- package/dist/_internal/components/data-display/MapPreview/MapLayers.js +4 -4
- package/dist/_internal/components/data-display/MapPreview/MapMarkers.js +3 -3
- package/dist/_internal/components/data-display/MapPreview/MapPreview.helpers.js +2 -2
- package/dist/_internal/components/data-display/MapPreview/MapPreview.js +6 -6
- package/dist/_internal/components/data-display/index.js +29 -29
- package/dist/_internal/components/form/CepField/CepField.js +1 -1
- package/dist/_internal/components/form/DateRangePicker/DateRangePicker.hooks.js +3 -3
- package/dist/_internal/components/form/DateRangePicker/DateRangePicker.js +5 -5
- 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/InputOTP/InputOTP.hooks.js +1 -1
- package/dist/_internal/components/form/InputOTP/InputOTP.js +2 -2
- package/dist/_internal/components/form/index.js +8 -8
- package/dist/_internal/components/form/total-form/Fields/CepField.js +2 -2
- package/dist/_internal/components/form/total-form/Fields/TextField.js +1 -1
- package/dist/_internal/components/form/total-form/Fields/index.js +4 -4
- package/dist/_internal/components/index.js +37 -37
- package/dist/_internal/en-US.data-display.js +1 -1
- package/dist/_internal/pt-BR.data-display.js +1 -1
- package/dist/_internal/user-avatar/user-avatar.js +4 -4
- package/dist/charts.js +11 -11
- package/dist/{chunk-HF2WLLGH.js → chunk-2XI4R6UO.js} +2 -2
- package/dist/{chunk-HF2WLLGH.js.map → chunk-2XI4R6UO.js.map} +1 -1
- package/dist/{chunk-GYFKIPR2.js → chunk-4PUCT3RX.js} +2 -2
- package/dist/{chunk-JQSF3CUR.js → chunk-6HMDUUVJ.js} +2 -1
- package/dist/{chunk-JQSF3CUR.js.map → chunk-6HMDUUVJ.js.map} +1 -1
- package/dist/{chunk-EBEMNKTK.js → chunk-6ONQTXFM.js} +7 -4
- package/dist/chunk-6ONQTXFM.js.map +1 -0
- package/dist/{chunk-C2I7NQC4.js → chunk-74KCGLOU.js} +2 -2
- package/dist/{chunk-4J62V5OE.js → chunk-7YJYIMWP.js} +2 -2
- package/dist/{chunk-MT74NRLY.js → chunk-C2OX3C7L.js} +4 -4
- package/dist/{chunk-62XVHRTX.js → chunk-D7SOXI2K.js} +70 -21
- package/dist/chunk-D7SOXI2K.js.map +1 -0
- package/dist/{chunk-BO6IMK5P.js → chunk-DPHSJLMN.js} +2 -2
- package/dist/{chunk-7XSCEHGA.js → chunk-EOQ6EKTS.js} +7 -7
- package/dist/{chunk-4OTJ66ID.js → chunk-EXTES7LP.js} +15 -4
- package/dist/chunk-EXTES7LP.js.map +1 -0
- package/dist/{chunk-4IVEBBF6.js → chunk-FYJDI5BW.js} +4 -3
- package/dist/{chunk-4IVEBBF6.js.map → chunk-FYJDI5BW.js.map} +1 -1
- package/dist/{chunk-A5U7HEBI.js → chunk-GNDIVKWF.js} +4 -2
- package/dist/chunk-GNDIVKWF.js.map +1 -0
- package/dist/{chunk-XKPV52CG.js → chunk-GPTNZ57P.js} +2 -2
- package/dist/{chunk-ZGAOA7LN.js → chunk-H56CRMCM.js} +6 -6
- package/dist/{chunk-AMLHEKSV.js → chunk-HI7JPDD6.js} +5 -5
- package/dist/{chunk-JK3QB7MO.js → chunk-I54LHHZS.js} +2 -2
- package/dist/{chunk-GLAAX5JJ.js → chunk-I5NTADBO.js} +2 -1
- package/dist/{chunk-GLAAX5JJ.js.map → chunk-I5NTADBO.js.map} +1 -1
- package/dist/{chunk-LCGK22QQ.js → chunk-IKXCAYFH.js} +5 -5
- package/dist/{chunk-MLGAGZJ3.js → chunk-ILNAPS44.js} +8 -7
- package/dist/chunk-ILNAPS44.js.map +1 -0
- package/dist/{chunk-D22FGMGU.js → chunk-JIAIPOEV.js} +2 -2
- package/dist/{chunk-HQCZT6TO.js → chunk-JVOEVTCZ.js} +5 -5
- package/dist/{chunk-76IHYINM.js → chunk-KEBYZ2MO.js} +16 -9
- package/dist/chunk-KEBYZ2MO.js.map +1 -0
- package/dist/{chunk-JJNY5MZL.js → chunk-KG7OTJ26.js} +2 -2
- package/dist/{chunk-2ZMR3TZU.js → chunk-L6UTYEUS.js} +3 -3
- package/dist/{chunk-WWB43LWU.js → chunk-LOGSJH2Q.js} +2 -2
- package/dist/{chunk-YJPBNIEM.js → chunk-MGFTHOPG.js} +2 -2
- package/dist/{chunk-RB3R6BJL.js → chunk-O4G7QKDU.js} +2 -2
- package/dist/{chunk-DYHOBKPU.js → chunk-OA6T2ME3.js} +5 -5
- package/dist/{chunk-U5FOJBLG.js → chunk-OOLES6RR.js} +14 -2
- package/dist/chunk-OOLES6RR.js.map +1 -0
- package/dist/{chunk-YHKHHSZH.js → chunk-OQ554425.js} +3 -3
- package/dist/{chunk-54OJAOXC.js → chunk-PDSZN26U.js} +2 -2
- package/dist/{chunk-MNNIOQTQ.js → chunk-PGVGCDPD.js} +3 -3
- package/dist/{chunk-RDRXTH47.js → chunk-PWXDMP7G.js} +10 -6
- package/dist/chunk-PWXDMP7G.js.map +1 -0
- package/dist/{chunk-6ATXOJVQ.js → chunk-QADTI63U.js} +4 -4
- package/dist/{chunk-UETHX57J.js → chunk-R6L376KR.js} +21 -7
- package/dist/chunk-R6L376KR.js.map +1 -0
- package/dist/{chunk-SEUJNFOD.js → chunk-RLDTV5I2.js} +2 -2
- package/dist/{chunk-4UCXJYOO.js → chunk-RUQNKOSP.js} +4 -4
- package/dist/chunk-RUQNKOSP.js.map +1 -0
- package/dist/{chunk-7RG37FVT.js → chunk-RXKFPXVH.js} +29 -2
- package/dist/chunk-RXKFPXVH.js.map +1 -0
- package/dist/{chunk-KSJBFT4G.js → chunk-SGAHME6W.js} +3 -3
- package/dist/{chunk-SB2SEGR6.js → chunk-TIM4PXWN.js} +3 -3
- package/dist/{chunk-D4LMRSY7.js → chunk-UIWVSZ6I.js} +2 -2
- package/dist/{chunk-GJOU26UW.js → chunk-V2UJEICC.js} +3 -3
- package/dist/chunk-V2UJEICC.js.map +1 -0
- package/dist/{chunk-XATRYJ4Q.js → chunk-VQBY73QH.js} +4 -4
- package/dist/{chunk-SYERREN5.js → chunk-W2JYXZC2.js} +4 -4
- package/dist/{chunk-XNLJ2Z7T.js → chunk-YC2QYRNE.js} +5 -3
- package/dist/chunk-YC2QYRNE.js.map +1 -0
- package/dist/chunk-YOPMXGHY.js +23 -0
- package/dist/chunk-YOPMXGHY.js.map +1 -0
- package/dist/{chunk-QK3XXPBA.js → chunk-YWJCMGTE.js} +2 -2
- package/dist/{chunk-UQ6SAIX7.js → chunk-Z47SYKRX.js} +2 -2
- package/dist/data-display/Avatar.js +3 -3
- package/dist/data-display/CardKit.js +3 -3
- package/dist/data-display/Carousel.js +5 -5
- package/dist/data-display/Chart.js +11 -11
- package/dist/data-display/DataGrid.js +2 -2
- package/dist/data-display/DataViews.js +25 -24
- package/dist/data-display/FleetMap.js +9 -9
- package/dist/data-display/MapPreview.js +6 -6
- package/dist/en-US.js +1 -1
- package/dist/form/CepField.js +1 -1
- package/dist/form/DateRangePicker.js +5 -5
- package/dist/form/InputOTP.js +2 -2
- package/dist/form/total-form.js +4 -4
- package/dist/locales.js +2 -2
- package/dist/pt-BR.js +1 -1
- package/dist/types/components/data-display/DataViews/data-views-copy.d.ts +6 -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 +32 -5
- 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-filter-panel.d.ts +6 -0
- package/dist/types/components/data-display/DataViews/data-views-filter-panel.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-grid-parts.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-inline-bar.d.ts +3 -1
- package/dist/types/components/data-display/DataViews/data-views-inline-bar.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-more-filters.d.ts +3 -1
- 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-range-pill.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-range-reset.d.ts +16 -0
- package/dist/types/components/data-display/DataViews/data-views-range-reset.d.ts.map +1 -0
- package/dist/types/components/data-display/DataViews/data-views-writers.d.ts +13 -0
- package/dist/types/components/data-display/DataViews/data-views-writers.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/use-data-views-state.d.ts +4 -0
- package/dist/types/components/data-display/DataViews/use-data-views-state.d.ts.map +1 -1
- package/dist/types/components/form/CepField/CepField.d.ts +1 -1
- package/dist/types/components/form/CepField/CepField.d.ts.map +1 -1
- package/dist/types/components/form/CepField/CepField.types.d.ts +8 -0
- package/dist/types/components/form/CepField/CepField.types.d.ts.map +1 -1
- package/dist/types/components/form/InputOTP/InputOTP.d.ts.map +1 -1
- package/dist/types/components/form/InputOTP/InputOTP.hooks.d.ts.map +1 -1
- package/dist/types/components/form/total-form/Fields/CepField.d.ts +6 -1
- package/dist/types/components/form/total-form/Fields/CepField.d.ts.map +1 -1
- package/dist/types/components/form/total-form/Fields/TextField.d.ts +22 -1
- package/dist/types/components/form/total-form/Fields/TextField.d.ts.map +1 -1
- package/dist/types/components/form/total-form/Fields/index.d.ts +1 -1
- package/dist/types/components/form/total-form/Fields/index.d.ts.map +1 -1
- package/dist/types/components/form/total-form/index.d.ts +1 -1
- package/dist/types/components/form/total-form/index.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/data-views-copy.ts +6 -0
- package/src/components/data-display/DataViews/data-views-day-input.tsx +134 -38
- package/src/components/data-display/DataViews/data-views-empty.tsx +1 -1
- package/src/components/data-display/DataViews/data-views-filter-panel.tsx +8 -2
- package/src/components/data-display/DataViews/data-views-grid-parts.tsx +3 -1
- package/src/components/data-display/DataViews/data-views-inline-bar.tsx +7 -0
- package/src/components/data-display/DataViews/data-views-more-filters.tsx +4 -1
- package/src/components/data-display/DataViews/data-views-range-pill.tsx +11 -3
- package/src/components/data-display/DataViews/data-views-range-reset.ts +34 -0
- package/src/components/data-display/DataViews/data-views-writers.ts +24 -1
- package/src/components/data-display/DataViews/use-data-views-state.ts +6 -1
- package/src/components/form/CepField/CepField.md +7 -2
- package/src/components/form/CepField/CepField.tsx +13 -2
- package/src/components/form/CepField/CepField.types.ts +8 -0
- package/src/components/form/InputOTP/InputOTP.hooks.ts +48 -9
- package/src/components/form/InputOTP/InputOTP.md +6 -1
- package/src/components/form/InputOTP/InputOTP.tsx +40 -1
- package/src/components/form/total-form/Fields/CepField.tsx +7 -0
- package/src/components/form/total-form/Fields/TextField.tsx +64 -1
- package/src/components/form/total-form/Fields/index.ts +1 -1
- package/src/components/form/total-form/index.ts +1 -1
- package/src/en-US.data-display.ts +1 -0
- package/src/pt-BR.data-display.ts +1 -0
- package/dist/chunk-4OTJ66ID.js.map +0 -1
- package/dist/chunk-4UCXJYOO.js.map +0 -1
- package/dist/chunk-62XVHRTX.js.map +0 -1
- package/dist/chunk-76IHYINM.js.map +0 -1
- package/dist/chunk-7RG37FVT.js.map +0 -1
- package/dist/chunk-A5U7HEBI.js.map +0 -1
- package/dist/chunk-EBEMNKTK.js.map +0 -1
- package/dist/chunk-GJOU26UW.js.map +0 -1
- package/dist/chunk-MLGAGZJ3.js.map +0 -1
- package/dist/chunk-RDRXTH47.js.map +0 -1
- package/dist/chunk-U5FOJBLG.js.map +0 -1
- package/dist/chunk-UETHX57J.js.map +0 -1
- package/dist/chunk-XNLJ2Z7T.js.map +0 -1
- /package/dist/{chunk-GYFKIPR2.js.map → chunk-4PUCT3RX.js.map} +0 -0
- /package/dist/{chunk-C2I7NQC4.js.map → chunk-74KCGLOU.js.map} +0 -0
- /package/dist/{chunk-4J62V5OE.js.map → chunk-7YJYIMWP.js.map} +0 -0
- /package/dist/{chunk-MT74NRLY.js.map → chunk-C2OX3C7L.js.map} +0 -0
- /package/dist/{chunk-BO6IMK5P.js.map → chunk-DPHSJLMN.js.map} +0 -0
- /package/dist/{chunk-7XSCEHGA.js.map → chunk-EOQ6EKTS.js.map} +0 -0
- /package/dist/{chunk-XKPV52CG.js.map → chunk-GPTNZ57P.js.map} +0 -0
- /package/dist/{chunk-ZGAOA7LN.js.map → chunk-H56CRMCM.js.map} +0 -0
- /package/dist/{chunk-AMLHEKSV.js.map → chunk-HI7JPDD6.js.map} +0 -0
- /package/dist/{chunk-JK3QB7MO.js.map → chunk-I54LHHZS.js.map} +0 -0
- /package/dist/{chunk-LCGK22QQ.js.map → chunk-IKXCAYFH.js.map} +0 -0
- /package/dist/{chunk-D22FGMGU.js.map → chunk-JIAIPOEV.js.map} +0 -0
- /package/dist/{chunk-HQCZT6TO.js.map → chunk-JVOEVTCZ.js.map} +0 -0
- /package/dist/{chunk-JJNY5MZL.js.map → chunk-KG7OTJ26.js.map} +0 -0
- /package/dist/{chunk-2ZMR3TZU.js.map → chunk-L6UTYEUS.js.map} +0 -0
- /package/dist/{chunk-WWB43LWU.js.map → chunk-LOGSJH2Q.js.map} +0 -0
- /package/dist/{chunk-YJPBNIEM.js.map → chunk-MGFTHOPG.js.map} +0 -0
- /package/dist/{chunk-RB3R6BJL.js.map → chunk-O4G7QKDU.js.map} +0 -0
- /package/dist/{chunk-DYHOBKPU.js.map → chunk-OA6T2ME3.js.map} +0 -0
- /package/dist/{chunk-YHKHHSZH.js.map → chunk-OQ554425.js.map} +0 -0
- /package/dist/{chunk-54OJAOXC.js.map → chunk-PDSZN26U.js.map} +0 -0
- /package/dist/{chunk-MNNIOQTQ.js.map → chunk-PGVGCDPD.js.map} +0 -0
- /package/dist/{chunk-6ATXOJVQ.js.map → chunk-QADTI63U.js.map} +0 -0
- /package/dist/{chunk-SEUJNFOD.js.map → chunk-RLDTV5I2.js.map} +0 -0
- /package/dist/{chunk-KSJBFT4G.js.map → chunk-SGAHME6W.js.map} +0 -0
- /package/dist/{chunk-SB2SEGR6.js.map → chunk-TIM4PXWN.js.map} +0 -0
- /package/dist/{chunk-D4LMRSY7.js.map → chunk-UIWVSZ6I.js.map} +0 -0
- /package/dist/{chunk-XATRYJ4Q.js.map → chunk-VQBY73QH.js.map} +0 -0
- /package/dist/{chunk-SYERREN5.js.map → chunk-W2JYXZC2.js.map} +0 -0
- /package/dist/{chunk-QK3XXPBA.js.map → chunk-YWJCMGTE.js.map} +0 -0
- /package/dist/{chunk-UQ6SAIX7.js.map → chunk-Z47SYKRX.js.map} +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DataViewsGrid
|
|
3
|
+
} from "./chunk-PGVGCDPD.js";
|
|
1
4
|
import {
|
|
2
5
|
DeleteViewDialog
|
|
3
6
|
} from "./chunk-TPAMLIN7.js";
|
|
4
|
-
import {
|
|
5
|
-
DataViewsGrid
|
|
6
|
-
} from "./chunk-MNNIOQTQ.js";
|
|
7
7
|
import {
|
|
8
8
|
viewStateKey
|
|
9
9
|
} from "./chunk-ZOLAYP2D.js";
|
|
@@ -166,4 +166,4 @@ function renderViewDialogs(ctl, fields, columns, views, testIdPrefix, onSaved) {
|
|
|
166
166
|
export {
|
|
167
167
|
DataViewsTableBase
|
|
168
168
|
};
|
|
169
|
-
//# sourceMappingURL=chunk-
|
|
169
|
+
//# sourceMappingURL=chunk-C2OX3C7L.js.map
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
|
|
8
8
|
// src/components/data-display/DataViews/data-views-day-input.tsx
|
|
9
9
|
import TextField from "@mui/material/TextField/index.js";
|
|
10
|
-
import { useEffect, useState } from "react";
|
|
10
|
+
import { useEffect, useId, useState } from "react";
|
|
11
11
|
import { jsx } from "react/jsx-runtime";
|
|
12
12
|
var SEGMENT_WIDTH = { year: 4, month: 2, day: 2 };
|
|
13
13
|
function segmentsOf(mask) {
|
|
@@ -62,13 +62,62 @@ function maskDate(raw, mask) {
|
|
|
62
62
|
}
|
|
63
63
|
return out.join(separator);
|
|
64
64
|
}
|
|
65
|
+
var ISO_DAY = /^\s*(\d{4}-\d{2}-\d{2})\s*$/;
|
|
66
|
+
function readDayText(raw, mask) {
|
|
67
|
+
const iso = ISO_DAY.exec(raw)?.[1];
|
|
68
|
+
const masked = iso ? isoToMasked(iso, mask) : "";
|
|
69
|
+
return masked || maskDate(raw, mask);
|
|
70
|
+
}
|
|
71
|
+
function isImpossibleDay(text, mask) {
|
|
72
|
+
return text.replace(/\D/g, "").length === 8 && maskedToIso(text, mask) === "";
|
|
73
|
+
}
|
|
65
74
|
function dayInputProps(testId, describedBy) {
|
|
75
|
+
const ids = describedBy.filter(Boolean).join(" ");
|
|
66
76
|
return {
|
|
67
77
|
"data-testid": testId,
|
|
68
78
|
maxLength: 10,
|
|
69
79
|
inputMode: "numeric",
|
|
70
80
|
autoComplete: "off",
|
|
71
|
-
...
|
|
81
|
+
...ids ? { "aria-describedby": ids } : {}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function useDayText(applied, mask, onChange, judgesImpossible) {
|
|
85
|
+
const [text, setText] = useState(() => isoToMasked(applied, mask));
|
|
86
|
+
const impossible = judgesImpossible && isImpossibleDay(text, mask);
|
|
87
|
+
const enter = (next) => {
|
|
88
|
+
setText(next);
|
|
89
|
+
if (next === "") return onChange(void 0);
|
|
90
|
+
const iso = maskedToIso(next, mask);
|
|
91
|
+
if (iso) onChange(iso);
|
|
92
|
+
};
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
setText((current) => {
|
|
95
|
+
const iso = maskedToIso(current, mask);
|
|
96
|
+
const means = (iso !== "" || current === "") && iso === applied;
|
|
97
|
+
return means ? current : isoToMasked(applied, mask);
|
|
98
|
+
});
|
|
99
|
+
}, [applied, mask]);
|
|
100
|
+
return {
|
|
101
|
+
text,
|
|
102
|
+
impossible,
|
|
103
|
+
handleChange: (event) => enter(readDayText(event.target.value, mask)),
|
|
104
|
+
// A pasted ISO day REPLACES the field whatever it held: inserted at the
|
|
105
|
+
// caret into existing digits it would be read as more digits, and the
|
|
106
|
+
// `maxLength` would cut a padded one before `onChange` ever saw it.
|
|
107
|
+
handlePaste: (event) => {
|
|
108
|
+
const pasted = event.clipboardData.getData("text");
|
|
109
|
+
if (!ISO_DAY.test(pasted)) return;
|
|
110
|
+
event.preventDefault();
|
|
111
|
+
enter(readDayText(pasted, mask));
|
|
112
|
+
},
|
|
113
|
+
// Leaving a half-typed date on screen would show a filter the list is not
|
|
114
|
+
// actually using. On blur the field snaps back to what IS applied; a
|
|
115
|
+
// complete date already equals it, so this only ever tidies. An impossible
|
|
116
|
+
// day the field is SAYING is impossible stays, with its message: snapping
|
|
117
|
+
// it back is the silent forgetting FUT-4144 removed.
|
|
118
|
+
handleBlur: () => {
|
|
119
|
+
if (!impossible) setText(isoToMasked(applied, mask));
|
|
120
|
+
}
|
|
72
121
|
};
|
|
73
122
|
}
|
|
74
123
|
function DayBoundInput({
|
|
@@ -78,34 +127,32 @@ function DayBoundInput({
|
|
|
78
127
|
testId,
|
|
79
128
|
error = false,
|
|
80
129
|
describedBy,
|
|
81
|
-
mask
|
|
130
|
+
mask,
|
|
131
|
+
invalidMessage
|
|
82
132
|
}) {
|
|
83
|
-
const
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
133
|
+
const id = useId();
|
|
134
|
+
const { text, impossible, handleChange, handlePaste, handleBlur } = useDayText(
|
|
135
|
+
value ?? "",
|
|
136
|
+
mask,
|
|
137
|
+
onChange,
|
|
138
|
+
invalidMessage !== void 0
|
|
139
|
+
);
|
|
90
140
|
return /* @__PURE__ */ jsx(
|
|
91
141
|
TextField,
|
|
92
142
|
{
|
|
93
143
|
size: "small",
|
|
94
144
|
type: "text",
|
|
145
|
+
id,
|
|
95
146
|
label,
|
|
96
|
-
error,
|
|
147
|
+
error: error || impossible,
|
|
148
|
+
helperText: impossible ? invalidMessage : void 0,
|
|
97
149
|
placeholder: mask,
|
|
98
150
|
value: text,
|
|
99
|
-
onChange:
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (next === "") return onChange(void 0);
|
|
103
|
-
const iso = maskedToIso(next, mask);
|
|
104
|
-
if (iso) onChange(iso);
|
|
105
|
-
},
|
|
106
|
-
onBlur: () => setText(isoToMasked(applied, mask)),
|
|
151
|
+
onChange: handleChange,
|
|
152
|
+
onPaste: handlePaste,
|
|
153
|
+
onBlur: handleBlur,
|
|
107
154
|
InputLabelProps: { shrink: true },
|
|
108
|
-
inputProps: dayInputProps(testId, describedBy),
|
|
155
|
+
inputProps: dayInputProps(testId, [impossible ? `${id}-helper-text` : void 0, describedBy]),
|
|
109
156
|
sx: [{ width: sxRem(165) }, fieldTextFieldStyles]
|
|
110
157
|
}
|
|
111
158
|
);
|
|
@@ -115,6 +162,8 @@ export {
|
|
|
115
162
|
isoToMasked,
|
|
116
163
|
maskedToIso,
|
|
117
164
|
maskDate,
|
|
165
|
+
readDayText,
|
|
166
|
+
isImpossibleDay,
|
|
118
167
|
DayBoundInput
|
|
119
168
|
};
|
|
120
|
-
//# sourceMappingURL=chunk-
|
|
169
|
+
//# sourceMappingURL=chunk-D7SOXI2K.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/DataViews/data-views-day-input.tsx"],"sourcesContent":["'use client';\n\n/**\n * A day bound as a MASKED `dd/mm/aaaa` text field, replacing `<input type=\"date\">`.\n *\n * The native control is three separate segments wearing one box. Typing a date\n * means filling a segment, being jumped to the next, and starting over — and\n * which segment comes first is the BROWSER's locale, not ours, so the same\n * field reads `dd/mm/aaaa` for one merchant and `mm/dd/yyyy` for the next with\n * nothing in our code saying which. There is no way to type a date as one\n * continuous run of digits, which is how people actually type dates.\n *\n * A mask gives that back: eight digits straight through, separators inserted as\n * you go, backspace walking back through them.\n *\n * Measured, driving both controls in Chromium with the same eight keystrokes\n * (`01072026`, one `keydown` at a time):\n *\n * native → field ends EMPTY, no filter applied, 0 requests\n * masked → field reads `01/07/2026`, filter applied, 1 request\n *\n * The native result is the whole complaint: you type a date and nothing lands.\n *\n * The second half of the fix is WHEN the bound is written. A partially-typed\n * year is itself a valid date — `2026` passes through `0002`, `0020`, `0202` on\n * the way — so committing on every keystroke would send the grid off to fetch\n * years nobody meant. A bound is written only once the text is a WHOLE, real\n * date, which is what keeps the run above at one request rather than four.\n */\nimport TextField from '@mui/material/TextField/index.js';\nimport React, { useEffect, useId, useState } from 'react';\nimport { fieldTextFieldStyles } from '../../../tokens/field-height';\nimport { sxRem } from '../../../tokens/relative';\n\n\n/**\n * THE MASK IS THE ORDER, and both halves of this file read it.\n *\n * The placeholder a host supplies (`copy.filters.dayMask` — `dd/mm/aaaa` for\n * pt-BR, `mm/dd/yyyy` for en-US) is not decoration: it tells the reader which\n * segment comes first. Everything below therefore derives the segment order\n * FROM that same string, so the shape on screen and the shape the parser\n * expects cannot disagree.\n *\n * They did disagree, and the failure was silent in the worst direction. The\n * mask/parse pair was hardcoded day-first (the `Br` in the old names was\n * accurate) while the placeholder followed the copy pack — so under `en-US` the\n * field ASKED for `mm/dd/yyyy`, and a reader who typed exactly that got a day\n * of 12 and a month of 31, which is not a date, which commits nothing. No\n * error, no filter, a full list that reads like an answer. The en-US pack's own\n * comment already said the mask \"is the shape that gets a date entered\n * backwards\"; nothing enforced it.\n */\n\n/** What one segment of a mask is, and how many digits it takes. */\ntype DaySegment = 'year' | 'month' | 'day';\nconst SEGMENT_WIDTH: Readonly<Record<DaySegment, number>> = { year: 4, month: 2, day: 2 };\n\n/**\n * The segments a mask asks for, in its own order.\n *\n * Keyed on each token's FIRST letter so one rule covers every spelling a host\n * might use — `aaaa`/`yyyy` for the year, `mm` for the month, `dd`/`tt` for the\n * day. An unreadable mask falls back to day-first rather than throwing: this\n * runs on every keystroke, and a field that renders is recoverable where one\n * that crashes the grid is not.\n */\nfunction segmentsOf(mask: string): readonly DaySegment[] {\n const tokens = mask.split(/[^A-Za-z]+/).filter(Boolean);\n if (tokens.length !== 3) return ['day', 'month', 'year'];\n const segments = tokens.map((token): DaySegment => {\n const head = token.slice(0, 1).toLowerCase();\n if (head === 'y' || head === 'a') return 'year';\n return head === 'm' ? 'month' : 'day';\n });\n // A mask naming the same segment twice describes no date. Fall back rather\n // than build a parser that can never succeed.\n return new Set(segments).size === 3 ? segments : ['day', 'month', 'year'];\n}\n\n/** The separator the mask uses, defaulting to `/`. */\nconst separatorOf = (mask: string): string => mask.replace(/[A-Za-z]/g, '').slice(0, 1) || '/';\n\n/** `AAAA-MM-DD` (the wire) → the mask's own order (what the reader sees). */\nexport function isoToMasked(iso: string, mask: string): string {\n const parts = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(iso);\n if (!parts) return '';\n const value: Record<DaySegment, string> = {\n year: parts[1] as string,\n month: parts[2] as string,\n day: parts[3] as string,\n };\n return segmentsOf(mask)\n .map((segment) => value[segment])\n .join(separatorOf(mask));\n}\n\n/**\n * The mask's order → `AAAA-MM-DD`, but ONLY for a day that exists.\n *\n * `31/02/2026` parses fine as three numbers and is not a date, and `Date` would\n * silently roll it into March rather than reject it — so the round trip through\n * UTC is the check: if the month or day comes back changed, the input was not a\n * day.\n */\nexport function maskedToIso(text: string, mask: string): string {\n const segments = segmentsOf(mask);\n const digits = text.replace(/\\D/g, '');\n if (digits.length !== 8) return '';\n const value = {} as Record<DaySegment, string>;\n let cursor = 0;\n for (const segment of segments) {\n value[segment] = digits.slice(cursor, cursor + SEGMENT_WIDTH[segment]);\n cursor += SEGMENT_WIDTH[segment];\n }\n const year = Number(value.year);\n const month = Number(value.month);\n const day = Number(value.day);\n if (year < 1000) return '';\n const probe = new Date(Date.UTC(year, month - 1, day));\n if (probe.getUTCMonth() !== month - 1 || probe.getUTCDate() !== day) return '';\n return `${value.year}-${value.month}-${value.day}`;\n}\n\n/**\n * Digits only, capped at the mask's width, with the separators put back as you\n * type.\n *\n * Deriving the whole string from the digits — rather than editing the text in\n * place — is what makes backspace behave. Four digits of `dd/mm/aaaa` render as\n * `06/08`, not `06/08/`, so deleting the first digit of the year removes the\n * trailing separator with it instead of leaving a dead keystroke that changes\n * nothing.\n */\nexport function maskDate(raw: string, mask: string): string {\n const segments = segmentsOf(mask);\n const separator = separatorOf(mask);\n const digits = raw.replace(/\\D/g, '').slice(0, 8);\n const out: string[] = [];\n let cursor = 0;\n for (const segment of segments) {\n if (cursor >= digits.length) break;\n out.push(digits.slice(cursor, cursor + SEGMENT_WIDTH[segment]));\n cursor += SEGMENT_WIDTH[segment];\n }\n return out.join(separator);\n}\n\n/** A wire day on its own, as a paste or an autofill delivers it: `2026-10-01`. */\nconst ISO_DAY = /^\\s*(\\d{4}-\\d{2}-\\d{2})\\s*$/;\n\n/**\n * What the field shows for whatever arrived — typed, pasted, autofilled.\n *\n * A whole ISO day (`AAAA-MM-DD`) is READ AS THAT DAY and written in the mask's\n * order. Through `maskDate` alone it is eight digits taken day-first, so a\n * pasted `2026-10-01` came out as `20/26/1001` (FUT-4144). Anything else is\n * masked exactly as typing always was, so the typed and pasted forms of one day\n * land on the same text.\n */\nexport function readDayText(raw: string, mask: string): string {\n const iso = ISO_DAY.exec(raw)?.[1];\n const masked = iso ? isoToMasked(iso, mask) : '';\n return masked || maskDate(raw, mask);\n}\n\n/**\n * Whether `text` is a WHOLE day that does not exist — `31/02/2026`. A partial\n * entry is not impossible, only unfinished, and is never flagged.\n */\nexport function isImpossibleDay(text: string, mask: string): boolean {\n return text.replace(/\\D/g, '').length === 8 && maskedToIso(text, mask) === '';\n}\n\n/**\n * What has to land on the `<input>` itself rather than on the `TextField`.\n *\n * Anything `TextField` does not recognise is spread onto its root `FormControl`\n * div. `inputMode` went up there once: the attribute sat on a non-editable\n * wrapper, meant nothing, and the phone went on offering the letter keyboard\n * for a field that only takes digits (the `dd/mm/aaaa` hint under a QWERTY\n * layout). Only the `<input>` this reaches decides which keypad opens — and the\n * same is true of `aria-describedby`, which on the wrapper points at a\n * description no screen reader will read out for the field.\n *\n * `numeric` and not `tel`: both raise a keypad, but the phone one is a dialler\n * with `+ * #` on it — keys that cannot occur in a date. A paste carrying\n * separators still lands, because the MASK is what filters the text; the keypad\n * only narrows what a thumb can reach for.\n *\n * Autofill off for the same reason: the browser's saved-value strip covers the\n * keypad to suggest names and addresses, none of which are a date, and none of\n * which the mask would keep.\n */\nfunction dayInputProps(testId: string, describedBy: readonly (string | undefined)[]) {\n const ids = describedBy.filter(Boolean).join(' ');\n return {\n 'data-testid': testId,\n maxLength: 10,\n inputMode: 'numeric' as const,\n autoComplete: 'off',\n ...(ids ? { 'aria-describedby': ids } : {}),\n };\n}\n\n/** Props of {@link DayBoundInput}. */\ninterface DayBoundInputProps {\n label: string;\n /** The applied bound, `AAAA-MM-DD`, or undefined when this end is open. */\n value: string | undefined;\n onChange: (bound: string | undefined) => void;\n testId: string;\n /**\n * Paint the field as rejected. It only ever writes a real day by itself, so\n * this is for a caller judging the PAIR: a window whose end precedes its\n * start is two valid days and one impossible period, and the field it was\n * typed into is the only place to say which half is being complained about.\n */\n error?: boolean;\n /** Id of the element carrying that complaint, so it is read WITH the field. */\n describedBy?: string;\n /**\n * The day mask, which IS the placeholder — so the expected ORDER is on\n * screen before the first keystroke rather than discovered by getting it\n * wrong. `dd/mm/aaaa` is one locale's order and one locale's letters.\n *\n * A PROP rather than a context read: this field has two callers, and only\n * one of them is inside DataViews. `DateRangePicker` mounts it standalone\n * with its own message table, so a context read here throws for every host\n * of that picker — which is exactly what it did.\n */\n mask: string;\n /**\n * Said under the field when its eight digits name no day (`31/02/2026`); the\n * field is then marked invalid and KEEPS the text on blur, so the reader sees\n * what was refused instead of the old value quietly coming back (FUT-4144).\n *\n * Opt-in, because the field ships no words of its own: without it an\n * impossible day is still never written, and blur still snaps back.\n */\n invalidMessage?: string;\n}\n\n/** What {@link useDayText} hands the field: its text, its verdict and its handlers. */\ninterface DayText {\n text: string;\n impossible: boolean;\n handleChange: (event: React.ChangeEvent<HTMLInputElement>) => void;\n handlePaste: (event: React.ClipboardEvent<HTMLDivElement>) => void;\n handleBlur: () => void;\n}\n\n/** The typed text of one bound, kept apart from the APPLIED bound it may commit. */\nfunction useDayText(\n applied: string,\n mask: string,\n onChange: (bound: string | undefined) => void,\n judgesImpossible: boolean,\n): DayText {\n const [text, setText] = useState(() => isoToMasked(applied, mask));\n const impossible = judgesImpossible && isImpossibleDay(text, mask);\n\n // Emptying clears the bound. A COMPLETE day applies it. A partial (or an\n // impossible) one does NEITHER — it leaves whatever is applied alone, so\n // typing is never fought and a half-typed year never reaches the backend.\n const enter = (next: string) => {\n setText(next);\n if (next === '') return onChange(undefined);\n const iso = maskedToIso(next, mask);\n if (iso) onChange(iso);\n };\n\n // The bound is the APPLIED filter; `text` is what is being typed. Re-sync only\n // when the applied value moved somewhere the text does not already mean — a\n // \"Limpar\", a saved view, the other pill resetting the pair. Without that\n // guard the field's own write bounces straight back mid-edit and resets the\n // caret, which is the native control's worst habit reproduced by hand.\n //\n // \"Already means\" is a REAL day equal to the bound, or an empty field for an\n // open bound. An impossible day parses to `''` too, so a bare comparison let\n // a \"Limpar\" (applied → `''`) keep `31/02/2026` on screen, red, over a filter\n // that had just been cleared.\n useEffect(() => {\n setText((current) => {\n const iso = maskedToIso(current, mask);\n const means = (iso !== '' || current === '') && iso === applied;\n return means ? current : isoToMasked(applied, mask);\n });\n }, [applied, mask]);\n\n return {\n text,\n impossible,\n handleChange: (event) => enter(readDayText(event.target.value, mask)),\n // A pasted ISO day REPLACES the field whatever it held: inserted at the\n // caret into existing digits it would be read as more digits, and the\n // `maxLength` would cut a padded one before `onChange` ever saw it.\n handlePaste: (event) => {\n const pasted = event.clipboardData.getData('text');\n if (!ISO_DAY.test(pasted)) return;\n event.preventDefault();\n enter(readDayText(pasted, mask));\n },\n // Leaving a half-typed date on screen would show a filter the list is not\n // actually using. On blur the field snaps back to what IS applied; a\n // complete date already equals it, so this only ever tidies. An impossible\n // day the field is SAYING is impossible stays, with its message: snapping\n // it back is the silent forgetting FUT-4144 removed.\n handleBlur: () => {\n if (!impossible) setText(isoToMasked(applied, mask));\n },\n };\n}\n\n/**\n * One end of a day window. The BOUND stays `AAAA-MM-DD` — the form the backend's\n * inclusive day comparison already speaks, and the form the chip label reads —\n * so only the typing surface changes.\n */\nexport function DayBoundInput({\n label,\n value,\n onChange,\n testId,\n error = false,\n describedBy,\n mask,\n invalidMessage,\n}: DayBoundInputProps): React.JSX.Element {\n const id = useId();\n const { text, impossible, handleChange, handlePaste, handleBlur } = useDayText(\n value ?? '',\n mask,\n onChange,\n invalidMessage !== undefined,\n );\n\n return (\n <TextField\n size=\"small\"\n type=\"text\"\n id={id}\n label={label}\n error={error || impossible}\n helperText={impossible ? invalidMessage : undefined}\n placeholder={mask}\n value={text}\n onChange={handleChange}\n onPaste={handlePaste}\n onBlur={handleBlur}\n // The placeholder occupies the space an un-shrunk label would render into.\n InputLabelProps={{ shrink: true }}\n inputProps={dayInputProps(testId, [impossible ? `${id}-helper-text` : undefined, describedBy])}\n sx={[{ width: sxRem(165) }, fieldTextFieldStyles]}\n />\n );\n}\n"],"mappings":";;;;;;;;AA6BA,OAAO,eAAe;AACtB,SAAgB,WAAW,OAAO,gBAAgB;AAoT9C;AA1RJ,IAAM,gBAAsD,EAAE,MAAM,GAAG,OAAO,GAAG,KAAK,EAAE;AAWxF,SAAS,WAAW,MAAqC;AACvD,QAAM,SAAS,KAAK,MAAM,YAAY,EAAE,OAAO,OAAO;AACtD,MAAI,OAAO,WAAW,EAAG,QAAO,CAAC,OAAO,SAAS,MAAM;AACvD,QAAM,WAAW,OAAO,IAAI,CAAC,UAAsB;AACjD,UAAM,OAAO,MAAM,MAAM,GAAG,CAAC,EAAE,YAAY;AAC3C,QAAI,SAAS,OAAO,SAAS,IAAK,QAAO;AACzC,WAAO,SAAS,MAAM,UAAU;AAAA,EAClC,CAAC;AAGD,SAAO,IAAI,IAAI,QAAQ,EAAE,SAAS,IAAI,WAAW,CAAC,OAAO,SAAS,MAAM;AAC1E;AAGA,IAAM,cAAc,CAAC,SAAyB,KAAK,QAAQ,aAAa,EAAE,EAAE,MAAM,GAAG,CAAC,KAAK;AAGpF,SAAS,YAAY,KAAa,MAAsB;AAC7D,QAAM,QAAQ,4BAA4B,KAAK,GAAG;AAClD,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,QAAoC;AAAA,IACxC,MAAM,MAAM,CAAC;AAAA,IACb,OAAO,MAAM,CAAC;AAAA,IACd,KAAK,MAAM,CAAC;AAAA,EACd;AACA,SAAO,WAAW,IAAI,EACnB,IAAI,CAAC,YAAY,MAAM,OAAO,CAAC,EAC/B,KAAK,YAAY,IAAI,CAAC;AAC3B;AAUO,SAAS,YAAY,MAAc,MAAsB;AAC9D,QAAM,WAAW,WAAW,IAAI;AAChC,QAAM,SAAS,KAAK,QAAQ,OAAO,EAAE;AACrC,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,QAAM,QAAQ,CAAC;AACf,MAAI,SAAS;AACb,aAAW,WAAW,UAAU;AAC9B,UAAM,OAAO,IAAI,OAAO,MAAM,QAAQ,SAAS,cAAc,OAAO,CAAC;AACrE,cAAU,cAAc,OAAO;AAAA,EACjC;AACA,QAAM,OAAO,OAAO,MAAM,IAAI;AAC9B,QAAM,QAAQ,OAAO,MAAM,KAAK;AAChC,QAAM,MAAM,OAAO,MAAM,GAAG;AAC5B,MAAI,OAAO,IAAM,QAAO;AACxB,QAAM,QAAQ,IAAI,KAAK,KAAK,IAAI,MAAM,QAAQ,GAAG,GAAG,CAAC;AACrD,MAAI,MAAM,YAAY,MAAM,QAAQ,KAAK,MAAM,WAAW,MAAM,IAAK,QAAO;AAC5E,SAAO,GAAG,MAAM,IAAI,IAAI,MAAM,KAAK,IAAI,MAAM,GAAG;AAClD;AAYO,SAAS,SAAS,KAAa,MAAsB;AAC1D,QAAM,WAAW,WAAW,IAAI;AAChC,QAAM,YAAY,YAAY,IAAI;AAClC,QAAM,SAAS,IAAI,QAAQ,OAAO,EAAE,EAAE,MAAM,GAAG,CAAC;AAChD,QAAM,MAAgB,CAAC;AACvB,MAAI,SAAS;AACb,aAAW,WAAW,UAAU;AAC9B,QAAI,UAAU,OAAO,OAAQ;AAC7B,QAAI,KAAK,OAAO,MAAM,QAAQ,SAAS,cAAc,OAAO,CAAC,CAAC;AAC9D,cAAU,cAAc,OAAO;AAAA,EACjC;AACA,SAAO,IAAI,KAAK,SAAS;AAC3B;AAGA,IAAM,UAAU;AAWT,SAAS,YAAY,KAAa,MAAsB;AAC7D,QAAM,MAAM,QAAQ,KAAK,GAAG,IAAI,CAAC;AACjC,QAAM,SAAS,MAAM,YAAY,KAAK,IAAI,IAAI;AAC9C,SAAO,UAAU,SAAS,KAAK,IAAI;AACrC;AAMO,SAAS,gBAAgB,MAAc,MAAuB;AACnE,SAAO,KAAK,QAAQ,OAAO,EAAE,EAAE,WAAW,KAAK,YAAY,MAAM,IAAI,MAAM;AAC7E;AAsBA,SAAS,cAAc,QAAgB,aAA8C;AACnF,QAAM,MAAM,YAAY,OAAO,OAAO,EAAE,KAAK,GAAG;AAChD,SAAO;AAAA,IACL,eAAe;AAAA,IACf,WAAW;AAAA,IACX,WAAW;AAAA,IACX,cAAc;AAAA,IACd,GAAI,MAAM,EAAE,oBAAoB,IAAI,IAAI,CAAC;AAAA,EAC3C;AACF;AAkDA,SAAS,WACP,SACA,MACA,UACA,kBACS;AACT,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,MAAM,YAAY,SAAS,IAAI,CAAC;AACjE,QAAM,aAAa,oBAAoB,gBAAgB,MAAM,IAAI;AAKjE,QAAM,QAAQ,CAAC,SAAiB;AAC9B,YAAQ,IAAI;AACZ,QAAI,SAAS,GAAI,QAAO,SAAS,MAAS;AAC1C,UAAM,MAAM,YAAY,MAAM,IAAI;AAClC,QAAI,IAAK,UAAS,GAAG;AAAA,EACvB;AAYA,YAAU,MAAM;AACd,YAAQ,CAAC,YAAY;AACnB,YAAM,MAAM,YAAY,SAAS,IAAI;AACrC,YAAM,SAAS,QAAQ,MAAM,YAAY,OAAO,QAAQ;AACxD,aAAO,QAAQ,UAAU,YAAY,SAAS,IAAI;AAAA,IACpD,CAAC;AAAA,EACH,GAAG,CAAC,SAAS,IAAI,CAAC;AAElB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,cAAc,CAAC,UAAU,MAAM,YAAY,MAAM,OAAO,OAAO,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,IAIpE,aAAa,CAAC,UAAU;AACtB,YAAM,SAAS,MAAM,cAAc,QAAQ,MAAM;AACjD,UAAI,CAAC,QAAQ,KAAK,MAAM,EAAG;AAC3B,YAAM,eAAe;AACrB,YAAM,YAAY,QAAQ,IAAI,CAAC;AAAA,IACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,YAAY,MAAM;AAChB,UAAI,CAAC,WAAY,SAAQ,YAAY,SAAS,IAAI,CAAC;AAAA,IACrD;AAAA,EACF;AACF;AAOO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AACF,GAA0C;AACxC,QAAM,KAAK,MAAM;AACjB,QAAM,EAAE,MAAM,YAAY,cAAc,aAAa,WAAW,IAAI;AAAA,IAClE,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA,mBAAmB;AAAA,EACrB;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,MAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,OAAO,SAAS;AAAA,MAChB,YAAY,aAAa,iBAAiB;AAAA,MAC1C,aAAa;AAAA,MACb,OAAO;AAAA,MACP,UAAU;AAAA,MACV,SAAS;AAAA,MACT,QAAQ;AAAA,MAER,iBAAiB,EAAE,QAAQ,KAAK;AAAA,MAChC,YAAY,cAAc,QAAQ,CAAC,aAAa,GAAG,EAAE,iBAAiB,QAAW,WAAW,CAAC;AAAA,MAC7F,IAAI,CAAC,EAAE,OAAO,MAAM,GAAG,EAAE,GAAG,oBAAoB;AAAA;AAAA,EAClD;AAEJ;","names":[]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-DQ22UKMZ.js";
|
|
4
4
|
import {
|
|
5
5
|
Avatar
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-7YJYIMWP.js";
|
|
7
7
|
import {
|
|
8
8
|
Card
|
|
9
9
|
} from "./chunk-W2RXXF7K.js";
|
|
@@ -80,4 +80,4 @@ export {
|
|
|
80
80
|
UserAvatar,
|
|
81
81
|
UserMenu
|
|
82
82
|
};
|
|
83
|
-
//# sourceMappingURL=chunk-
|
|
83
|
+
//# sourceMappingURL=chunk-DPHSJLMN.js.map
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
pulseAnimation,
|
|
3
|
-
rotateAnimation,
|
|
4
|
-
scaleInAnimation,
|
|
5
|
-
shimmerAnimation
|
|
6
|
-
} from "./chunk-MTEQEPNY.js";
|
|
7
1
|
import {
|
|
8
2
|
ACTIVE_SCALE,
|
|
9
3
|
AVATAR_SIZES,
|
|
@@ -23,6 +17,12 @@ import {
|
|
|
23
17
|
SPINNER,
|
|
24
18
|
STATUS_DOT
|
|
25
19
|
} from "./chunk-6ZZGK5DT.js";
|
|
20
|
+
import {
|
|
21
|
+
pulseAnimation,
|
|
22
|
+
rotateAnimation,
|
|
23
|
+
scaleInAnimation,
|
|
24
|
+
shimmerAnimation
|
|
25
|
+
} from "./chunk-MTEQEPNY.js";
|
|
26
26
|
import {
|
|
27
27
|
absoluteInk,
|
|
28
28
|
controlNeutral,
|
|
@@ -277,4 +277,4 @@ function AvatarView(props) {
|
|
|
277
277
|
export {
|
|
278
278
|
AvatarView
|
|
279
279
|
};
|
|
280
|
-
//# sourceMappingURL=chunk-
|
|
280
|
+
//# sourceMappingURL=chunk-EOQ6EKTS.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useOtpDigits
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-R6L376KR.js";
|
|
4
4
|
import {
|
|
5
5
|
otpSlotSx
|
|
6
6
|
} from "./chunk-WOSUYOAU.js";
|
|
@@ -17,6 +17,15 @@ import { jsx } from "react/jsx-runtime";
|
|
|
17
17
|
var StyledOTPInput = styled(TextField, {
|
|
18
18
|
shouldForwardProp: (prop) => !["customColor", "customSize", "glass", "gradient"].includes(prop)
|
|
19
19
|
})(({ theme, ...flags }) => ({ ...otpSlotSx(theme, flags) }));
|
|
20
|
+
function keypadProps(variant, index) {
|
|
21
|
+
if (variant !== "numeric") return {};
|
|
22
|
+
return {
|
|
23
|
+
inputMode: "numeric",
|
|
24
|
+
pattern: "[0-9]*",
|
|
25
|
+
...index === 0 ? { autoComplete: "one-time-code" } : {}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
var slotMaxLength = (variant, index, length) => variant === "numeric" && index === 0 ? length + 1 : 1;
|
|
20
29
|
var DEFAULTS = {
|
|
21
30
|
variant: "numeric",
|
|
22
31
|
color: "primary",
|
|
@@ -58,6 +67,7 @@ var InputOTP = forwardRef((props, ref) => {
|
|
|
58
67
|
{
|
|
59
68
|
ref,
|
|
60
69
|
"data-testid": dataTestId,
|
|
70
|
+
role: "group",
|
|
61
71
|
sx: { display: "flex", gap: 1, justifyContent: "center", alignItems: "center" },
|
|
62
72
|
...rest,
|
|
63
73
|
children: digits.map((digit, index) => /* @__PURE__ */ jsx(
|
|
@@ -78,9 +88,10 @@ var InputOTP = forwardRef((props, ref) => {
|
|
|
78
88
|
error,
|
|
79
89
|
disabled,
|
|
80
90
|
inputProps: {
|
|
81
|
-
maxLength:
|
|
91
|
+
maxLength: slotMaxLength(variant, index, length),
|
|
82
92
|
style: { textAlign: "center" },
|
|
83
|
-
"data-testid": dataTestId ? `${dataTestId}-slot-${index}` : void 0
|
|
93
|
+
"data-testid": dataTestId ? `${dataTestId}-slot-${index}` : void 0,
|
|
94
|
+
...keypadProps(variant, index)
|
|
84
95
|
}
|
|
85
96
|
},
|
|
86
97
|
index
|
|
@@ -93,4 +104,4 @@ InputOTP.displayName = "InputOTP";
|
|
|
93
104
|
export {
|
|
94
105
|
InputOTP
|
|
95
106
|
};
|
|
96
|
-
//# sourceMappingURL=chunk-
|
|
107
|
+
//# sourceMappingURL=chunk-EXTES7LP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/form/InputOTP/InputOTP.tsx"],"sourcesContent":["import Box from '@mui/material/Box/index.js';\nimport TextField from '@mui/material/TextField/index.js';\nimport { styled } from '@mui/material/styles/index.js';\nimport React, { forwardRef } from 'react';\n\nimport { withDefaults } from '../../../utils/withDefaults';\n\nimport { useOtpDigits } from './InputOTP.hooks';\nimport { otpSlotSx } from './InputOTP.styles';\nimport type { OtpSlotFlags } from './InputOTP.styles';\nimport type { InputOTPProps } from './InputOTP.types';\n\nconst StyledOTPInput = styled(TextField, {\n shouldForwardProp: (prop) =>\n !['customColor', 'customSize', 'glass', 'gradient'].includes(prop as string),\n})<OtpSlotFlags>(({ theme, ...flags }) => ({ ...otpSlotSx(theme, flags) }));\n\n/**\n * What tells a phone that a `numeric` code is digits (FUT-4144).\n *\n * The hook already refused letters, but nothing reached the `<input>` to say\n * so, and the courier's six-digit join code opened the letter keyboard.\n * `inputMode` picks the keypad; `pattern` is what iOS reads for the same; and\n * `one-time-code` on the FIRST slot lets the phone offer a code from an SMS —\n * the first slot, because it is the one that takes a paste and spreads it.\n * `alphanumeric` and `masked` are left exactly as they were.\n */\nfunction keypadProps(variant: InputOTPProps['variant'], index: number): Record<string, string> {\n if (variant !== 'numeric') return {};\n return {\n inputMode: 'numeric',\n pattern: '[0-9]*',\n ...(index === 0 ? { autoComplete: 'one-time-code' } : {}),\n };\n}\n\n/**\n * One character per slot — except the numeric FIRST slot, which carries\n * `one-time-code`: the phone's SMS fill writes the whole code there in one\n * change, and a `maxLength` of 1 would cut it to one digit before the hook\n * could spread it.\n *\n * The code's length PLUS ONE: a phone that INSERTS the code at the caret keeps\n * the digit already there in front (`4` + `482913`), and the browser caps that\n * insertion at `maxlength` BEFORE the hook sees it. At the bare length it\n * arrived as `448291` — a wrong code that looks whole. One more character lets\n * the hook see the leading digit and drop it. A keystroke into the slot once\n * filled is still refused, by the hook, as `maxLength={1}` refused it.\n */\nconst slotMaxLength = (variant: InputOTPProps['variant'], index: number, length: number): number =>\n variant === 'numeric' && index === 0 ? length + 1 : 1;\n\nconst DEFAULTS = {\n variant: 'numeric',\n color: 'primary',\n size: 'md',\n length: 6,\n value: '',\n glass: false,\n gradient: false,\n autoFocus: false,\n error: false,\n disabled: false,\n} satisfies Partial<InputOTPProps>;\n\ntype ResolvedProps = InputOTPProps & Required<Pick<InputOTPProps, keyof typeof DEFAULTS>>;\n\nexport const InputOTP = forwardRef<HTMLDivElement, InputOTPProps>((props, ref) => {\n const {\n variant, color, size, length, value, onChange, onComplete,\n glass, gradient, autoFocus, error, disabled, dataTestId,\n ...rest\n } = withDefaults(props, DEFAULTS) as ResolvedProps;\n\n const { digits, inputRefs, handleInputChange, handleKeyDown, handlePaste } = useOtpDigits({\n variant,\n length,\n value,\n onChange,\n onComplete,\n });\n\n return (\n <Box\n ref={ref}\n data-testid={dataTestId}\n // A group, so the `aria-label` a caller gives the code names the six\n // slots together: on a plain `div` it named nothing anyone could reach.\n role=\"group\"\n sx={{ display: 'flex', gap: 1, justifyContent: 'center', alignItems: 'center' }}\n {...rest}\n >\n {digits.map((digit, index) => (\n <StyledOTPInput\n key={index}\n ref={(el: HTMLDivElement | null) => {\n inputRefs.current[index] = el?.querySelector('input') || null;\n }}\n customColor={color}\n customSize={size}\n glass={glass}\n gradient={gradient}\n // `masked` keeps the digit in state and shows a bullet in its place.\n value={variant === 'masked' ? (digit ? '•' : '') : digit}\n onChange={(e) => handleInputChange(index, e.target.value)}\n onKeyDown={(e) => handleKeyDown(index, e)}\n // Only the first slot takes a paste; it fills the rest itself.\n onPaste={index === 0 ? handlePaste : undefined}\n autoFocus={autoFocus && index === 0}\n error={error}\n disabled={disabled}\n inputProps={{\n maxLength: slotMaxLength(variant, index, length),\n style: { textAlign: 'center' },\n 'data-testid': dataTestId ? `${dataTestId}-slot-${index}` : undefined,\n ...keypadProps(variant, index),\n }}\n />\n ))}\n </Box>\n );\n});\n\nInputOTP.displayName = 'InputOTP';\n"],"mappings":";;;;;;;;;;;AAAA,OAAO,SAAS;AAChB,OAAO,eAAe;AACtB,SAAS,cAAc;AACvB,SAAgB,kBAAkB;AA0F1B;AAjFR,IAAM,iBAAiB,OAAO,WAAW;AAAA,EACvC,mBAAmB,CAAC,SAClB,CAAC,CAAC,eAAe,cAAc,SAAS,UAAU,EAAE,SAAS,IAAc;AAC/E,CAAC,EAAgB,CAAC,EAAE,OAAO,GAAG,MAAM,OAAO,EAAE,GAAG,UAAU,OAAO,KAAK,EAAE,EAAE;AAY1E,SAAS,YAAY,SAAmC,OAAuC;AAC7F,MAAI,YAAY,UAAW,QAAO,CAAC;AACnC,SAAO;AAAA,IACL,WAAW;AAAA,IACX,SAAS;AAAA,IACT,GAAI,UAAU,IAAI,EAAE,cAAc,gBAAgB,IAAI,CAAC;AAAA,EACzD;AACF;AAeA,IAAM,gBAAgB,CAAC,SAAmC,OAAe,WACvE,YAAY,aAAa,UAAU,IAAI,SAAS,IAAI;AAEtD,IAAM,WAAW;AAAA,EACf,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,OAAO;AAAA,EACP,UAAU;AAAA,EACV,WAAW;AAAA,EACX,OAAO;AAAA,EACP,UAAU;AACZ;AAIO,IAAM,WAAW,WAA0C,CAAC,OAAO,QAAQ;AAChF,QAAM;AAAA,IACJ;AAAA,IAAS;AAAA,IAAO;AAAA,IAAM;AAAA,IAAQ;AAAA,IAAO;AAAA,IAAU;AAAA,IAC/C;AAAA,IAAO;AAAA,IAAU;AAAA,IAAW;AAAA,IAAO;AAAA,IAAU;AAAA,IAC7C,GAAG;AAAA,EACL,IAAI,aAAa,OAAO,QAAQ;AAEhC,QAAM,EAAE,QAAQ,WAAW,mBAAmB,eAAe,YAAY,IAAI,aAAa;AAAA,IACxF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,eAAa;AAAA,MAGb,MAAK;AAAA,MACL,IAAI,EAAE,SAAS,QAAQ,KAAK,GAAG,gBAAgB,UAAU,YAAY,SAAS;AAAA,MAC7E,GAAG;AAAA,MAEH,iBAAO,IAAI,CAAC,OAAO,UAClB;AAAA,QAAC;AAAA;AAAA,UAEC,KAAK,CAAC,OAA8B;AAClC,sBAAU,QAAQ,KAAK,IAAI,IAAI,cAAc,OAAO,KAAK;AAAA,UAC3D;AAAA,UACA,aAAa;AAAA,UACb,YAAY;AAAA,UACZ;AAAA,UACA;AAAA,UAEA,OAAO,YAAY,WAAY,QAAQ,WAAM,KAAM;AAAA,UACnD,UAAU,CAAC,MAAM,kBAAkB,OAAO,EAAE,OAAO,KAAK;AAAA,UACxD,WAAW,CAAC,MAAM,cAAc,OAAO,CAAC;AAAA,UAExC,SAAS,UAAU,IAAI,cAAc;AAAA,UACrC,WAAW,aAAa,UAAU;AAAA,UAClC;AAAA,UACA;AAAA,UACA,YAAY;AAAA,YACV,WAAW,cAAc,SAAS,OAAO,MAAM;AAAA,YAC/C,OAAO,EAAE,WAAW,SAAS;AAAA,YAC7B,eAAe,aAAa,GAAG,UAAU,SAAS,KAAK,KAAK;AAAA,YAC5D,GAAG,YAAY,SAAS,KAAK;AAAA,UAC/B;AAAA;AAAA,QAtBK;AAAA,MAuBP,CACD;AAAA;AAAA,EACH;AAEJ,CAAC;AAED,SAAS,cAAc;","names":[]}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
MoreGroup,
|
|
3
3
|
MoreQuick,
|
|
4
4
|
fieldClearing
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-PDSZN26U.js";
|
|
6
6
|
import {
|
|
7
7
|
useDataViewsCopy
|
|
8
8
|
} from "./chunk-KHG57NAE.js";
|
|
@@ -143,6 +143,7 @@ function MoreFilters({
|
|
|
143
143
|
onClearAll,
|
|
144
144
|
anyApplied,
|
|
145
145
|
compact = false,
|
|
146
|
+
clearKey,
|
|
146
147
|
...rest
|
|
147
148
|
}) {
|
|
148
149
|
const [anchor, setAnchor] = useState(null);
|
|
@@ -182,7 +183,7 @@ function MoreFilters({
|
|
|
182
183
|
slotProps: { paper: { sx: { width: sxRem(300), maxWidth: (theme) => `calc(100vw - ${rem(theme, 32)})` } } },
|
|
183
184
|
children: /* @__PURE__ */ jsxs(default2, { "data-testid": `${rest.testIdPrefix}-more-panel`, children: [
|
|
184
185
|
/* @__PURE__ */ jsx(MoreHeading, {}),
|
|
185
|
-
/* @__PURE__ */ jsx(default2, { sx: { maxHeight: sxRem(320), overflowY: "auto", overflowX: "hidden", p: 1.5, minWidth: 0 }, children: /* @__PURE__ */ jsx(MoreFields, { fields, ...rest }) }),
|
|
186
|
+
/* @__PURE__ */ jsx(default2, { sx: { maxHeight: sxRem(320), overflowY: "auto", overflowX: "hidden", p: 1.5, minWidth: 0 }, children: /* @__PURE__ */ jsx(MoreFields, { fields, ...rest }, clearKey) }),
|
|
186
187
|
anyApplied && /* @__PURE__ */ jsx(MoreFooter, { onClearAll, testIdPrefix: rest.testIdPrefix })
|
|
187
188
|
] })
|
|
188
189
|
}
|
|
@@ -193,4 +194,4 @@ function MoreFilters({
|
|
|
193
194
|
export {
|
|
194
195
|
MoreFilters
|
|
195
196
|
};
|
|
196
|
-
//# sourceMappingURL=chunk-
|
|
197
|
+
//# sourceMappingURL=chunk-FYJDI5BW.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/data-display/DataViews/data-views-more-filters.tsx"],"sourcesContent":["\"use client\";\n\nimport KeyboardArrowDownRoundedIcon from \"@mui/icons-material/KeyboardArrowDownRounded\";\n// A FUNNEL, not the tune sliders this used to share with \"Exibir\". The two\n// sit a few px apart on the same bar and do unrelated things — one narrows\n// WHICH rows you see, the other changes HOW they are shown — and with one\n// glyph between them the bar offered the operator no way to tell which was\n// which. On a phone, where both are icon-only, they were indistinguishable.\nimport FilterAltRoundedIcon from \"@mui/icons-material/FilterAltRounded\";\nimport Popover from \"@mui/material/Popover/index.js\";\nimport type { Theme } from \"@mui/material/styles/index.js\";\nimport { useState } from \"react\";\n\nimport { useDataViewsCopy } from \"./data-views-copy-context\";\nimport { Button } from \"../../form/Button\";\nimport { Box } from \"../../../mui/Box\";\nimport { Text } from \"../../typography/Text\";\n\nimport { fieldClearing, MoreGroup, MoreQuick, type MoreFieldProps } from \"./data-views-more-fields\";\nimport type { OverflowField } from \"./data-views-overflow\";\nimport { rem, sxRem } from \"../../../tokens/relative\";\n\n/**\n * \"MAIS\" — the filter overflow: its trigger, its panel and its footer. What\n * goes INSIDE it is `data-views-more-fields`.\n *\n * It holds the fields that had no room on the toolbar. An applied filter is\n * ranked ahead of an idle one for the visible slots but is NOT exempt (see\n * `useFilterOverflow`), so an applied filter can be in here — on a phone, most\n * of them are. That is why the trigger changes tone and counts the applied\n * ones: a filter you cannot see is a filter you forget you set, and the badge\n * is what stops that.\n */\n\ninterface MoreFiltersProps<T extends Record<string, unknown>> extends MoreFieldProps {\n fields: OverflowField<T>[];\n}\n\n/**\n * The trigger, badged with how many fields had no room on the bar — and told\n * apart when some of them are APPLIED.\n *\n * An applied filter can land in here now (it is ranked first, not exempt), so\n * this button is the only thing on screen still saying it exists. A neutral\n * badge reading \"3\" would make \"three filters you have not used\" and \"three\n * filters narrowing this list\" look identical, which is the whole failure the\n * old exemption was written to avoid. So an overflow holding applied filters\n * takes the applied tone and counts them in its own badge.\n */\nfunction MoreTrigger({\n count,\n appliedCount,\n compact,\n onOpen,\n testIdPrefix,\n}: {\n count: number;\n appliedCount: number;\n /** Icon only — the same rung that strips Exibir/Exportar. */\n compact: boolean;\n onOpen: (anchor: HTMLElement) => void;\n testIdPrefix: string;\n}): React.JSX.Element {\n const copy = useDataViewsCopy();\n const applied = appliedCount > 0;\n return (\n <Button\n variant=\"outline\"\n size=\"sm\"\n color=\"neutral\"\n onClick={(event) => onOpen(event.currentTarget as HTMLElement)}\n dataTestId={`${testIdPrefix}-more-filters`}\n aria-label={\n applied\n ? copy.filters.moreFiltersApplied(count, appliedCount)\n : copy.filters.moreFilters(count)\n }\n >\n <Box\n component=\"span\"\n sx={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 0.5,\n color: applied ? \"primary.main\" : undefined,\n }}\n >\n <FilterAltRoundedIcon fontSize=\"small\" />\n {!compact && (\n <Box component=\"span\" sx={{ display: { xs: \"none\", sm: \"inline\" } }}>\n {copy.filters.moreTriggerLabel}\n </Box>\n )}\n <Box\n component=\"span\"\n data-testid={`${testIdPrefix}-more-badge`}\n sx={{\n px: 0.75,\n borderRadius: 5,\n bgcolor: applied ? \"primary.main\" : \"action.selected\",\n color: applied ? \"primary.contrastText\" : undefined,\n fontSize: sxRem(11),\n fontWeight: applied ? 700 : undefined,\n }}\n >\n {applied ? appliedCount : count}\n </Box>\n {!compact && <KeyboardArrowDownRoundedIcon fontSize=\"small\" />}\n </Box>\n </Button>\n );\n}\n\n/** The panel's heading: what these are, and why they are in here. */\nfunction MoreHeading(): React.JSX.Element {\n const copy = useDataViewsCopy();\n return (\n <Box\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 1,\n px: 1.5,\n py: 1,\n borderBottom: 1,\n borderColor: \"divider\",\n }}\n >\n <Text variant=\"caption\" as=\"span\">\n <Box component=\"span\" sx={{ textTransform: \"uppercase\", letterSpacing: sxRem(0.5), color: \"text.disabled\" }}>\n {copy.filters.moreHeading}\n </Box>\n </Text>\n <Text variant=\"caption\" as=\"span\">\n <Box component=\"span\" sx={{ ml: \"auto\", color: \"text.disabled\" }}>\n {copy.filters.overflowNote}\n </Box>\n </Text>\n </Box>\n );\n}\n\n/**\n * The panel's own way back to the unfiltered list.\n *\n * The bar's \"Limpar\" is the primary one, but it is a control like any other\n * and the ladder can take its label — and on the narrowest rungs this panel is\n * where most of the fields ended up anyway. Clearing everything from inside it\n * saves closing it to reach a button three pixels wide.\n */\nfunction MoreFooter({\n onClearAll,\n testIdPrefix,\n}: {\n onClearAll: () => void;\n testIdPrefix: string;\n}): React.JSX.Element {\n const copy = useDataViewsCopy();\n return (\n <Box sx={{ px: 1.5, py: 1, borderTop: 1, borderColor: \"divider\" }}>\n <Box\n component=\"button\"\n type=\"button\"\n onClick={onClearAll}\n data-testid={`${testIdPrefix}-more-clear-all`}\n sx={{\n width: \"100%\",\n border: 0,\n p: 0,\n bgcolor: \"transparent\",\n cursor: \"pointer\",\n font: \"inherit\",\n fontSize: sxRem(13),\n textAlign: \"left\",\n color: \"primary.main\",\n \"&:hover\": { textDecoration: \"underline\" },\n }}\n >\n {copy.filters.clearAll}\n </Box>\n </Box>\n );\n}\n\n/** The panel's body: a shed quick chip as a toggle row, anything else as a labelled group. */\nfunction MoreFields<T extends Record<string, unknown>>({\n fields,\n ...rest\n}: MoreFiltersProps<T>): React.JSX.Element {\n return (\n <>\n {fields.map((field) =>\n field.quick ? (\n <MoreQuick key={field.id} quick={field.quick} {...rest} />\n ) : (\n <MoreGroup key={field.id} field={field} {...rest} />\n ),\n )}\n </>\n );\n}\n\n/** The overflow trigger + panel. Renders nothing when everything fits. */\nexport function MoreFilters<T extends Record<string, unknown>>({\n fields,\n onOpenChange,\n onClearAll,\n anyApplied,\n compact = false,\n ...rest\n}: MoreFiltersProps<T> & {\n /** Icon only — the same rung that strips Exibir/Exportar. */\n compact?: boolean;\n /** Clears every filter, not just the ones in here. */\n onClearAll: () => void;\n /** Whether anything is applied anywhere — the footer is pointless otherwise. */\n anyApplied: boolean;\n /**\n * So the shell can FREEZE the measured split while this panel is open.\n *\n * Applying a filter in here makes its field active, and an active field\n * takes an inline slot first — so the field being edited was promoted OUT of\n * this panel mid-keystroke, taking the focused input with it. Typing \"12\"\n * got as far as \"1\" and then had nowhere to go.\n */\n onOpenChange?: (open: boolean) => void;\n}): React.JSX.Element | null {\n const [anchor, setAnchor] = useState<HTMLElement | null>(null);\n if (fields.length === 0) return null;\n return (\n <>\n <MoreTrigger\n count={fields.length}\n appliedCount={\n fields.filter(\n (field) =>\n fieldClearing({\n field,\n pills: rest.pills,\n ranges: rest.ranges,\n onTogglePill: rest.onTogglePill,\n onChangeRange: rest.onChangeRange,\n }).applied,\n ).length\n }\n compact={compact}\n onOpen={(element) => {\n setAnchor(element);\n onOpenChange?.(true);\n }}\n testIdPrefix={rest.testIdPrefix}\n />\n <Popover\n open={Boolean(anchor)}\n anchorEl={anchor}\n onClose={() => {\n setAnchor(null);\n onOpenChange?.(false);\n }}\n anchorOrigin={{ vertical: \"bottom\", horizontal: \"left\" }}\n slotProps={{ paper: { sx: { width: sxRem(300), maxWidth: (theme: Theme) => `calc(100vw - ${rem(theme, 32)})` } } }}\n >\n <Box data-testid={`${rest.testIdPrefix}-more-panel`}>\n <MoreHeading />\n {/* overflowX hidden, not auto: this panel is a fixed 300px and its\n contents are told to shrink into it. A horizontal scrollbar here\n means something refused to, which is a bug to fix rather than a\n scrollbar to live with. */}\n <Box sx={{ maxHeight: sxRem(320), overflowY: \"auto\", overflowX: \"hidden\", p: 1.5, minWidth: 0 }}>\n <MoreFields fields={fields} {...rest} />\n </Box>\n {anyApplied && (\n <MoreFooter onClearAll={onClearAll} testIdPrefix={rest.testIdPrefix} />\n )}\n </Box>\n </Popover>\n </>\n );\n}\n"],"mappings":"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","names":["default"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/DataViews/data-views-more-filters.tsx"],"sourcesContent":["\"use client\";\n\nimport KeyboardArrowDownRoundedIcon from \"@mui/icons-material/KeyboardArrowDownRounded\";\n// A FUNNEL, not the tune sliders this used to share with \"Exibir\". The two\n// sit a few px apart on the same bar and do unrelated things — one narrows\n// WHICH rows you see, the other changes HOW they are shown — and with one\n// glyph between them the bar offered the operator no way to tell which was\n// which. On a phone, where both are icon-only, they were indistinguishable.\nimport FilterAltRoundedIcon from \"@mui/icons-material/FilterAltRounded\";\nimport Popover from \"@mui/material/Popover/index.js\";\nimport type { Theme } from \"@mui/material/styles/index.js\";\nimport { useState } from \"react\";\n\nimport { useDataViewsCopy } from \"./data-views-copy-context\";\nimport { Button } from \"../../form/Button\";\nimport { Box } from \"../../../mui/Box\";\nimport { Text } from \"../../typography/Text\";\n\nimport { fieldClearing, MoreGroup, MoreQuick, type MoreFieldProps } from \"./data-views-more-fields\";\nimport type { OverflowField } from \"./data-views-overflow\";\nimport { rem, sxRem } from \"../../../tokens/relative\";\n\n/**\n * \"MAIS\" — the filter overflow: its trigger, its panel and its footer. What\n * goes INSIDE it is `data-views-more-fields`.\n *\n * It holds the fields that had no room on the toolbar. An applied filter is\n * ranked ahead of an idle one for the visible slots but is NOT exempt (see\n * `useFilterOverflow`), so an applied filter can be in here — on a phone, most\n * of them are. That is why the trigger changes tone and counts the applied\n * ones: a filter you cannot see is a filter you forget you set, and the badge\n * is what stops that.\n */\n\ninterface MoreFiltersProps<T extends Record<string, unknown>> extends MoreFieldProps {\n fields: OverflowField<T>[];\n}\n\n/**\n * The trigger, badged with how many fields had no room on the bar — and told\n * apart when some of them are APPLIED.\n *\n * An applied filter can land in here now (it is ranked first, not exempt), so\n * this button is the only thing on screen still saying it exists. A neutral\n * badge reading \"3\" would make \"three filters you have not used\" and \"three\n * filters narrowing this list\" look identical, which is the whole failure the\n * old exemption was written to avoid. So an overflow holding applied filters\n * takes the applied tone and counts them in its own badge.\n */\nfunction MoreTrigger({\n count,\n appliedCount,\n compact,\n onOpen,\n testIdPrefix,\n}: {\n count: number;\n appliedCount: number;\n /** Icon only — the same rung that strips Exibir/Exportar. */\n compact: boolean;\n onOpen: (anchor: HTMLElement) => void;\n testIdPrefix: string;\n}): React.JSX.Element {\n const copy = useDataViewsCopy();\n const applied = appliedCount > 0;\n return (\n <Button\n variant=\"outline\"\n size=\"sm\"\n color=\"neutral\"\n onClick={(event) => onOpen(event.currentTarget as HTMLElement)}\n dataTestId={`${testIdPrefix}-more-filters`}\n aria-label={\n applied\n ? copy.filters.moreFiltersApplied(count, appliedCount)\n : copy.filters.moreFilters(count)\n }\n >\n <Box\n component=\"span\"\n sx={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 0.5,\n color: applied ? \"primary.main\" : undefined,\n }}\n >\n <FilterAltRoundedIcon fontSize=\"small\" />\n {!compact && (\n <Box component=\"span\" sx={{ display: { xs: \"none\", sm: \"inline\" } }}>\n {copy.filters.moreTriggerLabel}\n </Box>\n )}\n <Box\n component=\"span\"\n data-testid={`${testIdPrefix}-more-badge`}\n sx={{\n px: 0.75,\n borderRadius: 5,\n bgcolor: applied ? \"primary.main\" : \"action.selected\",\n color: applied ? \"primary.contrastText\" : undefined,\n fontSize: sxRem(11),\n fontWeight: applied ? 700 : undefined,\n }}\n >\n {applied ? appliedCount : count}\n </Box>\n {!compact && <KeyboardArrowDownRoundedIcon fontSize=\"small\" />}\n </Box>\n </Button>\n );\n}\n\n/** The panel's heading: what these are, and why they are in here. */\nfunction MoreHeading(): React.JSX.Element {\n const copy = useDataViewsCopy();\n return (\n <Box\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 1,\n px: 1.5,\n py: 1,\n borderBottom: 1,\n borderColor: \"divider\",\n }}\n >\n <Text variant=\"caption\" as=\"span\">\n <Box component=\"span\" sx={{ textTransform: \"uppercase\", letterSpacing: sxRem(0.5), color: \"text.disabled\" }}>\n {copy.filters.moreHeading}\n </Box>\n </Text>\n <Text variant=\"caption\" as=\"span\">\n <Box component=\"span\" sx={{ ml: \"auto\", color: \"text.disabled\" }}>\n {copy.filters.overflowNote}\n </Box>\n </Text>\n </Box>\n );\n}\n\n/**\n * The panel's own way back to the unfiltered list.\n *\n * The bar's \"Limpar\" is the primary one, but it is a control like any other\n * and the ladder can take its label — and on the narrowest rungs this panel is\n * where most of the fields ended up anyway. Clearing everything from inside it\n * saves closing it to reach a button three pixels wide.\n */\nfunction MoreFooter({\n onClearAll,\n testIdPrefix,\n}: {\n onClearAll: () => void;\n testIdPrefix: string;\n}): React.JSX.Element {\n const copy = useDataViewsCopy();\n return (\n <Box sx={{ px: 1.5, py: 1, borderTop: 1, borderColor: \"divider\" }}>\n <Box\n component=\"button\"\n type=\"button\"\n onClick={onClearAll}\n data-testid={`${testIdPrefix}-more-clear-all`}\n sx={{\n width: \"100%\",\n border: 0,\n p: 0,\n bgcolor: \"transparent\",\n cursor: \"pointer\",\n font: \"inherit\",\n fontSize: sxRem(13),\n textAlign: \"left\",\n color: \"primary.main\",\n \"&:hover\": { textDecoration: \"underline\" },\n }}\n >\n {copy.filters.clearAll}\n </Box>\n </Box>\n );\n}\n\n/** The panel's body: a shed quick chip as a toggle row, anything else as a labelled group. */\nfunction MoreFields<T extends Record<string, unknown>>({\n fields,\n ...rest\n}: MoreFiltersProps<T>): React.JSX.Element {\n return (\n <>\n {fields.map((field) =>\n field.quick ? (\n <MoreQuick key={field.id} quick={field.quick} {...rest} />\n ) : (\n <MoreGroup key={field.id} field={field} {...rest} />\n ),\n )}\n </>\n );\n}\n\n/** The overflow trigger + panel. Renders nothing when everything fits. */\nexport function MoreFilters<T extends Record<string, unknown>>({\n fields,\n onOpenChange,\n onClearAll,\n anyApplied,\n compact = false,\n clearKey,\n ...rest\n}: MoreFiltersProps<T> & {\n /** Changes on every clear-all; the fields here are keyed on it (FUT-4144). */\n clearKey?: number;\n /** Icon only — the same rung that strips Exibir/Exportar. */\n compact?: boolean;\n /** Clears every filter, not just the ones in here. */\n onClearAll: () => void;\n /** Whether anything is applied anywhere — the footer is pointless otherwise. */\n anyApplied: boolean;\n /**\n * So the shell can FREEZE the measured split while this panel is open.\n *\n * Applying a filter in here makes its field active, and an active field\n * takes an inline slot first — so the field being edited was promoted OUT of\n * this panel mid-keystroke, taking the focused input with it. Typing \"12\"\n * got as far as \"1\" and then had nowhere to go.\n */\n onOpenChange?: (open: boolean) => void;\n}): React.JSX.Element | null {\n const [anchor, setAnchor] = useState<HTMLElement | null>(null);\n if (fields.length === 0) return null;\n return (\n <>\n <MoreTrigger\n count={fields.length}\n appliedCount={\n fields.filter(\n (field) =>\n fieldClearing({\n field,\n pills: rest.pills,\n ranges: rest.ranges,\n onTogglePill: rest.onTogglePill,\n onChangeRange: rest.onChangeRange,\n }).applied,\n ).length\n }\n compact={compact}\n onOpen={(element) => {\n setAnchor(element);\n onOpenChange?.(true);\n }}\n testIdPrefix={rest.testIdPrefix}\n />\n <Popover\n open={Boolean(anchor)}\n anchorEl={anchor}\n onClose={() => {\n setAnchor(null);\n onOpenChange?.(false);\n }}\n anchorOrigin={{ vertical: \"bottom\", horizontal: \"left\" }}\n slotProps={{ paper: { sx: { width: sxRem(300), maxWidth: (theme: Theme) => `calc(100vw - ${rem(theme, 32)})` } } }}\n >\n <Box data-testid={`${rest.testIdPrefix}-more-panel`}>\n <MoreHeading />\n {/* overflowX hidden, not auto: this panel is a fixed 300px and its\n contents are told to shrink into it. A horizontal scrollbar here\n means something refused to, which is a bug to fix rather than a\n scrollbar to live with. */}\n <Box sx={{ maxHeight: sxRem(320), overflowY: \"auto\", overflowX: \"hidden\", p: 1.5, minWidth: 0 }}>\n <MoreFields key={clearKey} fields={fields} {...rest} />\n </Box>\n {anyApplied && (\n <MoreFooter onClearAll={onClearAll} testIdPrefix={rest.testIdPrefix} />\n )}\n </Box>\n </Popover>\n </>\n );\n}\n"],"mappings":"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","names":["default"]}
|
|
@@ -21,8 +21,9 @@ import {
|
|
|
21
21
|
useSelection
|
|
22
22
|
} from "./chunk-LLZWB32X.js";
|
|
23
23
|
import {
|
|
24
|
+
useClearFilters,
|
|
24
25
|
useStateWriters
|
|
25
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-OOLES6RR.js";
|
|
26
27
|
import {
|
|
27
28
|
emptyViewState
|
|
28
29
|
} from "./chunk-HLYYB4O5.js";
|
|
@@ -151,6 +152,7 @@ function useDataViewsState({
|
|
|
151
152
|
state,
|
|
152
153
|
ranges: state.ranges ?? {},
|
|
153
154
|
patch,
|
|
155
|
+
...useClearFilters(patch),
|
|
154
156
|
matched,
|
|
155
157
|
gridColumns,
|
|
156
158
|
hideableColumns,
|
|
@@ -176,4 +178,4 @@ function useDataViewsState({
|
|
|
176
178
|
export {
|
|
177
179
|
useDataViewsState
|
|
178
180
|
};
|
|
179
|
-
//# sourceMappingURL=chunk-
|
|
181
|
+
//# sourceMappingURL=chunk-GNDIVKWF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/DataViews/use-data-views-state.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { type GridColumn } from \"../DataGrid\";\nimport { type SortFieldDefinition } from \"../../layout/ContentToolbar\";\n\nimport { useDataViewsCopy } from \"./data-views-copy-context\";\nimport { filterRows } from \"./data-views-filter\";\nimport {\n useColumnsWithActions,\n useRenderedColumns,\n type HideableColumn,\n} from \"./data-views-columns\";\nimport { computeActiveFilterCount, defaultSortFields } from \"./data-views-grid-helpers\";\nimport { resolveScope, useScopeConfigChecks, type ScopeConfig } from \"./data-views-scopes\";\nimport { serverDerived, useServerQuery } from \"./data-views-server-query\";\nimport { useSelection } from \"./data-views-selection\";\nimport { useClearFilters, useStateWriters } from \"./data-views-writers\";\nimport {\n emptyViewState,\n type DataViewColumn,\n type DataViewServer,\n type DataViewState,\n type DataViewStatePatch,\n type DataViewSyncState,\n type FilterFieldConfig,\n type RangeFieldConfig,\n type DataViewQuery,\n type RangeValue,\n type RowAction,\n} from \"./data-views-types\";\n\nexport type { HideableColumn };\n\n/** Inputs the hook needs to own the view state + derived data. */\ninterface UseDataViewsStateArgs<T extends Record<string, unknown>> {\n rows: T[];\n columns: DataViewColumn<T>[];\n fields: FilterFieldConfig<T>[];\n rangeFields: RangeFieldConfig<T>[];\n getRowId: (row: T) => string | number;\n onRowClick?: (row: T) => void;\n appliedState?: DataViewState;\n /**\n * URL-driven controls (search/pills/ranges/sort) that re-apply on reference\n * change while preserving column visibility — see {@link DataViewSyncState}.\n */\n syncState?: DataViewSyncState;\n onStateChange?: (state: DataViewState) => void;\n testIdPrefix: string;\n sortFields?: SortFieldDefinition[];\n rowActions?: RowAction<T>[];\n rowActionsLeading?: (row: T) => React.ReactNode;\n /** Bespoke per-row menu rendered in the actions column instead of the auto kebab. */\n renderRowMenu?: (row: T) => React.ReactNode;\n /**\n * When present, the table is BACKEND-driven: `rows` is already the current\n * page (no in-browser filter/sort/paginate), and query changes re-fetch via\n * `server.onQueryChange`. Omit for the legacy client-side behaviour.\n */\n server?: DataViewServer;\n /**\n * The page-level partition rendered as tabs under the toolbar. Requires server\n * mode: a scope is applied at the BACKEND, never in the browser.\n */\n scopes?: ScopeConfig[];\n /**\n * The row field the scopes partition by, when the host knows it — used only to\n * reject the pill/scope clash at setup. See `assertNoScopePillOverlap`.\n */\n scopeFieldId?: string;\n}\n\n/** Everything the DataViewsGrid render needs; keeps the component itself thin. */\nexport interface DataViewsController<T extends Record<string, unknown>> {\n state: DataViewState;\n ranges: Record<string, RangeValue>;\n /**\n * Merge a partial into the view state.\n *\n * The UPDATER form is the one to reach for when the patch is derived from\n * state you are also changing — successive calls within one tick each see the\n * previous call's result, where the object form would have every caller build\n * its patch from the same render-scoped snapshot and the last write would win.\n */\n patch: (next: DataViewStatePatch) => void;\n /** Drop every filter — search, pills, ranges — from any surface that offers it. */\n clearFilters: () => void;\n /** Changes on every {@link clearFilters}; the filter controls are keyed on it. */\n clearKey: number;\n matched: T[];\n gridColumns: GridColumn<T>[];\n /** Columns eligible for the show/hide menu (hideable, with a text header). */\n hideableColumns: HideableColumn[];\n /** Every column id in reading order — what the Colunas tab reorders. */\n columnOrder: string[];\n /** Toggle one column's visibility in the current view state. */\n toggleColumn: (id: string, visible: boolean) => void;\n selectedIds: Set<string | number>;\n setSelectedIds: (ids: Set<string | number>) => void;\n /**\n * Add/remove ONE id from the selection. The card and board bodies both need\n * it, so it lives here rather than being written out twice at the call sites —\n * one selection model, one toggle, identical in every layout.\n */\n toggleId: (id: string | number) => void;\n selectedRows: T[];\n clearSelection: () => void;\n selectAll: () => void;\n filterOpen: boolean;\n setFilterOpen: (open: boolean) => void;\n resolvedSortFields: SortFieldDefinition[];\n activeSortField: string;\n activeSortOrder: \"asc\" | \"desc\";\n activeFilterCount: number;\n /** True when the table is backend-driven (server mode). */\n serverMode: boolean;\n /** Server-mode pagination: 1-based current page (1 when client mode). */\n serverPage: number;\n /** Server-mode pagination: total pages (1 when client mode). */\n serverPageCount: number;\n /** Server-mode: total matched rows across all pages (drives the counter). */\n serverTotalCount: number;\n /** Server-mode: request a specific 1-based page (re-fetches via onQueryChange). */\n changePage: (page: number) => void;\n /**\n * The active scope id, RESOLVED against the declared scopes (see\n * `resolveScope`). `undefined` when the table declares none — which is what\n * keeps `scope` out of the emitted query for every table that never opted in.\n */\n scope: string | undefined;\n /** Select a scope: re-fetches from page 1 and drops the selection. */\n setScope: (id: string) => void;\n /**\n * The query the grid is currently showing. Read by Export, which hands it\n * back to the host UNPAGINATED — so an export follows the filters rather\n * than the 25 rows that happen to be loaded.\n */\n currentQuery: DataViewQuery;\n /**\n * Server-supplied per-scope totals, passed through verbatim, or `undefined`\n * when the server omits them. NEVER falls back to counting `matched`: a count\n * off the loaded page is wrong under pagination, which is the bug scopes fix.\n */\n scopeCounts?: Record<string, number>;\n}\n\n/**\n * The rows to render: in server mode `rows` is already the current page (the\n * backend filtered/sorted/paginated), so it passes through untouched; otherwise\n * the client search/pill/range filter narrows it.\n */\nfunction useMatchedRows<T extends Record<string, unknown>>(\n server: DataViewServer | undefined,\n rows: T[],\n columns: DataViewColumn<T>[],\n fields: FilterFieldConfig<T>[],\n rangeFields: RangeFieldConfig<T>[],\n state: DataViewState,\n): T[] {\n return useMemo(\n () =>\n server\n ? rows\n : filterRows(\n rows,\n columns,\n fields,\n { search: state.search, pills: state.pills, ranges: state.ranges },\n rangeFields,\n ),\n [server, rows, columns, fields, rangeFields, state.search, state.pills, state.ranges],\n );\n}\n\n/**\n * Reconcile external state changes and surface every change to the caller:\n * - `appliedState` (a saved view) fully REPLACES the state — it is columns-\n * authoritative, so applying a view restores its filters, sort AND columns.\n * - `syncState` (URL-driven controls) MERGES over the current state, leaving\n * `visibleColumns` untouched — so browser back/forward or a same-route\n * deep-link re-applies search/pills/sort without wiping a user's hidden columns.\n * Each channel only fires when its own reference changes (after the first run).\n */\nfunction useStateSyncEffects(\n appliedState: DataViewState | undefined,\n syncState: DataViewSyncState | undefined,\n state: DataViewState,\n onStateChange: ((state: DataViewState) => void) | undefined,\n setState: React.Dispatch<React.SetStateAction<DataViewState>>,\n): void {\n const firstApplied = useRef(true);\n useEffect(() => {\n if (firstApplied.current) {\n firstApplied.current = false;\n return;\n }\n if (appliedState) setState(appliedState);\n // `setState` is a stable useState setter (passed in), included to satisfy\n // exhaustive-deps; the effect still only re-applies when `appliedState` changes.\n }, [appliedState, setState]);\n const firstSync = useRef(true);\n useEffect(() => {\n if (firstSync.current) {\n firstSync.current = false;\n return;\n }\n // Merge — keep the current `visibleColumns` (never URL-carried); only the\n // URL-driven controls change.\n if (syncState) setState((prev) => ({ ...prev, ...syncState }));\n }, [syncState, setState]);\n useEffect(() => {\n onStateChange?.(state);\n }, [state, onStateChange]);\n}\n\n/**\n * The seed view state: a saved view (`appliedState`) or a pristine all-columns\n * one, with the URL-driven controls (`syncState`) merged over it so a deep-linked\n * filter or scope is reflected on the FIRST render. Column visibility is never\n * URL-carried, so the merge cannot wipe it.\n */\nfunction seedState(\n appliedState: DataViewState | undefined,\n syncState: DataViewSyncState | undefined,\n allColumnIds: string[],\n): DataViewState {\n const seed = appliedState ?? emptyViewState(allColumnIds);\n return syncState ? { ...seed, ...syncState } : seed;\n}\n\n/**\n * Selecting a scope: record it, then DROP the selection.\n *\n * A scope change renders a different result set. A selection that survived it\n * would let a bulk action run against rows the user can no longer see — the\n * same reason changing any other part of the query clears it.\n */\nfunction makeSetScope(\n patch: (next: DataViewStatePatch) => void,\n clearSelection: () => void,\n): (id: string) => void {\n return (id) => {\n patch({ scope: id });\n clearSelection();\n };\n}\n\n/**\n * The declared column ids in the stored reading order — the same tolerance\n * `applyOrder` uses, so the Colunas tab lists exactly what the grid renders.\n */\nfunction orderedColumnIds(allColumnIds: string[], order: string[] | undefined): string[] {\n if (!order || order.length === 0) return allColumnIds;\n const declared = new Set(allColumnIds);\n const kept = order.filter((id) => declared.has(id));\n const seen = new Set(kept);\n return [...kept, ...allColumnIds.filter((id) => !seen.has(id))];\n}\n\n/**\n * The query the grid is currently SHOWING — the same shape `onQueryChange`\n * emits, kept as a value so a host control (Exportar) can re-run it against the\n * backend rather than reading the loaded rows.\n */\nfunction liveQuery(\n state: DataViewState,\n scope: string | undefined,\n server: DataViewServer | undefined,\n matchedCount: number,\n): DataViewQuery {\n return {\n search: state.search,\n pills: state.pills,\n ranges: state.ranges ?? {},\n sortBy: state.sortBy,\n // Absent, not undefined, when the table declares no scopes.\n ...(scope !== undefined ? { scope } : {}),\n page: server?.page ?? 1,\n // Client mode has one page, and it is everything that matched.\n pageSize: server?.pageSize ?? matchedCount,\n };\n}\n\n/** The toolbar's active sort, read off the state's FIRST sort entry. */\nfunction activeSortOf(\n state: DataViewState,\n resolvedSortFields: SortFieldDefinition[],\n): { activeSortField: string; activeSortOrder: \"asc\" | \"desc\" } {\n const active = state.sortBy?.[0];\n return {\n activeSortField: active?.id ?? resolvedSortFields[0]?.value ?? \"\",\n activeSortOrder: active?.dir === \"desc\" ? \"desc\" : \"asc\",\n };\n}\n\n/**\n * Owns the DataViews view state (search/pills/ranges/sort/visibleColumns),\n * multi-select, the filter-panel toggle, and every derived value (filtered rows,\n * grid columns, active sort/filter counts). Extracted from the component so the\n * render stays within the size/complexity budget.\n */\nexport function useDataViewsState<T extends Record<string, unknown>>({\n rows,\n columns,\n fields,\n rangeFields,\n getRowId,\n onRowClick,\n appliedState,\n syncState,\n onStateChange,\n testIdPrefix,\n sortFields,\n rowActions,\n rowActionsLeading,\n renderRowMenu,\n server,\n scopes = [],\n scopeFieldId,\n}: UseDataViewsStateArgs<T>): DataViewsController<T> {\n useScopeConfigChecks(scopes, fields.map((field) => field.id), scopeFieldId, server !== undefined);\n const copy = useDataViewsCopy();\n const { columnsWithActions, allColumnIds } = useColumnsWithActions(columns, {\n rowActions,\n rowActionsLeading,\n renderRowMenu,\n testIdPrefix,\n getRowId,\n });\n // Seed once — see {@link seedState}.\n const [state, setState] = useState<DataViewState>(() =>\n seedState(appliedState, syncState, allColumnIds),\n );\n const [filterOpen, setFilterOpen] = useState(false);\n\n useStateSyncEffects(appliedState, syncState, state, onStateChange, setState);\n\n const { patch, toggleColumn } = useStateWriters(setState);\n const matched = useMatchedRows(server, rows, columns, fields, rangeFields, state);\n // Resolved at READ time, every render: a stale deep link or a saved view naming\n // a scope that has since been removed falls back to the first declared scope\n // instead of putting an id the backend rejects on the wire.\n const scope = resolveScope(scopes, state.scope);\n // Server mode: re-fetch on query change (page resets to 1) + drive pagination.\n const { changePage } = useServerQuery(server, state, scope);\n const { gridColumns, hideableColumns } = useRenderedColumns(\n columnsWithActions,\n state.visibleColumns,\n onRowClick,\n state.order,\n );\n // Server mode is where `matched` is a PAGE — see `useSelection` (FUT-942).\n const selection = useSelection(matched, getRowId, { rememberOffPage: Boolean(server) });\n const resolvedSortFields = sortFields ?? defaultSortFields(columns, copy.grid);\n\n return {\n state,\n ranges: state.ranges ?? {},\n patch,\n ...useClearFilters(patch),\n matched,\n gridColumns,\n hideableColumns,\n columnOrder: orderedColumnIds(allColumnIds, state.order),\n toggleColumn,\n ...selection,\n filterOpen,\n setFilterOpen,\n resolvedSortFields,\n ...activeSortOf(state, resolvedSortFields),\n activeFilterCount: computeActiveFilterCount(state, fields, rangeFields),\n ...serverDerived(server, matched.length),\n changePage,\n scope,\n setScope: makeSetScope(patch, selection.clearSelection),\n currentQuery: liveQuery(state, scope, server, matched.length),\n // Verbatim, or absent. See DataViewServer.scopeCounts for why there is no\n // client-side fallback.\n scopeCounts: server?.scopeCounts,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
FleetCanvas
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4PUCT3RX.js";
|
|
4
4
|
import {
|
|
5
5
|
FleetRoster
|
|
6
6
|
} from "./chunk-WPFVQVQC.js";
|
|
@@ -79,4 +79,4 @@ function FleetBody({
|
|
|
79
79
|
export {
|
|
80
80
|
FleetBody
|
|
81
81
|
};
|
|
82
|
-
//# sourceMappingURL=chunk-
|
|
82
|
+
//# sourceMappingURL=chunk-GPTNZ57P.js.map
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DiscloseSlot,
|
|
3
|
+
DragSlot,
|
|
4
|
+
SelectSlot
|
|
5
|
+
} from "./chunk-TVMSXL3R.js";
|
|
1
6
|
import {
|
|
2
7
|
useDisclosure
|
|
3
8
|
} from "./chunk-2JCRNWHE.js";
|
|
@@ -17,11 +22,6 @@ import {
|
|
|
17
22
|
ListCardMeta,
|
|
18
23
|
ListCardTail
|
|
19
24
|
} from "./chunk-CSJ7WNXU.js";
|
|
20
|
-
import {
|
|
21
|
-
DiscloseSlot,
|
|
22
|
-
DragSlot,
|
|
23
|
-
SelectSlot
|
|
24
|
-
} from "./chunk-TVMSXL3R.js";
|
|
25
25
|
import {
|
|
26
26
|
DropIndicator
|
|
27
27
|
} from "./chunk-K4EKTMTC.js";
|
|
@@ -185,4 +185,4 @@ function BaseListCard(props) {
|
|
|
185
185
|
export {
|
|
186
186
|
BaseListCard
|
|
187
187
|
};
|
|
188
|
-
//# sourceMappingURL=chunk-
|
|
188
|
+
//# sourceMappingURL=chunk-H56CRMCM.js.map
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
renderChartByType
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QADTI63U.js";
|
|
4
|
+
import {
|
|
5
|
+
ChartContainer
|
|
6
|
+
} from "./chunk-RIRTW5EU.js";
|
|
4
7
|
import {
|
|
5
8
|
getSizeStyles,
|
|
6
9
|
getVariantStyles,
|
|
7
10
|
plotHeightPx
|
|
8
11
|
} from "./chunk-TCWISGSS.js";
|
|
9
|
-
import {
|
|
10
|
-
ChartContainer
|
|
11
|
-
} from "./chunk-RIRTW5EU.js";
|
|
12
12
|
import {
|
|
13
13
|
muiColor
|
|
14
14
|
} from "./chunk-7ZPUN7TV.js";
|
|
@@ -111,4 +111,4 @@ var Chart = (props) => {
|
|
|
111
111
|
export {
|
|
112
112
|
Chart
|
|
113
113
|
};
|
|
114
|
-
//# sourceMappingURL=chunk-
|
|
114
|
+
//# sourceMappingURL=chunk-HI7JPDD6.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-SUTOAW7I.js";
|
|
5
5
|
import {
|
|
6
6
|
isoToMasked
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-D7SOXI2K.js";
|
|
8
8
|
import {
|
|
9
9
|
EN_US_UI_LABELS
|
|
10
10
|
} from "./chunk-XOXXG7Q5.js";
|
|
@@ -65,4 +65,4 @@ export {
|
|
|
65
65
|
resolveQuickRanges,
|
|
66
66
|
activeQuickRangeId
|
|
67
67
|
};
|
|
68
|
-
//# sourceMappingURL=chunk-
|
|
68
|
+
//# sourceMappingURL=chunk-I54LHHZS.js.map
|
|
@@ -197,6 +197,7 @@ var EN_US_DATA_VIEWS_COPY = {
|
|
|
197
197
|
// rather than being carried over. A translated label above an unchanged
|
|
198
198
|
// mask is the shape that gets a date entered backwards.
|
|
199
199
|
dayMask: "mm/dd/yyyy",
|
|
200
|
+
dayInvalid: "That date does not exist.",
|
|
200
201
|
clearAllFilters: "Clear all filters",
|
|
201
202
|
// The KEYS are the package's own preset ids and stay as they are — the
|
|
202
203
|
// surface matches on them. Only the labels beside them are words.
|
|
@@ -270,4 +271,4 @@ export {
|
|
|
270
271
|
EN_US_DATA_STATE_COPY,
|
|
271
272
|
EN_US_DATA_VIEWS_COPY
|
|
272
273
|
};
|
|
273
|
-
//# sourceMappingURL=chunk-
|
|
274
|
+
//# sourceMappingURL=chunk-I5NTADBO.js.map
|