diff --git a/packages/eui/changelogs/upcoming/9056.md b/packages/eui/changelogs/upcoming/9056.md new file mode 100644 index 00000000000..8b427e7db0f --- /dev/null +++ b/packages/eui/changelogs/upcoming/9056.md @@ -0,0 +1 @@ +Added a new `hasChildBackground` boolean prop (defaults to false) to `EuiFlyout` \ No newline at end of file diff --git a/packages/eui/src/components/flyout/README.md b/packages/eui/src/components/flyout/README.md index f4f54d47271..9be70fc3e7d 100644 --- a/packages/eui/src/components/flyout/README.md +++ b/packages/eui/src/components/flyout/README.md @@ -45,7 +45,6 @@ Renders the primary flyout in a session. Currently a simple wrapper around `EuiM ### `src/components/flyout/manager/flyout_child.tsx` Renders child flyouts within a session: - **Positioning**: Automatically positions relative to main flyout width -- **Styling**: Supports `backgroundStyle` prop for default/shaded backgrounds - **Constraints**: Forces `type="overlay"` and `ownFocus={false}` - **Width Integration**: Uses main flyout width for positioning @@ -96,7 +95,7 @@ Core flyout styling with emotion CSS-in-JS: Menu-specific styling for the flyout menu component. ### `src/components/flyout/manager/flyout.styles.ts` -Managed flyout styling, including background styles for child flyouts. +Managed flyout styling for the flyout managment system. ## Testing and Documentation diff --git a/packages/eui/src/components/flyout/flyout.component.tsx b/packages/eui/src/components/flyout/flyout.component.tsx index d85ba5d198d..d168d222429 100644 --- a/packages/eui/src/components/flyout/flyout.component.tsx +++ b/packages/eui/src/components/flyout/flyout.component.tsx @@ -155,6 +155,11 @@ interface _EuiFlyoutComponentProps { */ pushAnimation?: boolean; style?: CSSProperties; + /** + * When the flyout is used as a child in a managed flyout session, setting `true` gives the shaded background style. + * @default false + */ + hasChildBackground?: boolean; /** * Object of props passed to EuiFocusTrap. * `shards` specifies an array of elements that will be considered part of the flyout, preventing the flyout from being closed when clicked. @@ -233,6 +238,7 @@ export const EuiFlyoutComponent = forwardRef( paddingSize = DEFAULT_PADDING_SIZE, maxWidth = false, style, + hasChildBackground = false, maskProps, type = DEFAULT_TYPE, outsideClickCloses, @@ -434,7 +440,11 @@ export const EuiFlyoutComponent = forwardRef( styles[side], ]; - const classes = classnames('euiFlyout', className); + const classes = classnames( + 'euiFlyout', + isChildFlyout && hasChildBackground && 'euiFlyout--hasChildBackground', + className + ); const flyoutToggle = useRef(document.activeElement); const [focusTrapShards, setFocusTrapShards] = useState([]); diff --git a/packages/eui/src/components/flyout/flyout.styles.ts b/packages/eui/src/components/flyout/flyout.styles.ts index d7b2560c937..2d768525b81 100644 --- a/packages/eui/src/components/flyout/flyout.styles.ts +++ b/packages/eui/src/components/flyout/flyout.styles.ts @@ -81,7 +81,7 @@ export const euiFlyoutStyles = (euiThemeContext: UseEuiTheme) => { ${logicalCSS('top', 'var(--euiFixedHeadersOffset, 0)')} ${logicalCSS('height', 'inherit')} z-index: ${euiTheme.levels.flyout}; - background: ${euiTheme.colors.emptyShade}; + background: ${euiTheme.colors.backgroundBasePlain}; display: flex; flex-direction: column; align-items: stretch; @@ -91,9 +91,12 @@ export const euiFlyoutStyles = (euiThemeContext: UseEuiTheme) => { outline: none; } + &.euiFlyout--hasChildBackground { + background: ${euiTheme.colors.backgroundBaseSubdued}; + } + ${maxedFlyoutWidth(euiThemeContext)} `, - // Flyout sizes // When a child flyout is stacked on top of the parent, the parent flyout size will match the child flyout size s: css` diff --git a/packages/eui/src/components/flyout/manager/flyout_child.styles.ts b/packages/eui/src/components/flyout/manager/flyout_child.styles.ts deleted file mode 100644 index 71a08c3cd2c..00000000000 --- a/packages/eui/src/components/flyout/manager/flyout_child.styles.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { css } from '@emotion/react'; -import { UseEuiTheme } from '../../../services'; - -/** - * Emotion styles for child flyouts. - * Provides background variants coordinated with the EUI theme. - * - * Returns an object with the following CSS snippets: - * - `backgroundDefault`: plain background - * - `backgroundShaded`: subdued background used to de-emphasize child content - */ -export const euiChildFlyoutStyles = (euiThemeContext: UseEuiTheme) => { - const { - euiTheme: { - colors: { backgroundBasePlain, backgroundBaseSubdued }, - }, - } = euiThemeContext; - - return { - backgroundDefault: css` - /* Default background for flyouts */ - background: ${backgroundBasePlain}; - `, - backgroundShaded: css` - /* Shaded background for child flyouts */ - background: ${backgroundBaseSubdued}; - `, - }; -}; diff --git a/packages/eui/src/components/flyout/manager/flyout_child.tsx b/packages/eui/src/components/flyout/manager/flyout_child.tsx index 890d32076b5..9705d09b3ca 100644 --- a/packages/eui/src/components/flyout/manager/flyout_child.tsx +++ b/packages/eui/src/components/flyout/manager/flyout_child.tsx @@ -7,8 +7,7 @@ */ import React from 'react'; -import { useEuiMemoizedStyles, useEuiTheme } from '../../../services'; -import { euiChildFlyoutStyles } from './flyout_child.styles'; +import { useEuiTheme } from '../../../services'; import { EuiManagedFlyout, type EuiManagedFlyoutProps } from './flyout_managed'; import { useCurrentMainFlyout, @@ -27,29 +26,26 @@ import { DEFAULT_SIDE } from '../const'; * * Notes: * - `type`, `side`, and `level` are fixed by the component and thus omitted. - * - `backgroundStyle` toggles between default and shaded backgrounds. */ -export interface EuiFlyoutChildProps - extends Omit< - EuiManagedFlyoutProps, - 'closeButtonPosition' | 'hideCloseButton' | 'type' | 'level' - > { - backgroundStyle?: 'default' | 'shaded'; -} +export type EuiFlyoutChildProps = Omit< + EuiManagedFlyoutProps, + | 'closeButtonPosition' + | 'hideCloseButton' + | 'type' + | 'level' + | 'hasChildBackground' +>; /** * Managed child flyout that renders alongside or stacked over the main flyout, - * depending on the current layout mode. Handles background styling and required - * managed flyout props. + * depending on the current layout mode. Handles required managed flyout props. */ export function EuiFlyoutChild({ css: customCss, - backgroundStyle, side = DEFAULT_SIDE, ...props }: EuiFlyoutChildProps) { const { euiTheme } = useEuiTheme(); - const styles = useEuiMemoizedStyles(euiChildFlyoutStyles); const mainFlyout = useCurrentMainFlyout(); const mainWidth = useFlyoutWidth(mainFlyout?.flyoutId); const layoutMode = useFlyoutLayoutMode(); @@ -85,12 +81,7 @@ export function EuiFlyoutChild({ type="overlay" ownFocus={false} side={side} - css={[ - backgroundStyle === 'shaded' - ? styles.backgroundShaded - : styles.backgroundDefault, - customCss, - ]} + css={customCss} /> ); } diff --git a/packages/eui/src/components/flyout/manager/flyout_manager.stories.tsx b/packages/eui/src/components/flyout/manager/flyout_manager.stories.tsx index de4cc0a22f3..d557fee2b7f 100644 --- a/packages/eui/src/components/flyout/manager/flyout_manager.stories.tsx +++ b/packages/eui/src/components/flyout/manager/flyout_manager.stories.tsx @@ -25,7 +25,6 @@ type EuiFlyoutChildActualProps = Pick< EuiFlyoutChildProps, | 'aria-label' | 'as' - | 'backgroundStyle' | 'children' | 'closeButtonProps' | 'focusTrapProps' @@ -47,7 +46,7 @@ type EuiFlyoutType = (typeof FLYOUT_TYPES)[number]; interface FlyoutChildStoryArgs extends EuiFlyoutChildActualProps { mainSize?: 's' | 'm'; childSize?: 's' | 'm'; - childBackgroundStyle?: 'default' | 'shaded'; + hasChildBackground: boolean; childMaxWidth?: number; mainFlyoutType: EuiFlyoutType; mainMaxWidth?: number; @@ -73,10 +72,10 @@ const meta: Meta = { description: 'The size of the child flyout. Valid combinations: both cannot be "m", both cannot be "fill", and "l" can only be used if the other flyout is "fill".', }, - childBackgroundStyle: { - options: ['default', 'shaded'], - control: { type: 'radio' }, - description: 'The background style of the child flyout.', + hasChildBackground: { + control: { type: 'boolean' }, + description: + 'When the flyout is used as a child in a managed flyout session, setting `true` gives the shaded background style.', }, childMaxWidth: { control: { type: 'number' }, @@ -116,9 +115,6 @@ const meta: Meta = { control: { type: 'boolean' }, description: 'Whether the child flyout should be resizable.', }, - - // use "childBackgroundStyle" instead - backgroundStyle: { table: { disable: true } }, // use "mainSize" and "childSize" instead size: { table: { disable: true } }, // use "mainMaxWidth" and "childMaxWidth" instead @@ -138,7 +134,7 @@ const meta: Meta = { args: { mainSize: 'm', childSize: 's', - childBackgroundStyle: 'default', + hasChildBackground: false, mainFlyoutType: 'overlay', outsideClickCloses: false, ownFocus: true, // Depends on `mainFlyoutType=overlay` @@ -166,7 +162,7 @@ type Story = StoryObj; const StatefulFlyout: React.FC = ({ mainSize, childSize, - childBackgroundStyle, + hasChildBackground, mainFlyoutType, pushMinBreakpoint, mainMaxWidth, @@ -256,7 +252,7 @@ const StatefulFlyout: React.FC = ({ = { title: 'Layout/EuiFlyout/Flyout Manager', component: EuiFlyout, + // Skipping Loki as this is a playground for the flyout manager + // https://github.com/elastic/eui/pull/9056/files#r2425379403 + parameters: { + loki: { + skip: true, + }, + }, }; export default meta; @@ -40,7 +47,7 @@ interface FlyoutSessionProps { childSize?: 's' | 'm' | 'fill'; childMaxWidth?: number; flyoutType: 'overlay' | 'push'; - childBackgroundShaded?: boolean; + hasChildBackground: boolean; } const FlyoutSession: React.FC = React.memo((props) => { @@ -51,6 +58,7 @@ const FlyoutSession: React.FC = React.memo((props) => { mainMaxWidth, childMaxWidth, flyoutType, + hasChildBackground, } = props; const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); @@ -146,6 +154,7 @@ const FlyoutSession: React.FC = React.memo((props) => { maxWidth={childMaxWidth} onActive={childFlyoutOnActive} onClose={childFlyoutOnClose} + hasChildBackground={hasChildBackground} > @@ -182,6 +191,7 @@ const ExampleComponent = () => { const bottomBorder: EuiPageTemplateProps['bottomBorder'] = 'extended'; const [flyoutType, setFlyoutType] = useState<'overlay' | 'push'>('overlay'); + const [hasChildBackground, setChildBackgroundShaded] = useState(false); const handleFlyoutTypeToggle = useCallback((e: EuiSwitchEvent) => { setFlyoutType(e.target.checked ? 'push' : 'overlay'); @@ -200,6 +210,7 @@ const ExampleComponent = () => { title="Session A" mainSize="s" childSize="s" + hasChildBackground={hasChildBackground} /> ), }, @@ -211,6 +222,7 @@ const ExampleComponent = () => { title="Session B" mainSize="m" childSize="s" + hasChildBackground={hasChildBackground} /> ), }, @@ -222,6 +234,7 @@ const ExampleComponent = () => { title="Session C" mainSize="s" childSize="fill" + hasChildBackground={hasChildBackground} /> ), }, @@ -233,6 +246,7 @@ const ExampleComponent = () => { title="Session D" mainSize="fill" childSize="s" + hasChildBackground={hasChildBackground} /> ), }, @@ -243,6 +257,7 @@ const ExampleComponent = () => { flyoutType={flyoutType} title="Session E" mainSize="fill" + hasChildBackground={hasChildBackground} /> ), }, @@ -256,6 +271,7 @@ const ExampleComponent = () => { mainSize={undefined} childSize="fill" childMaxWidth={1000} + hasChildBackground={hasChildBackground} /> ), }, @@ -268,11 +284,12 @@ const ExampleComponent = () => { mainSize="fill" mainMaxWidth={1000} childSize="s" + hasChildBackground={hasChildBackground} /> ), }, ], - [flyoutType] + [flyoutType, hasChildBackground] ); return ( @@ -297,7 +314,12 @@ const ExampleComponent = () => { checked={flyoutType === 'push'} onChange={handleFlyoutTypeToggle} /> - {/* FIXME add option to set child flyout background style to "shaded" */} + + setChildBackgroundShaded((prev) => !prev)} + />