Skip to content

Commit ce13b7f

Browse files
authored
fix: drawer is broken (#2351)
1 parent 6c72cce commit ce13b7f

File tree

2 files changed

+39
-23
lines changed

2 files changed

+39
-23
lines changed

src/components/Drawer/Drawer.tsx

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22

33
import {Xmark} from '@gravity-ui/icons';
44
import {DrawerItem, Drawer as GravityDrawer} from '@gravity-ui/navigation';
5-
import {ActionTooltip, Button, Flex, Icon, Text} from '@gravity-ui/uikit';
5+
import {ActionTooltip, Button, Flex, Icon, Portal, Text} from '@gravity-ui/uikit';
66

77
import {cn} from '../../utils/cn';
88
import {isNumeric} from '../../utils/utils';
@@ -52,7 +52,7 @@ const DrawerPaneContentWrapper = ({
5252
});
5353

5454
const drawerRef = React.useRef<HTMLDivElement>(null);
55-
const {containerWidth} = useDrawerContext();
55+
const {containerWidth, itemContainerRef} = useDrawerContext();
5656
// Calculate drawer width based on container width percentage if specified
5757
const calculatedWidth = React.useMemo(() => {
5858
if (isPercentageWidth && containerWidth > 0) {
@@ -103,29 +103,36 @@ const DrawerPaneContentWrapper = ({
103103
(event.nativeEvent as DrawerEvent)._capturedInsideDrawer = true;
104104
};
105105

106+
const itemContainer = itemContainerRef?.current;
107+
if (!itemContainer) {
108+
return null;
109+
}
110+
106111
return (
107-
<GravityDrawer
108-
onEscape={onClose}
109-
onVeilClick={onClose}
110-
hideVeil
111-
className={b('container', className)}
112-
>
113-
<DrawerItem
114-
id={drawerId}
115-
visible={isVisible}
116-
resizable
117-
maxResizeWidth={containerWidth}
118-
width={isPercentageWidth ? calculatedWidth : drawerWidth}
119-
onResize={handleResizeDrawer}
120-
direction={direction}
121-
className={b('item')}
122-
ref={detectClickOutside ? drawerRef : undefined}
112+
<Portal container={itemContainer}>
113+
<GravityDrawer
114+
onEscape={onClose}
115+
onVeilClick={onClose}
116+
hideVeil
117+
className={b('container', className)}
123118
>
124-
<div className={b('click-handler')} onClickCapture={handleClickInsideDrawer}>
125-
{children}
126-
</div>
127-
</DrawerItem>
128-
</GravityDrawer>
119+
<DrawerItem
120+
id={drawerId}
121+
visible={isVisible}
122+
resizable
123+
maxResizeWidth={containerWidth}
124+
width={isPercentageWidth ? calculatedWidth : drawerWidth}
125+
onResize={handleResizeDrawer}
126+
direction={direction}
127+
className={b('item')}
128+
ref={detectClickOutside ? drawerRef : undefined}
129+
>
130+
<div className={b('click-handler')} onClickCapture={handleClickInsideDrawer}>
131+
{children}
132+
</div>
133+
</DrawerItem>
134+
</GravityDrawer>
135+
</Portal>
129136
);
130137
};
131138

src/components/Drawer/DrawerContext.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ const b = cn('ydb-drawer');
88

99
export interface DrawerContextType {
1010
containerWidth: number;
11+
itemContainerRef: React.RefObject<HTMLDivElement> | null;
1112
setContainerWidth: React.Dispatch<React.SetStateAction<number>>;
1213
}
1314

1415
const DrawerContext = React.createContext<DrawerContextType>({
1516
containerWidth: 0,
17+
itemContainerRef: null,
1618
setContainerWidth: () => {},
1719
});
1820

@@ -24,6 +26,7 @@ interface DrawerContextProviderProps {
2426
export const DrawerContextProvider = ({children, className}: DrawerContextProviderProps) => {
2527
const [containerWidth, setContainerWidth] = React.useState(0);
2628
const containerRef = React.useRef<HTMLDivElement>(null);
29+
const itemContainerRef = React.useRef<HTMLDivElement>(null);
2730

2831
React.useEffect(() => {
2932
if (!containerRef.current) {
@@ -55,6 +58,7 @@ export const DrawerContextProvider = ({children, className}: DrawerContextProvid
5558
() => ({
5659
containerWidth,
5760
setContainerWidth,
61+
itemContainerRef,
5862
}),
5963
[containerWidth],
6064
);
@@ -63,6 +67,11 @@ export const DrawerContextProvider = ({children, className}: DrawerContextProvid
6367
<DrawerContext.Provider value={value}>
6468
<div ref={containerRef} className={b('drawer-container', className)}>
6569
{children}
70+
{/*
71+
Children styles should not affect drawer container behaviour
72+
So we mount it out of children in a separate portal
73+
*/}
74+
<div ref={itemContainerRef} className={b('item-container')} />
6675
</div>
6776
</DrawerContext.Provider>
6877
);

0 commit comments

Comments
 (0)