@12-apps/ui 6.0.0 → 6.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-U3J55YPN.js → chunk-GSEAUMCS.js} +18 -6
- package/dist/chunk-GSEAUMCS.js.map +1 -0
- package/dist/chunk-MQLM43E4.js +15 -0
- package/dist/chunk-MQLM43E4.js.map +1 -0
- package/dist/{chunk-XDP4HLQ3.js → chunk-QZZVHY6U.js} +7 -3
- package/dist/chunk-QZZVHY6U.js.map +1 -0
- package/dist/{chunk-LBYA4ZPT.js → chunk-R4TYXKDD.js} +7 -1
- package/dist/{chunk-LBYA4ZPT.js.map → chunk-R4TYXKDD.js.map} +1 -1
- package/dist/data-display/DataViews.js +16 -15
- package/dist/data-display/DataViews.js.map +1 -1
- package/dist/feedback/Dialog.js +1 -1
- package/dist/feedback/StackedModal.js +2 -1
- package/dist/form/CategorySelect.js +2 -1
- package/dist/form/CreatableSelect.js +4 -1
- package/dist/form/CreatableSelect.js.map +1 -1
- package/dist/form/total-form.js +2 -1
- package/dist/form/total-form.js.map +1 -1
- package/dist/navigation/AppHeader.js +1 -1
- package/dist/tokens/layers.js +16 -0
- package/dist/tokens/layers.js.map +1 -0
- package/dist/types/components/feedback/Dialog/Dialog.d.ts.map +1 -1
- package/dist/types/components/feedback/StackedModal/modal-stack.d.ts.map +1 -1
- package/dist/types/components/form/CategorySelect/CategoryPanelSurface.d.ts.map +1 -1
- package/dist/types/components/form/CreatableSelect/CreatableSelect.d.ts.map +1 -1
- package/dist/types/tokens/layers.d.ts +63 -0
- package/dist/types/tokens/layers.d.ts.map +1 -0
- package/package.json +6 -2
- package/src/components/feedback/Dialog/Dialog.md +40 -1
- package/src/components/feedback/Dialog/Dialog.tsx +50 -7
- package/src/components/feedback/StackedModal/StackedModal.md +26 -0
- package/src/components/feedback/StackedModal/modal-stack.tsx +10 -3
- package/src/components/form/CategorySelect/CategoryPanelSurface.tsx +15 -0
- package/src/components/form/CreatableSelect/CreatableSelect.tsx +5 -2
- package/src/tokens/layers.ts +70 -0
- package/dist/chunk-U3J55YPN.js.map +0 -1
- package/dist/chunk-XDP4HLQ3.js.map +0 -1
|
@@ -167,12 +167,24 @@ function backdropSxOf(theme, glass) {
|
|
|
167
167
|
|
|
168
168
|
// src/components/feedback/Dialog/Dialog.tsx
|
|
169
169
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
170
|
+
function hasSpacingSlot(children) {
|
|
171
|
+
return React.Children.toArray(children).some((child) => {
|
|
172
|
+
if (!React.isValidElement(child)) return false;
|
|
173
|
+
if (child.type === DialogContent || child.type === DialogActions) return true;
|
|
174
|
+
if (child.type !== React.Fragment) return false;
|
|
175
|
+
return hasSpacingSlot(child.props.children);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
var BODY_SX = {
|
|
179
|
+
px: 3,
|
|
180
|
+
pb: 2.5,
|
|
181
|
+
"&:has(> .MuiDialogContent-root), &:has(> .MuiDialogActions-root)": {
|
|
182
|
+
display: "contents"
|
|
183
|
+
}
|
|
184
|
+
};
|
|
170
185
|
function bodyOf(children, hasTitle) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
);
|
|
174
|
-
if (managesOwnSpacing) return children;
|
|
175
|
-
return /* @__PURE__ */ jsx(Box, { sx: { px: 3, pb: 2.5, pt: hasTitle ? 0.5 : 2.5 }, children });
|
|
186
|
+
if (hasSpacingSlot(children)) return children;
|
|
187
|
+
return /* @__PURE__ */ jsx(Box, { sx: { ...BODY_SX, pt: hasTitle ? 0.5 : 2.5 }, children });
|
|
176
188
|
}
|
|
177
189
|
var DIALOG_DEFAULTS = {
|
|
178
190
|
variant: "default",
|
|
@@ -387,4 +399,4 @@ export {
|
|
|
387
399
|
DialogContent,
|
|
388
400
|
DialogActions
|
|
389
401
|
};
|
|
390
|
-
//# sourceMappingURL=chunk-
|
|
402
|
+
//# sourceMappingURL=chunk-GSEAUMCS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/feedback/Dialog/Dialog.tsx","../src/components/feedback/Dialog/Dialog.styles.ts"],"sourcesContent":["import CloseIcon from '@mui/icons-material/Close';\nimport {\n Backdrop,\n Box,\n Dialog as MuiDialog,\n DialogActions as MuiDialogActions,\n DialogContent as MuiDialogContent,\n DialogTitle as MuiDialogTitle,\n Drawer,\n IconButton,\n Typography,\n useTheme,\n} from '@mui/material';\nimport React from 'react';\n\nimport { backdropSxOf, variantStylesOf } from './Dialog.styles';\nimport type {\n DialogActionsProps,\n DialogContentProps,\n DialogHeaderProps,\n DialogProps,\n} from './Dialog.types';\n\n/**\n * Does this hand us a spacing slot? Fragments are transparent: `<>` is a way of\n * passing several children, not a child that owns them, and a consumer who\n * groups a `DialogContent` and a `DialogActions` in one has still passed both.\n *\n * Only the slots themselves count, and only at the top. A `DialogContent`\n * genuinely nested inside a `<div>` is that div's content, and the dialog\n * padding the div is right.\n */\nfunction hasSpacingSlot(children: React.ReactNode): boolean {\n return React.Children.toArray(children).some((child) => {\n if (!React.isValidElement(child)) return false;\n if (child.type === DialogContent || child.type === DialogActions) return true;\n if (child.type !== React.Fragment) return false;\n return hasSpacingSlot((child.props as { children?: React.ReactNode }).children);\n });\n}\n\n/**\n * The padding a dialog gives children that are not managing their own — and the\n * rule that takes it back when it turns out they are.\n *\n * `:has()` is doing what {@link hasSpacingSlot} cannot. A slot passed through a\n * COMPONENT (`<Body />` rendering a `DialogContent`) is invisible to any check\n * on element type: React does not know what a component renders until it has\n * rendered it, and by then the wrapper is already in the tree. The selector\n * asks the question one step later, of the DOM, where the answer exists.\n *\n * `display: contents` rather than `padding: 0`, because the padding is only\n * half of what a wrapper does. The other half is standing between the paper and\n * its children: MUI's `scroll=\"paper\"` makes the paper a flex column with\n * `overflow-y: auto`, so a `DialogContent` that is no longer its direct child\n * cannot be the thing that scrolls — the whole dialog scrolls instead and\n * carries the `DialogActions` off the bottom with it. An element with\n * `display: contents` generates no box at all: its children become the paper's\n * flex items, and its padding is never applied. Both halves, one declaration.\n *\n * A browser without `:has()` falls back to the padded box — the layout this\n * had before, not a broken one.\n */\nconst BODY_SX = {\n px: 3,\n pb: 2.5,\n '&:has(> .MuiDialogContent-root), &:has(> .MuiDialogActions-root)': {\n display: 'contents',\n },\n} as const;\n\n/**\n * The dialog body. Consumers that pass raw children (no <DialogContent>) used\n * to render them flush against the paper edges — give them comfortable default\n * padding; <DialogContent>/<DialogActions> users keep managing their own\n * spacing.\n */\nfunction bodyOf(children: React.ReactNode, hasTitle: boolean): React.ReactNode {\n if (hasSpacingSlot(children)) return children;\n return <Box sx={{ ...BODY_SX, pt: hasTitle ? 0.5 : 2.5 }}>{children}</Box>;\n}\n\nconst DIALOG_DEFAULTS = {\n variant: 'default',\n size: 'md',\n showCloseButton: true,\n backdrop: true,\n persistent: false,\n glass: false,\n gradient: false,\n glow: false,\n pulse: false,\n borderRadius: 'lg',\n} as const satisfies Partial<DialogProps>;\n\n/** DialogProps with every defaulted field guaranteed present (wide types). */\ntype DialogPropsWithDefaults = DialogProps &\n Required<Pick<DialogProps, keyof typeof DIALOG_DEFAULTS>>;\n\n/**\n * Apply {@link DIALOG_DEFAULTS} exactly like parameter defaults would: only a\n * missing/`undefined` prop falls back (a loop, so the component's cyclomatic\n * complexity doesn't pay one branch per defaulted prop).\n */\nfunction withDialogDefaults(props: DialogProps): DialogPropsWithDefaults {\n const merged: Record<string, unknown> = { ...props };\n for (const [key, value] of Object.entries(DIALOG_DEFAULTS)) {\n if (merged[key] === undefined) merged[key] = value;\n }\n return merged as unknown as DialogPropsWithDefaults;\n}\n\nexport const Dialog: React.FC<DialogProps> = (rawProps) => {\n const {\n children,\n variant,\n size,\n title,\n description,\n showCloseButton,\n backdrop,\n persistent,\n glass,\n gradient,\n glow,\n pulse,\n borderRadius,\n onClose,\n open,\n dataTestId,\n ...props\n } = withDialogDefaults(rawProps);\n const theme = useTheme();\n const testId = dataTestId || 'dialog';\n const paperSx = variantStylesOf(theme, {\n variant, size, borderRadius, glass, gradient, glow, pulse,\n });\n\n const handleClose = (event: object, reason: 'backdropClick' | 'escapeKeyDown') => {\n if (persistent && (reason === 'backdropClick' || reason === 'escapeKeyDown')) {\n return;\n }\n onClose?.();\n };\n\n const header = title ? (\n <DialogHeader\n title={title}\n subtitle={description}\n showCloseButton={showCloseButton}\n onClose={onClose}\n dataTestId={dataTestId}\n />\n ) : null;\n const body = bodyOf(children, Boolean(title));\n\n if (variant === 'drawer') {\n return (\n <Drawer\n anchor=\"right\"\n open={open}\n onClose={onClose}\n data-testid={testId}\n {...props}\n >\n <Box sx={{ ...paperSx, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>\n {header}\n {body}\n </Box>\n </Drawer>\n );\n }\n\n return (\n <MuiDialog\n open={open}\n onClose={handleClose}\n fullScreen={variant === 'fullscreen'}\n BackdropComponent={backdrop ? Backdrop : undefined}\n BackdropProps={{ sx: backdropSxOf(theme, glass) }}\n PaperProps={{ sx: paperSx, 'data-testid': testId }}\n {...props}\n >\n {header}\n {body}\n </MuiDialog>\n );\n};\n\nexport const DialogHeader: React.FC<DialogHeaderProps> = ({\n children,\n title,\n subtitle,\n showCloseButton = true,\n onClose,\n dataTestId,\n}) => {\n if (children) {\n return (\n <Box sx={{ p: 2, borderBottom: '1px solid', borderColor: 'divider' }}>\n {children}\n </Box>\n );\n }\n\n return (\n <MuiDialogTitle\n data-testid={dataTestId ? `${dataTestId}-title` : 'dialog-title'}\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n pb: subtitle ? 1 : 2,\n }}\n >\n <Box>\n <Typography variant=\"h6\" component=\"div\">\n {title}\n </Typography>\n {subtitle && (\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mt: 0.5 }}>\n {subtitle}\n </Typography>\n )}\n </Box>\n {showCloseButton && onClose && (\n <IconButton\n aria-label=\"close\"\n onClick={onClose}\n data-testid={dataTestId ? `${dataTestId}-close` : 'dialog-close'}\n sx={{\n color: 'text.secondary',\n '&:hover': {\n backgroundColor: 'action.hover',\n },\n }}\n >\n <CloseIcon />\n </IconButton>\n )}\n </MuiDialogTitle>\n );\n};\n\n/**\n * Top padding for a body that sits directly under the title.\n *\n * MUI zeroes it there (`.MuiDialogTitle-root + &` on a non-`dividers` content),\n * assuming the title's own bottom padding is the whole gap. That assumption\n * breaks for a body opening with an outlined field: a filled field floats its\n * label ABOVE the input's border box, and `DialogContent` is `overflow-y: auto`\n * — a clipping box — so the label gets sliced in half (FUT-544: \"Tipo\" in the\n * \"Novo insumo\" dialog).\n *\n * Reserve the overhang rather than restore the full 24px: the title already\n * contributes its bottom padding, so a shrunk label's `translate(…, -9px)` is\n * all that is missing. 12px clears it and leaves the gap visually tight.\n */\nconst TITLED_BODY_PADDING_TOP = 1.5;\n\n/**\n * `.MuiDialogTitle-root + &` is `(0,2,0)`-specific and a plain `sx` entry is\n * `(0,1,0)`, so the padding above only survives the cascade by naming the class\n * again — `(0,3,0)`. Scoped to the title-following case so an untitled dialog\n * keeps MUI's roomier default.\n */\nconst TITLED_BODY_SELECTOR = '.MuiDialogTitle-root + &.MuiDialogContent-root';\n\nexport const DialogContent: React.FC<DialogContentProps> = ({\n children,\n dividers = false,\n dense = false,\n dataTestId,\n ...props\n}) => (\n <MuiDialogContent\n data-testid={dataTestId ? `${dataTestId}-content` : 'dialog-content'}\n dividers={dividers}\n sx={{\n padding: dense ? 1.5 : 3,\n [TITLED_BODY_SELECTOR]: { paddingTop: TITLED_BODY_PADDING_TOP },\n '&.MuiDialogContent-dividers': {\n borderTop: dividers ? '1px solid' : 'none',\n borderBottom: dividers ? '1px solid' : 'none',\n borderColor: 'divider',\n },\n }}\n {...props}\n >\n {children}\n </MuiDialogContent>\n );\n\nexport const DialogActions: React.FC<DialogActionsProps> = ({\n children,\n alignment = 'right',\n spacing = 1,\n dataTestId,\n ...props\n}) => {\n const getJustifyContent = () => {\n switch (alignment) {\n case 'left': return 'flex-start';\n case 'center': return 'center';\n case 'right': return 'flex-end';\n case 'space-between': return 'space-between';\n default: return 'flex-end';\n }\n };\n\n return (\n <MuiDialogActions\n data-testid={dataTestId ? `${dataTestId}-actions` : 'dialog-actions'}\n sx={{\n justifyContent: getJustifyContent(),\n gap: spacing,\n p: 2,\n }}\n {...props}\n >\n {children}\n </MuiDialogActions>\n );\n};","import type { SxProps, Theme } from '@mui/material';\nimport { alpha, keyframes } from '@mui/material';\n\nimport { dynamicViewportHeight } from '../../../utils/viewport';\nimport type { DialogProps } from './Dialog.types';\n\n/**\n * Paper/backdrop styling for the Dialog component (FUT-181 gate cleanup):\n * pure helpers so `Dialog.tsx` stays within the size/complexity budget.\n */\n\n// Define pulse animation\nconst pulseAnimation = keyframes`\n 0% {\n box-shadow: 0 0 0 0 currentColor;\n opacity: 1;\n }\n 70% {\n box-shadow: 0 0 0 20px currentColor;\n opacity: 0;\n }\n 100% {\n box-shadow: 0 0 0 0 currentColor;\n opacity: 0;\n }\n`;\n\n/** Style toggles that shape the dialog paper (extracted so each fn stays small). */\ninterface VariantStyleOptions {\n variant: NonNullable<DialogProps['variant']>;\n size: NonNullable<DialogProps['size']>;\n borderRadius: NonNullable<DialogProps['borderRadius']>;\n glass: boolean;\n gradient: boolean;\n glow: boolean;\n pulse: boolean;\n}\n\nfunction borderRadiusOf(theme: Theme, borderRadius: VariantStyleOptions['borderRadius']) {\n switch (borderRadius) {\n case 'none': return 0;\n case 'sm': return theme.spacing(0.5);\n case 'md': return theme.spacing(1);\n case 'xl': return theme.spacing(3);\n case 'lg':\n default: return theme.spacing(2);\n }\n}\n\nfunction maxWidthOf(size: VariantStyleOptions['size']): number {\n switch (size) {\n case 'xs': return 400;\n case 'sm': return 600;\n case 'lg': return 1000;\n case 'xl': return 1200;\n case 'md':\n default: return 800;\n }\n}\n\nfunction baseStylesOf(theme: Theme, opts: VariantStyleOptions) {\n return {\n borderRadius: borderRadiusOf(theme, opts.borderRadius),\n maxWidth: maxWidthOf(opts.size),\n width: '90vw',\n margin: theme.spacing(2),\n transition: theme.transitions.create(\n ['box-shadow', 'background-color', 'backdrop-filter'],\n { duration: theme.transitions.duration.standard },\n ),\n };\n}\n\nfunction glowStylesOf(theme: Theme, glow: boolean) {\n return glow ? { boxShadow: `0 0 40px ${alpha(theme.palette.primary.main, 0.3)}` } : {};\n}\n\nfunction pulseStylesOf(theme: Theme, pulse: boolean) {\n if (!pulse) return {};\n return {\n position: 'relative' as const,\n '&::after': {\n content: '\"\"',\n position: 'absolute' as const,\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n borderRadius: 'inherit',\n backgroundColor: theme.palette.primary.main,\n opacity: 0.3,\n animation: `${pulseAnimation} 2s infinite`,\n pointerEvents: 'none' as const,\n zIndex: -1,\n },\n };\n}\n\n/** The default variant's paper: optional gradient/glass over the base styles. */\nfunction defaultVariantStyles(theme: Theme, opts: VariantStyleOptions) {\n const gradientStyles = opts.gradient\n ? {\n background: `linear-gradient(135deg, ${alpha(theme.palette.primary.main, 0.1)}, ${alpha(theme.palette.secondary.main, 0.1)})`,\n backdropFilter: 'blur(10px)',\n }\n : {};\n return {\n ...gradientStyles,\n backgroundColor: opts.glass\n ? alpha(theme.palette.background.paper, 0.1)\n : theme.palette.background.paper,\n backdropFilter: opts.glass ? 'blur(20px)' : 'none',\n border: opts.glass ? `1px solid ${alpha(theme.palette.primary.main, 0.2)}` : 'none',\n };\n}\n\nexport function variantStylesOf(theme: Theme, opts: VariantStyleOptions): SxProps<Theme> {\n const decorations = {\n ...glowStylesOf(theme, opts.glow),\n ...pulseStylesOf(theme, opts.pulse),\n };\n switch (opts.variant) {\n case 'glass':\n return {\n ...baseStylesOf(theme, opts),\n ...decorations,\n backgroundColor: alpha(theme.palette.background.paper, 0.1),\n backdropFilter: 'blur(20px)',\n border: `1px solid ${alpha(theme.palette.primary.main, 0.2)}`,\n boxShadow: `0 8px 32px ${alpha(theme.palette.common.black, 0.1)}`,\n };\n case 'fullscreen':\n return {\n borderRadius: 0,\n margin: 0,\n width: '100vw',\n // `100dvh`, not `100vh` — see `dynamicViewportHeight`.\n ...dynamicViewportHeight('height'),\n maxWidth: 'none',\n maxHeight: 'none',\n ...decorations,\n };\n case 'drawer': {\n const radius = borderRadiusOf(theme, opts.borderRadius);\n return {\n borderRadius: `${radius}px 0 0 ${radius}px`,\n margin: 0,\n width: maxWidthOf(opts.size),\n ...dynamicViewportHeight('height'),\n maxHeight: 'none',\n position: 'absolute' as const,\n right: 0,\n ...decorations,\n };\n }\n default:\n return {\n ...baseStylesOf(theme, opts),\n ...decorations,\n ...defaultVariantStyles(theme, opts),\n };\n }\n}\n\nexport function backdropSxOf(theme: Theme, glass: boolean) {\n return {\n backgroundColor: glass\n ? alpha(theme.palette.common.black, 0.2)\n : alpha(theme.palette.common.black, 0.5),\n backdropFilter: glass ? 'blur(8px)' : 'none',\n };\n}\n\n"],"mappings":";;;;;AAAA,OAAO,eAAe;AACtB;AAAA,EACE;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,OAAO,WAAW;;;ACZlB,SAAS,OAAO,iBAAiB;AAWjC,IAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0BvB,SAAS,eAAe,OAAc,cAAmD;AACvF,UAAQ,cAAc;AAAA,IACpB,KAAK;AAAQ,aAAO;AAAA,IACpB,KAAK;AAAM,aAAO,MAAM,QAAQ,GAAG;AAAA,IACnC,KAAK;AAAM,aAAO,MAAM,QAAQ,CAAC;AAAA,IACjC,KAAK;AAAM,aAAO,MAAM,QAAQ,CAAC;AAAA,IACjC,KAAK;AAAA,IACL;AAAS,aAAO,MAAM,QAAQ,CAAC;AAAA,EACjC;AACF;AAEA,SAAS,WAAW,MAA2C;AAC7D,UAAQ,MAAM;AAAA,IACZ,KAAK;AAAM,aAAO;AAAA,IAClB,KAAK;AAAM,aAAO;AAAA,IAClB,KAAK;AAAM,aAAO;AAAA,IAClB,KAAK;AAAM,aAAO;AAAA,IAClB,KAAK;AAAA,IACL;AAAS,aAAO;AAAA,EAClB;AACF;AAEA,SAAS,aAAa,OAAc,MAA2B;AAC7D,SAAO;AAAA,IACL,cAAc,eAAe,OAAO,KAAK,YAAY;AAAA,IACrD,UAAU,WAAW,KAAK,IAAI;AAAA,IAC9B,OAAO;AAAA,IACP,QAAQ,MAAM,QAAQ,CAAC;AAAA,IACvB,YAAY,MAAM,YAAY;AAAA,MAC5B,CAAC,cAAc,oBAAoB,iBAAiB;AAAA,MACpD,EAAE,UAAU,MAAM,YAAY,SAAS,SAAS;AAAA,IAClD;AAAA,EACF;AACF;AAEA,SAAS,aAAa,OAAc,MAAe;AACjD,SAAO,OAAO,EAAE,WAAW,YAAY,MAAM,MAAM,QAAQ,QAAQ,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC;AACvF;AAEA,SAAS,cAAc,OAAc,OAAgB;AACnD,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,SAAO;AAAA,IACL,UAAU;AAAA,IACV,YAAY;AAAA,MACV,SAAS;AAAA,MACT,UAAU;AAAA,MACV,KAAK;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,iBAAiB,MAAM,QAAQ,QAAQ;AAAA,MACvC,SAAS;AAAA,MACT,WAAW,GAAG,cAAc;AAAA,MAC5B,eAAe;AAAA,MACf,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAGA,SAAS,qBAAqB,OAAc,MAA2B;AACrE,QAAM,iBAAiB,KAAK,WACxB;AAAA,IACE,YAAY,2BAA2B,MAAM,MAAM,QAAQ,QAAQ,MAAM,GAAG,CAAC,KAAK,MAAM,MAAM,QAAQ,UAAU,MAAM,GAAG,CAAC;AAAA,IAC1H,gBAAgB;AAAA,EAClB,IACA,CAAC;AACL,SAAO;AAAA,IACL,GAAG;AAAA,IACH,iBAAiB,KAAK,QAClB,MAAM,MAAM,QAAQ,WAAW,OAAO,GAAG,IACzC,MAAM,QAAQ,WAAW;AAAA,IAC7B,gBAAgB,KAAK,QAAQ,eAAe;AAAA,IAC5C,QAAQ,KAAK,QAAQ,aAAa,MAAM,MAAM,QAAQ,QAAQ,MAAM,GAAG,CAAC,KAAK;AAAA,EAC/E;AACF;AAEO,SAAS,gBAAgB,OAAc,MAA2C;AACvF,QAAM,cAAc;AAAA,IAClB,GAAG,aAAa,OAAO,KAAK,IAAI;AAAA,IAChC,GAAG,cAAc,OAAO,KAAK,KAAK;AAAA,EACpC;AACA,UAAQ,KAAK,SAAS;AAAA,IACpB,KAAK;AACH,aAAO;AAAA,QACL,GAAG,aAAa,OAAO,IAAI;AAAA,QAC3B,GAAG;AAAA,QACH,iBAAiB,MAAM,MAAM,QAAQ,WAAW,OAAO,GAAG;AAAA,QAC1D,gBAAgB;AAAA,QAChB,QAAQ,aAAa,MAAM,MAAM,QAAQ,QAAQ,MAAM,GAAG,CAAC;AAAA,QAC3D,WAAW,cAAc,MAAM,MAAM,QAAQ,OAAO,OAAO,GAAG,CAAC;AAAA,MACjE;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,cAAc;AAAA,QACd,QAAQ;AAAA,QACR,OAAO;AAAA;AAAA,QAEP,GAAG,sBAAsB,QAAQ;AAAA,QACjC,UAAU;AAAA,QACV,WAAW;AAAA,QACX,GAAG;AAAA,MACL;AAAA,IACF,KAAK,UAAU;AACb,YAAM,SAAS,eAAe,OAAO,KAAK,YAAY;AACtD,aAAO;AAAA,QACL,cAAc,GAAG,MAAM,UAAU,MAAM;AAAA,QACvC,QAAQ;AAAA,QACR,OAAO,WAAW,KAAK,IAAI;AAAA,QAC3B,GAAG,sBAAsB,QAAQ;AAAA,QACjC,WAAW;AAAA,QACX,UAAU;AAAA,QACV,OAAO;AAAA,QACP,GAAG;AAAA,MACL;AAAA,IACF;AAAA,IACA;AACE,aAAO;AAAA,QACL,GAAG,aAAa,OAAO,IAAI;AAAA,QAC3B,GAAG;AAAA,QACH,GAAG,qBAAqB,OAAO,IAAI;AAAA,MACrC;AAAA,EACJ;AACF;AAEO,SAAS,aAAa,OAAc,OAAgB;AACzD,SAAO;AAAA,IACL,iBAAiB,QACb,MAAM,MAAM,QAAQ,OAAO,OAAO,GAAG,IACrC,MAAM,MAAM,QAAQ,OAAO,OAAO,GAAG;AAAA,IACzC,gBAAgB,QAAQ,cAAc;AAAA,EACxC;AACF;;;AD5FS,cAsFD,YAtFC;AA/CT,SAAS,eAAe,UAAoC;AAC1D,SAAO,MAAM,SAAS,QAAQ,QAAQ,EAAE,KAAK,CAAC,UAAU;AACtD,QAAI,CAAC,MAAM,eAAe,KAAK,EAAG,QAAO;AACzC,QAAI,MAAM,SAAS,iBAAiB,MAAM,SAAS,cAAe,QAAO;AACzE,QAAI,MAAM,SAAS,MAAM,SAAU,QAAO;AAC1C,WAAO,eAAgB,MAAM,MAAyC,QAAQ;AAAA,EAChF,CAAC;AACH;AAwBA,IAAM,UAAU;AAAA,EACd,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,oEAAoE;AAAA,IAClE,SAAS;AAAA,EACX;AACF;AAQA,SAAS,OAAO,UAA2B,UAAoC;AAC7E,MAAI,eAAe,QAAQ,EAAG,QAAO;AACrC,SAAO,oBAAC,OAAI,IAAI,EAAE,GAAG,SAAS,IAAI,WAAW,MAAM,IAAI,GAAI,UAAS;AACtE;AAEA,IAAM,kBAAkB;AAAA,EACtB,SAAS;AAAA,EACT,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,UAAU;AAAA,EACV,MAAM;AAAA,EACN,OAAO;AAAA,EACP,cAAc;AAChB;AAWA,SAAS,mBAAmB,OAA6C;AACvE,QAAM,SAAkC,EAAE,GAAG,MAAM;AACnD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,eAAe,GAAG;AAC1D,QAAI,OAAO,GAAG,MAAM,OAAW,QAAO,GAAG,IAAI;AAAA,EAC/C;AACA,SAAO;AACT;AAEO,IAAM,SAAgC,CAAC,aAAa;AACzD,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,IAAI,mBAAmB,QAAQ;AAC/B,QAAM,QAAQ,SAAS;AACvB,QAAM,SAAS,cAAc;AAC7B,QAAM,UAAU,gBAAgB,OAAO;AAAA,IACrC;AAAA,IAAS;AAAA,IAAM;AAAA,IAAc;AAAA,IAAO;AAAA,IAAU;AAAA,IAAM;AAAA,EACtD,CAAC;AAED,QAAM,cAAc,CAAC,OAAe,WAA8C;AAChF,QAAI,eAAe,WAAW,mBAAmB,WAAW,kBAAkB;AAC5E;AAAA,IACF;AACA,cAAU;AAAA,EACZ;AAEA,QAAM,SAAS,QACb;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA;AAAA,EACF,IACE;AACJ,QAAM,OAAO,OAAO,UAAU,QAAQ,KAAK,CAAC;AAE5C,MAAI,YAAY,UAAU;AACxB,WACE;AAAA,MAAC;AAAA;AAAA,QACC,QAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA,eAAa;AAAA,QACZ,GAAG;AAAA,QAEJ,+BAAC,OAAI,IAAI,EAAE,GAAG,SAAS,SAAS,QAAQ,eAAe,UAAU,UAAU,SAAS,GACjF;AAAA;AAAA,UACA;AAAA,WACH;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,SAAS;AAAA,MACT,YAAY,YAAY;AAAA,MACxB,mBAAmB,WAAW,WAAW;AAAA,MACzC,eAAe,EAAE,IAAI,aAAa,OAAO,KAAK,EAAE;AAAA,MAChD,YAAY,EAAE,IAAI,SAAS,eAAe,OAAO;AAAA,MAChD,GAAG;AAAA,MAEH;AAAA;AAAA,QACA;AAAA;AAAA;AAAA,EACH;AAEJ;AAEO,IAAM,eAA4C,CAAC;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB;AAAA,EACA;AACF,MAAM;AACJ,MAAI,UAAU;AACZ,WACE,oBAAC,OAAI,IAAI,EAAE,GAAG,GAAG,cAAc,aAAa,aAAa,UAAU,GAChE,UACH;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAa,aAAa,GAAG,UAAU,WAAW;AAAA,MAClD,IAAI;AAAA,QACF,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,IAAI,WAAW,IAAI;AAAA,MACrB;AAAA,MAEA;AAAA,6BAAC,OACC;AAAA,8BAAC,cAAW,SAAQ,MAAK,WAAU,OAChC,iBACH;AAAA,UACC,YACC,oBAAC,cAAW,SAAQ,SAAQ,OAAM,kBAAiB,IAAI,EAAE,IAAI,IAAI,GAC9D,oBACH;AAAA,WAEJ;AAAA,QACC,mBAAmB,WAClB;AAAA,UAAC;AAAA;AAAA,YACC,cAAW;AAAA,YACX,SAAS;AAAA,YACT,eAAa,aAAa,GAAG,UAAU,WAAW;AAAA,YAClD,IAAI;AAAA,cACF,OAAO;AAAA,cACP,WAAW;AAAA,gBACT,iBAAiB;AAAA,cACnB;AAAA,YACF;AAAA,YAEA,8BAAC,aAAU;AAAA;AAAA,QACb;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAgBA,IAAM,0BAA0B;AAQhC,IAAM,uBAAuB;AAEtB,IAAM,gBAA8C,CAAC;AAAA,EAC1D;AAAA,EACA,WAAW;AAAA,EACX,QAAQ;AAAA,EACR;AAAA,EACA,GAAG;AACL,MACI;AAAA,EAAC;AAAA;AAAA,IACC,eAAa,aAAa,GAAG,UAAU,aAAa;AAAA,IACpD;AAAA,IACA,IAAI;AAAA,MACF,SAAS,QAAQ,MAAM;AAAA,MACvB,CAAC,oBAAoB,GAAG,EAAE,YAAY,wBAAwB;AAAA,MAC9D,+BAA+B;AAAA,QAC7B,WAAW,WAAW,cAAc;AAAA,QACpC,cAAc,WAAW,cAAc;AAAA,QACvC,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACC,GAAG;AAAA,IAEH;AAAA;AACH;AAGG,IAAM,gBAA8C,CAAC;AAAA,EAC1D;AAAA,EACA,YAAY;AAAA,EACZ,UAAU;AAAA,EACV;AAAA,EACA,GAAG;AACL,MAAM;AACJ,QAAM,oBAAoB,MAAM;AAC9B,YAAQ,WAAW;AAAA,MACjB,KAAK;AAAQ,eAAO;AAAA,MACpB,KAAK;AAAU,eAAO;AAAA,MACtB,KAAK;AAAS,eAAO;AAAA,MACrB,KAAK;AAAiB,eAAO;AAAA,MAC7B;AAAS,eAAO;AAAA,IAClB;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAa,aAAa,GAAG,UAAU,aAAa;AAAA,MACpD,IAAI;AAAA,QACF,gBAAgB,kBAAkB;AAAA,QAClC,KAAK;AAAA,QACL,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;","names":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// src/tokens/layers.ts
|
|
2
|
+
var MODAL_STACK_BASE_Z_INDEX = 1300;
|
|
3
|
+
var MODAL_STACK_Z_INDEX_STEP = 10;
|
|
4
|
+
var STACKED_OVERLAY_CLEARED_LEVELS = 10;
|
|
5
|
+
var STACKED_OVERLAY_HEADROOM = MODAL_STACK_Z_INDEX_STEP * STACKED_OVERLAY_CLEARED_LEVELS;
|
|
6
|
+
var stackedOverlayZIndex = (theme) => theme.zIndex.modal + STACKED_OVERLAY_HEADROOM;
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
MODAL_STACK_BASE_Z_INDEX,
|
|
10
|
+
MODAL_STACK_Z_INDEX_STEP,
|
|
11
|
+
STACKED_OVERLAY_CLEARED_LEVELS,
|
|
12
|
+
STACKED_OVERLAY_HEADROOM,
|
|
13
|
+
stackedOverlayZIndex
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=chunk-MQLM43E4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tokens/layers.ts"],"sourcesContent":["import type { Theme } from '@mui/material';\n\n/**\n * WHERE A PORTALLED OVERLAY SITS RELATIVE TO A STACK OF SHEETS.\n *\n * `StackedModal` does not put its panels on one layer. Each panel takes its own\n * z-index as it joins the stack — {@link MODAL_STACK_BASE_Z_INDEX} for the\n * first, another {@link MODAL_STACK_Z_INDEX_STEP} for every panel above it — so\n * the top of a two-deep stack sits at 1310, not at `zIndex.modal`.\n *\n * Anything that portals out of a panel has to clear that. MUI's own defaults do\n * not: a `Popover` (and therefore a `Menu`, and therefore a `Select`) renders at\n * `zIndex.modal`, and a temporary `Drawer` a step lower still at\n * `zIndex.drawer`. With exactly one sheet open the numbers tie and portal order\n * settles it in the overlay's favour, which is why this looks fine right up\n * until a second sheet opens over the first.\n *\n * ## What the failure looks like, because it is not \"the panel is invisible\"\n *\n * A `Popover` under a sheet is still a live modal. It takes focus into itself\n * and holds it, and its backdrop is under the sheet too — so no click can reach\n * the backdrop to dismiss it. The trigger flips its chevron, no panel appears,\n * and from that point every keystroke aimed at the rest of the form is swallowed\n * by an input nobody can see. One click on a field that looks inert leaves the\n * whole form inert. Reported downstream as three unrelated blocks being\n * \"disabled\" (12-57).\n *\n * ## Why this is a token and not a prop on each component\n *\n * The invariant belongs to the ladder, and the ladder is `StackedModal`'s. Left\n * to individual components it is a rule each one has to remember, and the ones\n * that did not remember are indistinguishable from the ones that did until a\n * consumer stacks a sheet. `CategorySelect` never had it and `Autocomplete`\n * answered the same question with `zIndex.tooltip` — three different heights for\n * one question, in one package.\n */\n\n/** The z-index `StackedModal` gives the FIRST panel in a stack. */\nexport const MODAL_STACK_BASE_Z_INDEX = 1300;\n\n/** How much higher each panel stacked on top of another one sits. */\nexport const MODAL_STACK_Z_INDEX_STEP = 10;\n\n/**\n * How many stacked panels a portalled overlay is guaranteed to clear.\n *\n * Ten rather than a number derived from the deepest stack anyone has built,\n * because there is nothing to derive it from: a theme is resolved once, at paint\n * time, and knows nothing about how many sheets happen to be open. So the\n * headroom is a constant, and this is the depth it buys.\n */\nexport const STACKED_OVERLAY_CLEARED_LEVELS = 10;\n\n/** The constant added to `zIndex.modal` to clear that many panels — 100. */\nexport const STACKED_OVERLAY_HEADROOM =\n MODAL_STACK_Z_INDEX_STEP * STACKED_OVERLAY_CLEARED_LEVELS;\n\n/**\n * The z-index for a surface that portals out of a sheet and must stay on top of\n * it — a dropdown, a picker panel, a menu.\n *\n * Read from the theme rather than hardcoded so a host that has moved\n * `zIndex.modal` keeps the same relationship instead of a stale absolute.\n *\n * ```tsx\n * <Popover sx={{ zIndex: stackedOverlayZIndex }} … />\n * ```\n */\nexport const stackedOverlayZIndex = (theme: Theme): number =>\n theme.zIndex.modal + STACKED_OVERLAY_HEADROOM;\n"],"mappings":";AAsCO,IAAM,2BAA2B;AAGjC,IAAM,2BAA2B;AAUjC,IAAM,iCAAiC;AAGvC,IAAM,2BACX,2BAA2B;AAatB,IAAM,uBAAuB,CAAC,UACnC,MAAM,OAAO,QAAQ;","names":[]}
|
|
@@ -2,6 +2,10 @@ import {
|
|
|
2
2
|
dynamicViewportHeight,
|
|
3
3
|
safeAreaBottom
|
|
4
4
|
} from "./chunk-TSPG6TWK.js";
|
|
5
|
+
import {
|
|
6
|
+
MODAL_STACK_BASE_Z_INDEX,
|
|
7
|
+
MODAL_STACK_Z_INDEX_STEP
|
|
8
|
+
} from "./chunk-MQLM43E4.js";
|
|
5
9
|
|
|
6
10
|
// src/components/feedback/StackedModal/StackedModal.tsx
|
|
7
11
|
import { Dialog, Slide, styled as styled2 } from "@mui/material";
|
|
@@ -14,8 +18,8 @@ import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } fro
|
|
|
14
18
|
// src/components/feedback/StackedModal/modal-stack.tsx
|
|
15
19
|
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
16
20
|
import { jsx } from "react/jsx-runtime";
|
|
17
|
-
var BASE_Z_INDEX =
|
|
18
|
-
var Z_INDEX_STEP =
|
|
21
|
+
var BASE_Z_INDEX = MODAL_STACK_BASE_Z_INDEX;
|
|
22
|
+
var Z_INDEX_STEP = MODAL_STACK_Z_INDEX_STEP;
|
|
19
23
|
var noop = () => {
|
|
20
24
|
};
|
|
21
25
|
var ModalStackContext = createContext({
|
|
@@ -721,4 +725,4 @@ export {
|
|
|
721
725
|
StackedModalActions,
|
|
722
726
|
StackedModal
|
|
723
727
|
};
|
|
724
|
-
//# sourceMappingURL=chunk-
|
|
728
|
+
//# sourceMappingURL=chunk-QZZVHY6U.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/feedback/StackedModal/StackedModal.tsx","../src/components/feedback/StackedModal/StackedModal.hooks.ts","../src/components/feedback/StackedModal/modal-stack.tsx","../src/components/feedback/StackedModal/StackedModal.parts.tsx","../src/components/feedback/StackedModal/StackedModal.styles.ts"],"sourcesContent":["import { Dialog, Slide, styled } from '@mui/material';\nimport type { TransitionProps } from '@mui/material/transitions';\nimport type { FC } from 'react';\nimport React, { forwardRef, useId } from 'react';\nimport { usePanelChrome } from './StackedModal.hooks';\nimport { modalAriaIds, ModalPanelContents, resolveModalContent } from './StackedModal.parts';\nimport type { PanelStyleProps } from './StackedModal.styles';\nimport { dialogRootStyles, STYLE_ONLY_PROPS } from './StackedModal.styles';\nimport type { StackedModalProps } from './StackedModal.types';\n\nconst StyledDialog = styled(Dialog, {\n shouldForwardProp: (prop) => !STYLE_ONLY_PROPS.includes(prop as string),\n})<PanelStyleProps>(({ theme, ...props }) => dialogRootStyles(theme, props));\n\n/** Panels slide in from the right on every device. */\nconst SlideTransition = forwardRef<HTMLDivElement, TransitionProps>(\n function SlideTransition(props, ref) {\n return (\n <Slide direction=\"left\" ref={ref} {...props}>\n {props.children as React.ReactElement}\n </Slide>\n );\n },\n);\n\nconst DEFAULTS: Partial<StackedModalProps> = {\n open: false,\n glass: false,\n navigationTitle: '',\n closeOnClickOutside: true,\n closeOnEsc: true,\n loading: false,\n loadingText: 'Loading...',\n maxWidth: false,\n disableBackdrop: false,\n disableFocusTrap: false,\n keepMounted: false,\n rtl: false,\n};\n\n/**\n * Fills in the defaults for props the caller left `undefined`. A table plus one\n * loop, rather than a default per destructured prop — each of those is a branch,\n * and fifteen of them put the component over the complexity bar on their own.\n */\nconst withDefaults = (props: StackedModalProps): StackedModalProps => {\n const resolved = { ...props };\n for (const [key, value] of Object.entries(DEFAULTS)) {\n const prop = key as keyof StackedModalProps;\n if (resolved[prop] === undefined) {\n Object.assign(resolved, { [prop]: value });\n }\n }\n return resolved;\n};\n\n/** The modal's props once defaults are applied and its stack identity is settled. */\ntype ResolvedProps = StackedModalProps & { modalId: string };\n\nconst StackedModalPanel: FC<ResolvedProps> = (props) => {\n const {\n open, onClose, glass, navigationTitle, hideClose, children, actions, modalId,\n closeOnClickOutside, closeOnEsc, loading, loadingText, fullScreen, maxWidth, disableBackdrop,\n disableFocusTrap, keepMounted, rtl, dataTestId,\n 'aria-labelledby': ariaLabelledBy, 'aria-describedby': ariaDescribedBy, ...otherProps\n } = props;\n\n const {\n dialogRef, modalRole, isAnimating, showSkeleton, zIndex, isMobile, canGoBack,\n handleBack, handleClose,\n } = usePanelChrome({\n open, modalId, loading, closeOnEsc, closeOnClickOutside, disableFocusTrap, onClose,\n });\n\n // Don't render if in background (performance optimization)\n if (modalRole === 'background' && !keepMounted) return null;\n\n const { content, modalActions, headerActions, hasMobileActions } = resolveModalContent(\n children,\n actions,\n isMobile,\n );\n const { titleId, descId } = modalAriaIds(modalId, ariaLabelledBy, ariaDescribedBy);\n\n return (\n <StyledDialog\n ref={dialogRef}\n open={Boolean(open)}\n onClose={handleClose}\n fullScreen={fullScreen ?? isMobile}\n modalRole={modalRole}\n isAnimating={isAnimating}\n glass={glass}\n rtl={rtl}\n customMaxWidth={maxWidth}\n TransitionComponent={SlideTransition}\n maxWidth={maxWidth}\n disableEscapeKeyDown={!closeOnEsc}\n hideBackdrop={disableBackdrop}\n keepMounted={keepMounted}\n aria-labelledby={titleId}\n aria-describedby={descId}\n data-testid={dataTestId}\n sx={{ zIndex }}\n {...otherProps}\n >\n <ModalPanelContents\n showSkeleton={showSkeleton}\n loadingText={loadingText}\n titleId={titleId}\n descId={descId}\n navigationTitle={navigationTitle}\n hideClose={hideClose}\n canGoBack={canGoBack}\n onBack={handleBack}\n onClose={onClose}\n headerActions={headerActions}\n content={content}\n modalActions={modalActions}\n hasMobileActions={hasMobileActions}\n rtl={rtl}\n dataTestId={dataTestId}\n />\n </StyledDialog>\n );\n};\n\nexport const StackedModal: FC<StackedModalProps> = (props) => {\n // A modal with no caller-supplied id still needs a STABLE one — it keys this\n // panel's entry in the stack, so a value that changed per render (as a\n // `Math.random()` default does) would re-register it on every pass.\n const fallbackId = useId();\n const resolved = withDefaults(props);\n return <StackedModalPanel {...resolved} modalId={resolved.modalId ?? fallbackId} />;\n};\n\n// Re-exported so `./StackedModal` stays the single public entry point for the\n// component and its stack primitives, as the barrel and existing imports expect.\nexport {\n ModalStackProvider,\n ModalStackProvider as StackedModalProvider,\n useModalStack,\n useModalStack as useStackedModal,\n} from './modal-stack';\nexport { StackedModalActions, StackedModalContent } from './StackedModal.parts';\n","import { useMediaQuery, useTheme } from '@mui/material';\nimport type { RefObject } from 'react';\nimport { useEffect, useRef, useState } from 'react';\nimport { useModalStack } from './modal-stack';\nimport type { ModalPanelRole } from './StackedModal.types';\n\nconst FOCUSABLE = 'a[href], button, textarea, input, select, [tabindex]:not([tabindex=\"-1\"])';\n/** MUI Dialog's own default, used when the modal isn't registered in the stack yet. */\nconst FALLBACK_Z_INDEX = 1300;\n/** Matches the panel's slide duration, so role swaps animate rather than jump. */\nconst ROLE_TRANSITION_MS = 300;\n\n/** Keeps Tab cycling inside the open panel instead of escaping to the page behind. */\nconst useFocusTrap = (\n ref: RefObject<HTMLElement | null>,\n isActive: boolean,\n disabled?: boolean,\n): void => {\n useEffect(() => {\n if (!isActive || disabled || !ref.current) return;\n\n const element = ref.current;\n const focusable = element.querySelectorAll(FOCUSABLE);\n const first = focusable[0] as HTMLElement | undefined;\n const last = focusable[focusable.length - 1] as HTMLElement | undefined;\n\n window.setTimeout(() => first?.focus(), 100);\n\n const handleTabKey = (e: globalThis.KeyboardEvent): void => {\n if (e.key !== 'Tab') return;\n const atEdge = e.shiftKey ? first : last;\n if (document.activeElement !== atEdge) return;\n e.preventDefault();\n (e.shiftKey ? last : first)?.focus();\n };\n\n element.addEventListener('keydown', handleTabKey);\n return () => element.removeEventListener('keydown', handleTabKey);\n }, [ref, isActive, disabled]);\n};\n\n/** Closes the panel on Escape — only while it is the top one. */\nconst useEscapeToClose = (active: boolean, onClose: () => void): void => {\n useEffect(() => {\n if (!active) return;\n\n const handleEsc = (e: globalThis.KeyboardEvent): void => {\n if (e.key !== 'Escape') return;\n e.preventDefault();\n onClose();\n };\n\n window.addEventListener('keydown', handleEsc);\n return () => window.removeEventListener('keydown', handleEsc);\n }, [active, onClose]);\n};\n\n/** Holds the skeleton a beat past `loading` so the swap to content isn't a flash. */\nconst useSkeleton = (loading: boolean): boolean => {\n const [showSkeleton, setShowSkeleton] = useState(loading);\n\n useEffect(() => {\n if (loading) {\n setShowSkeleton(true);\n return;\n }\n const timer = window.setTimeout(() => setShowSkeleton(false), 200);\n return () => window.clearTimeout(timer);\n }, [loading]);\n\n return showSkeleton;\n};\n\n/** Registers the modal in the stack while open, and unregisters it after it slides out. */\nconst useStackRegistration = (open: boolean, modalId: string): void => {\n const { pushModal, popModal, isModalInStack } = useModalStack();\n const hasRegisteredRef = useRef(false);\n\n useEffect(() => {\n if (open && !hasRegisteredRef.current) {\n pushModal(modalId);\n hasRegisteredRef.current = true;\n } else if (!open) {\n hasRegisteredRef.current = false;\n }\n }, [open, modalId, pushModal]);\n\n useEffect(() => {\n if (open || !isModalInStack(modalId)) return;\n const timer = window.setTimeout(() => popModal(modalId), ROLE_TRANSITION_MS);\n return () => window.clearTimeout(timer);\n }, [open, modalId, popModal, isModalInStack]);\n};\n\ninterface PanelChromeOptions {\n open?: boolean;\n modalId: string;\n loading?: boolean;\n closeOnEsc?: boolean;\n closeOnClickOutside?: boolean;\n disableFocusTrap?: boolean;\n onClose: () => void;\n}\n\ninterface PanelChrome {\n dialogRef: RefObject<HTMLDivElement | null>;\n modalRole: ModalPanelRole;\n isAnimating: boolean;\n showSkeleton: boolean;\n zIndex: number;\n isMobile: boolean;\n canGoBack: boolean;\n handleBack: () => void;\n handleClose: (event: object, reason: 'backdropClick' | 'escapeKeyDown') => void;\n}\n\n/**\n * Everything the panel needs to render itself: its place in the stack, the\n * viewport it is on, and the handlers that dismiss it. Bundled into one hook so\n * the component stays a description of the markup.\n */\nexport const usePanelChrome = (options: PanelChromeOptions): PanelChrome => {\n const { open, modalId, loading, closeOnEsc, closeOnClickOutside, disableFocusTrap, onClose } =\n options;\n\n const dialogRef = useRef<HTMLDivElement>(null);\n const { currentDepth } = useModalStack();\n const { modalRole, isAnimating } = useModalRole(Boolean(open), modalId);\n const showSkeleton = useSkeleton(Boolean(loading));\n const zIndex = usePanelZIndex(modalId, FALLBACK_Z_INDEX);\n\n const theme = useTheme();\n const isMobile = useMediaQuery(theme.breakpoints.down('sm'));\n const isPrimary = modalRole === 'primary';\n const canGoBack = currentDepth > 1;\n\n useFocusTrap(dialogRef, Boolean(open) && isPrimary, disableFocusTrap);\n useEscapeToClose(Boolean(open && closeOnEsc) && isPrimary, onClose);\n\n const { handleBack, handleClose } = useCloseHandlers({\n isPrimary,\n closeOnClickOutside,\n closeOnEsc,\n canGoBack,\n onClose,\n });\n\n return {\n dialogRef,\n modalRole,\n isAnimating,\n showSkeleton,\n zIndex,\n isMobile,\n canGoBack,\n handleBack,\n handleClose,\n };\n};\n\ninterface CloseHandlerOptions {\n /** Only the top panel responds to a backdrop click or Escape. */\n isPrimary: boolean;\n closeOnClickOutside?: boolean;\n closeOnEsc?: boolean;\n /** Deeper than one panel, so the leading control goes back rather than closing. */\n canGoBack: boolean;\n onClose: () => void;\n}\n\n/** The panel's dismissal handlers, honouring which gestures the caller allows. */\nconst useCloseHandlers = ({\n isPrimary,\n closeOnClickOutside,\n closeOnEsc,\n canGoBack,\n onClose,\n}: CloseHandlerOptions): {\n handleBack: () => void;\n handleClose: (event: object, reason: 'backdropClick' | 'escapeKeyDown') => void;\n} => ({\n handleBack: () => {\n if (canGoBack) onClose();\n },\n handleClose: (_event, reason) => {\n if (!isPrimary) return;\n if (reason === 'backdropClick' && !closeOnClickOutside) return;\n if (reason === 'escapeKeyDown' && !closeOnEsc) return;\n onClose();\n },\n});\n\n/** The z-index this panel was assigned when it joined the stack. */\nconst usePanelZIndex = (modalId: string, fallback: number): number => {\n const { stack } = useModalStack();\n return stack.find((m) => m.id === modalId)?.zIndex ?? fallback;\n};\n\n/**\n * This modal's role in the stack, plus whether it is mid-transition between two\n * roles (which drives the expand/contract animation).\n */\nconst useModalRole = (\n open: boolean,\n modalId: string,\n): { modalRole: ModalPanelRole; isAnimating: boolean } => {\n const { stack } = useModalStack();\n const [modalRole, setModalRole] = useState<ModalPanelRole>('primary');\n const [isAnimating, setIsAnimating] = useState(false);\n\n useStackRegistration(open, modalId);\n\n useEffect(() => {\n if (!open) return;\n\n const newRole = stack.find((m) => m.id === modalId)?.role;\n if (!newRole || newRole === modalRole) return;\n\n setIsAnimating(true);\n setModalRole(newRole);\n const timer = window.setTimeout(() => setIsAnimating(false), ROLE_TRANSITION_MS);\n return () => window.clearTimeout(timer);\n }, [stack, modalId, open, modalRole]);\n\n return { modalRole, isAnimating };\n};\n","import type { FC, ReactNode } from 'react';\nimport { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';\nimport { MODAL_STACK_BASE_Z_INDEX, MODAL_STACK_Z_INDEX_STEP } from '../../../tokens/layers';\nimport type { ModalInfo, ModalPanelRole, ModalStackContextValue } from './StackedModal.types';\n\n/**\n * MUI Dialog default z-index; each panel in the stack sits 10 above the last.\n *\n * Imported rather than declared here: anything that portals out of a panel has\n * to clear this ladder, so the numbers are shared with the token that tells it\n * how — see `tokens/layers`.\n */\nconst BASE_Z_INDEX = MODAL_STACK_BASE_Z_INDEX;\nconst Z_INDEX_STEP = MODAL_STACK_Z_INDEX_STEP;\n\nconst noop = (): void => {\n /** do nothing */\n};\n\nconst ModalStackContext = createContext<ModalStackContextValue>({\n stack: [],\n pushModal: noop,\n popModal: noop,\n clearStack: noop,\n currentDepth: 0,\n isModalInStack: () => false,\n getModalRole: () => null,\n});\n\nexport const useModalStack = (): ModalStackContextValue => {\n const context = useContext(ModalStackContext);\n if (!context) {\n throw new Error('useModalStack must be used within a ModalStackProvider');\n }\n return context;\n};\n\n/** Top of the stack drives the view; the one behind it recedes; the rest are hidden. */\nconst roleAt = (index: number, depth: number): ModalPanelRole => {\n if (index === depth - 1) return 'primary';\n if (index === depth - 2) return 'secondary';\n return 'background';\n};\n\n/** Re-derive every role from stack position — the one place roles are assigned. */\nconst withRoles = (stack: ModalInfo[]): ModalInfo[] =>\n stack.map((modal, index) => ({ ...modal, role: roleAt(index, stack.length) }));\n\n/**\n * Locks body scroll while any modal is open, restoring whatever the page had\n * before. Owned by the provider rather than each modal, so nested panels can't\n * fight over the same style.\n */\nconst useBodyScrollLock = (locked: boolean): void => {\n const originalOverflow = useRef<string>('');\n\n useEffect(() => {\n const restore = (): void => {\n if (!originalOverflow.current) return;\n document.body.style.overflow = originalOverflow.current;\n originalOverflow.current = '';\n };\n\n if (locked) {\n if (!originalOverflow.current) {\n originalOverflow.current = document.body.style.overflow || '';\n }\n document.body.style.overflow = 'hidden';\n } else {\n restore();\n }\n\n return restore;\n }, [locked]);\n};\n\nexport const ModalStackProvider: FC<{ children: ReactNode }> = ({ children }) => {\n const [stack, setStack] = useState<ModalInfo[]>([]);\n\n useBodyScrollLock(stack.length > 0);\n\n const pushModal = useCallback((modalId: string) => {\n setStack((prev) => {\n if (prev.some((m) => m.id === modalId)) return prev;\n const entry: ModalInfo = {\n id: modalId,\n zIndex: BASE_Z_INDEX + prev.length * Z_INDEX_STEP,\n role: 'primary',\n };\n return withRoles([...prev, entry]);\n });\n }, []);\n\n const popModal = useCallback((modalId?: string) => {\n setStack((prev) =>\n withRoles(modalId ? prev.filter((m) => m.id !== modalId) : prev.slice(0, -1)),\n );\n }, []);\n\n const clearStack = useCallback(() => setStack([]), []);\n\n const isModalInStack = useCallback(\n (modalId: string) => stack.some((m) => m.id === modalId),\n [stack],\n );\n\n const getModalRole = useCallback(\n (modalId: string) => stack.find((m) => m.id === modalId)?.role ?? null,\n [stack],\n );\n\n const value = useMemo(\n () => ({\n stack,\n pushModal,\n popModal,\n clearStack,\n currentDepth: stack.length,\n isModalInStack,\n getModalRole,\n }),\n [stack, pushModal, popModal, clearStack, isModalInStack, getModalRole],\n );\n\n return <ModalStackContext.Provider value={value}>{children}</ModalStackContext.Provider>;\n};\n","import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';\nimport CloseIcon from '@mui/icons-material/Close';\nimport {\n Box,\n CircularProgress,\n DialogActions,\n DialogContent,\n DialogTitle,\n IconButton,\n Skeleton,\n styled,\n Typography,\n} from '@mui/material';\nimport type { FC, ReactNode } from 'react';\nimport React from 'react';\nimport { safeAreaBottom } from '../../../utils/viewport';\nimport {\n loadingOverlayStyles,\n modalContentStyles,\n titleLeftStyles,\n titleRightStyles,\n titleStyles,\n} from './StackedModal.styles';\n\nconst StyledDialogTitle = styled(DialogTitle, {\n shouldForwardProp: (prop) => prop !== 'rtl',\n})<{ rtl?: boolean }>(({ theme, rtl }) => titleStyles(theme, rtl));\n\nconst DialogTitleLeft = styled(Box)(({ theme }) => titleLeftStyles(theme));\nconst DialogTitleRight = styled(Box)(({ theme }) => titleRightStyles(theme));\nconst LoadingOverlay = styled(Box)(({ theme }) => loadingOverlayStyles(theme));\n\n/**\n * The padded content wrapper callers put inside a StackedModal. The explicit\n * `typeof DialogContent` annotation keeps its type nameable across package\n * boundaries (TS2742) now that it is re-exported from the barrel.\n */\nexport const StackedModalContent: typeof DialogContent = styled(DialogContent)(({ theme }) =>\n modalContentStyles(theme),\n) as typeof DialogContent;\n\n/** Sub-element test IDs derive from the modal's own, or stay off when it has none. */\nexport const testId = (base: string | undefined, suffix: string): string | undefined =>\n base ? `${base}-${suffix}` : undefined;\n\n/**\n * A wrapper marking the subtree that should render as modal actions — the\n * StackedModal pulls it out of `children` and places it by device.\n */\nexport const StackedModalActions: FC<{ children?: ReactNode }> = ({ children }) => <>{children}</>;\n\n/** Separates the `StackedModalActions` subtree from the rest of the content. */\nconst splitModalChildren = (children: ReactNode): { content: ReactNode; actions: ReactNode } => {\n let actions: ReactNode = null;\n\n React.Children.forEach(children, (child) => {\n if (React.isValidElement<{ children?: ReactNode }>(child) && child.type === StackedModalActions) {\n actions = child.props.children;\n }\n });\n\n const content = React.Children.toArray(children).filter(\n (child) => !(React.isValidElement(child) && child.type === StackedModalActions),\n );\n\n return { content, actions };\n};\n\n/**\n * Works out what renders where: a `StackedModalActions` child wins over the\n * `actions` prop, and on phones those actions move out of the header into a\n * pinned bottom bar.\n */\nexport const resolveModalContent = (\n children: ReactNode,\n actions: ReactNode,\n isMobile: boolean,\n): {\n content: ReactNode;\n modalActions: ReactNode;\n headerActions: ReactNode;\n hasMobileActions: boolean;\n} => {\n const { content, actions: childActions } = splitModalChildren(children);\n const modalActions = childActions ?? actions;\n return {\n content,\n modalActions,\n headerActions: isMobile ? null : modalActions,\n hasMobileActions: Boolean(isMobile && modalActions),\n };\n};\n\n/** The panel's own ARIA ids, unless the caller wired it to its own labels. */\nexport const modalAriaIds = (\n modalId: string,\n ariaLabelledBy?: string,\n ariaDescribedBy?: string,\n): { titleId: string; descId: string } => ({\n titleId: ariaLabelledBy || `modal-title-${modalId}`,\n descId: ariaDescribedBy || `modal-desc-${modalId}`,\n});\n\nexport const ModalLoadingOverlay: FC<{ loadingText?: string; dataTestId?: string }> = ({\n loadingText,\n dataTestId,\n}) => (\n <LoadingOverlay data-testid={testId(dataTestId, 'loading-overlay')}>\n <CircularProgress size={40} data-testid={testId(dataTestId, 'loading-spinner')} />\n {loadingText && (\n <Typography variant=\"body2\" sx={{ mt: 2 }} data-testid={testId(dataTestId, 'loading-text')}>\n {loadingText}\n </Typography>\n )}\n </LoadingOverlay>\n);\n\ninterface ModalHeaderProps {\n titleId: string;\n navigationTitle?: ReactNode;\n /** Deeper than the first panel, so the leading button goes back instead of closing. */\n canGoBack: boolean;\n onBack: () => void;\n onClose: () => void;\n /** Renders the bar without its ✕ — the panel's content owns the dismiss. */\n hideClose?: boolean;\n /** Header actions — desktop only; on phones they move to the footer. */\n headerActions?: ReactNode;\n rtl?: boolean;\n dataTestId?: string;\n}\n\n/**\n * The bar's leading control: back at depth ≥2, otherwise close — and nothing at\n * all when the panel's content carries its own ✕ (`hideClose`).\n */\nconst HeaderLeadingButton: FC<\n Pick<ModalHeaderProps, 'canGoBack' | 'onBack' | 'onClose' | 'hideClose' | 'rtl' | 'dataTestId'>\n> = ({ canGoBack, onBack, onClose, hideClose, rtl, dataTestId }) => {\n if (canGoBack) {\n return (\n <IconButton\n edge=\"start\"\n color=\"inherit\"\n onClick={onBack}\n aria-label=\"go back\"\n size=\"small\"\n sx={{ transform: rtl ? 'rotate(180deg)' : 'none' }}\n data-testid={testId(dataTestId, 'back-button')}\n >\n <ChevronLeftIcon />\n </IconButton>\n );\n }\n if (hideClose) return null;\n return (\n <IconButton\n edge=\"start\"\n color=\"inherit\"\n onClick={onClose}\n aria-label=\"close\"\n size=\"small\"\n data-testid={testId(dataTestId, 'close-button')}\n >\n <CloseIcon />\n </IconButton>\n );\n};\n\nexport const ModalHeader: FC<ModalHeaderProps> = ({\n titleId,\n navigationTitle,\n canGoBack,\n onBack,\n onClose,\n hideClose,\n headerActions,\n rtl,\n dataTestId,\n}) => (\n <StyledDialogTitle id={titleId} rtl={rtl} data-testid={testId(dataTestId, 'header')}>\n <DialogTitleLeft>\n <HeaderLeadingButton\n canGoBack={canGoBack}\n onBack={onBack}\n onClose={onClose}\n hideClose={hideClose}\n rtl={rtl}\n dataTestId={dataTestId}\n />\n {navigationTitle && (\n <Typography\n variant=\"h6\"\n component=\"h2\"\n noWrap\n sx={{ ml: canGoBack || !hideClose ? 1 : 0 }}\n data-testid={testId(dataTestId, 'title')}\n >\n {navigationTitle}\n </Typography>\n )}\n </DialogTitleLeft>\n <DialogTitleRight data-testid={testId(dataTestId, 'header-actions')}>\n {headerActions}\n </DialogTitleRight>\n </StyledDialogTitle>\n);\n\nconst ContentSkeleton: FC = () => (\n <Box sx={{ p: 3 }}>\n <Skeleton variant=\"text\" width=\"60%\" height={32} />\n <Skeleton variant=\"text\" width=\"100%\" />\n <Skeleton variant=\"text\" width=\"100%\" />\n <Skeleton variant=\"rectangular\" height={200} sx={{ mt: 2 }} />\n </Box>\n);\n\ninterface ModalBodyProps {\n descId: string;\n showSkeleton: boolean;\n /** When there is no action bar, the body is what reaches the bottom of the panel. */\n endsPanel: boolean;\n dataTestId?: string;\n children?: ReactNode;\n}\n\nexport const ModalBody: FC<ModalBodyProps> = ({\n descId,\n showSkeleton,\n endsPanel,\n dataTestId,\n children,\n}) => (\n <Box\n id={descId}\n sx={{\n position: 'relative',\n flex: 1,\n overflow: 'auto',\n // iOS momentum scrolling, and no scroll-chaining to the page behind —\n // without `contain`, an overscroll at the end of the list rubber-bands the\n // whole panel and springs back before the last row can be tapped.\n WebkitOverflowScrolling: 'touch',\n overscrollBehavior: 'contain',\n // The content itself ends the panel when there is no action bar, so it has\n // to clear the home indicator on its own.\n ...(endsPanel ? safeAreaBottom(0) : {}),\n }}\n data-testid={testId(dataTestId, 'content')}\n >\n {showSkeleton ? <ContentSkeleton /> : children}\n </Box>\n);\n\n/** The phone-only pinned action bar; on desktop the actions live in the header. */\nexport const ModalFooter: FC<{ dataTestId?: string; children?: ReactNode }> = ({\n dataTestId,\n children,\n}) => (\n <DialogActions\n sx={{\n borderTop: (theme) => `1px solid ${theme.palette.divider}`,\n padding: 2,\n // Never let the action row sit under the iOS home indicator.\n flexShrink: 0,\n ...safeAreaBottom(16),\n }}\n data-testid={testId(dataTestId, 'footer')}\n >\n {children}\n </DialogActions>\n);\n\ninterface PanelContentsProps extends ModalHeaderProps {\n showSkeleton: boolean;\n loadingText?: string;\n descId: string;\n content: ReactNode;\n /** The resolved actions, already placed in the header or destined for the footer. */\n modalActions: ReactNode;\n hasMobileActions: boolean;\n}\n\n/** Everything inside the sliding panel: the loading veil, header, body and action bar. */\nexport const ModalPanelContents: FC<PanelContentsProps> = ({\n showSkeleton,\n loadingText,\n descId,\n content,\n modalActions,\n hasMobileActions,\n ...header\n}) => (\n <>\n {showSkeleton && (\n <ModalLoadingOverlay loadingText={loadingText} dataTestId={header.dataTestId} />\n )}\n <ModalHeader {...header} />\n <ModalBody\n descId={descId}\n showSkeleton={showSkeleton}\n endsPanel={!hasMobileActions}\n dataTestId={header.dataTestId}\n >\n {content}\n </ModalBody>\n {hasMobileActions && (\n <ModalFooter dataTestId={header.dataTestId}>{modalActions}</ModalFooter>\n )}\n </>\n);\n","import { alpha } from '@mui/material';\nimport type { CSSObject, Theme } from '@mui/material';\nimport { dynamicViewportHeight } from '../../../utils/viewport';\nimport type { ModalPanelRole, PanelMaxWidth } 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}\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'];\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\nconst BACKDROP_BY_ROLE: Partial<Record<ModalPanelRole, string>> = {\n secondary: 'rgba(0, 0, 0, 0.3)',\n background: 'rgba(0, 0, 0, 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// 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};\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 = (share: string, capPx: number | null): CSSObject =>\n capPx\n ? { width: `min(${share}, ${capPx}px)`, maxWidth: `${capPx}px` }\n : { width: share, maxWidth: share };\n\nconst backdropStyles = (modalRole?: ModalPanelRole): CSSObject => ({\n backgroundColor: (modalRole && BACKDROP_BY_ROLE[modalRole]) ?? 'rgba(0, 0, 0, 0.5)',\n backdropFilter: modalRole === 'primary' ? 'blur(4px)' : '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('100%', capPx),\n [theme.breakpoints.between('sm', 'lg')]: panelWidth('80vw', capPx),\n [theme.breakpoints.up('lg')]: panelWidth('60vw', capPx),\n '@media (min-width:2200px)': panelWidth('40vw', capPx),\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 = (theme: Theme, role: ModalPanelRole | undefined, capPx: number | null): CSSObject => {\n if (role === 'primary') return primaryPanelStyles(theme, capPx);\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(10px)',\n WebkitBackdropFilter: 'blur(10px)',\n border: `1px solid ${alpha(theme.palette.divider, 0.18)}`,\n }\n : {};\n\nconst animationStyles = (isAnimating?: boolean, role?: ModalPanelRole): CSSObject =>\n isAnimating ? { animation: (role && ANIMATION_BY_ROLE[role]) ?? 'none' } : {};\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),\n ...glassStyles(theme, props.glass, props.modalRole),\n ...animationStyles(props.isAnimating, props.modalRole),\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 '& .MuiBackdrop-root': backdropStyles(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":["styled","useEffect","useRef","useState","useEffect","useState","useRef","jsx","jsx","styled","SlideTransition"]}
|
|
@@ -3,6 +3,9 @@ import {
|
|
|
3
3
|
FormLabel,
|
|
4
4
|
FormMessage
|
|
5
5
|
} from "./chunk-FD4W36WR.js";
|
|
6
|
+
import {
|
|
7
|
+
stackedOverlayZIndex
|
|
8
|
+
} from "./chunk-MQLM43E4.js";
|
|
6
9
|
|
|
7
10
|
// src/components/form/CategorySelect/CategorySelect.tsx
|
|
8
11
|
import { useEffect, useMemo as useMemo4, useRef as useRef2 } from "react";
|
|
@@ -1072,6 +1075,7 @@ function PanelFooter({
|
|
|
1072
1075
|
import { Drawer, Popover } from "@mui/material";
|
|
1073
1076
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1074
1077
|
var BARE_PAPER = { background: "transparent", boxShadow: "none" };
|
|
1078
|
+
var ABOVE_SHEETS = { zIndex: stackedOverlayZIndex };
|
|
1075
1079
|
function CategoryPanelSurface({
|
|
1076
1080
|
open,
|
|
1077
1081
|
sheet,
|
|
@@ -1086,6 +1090,7 @@ function CategoryPanelSurface({
|
|
|
1086
1090
|
anchor: "bottom",
|
|
1087
1091
|
open,
|
|
1088
1092
|
onClose,
|
|
1093
|
+
sx: ABOVE_SHEETS,
|
|
1089
1094
|
slotProps: { paper: { sx: BARE_PAPER } },
|
|
1090
1095
|
children
|
|
1091
1096
|
}
|
|
@@ -1100,6 +1105,7 @@ function CategoryPanelSurface({
|
|
|
1100
1105
|
anchorOrigin: { vertical: "bottom", horizontal: "left" },
|
|
1101
1106
|
transformOrigin: { vertical: "top", horizontal: "left" },
|
|
1102
1107
|
marginThreshold: 8,
|
|
1108
|
+
sx: ABOVE_SHEETS,
|
|
1103
1109
|
slotProps: { paper: { sx: { ...BARE_PAPER, marginTop: "6px", overflow: "visible" } } },
|
|
1104
1110
|
children
|
|
1105
1111
|
}
|
|
@@ -1589,4 +1595,4 @@ export {
|
|
|
1589
1595
|
filterCategoryGroups,
|
|
1590
1596
|
CategorySelect
|
|
1591
1597
|
};
|
|
1592
|
-
//# sourceMappingURL=chunk-
|
|
1598
|
+
//# sourceMappingURL=chunk-R4TYXKDD.js.map
|