Compare commits

...

6 Commits

Author SHA1 Message Date
seb
056e4f63b6 u 2026-10-08 21:25:20 +02:00
seb
6578f7d1ac u 2026-10-08 21:20:40 +02:00
seb
f91c50ef69 u 2026-10-08 21:19:15 +02:00
seb
7f988c9d63 u 2026-10-08 21:17:30 +02:00
seb
064dd2bd31 u 2026-10-08 21:06:34 +02:00
seb
457c41ab1d u 2026-10-08 21:02:50 +02:00
11 changed files with 226 additions and 153 deletions

View File

@@ -104,41 +104,6 @@
html { html {
scrollbar-gutter: stable; scrollbar-gutter: stable;
} }
:root {
--df-zoom: 1;
--df-vh: 100vh;
}
@media (max-width: 1699.98px) {
:root {
--df-zoom: 0.8;
--df-vh: calc(100vh / 0.8);
}
body {
zoom: 0.8;
}
}
@media (max-width: 1399.98px) {
:root {
--df-zoom: 0.65;
--df-vh: calc(100vh / 0.65);
}
body {
zoom: 0.65;
}
}
@media (max-width: 999.98px) {
:root {
--df-zoom: 0.5;
--df-vh: calc(100vh / 0.5);
}
body {
zoom: 0.5;
}
}
</style> </style>
</head> </head>

View File

@@ -345,11 +345,18 @@ export const SHADOW_BUBBLE_ASSISTANT = `0 1px 4px ${TINT_ROW_HOVER}`;
* dialog is open (`html.df-dialog-open` in `src/index.css`). * dialog is open (`html.df-dialog-open` in `src/index.css`).
* -------------------------------------------------------------------------*/ * -------------------------------------------------------------------------*/
/** Opaque fog base — deep navy with a blue push. */ /** Raw deep-navy base tint used for the dialog fog backdrop. */
export const DIALOG_FOG_SOLID = mix(DARK_6, CHROMA.BLUE.dark, 0.42); export const DIALOG_FOG_NAVY = mix(DARK_6, CHROMA.BLUE.dark, 0.42);
/** Translucent backdrop wash painted over the page. */ /** Translucent backdrop wash painted over the page. */
export const DIALOG_FOG = alpha(DIALOG_FOG_SOLID, 0.72); export const DIALOG_FOG = alpha(DIALOG_FOG_NAVY, 0.72);
/**
* Solid fog color seen when DIALOG_FOG (72% opacity) is drawn over MAIN_BACKGROUND.
* Published as `--df-dialog-fog` so the reserved scrollbar-gutter strip on
* `html.df-dialog-open` seamlessly matches the translucent fog backdrop over the app.
*/
export const DIALOG_FOG_SOLID = mix(MAIN_BACKGROUND, DIALOG_FOG_NAVY, 0.72);
/* ──────────────────────────────────────────────────────────────────────────── /* ────────────────────────────────────────────────────────────────────────────
* 11. CSS VARIABLE BRIDGE * 11. CSS VARIABLE BRIDGE

View File

@@ -60,6 +60,7 @@ class AppDialog extends Component {
transitionDuration: _transitionDuration, transitionDuration: _transitionDuration,
TransitionProps: _transitionProps, TransitionProps: _transitionProps,
TransitionComponent: _transitionComponent, TransitionComponent: _transitionComponent,
disableScrollLock = true,
slotProps: userSlotProps, slotProps: userSlotProps,
slots: userSlots, slots: userSlots,
...rest ...rest
@@ -95,6 +96,7 @@ class AppDialog extends Component {
return ( return (
<Dialog <Dialog
disableScrollLock={disableScrollLock}
disableEnforceFocus disableEnforceFocus
{...rest} {...rest}
slots={restSlots} slots={restSlots}

View File

@@ -185,6 +185,8 @@ class AppSubNav extends PureComponent {
sx={{ sx={{
width: SUB_NAV_WIDTH, width: SUB_NAV_WIDTH,
flexShrink: 0, flexShrink: 0,
ml: 3,
mr: 2,
}} }}
/> />
); );
@@ -204,7 +206,10 @@ class AppSubNav extends PureComponent {
position: 'sticky', position: 'sticky',
top: 0, top: 0,
alignSelf: 'flex-start', alignSelf: 'flex-start',
height: 'var(--df-vh, 100vh)',
py: 4, py: 4,
ml: 3,
mr: 2,
}} }}
> >
{subNav.map(({ segment, label, title, help, icon: Icon }) => { {subNav.map(({ segment, label, title, help, icon: Icon }) => {
@@ -296,26 +301,24 @@ export default function AppShell() {
return ( return (
<Box sx={{ display: 'flex', minHeight: 'var(--df-vh, 100vh)', bgcolor: 'background.default' }}> <Box sx={{ display: 'flex', minHeight: 'var(--df-vh, 100vh)', bgcolor: 'background.default' }}>
<AppSidebar activeNav={activeNav} navigate={navigate} /> <AppSidebar activeNav={activeNav} navigate={navigate} />
<AppSubNav
activeNav={activeNav}
activeSub={activeSub}
navigate={navigate}
/>
<Box <Box
component="main" component="main"
sx={(theme) => ({ sx={(theme) => ({
flexGrow: 1, flexGrow: 1,
display: 'flex', display: 'flex',
gap: 2, flexDirection: 'column',
py: 4, py: 4,
px: 3, pr: 3,
bgcolor: theme.nav.mainBackground, bgcolor: theme.nav.mainBackground,
minWidth: 0, minWidth: 0,
})} })}
> >
<AppSubNav <Outlet />
activeNav={activeNav}
activeSub={activeSub}
navigate={navigate}
/>
<Box sx={{ flexGrow: 1, minWidth: 0 }}>
<Outlet />
</Box>
</Box> </Box>
<ChatFab /> <ChatFab />
<ChatDrawer /> <ChatDrawer />

View File

@@ -3,9 +3,9 @@ import Autocomplete from '@mui/material/Autocomplete';
import TextInput from '../../TextInput'; import TextInput from '../../TextInput';
import Typography from '@mui/material/Typography'; import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box'; import Box from '@mui/material/Box';
import { EditablePanelTile } from 'dashgui/panels'; import { EditablePanelTile, PanelTile } from 'dashgui/panels';
import brandAutomat from '../../../automats/brandAutomat'; import brandAutomat from '../../../automats/brandAutomat';
import artikelAutomat from '../../../automats/artikelAutomat'; import artikelAutomat, { getArticle } from '../../../automats/artikelAutomat';
import { requireObject } from '../../../utils/apiShape'; import { requireObject } from '../../../utils/apiShape';
import { notifyError } from '../../../utils/notify'; import { notifyError } from '../../../utils/notify';
import InputAdornment from '@mui/material/InputAdornment'; import InputAdornment from '@mui/material/InputAdornment';
@@ -33,12 +33,13 @@ class PanelValue extends Component {
} }
} }
function brandDraftValue(article) { function brandDraftValue(article, parentArticle) {
const brand = article?.brand || parentArticle?.brand;
return { return {
name: article?.brand?.name ?? '', name: brand?.name ?? '',
thumbHash: article?.brand?.thumbHash ?? null, thumbHash: brand?.thumbHash ?? null,
thumbW: article?.brand?.thumbW ?? null, thumbW: brand?.thumbW ?? null,
thumbH: article?.brand?.thumbH ?? null, thumbH: brand?.thumbH ?? null,
}; };
} }
@@ -128,12 +129,27 @@ export default class ArticleViewBrand extends PureComponent {
this.unsub = brandAutomat.subscribe(this, (state) => ({ this.unsub = brandAutomat.subscribe(this, (state) => ({
brands: state.brands ?? [], brands: state.brands ?? [],
})); }));
const parentSku = this.props.article?.parentSku || this.props.article?.parent_sku;
if (parentSku && !getArticle(parentSku)) {
void artikelAutomat.actions.loadArticle(parentSku).catch(() => {});
}
this.unsubArtikel = artikelAutomat.subscribe(this, () => ({}));
}
componentDidUpdate(prevProps) {
const parentSku = this.props.article?.parentSku || this.props.article?.parent_sku;
const prevParentSku = prevProps.article?.parentSku || prevProps.article?.parent_sku;
if (parentSku && parentSku !== prevParentSku && !getArticle(parentSku)) {
void artikelAutomat.actions.loadArticle(parentSku).catch(() => {});
}
} }
componentWillUnmount() { componentWillUnmount() {
this._cancelled = true; this._cancelled = true;
this.unsub?.(); this.unsub?.();
this.unsub = null; this.unsub = null;
this.unsubArtikel?.();
this.unsubArtikel = null;
} }
handleSave = async (draft) => { handleSave = async (draft) => {
@@ -170,7 +186,40 @@ export default class ArticleViewBrand extends PureComponent {
render() { render() {
const { article: articleData } = this.props; const { article: articleData } = this.props;
const { brands } = this.state; const { brands } = this.state;
const value = brandDraftValue(articleData); const isChild = Boolean(
articleData?.parentSku ||
articleData?.parent_sku ||
articleData?.parentArticleId != null ||
articleData?.parentId != null ||
articleData?.parent_id != null
);
const parentSku = articleData?.parentSku || articleData?.parent_sku;
const parentArticle = parentSku ? getArticle(parentSku) : null;
const value = brandDraftValue(articleData, parentArticle);
if (isChild) {
const brandObj = articleData?.brand || parentArticle?.brand || (value.name ? value : null);
return (
<PanelTile
title="Marke"
wide={1}
minHeight={SECOND_ROW_MIN_HEIGHT}
color={PURPLE_BG}
>
<PanelValue>
{value.name ? (
<BrandLabel
brand={brandObj}
name={value.name}
size={22}
typographyProps={{ variant: 'body2', fontWeight: 600 }}
/>
) : null}
</PanelValue>
</PanelTile>
);
}
return ( return (
<EditablePanelTile <EditablePanelTile

View File

@@ -85,10 +85,18 @@ export default class ArticleViewStock extends PureComponent {
const hasWarehouses = warehouses.length > 0; const hasWarehouses = warehouses.length > 0;
let totalVariantsStock = 0; let totalVariantsStock = 0;
let anyVariantTracksStock = false;
if (isParent) { if (isParent) {
const children = Array.isArray(articleData?.children) ? articleData.children : []; const children = Array.isArray(articleData?.children) ? articleData.children : [];
for (const child of children) { for (const child of children) {
const fullChild = getArticle(child.sku) || child; const fullChild = getArticle(child.sku) || child;
const tracks =
fullChild.track_stock !== false &&
fullChild.track_stock !== 0 &&
fullChild.track_stock !== '0';
if (tracks) {
anyVariantTracksStock = true;
}
if (Array.isArray(fullChild.warehouses) && fullChild.warehouses.length > 0) { if (Array.isArray(fullChild.warehouses) && fullChild.warehouses.length > 0) {
totalVariantsStock += fullChild.warehouses.reduce( totalVariantsStock += fullChild.warehouses.reduce(
(sum, wh) => sum + (Number(wh.stock) || 0), (sum, wh) => sum + (Number(wh.stock) || 0),
@@ -155,19 +163,21 @@ export default class ArticleViewStock extends PureComponent {
</Typography> </Typography>
{isParent ? ( {isParent ? (
<Box sx={{ my: 0.75 }}> anyVariantTracksStock || totalVariantsStock > 0 ? (
<Typography <Box sx={{ my: 0.75 }}>
component="div" <Typography
sx={{ component="div"
fontSize: '1.25rem', sx={{
fontWeight: 700, fontSize: '1.25rem',
lineHeight: 1.2, fontWeight: 700,
color: 'text.primary', lineHeight: 1.2,
}} color: 'text.primary',
> }}
Alle Varianten zusammen: {formatStock(totalVariantsStock)} >
</Typography> Alle Varianten zusammen: {formatStock(totalVariantsStock)}
</Box> </Typography>
</Box>
) : null
) : isStueckliste ? ( ) : isStueckliste ? (
<Tooltip title="Virtueller Bestand – Anpassung erfolgt an den einzelnen Komponenten" arrow placement="top-start"> <Tooltip title="Virtueller Bestand – Anpassung erfolgt an den einzelnen Komponenten" arrow placement="top-start">
<Box sx={{ my: 0.5 }}> <Box sx={{ my: 0.5 }}>

View File

@@ -290,7 +290,7 @@ export default class BrandImageSearchDialog extends PureComponent {
</IconButton> </IconButton>
</DialogTitle> </DialogTitle>
<DialogContent dividers sx={{ p: 2.5 }}> <DialogContent dividers>
{/* Search bar */} {/* Search bar */}
<Box <Box
component="form" component="form"

View File

@@ -112,12 +112,24 @@ export default class ChatDrawer extends PureComponent {
}, delay); }, delay);
}; };
updateGutterClass(isOpen) {
if (typeof document === 'undefined') return;
const html = document.documentElement;
if (!html) return;
if (isOpen) {
html.classList.add('df-chat-open');
} else {
html.classList.remove('df-chat-open');
}
}
componentDidMount() { componentDidMount() {
this.updateGutterClass(this.state.isOpen);
if (this.state.isOpen) { if (this.state.isOpen) {
if (chatAutomat.state.pendingInput != null) { if (chatAutomat.state.pendingInput != null) {
this.focusInputAtEnd(150); this.focusInputAtEnd(0);
} else { } else {
this.focusInput(150); this.focusInput(0);
} }
} }
void this.loadModelSettings(); void this.loadModelSettings();
@@ -157,9 +169,9 @@ export default class ChatDrawer extends PureComponent {
chatAutomat.setState({ pendingInput: null }); chatAutomat.setState({ pendingInput: null });
} }
}); });
this.focusInputAtEnd(150); this.focusInputAtEnd(0);
} else if (!wasOpen && willOpen) { } else if (!wasOpen && willOpen) {
this.focusInput(150); this.focusInput(0);
} }
return patch; return patch;
}); });
@@ -177,7 +189,14 @@ export default class ChatDrawer extends PureComponent {
})); }));
} }
componentDidUpdate(prevProps, prevState) {
if (this.state.isOpen !== prevState.isOpen) {
this.updateGutterClass(this.state.isOpen);
}
}
componentWillUnmount() { componentWillUnmount() {
this.updateGutterClass(false);
if (this.focusTimeout) clearTimeout(this.focusTimeout); if (this.focusTimeout) clearTimeout(this.focusTimeout);
this.unsub?.(); this.unsub?.();
this.unsubSettings?.(); this.unsubSettings?.();
@@ -1605,13 +1624,17 @@ export default class ChatDrawer extends PureComponent {
anchor="right" anchor="right"
open={isOpen} open={isOpen}
onClose={this.handleClose} onClose={this.handleClose}
disableScrollLock
transitionDuration={0}
ModalProps={{ ModalProps={{
disableScrollLock: true,
disableEnforceFocus: true, disableEnforceFocus: true,
}} }}
sx={(theme) => ({ sx={(theme) => ({
zIndex: theme.zIndex.modal + 10, zIndex: theme.zIndex.modal + 10,
'& .MuiBackdrop-root': { '& .MuiBackdrop-root': {
backgroundColor: DIALOG_FOG, backgroundColor: DIALOG_FOG,
transition: 'none !important',
}, },
'& .MuiDrawer-paper': { '& .MuiDrawer-paper': {
width: { xs: '100vw', sm: `${totalWidth}px` }, width: { xs: '100vw', sm: `${totalWidth}px` },
@@ -1621,12 +1644,13 @@ export default class ChatDrawer extends PureComponent {
boxShadow: SHADOW_DRAWER, boxShadow: SHADOW_DRAWER,
position: 'fixed', position: 'fixed',
overflow: 'visible', overflow: 'visible',
transition: isResizing ? 'none !important' : undefined, transition: 'none !important',
}, },
})} })}
slotProps={{ slotProps={{
transition: { transition: {
onEntered: () => this.focusInput(20), timeout: 0,
onEntered: () => this.focusInput(0),
}, },
paper: { paper: {
sx: { sx: {
@@ -1637,7 +1661,7 @@ export default class ChatDrawer extends PureComponent {
boxShadow: SHADOW_DRAWER, boxShadow: SHADOW_DRAWER,
position: 'fixed', position: 'fixed',
overflow: 'visible', overflow: 'visible',
transition: isResizing ? 'none !important' : undefined, transition: 'none !important',
}, },
}, },
}} }}

View File

@@ -13,9 +13,9 @@ import chatAutomat, { selectPendingAskUser, selectHasPendingAsk } from '../../au
import { import {
CHAT_BUSY, CHAT_BUSY,
CHAT_FAB_BUSY, CHAT_FAB_BUSY,
CHAT_FAB_PENDING, CHAT_FAB_SHADOW_BUSY, CHAT_FAB_PENDING, CHAT_FAB_SHADOW_BUSY,
CHAT_FAB_SHADOW_IDLE, CHAT_FAB_SHADOW_IDLE,
CHAT_FAB_SHADOW_PENDING, RED, CHAT_FAB_SHADOW_PENDING, RED,
RED_GLOW, RED_GLOW,
WHITE, WHITE,
} from '../../colors'; } from '../../colors';
@@ -59,18 +59,12 @@ export default class ChatFab extends PureComponent {
const { isOpen, conversationState, streamPhase, isSending, hasPendingAsk, pendingAsk } = this.state; const { isOpen, conversationState, streamPhase, isSending, hasPendingAsk, pendingAsk } = this.state;
const isBusy = conversationState === 'busy' || streamPhase === 'thinking' || streamPhase === 'working' || isSending; const isBusy = conversationState === 'busy' || streamPhase === 'thinking' || streamPhase === 'working' || isSending;
let tooltipTitle = 'KI-Chat öffnen';
let ariaLabel = 'KI-Chat'; let ariaLabel = 'KI-Chat';
if (isOpen) { if (isOpen) {
tooltipTitle = 'KI-Chat schließen';
ariaLabel = 'KI-Chat schließen'; ariaLabel = 'KI-Chat schließen';
} else if (hasPendingAsk) { } else if (hasPendingAsk) {
tooltipTitle = pendingAsk?.question
? `Antwort erforderlich: „${pendingAsk.question}“`
: 'Antwort erforderlich: Das Modell wartet auf Ihre Eingabe';
ariaLabel = 'KI-Chat: Antwort erforderlich'; ariaLabel = 'KI-Chat: Antwort erforderlich';
} else if (isBusy) { } else if (isBusy) {
tooltipTitle = 'Modell antwortet gerade…';
ariaLabel = 'KI-Chat: Modell antwortet'; ariaLabel = 'KI-Chat: Modell antwortet';
} }
@@ -143,77 +137,75 @@ export default class ChatFab extends PureComponent {
/> />
)} )}
<Tooltip title={tooltipTitle} placement="right" arrow> <Badge
<Badge badgeContent={hasPendingAsk ? '?' : undefined}
badgeContent={hasPendingAsk ? '?' : undefined} color={hasPendingAsk ? 'error' : isBusy ? 'warning' : 'default'}
color={hasPendingAsk ? 'error' : isBusy ? 'warning' : 'default'} variant={hasPendingAsk ? 'standard' : 'dot'}
variant={hasPendingAsk ? 'standard' : 'dot'} invisible={!hasPendingAsk && !isBusy}
invisible={!hasPendingAsk && !isBusy} overlap="circular"
overlap="circular" anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }} sx={{
sx={{ '& .MuiBadge-badge': hasPendingAsk
'& .MuiBadge-badge': hasPendingAsk ? {
? { bgcolor: RED,
bgcolor: RED, color: WHITE,
color: WHITE, fontWeight: 900,
fontWeight: 900, fontSize: '0.85rem',
fontSize: '0.85rem', minWidth: 22,
minWidth: 22, height: 22,
height: 22, borderRadius: '50%',
borderRadius: '50%', boxShadow: `0 2px 10px ${RED_GLOW}`,
boxShadow: `0 2px 10px ${RED_GLOW}`, animation: 'badgePop 1.5s ease infinite',
animation: 'badgePop 1.5s ease infinite', '@keyframes badgePop': {
'@keyframes badgePop': { '0%, 100%': { transform: 'scale(1)' },
'0%, 100%': { transform: 'scale(1)' }, '50%': { transform: 'scale(1.2)' },
'50%': { transform: 'scale(1.2)' }, },
}, }
} : undefined,
: undefined, }}
}} >
> <Fab
<Fab color="primary"
color="primary" aria-label={ariaLabel}
aria-label={ariaLabel} onClick={this.handleClick}
onClick={this.handleClick} sx={(theme) => ({
sx={(theme) => ({ width: 54,
width: 54, height: 54,
height: 54, boxShadow: hasPendingAsk
boxShadow: hasPendingAsk ? CHAT_FAB_SHADOW_PENDING
? CHAT_FAB_SHADOW_PENDING : isBusy
: isBusy
? CHAT_FAB_SHADOW_BUSY ? CHAT_FAB_SHADOW_BUSY
: CHAT_FAB_SHADOW_IDLE, : CHAT_FAB_SHADOW_IDLE,
background: hasPendingAsk background: hasPendingAsk
? CHAT_FAB_PENDING ? CHAT_FAB_PENDING
: isBusy : isBusy
? CHAT_FAB_BUSY ? CHAT_FAB_BUSY
: `linear-gradient(135deg, ${theme.palette.primary.main} 0%, ${theme.palette.primary.dark} 100%)`, : `linear-gradient(135deg, ${theme.palette.primary.main} 0%, ${theme.palette.primary.dark} 100%)`,
})} })}
> >
{isOpen ? ( {isOpen ? (
<CloseRoundedIcon sx={{ fontSize: 24 }} /> <CloseRoundedIcon sx={{ fontSize: 24 }} />
) : hasPendingAsk ? ( ) : hasPendingAsk ? (
<HelpOutlineRoundedIcon <HelpOutlineRoundedIcon
sx={{ sx={{
fontSize: 26, fontSize: 26,
animation: 'fabWiggle 2s ease infinite', animation: 'fabWiggle 2s ease infinite',
'@keyframes fabWiggle': { '@keyframes fabWiggle': {
'0%, 100%': { transform: 'rotate(0deg)' }, '0%, 100%': { transform: 'rotate(0deg)' },
'15%': { transform: 'rotate(-12deg)' }, '15%': { transform: 'rotate(-12deg)' },
'30%': { transform: 'rotate(12deg)' }, '30%': { transform: 'rotate(12deg)' },
'45%': { transform: 'rotate(-8deg)' }, '45%': { transform: 'rotate(-8deg)' },
'60%': { transform: 'rotate(0deg)' }, '60%': { transform: 'rotate(0deg)' },
}, },
}} }}
/> />
) : isBusy ? ( ) : isBusy ? (
<AutoAwesomeRoundedIcon sx={{ fontSize: 24 }} /> <AutoAwesomeRoundedIcon sx={{ fontSize: 24 }} />
) : ( ) : (
<ChatRoundedIcon sx={{ fontSize: 24 }} /> <ChatRoundedIcon sx={{ fontSize: 24 }} />
)} )}
</Fab> </Fab>
</Badge> </Badge>
</Tooltip>
</Box> </Box>
</Box> </Box>
); );

View File

@@ -44,6 +44,15 @@ html {
scrollbar-gutter: stable; scrollbar-gutter: stable;
} }
/* While the assistant chat drawer is open on the right edge of the screen,
the reserved scrollbar-gutter strip must read as white to seamlessly
continue the drawer surface. */
html.df-chat-open,
html.df-chat-open body,
html.df-chat-open #root {
background-color: #ffffff;
}
/* While any AppDialog is open, the reserved scrollbar-gutter strip must read /* While any AppDialog is open, the reserved scrollbar-gutter strip must read
as fog, not app background. AppDialog toggles `df-dialog-open` on <html> as fog, not app background. AppDialog toggles `df-dialog-open` on <html>
(ref-counted for stacked dialogs). The solid fog token is published by (ref-counted for stacked dialogs). The solid fog token is published by
@@ -51,7 +60,7 @@ html {
html.df-dialog-open, html.df-dialog-open,
html.df-dialog-open body, html.df-dialog-open body,
html.df-dialog-open #root { html.df-dialog-open #root {
background-color: var(--df-dialog-fog, #152e73); background-color: var(--df-dialog-fog, #345585);
} }
/* SortableJS: Kategorie-Reorder im Edit-Modus. /* SortableJS: Kategorie-Reorder im Edit-Modus.

View File

@@ -44,9 +44,20 @@ export function createDefaultTheme() {
}, },
nav, nav,
components: { components: {
MuiModal: {
defaultProps: {
disableScrollLock: true,
},
},
MuiDialog: {
defaultProps: {
disableScrollLock: true,
},
},
MuiMenu: { MuiMenu: {
defaultProps: { defaultProps: {
transitionDuration: 0, transitionDuration: 0,
disableScrollLock: true,
}, },
}, },
MuiButton: { MuiButton: {
@@ -79,6 +90,7 @@ export function createDefaultTheme() {
MuiPopover: { MuiPopover: {
defaultProps: { defaultProps: {
transitionDuration: 0, transitionDuration: 0,
disableScrollLock: true,
}, },
}, },
}, },