@12-apps/ui 6.67.0 → 6.69.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/components/data-display/Chip/Chip.js +3 -3
- package/dist/_internal/components/data-display/Chip/Chip.metrics.js +5 -1
- package/dist/_internal/components/data-display/Chip/Chip.styles.js +2 -2
- package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +12 -12
- package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +13 -13
- package/dist/_internal/components/data-display/DataViews/data-views-filter-panel.js +4 -4
- package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +11 -11
- package/dist/_internal/components/data-display/DataViews/data-views-inline-bar.js +6 -6
- package/dist/_internal/components/data-display/DataViews/data-views-more-fields.js +3 -3
- package/dist/_internal/components/data-display/DataViews/data-views-more-filters.js +4 -4
- package/dist/_internal/components/data-display/DataViews/data-views-overflow-costs.js +1 -1
- package/dist/_internal/components/data-display/DataViews/data-views-overflow-fields.js +2 -2
- package/dist/_internal/components/data-display/DataViews/data-views-overflow.js +3 -3
- package/dist/_internal/components/data-display/index.js +3 -3
- package/dist/_internal/components/feedback/StackedModal/StackedModal.js +3 -3
- package/dist/_internal/components/feedback/StackedModal/StackedModal.parts.js +2 -2
- package/dist/_internal/components/feedback/StackedModal/StackedModal.styles.js +1 -1
- package/dist/_internal/components/feedback/index.js +3 -3
- package/dist/_internal/components/index.js +14 -14
- package/dist/_internal/components/layout/SettingCard/SettingCard.js +6 -6
- package/dist/_internal/components/layout/SettingCard/SettingCard.parts.js +4 -4
- package/dist/_internal/components/layout/SettingCard/SettingCard.summary.js +5 -5
- package/dist/_internal/components/layout/SettingCard/SettingGrid.js +5 -5
- package/dist/_internal/components/layout/SettingCard/SettingGroup.js +7 -7
- package/dist/_internal/components/layout/SettingCard/SettingSwitch.js +6 -6
- package/dist/_internal/components/layout/SettingCard/SettingToggle.js +7 -7
- package/dist/_internal/components/layout/index.js +10 -10
- package/dist/_internal/components/navigation/Tabs/Tabs.js +1 -1
- package/dist/_internal/components/navigation/index.js +1 -1
- package/dist/{chunk-AAXLQFC7.js → chunk-3FIIMP7I.js} +2 -2
- package/dist/{chunk-6A6GZRXD.js → chunk-3VXS7O3X.js} +2 -2
- package/dist/{chunk-P3USTYIO.js → chunk-62YHJAWM.js} +2 -2
- package/dist/chunk-62YHJAWM.js.map +1 -0
- package/dist/{chunk-GCYGVWOI.js → chunk-AMT7IJYV.js} +2 -2
- package/dist/{chunk-HYQJJLBC.js → chunk-DHAXUVMR.js} +27 -3
- package/dist/chunk-DHAXUVMR.js.map +1 -0
- package/dist/{chunk-AHNEEFK6.js → chunk-E5GYHN4X.js} +3 -3
- package/dist/{chunk-KU6VHNRV.js → chunk-E5I776YW.js} +6 -2
- package/dist/{chunk-KU6VHNRV.js.map → chunk-E5I776YW.js.map} +1 -1
- package/dist/{chunk-T7ZERP7A.js → chunk-EYW6KXUC.js} +2 -2
- package/dist/{chunk-DNT5PZLF.js → chunk-GZOW6HNN.js} +4 -3
- package/dist/{chunk-DNT5PZLF.js.map → chunk-GZOW6HNN.js.map} +1 -1
- package/dist/{chunk-SAJDNO43.js → chunk-IGMD6S76.js} +3 -3
- package/dist/{chunk-EZFQO77P.js → chunk-IPYV7BLH.js} +2 -2
- package/dist/{chunk-QAZLQYSD.js → chunk-JCHJYBDG.js} +2 -2
- package/dist/{chunk-QAZLQYSD.js.map → chunk-JCHJYBDG.js.map} +1 -1
- package/dist/{chunk-TNVO3EVF.js → chunk-KT3TF2LT.js} +5 -3
- package/dist/chunk-KT3TF2LT.js.map +1 -0
- package/dist/{chunk-7JS2SPRW.js → chunk-LKRXLWCC.js} +3 -3
- package/dist/{chunk-5RC7WAHH.js → chunk-LY6L3DMB.js} +13 -9
- package/dist/chunk-LY6L3DMB.js.map +1 -0
- package/dist/{chunk-EWTSQTVR.js → chunk-NI67M453.js} +6 -5
- package/dist/chunk-NI67M453.js.map +1 -0
- package/dist/{chunk-CMLIWUBW.js → chunk-QPCHABOZ.js} +24 -1
- package/dist/chunk-QPCHABOZ.js.map +1 -0
- package/dist/{chunk-WTGIW7LX.js → chunk-SAXALTRL.js} +2 -2
- package/dist/{chunk-CSLBRJ7N.js → chunk-SOQIWXFO.js} +9 -9
- package/dist/chunk-SOQIWXFO.js.map +1 -0
- package/dist/{chunk-TQXB2OHP.js → chunk-TLPFSA55.js} +3 -3
- package/dist/{chunk-KUFDUXYB.js → chunk-U6ODZJCH.js} +2 -2
- package/dist/{chunk-3PGY4UL4.js → chunk-YKQA4NPM.js} +37 -7
- package/dist/chunk-YKQA4NPM.js.map +1 -0
- package/dist/{chunk-XMVPNCYM.js → chunk-YQGVO3ZU.js} +3 -3
- package/dist/{chunk-OJFE5PK6.js → chunk-ZZO5MRMV.js} +2 -2
- package/dist/data-display/Chip.js +3 -3
- package/dist/data-display/DataViews.js +13 -13
- package/dist/feedback/StackedModal.js +3 -3
- package/dist/layout/SettingCard.js +10 -10
- package/dist/native/data-display/Chip.js +20 -1
- package/dist/native/data-display/Chip.js.map +1 -1
- package/dist/navigation/Tabs.js +1 -1
- package/dist/types/components/data-display/Chip/Chip.base.d.ts +5 -1
- package/dist/types/components/data-display/Chip/Chip.base.d.ts.map +1 -1
- package/dist/types/components/data-display/Chip/Chip.d.ts.map +1 -1
- package/dist/types/components/data-display/Chip/Chip.metrics.d.ts +4 -0
- package/dist/types/components/data-display/Chip/Chip.metrics.d.ts.map +1 -1
- package/dist/types/components/data-display/Chip/Chip.styles.d.ts +2 -7
- package/dist/types/components/data-display/Chip/Chip.styles.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/DataViewsGrid.d.ts +7 -0
- package/dist/types/components/data-display/DataViews/DataViewsGrid.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/DataViewsTableBase.d.ts +2 -0
- package/dist/types/components/data-display/DataViews/DataViewsTableBase.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-grid-parts.d.ts +2 -0
- package/dist/types/components/data-display/DataViews/data-views-grid-parts.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-overflow-costs.d.ts +6 -2
- package/dist/types/components/data-display/DataViews/data-views-overflow-costs.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-overflow.d.ts +1 -1
- package/dist/types/components/data-display/DataViews/data-views-overflow.d.ts.map +1 -1
- package/dist/types/components/feedback/StackedModal/StackedModal.d.ts.map +1 -1
- package/dist/types/components/feedback/StackedModal/StackedModal.styles.d.ts +2 -1
- package/dist/types/components/feedback/StackedModal/StackedModal.styles.d.ts.map +1 -1
- package/dist/types/components/feedback/StackedModal/StackedModal.types.d.ts +17 -0
- package/dist/types/components/feedback/StackedModal/StackedModal.types.d.ts.map +1 -1
- package/dist/types/components/feedback/StackedModal/index.d.ts +1 -1
- package/dist/types/components/feedback/StackedModal/index.d.ts.map +1 -1
- package/dist/types/components/navigation/Tabs/Tabs.d.ts.map +1 -1
- package/dist/types/components/navigation/Tabs/Tabs.types.d.ts +12 -0
- package/dist/types/components/navigation/Tabs/Tabs.types.d.ts.map +1 -1
- package/dist/types/components/navigation/Tabs/index.d.ts +1 -1
- package/dist/types/components/navigation/Tabs/index.d.ts.map +1 -1
- package/dist/types-native/components/data-display/Chip/Chip.base.d.ts +5 -1
- package/dist/types-native/components/data-display/Chip/Chip.base.d.ts.map +1 -1
- package/dist/types-native/components/data-display/Chip/Chip.look.native.d.ts.map +1 -1
- package/dist/types-native/components/data-display/Chip/Chip.metrics.d.ts +4 -0
- package/dist/types-native/components/data-display/Chip/Chip.metrics.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/data-display/Chip/Chip.base.ts +5 -1
- package/src/components/data-display/Chip/Chip.look.native.ts +22 -1
- package/src/components/data-display/Chip/Chip.metrics.ts +5 -0
- package/src/components/data-display/Chip/Chip.styles.tsx +38 -1
- package/src/components/data-display/Chip/Chip.tsx +6 -2
- package/src/components/data-display/Chip/chip.md +2 -2
- package/src/components/data-display/DataViews/DataViewsGrid.tsx +7 -0
- package/src/components/data-display/DataViews/DataViewsTableBase.tsx +2 -0
- package/src/components/data-display/DataViews/RESPONSIVE-BEHAVIOUR.md +10 -0
- package/src/components/data-display/DataViews/data-views-grid-parts.tsx +11 -1
- package/src/components/data-display/DataViews/data-views-overflow-costs.ts +8 -3
- package/src/components/data-display/DataViews/data-views-overflow.ts +6 -4
- package/src/components/feedback/StackedModal/StackedModal.md +1 -0
- package/src/components/feedback/StackedModal/StackedModal.styles.ts +53 -6
- package/src/components/feedback/StackedModal/StackedModal.tsx +2 -1
- package/src/components/feedback/StackedModal/StackedModal.types.ts +17 -0
- package/src/components/feedback/StackedModal/index.ts +1 -1
- package/src/components/navigation/Tabs/Tabs.md +1 -0
- package/src/components/navigation/Tabs/Tabs.tsx +30 -1
- package/src/components/navigation/Tabs/Tabs.types.ts +14 -0
- package/src/components/navigation/Tabs/index.ts +1 -1
- package/dist/chunk-3PGY4UL4.js.map +0 -1
- package/dist/chunk-5RC7WAHH.js.map +0 -1
- package/dist/chunk-CMLIWUBW.js.map +0 -1
- package/dist/chunk-CSLBRJ7N.js.map +0 -1
- package/dist/chunk-EWTSQTVR.js.map +0 -1
- package/dist/chunk-HYQJJLBC.js.map +0 -1
- package/dist/chunk-P3USTYIO.js.map +0 -1
- package/dist/chunk-TNVO3EVF.js.map +0 -1
- /package/dist/{chunk-AAXLQFC7.js.map → chunk-3FIIMP7I.js.map} +0 -0
- /package/dist/{chunk-6A6GZRXD.js.map → chunk-3VXS7O3X.js.map} +0 -0
- /package/dist/{chunk-GCYGVWOI.js.map → chunk-AMT7IJYV.js.map} +0 -0
- /package/dist/{chunk-AHNEEFK6.js.map → chunk-E5GYHN4X.js.map} +0 -0
- /package/dist/{chunk-T7ZERP7A.js.map → chunk-EYW6KXUC.js.map} +0 -0
- /package/dist/{chunk-SAJDNO43.js.map → chunk-IGMD6S76.js.map} +0 -0
- /package/dist/{chunk-EZFQO77P.js.map → chunk-IPYV7BLH.js.map} +0 -0
- /package/dist/{chunk-7JS2SPRW.js.map → chunk-LKRXLWCC.js.map} +0 -0
- /package/dist/{chunk-WTGIW7LX.js.map → chunk-SAXALTRL.js.map} +0 -0
- /package/dist/{chunk-TQXB2OHP.js.map → chunk-TLPFSA55.js.map} +0 -0
- /package/dist/{chunk-KUFDUXYB.js.map → chunk-U6ODZJCH.js.map} +0 -0
- /package/dist/{chunk-XMVPNCYM.js.map → chunk-YQGVO3ZU.js.map} +0 -0
- /package/dist/{chunk-OJFE5PK6.js.map → chunk-ZZO5MRMV.js.map} +0 -0
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-Y2CCXB7R.js";
|
|
4
4
|
import {
|
|
5
5
|
InlineFilterControls
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-TLPFSA55.js";
|
|
7
7
|
import {
|
|
8
8
|
GridHeaderRow
|
|
9
9
|
} from "./chunk-X3AFXHY5.js";
|
|
@@ -13,17 +13,17 @@ import {
|
|
|
13
13
|
import {
|
|
14
14
|
FilterDialog,
|
|
15
15
|
GridFilterPanel
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-E5GYHN4X.js";
|
|
17
17
|
import {
|
|
18
18
|
DataViewsPagination
|
|
19
19
|
} from "./chunk-XZFTRGRW.js";
|
|
20
20
|
import {
|
|
21
21
|
useFilterOverflow
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-SOQIWXFO.js";
|
|
23
23
|
import {
|
|
24
24
|
toOverflowFields,
|
|
25
25
|
toggleQuick
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-AMT7IJYV.js";
|
|
27
27
|
import {
|
|
28
28
|
allOnPageSelected,
|
|
29
29
|
resolveSelectionExtra
|
|
@@ -76,7 +76,8 @@ function useGridShellFilters({
|
|
|
76
76
|
testIdPrefix,
|
|
77
77
|
alwaysShowSearch,
|
|
78
78
|
hasExport,
|
|
79
|
-
quickFilters
|
|
79
|
+
quickFilters,
|
|
80
|
+
showCounter
|
|
80
81
|
}) {
|
|
81
82
|
const { state } = c;
|
|
82
83
|
const [openControls, setOpenControls] = useState(0);
|
|
@@ -85,7 +86,8 @@ function useGridShellFilters({
|
|
|
85
86
|
state.pills,
|
|
86
87
|
c.ranges,
|
|
87
88
|
openControls > 0,
|
|
88
|
-
hasExport
|
|
89
|
+
hasExport,
|
|
90
|
+
showCounter
|
|
89
91
|
);
|
|
90
92
|
const showInline = inlineFilters;
|
|
91
93
|
const useModal = false;
|
|
@@ -111,6 +113,7 @@ function useGridShellFilters({
|
|
|
111
113
|
inlineVisible,
|
|
112
114
|
filterProps,
|
|
113
115
|
split,
|
|
116
|
+
counterHidden: !showCounter || showInline && split.counterHidden,
|
|
114
117
|
onControlOpenChange: (open) => setOpenControls((count) => Math.max(0, count + (open ? 1 : -1)))
|
|
115
118
|
};
|
|
116
119
|
}
|
|
@@ -158,7 +161,7 @@ function ShellStack({
|
|
|
158
161
|
allOnPageSelected: allOnPageSelected(c, props.getRowId),
|
|
159
162
|
toolbarRightSlot: props.toolbarRightSlot,
|
|
160
163
|
compactControls: showInline && split.compactControls,
|
|
161
|
-
counterHidden:
|
|
164
|
+
counterHidden: filters.counterHidden,
|
|
162
165
|
showInline,
|
|
163
166
|
sticky: props.stickyToolbar === true
|
|
164
167
|
}
|
|
@@ -225,7 +228,8 @@ function GridShell(props) {
|
|
|
225
228
|
testIdPrefix,
|
|
226
229
|
alwaysShowSearch,
|
|
227
230
|
hasExport: props.exportConfig !== void 0,
|
|
228
|
-
quickFilters: props.quickFilters ?? []
|
|
231
|
+
quickFilters: props.quickFilters ?? [],
|
|
232
|
+
showCounter: props.showCounter !== false
|
|
229
233
|
});
|
|
230
234
|
return /* @__PURE__ */ jsxs(
|
|
231
235
|
DataViewsLayoutProvider,
|
|
@@ -247,4 +251,4 @@ function GridShell(props) {
|
|
|
247
251
|
export {
|
|
248
252
|
GridShell
|
|
249
253
|
};
|
|
250
|
-
//# sourceMappingURL=chunk-
|
|
254
|
+
//# sourceMappingURL=chunk-LY6L3DMB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/DataViews/data-views-grid-parts.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { TableFilter } from \"../../layout/TableFilter\";\nimport { Stack } from \"../../../mui/Stack\";\n\nimport {\n DataViewsLayoutProvider,\n useDataViewsLayout,\n type DataViewsLayout,\n} from \"./data-views-layout-context\";\nimport { FilterDialog, GridFilterPanel } from \"./data-views-filter-panel\";\nimport { GridMain } from \"./data-views-grid-bodies\";\nimport type { ListGroupConfig } from \"./list-card-rails\";\nimport { InlineFilterControls } from \"./data-views-inline-bar\";\nimport { toOverflowFields, useFilterOverflow, type OverflowSplit } from \"./data-views-overflow\";\nimport { GridHeaderRow } from \"./data-views-header-row\";\nimport { allOnPageSelected, resolveSelectionExtra, type SelectionExtraRender } from \"./data-views-selection-extra\";\nimport { ShellToolbar } from \"./data-views-shell-toolbar\";\nimport type { DisplayPanelView } from \"./data-views-display-panel\";\nimport type { DataViewExport } from \"./data-views-export\";\nimport { useDataViewsCopy } from \"./data-views-copy-context\";\nimport { ShellEmpty } from \"./data-views-empty\";\nimport { DataViewsPagination } from \"./data-views-pagination\";\nimport type { BoardConfig } from \"./DataViewsBoard\";\nimport { type ScopeConfig } from \"./data-views-scopes\";\nimport { ScopeTabsSlot } from \"./data-views-scope-tabs\";\nimport { SHELL_PROPS, useStickyBarTop } from \"./data-views-sticky-head\";\nimport { togglePillValues } from \"./data-views-grid-helpers\";\nimport { toggleQuick } from \"./data-views-overflow-fields\";\nimport type {\n DataViewCardSelection,\n FilterFieldConfig,\n QuickFilterConfig,\n RangeFieldConfig,\n RangeValue,\n RowAction,\n} from \"./data-views-types\";\nimport type { DataViewRowDetail } from \"./data-views-row-detail\";\nimport type { DataViewsController } from \"./use-data-views-state\";\n\n/* ── Layout ⇄ view-state mirror ──────────────────────────────────────────── */\n\n/**\n * Mirrors the LIVE layout back into the view state, so saving a view captures\n * the layout the user is actually looking at.\n *\n * A component rather than a callback prop because only something INSIDE the\n * provider can read the layout, and only the controller can write the state.\n * The `stored !== layout` guard is what makes it idempotent: `c` is rebuilt on\n * every render, so an unguarded effect here would patch → re-render → patch.\n *\n * It re-fires when `stored` changes too, which is the case that matters after\n * applying a saved view: `appliedState` REPLACES the state, so a view saved\n * before layouts were captured clears `state.layout`, and the mirror puts the\n * current one back rather than leaving the next save with nothing to store.\n */\nfunction LayoutStateSync<T extends Record<string, unknown>>({\n c,\n}: {\n c: DataViewsController<T>;\n}): null {\n const { layout } = useDataViewsLayout();\n const stored = c.state.layout;\n useEffect(() => {\n if (stored !== layout) c.patch({ layout });\n // `c` is intentionally out of the deps — see the guard above.\n }, [layout, stored]);\n return null;\n}\n\n/* ── Shell (composes toolbar + body + panel) ─────────────────────────────── */\n\n/** The shared filter-surface props consumed by the inline bar, panel, and modal. */\ninterface FilterSurfaceProps<T extends Record<string, unknown>> {\n testIdPrefix: string;\n search: string;\n fields: FilterFieldConfig<T>[];\n rangeFields: RangeFieldConfig<T>[];\n pills: Record<string, string[]>;\n ranges: Record<string, RangeValue>;\n onSearchChange: (value: string) => void;\n onTogglePill: (fieldId: string, value: string, checked: boolean) => void;\n onChangeRange: (fieldId: string, range: RangeValue) => void;\n onClearField: (fieldId: string) => void;\n onClearAll: () => void;\n /** Press a quick chip (its field becomes `[value]`), or release the pressed one. */\n onToggleQuick: (quick: QuickFilterConfig) => void;\n}\n\n/**\n * Derives the responsive filter state (which surface to show at this width) and\n * the filter-mutation handlers from the controller — pulled out of `GridShell`\n * so the component body stays under the size/complexity budget.\n */\n/** Grouped rather than positional: the list had grown past readability. */\ninterface GridShellFiltersArgs<T extends Record<string, unknown>> {\n c: DataViewsController<T>;\n inlineFilters: boolean;\n fields: FilterFieldConfig<T>[];\n rangeFields: RangeFieldConfig<T>[];\n testIdPrefix: string;\n alwaysShowSearch: boolean;\n /** Is \"Exportar\" on the bar? Half the right cluster's cost when it is not. */\n hasExport: boolean;\n quickFilters: QuickFilterConfig[];\n /** Is the \"N de N\" counter on the bar? Priced at 0 when it is not. */\n showCounter: boolean;\n}\n\nfunction useGridShellFilters<T extends Record<string, unknown>>({\n c,\n inlineFilters,\n fields,\n rangeFields,\n testIdPrefix,\n alwaysShowSearch,\n hasExport,\n quickFilters,\n showCounter,\n}: GridShellFiltersArgs<T>): {\n showInline: boolean;\n useModal: boolean;\n inlineVisible: boolean;\n filterProps: FilterSurfaceProps<T>;\n split: OverflowSplit<T>;\n /** The counter is off: the host turned it off, or the ladder shed it. */\n counterHidden: boolean;\n onControlOpenChange: (open: boolean) => void;\n} {\n const { state } = c;\n // How many filter controls are open. A COUNT, not a flag: closing one popover\n // by opening another overlaps, and a boolean would unfreeze mid-handover.\n const [openControls, setOpenControls] = useState(0);\n // ONE measurement for the whole shell: the filter row decides which controls\n // it can keep, and the TOOLBAR needs the same answer to drop its labels.\n // Measuring twice would let the two disagree at the crossover width.\n const split = useFilterOverflow(\n toOverflowFields(fields, rangeFields, quickFilters),\n state.pills,\n c.ranges,\n openControls > 0,\n hasExport,\n showCounter,\n );\n // THE BAR RENDERS AT EVERY WIDTH. It used to be swapped for a full-screen\n // filter MODAL below `lg`, which was the responsive strategy before the\n // measured ladder existed — and the two now do the same job, badly together:\n // the modal took the bar away at 1199px, and with it the very degradation\n // (labels off, search collapsed, filters into \"Mais\") that exists to make a\n // narrow bar work. So a 900px window got no bar and no ladder, and the\n // operator lost the search entirely rather than gaining a compact one.\n //\n // The ladder is measured, so it already covers every width the modal did.\n const showInline = inlineFilters;\n const useModal = false;\n const inlineVisible =\n showInline &&\n (alwaysShowSearch ||\n fields.length > 0 ||\n rangeFields.length > 0 ||\n quickFilters.length > 0 ||\n state.search !== \"\");\n const filterProps: FilterSurfaceProps<T> = {\n testIdPrefix,\n search: state.search,\n fields,\n rangeFields,\n pills: state.pills,\n ranges: c.ranges,\n onSearchChange: (value) => c.patch({ search: value }),\n // Updater, never the render's `state` — see {@link DataViewStatePatch}.\n onTogglePill: (fieldId, value, checked) =>\n c.patch(({ pills }) => ({ pills: { ...pills, [fieldId]: togglePillValues(pills[fieldId], value, checked) } })),\n onChangeRange: (fieldId, range) => c.patch({ ranges: { ...c.ranges, [fieldId]: range } }),\n onClearField: (fieldId) => c.patch({ pills: { ...state.pills, [fieldId]: [] } }),\n onClearAll: () => c.patch({ search: \"\", pills: {}, ranges: {} }),\n onToggleQuick: (quick) => c.patch(({ pills }) => ({ pills: toggleQuick(pills, quick) })),\n };\n return {\n showInline,\n useModal,\n inlineVisible,\n filterProps,\n split,\n counterHidden: !showCounter || (showInline && split.counterHidden),\n onControlOpenChange: (open) =>\n setOpenControls((count) => Math.max(0, count + (open ? 1 : -1))),\n };\n}\n\ninterface GridShellProps<T extends Record<string, unknown>> {\n c: DataViewsController<T>;\n rows: T[];\n fields: FilterFieldConfig<T>[];\n rangeFields: RangeFieldConfig<T>[];\n getRowId: (row: T) => string | number;\n testIdPrefix: string;\n dataTestId?: string;\n emptyState?: React.ReactNode;\n toolbarRightSlot?: React.ReactNode;\n rowActions?: RowAction<T>[];\n bulkActions?: (selectedRows: T[], clearSelection: () => void) => React.ReactNode;\n /** A widening control beside the selection count — see `resolveSelectionExtra`. */\n selectionExtra?: SelectionExtraRender<T>;\n /** Opt-in \"Grade\" (cards) layout: renders each row as an entity-supplied card.\n * Omit ⇒ table only (no layout toggle). */\n renderCard?: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n /**\n * Opt-in \"Quadro\" (board) layout. Needs `renderCard` too — the board reuses\n * the entity's card, so a board config without one simply offers no board\n * rather than failing: that is a config gap, not a runtime error.\n */\n board?: BoardConfig<T>;\n /** Opt-in \"Lista\" layout: one full-width, entity-rendered row per record. */\n renderListRow?: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n /** The Lista's shared columns, so its rows line up by construction. */\n listGroup?: ListGroupConfig<T>;\n /** Opt-in expandable rows, drawn by the table layout only. */\n rowDetail?: DataViewRowDetail<T>;\n /** Row selection, on by default. False ⇒ no checkboxes in any layout, no select-all. */\n selectable?: boolean;\n /** The page-level partition rendered as tabs under the toolbar. */\n scopes?: ScopeConfig[];\n /**\n * The row field the scopes partition by. Compared against the board's\n * `groupBy` so the two are not shown as the same partition twice.\n */\n scopeFieldId?: string;\n /** Per-sort-field value kind, so directions read in the column's own terms. */\n sortKinds?: Record<string, string>;\n /** The saved-view chrome bracketing the Exibir panel. */\n displayView?: DisplayPanelView;\n /** Injected export — the host re-queries; the grid never fetches. */\n exportConfig?: DataViewExport;\n /** Page title in the grid's own header row, above the scopes + toolbar. */\n title?: string;\n /** Primary page actions rendered at the header row's right. */\n headerActions?: React.ReactNode;\n /** Which layout to show first when the user has expressed no preference (default \"table\"). */\n defaultLayout?: DataViewsLayout;\n /** Pin to `defaultLayout`, ignoring the remembered preference (stories/docs). */\n ignoreStoredLayout?: boolean;\n /**\n * Opt into the responsive inline filter UX: a collapsible filter row below the\n * toolbar on wide screens and a modal on narrow ones. When false (default),\n * keep the classic slide-in filter panel opened by the \"Filtros\" button.\n */\n inlineFilters?: boolean;\n /**\n * Keep the inline search box on screen even with no filter fields and no\n * active search. Without it a grid whose only filter IS the search (`fields`\n * empty) can never OFFER one: the row renders only once a search exists, so\n * the operator would have to hand-edit the URL to start one. Default false —\n * every grid that ships filter fields already shows the row.\n */\n alwaysShowSearch?: boolean;\n /** One-click toggle chips at the head of the bar — see `QuickFilterConfig`. */\n quickFilters?: QuickFilterConfig[];\n /** Pin the toolbar and the table header while the page scrolls. */\n stickyToolbar?: boolean;\n /** Hide the \"N de N\" counter — see `DataViewsGrid`. */\n showCounter?: boolean;\n}\n\n/** The scrollable content region: scope tabs, toolbar, filter bar, body, pager. */\nfunction ShellStack<T extends Record<string, unknown>>({\n props,\n filters,\n}: {\n props: GridShellProps<T>;\n filters: ReturnType<typeof useGridShellFilters<T>>;\n}): React.JSX.Element {\n const copy = useDataViewsCopy();\n const { c, testIdPrefix, dataTestId, scopes = [], emptyState, inlineFilters = false } = props;\n const { showInline, useModal, inlineVisible, filterProps, split, onControlOpenChange } = filters;\n const shellRef = useRef<HTMLDivElement>(null);\n useStickyBarTop(shellRef, props.stickyToolbar === true);\n const body = <ShellEmpty c={c} emptyState={emptyState} testIdPrefix={testIdPrefix} />;\n return (\n <TableFilter\n copy={copy.tableFilter} open={c.filterOpen} onOpenChange={c.setFilterOpen}\n hasActiveFilters={c.activeFilterCount > 0}\n >\n <Stack ref={shellRef} spacing={0} data-testid={dataTestId ? `${dataTestId}-container` : undefined} {...(props.stickyToolbar ? SHELL_PROPS : {})}>\n <GridHeaderRow title={props.title} headerActions={props.headerActions} testIdPrefix={testIdPrefix} />\n <ShellToolbar\n c={c}\n rows={props.rows}\n sortKinds={props.sortKinds}\n displayView={props.displayView}\n exportConfig={props.exportConfig}\n filterControls={\n inlineVisible ? (\n <InlineFilterControls\n {...filterProps} split={split} activeFilterCount={c.activeFilterCount}\n onControlOpenChange={onControlOpenChange}\n />\n ) : undefined\n }\n barRef={split.barRef}\n testIdPrefix={testIdPrefix}\n rowActions={props.rowActions}\n bulkActions={props.bulkActions}\n selectionExtra={resolveSelectionExtra(props)}\n allOnPageSelected={allOnPageSelected(c, props.getRowId)}\n toolbarRightSlot={props.toolbarRightSlot}\n compactControls={showInline && split.compactControls}\n counterHidden={filters.counterHidden}\n showInline={showInline}\n sticky={props.stickyToolbar === true}\n />\n <ScopeTabsSlot\n scopes={scopes} scopeFieldId={props.scopeFieldId} board={props.board}\n value={c.scope} onChange={c.setScope} counts={c.scopeCounts}\n testIdPrefix={testIdPrefix}\n />\n <TableFilter.Layout>\n <TableFilter.Main>\n <GridMain\n c={c}\n getRowId={props.getRowId}\n renderCard={props.renderCard}\n renderListRow={props.renderListRow}\n listGroup={props.listGroup}\n board={props.board}\n rowDetail={props.rowDetail} selectable={props.selectable !== false}\n dataTestId={dataTestId}\n testIdPrefix={testIdPrefix}\n emptyState={body}\n stickyHead={props.stickyToolbar === true}\n />\n <DataViewsPagination c={c} testIdPrefix={testIdPrefix} />\n </TableFilter.Main>\n {inlineFilters ? null : <GridFilterPanel {...filterProps} />}\n </TableFilter.Layout>\n {useModal && <FilterDialog open={c.filterOpen} onClose={() => c.setFilterOpen(false)} {...filterProps} />}\n </Stack>\n </TableFilter>\n );\n}\n\nexport function GridShell<T extends Record<string, unknown>>(props: GridShellProps<T>): React.JSX.Element {\n const {\n c,\n fields,\n rangeFields,\n testIdPrefix,\n renderCard,\n renderListRow,\n board,\n defaultLayout,\n ignoreStoredLayout,\n inlineFilters = false,\n alwaysShowSearch = false,\n } = props;\n const filters = useGridShellFilters({\n c,\n inlineFilters,\n fields,\n rangeFields,\n testIdPrefix,\n alwaysShowSearch,\n hasExport: props.exportConfig !== undefined,\n quickFilters: props.quickFilters ?? [],\n showCounter: props.showCounter !== false,\n });\n return (\n <DataViewsLayoutProvider\n canUseCards={Boolean(renderCard)}\n canUseList={Boolean(renderListRow)}\n // The board reuses the entity's card, so it needs BOTH — a `board` with no\n // `renderCard` offers no board rather than throwing.\n canUseBoard={Boolean(board && renderCard)}\n defaultLayout={defaultLayout}\n ignoreStoredLayout={ignoreStoredLayout}\n viewLayout={c.state.layout}\n >\n <LayoutStateSync c={c} />\n <ShellStack props={props} filters={filters} />\n </DataViewsLayoutProvider>\n );\n}\n"],"mappings":"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","names":["default"]}
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
chipStyles,
|
|
4
4
|
iconWithTestId,
|
|
5
5
|
makeKeyDownHandler
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-DHAXUVMR.js";
|
|
7
7
|
import {
|
|
8
8
|
chipMuiSize
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-E5I776YW.js";
|
|
10
10
|
import {
|
|
11
11
|
chipRole,
|
|
12
12
|
isClickable,
|
|
@@ -22,6 +22,7 @@ var muiColorFor = (color) => {
|
|
|
22
22
|
if (color === "danger") return "error";
|
|
23
23
|
return color === "neutral" ? "default" : color;
|
|
24
24
|
};
|
|
25
|
+
var muiVariantFor = (variant) => variant === "soft" ? "filled" : variant;
|
|
25
26
|
var Chip = forwardRef(({
|
|
26
27
|
label,
|
|
27
28
|
variant = "filled",
|
|
@@ -51,7 +52,7 @@ var Chip = forwardRef(({
|
|
|
51
52
|
{
|
|
52
53
|
ref,
|
|
53
54
|
label: /* @__PURE__ */ jsx("span", { "data-testid": testId("label"), children: label }),
|
|
54
|
-
variant,
|
|
55
|
+
variant: muiVariantFor(variant),
|
|
55
56
|
size: chipMuiSize(size),
|
|
56
57
|
color: muiColorFor(color),
|
|
57
58
|
avatar: avatarFor(avatar, avatarSrc),
|
|
@@ -66,7 +67,7 @@ var Chip = forwardRef(({
|
|
|
66
67
|
role: chipRole(selectable, onClick),
|
|
67
68
|
"aria-selected": selectable ? selected : void 0,
|
|
68
69
|
"data-testid": chipId || "chip",
|
|
69
|
-
sx: chipStyles({ variant, selected, clickable, disabled }),
|
|
70
|
+
sx: chipStyles({ variant, color, selected, clickable, disabled }),
|
|
70
71
|
...props
|
|
71
72
|
}
|
|
72
73
|
);
|
|
@@ -76,4 +77,4 @@ Chip.displayName = "Chip";
|
|
|
76
77
|
export {
|
|
77
78
|
Chip
|
|
78
79
|
};
|
|
79
|
-
//# sourceMappingURL=chunk-
|
|
80
|
+
//# sourceMappingURL=chunk-NI67M453.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/Chip/Chip.tsx"],"sourcesContent":["import CancelIcon from '@mui/icons-material/Cancel';\nimport MuiChip from '@mui/material/Chip/index.js';\nimport { forwardRef } from 'react';\n\nimport { chipRole, isClickable, makeTestId } from './Chip.helpers';\nimport { chipMuiSize } from './Chip.metrics';\nimport {\n avatarFor,\n chipStyles,\n iconWithTestId,\n makeKeyDownHandler,\n} from './Chip.styles';\nimport type { ChipProps } from './Chip.types';\n\ntype MuiChipColor =\n | 'primary'\n | 'secondary'\n | 'error'\n | 'info'\n | 'success'\n | 'warning'\n | 'default';\n\n/**\n * `danger` and `neutral` are ours; the rest are MUI's own names already.\n *\n * The same boundary translation `Button` performs, and it must stay a\n * translation rather than a cast: a cast is what let `danger` through untouched\n * and had MUI silently fall back to grey.\n *\n * `neutral` maps to `default`, not to `inherit` as it does on a button. A chip's\n * unaccented state is a real palette entry with its own fill; `inherit` would\n * take the surrounding text colour and paint a chip that reads as disabled.\n */\nconst muiColorFor = (color: NonNullable<ChipProps['color']>): MuiChipColor => {\n if (color === 'danger') return 'error';\n return color === 'neutral' ? 'default' : color;\n};\n\n/** `soft` is ours: MUI has two variants, so it paints as `filled` and `chipStyles` tints it. */\nconst muiVariantFor = (variant: NonNullable<ChipProps['variant']>): 'filled' | 'outlined' =>\n variant === 'soft' ? 'filled' : variant;\n\nexport const Chip = forwardRef<HTMLDivElement, ChipProps>(({\n label,\n variant = 'filled',\n size = 'md',\n color = 'primary',\n avatarSrc,\n avatar,\n icon,\n selected,\n selectable,\n deletable,\n disabled,\n onClick,\n onDelete,\n className,\n dataTestId,\n // React Native's spelling of the same id; it names the component on both\n // sides and must not reach the DOM as an attribute.\n testID,\n ...props\n}, ref) => {\n const chipId = testID ?? dataTestId;\n const testId = makeTestId(chipId);\n const clickable = isClickable(disabled, onClick, selectable);\n\n return (\n <MuiChip\n ref={ref}\n label={<span data-testid={testId('label')}>{label}</span>}\n variant={muiVariantFor(variant)}\n size={chipMuiSize(size)}\n color={muiColorFor(color)}\n avatar={avatarFor(avatar, avatarSrc)}\n icon={iconWithTestId(icon, testId('icon'))}\n onDelete={deletable ? onDelete : undefined}\n deleteIcon={deletable ? <CancelIcon data-testid={testId('delete')} /> : undefined}\n disabled={disabled}\n clickable={clickable}\n onClick={clickable ? onClick : undefined}\n onKeyDown={makeKeyDownHandler({ disabled, deletable, selectable, onClick, onDelete })}\n className={className}\n role={chipRole(selectable, onClick)}\n aria-selected={selectable ? selected : undefined}\n data-testid={chipId || 'chip'}\n sx={chipStyles({ variant, color, selected, clickable, disabled })}\n {...props}\n />\n );\n});\n\nChip.displayName = 'Chip';\n"],"mappings":";;;;;;;;;;;;;;;;AAAA,OAAO,gBAAgB;AACvB,OAAO,aAAa;AACpB,SAAS,kBAAkB;AAqEd;AArCb,IAAM,cAAc,CAAC,UAAyD;AAC5E,MAAI,UAAU,SAAU,QAAO;AAC/B,SAAO,UAAU,YAAY,YAAY;AAC3C;AAGA,IAAM,gBAAgB,CAAC,YACrB,YAAY,SAAS,WAAW;AAE3B,IAAM,OAAO,WAAsC,CAAC;AAAA,EACzD;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA,EAGA;AAAA,EACA,GAAG;AACL,GAAG,QAAQ;AACT,QAAM,SAAS,UAAU;AACzB,QAAM,SAAS,WAAW,MAAM;AAChC,QAAM,YAAY,YAAY,UAAU,SAAS,UAAU;AAE3D,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,OAAO,oBAAC,UAAK,eAAa,OAAO,OAAO,GAAI,iBAAM;AAAA,MAClD,SAAS,cAAc,OAAO;AAAA,MAC9B,MAAM,YAAY,IAAI;AAAA,MACtB,OAAO,YAAY,KAAK;AAAA,MACxB,QAAQ,UAAU,QAAQ,SAAS;AAAA,MACnC,MAAM,eAAe,MAAM,OAAO,MAAM,CAAC;AAAA,MACzC,UAAU,YAAY,WAAW;AAAA,MACjC,YAAY,YAAY,oBAAC,cAAW,eAAa,OAAO,QAAQ,GAAG,IAAK;AAAA,MACxE;AAAA,MACA;AAAA,MACA,SAAS,YAAY,UAAU;AAAA,MAC/B,WAAW,mBAAmB,EAAE,UAAU,WAAW,YAAY,SAAS,SAAS,CAAC;AAAA,MACpF;AAAA,MACA,MAAM,SAAS,YAAY,OAAO;AAAA,MAClC,iBAAe,aAAa,WAAW;AAAA,MACvC,eAAa,UAAU;AAAA,MACvB,IAAI,WAAW,EAAE,SAAS,OAAO,UAAU,WAAW,SAAS,CAAC;AAAA,MAC/D,GAAG;AAAA;AAAA,EACN;AAEJ,CAAC;AAED,KAAK,cAAc;","names":[]}
|
|
@@ -52,6 +52,28 @@ var BadgeWrapper = styled(Badge)(({ theme }) => ({
|
|
|
52
52
|
padding: 0
|
|
53
53
|
}
|
|
54
54
|
}));
|
|
55
|
+
var CountPill = styled("span", {
|
|
56
|
+
shouldForwardProp: (prop) => prop !== "tone"
|
|
57
|
+
})(({ theme, tone }) => {
|
|
58
|
+
const look = {
|
|
59
|
+
neutral: { backgroundColor: theme.palette.action.selected, color: theme.palette.text.secondary },
|
|
60
|
+
warning: { backgroundColor: alpha(theme.palette.warning.main, 0.16), color: theme.palette.warning.dark },
|
|
61
|
+
danger: { backgroundColor: theme.palette.error.main, color: theme.palette.error.contrastText }
|
|
62
|
+
}[tone];
|
|
63
|
+
return {
|
|
64
|
+
display: "inline-flex",
|
|
65
|
+
alignItems: "center",
|
|
66
|
+
justifyContent: "center",
|
|
67
|
+
height: rem(theme, 20),
|
|
68
|
+
minWidth: rem(theme, 20),
|
|
69
|
+
padding: theme.spacing(0, 0.875),
|
|
70
|
+
borderRadius: rem(theme, 999),
|
|
71
|
+
fontSize: rem(theme, 11.5),
|
|
72
|
+
fontWeight: 600,
|
|
73
|
+
lineHeight: 1,
|
|
74
|
+
...look
|
|
75
|
+
};
|
|
76
|
+
});
|
|
55
77
|
var TABS_DEFAULTS = {
|
|
56
78
|
variant: "default",
|
|
57
79
|
size: "md",
|
|
@@ -119,6 +141,7 @@ var TabLabel = ({ item, closeTabLabel, onClose }) => {
|
|
|
119
141
|
const content = /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
|
|
120
142
|
item.icon,
|
|
121
143
|
/* @__PURE__ */ jsx("span", { children: item.label }),
|
|
144
|
+
item.count !== void 0 && /* @__PURE__ */ jsx(CountPill, { tone: item.count.tone ?? "neutral", "data-tone": item.count.tone ?? "neutral", children: item.count.value }),
|
|
122
145
|
item.closable && /* @__PURE__ */ jsx(
|
|
123
146
|
CloseButton,
|
|
124
147
|
{
|
|
@@ -250,4 +273,4 @@ Tabs.displayName = "Tabs";
|
|
|
250
273
|
export {
|
|
251
274
|
Tabs
|
|
252
275
|
};
|
|
253
|
-
//# sourceMappingURL=chunk-
|
|
276
|
+
//# sourceMappingURL=chunk-QPCHABOZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/navigation/Tabs/Tabs.tsx"],"sourcesContent":["import Close from '@mui/icons-material/Close';\nimport Badge from '@mui/material/Badge/index.js';\nimport Box from '@mui/material/Box/index.js';\nimport Divider from '@mui/material/Divider/index.js';\nimport MuiTab from '@mui/material/Tab/index.js';\nimport MuiTabs from '@mui/material/Tabs/index.js';\nimport { alpha, styled } from '@mui/material/styles/index.js';\nimport type { Theme } from '@mui/material/styles/index.js';\nimport React from 'react';\n\nimport { CustomTabPanel } from './TabsPanel';\nimport { tabsRootStyles } from './Tabs.styles';\nimport type { TabCount, TabItem, TabsProps } from './Tabs.types';\nimport { rem, sxRem } from '../../../tokens/relative';\n\nconst StyledTabs = styled(MuiTabs, {\n shouldForwardProp: (prop) => !['customVariant', 'size', 'showDividers'].includes(prop as string) })<{ customVariant?: string; size?: string; showDividers?: boolean }>(\n ({ theme, customVariant, size, showDividers }) => ({\n ...tabsRootStyles({ theme, customVariant, size, showDividers }) }),\n);\n\nconst CloseButton = styled(Box)(({ theme }) => ({\n marginLeft: theme.spacing(0.5),\n padding: theme.spacing(0.25),\n width: rem(theme, 20),\n height: rem(theme, 20),\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n borderRadius: '50%',\n color: theme.palette.action.active,\n '&:hover': {\n backgroundColor: alpha(theme.palette.error.main, 0.1),\n color: theme.palette.error.main } }));\n\nconst BadgeWrapper = styled(Badge)(({ theme }) => ({\n '& .MuiBadge-badge': {\n right: rem(theme, -6),\n top: rem(theme, 4),\n fontSize: rem(theme, 12),\n minWidth: rem(theme, 16),\n height: rem(theme, 16),\n padding: 0 } }));\n\n/** A tab's inline count pill, toned by what it asks for. */\nconst CountPill = styled('span', {\n shouldForwardProp: (prop) => prop !== 'tone',\n})<{ tone: NonNullable<TabCount['tone']> }>(({ theme, tone }) => {\n const look = {\n neutral: { backgroundColor: theme.palette.action.selected, color: theme.palette.text.secondary },\n warning: { backgroundColor: alpha(theme.palette.warning.main, 0.16), color: theme.palette.warning.dark },\n danger: { backgroundColor: theme.palette.error.main, color: theme.palette.error.contrastText },\n }[tone];\n return {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n height: rem(theme, 20),\n minWidth: rem(theme, 20),\n padding: theme.spacing(0, 0.875),\n borderRadius: rem(theme, 999),\n fontSize: rem(theme, 11.5),\n fontWeight: 600,\n lineHeight: 1,\n ...look,\n };\n});\n\nconst TABS_DEFAULTS: Partial<TabsProps> = {\n variant: 'default',\n size: 'md',\n color: 'primary',\n fullWidth: false,\n orientation: 'horizontal',\n showDividers: false,\n centered: false,\n scrollable: false,\n scrollButtons: 'auto',\n sticky: false,\n stickyOffset: 0,\n animateContent: false,\n animationDuration: 300,\n persistContent: false,\n disabled: false,\n loading: false };\n\n/**\n * The props this component OWNS and MUI's `Tabs` does not understand (12-86).\n *\n * `rest` below is spread onto the DOM node, so anything left in it that React\n * cannot place on an element is reported — five `does not recognize the … prop`\n * warnings and three `Received false for a non-boolean attribute`, on every\n * render, in the browser console and in every host's jsdom output.\n *\n * An explicit list rather than `Object.keys(TABS_DEFAULTS)`, because the two\n * sets differ in both directions: `items`, `closeTabLabel`, `tabPanelProps` and\n * `loadingComponent` have no default and still must not reach the DOM, while\n * `orientation`, `centered` and `indicatorColor` are real MUI props that must.\n * An omission rather than more destructuring, so a prop added to `TabsProps`\n * costs a line here instead of an unused `_name` binding.\n *\n * Deliberately NOT here: `onFocus` and `onBlur`. They are ordinary DOM handlers\n * that reach the element through `rest` and nowhere else, so listing them would\n * silently stop them working.\n */\nconst OWN_PROPS = new Set<string>([\n 'items',\n 'closeTabLabel',\n 'color',\n 'size',\n 'fullWidth',\n 'scrollable',\n 'scrollButtons',\n 'sticky',\n 'stickyOffset',\n 'animateContent',\n 'animationDuration',\n 'persistContent',\n 'tabPanelProps',\n 'loading',\n 'loadingComponent',\n]);\n\n/** `props` with every {@link OWN_PROPS} key dropped — what is left is passthrough. */\nconst domPassthrough = (props: Record<string, unknown>): Record<string, unknown> =>\n Object.fromEntries(Object.entries(props).filter(([key]) => !OWN_PROPS.has(key)));\n\n// Strips explicitly-undefined props before the merge, so `prop={undefined}`\n// still falls back to the default as a destructuring default would.\nconst definedProps = (props: TabsProps): Partial<TabsProps> =>\n Object.fromEntries(\n Object.entries(props).filter(([, value]) => value !== undefined),\n ) as Partial<TabsProps>;\n\n// Once the row is scrollable every accepted scrollButtons value ends up as\n// MUI's 'auto'. That is exactly what the previous nested ternary did — it mapped\n// 'on'/'off'/'desktop' to 'auto', and its remaining branch could only ever be\n// 'auto' anyway — so the behaviour is preserved here rather than quietly\n// changed. Worth knowing that scrollButtons=\"off\" therefore still shows buttons.\nconst resolveScrollButtons = (scrollable?: boolean): 'auto' | false =>\n scrollable ? 'auto' : false;\n\nconst buildTabsSx = ({\n fullWidth,\n sticky,\n stickyOffset,\n indicatorColor,\n disabled }: {\n fullWidth?: boolean;\n sticky?: boolean;\n /** The pinned list's `top`, already through the theme (the prop is design px). */\n stickyOffset: (theme: Theme) => string;\n indicatorColor?: string;\n disabled?: boolean;\n}) => ({\n ...(fullWidth && { width: '100%' }),\n // Pin the tab list while panels scroll beneath it. Opaque background + bottom\n // divider so scrolled content does not show through.\n ...(sticky && {\n position: 'sticky',\n top: stickyOffset,\n zIndex: 2,\n backgroundColor: 'background.default',\n borderBottom: 1,\n borderColor: 'divider' }),\n ...(indicatorColor && {\n '& .MuiTabs-indicator': { backgroundColor: indicatorColor } }),\n ...(disabled && { opacity: 0.6, pointerEvents: 'none' }) });\n\n// A tab's label: icon, text, optional close affordance, optionally badged.\nconst TabLabel: React.FC<{\n item: TabItem;\n closeTabLabel: string;\n onClose: (event: React.MouseEvent | React.KeyboardEvent, tabId: string) => void;\n}> = ({ item, closeTabLabel, onClose }) => {\n const content = (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n {item.icon}\n <span>{item.label}</span>\n {item.count !== undefined && (\n <CountPill tone={item.count.tone ?? 'neutral'} data-tone={item.count.tone ?? 'neutral'}>\n {item.count.value}\n </CountPill>\n )}\n {item.closable && (\n <CloseButton\n onClick={(e) => onClose(e, item.id)}\n role=\"button\"\n tabIndex={0}\n aria-label={closeTabLabel}\n onKeyDown={(e) => {\n if (e.key !== 'Enter' && e.key !== ' ') return;\n onClose(e, item.id);\n }}\n >\n <Close fontSize=\"inherit\" />\n </CloseButton>\n )}\n </Box>\n );\n\n if (item.badge === undefined) return content;\n\n return (\n <BadgeWrapper badgeContent={item.badge} color=\"error\">\n {content}\n </BadgeWrapper>\n );\n};\n\ntype ResolvedTabs = TabsProps;\n\n// The tab strip. Kept in this file because StyledTabs cannot cross a module\n// boundary (TS2742).\nconst TabsBar: React.FC<\n ResolvedTabs & {\n rest: Record<string, unknown>;\n onChange: (event: React.SyntheticEvent, newValue: string) => void;\n onCloseTab: (event: React.MouseEvent | React.KeyboardEvent, tabId: string) => void;\n }\n> = ({ rest, items, value, onChange, onCloseTab, dataTestId, ...p }) => (\n <StyledTabs\n {...rest}\n value={value}\n onChange={onChange}\n customVariant={p.variant}\n size={p.size}\n showDividers={p.showDividers}\n orientation={p.orientation}\n centered={p.centered}\n // MUI only scrolls when its own `variant` is `scrollable`; map our\n // `scrollable` flag onto it so overflowing tab rows actually scroll.\n variant={p.scrollable ? 'scrollable' : 'standard'}\n data-testid={dataTestId ? `${dataTestId}-list` : 'tabs-list'}\n scrollButtons={resolveScrollButtons(p.scrollable)}\n allowScrollButtonsMobile={p.scrollable}\n textColor={p.color}\n indicatorColor={p.color}\n sx={buildTabsSx({\n fullWidth: p.fullWidth,\n sticky: p.sticky,\n stickyOffset: sxRem(p.stickyOffset ?? 0),\n indicatorColor: p.indicatorColor,\n disabled: p.disabled })}\n >\n {items.map((item, index) => (\n <MuiTab\n key={item.id}\n value={item.id}\n label={<TabLabel closeTabLabel={p.closeTabLabel} item={item} onClose={onCloseTab} />}\n disabled={item.disabled || p.disabled}\n className={item.className}\n id={`tab-${item.id}`}\n aria-controls={`tabpanel-${item.id}`}\n aria-disabled={item.disabled || p.disabled}\n data-testid={dataTestId ? `${dataTestId}-tab-${index}` : `tabs-tab-${index}`}\n />\n ))}\n </StyledTabs>\n);\n\nconst TabsPanels: React.FC<ResolvedTabs> = ({\n items,\n value,\n variant,\n animateContent,\n animationDuration,\n persistContent,\n loading,\n loadingComponent,\n tabPanelProps,\n dataTestId }) => (\n <Box sx={{ mt: variant === 'enclosed' ? 0 : 2 }}>\n {items.map((item, index) => (\n <CustomTabPanel\n key={item.id}\n id={item.id}\n value={value}\n animate={animateContent}\n animationDuration={animationDuration}\n persist={persistContent}\n loading={loading}\n loadingComponent={loadingComponent}\n className={tabPanelProps?.className}\n dataTestId={dataTestId}\n index={index}\n >\n {item.content}\n </CustomTabPanel>\n ))}\n </Box>\n);\n\nexport const Tabs = React.forwardRef<HTMLDivElement, TabsProps>(\n (tabsProps, ref) => {\n const resolved = { ...TABS_DEFAULTS, ...definedProps(tabsProps) } as TabsProps;\n const {\n // Destructured only to keep it OUT of `rest`, which is spread onto the\n // DOM node — `{...resolved}` below is what actually carries it to\n // `TabsBar`. Same reason as `value` on the next line.\n closeTabLabel: _closeTabLabel,\n value: _value,\n onChange,\n onTabClose,\n className,\n disabled,\n showDividers,\n variant,\n dataTestId,\n ...rest\n } = resolved;\n\n const handleChange = (event: React.SyntheticEvent, newValue: string) => {\n if (!disabled) onChange(event, newValue);\n };\n\n const handleTabClose = (event: React.MouseEvent | React.KeyboardEvent, tabId: string) => {\n event.stopPropagation();\n onTabClose?.(tabId);\n };\n\n return (\n <Box className={className} ref={ref} data-testid={dataTestId || 'tabs'}>\n <TabsBar\n {...resolved}\n // The destructuring above drops the props this component USES;\n // `domPassthrough` drops the ones it merely OWNS. Both have to go:\n // `rest` is spread onto the DOM node, and the second group is where\n // 12-86's warnings came from.\n rest={domPassthrough(rest as unknown as Record<string, unknown>)}\n onChange={handleChange}\n onCloseTab={handleTabClose}\n />\n\n {showDividers && variant !== 'enclosed' && <Divider />}\n\n <TabsPanels {...resolved} />\n </Box>\n );\n },\n);\n\nTabs.displayName = 'Tabs';\n"],"mappings":";;;;;;;;;;;;AAAA,OAAO,WAAW;AAClB,OAAO,WAAW;AAClB,OAAO,SAAS;AAChB,OAAO,aAAa;AACpB,OAAO,YAAY;AACnB,OAAO,aAAa;AACpB,SAAS,OAAO,cAAc;AAE9B,OAAO,WAAW;AAyKd,SAEE,KAFF;AAlKJ,IAAM,aAAa,OAAO,SAAS;AAAA,EACjC,mBAAmB,CAAC,SAAS,CAAC,CAAC,iBAAiB,QAAQ,cAAc,EAAE,SAAS,IAAc;AAAE,CAAC;AAAA,EAClG,CAAC,EAAE,OAAO,eAAe,MAAM,aAAa,OAAO;AAAA,IACjD,GAAG,eAAe,EAAE,OAAO,eAAe,MAAM,aAAa,CAAC;AAAA,EAAE;AACpE;AAEA,IAAM,cAAc,OAAO,GAAG,EAAE,CAAC,EAAE,MAAM,OAAO;AAAA,EAC9C,YAAY,MAAM,QAAQ,GAAG;AAAA,EAC7B,SAAS,MAAM,QAAQ,IAAI;AAAA,EAC3B,OAAO,IAAI,OAAO,EAAE;AAAA,EACpB,QAAQ,IAAI,OAAO,EAAE;AAAA,EACrB,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,OAAO,MAAM,QAAQ,OAAO;AAAA,EAC5B,WAAW;AAAA,IACT,iBAAiB,MAAM,MAAM,QAAQ,MAAM,MAAM,GAAG;AAAA,IACpD,OAAO,MAAM,QAAQ,MAAM;AAAA,EAAK;AAAE,EAAE;AAExC,IAAM,eAAe,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,OAAO;AAAA,EACjD,qBAAqB;AAAA,IACnB,OAAO,IAAI,OAAO,EAAE;AAAA,IACpB,KAAK,IAAI,OAAO,CAAC;AAAA,IACjB,UAAU,IAAI,OAAO,EAAE;AAAA,IACvB,UAAU,IAAI,OAAO,EAAE;AAAA,IACvB,QAAQ,IAAI,OAAO,EAAE;AAAA,IACrB,SAAS;AAAA,EAAE;AAAE,EAAE;AAGnB,IAAM,YAAY,OAAO,QAAQ;AAAA,EAC/B,mBAAmB,CAAC,SAAS,SAAS;AACxC,CAAC,EAA2C,CAAC,EAAE,OAAO,KAAK,MAAM;AAC/D,QAAM,OAAO;AAAA,IACX,SAAS,EAAE,iBAAiB,MAAM,QAAQ,OAAO,UAAU,OAAO,MAAM,QAAQ,KAAK,UAAU;AAAA,IAC/F,SAAS,EAAE,iBAAiB,MAAM,MAAM,QAAQ,QAAQ,MAAM,IAAI,GAAG,OAAO,MAAM,QAAQ,QAAQ,KAAK;AAAA,IACvG,QAAQ,EAAE,iBAAiB,MAAM,QAAQ,MAAM,MAAM,OAAO,MAAM,QAAQ,MAAM,aAAa;AAAA,EAC/F,EAAE,IAAI;AACN,SAAO;AAAA,IACL,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,QAAQ,IAAI,OAAO,EAAE;AAAA,IACrB,UAAU,IAAI,OAAO,EAAE;AAAA,IACvB,SAAS,MAAM,QAAQ,GAAG,KAAK;AAAA,IAC/B,cAAc,IAAI,OAAO,GAAG;AAAA,IAC5B,UAAU,IAAI,OAAO,IAAI;AAAA,IACzB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,GAAG;AAAA,EACL;AACF,CAAC;AAED,IAAM,gBAAoC;AAAA,EACxC,SAAS;AAAA,EACT,MAAM;AAAA,EACN,OAAO;AAAA,EACP,WAAW;AAAA,EACX,aAAa;AAAA,EACb,cAAc;AAAA,EACd,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,SAAS;AAAM;AAqBjB,IAAM,YAAY,oBAAI,IAAY;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGD,IAAM,iBAAiB,CAAC,UACtB,OAAO,YAAY,OAAO,QAAQ,KAAK,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC;AAIjF,IAAM,eAAe,CAAC,UACpB,OAAO;AAAA,EACL,OAAO,QAAQ,KAAK,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,UAAU,MAAS;AACjE;AAOF,IAAM,uBAAuB,CAAC,eAC5B,aAAa,SAAS;AAExB,IAAM,cAAc,CAAC;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAS,OAOJ;AAAA,EACL,GAAI,aAAa,EAAE,OAAO,OAAO;AAAA;AAAA;AAAA,EAGjC,GAAI,UAAU;AAAA,IACZ,UAAU;AAAA,IACV,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,cAAc;AAAA,IACd,aAAa;AAAA,EAAU;AAAA,EACzB,GAAI,kBAAkB;AAAA,IACpB,wBAAwB,EAAE,iBAAiB,eAAe;AAAA,EAAE;AAAA,EAC9D,GAAI,YAAY,EAAE,SAAS,KAAK,eAAe,OAAO;AAAG;AAG3D,IAAM,WAID,CAAC,EAAE,MAAM,eAAe,QAAQ,MAAM;AACzC,QAAM,UACJ,qBAAC,OAAI,IAAI,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,EAAE,GACtD;AAAA,SAAK;AAAA,IACN,oBAAC,UAAM,eAAK,OAAM;AAAA,IACjB,KAAK,UAAU,UACd,oBAAC,aAAU,MAAM,KAAK,MAAM,QAAQ,WAAW,aAAW,KAAK,MAAM,QAAQ,WAC1E,eAAK,MAAM,OACd;AAAA,IAED,KAAK,YACJ;AAAA,MAAC;AAAA;AAAA,QACC,SAAS,CAAC,MAAM,QAAQ,GAAG,KAAK,EAAE;AAAA,QAClC,MAAK;AAAA,QACL,UAAU;AAAA,QACV,cAAY;AAAA,QACZ,WAAW,CAAC,MAAM;AAChB,cAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,IAAK;AACxC,kBAAQ,GAAG,KAAK,EAAE;AAAA,QACpB;AAAA,QAEA,8BAAC,SAAM,UAAS,WAAU;AAAA;AAAA,IAC5B;AAAA,KAEJ;AAGF,MAAI,KAAK,UAAU,OAAW,QAAO;AAErC,SACE,oBAAC,gBAAa,cAAc,KAAK,OAAO,OAAM,SAC3C,mBACH;AAEJ;AAMA,IAAM,UAMF,CAAC,EAAE,MAAM,OAAO,OAAO,UAAU,YAAY,YAAY,GAAG,EAAE,MAChE;AAAA,EAAC;AAAA;AAAA,IACE,GAAG;AAAA,IACJ;AAAA,IACA;AAAA,IACA,eAAe,EAAE;AAAA,IACjB,MAAM,EAAE;AAAA,IACR,cAAc,EAAE;AAAA,IAChB,aAAa,EAAE;AAAA,IACf,UAAU,EAAE;AAAA,IAGZ,SAAS,EAAE,aAAa,eAAe;AAAA,IACvC,eAAa,aAAa,GAAG,UAAU,UAAU;AAAA,IACjD,eAAe,qBAAqB,EAAE,UAAU;AAAA,IAChD,0BAA0B,EAAE;AAAA,IAC5B,WAAW,EAAE;AAAA,IACb,gBAAgB,EAAE;AAAA,IAClB,IAAI,YAAY;AAAA,MACd,WAAW,EAAE;AAAA,MACb,QAAQ,EAAE;AAAA,MACV,cAAc,MAAM,EAAE,gBAAgB,CAAC;AAAA,MACvC,gBAAgB,EAAE;AAAA,MAClB,UAAU,EAAE;AAAA,IAAS,CAAC;AAAA,IAEvB,gBAAM,IAAI,CAAC,MAAM,UAChB;AAAA,MAAC;AAAA;AAAA,QAEC,OAAO,KAAK;AAAA,QACZ,OAAO,oBAAC,YAAS,eAAe,EAAE,eAAe,MAAY,SAAS,YAAY;AAAA,QAClF,UAAU,KAAK,YAAY,EAAE;AAAA,QAC7B,WAAW,KAAK;AAAA,QAChB,IAAI,OAAO,KAAK,EAAE;AAAA,QAClB,iBAAe,YAAY,KAAK,EAAE;AAAA,QAClC,iBAAe,KAAK,YAAY,EAAE;AAAA,QAClC,eAAa,aAAa,GAAG,UAAU,QAAQ,KAAK,KAAK,YAAY,KAAK;AAAA;AAAA,MARrE,KAAK;AAAA,IASZ,CACD;AAAA;AACH;AAGF,IAAM,aAAqC,CAAC;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAW,MACX,oBAAC,OAAI,IAAI,EAAE,IAAI,YAAY,aAAa,IAAI,EAAE,GAC3C,gBAAM,IAAI,CAAC,MAAM,UAChB;AAAA,EAAC;AAAA;AAAA,IAEC,IAAI,KAAK;AAAA,IACT;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA,WAAW,eAAe;AAAA,IAC1B;AAAA,IACA;AAAA,IAEC,eAAK;AAAA;AAAA,EAZD,KAAK;AAaZ,CACD,GACH;AAGK,IAAM,OAAO,MAAM;AAAA,EACxB,CAAC,WAAW,QAAQ;AAClB,UAAM,WAAW,EAAE,GAAG,eAAe,GAAG,aAAa,SAAS,EAAE;AAChE,UAAM;AAAA;AAAA;AAAA;AAAA,MAIJ,eAAe;AAAA,MACf,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IACL,IAAI;AAEJ,UAAM,eAAe,CAAC,OAA6B,aAAqB;AACtE,UAAI,CAAC,SAAU,UAAS,OAAO,QAAQ;AAAA,IACzC;AAEA,UAAM,iBAAiB,CAAC,OAA+C,UAAkB;AACvF,YAAM,gBAAgB;AACtB,mBAAa,KAAK;AAAA,IACpB;AAEA,WACE,qBAAC,OAAI,WAAsB,KAAU,eAAa,cAAc,QAC9D;AAAA;AAAA,QAAC;AAAA;AAAA,UACE,GAAG;AAAA,UAKJ,MAAM,eAAe,IAA0C;AAAA,UAC/D,UAAU;AAAA,UACV,YAAY;AAAA;AAAA,MACd;AAAA,MAEC,gBAAgB,YAAY,cAAc,oBAAC,WAAQ;AAAA,MAEpD,oBAAC,cAAY,GAAG,UAAU;AAAA,OAC5B;AAAA,EAEJ;AACF;AAEA,KAAK,cAAc;","names":[]}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
MoreGroup,
|
|
3
3
|
MoreQuick,
|
|
4
4
|
fieldClearing
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-EYW6KXUC.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-
|
|
196
|
+
//# sourceMappingURL=chunk-SAXALTRL.js.map
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
anyApplied,
|
|
3
3
|
isQuickActive,
|
|
4
4
|
keepChipsInOrder
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-AMT7IJYV.js";
|
|
6
6
|
import {
|
|
7
7
|
RESERVED,
|
|
8
8
|
estimateWidth,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
pillText,
|
|
12
12
|
pricesFor,
|
|
13
13
|
rightClusterCost
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-GZOW6HNN.js";
|
|
15
15
|
import {
|
|
16
16
|
splitToFit,
|
|
17
17
|
useMeasuredWidth
|
|
@@ -63,7 +63,7 @@ function splitFilters(all, pills, ranges, width, furniture, compact, theme) {
|
|
|
63
63
|
used: split.used + clearCost + pinnedCost
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
|
-
function computeSplit(all, pills, ranges, width, hasExport, theme) {
|
|
66
|
+
function computeSplit(all, pills, ranges, width, hasExport, theme, showCounter = true) {
|
|
67
67
|
if (width === 0) {
|
|
68
68
|
return {
|
|
69
69
|
inline: all.filter((field) => !field.pinned),
|
|
@@ -75,7 +75,7 @@ function computeSplit(all, pills, ranges, width, hasExport, theme) {
|
|
|
75
75
|
searchTakeover: false
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
|
-
const price = pricesFor(theme);
|
|
78
|
+
const price = pricesFor(theme, showCounter);
|
|
79
79
|
let budget = furnitureCost(price, UNCOLLAPSED, hasExport);
|
|
80
80
|
let split = splitFilters(all, pills, ranges, width, budget, false, theme);
|
|
81
81
|
let flags = ladderFlags(split, width, hasExport, price);
|
|
@@ -103,22 +103,22 @@ function ladderFlags(split, width, hasExport, price) {
|
|
|
103
103
|
const searchTakeover = searchCollapsed && searchBoxRoom < price.usableSearch;
|
|
104
104
|
return { compactControls, counterHidden, searchCollapsed, clearAllHidden, searchTakeover };
|
|
105
105
|
}
|
|
106
|
-
function useFilterOverflow(all, pills, ranges, frozen = false, hasExport = true) {
|
|
106
|
+
function useFilterOverflow(all, pills, ranges, frozen = false, hasExport = true, showCounter = true) {
|
|
107
107
|
const { ref: barRef, width } = useMeasuredWidth();
|
|
108
108
|
const theme = useTheme();
|
|
109
109
|
const signature = JSON.stringify({
|
|
110
|
-
// A chip's count and
|
|
111
|
-
// without changing its id, so both are part of the key.
|
|
110
|
+
// A chip's count and `inMore` move its price or place, not its id: both key.
|
|
112
111
|
ids: all.map((field) => [field.id, field.quick?.count ?? null, field.pinned === true]),
|
|
113
112
|
pills,
|
|
114
113
|
ranges,
|
|
115
114
|
width,
|
|
116
115
|
hasExport,
|
|
116
|
+
showCounter,
|
|
117
117
|
scale: remPx(theme, 1)
|
|
118
118
|
});
|
|
119
119
|
const cache = useRef(null);
|
|
120
120
|
if (cache.current === null || !frozen && cache.current.signature !== signature) {
|
|
121
|
-
cache.current = { signature, split: computeSplit(all, pills, ranges, width, hasExport, theme) };
|
|
121
|
+
cache.current = { signature, split: computeSplit(all, pills, ranges, width, hasExport, theme, showCounter) };
|
|
122
122
|
}
|
|
123
123
|
const { split } = cache.current;
|
|
124
124
|
const current = new Map(all.map((field) => [field.id, field]));
|
|
@@ -129,4 +129,4 @@ function useFilterOverflow(all, pills, ranges, frozen = false, hasExport = true)
|
|
|
129
129
|
export {
|
|
130
130
|
useFilterOverflow
|
|
131
131
|
};
|
|
132
|
-
//# sourceMappingURL=chunk-
|
|
132
|
+
//# sourceMappingURL=chunk-SOQIWXFO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/DataViews/data-views-overflow.ts"],"sourcesContent":["\"use client\";\n\nimport { useTheme, type Theme } from \"@mui/material/styles/index.js\";\nimport { useRef } from \"react\";\n\nimport { remPx } from \"../../../tokens/relative\";\nimport { splitToFit, useMeasuredWidth } from \"../../utility/Overflow\";\nimport {\n estimateWidth,\n furnitureCost,\n isRangeSet,\n pillText,\n pricesFor,\n RESERVED,\n rightClusterCost,\n type Prices,\n} from \"./data-views-overflow-costs\";\nimport type { FilterFieldConfig, QuickFilterConfig, RangeFieldConfig, RangeValue } from \"./data-views-types\";\nimport { anyApplied, isQuickActive, keepChipsInOrder } from \"./data-views-overflow-fields\";\n\n// Declaring the controls lives in its own module (size gate); re-exported for its callers.\nexport { isQuickActive, toOverflowFields } from \"./data-views-overflow-fields\";\n\n/**\n * PROGRESSIVE COLLAPSE — which filter controls fit on the toolbar, measured.\n *\n * Two rules, and both come from watching the all-or-nothing version fail:\n *\n * 1. Controls shed ONE AT A TIME into an overflow, never all at once. With four\n * filters and room for three, hiding all four throws away the room that was\n * there.\n * 2. An APPLIED filter is ranked first, not exempt. Applied controls take the\n * visible slots ahead of idle ones, and go into \"Mais\" like anything else\n * when even those slots run out. Exempting them outright — the earlier rule\n * — meant four applied filters on a phone claimed more width than the row\n * had, and the bar painted past its own edge: the pills were reachable only\n * by scrolling the toolbar sideways. Hiding one is safe because \"Mais\" says\n * how many applied filters are behind it; scrolling one off-screen says\n * nothing at all.\n *\n * It MEASURES rather than picking a breakpoint, which is what\n * `FILTERS-CONTRACT.md` asks for: pages declare different numbers of filters\n * with different label lengths, and the same page collapses at a different\n * width in another language. A shared breakpoint is wrong for at least one\n * table by construction.\n *\n * Collapsing is presentation only — nothing here emits a query, drops a filter\n * or changes a rendered row.\n */\n\n/** A filter control on the bar: a multi-select pill, a min/max range or a quick chip. */\nexport interface OverflowField<T extends Record<string, unknown>> {\n id: string;\n label: string;\n /** Which control it is — the caller renders the right one. */\n group: \"pill\" | \"range\" | \"quick\";\n pill?: FilterFieldConfig<T>;\n range?: RangeFieldConfig<T>;\n quick?: QuickFilterConfig;\n /** Declared `inMore`: never on the bar, always behind \"Mais\". */\n pinned?: boolean;\n}\n\n/** What the caller renders inline, and what goes behind \"Mais\". */\nexport interface OverflowSplit<T extends Record<string, unknown>> {\n inline: OverflowField<T>[];\n overflow: OverflowField<T>[];\n /**\n * Step 2 — Exibir/Exportar drop their text labels and become icons.\n * Cheap: both keep their icon, their tooltip and their position.\n */\n compactControls: boolean;\n /**\n * Step 5, and the LAST resort — the \"N de N\" counter is dropped.\n *\n * Only once every control has already collapsed and the row STILL does not\n * fit, which on a six-filter table is below about 400px. The counter goes\n * last because it is the only thing left that reports rather than does: an\n * operator can act without knowing the total, but not without the search.\n */\n counterHidden: boolean;\n /**\n * Step 4 — the search collapses to a magnifier that expands on click.\n * The most expensive step, so it is taken last: the search is the one\n * control on the bar that cannot be guessed from an icon's position.\n */\n searchCollapsed: boolean;\n /**\n * Step 6, below even the counter — \"Limpar\" leaves the bar.\n *\n * The one control here with a second home: the overflow panel's footer\n * carries \"Limpar todos os filtros\". So it goes before the search icon or\n * \"Mais\", neither of which has anywhere else to be.\n */\n clearAllHidden: boolean;\n /**\n * Expanding the magnifier must take the whole cluster, filters and all.\n *\n * Only on the rungs where what is left over would be too narrow to read —\n * on a large phone the box simply shrinks and the filters stay, which is why\n * this is its own answer rather than `searchCollapsed` reused.\n */\n searchTakeover: boolean;\n /** Attach to the toolbar row being measured. */\n barRef: React.RefObject<HTMLDivElement | null>;\n}\n\n/** Is this control carrying a value the operator set? */\nfunction isActiveField<T extends Record<string, unknown>>(\n field: OverflowField<T>,\n pills: Record<string, string[]>,\n ranges: Record<string, RangeValue>,\n): boolean {\n if (field.group === \"quick\" && field.quick) return isQuickActive(field.quick, pills);\n return field.group === \"pill\"\n ? (pills[field.id]?.length ?? 0) > 0\n : isRangeSet(ranges[field.id]);\n}\n\n/** Estimated rendered width of one control at its CURRENT value, in px at `theme`'s scale. */\nfunction fieldWidth<T extends Record<string, unknown>>(\n theme: Theme,\n field: OverflowField<T>,\n pills: Record<string, string[]>,\n ranges: Record<string, RangeValue>,\n): number {\n // A chip is a pill with its count beside the label and no chevron.\n if (field.group === \"quick\") return estimateWidth(theme, `${field.label} ${field.quick?.count ?? \"\"}`, -20);\n if (field.group === \"pill\") return estimateWidth(theme, pillText(field, pills[field.id] ?? []), 0);\n // A bounded range renders two number inputs (100 design px) beside its label.\n return estimateWidth(theme, field.label, isRangeSet(ranges[field.id]) ? 100 : 0);\n}\n\n/** What one split costs on the bar, so the ladder below can price the next step. */\ntype Split<T extends Record<string, unknown>> = {\n inline: OverflowField<T>[];\n overflow: OverflowField<T>[];\n /** Width the surviving inline controls occupy, incl. the \"Mais\" button. */\n used: number;\n};\n\n/** Step 1 — shed filter controls into the overflow. Pure. */\nfunction splitFilters<T extends Record<string, unknown>>(\n all: OverflowField<T>[],\n pills: Record<string, string[]>,\n ranges: Record<string, RangeValue>,\n width: number,\n /** Search + counter + right cluster + chrome, at the rung being considered. */\n furniture: number,\n /** Is the bar already down to icons? \"Mais\" shrinks with everything else. */\n compact: boolean,\n /** Whose type scale every price is read at — the bar's own. */\n theme: Theme,\n): Split<T> {\n // `inMore` fields never compete for the bar: they are behind \"Mais\" from the\n // start, so \"Mais\" is on the bar whatever else fits.\n const pinned = all.filter((field) => field.pinned);\n const candidates = all.filter((field) => !field.pinned);\n const chips = candidates.filter((field) => field.group === \"quick\");\n const rest = candidates.filter((field) => field.group !== \"quick\");\n const active = rest.filter((field) => isActiveField(field, pills, ranges));\n const idle = rest.filter((field) => !isActiveField(field, pills, ranges));\n const price = pricesFor(theme);\n const moreCost = compact ? price.overflowButtonCompact : price.overflowButton;\n const gap = remPx(theme, RESERVED.betweenControls);\n\n // \"Limpar\" rides the end of the cluster whenever anything is applied —\n // ANYTHING, a pinned field and a chip's field included, since the bar draws\n // it on the active count, not on what it can see. Pressing a chip can\n // therefore cost the bar room; chips rank first and stay a prefix (below),\n // so what leaves is an idle pill, or the chips together — never one chip\n // swapped for another.\n const clearCost = anyApplied(all, pills, ranges) ? price.clearAll + gap : 0;\n // APPLIED FIRST, BUT NOT EXEMPT.\n //\n // Applied controls take the visible slots ahead of idle ones — that part was\n // always right. Exempting them from the overflow entirely was not: applying\n // a value LENGTHENS a control (\"Pagamento (1)\"), so on a phone four applied\n // filters claimed more width than the row had and the bar simply painted\n // past its own edge, leaving pills reachable only by scrolling sideways.\n //\n // An applied filter hidden in \"Mais\" is not lost the way it would be if it\n // vanished silently: the trigger goes to the applied tone and says how many\n // are in there (see `MoreTrigger`), which is the same signal the pill itself\n // was carrying. A control you scroll off-screen carries no signal at all.\n //\n // Quick chips come before all of it, in their DECLARED order whatever is\n // pressed: they are the bar's fixed vocabulary, so their slots never move.\n //\n // The keep-what-fits loop is `splitToFit` (`utility/Overflow`). With pinned\n // fields \"Mais\" is always drawn, so its cost is paid up front.\n const pinnedCost = pinned.length > 0 ? moreCost + gap : 0;\n const widthOf = (field: OverflowField<T>): number => fieldWidth(theme, field, pills, ranges);\n const split = keepChipsInOrder(\n splitToFit(candidates, {\n widthOf,\n keyOf: (field) => field.id,\n gap,\n available: width - furniture - clearCost - pinnedCost,\n overflowCost: pinned.length > 0 ? 0 : moreCost,\n priority: [...chips, ...active, ...idle],\n }),\n chips,\n (field) => widthOf(field) + gap,\n );\n return {\n inline: split.inline,\n overflow: [...split.overflow, ...pinned],\n used: split.used + clearCost + pinnedCost,\n };\n}\n\n/**\n * THE DEGRADATION LADDER — cheapest loss first, and each rung taken only if\n * the one before it did not free enough:\n *\n * 1. filter controls move into the \"Mais\" overflow (`splitFilters`)\n * 2. Exibir / Exportar drop their text labels (`compactControls`)\n * 3. the search shrinks toward its minimum (CSS: it is `flex: 1`)\n * 4. the search itself collapses to an icon (`searchCollapsed`)\n *\n * Step 3 needs no flag — the search is a flex child, so it gives up width on\n * its own until it hits `RESERVED.search`. The flags mark the two steps that\n * change what is RENDERED rather than how wide it is.\n *\n * Measured against what is CURRENTLY on the bar, never a breakpoint: a\n * two-filter page and a five-filter page would otherwise collapse at the same\n * width, and only one of them would be right.\n */\nfunction computeSplit<T extends Record<string, unknown>>(\n all: OverflowField<T>[],\n pills: Record<string, string[]>,\n ranges: Record<string, RangeValue>,\n width: number,\n /** Does the host render \"Exportar\" beside \"Exibir\"? Half the cluster if not. */\n hasExport: boolean,\n theme: Theme,\n showCounter = true, // the host shows the \"N de N\" counter — priced at 0 when not\n): Omit<OverflowSplit<T>, \"barRef\"> {\n // Unmeasured (SSR, or jsdom without a ResizeObserver) ⇒ degrade nothing.\n if (width === 0) {\n return {\n inline: all.filter((field) => !field.pinned),\n overflow: all.filter((field) => field.pinned),\n compactControls: false,\n counterHidden: false,\n searchCollapsed: false,\n clearAllHidden: false,\n searchTakeover: false,\n };\n }\n const price = pricesFor(theme, showCounter);\n // Pass 1 prices the furniture at its widest — no rung has been taken yet.\n let budget = furnitureCost(price, UNCOLLAPSED, hasExport);\n let split = splitFilters(all, pills, ranges, width, budget, false, theme);\n let flags = ladderFlags(split, width, hasExport, price);\n // RE-SPEND WHAT THE LATER RUNGS FREED.\n //\n // Rungs 2/4/5 turn 200 + 96 + 216 of furniture into 44 + 0 + 140, and until\n // this loop existed nobody handed those ~330px back to the filters: the\n // split was decided once, against the uncollapsed row, so a phone shed every\n // control and then sat with a band of empty bar beside \"Mais 5\".\n //\n // Settles rather than oscillates, and cannot overfill: a cheaper furniture\n // can only give the filters MORE room, more filter width can only push the\n // ladder FURTHER down, and a further rung can only make the furniture\n // cheaper again — so the budget decreases monotonically and the loop exits\n // the moment it stops moving. The bound is a backstop, not the exit.\n for (let pass = 0; pass < 3; pass += 1) {\n const freed = furnitureCost(price, flags, hasExport);\n if (freed >= budget) break;\n budget = freed;\n split = splitFilters(all, pills, ranges, width, budget, flags.compactControls, theme);\n flags = ladderFlags(split, width, hasExport, price);\n }\n return { inline: split.inline, overflow: split.overflow, ...flags };\n}\n\n/** The widest the furniture ever is — every rung still untaken. */\nconst UNCOLLAPSED = { searchCollapsed: false, counterHidden: false, compactControls: false };\n\n/** Rungs 2 and 4-6, priced against what the filters actually took. */\nfunction ladderFlags<T extends Record<string, unknown>>(\n split: Split<T>,\n width: number,\n hasExport: boolean,\n price: Prices,\n): Omit<OverflowSplit<T>, \"barRef\" | \"inline\" | \"overflow\"> {\n const { overflow, used } = split;\n const base = width - used - price.chrome;\n\n // Would the search still make its minimum with the labels on?\n const compactControls = base - price.counter - rightClusterCost(price, hasExport, false) < price.search;\n const rightCost = rightClusterCost(price, hasExport, compactControls);\n // …and with them off?\n const searchCollapsed = base - price.counter - rightCost < price.search;\n // Everything has collapsed and the row STILL overflows. The controls cannot\n // shrink further — they are `flexShrink: 0` precisely so an over-packed row\n // sheds rather than squeezes — so without this last rung they simply paint\n // outside the toolbar, which is what a narrow phone was doing.\n const counterHidden =\n searchCollapsed && base - price.counter - rightCost < price.searchIcon;\n // Step 6 — below even that, \"Limpar\" leaves the bar. It is the ONLY control\n // here with a second home: the overflow panel's footer carries \"Limpar todos\n // os filtros\", so nothing is lost, which is exactly why it goes before the\n // search icon or \"Mais\" (neither of which has anywhere else to be). Guarded\n // on there BEING an overflow, because with no panel the footer does not\n // exist and dropping this would strand the operator.\n const clearAllHidden = counterHidden && overflow.length > 0;\n // What the keyword box would get if the operator expanded the magnifier.\n // `searchCollapsed` is a different question — it asks whether the box fits at\n // its PREFERRED 200px, and is deliberately pessimistic — so reusing it to\n // decide the takeover evicted the filters on screens where the box had plenty\n // of room to simply shrink.\n //\n // Asked with the inline filters SHED, because shedding them is exactly what\n // expanding the box does: the row re-splits and they go behind \"Mais\".\n // Measuring against the resting row instead made a filter argue for its own\n // eviction — now that a large phone keeps one, its width came out of `base`,\n // pushed the box under `usableSearch`, and tipped a row that had ample space\n // to share into a full takeover.\n const overflowButton = compactControls\n ? price.overflowButtonCompact\n : price.overflowButton;\n const shedRoom = width - price.chrome - (overflow.length > 0 ? overflowButton : 0);\n const searchBoxRoom = shedRoom - (counterHidden ? 0 : price.counter) - rightCost;\n // Below this a box is too narrow to read what you typed into it, and shrinking\n // further buys nothing; that is the only point at which taking the whole\n // cluster is worth losing the filters.\n const searchTakeover = searchCollapsed && searchBoxRoom < price.usableSearch;\n\n return { compactControls, counterHidden, searchCollapsed, clearAllHidden, searchTakeover };\n}\n\n/**\n * Split the declared filter controls into what fits and what goes behind\n * \"Mais\", measured against the live toolbar width.\n *\n * Cached on a SIGNATURE rather than by `useMemo` over the inputs: hosts declare\n * their fields inline, so `all` is a fresh array on every render while the\n * configuration is unchanged, and a reference-keyed memo would never hit.\n */\nexport function useFilterOverflow<T extends Record<string, unknown>>(\n all: OverflowField<T>[],\n pills: Record<string, string[]>,\n ranges: Record<string, RangeValue>,\n /**\n * A filter control is open — hold the current answer until it closes.\n *\n * Applying a filter changes that control's LABEL (\"Valor\" becomes \"Valor: ≥\n * R$ 1\"), which changes its measured width, which re-runs the whole split\n * while its popover is open on top of it. Measured: setting a minimum moved\n * the trigger 192px left, took the popover with it, and pushed two other\n * controls into a newly-appeared \"Mais 2\" — so reaching for the second bound\n * meant chasing the control across the row. Nobody sets a range that way.\n *\n * Frozen only for the duration: closing re-measures against the new labels,\n * so the row still ends up correct, it just does not rearrange under a hand\n * that is mid-edit.\n */\n frozen = false,\n /** Whether \"Exportar\" is on the bar — see `rightClusterCost`. */\n hasExport = true,\n showCounter = true, // whether the \"N de N\" counter is on the bar — see `computeSplit`\n): OverflowSplit<T> {\n // The measurement is `useMeasuredWidth` (`utility/Overflow`): the same\n // ResizeObserver every collapsing cluster in the design system reads, so\n // there is one loop to get right rather than one per bar. `0` until the\n // first measurement lands (and forever under SSR or jsdom), which\n // `computeSplit` reads as \"degrade nothing\".\n const { ref: barRef, width } = useMeasuredWidth<HTMLDivElement>();\n // The prices follow the theme's type scale, so the answer does too.\n const theme = useTheme();\n const signature = JSON.stringify({\n // A chip's count and `inMore` move its price or place, not its id: both key.\n ids: all.map((field) => [field.id, field.quick?.count ?? null, field.pinned === true]),\n pills,\n ranges,\n width,\n hasExport,\n showCounter,\n scale: remPx(theme, 1),\n });\n const cache = useRef<{ signature: string; split: ReturnType<typeof computeSplit<T>> } | null>(null);\n if (cache.current === null || (!frozen && cache.current.signature !== signature)) {\n cache.current = { signature, split: computeSplit(all, pills, ranges, width, hasExport, theme, showCounter) };\n }\n // The cache holds the ARRANGEMENT — which ids sit on the bar, which in \"Mais\"\n // — never the fields themselves. The signature keys on ids, so a field whose\n // options arrive after the first measurement (a category list still loading)\n // does not re-split, and handing back the cached objects served the empty\n // list for good: \"Categoria\" in \"Mais\" rendered a label with no control under\n // it (FUT-2828). Re-reading each field from `all` keeps the slots and the\n // current config.\n const { split } = cache.current;\n const current = new Map(all.map((field) => [field.id, field]));\n const fresh = (fields: OverflowField<T>[]): OverflowField<T>[] =>\n fields.map((field) => current.get(field.id) ?? field);\n return { ...split, inline: fresh(split.inline), overflow: fresh(split.overflow), barRef };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
} from "./chunk-QLJU7UUI.js";
|
|
5
5
|
import {
|
|
6
6
|
MoreFilters
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-SAXALTRL.js";
|
|
8
8
|
import {
|
|
9
9
|
PillControl
|
|
10
10
|
} from "./chunk-RQF4NXDC.js";
|
|
11
11
|
import {
|
|
12
12
|
isQuickActive
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-AMT7IJYV.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-
|
|
247
|
+
//# sourceMappingURL=chunk-TLPFSA55.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
partTestId
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZZO5MRMV.js";
|
|
4
4
|
import {
|
|
5
5
|
SETTING_CARD_OPEN_ATTR,
|
|
6
6
|
withCallerSx
|
|
@@ -79,4 +79,4 @@ export {
|
|
|
79
79
|
settingGridStyles,
|
|
80
80
|
SettingGrid
|
|
81
81
|
};
|
|
82
|
-
//# sourceMappingURL=chunk-
|
|
82
|
+
//# sourceMappingURL=chunk-U6ODZJCH.js.map
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
|
|
11
11
|
// src/components/feedback/StackedModal/StackedModal.styles.ts
|
|
12
12
|
import { alpha } from "@mui/material/styles/index.js";
|
|
13
|
-
var STYLE_ONLY_PROPS = ["modalRole", "isAnimating", "glass", "rtl", "customMaxWidth", "panelSize"];
|
|
13
|
+
var STYLE_ONLY_PROPS = ["modalRole", "isAnimating", "glass", "rtl", "customMaxWidth", "panelSize", "panelWidth"];
|
|
14
14
|
var MAX_WIDTH_PX = {
|
|
15
15
|
xs: 444,
|
|
16
16
|
sm: 600,
|
|
@@ -26,6 +26,11 @@ var ANIMATION_BY_ROLE = {
|
|
|
26
26
|
secondary: "expandModal 300ms ease-in-out forwards",
|
|
27
27
|
primary: "contractModal 300ms ease-in-out forwards"
|
|
28
28
|
};
|
|
29
|
+
var EXACT_WIDTH_VAR = "--stacked-modal-width";
|
|
30
|
+
var EXACT_ANIMATION_BY_ROLE = {
|
|
31
|
+
secondary: "expandModalExact 300ms ease-in-out forwards",
|
|
32
|
+
primary: "contractModalExact 300ms ease-in-out forwards"
|
|
33
|
+
};
|
|
29
34
|
var WIDE_ANIMATION_BY_ROLE = {
|
|
30
35
|
secondary: "expandModalWide 300ms ease-in-out forwards",
|
|
31
36
|
primary: "contractModalWide 300ms ease-in-out forwards"
|
|
@@ -46,6 +51,15 @@ var KEYFRAMES = {
|
|
|
46
51
|
"@keyframes contractModalWide": {
|
|
47
52
|
from: { width: "100vw", transform: "translateX(0)" },
|
|
48
53
|
to: { width: "90vw", transform: "translateX(0)" }
|
|
54
|
+
},
|
|
55
|
+
// An exact-width panel settles at its own width, carried by the custom property.
|
|
56
|
+
"@keyframes expandModalExact": {
|
|
57
|
+
from: { width: `var(${EXACT_WIDTH_VAR})`, transform: "translateX(0)" },
|
|
58
|
+
to: { width: "100vw", transform: "translateX(0)" }
|
|
59
|
+
},
|
|
60
|
+
"@keyframes contractModalExact": {
|
|
61
|
+
from: { width: "100vw", transform: "translateX(0)" },
|
|
62
|
+
to: { width: `var(${EXACT_WIDTH_VAR})`, transform: "translateX(0)" }
|
|
49
63
|
}
|
|
50
64
|
};
|
|
51
65
|
var cap = (customMaxWidth) => customMaxWidth ? MAX_WIDTH_PX[customMaxWidth] : null;
|
|
@@ -67,6 +81,17 @@ var widePrimaryPanelStyles = (theme, capPx) => ({
|
|
|
67
81
|
[theme.breakpoints.up("xl")]: panelWidth(theme, "75vw", capPx),
|
|
68
82
|
[theme.breakpoints.up(2200)]: panelWidth(theme, "60vw", capPx)
|
|
69
83
|
});
|
|
84
|
+
var exactPrimaryPanelStyles = (theme, exact) => {
|
|
85
|
+
const width = `min(${exact.share}, ${rem(theme, exact.maxPx)})`;
|
|
86
|
+
const full = { [EXACT_WIDTH_VAR]: "100%", width: "100%", maxWidth: "100%" };
|
|
87
|
+
return {
|
|
88
|
+
[EXACT_WIDTH_VAR]: width,
|
|
89
|
+
width: `var(${EXACT_WIDTH_VAR})`,
|
|
90
|
+
maxWidth: `var(${EXACT_WIDTH_VAR})`,
|
|
91
|
+
[theme.breakpoints.down("sm")]: full,
|
|
92
|
+
...exact.fullBelowPx ? { [theme.breakpoints.down(exact.fullBelowPx)]: full } : {}
|
|
93
|
+
};
|
|
94
|
+
};
|
|
70
95
|
var secondaryPanelStyles = () => ({
|
|
71
96
|
width: "100vw !important",
|
|
72
97
|
maxWidth: "100vw !important",
|
|
@@ -77,8 +102,9 @@ var secondaryPanelStyles = () => ({
|
|
|
77
102
|
opacity: 0.95,
|
|
78
103
|
transform: "scale(1)"
|
|
79
104
|
});
|
|
80
|
-
var rolePanelStyles = (theme, role, capPx, size) => {
|
|
105
|
+
var rolePanelStyles = (theme, role, capPx, size, exact) => {
|
|
81
106
|
if (role === "primary") {
|
|
107
|
+
if (exact) return exactPrimaryPanelStyles(theme, exact);
|
|
82
108
|
return size === "wide" ? widePrimaryPanelStyles(theme, capPx) : primaryPanelStyles(theme, capPx);
|
|
83
109
|
}
|
|
84
110
|
if (role === "secondary") return secondaryPanelStyles();
|
|
@@ -91,8 +117,12 @@ var glassStyles = (theme, glass, role) => glass && role === "primary" ? {
|
|
|
91
117
|
WebkitBackdropFilter: `blur(${rem(theme, 10)})`,
|
|
92
118
|
border: `1px solid ${alpha(theme.palette.divider, 0.18)}`
|
|
93
119
|
} : {};
|
|
94
|
-
var
|
|
95
|
-
|
|
120
|
+
var animationByRole = (size, exact) => {
|
|
121
|
+
if (exact) return EXACT_ANIMATION_BY_ROLE;
|
|
122
|
+
return size === "wide" ? WIDE_ANIMATION_BY_ROLE : ANIMATION_BY_ROLE;
|
|
123
|
+
};
|
|
124
|
+
var animationStyles = (isAnimating, role, size, exact) => {
|
|
125
|
+
const byRole = animationByRole(size, exact);
|
|
96
126
|
return isAnimating ? { animation: (role && byRole[role]) ?? "none" } : {};
|
|
97
127
|
};
|
|
98
128
|
var panelBaseStyles = (theme) => ({
|
|
@@ -115,9 +145,9 @@ var panelStyles = (theme, props) => {
|
|
|
115
145
|
const capPx = cap(props.customMaxWidth);
|
|
116
146
|
return {
|
|
117
147
|
...panelBaseStyles(theme),
|
|
118
|
-
...rolePanelStyles(theme, props.modalRole, capPx, props.panelSize),
|
|
148
|
+
...rolePanelStyles(theme, props.modalRole, capPx, props.panelSize, props.panelWidth),
|
|
119
149
|
...glassStyles(theme, props.glass, props.modalRole),
|
|
120
|
-
...animationStyles(props.isAnimating, props.modalRole, props.panelSize)
|
|
150
|
+
...animationStyles(props.isAnimating, props.modalRole, props.panelSize, props.panelWidth)
|
|
121
151
|
};
|
|
122
152
|
};
|
|
123
153
|
var dialogRootStyles = (theme, props) => ({
|
|
@@ -183,4 +213,4 @@ export {
|
|
|
183
213
|
loadingOverlayStyles,
|
|
184
214
|
modalContentStyles
|
|
185
215
|
};
|
|
186
|
-
//# sourceMappingURL=chunk-
|
|
216
|
+
//# sourceMappingURL=chunk-YKQA4NPM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/feedback/StackedModal/StackedModal.styles.ts"],"sourcesContent":["import { alpha } from '@mui/material/styles/index.js';\nimport type { CSSObject, Theme } from '@mui/material/styles/index.js';\nimport { scrim } from '../../../tokens/ink';\nimport { rem } from '../../../tokens/relative';\nimport { dynamicViewportHeight } from '../../../utils/viewport';\nimport type { ModalPanelRole, PanelMaxWidth, PanelSize, PanelWidth } from './StackedModal.types';\n\n/** Props that drive the panel's look but must not reach the DOM. */\nexport interface PanelStyleProps {\n modalRole?: ModalPanelRole;\n isAnimating?: boolean;\n glass?: boolean;\n rtl?: boolean;\n customMaxWidth?: PanelMaxWidth;\n panelSize?: PanelSize;\n panelWidth?: PanelWidth;\n}\n\n/** Style-only props, filtered out before they can land on a DOM node. */\nexport const STYLE_ONLY_PROPS = ['modalRole', 'isAnimating', 'glass', 'rtl', 'customMaxWidth', 'panelSize', 'panelWidth'];\n\n/** MUI breakpoint names mapped to the pixel width they cap the panel at. */\nconst MAX_WIDTH_PX: Record<Exclude<PanelMaxWidth, false>, number> = {\n xs: 444,\n sm: 600,\n md: 960,\n lg: 1280,\n xl: 1920,\n};\n\n/** The scrim's opacity behind each receding panel role. */\nconst BACKDROP_ALPHA_BY_ROLE: Partial<Record<ModalPanelRole, number>> = {\n secondary: 0.3,\n background: 0.1,\n};\n\nconst ANIMATION_BY_ROLE: Partial<Record<ModalPanelRole, string>> = {\n secondary: 'expandModal 300ms ease-in-out forwards',\n primary: 'contractModal 300ms ease-in-out forwards',\n};\n\n/** The custom property an exact-width panel's width and keyframes share. */\nconst EXACT_WIDTH_VAR = '--stacked-modal-width';\n\n/** An exact-width panel settles at its own width, so its keyframes read it too. */\nconst EXACT_ANIMATION_BY_ROLE: Partial<Record<ModalPanelRole, string>> = {\n secondary: 'expandModalExact 300ms ease-in-out forwards',\n primary: 'contractModalExact 300ms ease-in-out forwards',\n};\n\n/** A wide panel settles at 90vw, so its keyframes must end there too, or it snaps. */\nconst WIDE_ANIMATION_BY_ROLE: Partial<Record<ModalPanelRole, string>> = {\n secondary: 'expandModalWide 300ms ease-in-out forwards',\n primary: 'contractModalWide 300ms ease-in-out forwards',\n};\n\n// Animation endpoints use the common lg width (60vw); the role styles set the\n// exact per-breakpoint width once the animation settles.\nconst KEYFRAMES: CSSObject = {\n '@keyframes expandModal': {\n from: { width: '60vw', transform: 'translateX(0)' },\n to: { width: '100vw', transform: 'translateX(0)' },\n },\n '@keyframes contractModal': {\n from: { width: '100vw', transform: 'translateX(0)' },\n to: { width: '60vw', transform: 'translateX(0)' },\n },\n '@keyframes expandModalWide': {\n from: { width: '90vw', transform: 'translateX(0)' },\n to: { width: '100vw', transform: 'translateX(0)' },\n },\n '@keyframes contractModalWide': {\n from: { width: '100vw', transform: 'translateX(0)' },\n to: { width: '90vw', transform: 'translateX(0)' },\n },\n // An exact-width panel settles at its own width, carried by the custom property.\n '@keyframes expandModalExact': {\n from: { width: `var(${EXACT_WIDTH_VAR})`, transform: 'translateX(0)' },\n to: { width: '100vw', transform: 'translateX(0)' },\n },\n '@keyframes contractModalExact': {\n from: { width: '100vw', transform: 'translateX(0)' },\n to: { width: `var(${EXACT_WIDTH_VAR})`, transform: 'translateX(0)' },\n },\n};\n\nconst cap = (customMaxWidth?: PanelMaxWidth): number | null =>\n customMaxWidth ? MAX_WIDTH_PX[customMaxWidth] : null;\n\n/** One breakpoint's width: the viewport share, held under the optional px cap. */\nconst panelWidth = (theme: Theme, share: string, capPx: number | null): CSSObject =>\n capPx\n ? { width: `min(${share}, ${rem(theme, capPx)})`, maxWidth: rem(theme, capPx) }\n : { width: share, maxWidth: share };\n\nconst backdropStyles = (theme: Theme, modalRole?: ModalPanelRole): CSSObject => ({\n backgroundColor: scrim(theme, (modalRole && BACKDROP_ALPHA_BY_ROLE[modalRole]) ?? 0.5),\n backdropFilter: modalRole === 'primary' ? `blur(${rem(theme, 4)})` : 'none',\n});\n\n/**\n * The top panel is viewport-aware and narrows as the screen grows: full width on\n * mobile, 80vw on tablet/small desktop, 60vw on regular desktops (lg up —\n * including ~1080p/1440p/1080-wide), and 40vw only on ultra-wide screens\n * (≥2200px) so the receding panel stays visible on huge monitors. A `maxWidth`\n * prop, when given, caps it further.\n */\nconst primaryPanelStyles = (theme: Theme, capPx: number | null): CSSObject => ({\n [theme.breakpoints.down('sm')]: panelWidth(theme, '100%', capPx),\n [theme.breakpoints.between('sm', 'lg')]: panelWidth(theme, '80vw', capPx),\n [theme.breakpoints.up('lg')]: panelWidth(theme, '60vw', capPx),\n // A viewport width, in the theme's breakpoint unit like the three above.\n [theme.breakpoints.up(2200)]: panelWidth(theme, '40vw', capPx),\n});\n\n/**\n * `size=\"wide\"`: 90vw up to `xl`, 75vw above it, 60vw on ultra-wide screens.\n * At 1280 that is ~1150px instead of 768px — room for a form column beside a\n * fixed ~350px sidebar — while a sliver of the page behind stays visible.\n */\nconst widePrimaryPanelStyles = (theme: Theme, capPx: number | null): CSSObject => ({\n [theme.breakpoints.down('sm')]: panelWidth(theme, '100%', capPx),\n [theme.breakpoints.between('sm', 'xl')]: panelWidth(theme, '90vw', capPx),\n [theme.breakpoints.up('xl')]: panelWidth(theme, '75vw', capPx),\n [theme.breakpoints.up(2200)]: panelWidth(theme, '60vw', capPx),\n});\n\n/**\n * `panelWidth`: `min(share, maxPx)` from `sm` up, the whole screen under `sm`\n * and under `fullBelowPx`. Viewport media queries only — never the panel's size.\n */\nconst exactPrimaryPanelStyles = (theme: Theme, exact: PanelWidth): CSSObject => {\n const width = `min(${exact.share}, ${rem(theme, exact.maxPx)})`;\n const full = { [EXACT_WIDTH_VAR]: '100%', width: '100%', maxWidth: '100%' };\n return {\n [EXACT_WIDTH_VAR]: width,\n width: `var(${EXACT_WIDTH_VAR})`,\n maxWidth: `var(${EXACT_WIDTH_VAR})`,\n [theme.breakpoints.down('sm')]: full,\n ...(exact.fullBelowPx ? { [theme.breakpoints.down(exact.fullBelowPx)]: full } : {}),\n };\n};\n\n/** Panels below the top one expand to full width, producing the GTM stacking effect. */\nconst secondaryPanelStyles = (): CSSObject => ({\n width: '100vw !important',\n maxWidth: '100vw !important',\n right: '0 !important',\n top: '0 !important',\n ...dynamicViewportHeight('height', 'maxHeight'),\n borderRadius: '0 !important',\n opacity: 0.95,\n transform: 'scale(1)',\n});\n\nconst rolePanelStyles = (\n theme: Theme,\n role: ModalPanelRole | undefined,\n capPx: number | null,\n size?: PanelSize,\n exact?: PanelWidth,\n): CSSObject => {\n if (role === 'primary') {\n if (exact) return exactPrimaryPanelStyles(theme, exact);\n return size === 'wide' ? widePrimaryPanelStyles(theme, capPx) : primaryPanelStyles(theme, capPx);\n }\n if (role === 'secondary') return secondaryPanelStyles();\n // Background modals stay mounted but hidden, for performance.\n if (role === 'background') return { display: 'none' };\n return {};\n};\n\nconst glassStyles = (theme: Theme, glass?: boolean, role?: ModalPanelRole): CSSObject =>\n glass && role === 'primary'\n ? {\n backgroundColor: alpha(theme.palette.background.paper, 0.85),\n backdropFilter: `blur(${rem(theme, 10)})`,\n WebkitBackdropFilter: `blur(${rem(theme, 10)})`,\n border: `1px solid ${alpha(theme.palette.divider, 0.18)}`,\n }\n : {};\n\nconst animationByRole = (size?: PanelSize, exact?: PanelWidth): Partial<Record<ModalPanelRole, string>> => {\n if (exact) return EXACT_ANIMATION_BY_ROLE;\n return size === 'wide' ? WIDE_ANIMATION_BY_ROLE : ANIMATION_BY_ROLE;\n};\n\nconst animationStyles = (\n isAnimating?: boolean,\n role?: ModalPanelRole,\n size?: PanelSize,\n exact?: PanelWidth,\n): CSSObject => {\n const byRole = animationByRole(size, exact);\n return isAnimating ? { animation: (role && byRole[role]) ?? 'none' } : {};\n};\n\nconst panelBaseStyles = (theme: Theme): CSSObject => ({\n margin: 0,\n position: 'fixed',\n right: 0,\n top: 0,\n // Pinned to the DYNAMIC viewport: on iOS a `100vh` panel runs underneath the\n // browser toolbar, which parks the tail of the scroll area (the submit row)\n // out of reach. See `dynamicViewportHeight`.\n ...dynamicViewportHeight('height', 'maxHeight'),\n borderRadius: 0,\n willChange: 'transform, width, border-radius',\n transition: theme.transitions.create(\n ['width', 'max-width', 'border-radius', 'transform', 'opacity'],\n { duration: 300, easing: theme.transitions.easing.easeInOut },\n ),\n});\n\nconst panelStyles = (theme: Theme, props: PanelStyleProps): CSSObject => {\n const capPx = cap(props.customMaxWidth);\n return {\n ...panelBaseStyles(theme),\n ...rolePanelStyles(theme, props.modalRole, capPx, props.panelSize, props.panelWidth),\n ...glassStyles(theme, props.glass, props.modalRole),\n ...animationStyles(props.isAnimating, props.modalRole, props.panelSize, props.panelWidth),\n };\n};\n\n/** The full rule set for the sliding panel's Dialog root. */\nexport const dialogRootStyles = (theme: Theme, props: PanelStyleProps): CSSObject => ({\n direction: props.rtl ? 'rtl' : 'ltr',\n // The dialog's OWN backdrop only: a descendant selector also reached the\n // backdrop of any sheet or drawer rendered inside the panel, and blurred the\n // very panel that sheet sits on.\n '& > .MuiBackdrop-root': backdropStyles(theme, props.modalRole),\n '& .MuiDialog-container': { alignItems: 'flex-start', justifyContent: 'flex-end' },\n '& .MuiDialog-paper': panelStyles(theme, props),\n ...KEYFRAMES,\n});\n\nexport const titleStyles = (theme: Theme, rtl?: boolean): CSSObject => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: theme.spacing(2, 2.5),\n borderBottom: `1px solid ${theme.palette.divider}`,\n direction: rtl ? 'rtl' : 'ltr',\n});\n\nexport const titleLeftStyles = (theme: Theme): CSSObject => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1.5),\n flex: 1,\n});\n\nexport const titleRightStyles = (theme: Theme): CSSObject => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n});\n\nexport const loadingOverlayStyles = (theme: Theme): CSSObject => ({\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: alpha(theme.palette.background.paper, 0.8),\n zIndex: 9999,\n});\n\nexport const modalContentStyles = (theme: Theme): CSSObject => ({\n padding: theme.spacing(3),\n // MUI's DialogContent defaults to `overflow-y: auto`, but inside a panel it is\n // NOT the element that scrolls — ModalBody above it is, and this box always\n // ends up exactly as tall as its own content. A scroll container that never\n // scrolls is still the containing block for every `position: sticky`\n // descendant, so a sticky header anchored here gets zero travel and rides the\n // content out of view: sticky, and pinned to nothing. Handing the overflow\n // back to ModalBody makes the panel's own scroller the anchor.\n overflowY: 'visible',\n});\n"],"mappings":"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","names":[]}
|
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
} from "./chunk-SALQ65SM.js";
|
|
4
4
|
import {
|
|
5
5
|
useSummaryInfo
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-3FIIMP7I.js";
|
|
7
7
|
import {
|
|
8
8
|
LearnMore,
|
|
9
9
|
PendingSpinner,
|
|
10
10
|
SaveError,
|
|
11
11
|
SettingHeader,
|
|
12
12
|
partTestId
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-ZZO5MRMV.js";
|
|
14
14
|
import {
|
|
15
15
|
SETTING_CARD_OPEN_ATTR,
|
|
16
16
|
actionsStyles,
|
|
@@ -170,4 +170,4 @@ SettingCard.displayName = "SettingCard";
|
|
|
170
170
|
export {
|
|
171
171
|
SettingCard
|
|
172
172
|
};
|
|
173
|
-
//# sourceMappingURL=chunk-
|
|
173
|
+
//# sourceMappingURL=chunk-YQGVO3ZU.js.map
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from "./chunk-JYWF76Z5.js";
|
|
13
13
|
import {
|
|
14
14
|
Chip
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-NI67M453.js";
|
|
16
16
|
import {
|
|
17
17
|
Icon
|
|
18
18
|
} from "./chunk-SEWUYHSG.js";
|
|
@@ -139,4 +139,4 @@ export {
|
|
|
139
139
|
PendingSpinner,
|
|
140
140
|
LearnMore
|
|
141
141
|
};
|
|
142
|
-
//# sourceMappingURL=chunk-
|
|
142
|
+
//# sourceMappingURL=chunk-ZZO5MRMV.js.map
|