Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
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
3 changes: 3 additions & 0 deletions packages/eui/changelogs/upcoming/9592.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**Bug fixes**

- Fix `EuiFlyout` for `pushMinBreakpoint` when `container` prop is provided
6 changes: 5 additions & 1 deletion packages/eui/src/components/flyout/flyout.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,11 @@ export const EuiFlyoutComponent = forwardRef(

// Ref for the main flyout element to pass to context
const internalParentFlyoutRef = useRef<HTMLDivElement>(null);
const isPushed = useIsPushed({ type, pushMinBreakpoint });
const isPushed = useIsPushed({
type,
pushMinBreakpoint,
containerElement: container,
Comment thread
tsullivan marked this conversation as resolved.
Outdated
});
// When no explicit container is provided, push padding targets
// document.body and global push-offset CSS vars are set. When a
// container is provided, only that element receives padding.
Expand Down
35 changes: 31 additions & 4 deletions packages/eui/src/components/flyout/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,50 @@
* Side Public License, v 1.
*/

import { useIsWithinMinBreakpoint } from '../../services';
import { useIsWithinMinBreakpoint, useEuiTheme } from '../../services';
import { useResizeObserver } from '../observer/resize_observer';
import { EuiFlyoutProps } from './flyout';
import { usePropsWithComponentDefaults } from '../provider/component_defaults';
import { DEFAULT_PUSH_MIN_BREAKPOINT, DEFAULT_TYPE } from './const';

/**
* Determines if a flyout should be rendered in a "pushed" state based on its
* configuration and the current window size.
* configuration and the current window or container size.
*
* When `containerElement` is provided, the push/overlay breakpoint decision
* is based on the container's width rather than the viewport width. This
* ensures flyouts scoped to a container respond to the available space
* within that container.
*/
export const useIsPushed = (
props: Pick<EuiFlyoutProps, 'type' | 'pushMinBreakpoint'>
props: Pick<EuiFlyoutProps, 'type' | 'pushMinBreakpoint'> & {
containerElement?: HTMLElement | null;
}
) => {
const {
type = DEFAULT_TYPE,
pushMinBreakpoint = DEFAULT_PUSH_MIN_BREAKPOINT,
} = usePropsWithComponentDefaults('EuiFlyout', props);

const {
euiTheme: { breakpoint: breakpoints },
} = useEuiTheme();

// Always called to satisfy React hook rules; used as fallback
// when no container element is provided.
const windowIsLargeEnoughToPush = useIsWithinMinBreakpoint(pushMinBreakpoint);
return type === 'push' && windowIsLargeEnoughToPush;

// Observe container width so the push/overlay decision reacts to
// container resizes, not just viewport resizes.
const containerDimensions = useResizeObserver(
props.containerElement ?? null,
'width'
);

const isLargeEnoughToPush = props.containerElement
? (containerDimensions.width || props.containerElement.clientWidth) >=
Comment thread
tsullivan marked this conversation as resolved.
Outdated
breakpoints[pushMinBreakpoint]
: windowIsLargeEnoughToPush;

return type === 'push' && isLargeEnoughToPush;
Comment thread
tsullivan marked this conversation as resolved.
};
9 changes: 7 additions & 2 deletions packages/eui/src/components/flyout/manager/flyout_main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import React, { forwardRef } from 'react';

import { EuiManagedFlyout, type EuiManagedFlyoutProps } from './flyout_managed';
import { useHasChildFlyout, useFlyoutId } from './hooks';
import { useHasChildFlyout, useFlyoutId, useFlyoutManager } from './hooks';
import { euiMainFlyoutStyles } from './flyout_main.styles';
import { useEuiMemoizedStyles } from '../../../services';
import {
Expand Down Expand Up @@ -44,7 +44,12 @@ export const EuiFlyoutMain = forwardRef<HTMLElement, EuiFlyoutMainProps>(
const flyoutId = useFlyoutId(id);
const hasChildFlyout = useHasChildFlyout(flyoutId);
const styles = useEuiMemoizedStyles(euiMainFlyoutStyles);
const isPushed = useIsPushed({ type, pushMinBreakpoint });
const context = useFlyoutManager();
const isPushed = useIsPushed({
type,
pushMinBreakpoint,
containerElement: context?.state.containerElement,
});
Comment thread
tsullivan marked this conversation as resolved.

const cssStyles = [
hasChildFlyout && !isPushed && styles.hasChildFlyout[side],
Expand Down