Skip to content

Commit c4446c2

Browse files
committed
fix: relative width
1 parent 8d69beb commit c4446c2

File tree

3 files changed

+103
-29
lines changed

3 files changed

+103
-29
lines changed

src/containers/Drawer/Drawer.tsx

Lines changed: 97 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,41 @@ import {DrawerItem, Drawer as GravityDrawer} from '@gravity-ui/navigation';
44

55
import {cn} from '../../utils/cn';
66

7+
const DEFAULT_DRAWER_WIDTH_PERCENTS = 60;
78
const DEFAULT_DRAWER_WIDTH = 600;
89
const DRAWER_WIDTH_KEY = 'drawer-width';
910
const b = cn('ydb-drawer');
1011

1112
import './Drawer.scss';
1213

13-
interface ContainerProps {
14-
children: React.ReactNode;
15-
className?: string;
14+
// Create a context for sharing container dimensions
15+
interface DrawerContextType {
16+
containerWidth: number;
17+
setContainerWidth: React.Dispatch<React.SetStateAction<number>>;
1618
}
1719

18-
interface WrapperProps {
19-
children: React.ReactNode;
20-
renderDrawerContent: () => React.ReactNode;
21-
isDrawerVisible: boolean;
22-
onCloseDrawer: () => void;
23-
drawerId?: string;
24-
storageKey?: string;
25-
defaultWidth?: number;
26-
direction?: 'left' | 'right';
27-
className?: string;
28-
detectClickOutside?: boolean;
29-
}
20+
const DrawerContext = React.createContext<DrawerContextType | undefined>(undefined);
21+
22+
// Custom hook to use the drawer context
23+
const useDrawerContext = () => {
24+
const context = React.useContext(DrawerContext);
25+
if (context === undefined) {
26+
return {containerWidth: 0, setContainerWidth: () => {}};
27+
}
28+
return context;
29+
};
3030

3131
interface ContentWrapperProps {
3232
isVisible: boolean;
3333
onClose: () => void;
3434
children: React.ReactNode;
3535
drawerId?: string;
3636
storageKey?: string;
37-
defaultWidth?: number;
3837
direction?: 'left' | 'right';
3938
className?: string;
4039
detectClickOutside?: boolean;
40+
defaultWidth?: number;
41+
isPercentageWidth?: boolean;
4142
}
4243

4344
const ContentWrapper = ({
@@ -46,17 +47,28 @@ const ContentWrapper = ({
4647
children,
4748
drawerId = 'drawer',
4849
storageKey = DRAWER_WIDTH_KEY,
49-
defaultWidth = DEFAULT_DRAWER_WIDTH,
50+
defaultWidth,
5051
direction = 'right',
5152
className,
5253
detectClickOutside = false,
54+
isPercentageWidth,
5355
}: ContentWrapperProps) => {
5456
const [drawerWidth, setDrawerWidth] = React.useState(() => {
5557
const savedWidth = localStorage.getItem(storageKey);
5658
return savedWidth ? Number(savedWidth) : defaultWidth;
5759
});
5860

5961
const drawerRef = React.useRef<HTMLDivElement>(null);
62+
const {containerWidth} = useDrawerContext();
63+
// Calculate drawer width based on container width percentage if specified
64+
const calculatedWidth = React.useMemo(() => {
65+
if (isPercentageWidth && containerWidth > 0) {
66+
return Math.round(
67+
(containerWidth * (drawerWidth || DEFAULT_DRAWER_WIDTH_PERCENTS)) / 100,
68+
);
69+
}
70+
return drawerWidth || DEFAULT_DRAWER_WIDTH;
71+
}, [containerWidth, isPercentageWidth, drawerWidth]);
6072

6173
React.useEffect(() => {
6274
if (!detectClickOutside) {
@@ -80,8 +92,14 @@ const ContentWrapper = ({
8092
}, [isVisible, onClose, detectClickOutside]);
8193

8294
const handleResizeDrawer = (width: number) => {
83-
setDrawerWidth(width);
84-
localStorage.setItem(storageKey, width.toString());
95+
if (isPercentageWidth && containerWidth > 0) {
96+
const percentageWidth = Math.round((width / containerWidth) * 100);
97+
setDrawerWidth(percentageWidth);
98+
localStorage.setItem(storageKey, percentageWidth.toString());
99+
} else {
100+
setDrawerWidth(width);
101+
localStorage.setItem(storageKey, width.toString());
102+
}
85103
};
86104

87105
return (
@@ -95,7 +113,8 @@ const ContentWrapper = ({
95113
id={drawerId}
96114
visible={isVisible}
97115
resizable
98-
width={drawerWidth}
116+
maxResizeWidth={containerWidth}
117+
width={isPercentageWidth ? calculatedWidth : drawerWidth}
99118
onResize={handleResizeDrawer}
100119
direction={direction}
101120
className={b('item')}
@@ -107,12 +126,65 @@ const ContentWrapper = ({
107126
);
108127
};
109128

129+
interface ContainerProps {
130+
children: React.ReactNode;
131+
className?: string;
132+
}
133+
134+
interface ItemWrapperProps {
135+
children: React.ReactNode;
136+
renderDrawerContent: () => React.ReactNode;
137+
isDrawerVisible: boolean;
138+
onCloseDrawer: () => void;
139+
drawerId?: string;
140+
storageKey?: string;
141+
defaultWidth?: number;
142+
direction?: 'left' | 'right';
143+
className?: string;
144+
detectClickOutside?: boolean;
145+
isPercentageWidth?: boolean;
146+
}
147+
110148
export const Drawer = {
111149
Container: ({children, className}: ContainerProps) => {
112-
return <div className={b('drawer-container', className)}>{children}</div>;
150+
const [containerWidth, setContainerWidth] = React.useState(0);
151+
const containerRef = React.useRef<HTMLDivElement>(null);
152+
153+
React.useEffect(() => {
154+
if (!containerRef.current) {
155+
return undefined;
156+
}
157+
158+
const updateWidth = () => {
159+
if (containerRef.current) {
160+
setContainerWidth(containerRef.current.clientWidth);
161+
}
162+
};
163+
164+
// Set initial width
165+
updateWidth();
166+
167+
// Update width on resize
168+
const resizeObserver = new ResizeObserver(updateWidth);
169+
resizeObserver.observe(containerRef.current);
170+
171+
return () => {
172+
if (containerRef.current) {
173+
resizeObserver.disconnect();
174+
}
175+
};
176+
}, []);
177+
178+
return (
179+
<DrawerContext.Provider value={{containerWidth, setContainerWidth}}>
180+
<div ref={containerRef} className={b('drawer-container', className)}>
181+
{children}
182+
</div>
183+
</DrawerContext.Provider>
184+
);
113185
},
114186

115-
Wrapper: ({
187+
ItemWrapper: ({
116188
children,
117189
renderDrawerContent,
118190
isDrawerVisible,
@@ -123,7 +195,8 @@ export const Drawer = {
123195
direction,
124196
className,
125197
detectClickOutside,
126-
}: WrapperProps) => {
198+
isPercentageWidth,
199+
}: ItemWrapperProps) => {
127200
React.useEffect(() => {
128201
return () => {
129202
onCloseDrawer();
@@ -141,6 +214,7 @@ export const Drawer = {
141214
direction={direction}
142215
className={className}
143216
detectClickOutside={detectClickOutside}
217+
isPercentageWidth={isPercentageWidth}
144218
>
145219
{renderDrawerContent()}
146220
</ContentWrapper>

src/containers/Tenant/Diagnostics/TopQueries/RunningQueriesData.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,14 @@ export const RunningQueriesData = ({
100100
);
101101

102102
return (
103-
<Drawer.Wrapper
103+
<Drawer.ItemWrapper
104104
isDrawerVisible={isDrawerVisible}
105105
onCloseDrawer={handleCloseDetails}
106106
renderDrawerContent={renderDrawerContent}
107107
drawerId="running-query-details"
108108
storageKey="running-queries-drawer-width"
109-
defaultWidth={600}
110109
detectClickOutside
110+
isPercentageWidth
111111
>
112112
<TableWithControlsLayout>
113113
<TableWithControlsLayout.Controls>
@@ -143,6 +143,6 @@ export const RunningQueriesData = ({
143143
/>
144144
</TableWithControlsLayout.Table>
145145
</TableWithControlsLayout>
146-
</Drawer.Wrapper>
146+
</Drawer.ItemWrapper>
147147
);
148148
};

src/containers/Tenant/Diagnostics/TopQueries/TopQueriesData.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,14 @@ export const TopQueriesData = ({
128128
);
129129

130130
return (
131-
<Drawer.Wrapper
131+
<Drawer.ItemWrapper
132132
isDrawerVisible={isDrawerVisible}
133133
onCloseDrawer={handleCloseDetails}
134134
renderDrawerContent={renderDrawerContent}
135135
drawerId="query-details"
136136
storageKey="kv-top-queries-drawer-width"
137-
defaultWidth={600}
138137
detectClickOutside
138+
isPercentageWidth
139139
>
140140
<TableWithControlsLayout>
141141
<TableWithControlsLayout.Controls>
@@ -182,6 +182,6 @@ export const TopQueriesData = ({
182182
/>
183183
</TableWithControlsLayout.Table>
184184
</TableWithControlsLayout>
185-
</Drawer.Wrapper>
185+
</Drawer.ItemWrapper>
186186
);
187187
};

0 commit comments

Comments
 (0)