Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions src/components/Fullscreen/Fullscreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {Button, Icon} from '@gravity-ui/uikit';
import {disableFullscreen} from '../../store/reducers/fullscreen';
import {cn} from '../../utils/cn';
import {useTypedDispatch, useTypedSelector} from '../../utils/hooks';
import {useResizeObserverTrigger} from '../../utils/hooks/useResizeObserverTrigger';
import {Portal} from '../Portal/Portal';

import {useFullscreenContext} from './FullscreenContext';
Expand Down Expand Up @@ -62,14 +63,12 @@ export function Fullscreen({children, className}: FullscreenProps) {
} else {
ref.current?.appendChild(container);
}
// Trigger recalculation for components relying on window resize
// Dispatch after DOM repaint to ensure correct measurements
requestAnimationFrame(() => {
window.dispatchEvent(new Event('resize'));
});
}
}, [container, fullscreenRootRef, isFullscreen]);

// Trigger resize event when fullscreen state changes to force virtualization recalculation
useResizeObserverTrigger([isFullscreen]);

if (!container) {
return null;
}
Expand Down
4 changes: 4 additions & 0 deletions src/containers/Cluster/ClusterOverview/ClusterOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {isClusterInfoV2, isClusterInfoV5} from '../../../types/api/cluster';
import type {TClusterInfo} from '../../../types/api/cluster';
import type {IResponseError} from '../../../types/api/error';
import {valueIsDefined} from '../../../utils';
import {useResizeObserverTrigger} from '../../../utils/hooks/useResizeObserverTrigger';
import {useSetting} from '../../../utils/hooks/useSetting';
import {ClusterInfo} from '../ClusterInfo/ClusterInfo';
import i18n from '../i18n';
Expand Down Expand Up @@ -43,6 +44,9 @@ export function ClusterOverview(props: ClusterOverviewProps) {
const [expandDashboard, setExpandDashboard] = useSetting<boolean>(
SETTING_KEYS.EXPAND_CLUSTER_DASHBOARD,
);

//needs timeout to ensure layout has been recalculated after Disclosure animations
useResizeObserverTrigger([expandDashboard], 110);
const bridgeModeEnabled = useBridgeModeEnabled();

const bridgePiles = React.useMemo(() => {
Expand Down
2 changes: 2 additions & 0 deletions src/containers/Tenant/utils/paneVisibilityToggleHelpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {ChevronsUp} from '@gravity-ui/icons';
import {ActionTooltip, Button, Icon} from '@gravity-ui/uikit';

import {cn} from '../../../utils/cn';
import {useResizeObserverTrigger} from '../../../utils/hooks/useResizeObserverTrigger';

import './ToggleButton.scss';

Expand Down Expand Up @@ -82,6 +83,7 @@ export function PaneVisibilityToggleButtons({
initialDirection = 'top',
className,
}: ToggleButtonProps) {
useResizeObserverTrigger([isCollapsed]);
return (
<React.Fragment>
<ActionTooltip title="Collapse">
Expand Down
32 changes: 32 additions & 0 deletions src/utils/hooks/useResizeObserverTrigger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';

/**
* Triggers a window resize event when dependencies change.
* Useful for forcing virtualized components to recalculate visible items
* after layout changes (e.g., when panels expand/collapse).
*
* Uses double requestAnimationFrame to ensure the resize event is dispatched
* after the browser has completed layout recalculation.
* @param dependencies - Array of values to watch for changes
* @example
* ```typescript
* const [isExpanded, setIsExpanded] = useState(false);
* useResizeObserverTrigger([isExpanded]);
* ```
*/
export function useResizeObserverTrigger(dependencies: React.DependencyList, timeout = 0): void {
React.useEffect(() => {
// Use double RAF to ensure layout has been recalculated after animation
const rafId1 = requestAnimationFrame(() => {
const rafId2 = requestAnimationFrame(() => {
// Dispatch resize event to trigger virtualization recalculation
window.setTimeout(() => {
window.dispatchEvent(new Event('resize'));
}, timeout);
});
return () => cancelAnimationFrame(rafId2);
});
return () => cancelAnimationFrame(rafId1);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, dependencies);
}
Loading