@12-apps/ui 6.92.1 → 6.92.2
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/DataViews/DataViewsGrid.js +5 -5
- package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +6 -6
- package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +4 -4
- package/dist/_internal/components/data-display/DataViews/data-views-inline-bar.js +3 -3
- package/dist/_internal/components/data-display/DataViews/data-views-more-fields.js +9 -3
- package/dist/_internal/components/data-display/DataViews/data-views-more-filters.js +2 -2
- package/dist/{chunk-ZVHHFLYY.js → chunk-3I5PHWKQ.js} +2 -2
- package/dist/{chunk-OCGPOACB.js → chunk-CNUO2BRV.js} +2 -2
- package/dist/{chunk-VCJ72ODU.js → chunk-D2JQF2WC.js} +65 -15
- package/dist/chunk-D2JQF2WC.js.map +1 -0
- package/dist/{chunk-RZWU2KYP.js → chunk-DWH4TQXK.js} +4 -3
- package/dist/chunk-DWH4TQXK.js.map +1 -0
- package/dist/{chunk-BXZMV6QC.js → chunk-KQDBOZQE.js} +2 -2
- package/dist/{chunk-IEUVP6UV.js → chunk-QE4KYG5I.js} +2 -2
- package/dist/data-display/DataViews.js +6 -6
- package/dist/types/components/data-display/DataViews/data-views-more-fields.d.ts +80 -0
- 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.map +1 -1
- package/package.json +1 -1
- package/src/components/data-display/DataViews/data-views-more-fields.tsx +90 -14
- package/src/components/data-display/DataViews/data-views-more-filters.tsx +2 -2
- package/dist/chunk-RZWU2KYP.js.map +0 -1
- package/dist/chunk-VCJ72ODU.js.map +0 -1
- /package/dist/{chunk-ZVHHFLYY.js.map → chunk-3I5PHWKQ.js.map} +0 -0
- /package/dist/{chunk-OCGPOACB.js.map → chunk-CNUO2BRV.js.map} +0 -0
- /package/dist/{chunk-BXZMV6QC.js.map → chunk-KQDBOZQE.js.map} +0 -0
- /package/dist/{chunk-IEUVP6UV.js.map → chunk-QE4KYG5I.js.map} +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
DataViewsGrid
|
|
4
|
-
} from "../../../../chunk-
|
|
5
|
-
import "../../../../chunk-
|
|
4
|
+
} from "../../../../chunk-CNUO2BRV.js";
|
|
5
|
+
import "../../../../chunk-KQDBOZQE.js";
|
|
6
6
|
import "../../../../chunk-FYUNROLW.js";
|
|
7
7
|
import "../../../../chunk-MKVDHR3B.js";
|
|
8
|
-
import "../../../../chunk-
|
|
8
|
+
import "../../../../chunk-QE4KYG5I.js";
|
|
9
9
|
import "../../../../chunk-T7OIVPCO.js";
|
|
10
10
|
import "../../../../chunk-X3AFXHY5.js";
|
|
11
11
|
import "../../../../chunk-XNAI7QGU.js";
|
|
@@ -13,8 +13,8 @@ import "../../../../chunk-7TCOYCD7.js";
|
|
|
13
13
|
import "../../../../chunk-4ZQQUICR.js";
|
|
14
14
|
import "../../../../chunk-XZFTRGRW.js";
|
|
15
15
|
import "../../../../chunk-WWH674WU.js";
|
|
16
|
-
import "../../../../chunk-
|
|
17
|
-
import "../../../../chunk-
|
|
16
|
+
import "../../../../chunk-DWH4TQXK.js";
|
|
17
|
+
import "../../../../chunk-D2JQF2WC.js";
|
|
18
18
|
import "../../../../chunk-AJ6KFHEE.js";
|
|
19
19
|
import "../../../../chunk-KYUEO2IO.js";
|
|
20
20
|
import "../../../../chunk-GZOW6HNN.js";
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
DataViewsTableBase
|
|
4
|
-
} from "../../../../chunk-
|
|
4
|
+
} from "../../../../chunk-3I5PHWKQ.js";
|
|
5
5
|
import "../../../../chunk-YNVTUQ5B.js";
|
|
6
|
-
import "../../../../chunk-
|
|
6
|
+
import "../../../../chunk-CNUO2BRV.js";
|
|
7
7
|
import "../../../../chunk-ZOLAYP2D.js";
|
|
8
|
-
import "../../../../chunk-
|
|
8
|
+
import "../../../../chunk-KQDBOZQE.js";
|
|
9
9
|
import "../../../../chunk-FYUNROLW.js";
|
|
10
10
|
import "../../../../chunk-MKVDHR3B.js";
|
|
11
|
-
import "../../../../chunk-
|
|
11
|
+
import "../../../../chunk-QE4KYG5I.js";
|
|
12
12
|
import "../../../../chunk-T7OIVPCO.js";
|
|
13
13
|
import "../../../../chunk-X3AFXHY5.js";
|
|
14
14
|
import "../../../../chunk-XNAI7QGU.js";
|
|
@@ -16,8 +16,8 @@ import "../../../../chunk-7TCOYCD7.js";
|
|
|
16
16
|
import "../../../../chunk-4ZQQUICR.js";
|
|
17
17
|
import "../../../../chunk-XZFTRGRW.js";
|
|
18
18
|
import "../../../../chunk-WWH674WU.js";
|
|
19
|
-
import "../../../../chunk-
|
|
20
|
-
import "../../../../chunk-
|
|
19
|
+
import "../../../../chunk-DWH4TQXK.js";
|
|
20
|
+
import "../../../../chunk-D2JQF2WC.js";
|
|
21
21
|
import "../../../../chunk-AJ6KFHEE.js";
|
|
22
22
|
import "../../../../chunk-KYUEO2IO.js";
|
|
23
23
|
import "../../../../chunk-GZOW6HNN.js";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
GridShell
|
|
4
|
-
} from "../../../../chunk-
|
|
4
|
+
} from "../../../../chunk-KQDBOZQE.js";
|
|
5
5
|
import "../../../../chunk-FYUNROLW.js";
|
|
6
6
|
import "../../../../chunk-MKVDHR3B.js";
|
|
7
|
-
import "../../../../chunk-
|
|
7
|
+
import "../../../../chunk-QE4KYG5I.js";
|
|
8
8
|
import "../../../../chunk-T7OIVPCO.js";
|
|
9
9
|
import "../../../../chunk-X3AFXHY5.js";
|
|
10
10
|
import "../../../../chunk-XNAI7QGU.js";
|
|
@@ -12,8 +12,8 @@ import "../../../../chunk-7TCOYCD7.js";
|
|
|
12
12
|
import "../../../../chunk-4ZQQUICR.js";
|
|
13
13
|
import "../../../../chunk-XZFTRGRW.js";
|
|
14
14
|
import "../../../../chunk-WWH674WU.js";
|
|
15
|
-
import "../../../../chunk-
|
|
16
|
-
import "../../../../chunk-
|
|
15
|
+
import "../../../../chunk-DWH4TQXK.js";
|
|
16
|
+
import "../../../../chunk-D2JQF2WC.js";
|
|
17
17
|
import "../../../../chunk-AJ6KFHEE.js";
|
|
18
18
|
import "../../../../chunk-KYUEO2IO.js";
|
|
19
19
|
import "../../../../chunk-GZOW6HNN.js";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
InlineFilterControls
|
|
4
|
-
} from "../../../../chunk-
|
|
4
|
+
} from "../../../../chunk-QE4KYG5I.js";
|
|
5
5
|
import "../../../../chunk-T7OIVPCO.js";
|
|
6
6
|
import "../../../../chunk-WWH674WU.js";
|
|
7
|
-
import "../../../../chunk-
|
|
8
|
-
import "../../../../chunk-
|
|
7
|
+
import "../../../../chunk-DWH4TQXK.js";
|
|
8
|
+
import "../../../../chunk-D2JQF2WC.js";
|
|
9
9
|
import "../../../../chunk-AJ6KFHEE.js";
|
|
10
10
|
import "../../../../chunk-KYUEO2IO.js";
|
|
11
11
|
import "../../../../chunk-GZOW6HNN.js";
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
|
+
MORE_SPACING,
|
|
3
4
|
MoreGroup,
|
|
4
5
|
MoreQuick,
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
clearTargetSx,
|
|
7
|
+
fieldClearing,
|
|
8
|
+
moreHeaderSx
|
|
9
|
+
} from "../../../../chunk-D2JQF2WC.js";
|
|
7
10
|
import "../../../../chunk-AJ6KFHEE.js";
|
|
8
11
|
import "../../../../chunk-KYUEO2IO.js";
|
|
9
12
|
import "../../../../chunk-GZOW6HNN.js";
|
|
@@ -97,8 +100,11 @@ import "../../../../chunk-YKCAJ2TN.js";
|
|
|
97
100
|
import "../../../../chunk-MFU4Y25U.js";
|
|
98
101
|
import "../../../../chunk-PZ5AY32C.js";
|
|
99
102
|
export {
|
|
103
|
+
MORE_SPACING,
|
|
100
104
|
MoreGroup,
|
|
101
105
|
MoreQuick,
|
|
102
|
-
|
|
106
|
+
clearTargetSx,
|
|
107
|
+
fieldClearing,
|
|
108
|
+
moreHeaderSx
|
|
103
109
|
};
|
|
104
110
|
//# sourceMappingURL=data-views-more-fields.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
MoreFilters
|
|
4
|
-
} from "../../../../chunk-
|
|
5
|
-
import "../../../../chunk-
|
|
4
|
+
} from "../../../../chunk-DWH4TQXK.js";
|
|
5
|
+
import "../../../../chunk-D2JQF2WC.js";
|
|
6
6
|
import "../../../../chunk-AJ6KFHEE.js";
|
|
7
7
|
import "../../../../chunk-KYUEO2IO.js";
|
|
8
8
|
import "../../../../chunk-GZOW6HNN.js";
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-YNVTUQ5B.js";
|
|
4
4
|
import {
|
|
5
5
|
DataViewsGrid
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-CNUO2BRV.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-3I5PHWKQ.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
GridShell
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-KQDBOZQE.js";
|
|
4
4
|
import {
|
|
5
5
|
useDataViewsState
|
|
6
6
|
} from "./chunk-ZCNR4DN5.js";
|
|
@@ -27,4 +27,4 @@ function DataViewsGrid(props) {
|
|
|
27
27
|
export {
|
|
28
28
|
DataViewsGrid
|
|
29
29
|
};
|
|
30
|
-
//# sourceMappingURL=chunk-
|
|
30
|
+
//# sourceMappingURL=chunk-CNUO2BRV.js.map
|
|
@@ -148,13 +148,18 @@ function fieldClearing({
|
|
|
148
148
|
clear: () => values.forEach((value) => onTogglePill(field.id, value, false))
|
|
149
149
|
};
|
|
150
150
|
}
|
|
151
|
+
var quickSx = (theme) => ({
|
|
152
|
+
mb: MORE_SPACING.underQuick,
|
|
153
|
+
[theme.breakpoints.up("sm")]: { mb: 1 },
|
|
154
|
+
"&:last-of-type": { mb: 0 }
|
|
155
|
+
});
|
|
151
156
|
function MoreQuick({
|
|
152
157
|
quick,
|
|
153
158
|
pills,
|
|
154
159
|
onToggleQuick,
|
|
155
160
|
testIdPrefix
|
|
156
161
|
}) {
|
|
157
|
-
return /* @__PURE__ */ jsx(default2, { sx:
|
|
162
|
+
return /* @__PURE__ */ jsx(default2, { sx: quickSx, children: /* @__PURE__ */ jsx(
|
|
158
163
|
QuickRow,
|
|
159
164
|
{
|
|
160
165
|
quick,
|
|
@@ -164,6 +169,45 @@ function MoreQuick({
|
|
|
164
169
|
}
|
|
165
170
|
) });
|
|
166
171
|
}
|
|
172
|
+
var MORE_SPACING = {
|
|
173
|
+
/** Under a group. */
|
|
174
|
+
underGroup: 1.5,
|
|
175
|
+
/** Under a shed quick chip, below `sm` (8px from `sm` up, as before). */
|
|
176
|
+
underQuick: 1.5,
|
|
177
|
+
/**
|
|
178
|
+
* The scroller's top inset (`data-views-more-filters.tsx`), at every width:
|
|
179
|
+
* the first group's overlay reaches into it. Not part of a responsive `p`,
|
|
180
|
+
* whose `xs` value is emitted as a media query and would win over it.
|
|
181
|
+
*/
|
|
182
|
+
aboveFirst: 1.5,
|
|
183
|
+
/** Under a group's header, below `sm`, applied or not, so nothing moves on apply. */
|
|
184
|
+
underHeader: 1.25,
|
|
185
|
+
/** Under a group's header from `sm` up, as it always was. */
|
|
186
|
+
underHeaderFromSm: 0.5,
|
|
187
|
+
reachUp: 1.5,
|
|
188
|
+
reachDown: 1.25,
|
|
189
|
+
reachSide: 0.25
|
|
190
|
+
};
|
|
191
|
+
var moreHeaderSx = (theme) => ({
|
|
192
|
+
display: "flex",
|
|
193
|
+
alignItems: "center",
|
|
194
|
+
gap: 1,
|
|
195
|
+
mb: MORE_SPACING.underHeader,
|
|
196
|
+
[theme.breakpoints.up("sm")]: { mb: MORE_SPACING.underHeaderFromSm }
|
|
197
|
+
});
|
|
198
|
+
var clearTargetSx = (theme) => ({
|
|
199
|
+
position: "relative",
|
|
200
|
+
[theme.breakpoints.up("sm")]: { position: "static" },
|
|
201
|
+
"&::before": {
|
|
202
|
+
content: '""',
|
|
203
|
+
position: "absolute",
|
|
204
|
+
top: `-${theme.spacing(MORE_SPACING.reachUp)}`,
|
|
205
|
+
bottom: `-${theme.spacing(MORE_SPACING.reachDown)}`,
|
|
206
|
+
left: `-${theme.spacing(MORE_SPACING.reachSide)}`,
|
|
207
|
+
right: `-${theme.spacing(MORE_SPACING.reachSide)}`,
|
|
208
|
+
[theme.breakpoints.up("sm")]: { display: "none" }
|
|
209
|
+
}
|
|
210
|
+
});
|
|
167
211
|
function MoreGroup({
|
|
168
212
|
field,
|
|
169
213
|
pills,
|
|
@@ -174,8 +218,8 @@ function MoreGroup({
|
|
|
174
218
|
}) {
|
|
175
219
|
const copy = useDataViewsCopy();
|
|
176
220
|
const { applied, clear } = fieldClearing({ field, pills, ranges, onTogglePill, onChangeRange });
|
|
177
|
-
return /* @__PURE__ */ jsxs(default2, { sx: { mb:
|
|
178
|
-
/* @__PURE__ */ jsxs(default2, { sx:
|
|
221
|
+
return /* @__PURE__ */ jsxs(default2, { sx: { mb: MORE_SPACING.underGroup, "&:last-of-type": { mb: 0 } }, children: [
|
|
222
|
+
/* @__PURE__ */ jsxs(default2, { sx: moreHeaderSx, children: [
|
|
179
223
|
/* @__PURE__ */ jsx(Text, { variant: "caption", as: "span", children: /* @__PURE__ */ jsxs(default2, { component: "span", sx: { color: "text.secondary" }, children: [
|
|
180
224
|
field.label,
|
|
181
225
|
field.group === "range" && isRangeSet(ranges[field.id] ?? {}) ? " \u2022" : ""
|
|
@@ -187,17 +231,20 @@ function MoreGroup({
|
|
|
187
231
|
type: "button",
|
|
188
232
|
onClick: clear,
|
|
189
233
|
"data-testid": `${testIdPrefix}-more-${field.id}-clear`,
|
|
190
|
-
sx:
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
234
|
+
sx: [
|
|
235
|
+
{
|
|
236
|
+
ml: "auto",
|
|
237
|
+
border: 0,
|
|
238
|
+
p: 0,
|
|
239
|
+
bgcolor: "transparent",
|
|
240
|
+
cursor: "pointer",
|
|
241
|
+
font: "inherit",
|
|
242
|
+
fontSize: sxRem(12),
|
|
243
|
+
color: "primary.main",
|
|
244
|
+
"&:hover": { textDecoration: "underline" }
|
|
245
|
+
},
|
|
246
|
+
clearTargetSx
|
|
247
|
+
],
|
|
201
248
|
children: copy.filters.clear
|
|
202
249
|
}
|
|
203
250
|
)
|
|
@@ -226,6 +273,9 @@ function MoreGroup({
|
|
|
226
273
|
export {
|
|
227
274
|
fieldClearing,
|
|
228
275
|
MoreQuick,
|
|
276
|
+
MORE_SPACING,
|
|
277
|
+
moreHeaderSx,
|
|
278
|
+
clearTargetSx,
|
|
229
279
|
MoreGroup
|
|
230
280
|
};
|
|
231
|
-
//# sourceMappingURL=chunk-
|
|
281
|
+
//# sourceMappingURL=chunk-D2JQF2WC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/DataViews/data-views-more-fields.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * ONE FIELD, RENDERED INSIDE THE \"MAIS\" PANEL.\n *\n * Split from `data-views-more-filters` at the file-size gate, along the seam\n * that was already there: that module is the trigger, the panel and its\n * footer — the chrome — and this is what goes in it.\n *\n * A field with one or two options renders FLAT: inside a panel there is no\n * space to win back, and two labelled checkboxes are faster than a dropdown\n * needing a second click. Past that — or whenever the field asks for a tree or\n * a search — it is the bar's own {@link PillControl}; see `sharesBarControl`.\n */\nimport Checkbox from \"@mui/material/Checkbox/index.js\";\nimport type { Theme } from \"@mui/material/styles/index.js\";\n\nimport { Box } from \"../../../mui/Box\";\nimport { Text } from \"../../typography/Text\";\n\nimport { PillControl } from \"./data-views-category-pill\";\nimport type { OverflowField } from \"./data-views-overflow\";\nimport { RangeBounds } from \"./data-views-range-pill\";\nimport { isRangeSet } from \"./data-views-range-values\";\nimport type { QuickFilterConfig, RangeValue } from \"./data-views-types\";\nimport { QuickRow } from \"./data-views-quick-chip\";\nimport { isQuickActive } from \"./data-views-overflow-fields\";\nimport { useDataViewsCopy } from \"./data-views-copy-context\";\nimport { fieldRadiusPx } from \"../../../tokens/field-radius\";\nimport { fieldHeight } from \"../../../tokens/field-height\";\nimport { fieldEdge } from \"../../../tokens/field-edge\";\nimport { sxRem } from \"../../../tokens/relative\";\n\n/** What each field's control needs, minus the panel's own chrome. */\nexport interface MoreFieldProps {\n pills: Record<string, string[]>;\n ranges: Record<string, RangeValue>;\n onTogglePill: (fieldId: string, value: string, checked: boolean) => void;\n onChangeRange: (fieldId: string, range: RangeValue) => void;\n /** Presses or releases a quick chip shed into the panel. */\n onToggleQuick?: (quick: QuickFilterConfig) => void;\n testIdPrefix: string;\n}\n\n/**\n * Above this many options a field is a DROPDOWN rather than a flat row of\n * checkboxes. Two options cost two lines and read faster laid out; a \"Cliente\"\n * with a dozen turns the panel into a scrolling wall and buries every field\n * under it, which is exactly what the overflow was meant to avoid.\n */\nconst INLINE_OPTION_LIMIT = 2;\n\n/**\n * Whether an overflowed pill keeps the SAME control it has on the bar.\n *\n * The panel used to build its own flat dropdown for every field past two\n * options, so a field's config only held while it fitted: `control:\n * \"category\"` lost its tree (subcategories flattened into one list, no\n * \"Marcar tudo\", no count footer) and `searchEnabled` lost its search, on\n * exactly the phone widths where most filters live in here. Anything the bar\n * would render as a dropdown now renders as the bar's own {@link PillControl};\n * only a plain two-option field — one that did not ask for a dropdown, a tree\n * or a search — stays a flat checkbox row, which is a panel layout rather than\n * a different control (the filter panel draws the same line).\n */\nfunction sharesBarControl<T extends Record<string, unknown>>(field: OverflowField<T>): boolean {\n const pill = field.pill;\n if (!pill) return false;\n return (\n pill.control === \"category\" ||\n pill.control === \"multiselect\" ||\n pill.searchEnabled === true ||\n pill.options.length > INLINE_OPTION_LIMIT\n );\n}\n\n/** One overflowed pill: the bar's control, or its options as checkboxes. */\nfunction OverflowPill<T extends Record<string, unknown>>({\n field,\n values,\n onTogglePill,\n onClear,\n testIdPrefix,\n}: {\n field: OverflowField<T>;\n values: string[];\n onTogglePill: (fieldId: string, value: string, checked: boolean) => void;\n onClear: () => void;\n testIdPrefix: string;\n}): React.JSX.Element {\n const testId = `${testIdPrefix}-more-${field.id}`;\n if (field.pill && sharesBarControl(field)) {\n return (\n <PillControl\n fieldId={field.id}\n pill={field.pill}\n selected={values}\n onTogglePill={onTogglePill}\n onClearField={onClear}\n testIdPrefix={testIdPrefix}\n testId={testId}\n />\n );\n }\n const onToggle = (value: string, checked: boolean) => onTogglePill(field.id, value, checked);\n return (\n <Box sx={{ display: \"flex\", flexWrap: \"wrap\", gap: 0.75 }}>\n {(field.pill?.options ?? []).map((option) => {\n const checked = values.includes(option.value);\n return (\n <Box\n key={option.value}\n component=\"label\"\n data-testid={`${testId}-${option.value}`}\n sx={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 0.25,\n pr: 1,\n border: 1,\n borderStyle: \"solid\",\n minHeight: fieldHeight,\n borderColor: (theme) => (checked ? theme.palette.primary.main : fieldEdge(theme)),\n bgcolor: checked ? \"action.selected\" : \"transparent\",\n borderRadius: fieldRadiusPx,\n cursor: \"pointer\",\n fontSize: sxRem(13),\n color: checked ? \"primary.main\" : \"text.secondary\",\n }}\n >\n <Checkbox\n size=\"small\"\n checked={checked}\n onChange={(event) => onToggle(option.value, event.target.checked)}\n inputProps={{ \"aria-label\": `${field.label}: ${option.label}` }}\n />\n {option.label}\n </Box>\n );\n })}\n </Box>\n );\n}\n\n\n/**\n * One overflowed range: its presets and its two bounds, as the same controls\n * the pill uses.\n *\n * The whole control DELEGATES to {@link RangeBounds} rather than being built\n * here, which is the point — this panel used to render a raw\n * `<input type=\"date\">`, so the masked `dd/mm/aaaa` field existed only while\n * the filter FITTED on the bar. The moment \"Data\" overflowed it reverted to the\n * native control the mask replaced, and a merchant on a narrow screen never saw\n * the fix at all (FUT-744). `Valor` had the twin bug: a bare `type=\"number\"`\n * plus `Number(raw)` dropped the decimal comma this panel is meant to accept.\n *\n * That also retires the intrinsic-width workaround this pair used to need — a\n * native date input reports a wide minimum (its own mask plus the picker\n * glyph), which is what made two of them refuse to shrink and scrolled the\n * panel sideways. A text input has no such minimum.\n *\n * `RangeBounds` renders the preset chips ITSELF, above the inputs. This panel\n * must NOT render its own row as well: when the delegation above landed, the\n * chips it used to draw by hand stayed behind, and \"Data\" showed Hoje/Ontem/\n * Esta semana/Este mês/Este ano twice — two rows, duplicated test ids, and half\n * the panel's height spent saying the same thing (FUT-751).\n */\nfunction OverflowRange<T extends Record<string, unknown>>({\n field,\n value,\n onChange,\n testIdPrefix,\n}: {\n field: OverflowField<T>;\n value: RangeValue;\n onChange: (range: RangeValue) => void;\n testIdPrefix: string;\n}): React.JSX.Element | null {\n // `group === \"range\"` is what selects this component, so `range` is always\n // set; the guard is for the type, not for a state the caller can reach.\n if (!field.range) return null;\n return (\n <RangeBounds\n field={field.range}\n value={value}\n onChange={onChange}\n testId={`${testIdPrefix}-more-${field.id}`}\n fillRow\n />\n );\n}\n\n/**\n * Whether a field has anything applied, and how to unapply it — the two shapes\n * (a pill's selected values, a range's bounds) answered in one place so the\n * group that renders them stays a renderer.\n */\nexport function fieldClearing<T extends Record<string, unknown>>({\n field,\n pills,\n ranges,\n onTogglePill,\n onChangeRange,\n}: {\n field: OverflowField<T>;\n} & Pick<MoreFieldProps, \"pills\" | \"ranges\" | \"onTogglePill\" | \"onChangeRange\">): {\n applied: boolean;\n clear: () => void;\n} {\n if (field.group === \"quick\" && field.quick) {\n const quick = field.quick;\n // A `default` chip lit by an empty field has nothing to clear.\n const applied = isQuickActive(quick, pills) && (pills[quick.fieldId]?.length ?? 0) > 0;\n return { applied, clear: () => onTogglePill(quick.fieldId, quick.value, false) };\n }\n if (field.group === \"range\") {\n return {\n applied: isRangeSet(ranges[field.id] ?? {}),\n clear: () => onChangeRange(field.id, {}),\n };\n }\n const values = pills[field.id] ?? [];\n return {\n applied: values.length > 0,\n clear: () => values.forEach((value) => onTogglePill(field.id, value, false)),\n };\n}\n\n\n/**\n * Under a shed quick chip: 12px below `sm`, the gap a following group's\n * \"Limpar\" target reaches into (its 8px let the target cover the chip's\n * label); 8px from `sm` up, as before.\n */\nconst quickSx = (theme: Theme) => ({\n mb: MORE_SPACING.underQuick,\n [theme.breakpoints.up(\"sm\")]: { mb: 1 },\n \"&:last-of-type\": { mb: 0 },\n});\n\n/**\n * A quick chip shed into the panel: its own line, because label and count are\n * already the whole control — no heading above it, no \"Limpar\" beside it.\n */\nexport function MoreQuick({\n quick,\n pills,\n onToggleQuick,\n testIdPrefix,\n}: {\n quick: QuickFilterConfig;\n} & Pick<MoreFieldProps, \"pills\" | \"onToggleQuick\" | \"testIdPrefix\">): React.JSX.Element {\n return (\n <Box sx={quickSx}>\n <QuickRow\n quick={quick}\n active={isQuickActive(quick, pills)}\n onToggle={() => onToggleQuick?.(quick)}\n testIdPrefix={testIdPrefix}\n />\n </Box>\n );\n}\n\n/**\n * The \"Mais\" panel's vertical rhythm, in the theme's spacing units: the unit\n * the header \"Limpar\"'s phone target reaches into (FUT-4144). The target is\n * the button's 18px of text plus `reachUp` and `reachDown`, 40px at the\n * default type scale, and it may never reach further than the gap that is\n * there: under the group or quick chip above it (or the scroller's own top\n * inset, for the first group) and under its own header. Sideways it reaches\n * into the header row's empty gap and the scroller's padding, so a 37px\n * \"Limpar\" is 41px wide.\n */\nexport const MORE_SPACING = {\n /** Under a group. */\n underGroup: 1.5,\n /** Under a shed quick chip, below `sm` (8px from `sm` up, as before). */\n underQuick: 1.5,\n /**\n * The scroller's top inset (`data-views-more-filters.tsx`), at every width:\n * the first group's overlay reaches into it. Not part of a responsive `p`,\n * whose `xs` value is emitted as a media query and would win over it.\n */\n aboveFirst: 1.5,\n /** Under a group's header, below `sm`, applied or not, so nothing moves on apply. */\n underHeader: 1.25,\n /** Under a group's header from `sm` up, as it always was. */\n underHeaderFromSm: 0.5,\n reachUp: 1.5,\n reachDown: 1.25,\n reachSide: 0.25,\n} as const;\n\n/** A group's header row: the field's name, and \"Limpar\" while it is applied. */\nexport const moreHeaderSx = (theme: Theme) => ({\n display: \"flex\",\n alignItems: \"center\",\n gap: 1,\n mb: MORE_SPACING.underHeader,\n [theme.breakpoints.up(\"sm\")]: { mb: MORE_SPACING.underHeaderFromSm },\n});\n\n/**\n * \"Limpar\" is 12px text, a 37×18 button: on a phone that was the whole target\n * (FUT-4144, measured in the admin at 320–900). Below `sm` an overlay makes it\n * at least 40×40 without moving the text, reaching only into gaps\n * {@link MORE_SPACING} guarantees, in the same unit, so it grows and shrinks\n * with them and covers nothing else. From `sm` up there is no overlay and the\n * button is exactly as it was.\n */\nexport const clearTargetSx = (theme: Theme) => ({\n position: \"relative\" as const,\n [theme.breakpoints.up(\"sm\")]: { position: \"static\" as const },\n \"&::before\": {\n content: '\"\"',\n position: \"absolute\" as const,\n top: `-${theme.spacing(MORE_SPACING.reachUp)}`,\n bottom: `-${theme.spacing(MORE_SPACING.reachDown)}`,\n left: `-${theme.spacing(MORE_SPACING.reachSide)}`,\n right: `-${theme.spacing(MORE_SPACING.reachSide)}`,\n [theme.breakpoints.up(\"sm\")]: { display: \"none\" },\n },\n});\n\n/** One labelled group in the panel: the field's name, then its control. */\nexport function MoreGroup<T extends Record<string, unknown>>({\n field,\n pills,\n ranges,\n onTogglePill,\n onChangeRange,\n testIdPrefix,\n}: {\n field: OverflowField<T>;\n} & MoreFieldProps): React.JSX.Element {\n const copy = useDataViewsCopy();\n const { applied, clear } = fieldClearing({ field, pills, ranges, onTogglePill, onChangeRange });\n return (\n <Box sx={{ mb: MORE_SPACING.underGroup, \"&:last-of-type\": { mb: 0 } }}>\n <Box sx={moreHeaderSx}>\n <Text variant=\"caption\" as=\"span\">\n <Box component=\"span\" sx={{ color: \"text.secondary\" }}>\n {field.label}\n {field.group === \"range\" && isRangeSet(ranges[field.id] ?? {}) ? \" •\" : \"\"}\n </Box>\n </Text>\n {/* The panel's equivalent of the pill's ✕. Without it a field applied\n in here could only be cleared by finding it again on the bar —\n which is where it goes the moment it becomes active, so the\n operator has to close this panel to undo what they just did. */}\n {applied && (\n <Box\n component=\"button\"\n type=\"button\"\n onClick={clear}\n data-testid={`${testIdPrefix}-more-${field.id}-clear`}\n sx={[\n {\n ml: \"auto\",\n border: 0,\n p: 0,\n bgcolor: \"transparent\",\n cursor: \"pointer\",\n font: \"inherit\",\n fontSize: sxRem(12),\n color: \"primary.main\",\n \"&:hover\": { textDecoration: \"underline\" },\n },\n clearTargetSx,\n ]}\n >\n {copy.filters.clear}\n </Box>\n )}\n </Box>\n {field.group === \"pill\" ? (\n <OverflowPill\n field={field}\n values={pills[field.id] ?? []}\n onTogglePill={onTogglePill}\n onClear={() => (pills[field.id] ?? []).forEach((v) => onTogglePill(field.id, v, false))}\n testIdPrefix={testIdPrefix}\n />\n ) : (\n <OverflowRange\n field={field}\n value={ranges[field.id] ?? {}}\n onChange={(range) => onChangeRange(field.id, range)}\n testIdPrefix={testIdPrefix}\n />\n )}\n </Box>\n );\n}\n\n"],"mappings":"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","names":["default"]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
+
MORE_SPACING,
|
|
2
3
|
MoreGroup,
|
|
3
4
|
MoreQuick,
|
|
4
5
|
fieldClearing
|
|
5
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-D2JQF2WC.js";
|
|
6
7
|
import {
|
|
7
8
|
useStillAnchor
|
|
8
9
|
} from "./chunk-7CUZTWKW.js";
|
|
@@ -211,7 +212,7 @@ function MoreFilters({
|
|
|
211
212
|
slotProps: { paper: { ref: still.paperRef, sx: phone ? PHONE_PAPER_SX : PAPER_SX } },
|
|
212
213
|
children: /* @__PURE__ */ jsxs(default2, { "data-testid": `${rest.testIdPrefix}-more-panel`, sx: { ...COLUMN_SX, flex: "1 1 auto", minHeight: 0 }, children: [
|
|
213
214
|
/* @__PURE__ */ jsx(MoreHeading, {}),
|
|
214
|
-
/* @__PURE__ */ jsx(default2, { sx: { flex: "1 1 auto", minHeight: 0, overflowY: "auto", overflowX: "hidden",
|
|
215
|
+
/* @__PURE__ */ jsx(default2, { sx: { flex: "1 1 auto", minHeight: 0, overflowY: "auto", overflowX: "hidden", px: { xs: 1, sm: 1.5 }, pb: { xs: 1, sm: 1.5 }, pt: MORE_SPACING.aboveFirst, minWidth: 0 }, children: /* @__PURE__ */ jsx(MoreFields, { fields, ...rest }, clearKey) }),
|
|
215
216
|
(anyApplied || holdsDayRange) && /* @__PURE__ */ jsx(MoreFooter, { onClearAll, testIdPrefix: rest.testIdPrefix, reserved: !anyApplied })
|
|
216
217
|
] })
|
|
217
218
|
}
|
|
@@ -222,4 +223,4 @@ function MoreFilters({
|
|
|
222
223
|
export {
|
|
223
224
|
MoreFilters
|
|
224
225
|
};
|
|
225
|
-
//# sourceMappingURL=chunk-
|
|
226
|
+
//# sourceMappingURL=chunk-DWH4TQXK.js.map
|
|
@@ -0,0 +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 { useTheme, type Theme } from \"@mui/material/styles/index.js\";\nimport useMediaQuery from \"@mui/material/useMediaQuery/index.js\";\n\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, MORE_SPACING, MoreGroup, MoreQuick, type MoreFieldProps } from \"./data-views-more-fields\";\nimport { useStillAnchor } from \"./data-views-still-anchor\";\nimport type { OverflowField } from \"./data-views-overflow\";\nimport { rem, remPx, 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 reserved = false,\n}: {\n onClearAll: () => void;\n testIdPrefix: string;\n /**\n * Hold the footer's height with nothing in it. A panel holding a day range\n * keeps the row while nothing is applied, so the first tap on its calendar\n * does not grow the panel by a row and move its top under the finger\n * (FUT-4144 UI review).\n */\n reserved?: boolean;\n}): React.JSX.Element {\n const copy = useDataViewsCopy();\n return (\n <Box\n aria-hidden={reserved || undefined}\n // Held, the row is blank — no rule over it either, or it reads as an\n // empty bordered row.\n sx={{ px: 1.5, py: 1, borderTop: 1, borderColor: reserved ? \"transparent\" : \"divider\", visibility: reserved ? \"hidden\" : undefined }}\n >\n <Box\n component=\"button\"\n type=\"button\"\n onClick={reserved ? undefined : onClearAll}\n tabIndex={reserved ? -1 : undefined}\n data-testid={reserved ? undefined : `${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/**\n * The panel is a column: heading, the fields' scroller, footer. Its height is\n * the screen's, not a fixed 320px — at 390×844 that cap scrolled a day range's\n * month caption and weekday row out of view after the first tap, and a typed\n * day's refusal out of sight of its box (FUT-4144 UI review). MUI moves the\n * panel up when it is taller than the room under its trigger.\n */\nconst COLUMN_SX = { display: \"flex\", flexDirection: \"column\" } as const;\n\n/**\n * 320, not 300: inside 12px of padding a day range's month then has the 280px\n * its seven 40px columns need and its month/year caption one row (FUT-4144).\n */\nconst PAPER_SX = (theme: Theme) => ({\n ...COLUMN_SX,\n width: rem(theme, 320),\n maxWidth: `calc(100vw - ${rem(theme, 32)})`,\n});\n\n/**\n * Below `sm` the panel takes the screen's width less 8px each side, so a day\n * range's calendar gets the 280px its seven 40px columns need (it had 264 at\n * 320 and 276 at 390, so every day was a 34-36px target).\n */\nconst PHONE_PAPER_SX = (theme: Theme) => ({\n ...COLUMN_SX,\n width: `calc(100vw - ${rem(theme, 16)})`,\n maxWidth: `calc(100vw - ${rem(theme, 16)})`,\n maxHeight: `calc(100% - ${rem(theme, 16)})`,\n});\n\n/** Props of {@link MoreFilters}. */\ninterface MoreFiltersPanelProps<T extends Record<string, unknown>> extends 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}\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}: MoreFiltersPanelProps<T>): React.JSX.Element | null {\n const still = useStillAnchor();\n const theme = useTheme();\n const phone = useMediaQuery(theme.breakpoints.down(\"sm\"));\n if (fields.length === 0) return null;\n const holdsDayRange = fields.some((field) => field.range?.kind === \"day\");\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 still.open(element);\n onOpenChange?.(true);\n }}\n testIdPrefix={rest.testIdPrefix}\n />\n <Popover\n {...still.popoverProps}\n onClose={() => {\n still.close();\n onOpenChange?.(false);\n }}\n // Below `sm`, 8px from the screen's edges instead of 16.\n marginThreshold={phone ? remPx(theme, 8) : undefined}\n slotProps={{ paper: { ref: still.paperRef, sx: phone ? PHONE_PAPER_SX : PAPER_SX } }}\n >\n <Box data-testid={`${rest.testIdPrefix}-more-panel`} sx={{ ...COLUMN_SX, flex: \"1 1 auto\", minHeight: 0 }}>\n <MoreHeading />\n {/* overflowX hidden, not auto: this panel is a fixed width 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={{ flex: \"1 1 auto\", minHeight: 0, overflowY: \"auto\", overflowX: \"hidden\", px: { xs: 1, sm: 1.5 }, pb: { xs: 1, sm: 1.5 }, pt: MORE_SPACING.aboveFirst, minWidth: 0 }}>\n <MoreFields key={clearKey} fields={fields} {...rest} />\n </Box>\n {(anyApplied || holdsDayRange) && (\n <MoreFooter onClearAll={onClearAll} testIdPrefix={rest.testIdPrefix} reserved={!anyApplied} />\n )}\n </Box>\n </Popover>\n </>\n );\n}\n"],"mappings":"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","names":["default"]}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-MKVDHR3B.js";
|
|
8
8
|
import {
|
|
9
9
|
InlineFilterControls
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-QE4KYG5I.js";
|
|
11
11
|
import {
|
|
12
12
|
GridHeaderRow
|
|
13
13
|
} from "./chunk-X3AFXHY5.js";
|
|
@@ -252,4 +252,4 @@ function GridShell(props) {
|
|
|
252
252
|
export {
|
|
253
253
|
GridShell
|
|
254
254
|
};
|
|
255
|
-
//# sourceMappingURL=chunk-
|
|
255
|
+
//# sourceMappingURL=chunk-KQDBOZQE.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "./chunk-T7OIVPCO.js";
|
|
6
6
|
import {
|
|
7
7
|
MoreFilters
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-DWH4TQXK.js";
|
|
9
9
|
import {
|
|
10
10
|
PillControl
|
|
11
11
|
} from "./chunk-AJ6KFHEE.js";
|
|
@@ -251,4 +251,4 @@ function FilterSlots({
|
|
|
251
251
|
export {
|
|
252
252
|
InlineFilterControls
|
|
253
253
|
};
|
|
254
|
-
//# sourceMappingURL=chunk-
|
|
254
|
+
//# sourceMappingURL=chunk-QE4KYG5I.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DataViewsTableBase
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-3I5PHWKQ.js";
|
|
4
4
|
import "../chunk-YNVTUQ5B.js";
|
|
5
5
|
import {
|
|
6
6
|
DataViewsGrid
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-CNUO2BRV.js";
|
|
8
8
|
import {
|
|
9
9
|
BaseListCard
|
|
10
10
|
} from "../chunk-IWSTMVCA.js";
|
|
@@ -23,10 +23,10 @@ import {
|
|
|
23
23
|
useDragItem
|
|
24
24
|
} from "../chunk-K4EKTMTC.js";
|
|
25
25
|
import "../chunk-ZOLAYP2D.js";
|
|
26
|
-
import "../chunk-
|
|
26
|
+
import "../chunk-KQDBOZQE.js";
|
|
27
27
|
import "../chunk-FYUNROLW.js";
|
|
28
28
|
import "../chunk-MKVDHR3B.js";
|
|
29
|
-
import "../chunk-
|
|
29
|
+
import "../chunk-QE4KYG5I.js";
|
|
30
30
|
import "../chunk-T7OIVPCO.js";
|
|
31
31
|
import "../chunk-X3AFXHY5.js";
|
|
32
32
|
import "../chunk-XNAI7QGU.js";
|
|
@@ -36,8 +36,8 @@ import {
|
|
|
36
36
|
import "../chunk-4ZQQUICR.js";
|
|
37
37
|
import "../chunk-XZFTRGRW.js";
|
|
38
38
|
import "../chunk-WWH674WU.js";
|
|
39
|
-
import "../chunk-
|
|
40
|
-
import "../chunk-
|
|
39
|
+
import "../chunk-DWH4TQXK.js";
|
|
40
|
+
import "../chunk-D2JQF2WC.js";
|
|
41
41
|
import "../chunk-AJ6KFHEE.js";
|
|
42
42
|
import "../chunk-KYUEO2IO.js";
|
|
43
43
|
import "../chunk-GZOW6HNN.js";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Theme } from "@mui/material/styles/index.js";
|
|
1
2
|
import type { OverflowField } from "./data-views-overflow";
|
|
2
3
|
import type { QuickFilterConfig, RangeValue } from "./data-views-types";
|
|
3
4
|
/** What each field's control needs, minus the panel's own chrome. */
|
|
@@ -28,6 +29,85 @@ export declare function fieldClearing<T extends Record<string, unknown>>({ field
|
|
|
28
29
|
export declare function MoreQuick({ quick, pills, onToggleQuick, testIdPrefix, }: {
|
|
29
30
|
quick: QuickFilterConfig;
|
|
30
31
|
} & Pick<MoreFieldProps, "pills" | "onToggleQuick" | "testIdPrefix">): React.JSX.Element;
|
|
32
|
+
/**
|
|
33
|
+
* The "Mais" panel's vertical rhythm, in the theme's spacing units: the unit
|
|
34
|
+
* the header "Limpar"'s phone target reaches into (FUT-4144). The target is
|
|
35
|
+
* the button's 18px of text plus `reachUp` and `reachDown`, 40px at the
|
|
36
|
+
* default type scale, and it may never reach further than the gap that is
|
|
37
|
+
* there: under the group or quick chip above it (or the scroller's own top
|
|
38
|
+
* inset, for the first group) and under its own header. Sideways it reaches
|
|
39
|
+
* into the header row's empty gap and the scroller's padding, so a 37px
|
|
40
|
+
* "Limpar" is 41px wide.
|
|
41
|
+
*/
|
|
42
|
+
export declare const MORE_SPACING: {
|
|
43
|
+
/** Under a group. */
|
|
44
|
+
readonly underGroup: 1.5;
|
|
45
|
+
/** Under a shed quick chip, below `sm` (8px from `sm` up, as before). */
|
|
46
|
+
readonly underQuick: 1.5;
|
|
47
|
+
/**
|
|
48
|
+
* The scroller's top inset (`data-views-more-filters.tsx`), at every width:
|
|
49
|
+
* the first group's overlay reaches into it. Not part of a responsive `p`,
|
|
50
|
+
* whose `xs` value is emitted as a media query and would win over it.
|
|
51
|
+
*/
|
|
52
|
+
readonly aboveFirst: 1.5;
|
|
53
|
+
/** Under a group's header, below `sm`, applied or not, so nothing moves on apply. */
|
|
54
|
+
readonly underHeader: 1.25;
|
|
55
|
+
/** Under a group's header from `sm` up, as it always was. */
|
|
56
|
+
readonly underHeaderFromSm: 0.5;
|
|
57
|
+
readonly reachUp: 1.5;
|
|
58
|
+
readonly reachDown: 1.25;
|
|
59
|
+
readonly reachSide: 0.25;
|
|
60
|
+
};
|
|
61
|
+
/** A group's header row: the field's name, and "Limpar" while it is applied. */
|
|
62
|
+
export declare const moreHeaderSx: (theme: Theme) => {
|
|
63
|
+
[x: string]: string | number | {
|
|
64
|
+
mb: 0.5;
|
|
65
|
+
};
|
|
66
|
+
display: string;
|
|
67
|
+
alignItems: string;
|
|
68
|
+
gap: number;
|
|
69
|
+
mb: 1.25;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* "Limpar" is 12px text, a 37×18 button: on a phone that was the whole target
|
|
73
|
+
* (FUT-4144, measured in the admin at 320–900). Below `sm` an overlay makes it
|
|
74
|
+
* at least 40×40 without moving the text, reaching only into gaps
|
|
75
|
+
* {@link MORE_SPACING} guarantees, in the same unit, so it grows and shrinks
|
|
76
|
+
* with them and covers nothing else. From `sm` up there is no overlay and the
|
|
77
|
+
* button is exactly as it was.
|
|
78
|
+
*/
|
|
79
|
+
export declare const clearTargetSx: (theme: Theme) => {
|
|
80
|
+
[x: string]: "relative" | {
|
|
81
|
+
position: "static";
|
|
82
|
+
content?: undefined;
|
|
83
|
+
top?: undefined;
|
|
84
|
+
bottom?: undefined;
|
|
85
|
+
left?: undefined;
|
|
86
|
+
right?: undefined;
|
|
87
|
+
} | {
|
|
88
|
+
[x: string]: string | {
|
|
89
|
+
display: string;
|
|
90
|
+
};
|
|
91
|
+
content: string;
|
|
92
|
+
position: "absolute";
|
|
93
|
+
top: string;
|
|
94
|
+
bottom: string;
|
|
95
|
+
left: string;
|
|
96
|
+
right: string;
|
|
97
|
+
};
|
|
98
|
+
position: "relative";
|
|
99
|
+
"&::before": {
|
|
100
|
+
[x: string]: string | {
|
|
101
|
+
display: string;
|
|
102
|
+
};
|
|
103
|
+
content: string;
|
|
104
|
+
position: "absolute";
|
|
105
|
+
top: string;
|
|
106
|
+
bottom: string;
|
|
107
|
+
left: string;
|
|
108
|
+
right: string;
|
|
109
|
+
};
|
|
110
|
+
};
|
|
31
111
|
/** One labelled group in the panel: the field's name, then its control. */
|
|
32
112
|
export declare function MoreGroup<T extends Record<string, unknown>>({ field, pills, ranges, onTogglePill, onChangeRange, testIdPrefix, }: {
|
|
33
113
|
field: OverflowField<T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-views-more-fields.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/DataViews/data-views-more-fields.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"data-views-more-fields.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/DataViews/data-views-more-fields.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAM3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AASxE,qEAAqE;AACrE,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACzE,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAC5D,4DAA4D;IAC5D,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACnD,YAAY,EAAE,MAAM,CAAC;CACtB;AAuJD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC/D,KAAK,EACL,KAAK,EACL,MAAM,EACN,YAAY,EACZ,aAAa,GACd,EAAE;IACD,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;CACzB,GAAG,IAAI,CAAC,cAAc,EAAE,OAAO,GAAG,QAAQ,GAAG,cAAc,GAAG,eAAe,CAAC,GAAG;IAChF,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAkBA;AAcD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,KAAK,EACL,aAAa,EACb,YAAY,GACb,EAAE;IACD,KAAK,EAAE,iBAAiB,CAAC;CAC1B,GAAG,IAAI,CAAC,cAAc,EAAE,OAAO,GAAG,eAAe,GAAG,cAAc,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAWvF;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY;IACvB,qBAAqB;;IAErB,yEAAyE;;IAEzE;;;;OAIG;;IAEH,qFAAqF;;IAErF,6DAA6D;;;;;CAKrD,CAAC;AAEX,gFAAgF;AAChF,eAAO,MAAM,YAAY,GAAI,OAAO,KAAK;;;;;;;;CAMvC,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAYxC,CAAC;AAEH,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC3D,KAAK,EACL,KAAK,EACL,MAAM,EACN,YAAY,EACZ,aAAa,EACb,YAAY,GACb,EAAE;IACD,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;CACzB,GAAG,cAAc,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA2DrC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-views-more-filters.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/DataViews/data-views-more-filters.tsx"],"names":[],"mappings":"AAmBA,OAAO,
|
|
1
|
+
{"version":3,"file":"data-views-more-filters.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/DataViews/data-views-more-filters.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAAqD,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAElH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D;;;;;;;;;;GAUG;AAEH,UAAU,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,cAAc;IAClF,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;CAC5B;AAmND,oCAAoC;AACpC,UAAU,qBAAqB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IAC5F,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,gFAAgF;IAChF,UAAU,EAAE,OAAO,CAAC;IACpB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACxC;AAED,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC7D,MAAM,EACN,YAAY,EACZ,UAAU,EACV,UAAU,EACV,OAAe,EACf,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAuDrD"}
|
package/package.json
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* a search — it is the bar's own {@link PillControl}; see `sharesBarControl`.
|
|
14
14
|
*/
|
|
15
15
|
import Checkbox from "@mui/material/Checkbox/index.js";
|
|
16
|
+
import type { Theme } from "@mui/material/styles/index.js";
|
|
16
17
|
|
|
17
18
|
import { Box } from "../../../mui/Box";
|
|
18
19
|
import { Text } from "../../typography/Text";
|
|
@@ -227,6 +228,17 @@ export function fieldClearing<T extends Record<string, unknown>>({
|
|
|
227
228
|
}
|
|
228
229
|
|
|
229
230
|
|
|
231
|
+
/**
|
|
232
|
+
* Under a shed quick chip: 12px below `sm`, the gap a following group's
|
|
233
|
+
* "Limpar" target reaches into (its 8px let the target cover the chip's
|
|
234
|
+
* label); 8px from `sm` up, as before.
|
|
235
|
+
*/
|
|
236
|
+
const quickSx = (theme: Theme) => ({
|
|
237
|
+
mb: MORE_SPACING.underQuick,
|
|
238
|
+
[theme.breakpoints.up("sm")]: { mb: 1 },
|
|
239
|
+
"&:last-of-type": { mb: 0 },
|
|
240
|
+
});
|
|
241
|
+
|
|
230
242
|
/**
|
|
231
243
|
* A quick chip shed into the panel: its own line, because label and count are
|
|
232
244
|
* already the whole control — no heading above it, no "Limpar" beside it.
|
|
@@ -240,7 +252,7 @@ export function MoreQuick({
|
|
|
240
252
|
quick: QuickFilterConfig;
|
|
241
253
|
} & Pick<MoreFieldProps, "pills" | "onToggleQuick" | "testIdPrefix">): React.JSX.Element {
|
|
242
254
|
return (
|
|
243
|
-
<Box sx={
|
|
255
|
+
<Box sx={quickSx}>
|
|
244
256
|
<QuickRow
|
|
245
257
|
quick={quick}
|
|
246
258
|
active={isQuickActive(quick, pills)}
|
|
@@ -251,6 +263,67 @@ export function MoreQuick({
|
|
|
251
263
|
);
|
|
252
264
|
}
|
|
253
265
|
|
|
266
|
+
/**
|
|
267
|
+
* The "Mais" panel's vertical rhythm, in the theme's spacing units: the unit
|
|
268
|
+
* the header "Limpar"'s phone target reaches into (FUT-4144). The target is
|
|
269
|
+
* the button's 18px of text plus `reachUp` and `reachDown`, 40px at the
|
|
270
|
+
* default type scale, and it may never reach further than the gap that is
|
|
271
|
+
* there: under the group or quick chip above it (or the scroller's own top
|
|
272
|
+
* inset, for the first group) and under its own header. Sideways it reaches
|
|
273
|
+
* into the header row's empty gap and the scroller's padding, so a 37px
|
|
274
|
+
* "Limpar" is 41px wide.
|
|
275
|
+
*/
|
|
276
|
+
export const MORE_SPACING = {
|
|
277
|
+
/** Under a group. */
|
|
278
|
+
underGroup: 1.5,
|
|
279
|
+
/** Under a shed quick chip, below `sm` (8px from `sm` up, as before). */
|
|
280
|
+
underQuick: 1.5,
|
|
281
|
+
/**
|
|
282
|
+
* The scroller's top inset (`data-views-more-filters.tsx`), at every width:
|
|
283
|
+
* the first group's overlay reaches into it. Not part of a responsive `p`,
|
|
284
|
+
* whose `xs` value is emitted as a media query and would win over it.
|
|
285
|
+
*/
|
|
286
|
+
aboveFirst: 1.5,
|
|
287
|
+
/** Under a group's header, below `sm`, applied or not, so nothing moves on apply. */
|
|
288
|
+
underHeader: 1.25,
|
|
289
|
+
/** Under a group's header from `sm` up, as it always was. */
|
|
290
|
+
underHeaderFromSm: 0.5,
|
|
291
|
+
reachUp: 1.5,
|
|
292
|
+
reachDown: 1.25,
|
|
293
|
+
reachSide: 0.25,
|
|
294
|
+
} as const;
|
|
295
|
+
|
|
296
|
+
/** A group's header row: the field's name, and "Limpar" while it is applied. */
|
|
297
|
+
export const moreHeaderSx = (theme: Theme) => ({
|
|
298
|
+
display: "flex",
|
|
299
|
+
alignItems: "center",
|
|
300
|
+
gap: 1,
|
|
301
|
+
mb: MORE_SPACING.underHeader,
|
|
302
|
+
[theme.breakpoints.up("sm")]: { mb: MORE_SPACING.underHeaderFromSm },
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* "Limpar" is 12px text, a 37×18 button: on a phone that was the whole target
|
|
307
|
+
* (FUT-4144, measured in the admin at 320–900). Below `sm` an overlay makes it
|
|
308
|
+
* at least 40×40 without moving the text, reaching only into gaps
|
|
309
|
+
* {@link MORE_SPACING} guarantees, in the same unit, so it grows and shrinks
|
|
310
|
+
* with them and covers nothing else. From `sm` up there is no overlay and the
|
|
311
|
+
* button is exactly as it was.
|
|
312
|
+
*/
|
|
313
|
+
export const clearTargetSx = (theme: Theme) => ({
|
|
314
|
+
position: "relative" as const,
|
|
315
|
+
[theme.breakpoints.up("sm")]: { position: "static" as const },
|
|
316
|
+
"&::before": {
|
|
317
|
+
content: '""',
|
|
318
|
+
position: "absolute" as const,
|
|
319
|
+
top: `-${theme.spacing(MORE_SPACING.reachUp)}`,
|
|
320
|
+
bottom: `-${theme.spacing(MORE_SPACING.reachDown)}`,
|
|
321
|
+
left: `-${theme.spacing(MORE_SPACING.reachSide)}`,
|
|
322
|
+
right: `-${theme.spacing(MORE_SPACING.reachSide)}`,
|
|
323
|
+
[theme.breakpoints.up("sm")]: { display: "none" },
|
|
324
|
+
},
|
|
325
|
+
});
|
|
326
|
+
|
|
254
327
|
/** One labelled group in the panel: the field's name, then its control. */
|
|
255
328
|
export function MoreGroup<T extends Record<string, unknown>>({
|
|
256
329
|
field,
|
|
@@ -265,8 +338,8 @@ export function MoreGroup<T extends Record<string, unknown>>({
|
|
|
265
338
|
const copy = useDataViewsCopy();
|
|
266
339
|
const { applied, clear } = fieldClearing({ field, pills, ranges, onTogglePill, onChangeRange });
|
|
267
340
|
return (
|
|
268
|
-
<Box sx={{ mb:
|
|
269
|
-
<Box sx={
|
|
341
|
+
<Box sx={{ mb: MORE_SPACING.underGroup, "&:last-of-type": { mb: 0 } }}>
|
|
342
|
+
<Box sx={moreHeaderSx}>
|
|
270
343
|
<Text variant="caption" as="span">
|
|
271
344
|
<Box component="span" sx={{ color: "text.secondary" }}>
|
|
272
345
|
{field.label}
|
|
@@ -283,17 +356,20 @@ export function MoreGroup<T extends Record<string, unknown>>({
|
|
|
283
356
|
type="button"
|
|
284
357
|
onClick={clear}
|
|
285
358
|
data-testid={`${testIdPrefix}-more-${field.id}-clear`}
|
|
286
|
-
sx={
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
359
|
+
sx={[
|
|
360
|
+
{
|
|
361
|
+
ml: "auto",
|
|
362
|
+
border: 0,
|
|
363
|
+
p: 0,
|
|
364
|
+
bgcolor: "transparent",
|
|
365
|
+
cursor: "pointer",
|
|
366
|
+
font: "inherit",
|
|
367
|
+
fontSize: sxRem(12),
|
|
368
|
+
color: "primary.main",
|
|
369
|
+
"&:hover": { textDecoration: "underline" },
|
|
370
|
+
},
|
|
371
|
+
clearTargetSx,
|
|
372
|
+
]}
|
|
297
373
|
>
|
|
298
374
|
{copy.filters.clear}
|
|
299
375
|
</Box>
|
|
@@ -17,7 +17,7 @@ import { Button } from "../../form/Button";
|
|
|
17
17
|
import { Box } from "../../../mui/Box";
|
|
18
18
|
import { Text } from "../../typography/Text";
|
|
19
19
|
|
|
20
|
-
import { fieldClearing, MoreGroup, MoreQuick, type MoreFieldProps } from "./data-views-more-fields";
|
|
20
|
+
import { fieldClearing, MORE_SPACING, MoreGroup, MoreQuick, type MoreFieldProps } from "./data-views-more-fields";
|
|
21
21
|
import { useStillAnchor } from "./data-views-still-anchor";
|
|
22
22
|
import type { OverflowField } from "./data-views-overflow";
|
|
23
23
|
import { rem, remPx, sxRem } from "../../../tokens/relative";
|
|
@@ -322,7 +322,7 @@ export function MoreFilters<T extends Record<string, unknown>>({
|
|
|
322
322
|
contents are told to shrink into it. A horizontal scrollbar here
|
|
323
323
|
means something refused to, which is a bug to fix rather than a
|
|
324
324
|
scrollbar to live with. */}
|
|
325
|
-
<Box sx={{ flex: "1 1 auto", minHeight: 0, overflowY: "auto", overflowX: "hidden",
|
|
325
|
+
<Box sx={{ flex: "1 1 auto", minHeight: 0, overflowY: "auto", overflowX: "hidden", px: { xs: 1, sm: 1.5 }, pb: { xs: 1, sm: 1.5 }, pt: MORE_SPACING.aboveFirst, minWidth: 0 }}>
|
|
326
326
|
<MoreFields key={clearKey} fields={fields} {...rest} />
|
|
327
327
|
</Box>
|
|
328
328
|
{(anyApplied || holdsDayRange) && (
|
|
@@ -1 +0,0 @@
|
|
|
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 { useTheme, type Theme } from \"@mui/material/styles/index.js\";\nimport useMediaQuery from \"@mui/material/useMediaQuery/index.js\";\n\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 { useStillAnchor } from \"./data-views-still-anchor\";\nimport type { OverflowField } from \"./data-views-overflow\";\nimport { rem, remPx, 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 reserved = false,\n}: {\n onClearAll: () => void;\n testIdPrefix: string;\n /**\n * Hold the footer's height with nothing in it. A panel holding a day range\n * keeps the row while nothing is applied, so the first tap on its calendar\n * does not grow the panel by a row and move its top under the finger\n * (FUT-4144 UI review).\n */\n reserved?: boolean;\n}): React.JSX.Element {\n const copy = useDataViewsCopy();\n return (\n <Box\n aria-hidden={reserved || undefined}\n // Held, the row is blank — no rule over it either, or it reads as an\n // empty bordered row.\n sx={{ px: 1.5, py: 1, borderTop: 1, borderColor: reserved ? \"transparent\" : \"divider\", visibility: reserved ? \"hidden\" : undefined }}\n >\n <Box\n component=\"button\"\n type=\"button\"\n onClick={reserved ? undefined : onClearAll}\n tabIndex={reserved ? -1 : undefined}\n data-testid={reserved ? undefined : `${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/**\n * The panel is a column: heading, the fields' scroller, footer. Its height is\n * the screen's, not a fixed 320px — at 390×844 that cap scrolled a day range's\n * month caption and weekday row out of view after the first tap, and a typed\n * day's refusal out of sight of its box (FUT-4144 UI review). MUI moves the\n * panel up when it is taller than the room under its trigger.\n */\nconst COLUMN_SX = { display: \"flex\", flexDirection: \"column\" } as const;\n\n/**\n * 320, not 300: inside 12px of padding a day range's month then has the 280px\n * its seven 40px columns need and its month/year caption one row (FUT-4144).\n */\nconst PAPER_SX = (theme: Theme) => ({\n ...COLUMN_SX,\n width: rem(theme, 320),\n maxWidth: `calc(100vw - ${rem(theme, 32)})`,\n});\n\n/**\n * Below `sm` the panel takes the screen's width less 8px each side, so a day\n * range's calendar gets the 280px its seven 40px columns need (it had 264 at\n * 320 and 276 at 390, so every day was a 34-36px target).\n */\nconst PHONE_PAPER_SX = (theme: Theme) => ({\n ...COLUMN_SX,\n width: `calc(100vw - ${rem(theme, 16)})`,\n maxWidth: `calc(100vw - ${rem(theme, 16)})`,\n maxHeight: `calc(100% - ${rem(theme, 16)})`,\n});\n\n/** Props of {@link MoreFilters}. */\ninterface MoreFiltersPanelProps<T extends Record<string, unknown>> extends 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}\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}: MoreFiltersPanelProps<T>): React.JSX.Element | null {\n const still = useStillAnchor();\n const theme = useTheme();\n const phone = useMediaQuery(theme.breakpoints.down(\"sm\"));\n if (fields.length === 0) return null;\n const holdsDayRange = fields.some((field) => field.range?.kind === \"day\");\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 still.open(element);\n onOpenChange?.(true);\n }}\n testIdPrefix={rest.testIdPrefix}\n />\n <Popover\n {...still.popoverProps}\n onClose={() => {\n still.close();\n onOpenChange?.(false);\n }}\n // Below `sm`, 8px from the screen's edges instead of 16.\n marginThreshold={phone ? remPx(theme, 8) : undefined}\n slotProps={{ paper: { ref: still.paperRef, sx: phone ? PHONE_PAPER_SX : PAPER_SX } }}\n >\n <Box data-testid={`${rest.testIdPrefix}-more-panel`} sx={{ ...COLUMN_SX, flex: \"1 1 auto\", minHeight: 0 }}>\n <MoreHeading />\n {/* overflowX hidden, not auto: this panel is a fixed width 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={{ flex: \"1 1 auto\", minHeight: 0, overflowY: \"auto\", overflowX: \"hidden\", p: { xs: 1, sm: 1.5 }, minWidth: 0 }}>\n <MoreFields key={clearKey} fields={fields} {...rest} />\n </Box>\n {(anyApplied || holdsDayRange) && (\n <MoreFooter onClearAll={onClearAll} testIdPrefix={rest.testIdPrefix} reserved={!anyApplied} />\n )}\n </Box>\n </Popover>\n </>\n );\n}\n"],"mappings":"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","names":["default"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/data-display/DataViews/data-views-more-fields.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * ONE FIELD, RENDERED INSIDE THE \"MAIS\" PANEL.\n *\n * Split from `data-views-more-filters` at the file-size gate, along the seam\n * that was already there: that module is the trigger, the panel and its\n * footer — the chrome — and this is what goes in it.\n *\n * A field with one or two options renders FLAT: inside a panel there is no\n * space to win back, and two labelled checkboxes are faster than a dropdown\n * needing a second click. Past that — or whenever the field asks for a tree or\n * a search — it is the bar's own {@link PillControl}; see `sharesBarControl`.\n */\nimport Checkbox from \"@mui/material/Checkbox/index.js\";\n\nimport { Box } from \"../../../mui/Box\";\nimport { Text } from \"../../typography/Text\";\n\nimport { PillControl } from \"./data-views-category-pill\";\nimport type { OverflowField } from \"./data-views-overflow\";\nimport { RangeBounds } from \"./data-views-range-pill\";\nimport { isRangeSet } from \"./data-views-range-values\";\nimport type { QuickFilterConfig, RangeValue } from \"./data-views-types\";\nimport { QuickRow } from \"./data-views-quick-chip\";\nimport { isQuickActive } from \"./data-views-overflow-fields\";\nimport { useDataViewsCopy } from \"./data-views-copy-context\";\nimport { fieldRadiusPx } from \"../../../tokens/field-radius\";\nimport { fieldHeight } from \"../../../tokens/field-height\";\nimport { fieldEdge } from \"../../../tokens/field-edge\";\nimport { sxRem } from \"../../../tokens/relative\";\n\n/** What each field's control needs, minus the panel's own chrome. */\nexport interface MoreFieldProps {\n pills: Record<string, string[]>;\n ranges: Record<string, RangeValue>;\n onTogglePill: (fieldId: string, value: string, checked: boolean) => void;\n onChangeRange: (fieldId: string, range: RangeValue) => void;\n /** Presses or releases a quick chip shed into the panel. */\n onToggleQuick?: (quick: QuickFilterConfig) => void;\n testIdPrefix: string;\n}\n\n/**\n * Above this many options a field is a DROPDOWN rather than a flat row of\n * checkboxes. Two options cost two lines and read faster laid out; a \"Cliente\"\n * with a dozen turns the panel into a scrolling wall and buries every field\n * under it, which is exactly what the overflow was meant to avoid.\n */\nconst INLINE_OPTION_LIMIT = 2;\n\n/**\n * Whether an overflowed pill keeps the SAME control it has on the bar.\n *\n * The panel used to build its own flat dropdown for every field past two\n * options, so a field's config only held while it fitted: `control:\n * \"category\"` lost its tree (subcategories flattened into one list, no\n * \"Marcar tudo\", no count footer) and `searchEnabled` lost its search, on\n * exactly the phone widths where most filters live in here. Anything the bar\n * would render as a dropdown now renders as the bar's own {@link PillControl};\n * only a plain two-option field — one that did not ask for a dropdown, a tree\n * or a search — stays a flat checkbox row, which is a panel layout rather than\n * a different control (the filter panel draws the same line).\n */\nfunction sharesBarControl<T extends Record<string, unknown>>(field: OverflowField<T>): boolean {\n const pill = field.pill;\n if (!pill) return false;\n return (\n pill.control === \"category\" ||\n pill.control === \"multiselect\" ||\n pill.searchEnabled === true ||\n pill.options.length > INLINE_OPTION_LIMIT\n );\n}\n\n/** One overflowed pill: the bar's control, or its options as checkboxes. */\nfunction OverflowPill<T extends Record<string, unknown>>({\n field,\n values,\n onTogglePill,\n onClear,\n testIdPrefix,\n}: {\n field: OverflowField<T>;\n values: string[];\n onTogglePill: (fieldId: string, value: string, checked: boolean) => void;\n onClear: () => void;\n testIdPrefix: string;\n}): React.JSX.Element {\n const testId = `${testIdPrefix}-more-${field.id}`;\n if (field.pill && sharesBarControl(field)) {\n return (\n <PillControl\n fieldId={field.id}\n pill={field.pill}\n selected={values}\n onTogglePill={onTogglePill}\n onClearField={onClear}\n testIdPrefix={testIdPrefix}\n testId={testId}\n />\n );\n }\n const onToggle = (value: string, checked: boolean) => onTogglePill(field.id, value, checked);\n return (\n <Box sx={{ display: \"flex\", flexWrap: \"wrap\", gap: 0.75 }}>\n {(field.pill?.options ?? []).map((option) => {\n const checked = values.includes(option.value);\n return (\n <Box\n key={option.value}\n component=\"label\"\n data-testid={`${testId}-${option.value}`}\n sx={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 0.25,\n pr: 1,\n border: 1,\n borderStyle: \"solid\",\n minHeight: fieldHeight,\n borderColor: (theme) => (checked ? theme.palette.primary.main : fieldEdge(theme)),\n bgcolor: checked ? \"action.selected\" : \"transparent\",\n borderRadius: fieldRadiusPx,\n cursor: \"pointer\",\n fontSize: sxRem(13),\n color: checked ? \"primary.main\" : \"text.secondary\",\n }}\n >\n <Checkbox\n size=\"small\"\n checked={checked}\n onChange={(event) => onToggle(option.value, event.target.checked)}\n inputProps={{ \"aria-label\": `${field.label}: ${option.label}` }}\n />\n {option.label}\n </Box>\n );\n })}\n </Box>\n );\n}\n\n\n/**\n * One overflowed range: its presets and its two bounds, as the same controls\n * the pill uses.\n *\n * The whole control DELEGATES to {@link RangeBounds} rather than being built\n * here, which is the point — this panel used to render a raw\n * `<input type=\"date\">`, so the masked `dd/mm/aaaa` field existed only while\n * the filter FITTED on the bar. The moment \"Data\" overflowed it reverted to the\n * native control the mask replaced, and a merchant on a narrow screen never saw\n * the fix at all (FUT-744). `Valor` had the twin bug: a bare `type=\"number\"`\n * plus `Number(raw)` dropped the decimal comma this panel is meant to accept.\n *\n * That also retires the intrinsic-width workaround this pair used to need — a\n * native date input reports a wide minimum (its own mask plus the picker\n * glyph), which is what made two of them refuse to shrink and scrolled the\n * panel sideways. A text input has no such minimum.\n *\n * `RangeBounds` renders the preset chips ITSELF, above the inputs. This panel\n * must NOT render its own row as well: when the delegation above landed, the\n * chips it used to draw by hand stayed behind, and \"Data\" showed Hoje/Ontem/\n * Esta semana/Este mês/Este ano twice — two rows, duplicated test ids, and half\n * the panel's height spent saying the same thing (FUT-751).\n */\nfunction OverflowRange<T extends Record<string, unknown>>({\n field,\n value,\n onChange,\n testIdPrefix,\n}: {\n field: OverflowField<T>;\n value: RangeValue;\n onChange: (range: RangeValue) => void;\n testIdPrefix: string;\n}): React.JSX.Element | null {\n // `group === \"range\"` is what selects this component, so `range` is always\n // set; the guard is for the type, not for a state the caller can reach.\n if (!field.range) return null;\n return (\n <RangeBounds\n field={field.range}\n value={value}\n onChange={onChange}\n testId={`${testIdPrefix}-more-${field.id}`}\n fillRow\n />\n );\n}\n\n/**\n * Whether a field has anything applied, and how to unapply it — the two shapes\n * (a pill's selected values, a range's bounds) answered in one place so the\n * group that renders them stays a renderer.\n */\nexport function fieldClearing<T extends Record<string, unknown>>({\n field,\n pills,\n ranges,\n onTogglePill,\n onChangeRange,\n}: {\n field: OverflowField<T>;\n} & Pick<MoreFieldProps, \"pills\" | \"ranges\" | \"onTogglePill\" | \"onChangeRange\">): {\n applied: boolean;\n clear: () => void;\n} {\n if (field.group === \"quick\" && field.quick) {\n const quick = field.quick;\n // A `default` chip lit by an empty field has nothing to clear.\n const applied = isQuickActive(quick, pills) && (pills[quick.fieldId]?.length ?? 0) > 0;\n return { applied, clear: () => onTogglePill(quick.fieldId, quick.value, false) };\n }\n if (field.group === \"range\") {\n return {\n applied: isRangeSet(ranges[field.id] ?? {}),\n clear: () => onChangeRange(field.id, {}),\n };\n }\n const values = pills[field.id] ?? [];\n return {\n applied: values.length > 0,\n clear: () => values.forEach((value) => onTogglePill(field.id, value, false)),\n };\n}\n\n\n/**\n * A quick chip shed into the panel: its own line, because label and count are\n * already the whole control — no heading above it, no \"Limpar\" beside it.\n */\nexport function MoreQuick({\n quick,\n pills,\n onToggleQuick,\n testIdPrefix,\n}: {\n quick: QuickFilterConfig;\n} & Pick<MoreFieldProps, \"pills\" | \"onToggleQuick\" | \"testIdPrefix\">): React.JSX.Element {\n return (\n <Box sx={{ mb: 1, \"&:last-of-type\": { mb: 0 } }}>\n <QuickRow\n quick={quick}\n active={isQuickActive(quick, pills)}\n onToggle={() => onToggleQuick?.(quick)}\n testIdPrefix={testIdPrefix}\n />\n </Box>\n );\n}\n\n/** One labelled group in the panel: the field's name, then its control. */\nexport function MoreGroup<T extends Record<string, unknown>>({\n field,\n pills,\n ranges,\n onTogglePill,\n onChangeRange,\n testIdPrefix,\n}: {\n field: OverflowField<T>;\n} & MoreFieldProps): React.JSX.Element {\n const copy = useDataViewsCopy();\n const { applied, clear } = fieldClearing({ field, pills, ranges, onTogglePill, onChangeRange });\n return (\n <Box sx={{ mb: 1.5, \"&:last-of-type\": { mb: 0 } }}>\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1, mb: 0.5 }}>\n <Text variant=\"caption\" as=\"span\">\n <Box component=\"span\" sx={{ color: \"text.secondary\" }}>\n {field.label}\n {field.group === \"range\" && isRangeSet(ranges[field.id] ?? {}) ? \" •\" : \"\"}\n </Box>\n </Text>\n {/* The panel's equivalent of the pill's ✕. Without it a field applied\n in here could only be cleared by finding it again on the bar —\n which is where it goes the moment it becomes active, so the\n operator has to close this panel to undo what they just did. */}\n {applied && (\n <Box\n component=\"button\"\n type=\"button\"\n onClick={clear}\n data-testid={`${testIdPrefix}-more-${field.id}-clear`}\n sx={{\n ml: \"auto\",\n border: 0,\n p: 0,\n bgcolor: \"transparent\",\n cursor: \"pointer\",\n font: \"inherit\",\n fontSize: sxRem(12),\n color: \"primary.main\",\n \"&:hover\": { textDecoration: \"underline\" },\n }}\n >\n {copy.filters.clear}\n </Box>\n )}\n </Box>\n {field.group === \"pill\" ? (\n <OverflowPill\n field={field}\n values={pills[field.id] ?? []}\n onTogglePill={onTogglePill}\n onClear={() => (pills[field.id] ?? []).forEach((v) => onTogglePill(field.id, v, false))}\n testIdPrefix={testIdPrefix}\n />\n ) : (\n <OverflowRange\n field={field}\n value={ranges[field.id] ?? {}}\n onChange={(range) => onChangeRange(field.id, range)}\n testIdPrefix={testIdPrefix}\n />\n )}\n </Box>\n );\n}\n\n"],"mappings":"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","names":["default"]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|