@12-apps/ui 6.70.0 → 6.72.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.
Files changed (47) hide show
  1. package/dist/_internal/components/data-display/CardKit/card-actions-context.js +1 -1
  2. package/dist/_internal/components/data-display/CardKit/use-remove-confirm.js +2 -2
  3. package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +7 -7
  4. package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +8 -8
  5. package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +6 -6
  6. package/dist/_internal/components/data-display/DataViews/data-views-inline-bar.js +5 -5
  7. package/dist/_internal/components/data-display/DataViews/data-views-more-fields.js +2 -2
  8. package/dist/_internal/components/data-display/DataViews/data-views-more-filters.js +3 -3
  9. package/dist/_internal/components/data-display/DataViews/data-views-overflow-fields.js +1 -1
  10. package/dist/_internal/components/data-display/DataViews/data-views-overflow.js +2 -2
  11. package/dist/{chunk-EYW6KXUC.js → chunk-2B3NX5HJ.js} +3 -3
  12. package/dist/{chunk-EYW6KXUC.js.map → chunk-2B3NX5HJ.js.map} +1 -1
  13. package/dist/{chunk-SAXALTRL.js → chunk-6OLERKNC.js} +2 -2
  14. package/dist/{chunk-62BY4ZUQ.js → chunk-7KAZ3B5B.js} +2 -2
  15. package/dist/{chunk-62YHJAWM.js → chunk-7SPFK73H.js} +2 -2
  16. package/dist/{chunk-LY6L3DMB.js → chunk-DAT4XWYX.js} +4 -4
  17. package/dist/{chunk-AMT7IJYV.js → chunk-KYUEO2IO.js} +3 -1
  18. package/dist/chunk-KYUEO2IO.js.map +1 -0
  19. package/dist/{chunk-N7KWWIF7.js → chunk-LY7PBZ3Z.js} +7 -3
  20. package/dist/chunk-LY7PBZ3Z.js.map +1 -0
  21. package/dist/{chunk-JCHJYBDG.js → chunk-QVEQOUQY.js} +2 -2
  22. package/dist/{chunk-SOQIWXFO.js → chunk-WWH674WU.js} +2 -2
  23. package/dist/{chunk-TLPFSA55.js → chunk-ZEH6MGP5.js} +3 -3
  24. package/dist/data-display/CardKit.js +2 -2
  25. package/dist/data-display/DataViews.js +8 -8
  26. package/dist/types/components/data-display/CardKit/card-actions-context.d.ts +10 -1
  27. package/dist/types/components/data-display/CardKit/card-actions-context.d.ts.map +1 -1
  28. package/dist/types/components/data-display/DataViews/data-views-more-fields.d.ts.map +1 -1
  29. package/dist/types/components/data-display/DataViews/data-views-overflow-fields.d.ts.map +1 -1
  30. package/dist/types/components/data-display/DataViews/data-views-quick-types.d.ts +14 -0
  31. package/dist/types/components/data-display/DataViews/data-views-quick-types.d.ts.map +1 -1
  32. package/package.json +1 -1
  33. package/src/components/data-display/CardKit/CardKit.md +3 -0
  34. package/src/components/data-display/CardKit/card-actions-context.tsx +16 -1
  35. package/src/components/data-display/DataViews/RESPONSIVE-BEHAVIOUR.md +8 -0
  36. package/src/components/data-display/DataViews/data-views-more-fields.tsx +2 -1
  37. package/src/components/data-display/DataViews/data-views-overflow-fields.ts +4 -0
  38. package/src/components/data-display/DataViews/data-views-quick-types.ts +14 -0
  39. package/dist/chunk-AMT7IJYV.js.map +0 -1
  40. package/dist/chunk-N7KWWIF7.js.map +0 -1
  41. /package/dist/{chunk-SAXALTRL.js.map → chunk-6OLERKNC.js.map} +0 -0
  42. /package/dist/{chunk-62BY4ZUQ.js.map → chunk-7KAZ3B5B.js.map} +0 -0
  43. /package/dist/{chunk-62YHJAWM.js.map → chunk-7SPFK73H.js.map} +0 -0
  44. /package/dist/{chunk-LY6L3DMB.js.map → chunk-DAT4XWYX.js.map} +0 -0
  45. /package/dist/{chunk-JCHJYBDG.js.map → chunk-QVEQOUQY.js.map} +0 -0
  46. /package/dist/{chunk-SOQIWXFO.js.map → chunk-WWH674WU.js.map} +0 -0
  47. /package/dist/{chunk-TLPFSA55.js.map → chunk-ZEH6MGP5.js.map} +0 -0
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  CardActionsProvider,
4
4
  useCardActions
5
- } from "../../../../chunk-N7KWWIF7.js";
5
+ } from "../../../../chunk-LY7PBZ3Z.js";
6
6
  import "../../../../chunk-NUGT7LMR.js";
7
7
  import "../../../../chunk-DQJFCVXW.js";
8
8
  import "../../../../chunk-JYAXTRNH.js";
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import {
3
3
  useRemoveConfirm
4
- } from "../../../../chunk-62BY4ZUQ.js";
5
- import "../../../../chunk-N7KWWIF7.js";
4
+ } from "../../../../chunk-7KAZ3B5B.js";
5
+ import "../../../../chunk-LY7PBZ3Z.js";
6
6
  import "../../../../chunk-XCBQXSTR.js";
7
7
  import "../../../../chunk-NJMAFII4.js";
8
8
  import "../../../../chunk-GICG3XJK.js";
@@ -1,10 +1,10 @@
1
1
  "use client";
2
2
  import {
3
3
  DataViewsGrid
4
- } from "../../../../chunk-JCHJYBDG.js";
5
- import "../../../../chunk-LY6L3DMB.js";
4
+ } from "../../../../chunk-QVEQOUQY.js";
5
+ import "../../../../chunk-DAT4XWYX.js";
6
6
  import "../../../../chunk-Y2CCXB7R.js";
7
- import "../../../../chunk-TLPFSA55.js";
7
+ import "../../../../chunk-ZEH6MGP5.js";
8
8
  import "../../../../chunk-QLJU7UUI.js";
9
9
  import "../../../../chunk-X3AFXHY5.js";
10
10
  import "../../../../chunk-WQ32YFM5.js";
@@ -12,11 +12,11 @@ import "../../../../chunk-7TCOYCD7.js";
12
12
  import "../../../../chunk-SZSS5KKX.js";
13
13
  import "../../../../chunk-E5GYHN4X.js";
14
14
  import "../../../../chunk-XZFTRGRW.js";
15
- import "../../../../chunk-SOQIWXFO.js";
16
- import "../../../../chunk-SAXALTRL.js";
17
- import "../../../../chunk-EYW6KXUC.js";
15
+ import "../../../../chunk-WWH674WU.js";
16
+ import "../../../../chunk-6OLERKNC.js";
17
+ import "../../../../chunk-2B3NX5HJ.js";
18
18
  import "../../../../chunk-RQF4NXDC.js";
19
- import "../../../../chunk-AMT7IJYV.js";
19
+ import "../../../../chunk-KYUEO2IO.js";
20
20
  import "../../../../chunk-GZOW6HNN.js";
21
21
  import "../../../../chunk-5WJFCQFN.js";
22
22
  import "../../../../chunk-FJ3UZ4RC.js";
@@ -1,13 +1,13 @@
1
1
  "use client";
2
2
  import {
3
3
  DataViewsTableBase
4
- } from "../../../../chunk-62YHJAWM.js";
4
+ } from "../../../../chunk-7SPFK73H.js";
5
5
  import "../../../../chunk-ZEVFMQAQ.js";
6
- import "../../../../chunk-JCHJYBDG.js";
6
+ import "../../../../chunk-QVEQOUQY.js";
7
7
  import "../../../../chunk-ZOLAYP2D.js";
8
- import "../../../../chunk-LY6L3DMB.js";
8
+ import "../../../../chunk-DAT4XWYX.js";
9
9
  import "../../../../chunk-Y2CCXB7R.js";
10
- import "../../../../chunk-TLPFSA55.js";
10
+ import "../../../../chunk-ZEH6MGP5.js";
11
11
  import "../../../../chunk-QLJU7UUI.js";
12
12
  import "../../../../chunk-X3AFXHY5.js";
13
13
  import "../../../../chunk-WQ32YFM5.js";
@@ -15,11 +15,11 @@ import "../../../../chunk-7TCOYCD7.js";
15
15
  import "../../../../chunk-SZSS5KKX.js";
16
16
  import "../../../../chunk-E5GYHN4X.js";
17
17
  import "../../../../chunk-XZFTRGRW.js";
18
- import "../../../../chunk-SOQIWXFO.js";
19
- import "../../../../chunk-SAXALTRL.js";
20
- import "../../../../chunk-EYW6KXUC.js";
18
+ import "../../../../chunk-WWH674WU.js";
19
+ import "../../../../chunk-6OLERKNC.js";
20
+ import "../../../../chunk-2B3NX5HJ.js";
21
21
  import "../../../../chunk-RQF4NXDC.js";
22
- import "../../../../chunk-AMT7IJYV.js";
22
+ import "../../../../chunk-KYUEO2IO.js";
23
23
  import "../../../../chunk-GZOW6HNN.js";
24
24
  import "../../../../chunk-5WJFCQFN.js";
25
25
  import "../../../../chunk-FJ3UZ4RC.js";
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  import {
3
3
  GridShell
4
- } from "../../../../chunk-LY6L3DMB.js";
4
+ } from "../../../../chunk-DAT4XWYX.js";
5
5
  import "../../../../chunk-Y2CCXB7R.js";
6
- import "../../../../chunk-TLPFSA55.js";
6
+ import "../../../../chunk-ZEH6MGP5.js";
7
7
  import "../../../../chunk-QLJU7UUI.js";
8
8
  import "../../../../chunk-X3AFXHY5.js";
9
9
  import "../../../../chunk-WQ32YFM5.js";
@@ -11,11 +11,11 @@ import "../../../../chunk-7TCOYCD7.js";
11
11
  import "../../../../chunk-SZSS5KKX.js";
12
12
  import "../../../../chunk-E5GYHN4X.js";
13
13
  import "../../../../chunk-XZFTRGRW.js";
14
- import "../../../../chunk-SOQIWXFO.js";
15
- import "../../../../chunk-SAXALTRL.js";
16
- import "../../../../chunk-EYW6KXUC.js";
14
+ import "../../../../chunk-WWH674WU.js";
15
+ import "../../../../chunk-6OLERKNC.js";
16
+ import "../../../../chunk-2B3NX5HJ.js";
17
17
  import "../../../../chunk-RQF4NXDC.js";
18
- import "../../../../chunk-AMT7IJYV.js";
18
+ import "../../../../chunk-KYUEO2IO.js";
19
19
  import "../../../../chunk-GZOW6HNN.js";
20
20
  import "../../../../chunk-5WJFCQFN.js";
21
21
  import "../../../../chunk-FJ3UZ4RC.js";
@@ -1,13 +1,13 @@
1
1
  "use client";
2
2
  import {
3
3
  InlineFilterControls
4
- } from "../../../../chunk-TLPFSA55.js";
4
+ } from "../../../../chunk-ZEH6MGP5.js";
5
5
  import "../../../../chunk-QLJU7UUI.js";
6
- import "../../../../chunk-SOQIWXFO.js";
7
- import "../../../../chunk-SAXALTRL.js";
8
- import "../../../../chunk-EYW6KXUC.js";
6
+ import "../../../../chunk-WWH674WU.js";
7
+ import "../../../../chunk-6OLERKNC.js";
8
+ import "../../../../chunk-2B3NX5HJ.js";
9
9
  import "../../../../chunk-RQF4NXDC.js";
10
- import "../../../../chunk-AMT7IJYV.js";
10
+ import "../../../../chunk-KYUEO2IO.js";
11
11
  import "../../../../chunk-GZOW6HNN.js";
12
12
  import "../../../../chunk-5WJFCQFN.js";
13
13
  import "../../../../chunk-FJ3UZ4RC.js";
@@ -3,9 +3,9 @@ import {
3
3
  MoreGroup,
4
4
  MoreQuick,
5
5
  fieldClearing
6
- } from "../../../../chunk-EYW6KXUC.js";
6
+ } from "../../../../chunk-2B3NX5HJ.js";
7
7
  import "../../../../chunk-RQF4NXDC.js";
8
- import "../../../../chunk-AMT7IJYV.js";
8
+ import "../../../../chunk-KYUEO2IO.js";
9
9
  import "../../../../chunk-GZOW6HNN.js";
10
10
  import "../../../../chunk-5WJFCQFN.js";
11
11
  import "../../../../chunk-FJ3UZ4RC.js";
@@ -1,10 +1,10 @@
1
1
  "use client";
2
2
  import {
3
3
  MoreFilters
4
- } from "../../../../chunk-SAXALTRL.js";
5
- import "../../../../chunk-EYW6KXUC.js";
4
+ } from "../../../../chunk-6OLERKNC.js";
5
+ import "../../../../chunk-2B3NX5HJ.js";
6
6
  import "../../../../chunk-RQF4NXDC.js";
7
- import "../../../../chunk-AMT7IJYV.js";
7
+ import "../../../../chunk-KYUEO2IO.js";
8
8
  import "../../../../chunk-GZOW6HNN.js";
9
9
  import "../../../../chunk-5WJFCQFN.js";
10
10
  import "../../../../chunk-FJ3UZ4RC.js";
@@ -4,7 +4,7 @@ import {
4
4
  keepChipsInOrder,
5
5
  toOverflowFields,
6
6
  toggleQuick
7
- } from "../../../../chunk-AMT7IJYV.js";
7
+ } from "../../../../chunk-KYUEO2IO.js";
8
8
  import "../../../../chunk-GZOW6HNN.js";
9
9
  import "../../../../chunk-YKCAJ2TN.js";
10
10
  import "../../../../chunk-PZ5AY32C.js";
@@ -1,11 +1,11 @@
1
1
  "use client";
2
2
  import {
3
3
  useFilterOverflow
4
- } from "../../../../chunk-SOQIWXFO.js";
4
+ } from "../../../../chunk-WWH674WU.js";
5
5
  import {
6
6
  isQuickActive,
7
7
  toOverflowFields
8
- } from "../../../../chunk-AMT7IJYV.js";
8
+ } from "../../../../chunk-KYUEO2IO.js";
9
9
  import "../../../../chunk-GZOW6HNN.js";
10
10
  import "../../../../chunk-NCS2TBIP.js";
11
11
  import "../../../../chunk-Y4KKS6WL.js";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-RQF4NXDC.js";
4
4
  import {
5
5
  isQuickActive
6
- } from "./chunk-AMT7IJYV.js";
6
+ } from "./chunk-KYUEO2IO.js";
7
7
  import {
8
8
  RangeBounds
9
9
  } from "./chunk-5WJFCQFN.js";
@@ -132,7 +132,7 @@ function fieldClearing({
132
132
  }) {
133
133
  if (field.group === "quick" && field.quick) {
134
134
  const quick = field.quick;
135
- const applied = isQuickActive(quick, pills);
135
+ const applied = isQuickActive(quick, pills) && (pills[quick.fieldId]?.length ?? 0) > 0;
136
136
  return { applied, clear: () => onTogglePill(quick.fieldId, quick.value, false) };
137
137
  }
138
138
  if (field.group === "range") {
@@ -227,4 +227,4 @@ export {
227
227
  MoreQuick,
228
228
  MoreGroup
229
229
  };
230
- //# sourceMappingURL=chunk-EYW6KXUC.js.map
230
+ //# sourceMappingURL=chunk-2B3NX5HJ.js.map
@@ -1 +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\";\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 />\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 const applied = isQuickActive(quick, pills);\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"]}
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 />\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,OAAO,cAAc;AA8Ef,cAiBI,YAjBJ;AA3CN,IAAM,sBAAsB;AAe5B,SAAS,iBAAoD,OAAkC;AAC7F,QAAM,OAAO,MAAM;AACnB,MAAI,CAAC,KAAM,QAAO;AAClB,SACE,KAAK,YAAY,cACjB,KAAK,YAAY,iBACjB,KAAK,kBAAkB,QACvB,KAAK,QAAQ,SAAS;AAE1B;AAGA,SAAS,aAAgD;AAAA,EACvD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMsB;AACpB,QAAM,SAAS,GAAG,YAAY,SAAS,MAAM,EAAE;AAC/C,MAAI,MAAM,QAAQ,iBAAiB,KAAK,GAAG;AACzC,WACE;AAAA,MAAC;AAAA;AAAA,QACC,SAAS,MAAM;AAAA,QACf,MAAM,MAAM;AAAA,QACZ,UAAU;AAAA,QACV;AAAA,QACA,cAAc;AAAA,QACd;AAAA,QACA;AAAA;AAAA,IACF;AAAA,EAEJ;AACA,QAAM,WAAW,CAAC,OAAe,YAAqB,aAAa,MAAM,IAAI,OAAO,OAAO;AAC3F,SACE,oBAACA,UAAA,EAAI,IAAI,EAAE,SAAS,QAAQ,UAAU,QAAQ,KAAK,KAAK,GACpD,iBAAM,MAAM,WAAW,CAAC,GAAG,IAAI,CAAC,WAAW;AAC3C,UAAM,UAAU,OAAO,SAAS,OAAO,KAAK;AAC5C,WACE;AAAA,MAACA;AAAA,MAAA;AAAA,QAEC,WAAU;AAAA,QACV,eAAa,GAAG,MAAM,IAAI,OAAO,KAAK;AAAA,QACtC,IAAI;AAAA,UACF,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,KAAK;AAAA,UACL,IAAI;AAAA,UACJ,QAAQ;AAAA,UACR,aAAa;AAAA,UACb,WAAW;AAAA,UACX,aAAa,CAAC,UAAW,UAAU,MAAM,QAAQ,QAAQ,OAAO,UAAU,KAAK;AAAA,UAC/E,SAAS,UAAU,oBAAoB;AAAA,UACvC,cAAc;AAAA,UACd,QAAQ;AAAA,UACR,UAAU,MAAM,EAAE;AAAA,UAClB,OAAO,UAAU,iBAAiB;AAAA,QACpC;AAAA,QAEA;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL;AAAA,cACA,UAAU,CAAC,UAAU,SAAS,OAAO,OAAO,MAAM,OAAO,OAAO;AAAA,cAChE,YAAY,EAAE,cAAc,GAAG,MAAM,KAAK,KAAK,OAAO,KAAK,GAAG;AAAA;AAAA,UAChE;AAAA,UACC,OAAO;AAAA;AAAA;AAAA,MAzBH,OAAO;AAAA,IA0Bd;AAAA,EAEJ,CAAC,GACH;AAEJ;AA0BA,SAAS,cAAiD;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAK6B;AAG3B,MAAI,CAAC,MAAM,MAAO,QAAO;AACzB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,MAAM;AAAA,MACb;AAAA,MACA;AAAA,MACA,QAAQ,GAAG,YAAY,SAAS,MAAM,EAAE;AAAA;AAAA,EAC1C;AAEJ;AAOO,SAAS,cAAiD;AAAA,EAC/D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKE;AACA,MAAI,MAAM,UAAU,WAAW,MAAM,OAAO;AAC1C,UAAM,QAAQ,MAAM;AAEpB,UAAM,UAAU,cAAc,OAAO,KAAK,MAAM,MAAM,MAAM,OAAO,GAAG,UAAU,KAAK;AACrF,WAAO,EAAE,SAAS,OAAO,MAAM,aAAa,MAAM,SAAS,MAAM,OAAO,KAAK,EAAE;AAAA,EACjF;AACA,MAAI,MAAM,UAAU,SAAS;AAC3B,WAAO;AAAA,MACL,SAAS,WAAW,OAAO,MAAM,EAAE,KAAK,CAAC,CAAC;AAAA,MAC1C,OAAO,MAAM,cAAc,MAAM,IAAI,CAAC,CAAC;AAAA,IACzC;AAAA,EACF;AACA,QAAM,SAAS,MAAM,MAAM,EAAE,KAAK,CAAC;AACnC,SAAO;AAAA,IACL,SAAS,OAAO,SAAS;AAAA,IACzB,OAAO,MAAM,OAAO,QAAQ,CAAC,UAAU,aAAa,MAAM,IAAI,OAAO,KAAK,CAAC;AAAA,EAC7E;AACF;AAOO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAEyF;AACvF,SACE,oBAACA,UAAA,EAAI,IAAI,EAAE,IAAI,GAAG,kBAAkB,EAAE,IAAI,EAAE,EAAE,GAC5C;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,QAAQ,cAAc,OAAO,KAAK;AAAA,MAClC,UAAU,MAAM,gBAAgB,KAAK;AAAA,MACrC;AAAA;AAAA,EACF,GACF;AAEJ;AAGO,SAAS,UAA6C;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAEuC;AACrC,QAAM,OAAO,iBAAiB;AAC9B,QAAM,EAAE,SAAS,MAAM,IAAI,cAAc,EAAE,OAAO,OAAO,QAAQ,cAAc,cAAc,CAAC;AAC9F,SACE,qBAACA,UAAA,EAAI,IAAI,EAAE,IAAI,KAAK,kBAAkB,EAAE,IAAI,EAAE,EAAE,GAC9C;AAAA,yBAACA,UAAA,EAAI,IAAI,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,GAAG,IAAI,IAAI,GAChE;AAAA,0BAAC,QAAK,SAAQ,WAAU,IAAG,QACzB,+BAACA,UAAA,EAAI,WAAU,QAAO,IAAI,EAAE,OAAO,iBAAiB,GACjD;AAAA,cAAM;AAAA,QACN,MAAM,UAAU,WAAW,WAAW,OAAO,MAAM,EAAE,KAAK,CAAC,CAAC,IAAI,YAAO;AAAA,SAC1E,GACF;AAAA,MAKC,WACC;AAAA,QAACA;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,MAAK;AAAA,UACL,SAAS;AAAA,UACT,eAAa,GAAG,YAAY,SAAS,MAAM,EAAE;AAAA,UAC7C,IAAI;AAAA,YACF,IAAI;AAAA,YACJ,QAAQ;AAAA,YACR,GAAG;AAAA,YACH,SAAS;AAAA,YACT,QAAQ;AAAA,YACR,MAAM;AAAA,YACN,UAAU,MAAM,EAAE;AAAA,YAClB,OAAO;AAAA,YACP,WAAW,EAAE,gBAAgB,YAAY;AAAA,UAC3C;AAAA,UAEC,eAAK,QAAQ;AAAA;AAAA,MAChB;AAAA,OAEJ;AAAA,IACC,MAAM,UAAU,SACf;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAQ,MAAM,MAAM,EAAE,KAAK,CAAC;AAAA,QAC5B;AAAA,QACA,SAAS,OAAO,MAAM,MAAM,EAAE,KAAK,CAAC,GAAG,QAAQ,CAAC,MAAM,aAAa,MAAM,IAAI,GAAG,KAAK,CAAC;AAAA,QACtF;AAAA;AAAA,IACF,IAEA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,OAAO,OAAO,MAAM,EAAE,KAAK,CAAC;AAAA,QAC5B,UAAU,CAAC,UAAU,cAAc,MAAM,IAAI,KAAK;AAAA,QAClD;AAAA;AAAA,IACF;AAAA,KAEJ;AAEJ;","names":["default"]}
@@ -2,7 +2,7 @@ import {
2
2
  MoreGroup,
3
3
  MoreQuick,
4
4
  fieldClearing
5
- } from "./chunk-EYW6KXUC.js";
5
+ } from "./chunk-2B3NX5HJ.js";
6
6
  import {
7
7
  useDataViewsCopy
8
8
  } from "./chunk-KHG57NAE.js";
@@ -193,4 +193,4 @@ function MoreFilters({
193
193
  export {
194
194
  MoreFilters
195
195
  };
196
- //# sourceMappingURL=chunk-SAXALTRL.js.map
196
+ //# sourceMappingURL=chunk-6OLERKNC.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  useCardActions
3
- } from "./chunk-N7KWWIF7.js";
3
+ } from "./chunk-LY7PBZ3Z.js";
4
4
  import {
5
5
  useConfirmAction
6
6
  } from "./chunk-EMYESBIT.js";
@@ -50,4 +50,4 @@ function useRemoveConfirm({
50
50
  export {
51
51
  useRemoveConfirm
52
52
  };
53
- //# sourceMappingURL=chunk-62BY4ZUQ.js.map
53
+ //# sourceMappingURL=chunk-7KAZ3B5B.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-ZEVFMQAQ.js";
4
4
  import {
5
5
  DataViewsGrid
6
- } from "./chunk-JCHJYBDG.js";
6
+ } from "./chunk-QVEQOUQY.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-62YHJAWM.js.map
169
+ //# sourceMappingURL=chunk-7SPFK73H.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-Y2CCXB7R.js";
4
4
  import {
5
5
  InlineFilterControls
6
- } from "./chunk-TLPFSA55.js";
6
+ } from "./chunk-ZEH6MGP5.js";
7
7
  import {
8
8
  GridHeaderRow
9
9
  } from "./chunk-X3AFXHY5.js";
@@ -19,11 +19,11 @@ import {
19
19
  } from "./chunk-XZFTRGRW.js";
20
20
  import {
21
21
  useFilterOverflow
22
- } from "./chunk-SOQIWXFO.js";
22
+ } from "./chunk-WWH674WU.js";
23
23
  import {
24
24
  toOverflowFields,
25
25
  toggleQuick
26
- } from "./chunk-AMT7IJYV.js";
26
+ } from "./chunk-KYUEO2IO.js";
27
27
  import {
28
28
  allOnPageSelected,
29
29
  resolveSelectionExtra
@@ -251,4 +251,4 @@ function GridShell(props) {
251
251
  export {
252
252
  GridShell
253
253
  };
254
- //# sourceMappingURL=chunk-LY6L3DMB.js.map
254
+ //# sourceMappingURL=chunk-DAT4XWYX.js.map
@@ -24,6 +24,7 @@ function toOverflowFields(fields, rangeFields, quickFilters = []) {
24
24
  }
25
25
  function isQuickActive(quick, pills) {
26
26
  const selected = pills[quick.fieldId] ?? [];
27
+ if (quick.default === true && selected.length === 0) return true;
27
28
  return selected.length === 1 && selected[0] === quick.value;
28
29
  }
29
30
  function anyApplied(all, pills, ranges) {
@@ -45,6 +46,7 @@ function keepChipsInOrder(split, chips, cost) {
45
46
  };
46
47
  }
47
48
  function toggleQuick(pills, quick) {
49
+ if (quick.default === true) return { ...pills, [quick.fieldId]: [] };
48
50
  const pressed = isQuickActive(quick, pills);
49
51
  return { ...pills, [quick.fieldId]: pressed ? [] : [quick.value] };
50
52
  }
@@ -56,4 +58,4 @@ export {
56
58
  keepChipsInOrder,
57
59
  toggleQuick
58
60
  };
59
- //# sourceMappingURL=chunk-AMT7IJYV.js.map
61
+ //# sourceMappingURL=chunk-KYUEO2IO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/data-display/DataViews/data-views-overflow-fields.ts"],"sourcesContent":["/**\n * WHICH CONTROLS THE BAR DECLARES — split from `data-views-overflow` at the\n * file-size gate. That module decides where each control goes; this one only\n * lists them, in the order the bar renders them.\n */\nimport type { OverflowField } from \"./data-views-overflow\";\nimport { isRangeSet } from \"./data-views-overflow-costs\";\nimport type { FilterFieldConfig, QuickFilterConfig, RangeFieldConfig, RangeValue } from \"./data-views-types\";\n\n/**\n * Every declared control in the order the bar renders them: quick chips first,\n * then pills, then ranges.\n *\n * A pill field a quick chip writes to is NOT a control of its own — the chips\n * stand in for it (see `QuickFilterConfig`) — so it is left out here, and only\n * here: it stays in `fields`, where the active count and saved views read it.\n */\nexport function toOverflowFields<T extends Record<string, unknown>>(\n fields: FilterFieldConfig<T>[],\n rangeFields: RangeFieldConfig<T>[],\n quickFilters: QuickFilterConfig[] = [],\n): OverflowField<T>[] {\n const chipFields = new Set(quickFilters.map((quick) => quick.fieldId));\n return [\n ...quickFilters.map((quick) => ({\n id: `quick:${quick.id}`,\n label: quick.label,\n group: \"quick\" as const,\n quick,\n })),\n ...fields\n .filter((pill) => !chipFields.has(pill.id))\n .map((pill) => ({ id: pill.id, label: pill.label, group: \"pill\" as const, pill, pinned: pill.inMore === true })),\n ...rangeFields.map((range) => ({\n id: range.id,\n label: range.label,\n group: \"range\" as const,\n range,\n pinned: range.inMore === true,\n })),\n ];\n}\n\n/**\n * Is this quick chip pressed — its one value the field's WHOLE selection?\n *\n * Exactly, not \"includes\": a field holding two values (from a saved view, the\n * URL or the side panel) is not what either chip applies, and reading both as\n * pressed made pressing one clear the other.\n */\nexport function isQuickActive(quick: QuickFilterConfig, pills: Record<string, string[]>): boolean {\n const selected = pills[quick.fieldId] ?? [];\n // A `default` chip is the empty field (see `QuickFilterConfig.default`).\n if (quick.default === true && selected.length === 0) return true;\n return selected.length === 1 && selected[0] === quick.value;\n}\n\n/**\n * Is any DECLARED filter applied — a pill value or a bounded range, wherever it\n * is drawn (on the bar, in \"Mais\", or as a chip)? Only declared ids count: the\n * bar draws \"Limpar\" on the active count, which ignores a stale key a saved view\n * still carries for a field since removed.\n */\nexport function anyApplied<T extends Record<string, unknown>>(\n all: OverflowField<T>[],\n pills: Record<string, string[]>,\n ranges: Record<string, RangeValue>,\n): boolean {\n return all.some((field) => {\n if (field.group === \"range\") return isRangeSet(ranges[field.id]);\n const id = field.quick?.fieldId ?? field.id;\n return (pills[id]?.length ?? 0) > 0;\n });\n}\n\n/**\n * Quick chips stay a PREFIX of their declared order on the bar.\n *\n * The keep-what-fits loop skips a control that does not fit and tries the next,\n * which for pills is right (any narrower one is worth the room) and for chips\n * is not: \"Zerado\" alone on the bar, with \"Estoque baixo\" in \"Mais\", reads as a\n * different bar from the one declared. So the first chip that went to \"Mais\"\n * takes every later chip with it. Their room is NOT re-spent here — `used`\n * drops, and the ladder's later passes can hand it to the furniture.\n */\nexport function keepChipsInOrder<T extends Record<string, unknown>>(\n split: { inline: OverflowField<T>[]; overflow: OverflowField<T>[]; used: number },\n chips: OverflowField<T>[],\n cost: (field: OverflowField<T>) => number,\n): { inline: OverflowField<T>[]; overflow: OverflowField<T>[]; used: number } {\n const firstOut = chips.findIndex((chip) => split.overflow.includes(chip));\n if (firstOut < 0) return split;\n const evicted = chips.slice(firstOut).filter((chip) => split.inline.includes(chip));\n if (evicted.length === 0) return split;\n return {\n inline: split.inline.filter((field) => !evicted.includes(field)),\n overflow: [...chips.slice(firstOut), ...split.overflow.filter((field) => !chips.includes(field))],\n used: split.used - evicted.reduce((sum, chip) => sum + cost(chip), 0),\n };\n}\n\n\n\n/**\n * A quick chip's press, as a pill write. Exclusive within the field: the chip's\n * value REPLACES the selection, and pressing the pressed chip empties it.\n */\nexport function toggleQuick(pills: Record<string, string[]>, quick: QuickFilterConfig): Record<string, string[]> {\n // A `default` chip only ever empties its field: pressing it again stays put.\n if (quick.default === true) return { ...pills, [quick.fieldId]: [] };\n const pressed = isQuickActive(quick, pills);\n return { ...pills, [quick.fieldId]: pressed ? [] : [quick.value] };\n}\n\n"],"mappings":";;;;;AAiBO,SAAS,iBACd,QACA,aACA,eAAoC,CAAC,GACjB;AACpB,QAAM,aAAa,IAAI,IAAI,aAAa,IAAI,CAAC,UAAU,MAAM,OAAO,CAAC;AACrE,SAAO;AAAA,IACL,GAAG,aAAa,IAAI,CAAC,WAAW;AAAA,MAC9B,IAAI,SAAS,MAAM,EAAE;AAAA,MACrB,OAAO,MAAM;AAAA,MACb,OAAO;AAAA,MACP;AAAA,IACF,EAAE;AAAA,IACF,GAAG,OACA,OAAO,CAAC,SAAS,CAAC,WAAW,IAAI,KAAK,EAAE,CAAC,EACzC,IAAI,CAAC,UAAU,EAAE,IAAI,KAAK,IAAI,OAAO,KAAK,OAAO,OAAO,QAAiB,MAAM,QAAQ,KAAK,WAAW,KAAK,EAAE;AAAA,IACjH,GAAG,YAAY,IAAI,CAAC,WAAW;AAAA,MAC7B,IAAI,MAAM;AAAA,MACV,OAAO,MAAM;AAAA,MACb,OAAO;AAAA,MACP;AAAA,MACA,QAAQ,MAAM,WAAW;AAAA,IAC3B,EAAE;AAAA,EACJ;AACF;AASO,SAAS,cAAc,OAA0B,OAA0C;AAChG,QAAM,WAAW,MAAM,MAAM,OAAO,KAAK,CAAC;AAE1C,MAAI,MAAM,YAAY,QAAQ,SAAS,WAAW,EAAG,QAAO;AAC5D,SAAO,SAAS,WAAW,KAAK,SAAS,CAAC,MAAM,MAAM;AACxD;AAQO,SAAS,WACd,KACA,OACA,QACS;AACT,SAAO,IAAI,KAAK,CAAC,UAAU;AACzB,QAAI,MAAM,UAAU,QAAS,QAAO,WAAW,OAAO,MAAM,EAAE,CAAC;AAC/D,UAAM,KAAK,MAAM,OAAO,WAAW,MAAM;AACzC,YAAQ,MAAM,EAAE,GAAG,UAAU,KAAK;AAAA,EACpC,CAAC;AACH;AAYO,SAAS,iBACd,OACA,OACA,MAC4E;AAC5E,QAAM,WAAW,MAAM,UAAU,CAAC,SAAS,MAAM,SAAS,SAAS,IAAI,CAAC;AACxE,MAAI,WAAW,EAAG,QAAO;AACzB,QAAM,UAAU,MAAM,MAAM,QAAQ,EAAE,OAAO,CAAC,SAAS,MAAM,OAAO,SAAS,IAAI,CAAC;AAClF,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SAAO;AAAA,IACL,QAAQ,MAAM,OAAO,OAAO,CAAC,UAAU,CAAC,QAAQ,SAAS,KAAK,CAAC;AAAA,IAC/D,UAAU,CAAC,GAAG,MAAM,MAAM,QAAQ,GAAG,GAAG,MAAM,SAAS,OAAO,CAAC,UAAU,CAAC,MAAM,SAAS,KAAK,CAAC,CAAC;AAAA,IAChG,MAAM,MAAM,OAAO,QAAQ,OAAO,CAAC,KAAK,SAAS,MAAM,KAAK,IAAI,GAAG,CAAC;AAAA,EACtE;AACF;AAQO,SAAS,YAAY,OAAiC,OAAoD;AAE/G,MAAI,MAAM,YAAY,KAAM,QAAO,EAAE,GAAG,OAAO,CAAC,MAAM,OAAO,GAAG,CAAC,EAAE;AACnE,QAAM,UAAU,cAAc,OAAO,KAAK;AAC1C,SAAO,EAAE,GAAG,OAAO,CAAC,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,KAAK,EAAE;AACnE;","names":[]}
@@ -13,13 +13,17 @@ function CardActionsProvider({
13
13
  errorTitle,
14
14
  errorDismissLabel,
15
15
  autoHideMs = 6e3,
16
+ onError,
16
17
  children
17
18
  }) {
18
19
  const [error, setError] = useState(null);
19
- const notifyError = useCallback((message) => setError(message), []);
20
+ const notifyError = useCallback(
21
+ (message) => onError ? onError(errorTitle, message) : setError(message),
22
+ [onError, errorTitle]
23
+ );
20
24
  return /* @__PURE__ */ jsxs(CardActionsContext.Provider, { value: { tenantSlug, onRefresh, notifyError }, children: [
21
25
  children,
22
- /* @__PURE__ */ jsx(
26
+ onError === void 0 && /* @__PURE__ */ jsx(
23
27
  Snackbar,
24
28
  {
25
29
  open: error !== null,
@@ -54,4 +58,4 @@ export {
54
58
  CardActionsProvider,
55
59
  useCardActions
56
60
  };
57
- //# sourceMappingURL=chunk-N7KWWIF7.js.map
61
+ //# sourceMappingURL=chunk-LY7PBZ3Z.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/data-display/CardKit/card-actions-context.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, useCallback, useContext, useState, type JSX, type ReactNode } from 'react';\n\nimport Snackbar from '@mui/material/Snackbar/index.js';\n\nimport { Alert } from '../Alert';\n\n/**\n * The ambient wiring a self-contained row/card menu needs, and nothing else.\n *\n * A menu that owns its own popups still needs three things it cannot know: the\n * tenant it is acting inside, what to do after a write lands, and somewhere to\n * put a failure. Passing those down through the grid, the layout and the card\n * is four props of drilling per entity; holding them in context is one.\n *\n * Kept deliberately SMALL — it is not an edit-dialog host. A menu that read its\n * dialogs from here would stop being portable, because the set of dialogs is\n * per-entity. What it may read is the three facts below.\n *\n * The provider renders ONE shared error snackbar, which is the whole reason the\n * error channel is here rather than per-menu: before it, every page carried its\n * own error alert and every menu had to find its page's.\n */\ninterface CardActionsValue {\n /** The tenant every action in this subtree acts inside. */\n tenantSlug: string;\n /** Re-read the list after a write. */\n onRefresh: () => void;\n /** Surface a failed action's message (the shared snackbar). */\n notifyError: (message: string) => void;\n}\n\nconst CardActionsContext = createContext<CardActionsValue | null>(null);\n\nexport function CardActionsProvider({\n tenantSlug,\n onRefresh,\n errorTitle,\n errorDismissLabel,\n autoHideMs = 6_000,\n onError,\n children,\n}: {\n tenantSlug: string;\n onRefresh: () => void;\n /**\n * The snackbar's heading — required, no default.\n *\n * It is the one sentence this provider renders on its own, and a default\n * would be the origin's language shipped as a finished-looking silence. The\n * MESSAGE beside it comes from whatever failed, which is already the host's.\n */\n errorTitle: string;\n /** The dismiss on that alert, which carries a glyph only. REQUIRED. */\n errorDismissLabel: string;\n /** How long the snackbar stays up. */\n autoHideMs?: number;\n /**\n * Hand a failure to the HOST's own toast channel instead of this provider's\n * snackbar. Given, the provider draws nothing of its own: an app with one\n * toast column (every toast in one place, in one look) passes its `toast`\n * here, so a card's failure lands with every other toast rather than in a\n * corner of its own. It receives the same heading and message the snackbar\n * would have shown.\n */\n onError?: (title: string, message: string) => void;\n children: ReactNode;\n}): JSX.Element {\n const [error, setError] = useState<string | null>(null);\n const notifyError = useCallback(\n (message: string) => (onError ? onError(errorTitle, message) : setError(message)),\n [onError, errorTitle],\n );\n\n return (\n <CardActionsContext.Provider value={{ tenantSlug, onRefresh, notifyError }}>\n {children}\n {onError === undefined && (\n <Snackbar\n open={error !== null}\n autoHideDuration={autoHideMs}\n onClose={() => setError(null)}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}\n >\n <span>\n <Alert\n variant=\"danger\"\n title={errorTitle}\n description={error ?? ''}\n closable\n closeLabel={errorDismissLabel}\n onClose={() => setError(null)}\n data-testid=\"card-action-error\"\n />\n </span>\n </Snackbar>\n )}\n </CardActionsContext.Provider>\n );\n}\n\n/**\n * Read the tenant + refresh + error wiring.\n *\n * THROWS outside a provider rather than answering a null object, deliberately:\n * a menu whose `onRefresh` silently did nothing would leave the operator\n * looking at a stale row after a delete that worked, which reads as the delete\n * having failed. Failing at mount says where the provider is missing.\n */\nexport function useCardActions(): CardActionsValue {\n const value = useContext(CardActionsContext);\n if (!value) {\n throw new Error('useCardActions must be used within a CardActionsProvider');\n }\n return value;\n}\n"],"mappings":";;;;;AAEA,SAAS,eAAe,aAAa,YAAY,gBAA0C;AAE3F,OAAO,cAAc;AAwEjB,SAUM,KAVN;AA3CJ,IAAM,qBAAqB,cAAuC,IAAI;AAE/D,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb;AAAA,EACA;AACF,GAyBgB;AACd,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AACtD,QAAM,cAAc;AAAA,IAClB,CAAC,YAAqB,UAAU,QAAQ,YAAY,OAAO,IAAI,SAAS,OAAO;AAAA,IAC/E,CAAC,SAAS,UAAU;AAAA,EACtB;AAEA,SACE,qBAAC,mBAAmB,UAAnB,EAA4B,OAAO,EAAE,YAAY,WAAW,YAAY,GACtE;AAAA;AAAA,IACA,YAAY,UACb;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,UAAU;AAAA,QAChB,kBAAkB;AAAA,QAClB,SAAS,MAAM,SAAS,IAAI;AAAA,QAC5B,cAAc,EAAE,UAAU,UAAU,YAAY,SAAS;AAAA,QAEzD,8BAAC,UACC;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,OAAO;AAAA,YACP,aAAa,SAAS;AAAA,YACtB,UAAQ;AAAA,YACR,YAAY;AAAA,YACZ,SAAS,MAAM,SAAS,IAAI;AAAA,YAC5B,eAAY;AAAA;AAAA,QACd,GACF;AAAA;AAAA,IACF;AAAA,KAEF;AAEJ;AAUO,SAAS,iBAAmC;AACjD,QAAM,QAAQ,WAAW,kBAAkB;AAC3C,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AACA,SAAO;AACT;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  GridShell
3
- } from "./chunk-LY6L3DMB.js";
3
+ } from "./chunk-DAT4XWYX.js";
4
4
  import {
5
5
  useDataViewsState
6
6
  } from "./chunk-2QB4WIU5.js";
@@ -27,4 +27,4 @@ function DataViewsGrid(props) {
27
27
  export {
28
28
  DataViewsGrid
29
29
  };
30
- //# sourceMappingURL=chunk-JCHJYBDG.js.map
30
+ //# sourceMappingURL=chunk-QVEQOUQY.js.map
@@ -2,7 +2,7 @@ import {
2
2
  anyApplied,
3
3
  isQuickActive,
4
4
  keepChipsInOrder
5
- } from "./chunk-AMT7IJYV.js";
5
+ } from "./chunk-KYUEO2IO.js";
6
6
  import {
7
7
  RESERVED,
8
8
  estimateWidth,
@@ -129,4 +129,4 @@ function useFilterOverflow(all, pills, ranges, frozen = false, hasExport = true,
129
129
  export {
130
130
  useFilterOverflow
131
131
  };
132
- //# sourceMappingURL=chunk-SOQIWXFO.js.map
132
+ //# sourceMappingURL=chunk-WWH674WU.js.map
@@ -4,13 +4,13 @@ import {
4
4
  } from "./chunk-QLJU7UUI.js";
5
5
  import {
6
6
  MoreFilters
7
- } from "./chunk-SAXALTRL.js";
7
+ } from "./chunk-6OLERKNC.js";
8
8
  import {
9
9
  PillControl
10
10
  } from "./chunk-RQF4NXDC.js";
11
11
  import {
12
12
  isQuickActive
13
- } from "./chunk-AMT7IJYV.js";
13
+ } from "./chunk-KYUEO2IO.js";
14
14
  import {
15
15
  RangePill
16
16
  } from "./chunk-5WJFCQFN.js";
@@ -244,4 +244,4 @@ function FilterSlots({
244
244
  export {
245
245
  InlineFilterControls
246
246
  };
247
- //# sourceMappingURL=chunk-TLPFSA55.js.map
247
+ //# sourceMappingURL=chunk-ZEH6MGP5.js.map
@@ -6,11 +6,11 @@ import {
6
6
  } from "../chunk-6QOJEZDH.js";
7
7
  import {
8
8
  useRemoveConfirm
9
- } from "../chunk-62BY4ZUQ.js";
9
+ } from "../chunk-7KAZ3B5B.js";
10
10
  import {
11
11
  CardActionsProvider,
12
12
  useCardActions
13
- } from "../chunk-N7KWWIF7.js";
13
+ } from "../chunk-LY7PBZ3Z.js";
14
14
  import {
15
15
  rowActionsToMenuItems
16
16
  } from "../chunk-ZBXG6RVJ.js";
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  DataViewsTableBase
3
- } from "../chunk-62YHJAWM.js";
3
+ } from "../chunk-7SPFK73H.js";
4
4
  import "../chunk-ZEVFMQAQ.js";
5
5
  import {
6
6
  DataViewsGrid
7
- } from "../chunk-JCHJYBDG.js";
7
+ } from "../chunk-QVEQOUQY.js";
8
8
  import {
9
9
  BaseCard
10
10
  } from "../chunk-D34PZJH3.js";
@@ -23,9 +23,9 @@ import {
23
23
  useDragItem
24
24
  } from "../chunk-K4EKTMTC.js";
25
25
  import "../chunk-ZOLAYP2D.js";
26
- import "../chunk-LY6L3DMB.js";
26
+ import "../chunk-DAT4XWYX.js";
27
27
  import "../chunk-Y2CCXB7R.js";
28
- import "../chunk-TLPFSA55.js";
28
+ import "../chunk-ZEH6MGP5.js";
29
29
  import "../chunk-QLJU7UUI.js";
30
30
  import "../chunk-X3AFXHY5.js";
31
31
  import "../chunk-WQ32YFM5.js";
@@ -35,11 +35,11 @@ import {
35
35
  import "../chunk-SZSS5KKX.js";
36
36
  import "../chunk-E5GYHN4X.js";
37
37
  import "../chunk-XZFTRGRW.js";
38
- import "../chunk-SOQIWXFO.js";
39
- import "../chunk-SAXALTRL.js";
40
- import "../chunk-EYW6KXUC.js";
38
+ import "../chunk-WWH674WU.js";
39
+ import "../chunk-6OLERKNC.js";
40
+ import "../chunk-2B3NX5HJ.js";
41
41
  import "../chunk-RQF4NXDC.js";
42
- import "../chunk-AMT7IJYV.js";
42
+ import "../chunk-KYUEO2IO.js";
43
43
  import "../chunk-GZOW6HNN.js";
44
44
  import "../chunk-5WJFCQFN.js";
45
45
  import "../chunk-FJ3UZ4RC.js";
@@ -23,7 +23,7 @@ interface CardActionsValue {
23
23
  /** Surface a failed action's message (the shared snackbar). */
24
24
  notifyError: (message: string) => void;
25
25
  }
26
- export declare function CardActionsProvider({ tenantSlug, onRefresh, errorTitle, errorDismissLabel, autoHideMs, children, }: {
26
+ export declare function CardActionsProvider({ tenantSlug, onRefresh, errorTitle, errorDismissLabel, autoHideMs, onError, children, }: {
27
27
  tenantSlug: string;
28
28
  onRefresh: () => void;
29
29
  /**
@@ -38,6 +38,15 @@ export declare function CardActionsProvider({ tenantSlug, onRefresh, errorTitle,
38
38
  errorDismissLabel: string;
39
39
  /** How long the snackbar stays up. */
40
40
  autoHideMs?: number;
41
+ /**
42
+ * Hand a failure to the HOST's own toast channel instead of this provider's
43
+ * snackbar. Given, the provider draws nothing of its own: an app with one
44
+ * toast column (every toast in one place, in one look) passes its `toast`
45
+ * here, so a card's failure lands with every other toast rather than in a
46
+ * corner of its own. It receives the same heading and message the snackbar
47
+ * would have shown.
48
+ */
49
+ onError?: (title: string, message: string) => void;
41
50
  children: ReactNode;
42
51
  }): JSX.Element;
43
52
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"card-actions-context.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/CardKit/card-actions-context.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAoD,KAAK,GAAG,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAMnG;;;;;;;;;;;;;;;GAeG;AACH,UAAU,gBAAgB;IACxB,2DAA2D;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,+DAA+D;IAC/D,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAID,wBAAgB,mBAAmB,CAAC,EAClC,UAAU,EACV,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,UAAkB,EAClB,QAAQ,GACT,EAAE;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,sCAAsC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,GAAG,CAAC,OAAO,CA2Bd;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,IAAI,gBAAgB,CAMjD"}
1
+ {"version":3,"file":"card-actions-context.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/CardKit/card-actions-context.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAoD,KAAK,GAAG,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAMnG;;;;;;;;;;;;;;;GAeG;AACH,UAAU,gBAAgB;IACxB,2DAA2D;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,+DAA+D;IAC/D,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAID,wBAAgB,mBAAmB,CAAC,EAClC,UAAU,EACV,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,UAAkB,EAClB,OAAO,EACP,QAAQ,GACT,EAAE;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,sCAAsC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,GAAG,CAAC,OAAO,CAgCd;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,IAAI,gBAAgB,CAMjD"}
@@ -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":"AAoBA,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;AAsJD;;;;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,CAiBA;AAGD;;;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,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,CAwDrC"}
1
+ {"version":3,"file":"data-views-more-fields.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/DataViews/data-views-more-fields.tsx"],"names":[],"mappings":"AAoBA,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;AAsJD;;;;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;AAGD;;;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,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,CAwDrC"}
@@ -1 +1 @@
1
- {"version":3,"file":"data-views-overflow-fields.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/DataViews/data-views-overflow-fields.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAE7G;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChE,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAC9B,WAAW,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,EAClC,YAAY,GAAE,iBAAiB,EAAO,GACrC,aAAa,CAAC,CAAC,CAAC,EAAE,CAoBpB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,OAAO,CAGhG;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1D,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,EACvB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GACjC,OAAO,CAMT;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChE,KAAK,EAAE;IAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EACjF,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,EACzB,IAAI,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,MAAM,GACxC;IAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAU5E;AAID;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAG/G"}
1
+ {"version":3,"file":"data-views-overflow-fields.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/DataViews/data-views-overflow-fields.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAE7G;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChE,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAC9B,WAAW,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,EAClC,YAAY,GAAE,iBAAiB,EAAO,GACrC,aAAa,CAAC,CAAC,CAAC,EAAE,CAoBpB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,OAAO,CAKhG;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1D,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,EACvB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GACjC,OAAO,CAMT;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChE,KAAK,EAAE;IAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EACjF,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,EACzB,IAAI,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,MAAM,GACxC;IAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAU5E;AAID;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAK/G"}
@@ -29,5 +29,19 @@ export interface QuickFilterConfig {
29
29
  count?: number;
30
30
  /** Colours the count: what kind of attention the rows need. */
31
31
  tone?: "error" | "warning" | "info" | "success";
32
+ /**
33
+ * The page's DEFAULT view: this chip reads pressed while its field is EMPTY,
34
+ * and pressing it empties the field rather than writing `[value]`.
35
+ *
36
+ * For a page whose unfiltered view is already one of the chips ("Precisa
37
+ * repor"): seeding `[value]` to light the chip made the default view count as
38
+ * a filter, so "Limpar" showed on arrival and did nothing — it cleared the
39
+ * field and the host put it back. An empty field is no filter, so "Limpar",
40
+ * the active count and the ladder see the default view as unfiltered, and
41
+ * "Limpar" from any other chip lands back here. The HOST owns what an empty
42
+ * field means: the grid applies no filter for it. At most ONE per `fieldId`:
43
+ * two would both read pressed on the empty field.
44
+ */
45
+ default?: boolean;
32
46
  }
33
47
  //# sourceMappingURL=data-views-quick-types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"data-views-quick-types.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/DataViews/data-views-quick-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,iBAAiB;IAChC,oDAAoD;IACpD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;CACjD"}
1
+ {"version":3,"file":"data-views-quick-types.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/DataViews/data-views-quick-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,iBAAiB;IAChC,oDAAoD;IACpD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;IAChD;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@12-apps/ui",
3
- "version": "6.70.0",
3
+ "version": "6.72.0",
4
4
  "license": "MIT",
5
5
  "packageManager": "pnpm@10.34.5",
6
6
  "type": "module",
@@ -33,6 +33,9 @@ language shipped as a finished-looking silence:
33
33
  verbatim by a screen reader.
34
34
  - `CardActionsProvider`'s **`errorTitle`** — the one sentence the provider
35
35
  renders on its own. The message beside it comes from whatever failed.
36
+ An app with one toast channel passes **`onError(title, message)`** instead of
37
+ living with the provider's bottom snackbar: given, the provider draws
38
+ nothing of its own and the failure lands with every other toast.
36
39
  - Both hooks' **`confirmText`** — the verb. `ConfirmOptions` already refuses to
37
40
  default one, for the same reason: a confirm button reading "OK" tells the
38
41
  operator nothing about what is about to happen.
@@ -39,6 +39,7 @@ export function CardActionsProvider({
39
39
  errorTitle,
40
40
  errorDismissLabel,
41
41
  autoHideMs = 6_000,
42
+ onError,
42
43
  children,
43
44
  }: {
44
45
  tenantSlug: string;
@@ -55,14 +56,27 @@ export function CardActionsProvider({
55
56
  errorDismissLabel: string;
56
57
  /** How long the snackbar stays up. */
57
58
  autoHideMs?: number;
59
+ /**
60
+ * Hand a failure to the HOST's own toast channel instead of this provider's
61
+ * snackbar. Given, the provider draws nothing of its own: an app with one
62
+ * toast column (every toast in one place, in one look) passes its `toast`
63
+ * here, so a card's failure lands with every other toast rather than in a
64
+ * corner of its own. It receives the same heading and message the snackbar
65
+ * would have shown.
66
+ */
67
+ onError?: (title: string, message: string) => void;
58
68
  children: ReactNode;
59
69
  }): JSX.Element {
60
70
  const [error, setError] = useState<string | null>(null);
61
- const notifyError = useCallback((message: string) => setError(message), []);
71
+ const notifyError = useCallback(
72
+ (message: string) => (onError ? onError(errorTitle, message) : setError(message)),
73
+ [onError, errorTitle],
74
+ );
62
75
 
63
76
  return (
64
77
  <CardActionsContext.Provider value={{ tenantSlug, onRefresh, notifyError }}>
65
78
  {children}
79
+ {onError === undefined && (
66
80
  <Snackbar
67
81
  open={error !== null}
68
82
  autoHideDuration={autoHideMs}
@@ -81,6 +95,7 @@ export function CardActionsProvider({
81
95
  />
82
96
  </span>
83
97
  </Snackbar>
98
+ )}
84
99
  </CardActionsContext.Provider>
85
100
  );
86
101
  }
@@ -324,6 +324,14 @@ an idle pill first, or the chips together — never one chip swapped for another
324
324
  under the hand that pressed it. A chip reads as pressed
325
325
  only when its value is the field's WHOLE selection.
326
326
 
327
+ A chip declared `default: true` is the page's unfiltered view ("Precisa repor"):
328
+ it reads pressed while its field is EMPTY, and pressing it empties the field
329
+ rather than writing its value. So the default view is no filter: no "Limpar" on
330
+ arrival, no applied badge on "Mais", and "Limpar" from any other chip lands back
331
+ on it. The host owns what the empty field means (the grid filters nothing for
332
+ it); seeding the value instead made "Limpar" show on arrival and do nothing.
333
+ `data-views-quick-default.test.tsx` pins it.
334
+
327
335
  Both are inline-bar features: in the classic slide-in panel (`inlineFilters`
328
336
  off) there is no bar, and the chips' field is drawn as its ordinary pill.
329
337
 
@@ -208,7 +208,8 @@ export function fieldClearing<T extends Record<string, unknown>>({
208
208
  } {
209
209
  if (field.group === "quick" && field.quick) {
210
210
  const quick = field.quick;
211
- const applied = isQuickActive(quick, pills);
211
+ // A `default` chip lit by an empty field has nothing to clear.
212
+ const applied = isQuickActive(quick, pills) && (pills[quick.fieldId]?.length ?? 0) > 0;
212
213
  return { applied, clear: () => onTogglePill(quick.fieldId, quick.value, false) };
213
214
  }
214
215
  if (field.group === "range") {
@@ -50,6 +50,8 @@ export function toOverflowFields<T extends Record<string, unknown>>(
50
50
  */
51
51
  export function isQuickActive(quick: QuickFilterConfig, pills: Record<string, string[]>): boolean {
52
52
  const selected = pills[quick.fieldId] ?? [];
53
+ // A `default` chip is the empty field (see `QuickFilterConfig.default`).
54
+ if (quick.default === true && selected.length === 0) return true;
53
55
  return selected.length === 1 && selected[0] === quick.value;
54
56
  }
55
57
 
@@ -104,6 +106,8 @@ export function keepChipsInOrder<T extends Record<string, unknown>>(
104
106
  * value REPLACES the selection, and pressing the pressed chip empties it.
105
107
  */
106
108
  export function toggleQuick(pills: Record<string, string[]>, quick: QuickFilterConfig): Record<string, string[]> {
109
+ // A `default` chip only ever empties its field: pressing it again stays put.
110
+ if (quick.default === true) return { ...pills, [quick.fieldId]: [] };
107
111
  const pressed = isQuickActive(quick, pills);
108
112
  return { ...pills, [quick.fieldId]: pressed ? [] : [quick.value] };
109
113
  }
@@ -30,4 +30,18 @@ export interface QuickFilterConfig {
30
30
  count?: number;
31
31
  /** Colours the count: what kind of attention the rows need. */
32
32
  tone?: "error" | "warning" | "info" | "success";
33
+ /**
34
+ * The page's DEFAULT view: this chip reads pressed while its field is EMPTY,
35
+ * and pressing it empties the field rather than writing `[value]`.
36
+ *
37
+ * For a page whose unfiltered view is already one of the chips ("Precisa
38
+ * repor"): seeding `[value]` to light the chip made the default view count as
39
+ * a filter, so "Limpar" showed on arrival and did nothing — it cleared the
40
+ * field and the host put it back. An empty field is no filter, so "Limpar",
41
+ * the active count and the ladder see the default view as unfiltered, and
42
+ * "Limpar" from any other chip lands back here. The HOST owns what an empty
43
+ * field means: the grid applies no filter for it. At most ONE per `fieldId`:
44
+ * two would both read pressed on the empty field.
45
+ */
46
+ default?: boolean;
33
47
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/data-display/DataViews/data-views-overflow-fields.ts"],"sourcesContent":["/**\n * WHICH CONTROLS THE BAR DECLARES — split from `data-views-overflow` at the\n * file-size gate. That module decides where each control goes; this one only\n * lists them, in the order the bar renders them.\n */\nimport type { OverflowField } from \"./data-views-overflow\";\nimport { isRangeSet } from \"./data-views-overflow-costs\";\nimport type { FilterFieldConfig, QuickFilterConfig, RangeFieldConfig, RangeValue } from \"./data-views-types\";\n\n/**\n * Every declared control in the order the bar renders them: quick chips first,\n * then pills, then ranges.\n *\n * A pill field a quick chip writes to is NOT a control of its own — the chips\n * stand in for it (see `QuickFilterConfig`) — so it is left out here, and only\n * here: it stays in `fields`, where the active count and saved views read it.\n */\nexport function toOverflowFields<T extends Record<string, unknown>>(\n fields: FilterFieldConfig<T>[],\n rangeFields: RangeFieldConfig<T>[],\n quickFilters: QuickFilterConfig[] = [],\n): OverflowField<T>[] {\n const chipFields = new Set(quickFilters.map((quick) => quick.fieldId));\n return [\n ...quickFilters.map((quick) => ({\n id: `quick:${quick.id}`,\n label: quick.label,\n group: \"quick\" as const,\n quick,\n })),\n ...fields\n .filter((pill) => !chipFields.has(pill.id))\n .map((pill) => ({ id: pill.id, label: pill.label, group: \"pill\" as const, pill, pinned: pill.inMore === true })),\n ...rangeFields.map((range) => ({\n id: range.id,\n label: range.label,\n group: \"range\" as const,\n range,\n pinned: range.inMore === true,\n })),\n ];\n}\n\n/**\n * Is this quick chip pressed — its one value the field's WHOLE selection?\n *\n * Exactly, not \"includes\": a field holding two values (from a saved view, the\n * URL or the side panel) is not what either chip applies, and reading both as\n * pressed made pressing one clear the other.\n */\nexport function isQuickActive(quick: QuickFilterConfig, pills: Record<string, string[]>): boolean {\n const selected = pills[quick.fieldId] ?? [];\n return selected.length === 1 && selected[0] === quick.value;\n}\n\n/**\n * Is any DECLARED filter applied — a pill value or a bounded range, wherever it\n * is drawn (on the bar, in \"Mais\", or as a chip)? Only declared ids count: the\n * bar draws \"Limpar\" on the active count, which ignores a stale key a saved view\n * still carries for a field since removed.\n */\nexport function anyApplied<T extends Record<string, unknown>>(\n all: OverflowField<T>[],\n pills: Record<string, string[]>,\n ranges: Record<string, RangeValue>,\n): boolean {\n return all.some((field) => {\n if (field.group === \"range\") return isRangeSet(ranges[field.id]);\n const id = field.quick?.fieldId ?? field.id;\n return (pills[id]?.length ?? 0) > 0;\n });\n}\n\n/**\n * Quick chips stay a PREFIX of their declared order on the bar.\n *\n * The keep-what-fits loop skips a control that does not fit and tries the next,\n * which for pills is right (any narrower one is worth the room) and for chips\n * is not: \"Zerado\" alone on the bar, with \"Estoque baixo\" in \"Mais\", reads as a\n * different bar from the one declared. So the first chip that went to \"Mais\"\n * takes every later chip with it. Their room is NOT re-spent here — `used`\n * drops, and the ladder's later passes can hand it to the furniture.\n */\nexport function keepChipsInOrder<T extends Record<string, unknown>>(\n split: { inline: OverflowField<T>[]; overflow: OverflowField<T>[]; used: number },\n chips: OverflowField<T>[],\n cost: (field: OverflowField<T>) => number,\n): { inline: OverflowField<T>[]; overflow: OverflowField<T>[]; used: number } {\n const firstOut = chips.findIndex((chip) => split.overflow.includes(chip));\n if (firstOut < 0) return split;\n const evicted = chips.slice(firstOut).filter((chip) => split.inline.includes(chip));\n if (evicted.length === 0) return split;\n return {\n inline: split.inline.filter((field) => !evicted.includes(field)),\n overflow: [...chips.slice(firstOut), ...split.overflow.filter((field) => !chips.includes(field))],\n used: split.used - evicted.reduce((sum, chip) => sum + cost(chip), 0),\n };\n}\n\n\n\n/**\n * A quick chip's press, as a pill write. Exclusive within the field: the chip's\n * value REPLACES the selection, and pressing the pressed chip empties it.\n */\nexport function toggleQuick(pills: Record<string, string[]>, quick: QuickFilterConfig): Record<string, string[]> {\n const pressed = isQuickActive(quick, pills);\n return { ...pills, [quick.fieldId]: pressed ? [] : [quick.value] };\n}\n\n"],"mappings":";;;;;AAiBO,SAAS,iBACd,QACA,aACA,eAAoC,CAAC,GACjB;AACpB,QAAM,aAAa,IAAI,IAAI,aAAa,IAAI,CAAC,UAAU,MAAM,OAAO,CAAC;AACrE,SAAO;AAAA,IACL,GAAG,aAAa,IAAI,CAAC,WAAW;AAAA,MAC9B,IAAI,SAAS,MAAM,EAAE;AAAA,MACrB,OAAO,MAAM;AAAA,MACb,OAAO;AAAA,MACP;AAAA,IACF,EAAE;AAAA,IACF,GAAG,OACA,OAAO,CAAC,SAAS,CAAC,WAAW,IAAI,KAAK,EAAE,CAAC,EACzC,IAAI,CAAC,UAAU,EAAE,IAAI,KAAK,IAAI,OAAO,KAAK,OAAO,OAAO,QAAiB,MAAM,QAAQ,KAAK,WAAW,KAAK,EAAE;AAAA,IACjH,GAAG,YAAY,IAAI,CAAC,WAAW;AAAA,MAC7B,IAAI,MAAM;AAAA,MACV,OAAO,MAAM;AAAA,MACb,OAAO;AAAA,MACP;AAAA,MACA,QAAQ,MAAM,WAAW;AAAA,IAC3B,EAAE;AAAA,EACJ;AACF;AASO,SAAS,cAAc,OAA0B,OAA0C;AAChG,QAAM,WAAW,MAAM,MAAM,OAAO,KAAK,CAAC;AAC1C,SAAO,SAAS,WAAW,KAAK,SAAS,CAAC,MAAM,MAAM;AACxD;AAQO,SAAS,WACd,KACA,OACA,QACS;AACT,SAAO,IAAI,KAAK,CAAC,UAAU;AACzB,QAAI,MAAM,UAAU,QAAS,QAAO,WAAW,OAAO,MAAM,EAAE,CAAC;AAC/D,UAAM,KAAK,MAAM,OAAO,WAAW,MAAM;AACzC,YAAQ,MAAM,EAAE,GAAG,UAAU,KAAK;AAAA,EACpC,CAAC;AACH;AAYO,SAAS,iBACd,OACA,OACA,MAC4E;AAC5E,QAAM,WAAW,MAAM,UAAU,CAAC,SAAS,MAAM,SAAS,SAAS,IAAI,CAAC;AACxE,MAAI,WAAW,EAAG,QAAO;AACzB,QAAM,UAAU,MAAM,MAAM,QAAQ,EAAE,OAAO,CAAC,SAAS,MAAM,OAAO,SAAS,IAAI,CAAC;AAClF,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SAAO;AAAA,IACL,QAAQ,MAAM,OAAO,OAAO,CAAC,UAAU,CAAC,QAAQ,SAAS,KAAK,CAAC;AAAA,IAC/D,UAAU,CAAC,GAAG,MAAM,MAAM,QAAQ,GAAG,GAAG,MAAM,SAAS,OAAO,CAAC,UAAU,CAAC,MAAM,SAAS,KAAK,CAAC,CAAC;AAAA,IAChG,MAAM,MAAM,OAAO,QAAQ,OAAO,CAAC,KAAK,SAAS,MAAM,KAAK,IAAI,GAAG,CAAC;AAAA,EACtE;AACF;AAQO,SAAS,YAAY,OAAiC,OAAoD;AAC/G,QAAM,UAAU,cAAc,OAAO,KAAK;AAC1C,SAAO,EAAE,GAAG,OAAO,CAAC,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,KAAK,EAAE;AACnE;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/data-display/CardKit/card-actions-context.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, useCallback, useContext, useState, type JSX, type ReactNode } from 'react';\n\nimport Snackbar from '@mui/material/Snackbar/index.js';\n\nimport { Alert } from '../Alert';\n\n/**\n * The ambient wiring a self-contained row/card menu needs, and nothing else.\n *\n * A menu that owns its own popups still needs three things it cannot know: the\n * tenant it is acting inside, what to do after a write lands, and somewhere to\n * put a failure. Passing those down through the grid, the layout and the card\n * is four props of drilling per entity; holding them in context is one.\n *\n * Kept deliberately SMALL — it is not an edit-dialog host. A menu that read its\n * dialogs from here would stop being portable, because the set of dialogs is\n * per-entity. What it may read is the three facts below.\n *\n * The provider renders ONE shared error snackbar, which is the whole reason the\n * error channel is here rather than per-menu: before it, every page carried its\n * own error alert and every menu had to find its page's.\n */\ninterface CardActionsValue {\n /** The tenant every action in this subtree acts inside. */\n tenantSlug: string;\n /** Re-read the list after a write. */\n onRefresh: () => void;\n /** Surface a failed action's message (the shared snackbar). */\n notifyError: (message: string) => void;\n}\n\nconst CardActionsContext = createContext<CardActionsValue | null>(null);\n\nexport function CardActionsProvider({\n tenantSlug,\n onRefresh,\n errorTitle,\n errorDismissLabel,\n autoHideMs = 6_000,\n children,\n}: {\n tenantSlug: string;\n onRefresh: () => void;\n /**\n * The snackbar's heading — required, no default.\n *\n * It is the one sentence this provider renders on its own, and a default\n * would be the origin's language shipped as a finished-looking silence. The\n * MESSAGE beside it comes from whatever failed, which is already the host's.\n */\n errorTitle: string;\n /** The dismiss on that alert, which carries a glyph only. REQUIRED. */\n errorDismissLabel: string;\n /** How long the snackbar stays up. */\n autoHideMs?: number;\n children: ReactNode;\n}): JSX.Element {\n const [error, setError] = useState<string | null>(null);\n const notifyError = useCallback((message: string) => setError(message), []);\n\n return (\n <CardActionsContext.Provider value={{ tenantSlug, onRefresh, notifyError }}>\n {children}\n <Snackbar\n open={error !== null}\n autoHideDuration={autoHideMs}\n onClose={() => setError(null)}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}\n >\n <span>\n <Alert\n variant=\"danger\"\n title={errorTitle}\n description={error ?? ''}\n closable\n closeLabel={errorDismissLabel}\n onClose={() => setError(null)}\n data-testid=\"card-action-error\"\n />\n </span>\n </Snackbar>\n </CardActionsContext.Provider>\n );\n}\n\n/**\n * Read the tenant + refresh + error wiring.\n *\n * THROWS outside a provider rather than answering a null object, deliberately:\n * a menu whose `onRefresh` silently did nothing would leave the operator\n * looking at a stale row after a delete that worked, which reads as the delete\n * having failed. Failing at mount says where the provider is missing.\n */\nexport function useCardActions(): CardActionsValue {\n const value = useContext(CardActionsContext);\n if (!value) {\n throw new Error('useCardActions must be used within a CardActionsProvider');\n }\n return value;\n}\n"],"mappings":";;;;;AAEA,SAAS,eAAe,aAAa,YAAY,gBAA0C;AAE3F,OAAO,cAAc;AA2DjB,SASM,KATN;AA9BJ,IAAM,qBAAqB,cAAuC,IAAI;AAE/D,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb;AACF,GAgBgB;AACd,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AACtD,QAAM,cAAc,YAAY,CAAC,YAAoB,SAAS,OAAO,GAAG,CAAC,CAAC;AAE1E,SACE,qBAAC,mBAAmB,UAAnB,EAA4B,OAAO,EAAE,YAAY,WAAW,YAAY,GACtE;AAAA;AAAA,IACD;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,UAAU;AAAA,QAChB,kBAAkB;AAAA,QAClB,SAAS,MAAM,SAAS,IAAI;AAAA,QAC5B,cAAc,EAAE,UAAU,UAAU,YAAY,SAAS;AAAA,QAEzD,8BAAC,UACC;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,OAAO;AAAA,YACP,aAAa,SAAS;AAAA,YACtB,UAAQ;AAAA,YACR,YAAY;AAAA,YACZ,SAAS,MAAM,SAAS,IAAI;AAAA,YAC5B,eAAY;AAAA;AAAA,QACd,GACF;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;AAUO,SAAS,iBAAmC;AACjD,QAAM,QAAQ,WAAW,kBAAkB;AAC3C,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AACA,SAAO;AACT;","names":[]}