From 81b48343384fcdd912264e17b5c57f1ebd49c116 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 19 Aug 2025 11:37:00 -0400 Subject: [PATCH 01/36] wip --- .../drawer/src/DrawerLayout/DrawerLayout.tsx | 10 +- .../DrawerLayoutContext.tsx | 5 +- .../DrawerLayoutContext.types.ts | 5 + .../DrawerToolbarLayout.stories.tsx | 13 +- .../DrawerToolbarLayoutContent.tsx | 118 +++++++++++------- 5 files changed, 99 insertions(+), 52 deletions(-) diff --git a/packages/drawer/src/DrawerLayout/DrawerLayout.tsx b/packages/drawer/src/DrawerLayout/DrawerLayout.tsx index 6ad2d0ebd2..7560392044 100644 --- a/packages/drawer/src/DrawerLayout/DrawerLayout.tsx +++ b/packages/drawer/src/DrawerLayout/DrawerLayout.tsx @@ -29,11 +29,11 @@ export const DrawerLayout = forwardRef( ) => { const hasToolbar = toolbarData && toolbarData.length > 0; - if (!hasToolbar) { - consoleOnce.warn( - 'Using a Drawer without a toolbar is not recommended. To include a toolbar, pass a toolbarData prop containing the desired toolbar items.', - ); - } + // if (!hasToolbar) { + // consoleOnce.warn( + // 'Using a Drawer without a toolbar is not recommended. To include a toolbar, pass a toolbarData prop containing the desired toolbar items.', + // ); + // } return ( ({ hasToolbar: false, isDrawerResizing: false, drawerWidth: 0, + setHasToolbar: () => {}, setIsDrawerOpen: () => {}, setDrawerWidth: () => {}, setIsDrawerResizing: () => {}, @@ -36,12 +37,13 @@ export const DrawerLayoutProvider = ({ resizable, displayMode, onClose, - hasToolbar, + hasToolbar: hasToolbarProp = false, size, }: PropsWithChildren) => { const [isDrawerOpen, setIsDrawerOpen] = React.useState(isDrawerOpenProp); const [isDrawerResizing, setIsDrawerResizing] = React.useState(false); const [drawerWidth, setDrawerWidth] = React.useState(0); + const [hasToolbar, setHasToolbar] = React.useState(hasToolbarProp); useEffect(() => { setIsDrawerOpen(isDrawerOpenProp); @@ -53,6 +55,7 @@ export const DrawerLayoutProvider = ({ displayMode, onClose, hasToolbar, + setHasToolbar, setIsDrawerOpen, isDrawerResizing, setIsDrawerResizing, diff --git a/packages/drawer/src/DrawerLayout/DrawerLayoutContext/DrawerLayoutContext.types.ts b/packages/drawer/src/DrawerLayout/DrawerLayoutContext/DrawerLayoutContext.types.ts index 6c550794f1..e9df6c1c94 100644 --- a/packages/drawer/src/DrawerLayout/DrawerLayoutContext/DrawerLayoutContext.types.ts +++ b/packages/drawer/src/DrawerLayout/DrawerLayoutContext/DrawerLayoutContext.types.ts @@ -57,4 +57,9 @@ export interface DrawerLayoutContextType extends DrawerLayoutProviderProps { * Function to set the drawer resizing state. */ setIsDrawerResizing: React.Dispatch>; + + /** + * Function to set the drawer toolbar state. + */ + setHasToolbar: React.Dispatch>; } diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.stories.tsx b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.stories.tsx index dfa2d2ec99..cf1ea1dfcd 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.stories.tsx +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.stories.tsx @@ -24,26 +24,31 @@ const DRAWER_TOOLBAR_DATA: DrawerLayoutProps['toolbarData'] = [ label: 'Code', content: , title: 'Code Title', - glyph: 'Code', + // glyph: 'Code', }, { id: 'Dashboard', label: 'Dashboard', content: , title: 'Dashboard Title', - glyph: 'Dashboard', + // glyph: 'Dashboard', }, { id: 'Plus', label: "Perform some action, doesn't open a drawer", - glyph: 'Plus', + // glyph: 'Plus', }, { id: 'Sparkle', label: 'Disabled item', - glyph: 'Sparkle', + // glyph: 'Sparkle', disabled: true, }, + { + id: 'Sparkle2', + label: 'Sparkle 2', + content: , + }, ]; const defaultExcludedControls = [ diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx index 840fdfc47c..143c05b636 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx @@ -43,7 +43,8 @@ export const DrawerToolbarLayoutContent = forwardRef< content, scrollable = true, } = getActiveDrawerContent() || {}; - const { onClose, displayMode, setIsDrawerOpen } = useDrawerLayoutContext(); + const { onClose, displayMode, setIsDrawerOpen, setHasToolbar } = + useDrawerLayoutContext(); useEffect(() => { setIsDrawerOpen(isDrawerOpen); @@ -65,49 +66,82 @@ export const DrawerToolbarLayoutContent = forwardRef< openDrawer(id); }; + const visibleToolbarData = toolbarData?.filter( + toolbarItem => toolbarItem.glyph, + ); + + const hasVisibleToolbarData = visibleToolbarData.length > 0; + + if (!hasVisibleToolbarData) { + setHasToolbar(false); + } + + console.log({ toolbarData, visibleToolbarData }); + + const renderDrawer = () => { + return ( + + {content} + + ); + }; + + const renderToolbar = () => { + return ( + + {visibleToolbarData?.map(toolbarItem => ( + ) => { + if (!toolbarItem.content) { + // If the toolbar item does not have content, we don't want to open/update/close the drawer + // but we still want to call the onClick function if it exists. E.g. open a modal or perform an action + toolbarItem.onClick?.(event); + return; + } + + return handleIconClick( + event, + toolbarItem.id, + toolbarItem.onClick, + ); + }} + active={toolbarItem.id === id} + disabled={toolbarItem.disabled} + /> + ))} + + ); + }; + return ( -
{children}
- - - {toolbarData?.map(toolbarItem => ( - ) => { - if (!toolbarItem.content) { - // If the toolbar item does not have content, we don't want to open/update/close the drawer - // but we still want to call the onClick function if it exists. E.g. open a modal or perform an action - toolbarItem.onClick?.(event); - return; - } - - return handleIconClick( - event, - toolbarItem.id, - toolbarItem.onClick, - ); - }} - active={toolbarItem.id === id} - disabled={toolbarItem.disabled} - /> - ))} - - - {content} - - + {hasVisibleToolbarData ? ( + <> +
{children}
+ + {renderToolbar()} + {renderDrawer()} + + + ) : ( + <> + {children} + {renderDrawer()} + + )}
); }, From 4425a92a9e5cdbbbc53c3f4004233f0d0199338b Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 19 Aug 2025 16:53:52 -0400 Subject: [PATCH 02/36] feat(DrawerToolbar): enhance toolbar visibility management and add toggle functionality --- .../DrawerToolbarLayout.stories.tsx | 71 +++++++++++++++++-- .../DrawerToolbarLayout.types.ts | 6 ++ .../DrawerToolbarLayoutContent.tsx | 34 ++++----- 3 files changed, 88 insertions(+), 23 deletions(-) diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.stories.tsx b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.stories.tsx index cf1ea1dfcd..ed144aee75 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.stories.tsx +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.stories.tsx @@ -24,30 +24,73 @@ const DRAWER_TOOLBAR_DATA: DrawerLayoutProps['toolbarData'] = [ label: 'Code', content: , title: 'Code Title', - // glyph: 'Code', + glyph: 'Code', }, { id: 'Dashboard', label: 'Dashboard', content: , title: 'Dashboard Title', - // glyph: 'Dashboard', + glyph: 'Dashboard', }, { id: 'Plus', label: "Perform some action, doesn't open a drawer", - // glyph: 'Plus', + glyph: 'Plus', }, { id: 'Sparkle', label: 'Disabled item', - // glyph: 'Sparkle', + glyph: 'Sparkle', disabled: true, }, { - id: 'Sparkle2', - label: 'Sparkle 2', + id: 'Apps', + label: 'Apps', content: , + glyph: 'Apps', + title: 'Apps Title', + visible: false, + }, +]; + +const DRAWER_TOOLBAR_DATA_NOT_VISIBLE: DrawerLayoutProps['toolbarData'] = [ + { + id: 'Code', + label: 'Code', + content: , + title: 'Code Title', + glyph: 'Code', + visible: false, + }, + { + id: 'Dashboard', + label: 'Dashboard', + content: , + title: 'Dashboard Title', + glyph: 'Dashboard', + visible: false, + }, + { + id: 'Plus', + label: "Perform some action, doesn't open a drawer", + glyph: 'Plus', + visible: false, + }, + { + id: 'Sparkle', + label: 'Disabled item', + glyph: 'Sparkle', + disabled: true, + visible: false, + }, + { + id: 'Apps', + label: 'Apps', + content: , + glyph: 'Apps', + title: 'Apps Title', + visible: false, }, ]; @@ -149,8 +192,11 @@ const CloudNavLayoutMock: React.FC<{ children?: React.ReactNode }> = ({ ); const Component: StoryFn = ({ + toolbarData = DRAWER_TOOLBAR_DATA, ...args }: DrawerLayoutProps) => { + const [toolbarDataArr, setToolbarDataArr] = useState(DRAWER_TOOLBAR_DATA); + const MainContent = () => { const { openDrawer } = useDrawerToolbarContext(); @@ -161,6 +207,17 @@ const Component: StoryFn = ({ `} > + @@ -174,7 +231,7 @@ const Component: StoryFn = ({ width: 100%; `} > - + diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.types.ts b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.types.ts index 2643d01601..250f60fb5a 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.types.ts +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.types.ts @@ -13,6 +13,12 @@ interface LayoutBase extends PickedRequiredToolbarIconButtonProps { * The id of the layout. This is used to open the drawer. */ id: string; + + /** + * Determines if the current toolbar item is visible. If all toolbar items have `visible` set to `false`, the toolbar will not be rendered. + * @defaultValue true + */ + visible?: boolean; } interface LayoutWithContent extends LayoutBase { diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx index 143c05b636..7867654a09 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx @@ -1,4 +1,4 @@ -import React, { forwardRef, useEffect } from 'react'; +import React, { forwardRef, useEffect, useLayoutEffect } from 'react'; import { Toolbar, ToolbarIconButton } from '@leafygreen-ui/toolbar'; @@ -20,6 +20,8 @@ import { * * DrawerToolbarLayoutContent is a component that provides a layout for displaying content in a drawer with a toolbar. * It manages the state of the drawer and toolbar, and renders the appropriate components based on the display mode. + * + * If all toolbar items are not visible, the toolbar will not be rendered. */ export const DrawerToolbarLayoutContent = forwardRef< HTMLDivElement, @@ -45,12 +47,24 @@ export const DrawerToolbarLayoutContent = forwardRef< } = getActiveDrawerContent() || {}; const { onClose, displayMode, setIsDrawerOpen, setHasToolbar } = useDrawerLayoutContext(); + const lgIds = getLgIds(dataLgId); + // This updates the drawer open state when the toolbar is inter useEffect(() => { setIsDrawerOpen(isDrawerOpen); }, [isDrawerOpen, setIsDrawerOpen]); - const lgIds = getLgIds(dataLgId); + // Calculate visibleToolbarItems in component body (needed for rendering) + const visibleToolbarItems = toolbarData?.filter( + toolbarItem => toolbarItem.visible ?? true, + ); + + const shouldRenderToolbar = visibleToolbarItems.length > 0; + + // runs synchronously after the DOM is updated and before the browser paints to avoid flickering of the toolbar + useLayoutEffect(() => { + setHasToolbar(shouldRenderToolbar); + }, [shouldRenderToolbar, setHasToolbar]); const handleOnClose = (event: React.MouseEvent) => { onClose?.(event); @@ -66,18 +80,6 @@ export const DrawerToolbarLayoutContent = forwardRef< openDrawer(id); }; - const visibleToolbarData = toolbarData?.filter( - toolbarItem => toolbarItem.glyph, - ); - - const hasVisibleToolbarData = visibleToolbarData.length > 0; - - if (!hasVisibleToolbarData) { - setHasToolbar(false); - } - - console.log({ toolbarData, visibleToolbarData }); - const renderDrawer = () => { return ( { return ( - {visibleToolbarData?.map(toolbarItem => ( + {visibleToolbarItems?.map(toolbarItem => ( - {hasVisibleToolbarData ? ( + {shouldRenderToolbar ? ( <>
{children}
From 765cb0e6d7e505c90f5483d7990a278c74534fe8 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 20 Aug 2025 17:15:58 -0400 Subject: [PATCH 03/36] wip, not complete --- packages/drawer/src/Drawer/Drawer.tsx | 27 +++- .../DrawerToolbarLayoutContent.tsx | 15 +- .../DrawerWithToolbarWrapper.styles.ts | 40 ++---- .../EmbeddedDrawerLayout.styles.ts | 1 + .../EmbeddedDrawerLayout.tsx | 46 ++++--- .../EmbeddedDrawerLayout.types.ts | 2 +- .../src/LayoutComponent/LayoutComponent.tsx | 11 +- .../OverlayDrawerLayout.styles.ts | 130 +++++++++++++++++- .../OverlayDrawerLayout.tsx | 39 +++++- .../OverlayDrawerLayout.types.ts | 3 +- 10 files changed, 240 insertions(+), 74 deletions(-) diff --git a/packages/drawer/src/Drawer/Drawer.tsx b/packages/drawer/src/Drawer/Drawer.tsx index 48a16c9a9d..eed318962c 100644 --- a/packages/drawer/src/Drawer/Drawer.tsx +++ b/packages/drawer/src/Drawer/Drawer.tsx @@ -65,11 +65,14 @@ export const Drawer = forwardRef( hasToolbar, setIsDrawerResizing, setDrawerWidth, + drawerWidth, size: sizeContextProp, } = useDrawerLayoutContext(); const [shouldAnimate, setShouldAnimate] = useState(false); const ref = useRef(null); + // const [initialSize, setInitialSize] = useState(0); + // Returns the resolved displayMode, open state, and onClose function based on the component and context props. const { displayMode, open, onClose, size } = useResolvedDrawerProps({ componentDisplayMode: displayModeProp, @@ -83,8 +86,18 @@ export const Drawer = forwardRef( }); // Returns the resolved drawer sizes based on whether a toolbar is present. - const { initialSize, resizableMinWidth, resizableMaxWidth } = - getResolvedDrawerSizes(size, hasToolbar); + const { + initialSize: resolvedInitialSize, + resizableMinWidth, + resizableMaxWidth, + } = getResolvedDrawerSizes(size, hasToolbar); + + const initialSize = + drawerWidth === 0 + ? resolvedInitialSize + : hasToolbar + ? drawerWidth - 42 + : drawerWidth; const isEmbedded = displayMode === DisplayMode.Embedded; const isOverlay = displayMode === DisplayMode.Overlay; @@ -155,16 +168,24 @@ export const Drawer = forwardRef( const { resizableRef, size: drawerSize, + setSize, getResizerProps, isResizing, } = useResizable({ enabled: isResizableEnabled, - initialSize, + initialSize: resolvedInitialSize, minSize: resizableMinWidth, maxSize: resizableMaxWidth, position: Position.Right, }); + useEffect(() => { + console.log('🥊drawer render', { drawerWidth, open, hasToolbar }); + if (open && isEmbedded && drawerWidth) { + console.log('😡'); + } + }, []); + // In an embedded drawer, the parent grid container controls the drawer width with grid-template-columns, so we pass the width to the context where it is read by the parent grid container. useEffect(() => { if (!isEmbedded) return; diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx index 7867654a09..4e6e1e88f6 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx @@ -129,22 +129,21 @@ export const DrawerToolbarLayoutContent = forwardRef< }; return ( - + <> {shouldRenderToolbar ? ( - <> +
{children}
{renderToolbar()} {renderDrawer()} - +
) : ( - <> - {children} - {renderDrawer()} - + +
{children}
+
)} -
+ ); }, ); diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts index e7f780aeb0..a3e5a33a56 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts @@ -17,25 +17,6 @@ import { getDrawerWidth } from '../../Drawer/Drawer.utils'; const MOBILE_BREAKPOINT = breakpoints.Tablet; const SHADOW_WIDTH = 36; // Width of the shadow padding on the left side -const getDrawerIn = (size: number) => keyframes` - from { - // Because of .show() and .close() in the drawer component, transitioning from 0px to (x)px does not transition correctly. Using 1px along with css animations is a workaround to get the animation to work when the Drawer is overlay. - grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px 1px; - } - to { - grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px ${size}px; - } -`; - -const getDrawerOut = (size: number) => keyframes` - from { - grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px ${size}px; - } - to { - grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px 0px; - } -`; - const drawerOutMobile = keyframes` from { grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px calc(100vw - ${ @@ -72,20 +53,11 @@ const drawerPaddingOut = keyframes` `; const getOpenOverlayStyles = (size: number) => css` - animation-name: ${getDrawerIn(size)}; - animation-fill-mode: forwards; - - @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { - animation-name: ${drawerInMobile}; - } + grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px ${size}px; `; const getClosedOverlayStyles = (size: number) => css` - animation-name: ${getDrawerOut(size)}; - - @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { - animation-name: ${drawerOutMobile}; - } + grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px 0px; `; const openEmbeddedStyles = css` @@ -165,6 +137,11 @@ const baseStyles = css` `; const baseOverlayStyles = css` + transition-property: grid-template-columns; + transition-duration: ${TRANSITION_DURATION}ms; + transition-timing-function: ${TRANSITION_TIMING_FUNCTION}; + grid-template-columns: 1fr auto; + .${drawerClassName} { width: 100%; } @@ -207,8 +184,7 @@ export const getDrawerWithToolbarWrapperStyles = ({ [closedOverlayShadowStyles]: isOverlay && !isDrawerOpen, [baseOverlayStyles]: isOverlay, [getOpenOverlayStyles(size)]: isDrawerOpen && isOverlay, - [getClosedOverlayStyles(size)]: - !isDrawerOpen && shouldAnimate && isOverlay, // This ensures that the drawer does not animate closed on initial render + [getClosedOverlayStyles(size)]: !isDrawerOpen && isOverlay, // This ensures that the drawer does not animate closed on initial render [baseEmbeddedStyles]: isEmbedded, [openEmbeddedStyles]: isDrawerOpen && isEmbedded, [closedEmbeddedStyles]: !isDrawerOpen && isEmbedded, diff --git a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.styles.ts b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.styles.ts index 7577e99566..612317ea18 100644 --- a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.styles.ts +++ b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.styles.ts @@ -15,6 +15,7 @@ const baseStyles = css` width: 100%; display: grid; grid-template-columns: auto 0; + grid-template-areas: '${GRID_AREA.content} ${GRID_AREA.drawer}'; transition-property: grid-template-columns, grid-template-rows; transition-timing-function: ${TRANSITION_TIMING_FUNCTION}; transition-duration: ${TRANSITION_DURATION}ms; diff --git a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx index 024fe9bf46..0357a0876c 100644 --- a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx +++ b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx @@ -16,26 +16,32 @@ import { EmbeddedDrawerLayoutProps } from './EmbeddedDrawerLayout.types'; export const EmbeddedDrawerLayout = forwardRef< HTMLDivElement, EmbeddedDrawerLayoutProps ->(({ children, className }: EmbeddedDrawerLayoutProps, forwardedRef) => { - const { hasToolbar, isDrawerOpen, drawerWidth, isDrawerResizing, size } = - useDrawerLayoutContext(); +>( + ( + { children, className, drawer }: EmbeddedDrawerLayoutProps, + forwardedRef, + ) => { + const { hasToolbar, isDrawerOpen, drawerWidth, isDrawerResizing, size } = + useDrawerLayoutContext(); - return ( -
- {children} -
- ); -}); + return ( +
+ {children} + {drawer} +
+ ); + }, +); EmbeddedDrawerLayout.displayName = 'EmbeddedDrawerLayout'; diff --git a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.types.ts b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.types.ts index fce5c4f7de..35d11ae656 100644 --- a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.types.ts +++ b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.types.ts @@ -1,3 +1,3 @@ import { LayoutComponentProps } from '../../LayoutComponent/LayoutComponent.types'; -export type EmbeddedDrawerLayoutProps = Omit; +export type EmbeddedDrawerLayoutProps = LayoutComponentProps; diff --git a/packages/drawer/src/LayoutComponent/LayoutComponent.tsx b/packages/drawer/src/LayoutComponent/LayoutComponent.tsx index 8ec5b3ae3c..95a4aadbf8 100644 --- a/packages/drawer/src/LayoutComponent/LayoutComponent.tsx +++ b/packages/drawer/src/LayoutComponent/LayoutComponent.tsx @@ -1,4 +1,4 @@ -import React, { forwardRef } from 'react'; +import React, { forwardRef, useEffect } from 'react'; import LeafyGreenProvider, { useDarkMode, @@ -10,6 +10,8 @@ import { useDrawerLayoutContext } from '../DrawerLayout'; import { EmbeddedDrawerLayout } from './EmbeddedDrawerLayout'; import { LayoutComponentProps } from './LayoutComponent.types'; import { OverlayDrawerLayout } from './OverlayDrawerLayout'; +import { GRID_AREA } from '../constants'; +import { css } from '@leafygreen-ui/emotion'; /** * @internal @@ -19,12 +21,16 @@ import { OverlayDrawerLayout } from './OverlayDrawerLayout'; */ export const LayoutComponent = forwardRef( ( - { children, darkMode: darkModeProp, drawer, ...rest }: LayoutComponentProps, + { children, darkMode: darkModeProp, ...rest }: LayoutComponentProps, forwardRef, ) => { const { darkMode } = useDarkMode(darkModeProp); const { displayMode } = useDrawerLayoutContext(); + useEffect(() => { + console.log('🥬 initial render'); + }, []); + const Component = displayMode === DisplayMode.Overlay ? OverlayDrawerLayout @@ -34,7 +40,6 @@ export const LayoutComponent = forwardRef( {children} - {drawer} ); diff --git a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.styles.ts b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.styles.ts index 21b2402cb2..d6dd2aac46 100644 --- a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.styles.ts +++ b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.styles.ts @@ -1,7 +1,18 @@ -import { css, cx } from '@leafygreen-ui/emotion'; - import { DRAWER_TOOLBAR_WIDTH, GRID_AREA } from '../../constants'; +import { css, cx, keyframes } from '@leafygreen-ui/emotion'; +import { Theme } from '@leafygreen-ui/lib'; +import { addOverflowShadow, Side } from '@leafygreen-ui/tokens'; +import { toolbarClassName } from '@leafygreen-ui/toolbar'; + +import { + TRANSITION_DURATION, + TRANSITION_TIMING_FUNCTION, +} from '../../constants'; +import { drawerClassName } from '../../Drawer/Drawer.styles'; +import { DisplayMode, Size } from '../../Drawer/Drawer.types'; +import { getDrawerWidth } from '../../Drawer/Drawer.utils'; + const baseStyles = css` width: 100%; position: relative; @@ -11,6 +22,7 @@ const baseStyles = css` const drawerBaseStyles = css` display: grid; grid-template-columns: auto 0px; + grid-template-areas: '${GRID_AREA.content} ${GRID_AREA.drawer}'; overflow: hidden; `; @@ -36,3 +48,117 @@ export const getOverlayDrawerLayoutStyles = ({ }, className, ); + +const SHADOW_WIDTH = 36; // Width of the shadow padding on the left side + +// This animation is used to animate the padding of the drawer when it closes, so that the padding does not block the content underneath it. +const drawerPaddingOut = keyframes` + 0% { + padding-left: ${SHADOW_WIDTH}px; + } + 99% { + padding-left: ${SHADOW_WIDTH}px; + } + 100% { + padding-left: 0px; + } +`; + +const getOpenOverlayStyles = (size: number) => css` + grid-template-columns: 0px ${size}px; +`; + +const getClosedOverlayStyles = (size: number) => css` + grid-template-columns: 0px 0px; +`; + +const getOverlayShadowStyles = ({ theme }: { theme: Theme }) => css` + ${addOverflowShadow({ isInside: false, side: Side.Left, theme })}; + + // Need this to show the box shadow since we are using overflow: hidden + padding-left: ${SHADOW_WIDTH}px; + + &::before { + transition-property: opacity; + transition-duration: ${TRANSITION_DURATION}ms; + transition-timing-function: ${TRANSITION_TIMING_FUNCTION}; + opacity: 1; + left: ${SHADOW_WIDTH}px; + } +`; + +const baseWrapperStyles = css` + display: grid; + grid-template-columns: 0px 0px; + grid-template-areas: 'filler ${GRID_AREA.innerDrawer}'; + grid-area: ${GRID_AREA.drawer}; + justify-self: end; + z-index: 0; + height: 100%; + overflow: hidden; + position: relative; + + .${drawerClassName} { + grid-area: ${GRID_AREA.innerDrawer}; + position: unset; + transform: unset; + overflow: hidden; + opacity: 1; + border-left: 0; + border-right: 0; + height: 100%; + animation: none; + + > div::before { + box-shadow: unset; + } + } +`; + +const baseOverlayStyles = css` + transition-property: grid-template-columns; + transition-duration: ${TRANSITION_DURATION}ms; + transition-timing-function: ${TRANSITION_TIMING_FUNCTION}; + grid-template-columns: 1fr auto; + + .${drawerClassName} { + width: 100%; + } +`; + +const closedOverlayShadowStyles = css` + padding-left: 0; + animation-name: ${drawerPaddingOut}; + animation-timing-function: ${TRANSITION_TIMING_FUNCTION}; + animation-duration: ${TRANSITION_DURATION}ms; + + ::before { + opacity: 0; + } +`; + +export const getOverlayDrawerWrapperStyles = ({ + className, + isDrawerOpen, + theme, + size: sizeProp = Size.Default, +}: { + className?: string; + isDrawerOpen?: boolean; + theme: Theme; + size?: Size; +}) => { + const size = getDrawerWidth({ size: sizeProp }).default; + + return cx( + baseWrapperStyles, + getOverlayShadowStyles({ theme }), + baseOverlayStyles, + { + [closedOverlayShadowStyles]: !isDrawerOpen, + [getOpenOverlayStyles(size)]: isDrawerOpen, + [getClosedOverlayStyles(size)]: !isDrawerOpen, + }, + className, + ); +}; diff --git a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx index 73a033a310..4964da9b2a 100644 --- a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx +++ b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx @@ -2,8 +2,14 @@ import React, { forwardRef } from 'react'; import { useDrawerLayoutContext } from '../../DrawerLayout/DrawerLayoutContext/DrawerLayoutContext'; -import { getOverlayDrawerLayoutStyles } from './OverlayDrawerLayout.styles'; +import { + getOverlayDrawerLayoutStyles, + getOverlayDrawerWrapperStyles, +} from './OverlayDrawerLayout.styles'; import { OverlayDrawerLayoutProps } from './OverlayDrawerLayout.types'; +import { css } from '@leafygreen-ui/emotion'; +import { GRID_AREA } from '../../constants'; +import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; /** * @internal @@ -16,8 +22,9 @@ import { OverlayDrawerLayoutProps } from './OverlayDrawerLayout.types'; export const OverlayDrawerLayout = forwardRef< HTMLDivElement, OverlayDrawerLayoutProps ->(({ children, className }: OverlayDrawerLayoutProps, forwardedRef) => { - const { hasToolbar } = useDrawerLayoutContext(); +>(({ children, className, drawer }: OverlayDrawerLayoutProps, forwardedRef) => { + const { hasToolbar, isDrawerOpen, size } = useDrawerLayoutContext(); + const { theme } = useDarkMode(); return (
- {children} + {drawer !== undefined ? ( + <> +
+ {children} +
+
+ {drawer} +
+ + ) : ( + children + )}
); }); diff --git a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.types.ts b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.types.ts index 83a3e22d0d..9fd349c46d 100644 --- a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.types.ts +++ b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.types.ts @@ -1,3 +1,4 @@ import { LayoutComponentProps } from '../../LayoutComponent/LayoutComponent.types'; -export type OverlayDrawerLayoutProps = Omit; +// export type OverlayDrawerLayoutProps = Omit; +export type OverlayDrawerLayoutProps = LayoutComponentProps; From 8fbac68dfcfbf9ceffadff24726a6a1b35ea0e8f Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 20 Aug 2025 17:29:29 -0400 Subject: [PATCH 04/36] remove resolvedInitialState --- packages/drawer/src/Drawer/Drawer.tsx | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/packages/drawer/src/Drawer/Drawer.tsx b/packages/drawer/src/Drawer/Drawer.tsx index eed318962c..71acc5c06d 100644 --- a/packages/drawer/src/Drawer/Drawer.tsx +++ b/packages/drawer/src/Drawer/Drawer.tsx @@ -86,18 +86,15 @@ export const Drawer = forwardRef( }); // Returns the resolved drawer sizes based on whether a toolbar is present. - const { - initialSize: resolvedInitialSize, - resizableMinWidth, - resizableMaxWidth, - } = getResolvedDrawerSizes(size, hasToolbar); + const { initialSize, resizableMinWidth, resizableMaxWidth } = + getResolvedDrawerSizes(size, hasToolbar); - const initialSize = - drawerWidth === 0 - ? resolvedInitialSize - : hasToolbar - ? drawerWidth - 42 - : drawerWidth; + // const initialSize = + // drawerWidth === 0 + // ? resolvedInitialSize + // : hasToolbar + // ? drawerWidth - 42 + // : drawerWidth; const isEmbedded = displayMode === DisplayMode.Embedded; const isOverlay = displayMode === DisplayMode.Overlay; From 239f2303f705e3f4381bb65de2585391c218ac69 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 20 Aug 2025 17:31:06 -0400 Subject: [PATCH 05/36] actually remove resolvedInitialState --- packages/drawer/src/Drawer/Drawer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/drawer/src/Drawer/Drawer.tsx b/packages/drawer/src/Drawer/Drawer.tsx index 71acc5c06d..8bedc70f09 100644 --- a/packages/drawer/src/Drawer/Drawer.tsx +++ b/packages/drawer/src/Drawer/Drawer.tsx @@ -170,7 +170,7 @@ export const Drawer = forwardRef( isResizing, } = useResizable({ enabled: isResizableEnabled, - initialSize: resolvedInitialSize, + initialSize, minSize: resizableMinWidth, maxSize: resizableMaxWidth, position: Position.Right, From 722285bfd0e783cfa986db34b36509ac04cffc11 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 20 Aug 2025 17:56:17 -0400 Subject: [PATCH 06/36] maybe a fix? --- packages/drawer/src/Drawer/Drawer.tsx | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/packages/drawer/src/Drawer/Drawer.tsx b/packages/drawer/src/Drawer/Drawer.tsx index 8bedc70f09..30d6b6ef46 100644 --- a/packages/drawer/src/Drawer/Drawer.tsx +++ b/packages/drawer/src/Drawer/Drawer.tsx @@ -70,6 +70,7 @@ export const Drawer = forwardRef( } = useDrawerLayoutContext(); const [shouldAnimate, setShouldAnimate] = useState(false); const ref = useRef(null); + const [previousWidth, setPreviousWidth] = useState(0); // const [initialSize, setInitialSize] = useState(0); @@ -89,13 +90,15 @@ export const Drawer = forwardRef( const { initialSize, resizableMinWidth, resizableMaxWidth } = getResolvedDrawerSizes(size, hasToolbar); - // const initialSize = + // const initialSizeEmbedded = // drawerWidth === 0 - // ? resolvedInitialSize + // ? initialSize // : hasToolbar - // ? drawerWidth - 42 + // ? drawerWidth - 48 // : drawerWidth; + // console.log('🐙', { initialSizeEmbedded }); + const isEmbedded = displayMode === DisplayMode.Embedded; const isOverlay = displayMode === DisplayMode.Overlay; const isResizableEnabled = isEmbedded && !!resizable && open; @@ -170,19 +173,30 @@ export const Drawer = forwardRef( isResizing, } = useResizable({ enabled: isResizableEnabled, - initialSize, + initialSize: previousWidth !== 0 ? previousWidth : initialSize, minSize: resizableMinWidth, maxSize: resizableMaxWidth, position: Position.Right, }); useEffect(() => { - console.log('🥊drawer render', { drawerWidth, open, hasToolbar }); - if (open && isEmbedded && drawerWidth) { + console.log('🥊drawer render', { + drawerWidth, + open, + hasToolbar, + initialSize, + }); + if (open && isEmbedded && drawerWidth !== 0) { console.log('😡'); + const prevWidth = hasToolbar ? drawerWidth + 48 : drawerWidth - 48; + setPreviousWidth(prevWidth); } }, []); + useEffect(() => { + if (!open) setPreviousWidth(0); + }, [open]); + // In an embedded drawer, the parent grid container controls the drawer width with grid-template-columns, so we pass the width to the context where it is read by the parent grid container. useEffect(() => { if (!isEmbedded) return; From 4f4c940f41a4c2d352e5d30496454eb6a6334e7a Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 21 Aug 2025 08:40:44 -0400 Subject: [PATCH 07/36] refactor(Drawer): remove unused animations and update layout styles for mobile responsiveness --- .../DrawerWithToolbarWrapper.styles.ts | 36 ++++-------- .../EmbeddedDrawerLayout.styles.ts | 58 ++++++++++++++++++- .../EmbeddedDrawerLayout.tsx | 34 ++++++++++- .../OverlayDrawerLayout.styles.ts | 9 ++- .../OverlayDrawerLayout.tsx | 1 - 5 files changed, 103 insertions(+), 35 deletions(-) diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts index a3e5a33a56..2bbf4b3c29 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts @@ -17,28 +17,6 @@ import { getDrawerWidth } from '../../Drawer/Drawer.utils'; const MOBILE_BREAKPOINT = breakpoints.Tablet; const SHADOW_WIDTH = 36; // Width of the shadow padding on the left side -const drawerOutMobile = keyframes` - from { - grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px calc(100vw - ${ - DRAWER_TOOLBAR_WIDTH * 2 -}px); - } - to { - grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px 0px; - } -`; - -const drawerInMobile = keyframes` - from { - grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px 1px; - } - to { - grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px calc(100vw - ${ - DRAWER_TOOLBAR_WIDTH * 2 -}px); - } -`; - // This animation is used to animate the padding of the drawer when it closes, so that the padding does not block the content underneath it. const drawerPaddingOut = keyframes` 0% { @@ -54,6 +32,12 @@ const drawerPaddingOut = keyframes` const getOpenOverlayStyles = (size: number) => css` grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px ${size}px; + + @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { + grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px calc( + 100vw - ${DRAWER_TOOLBAR_WIDTH * 2}px + ); + } `; const getClosedOverlayStyles = (size: number) => css` @@ -67,15 +51,15 @@ const openEmbeddedStyles = css` margin-left: -${EMBEDDED_TOOLBAR_OVERFLOW_PADDING}px; @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { - animation-name: ${drawerInMobile}; - animation-fill-mode: forwards; + grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px calc( + 100vw - ${DRAWER_TOOLBAR_WIDTH * 2}px + ); } `; const closedEmbeddedStyles = css` @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { - animation-name: ${drawerOutMobile}; - animation-fill-mode: forwards; + grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px 0px; } `; diff --git a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.styles.ts b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.styles.ts index 612317ea18..f5991c6c70 100644 --- a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.styles.ts +++ b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.styles.ts @@ -10,6 +10,8 @@ import { } from '../../constants'; import { Size } from '../../Drawer/Drawer.types'; import { getDrawerWidth } from '../../Drawer/Drawer.utils'; +import { Theme } from '@leafygreen-ui/lib'; +import { drawerClassName } from '../../Drawer/Drawer.styles'; const baseStyles = css` width: 100%; @@ -22,6 +24,10 @@ const baseStyles = css` overflow: hidden; position: relative; height: 100%; + + @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { + /* grid-template-areas: unset; */ + } `; const setDrawerDefaultWidth = ({ @@ -59,14 +65,16 @@ const withoutToolbarBaseStyles = css` ); @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { - grid-template-columns: unset; - grid-template-rows: 100% 0; + /* grid-template-columns: unset; + grid-template-rows: 100% 0; */ + grid-template-columns: auto 0; } `; const withoutToolbarOpenStyles = css` @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { - grid-template-rows: 50% 50%; + /* grid-template-rows: 50% 50%; */ + grid-template-columns: auto 0; } `; @@ -116,3 +124,47 @@ export const getEmbeddedDrawerLayoutStyles = ({ }, className, ); + +export const baseWrapperStyles = css` + display: grid; + grid-template-columns: 0px auto; + grid-template-areas: 'filler ${GRID_AREA.innerDrawer}'; + grid-area: ${GRID_AREA.drawer}; + justify-self: end; + z-index: 0; + height: 100%; + overflow: hidden; + position: relative; + transition-property: grid-template-columns; + transition-duration: ${TRANSITION_DURATION}ms; + transition-timing-function: ${TRANSITION_TIMING_FUNCTION}; + + @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { + grid-template-columns: 0px 0px; + } + + .${drawerClassName} { + grid-area: ${GRID_AREA.innerDrawer}; + + @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { + height: unset; + } + } +`; + +export const wrapperOpenStyles = css` + @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { + grid-template-columns: 0px calc(100vw - ${DRAWER_TOOLBAR_WIDTH}px); + } +`; + +export const getEmbeddedDrawerWrapperStyles = ({ + isDrawerOpen, + theme, +}: { + isDrawerOpen?: boolean; + theme: Theme; +}) => + cx(baseWrapperStyles, { + [wrapperOpenStyles]: isDrawerOpen, + }); diff --git a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx index 0357a0876c..e707711756 100644 --- a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx +++ b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx @@ -2,8 +2,14 @@ import React, { forwardRef } from 'react'; import { useDrawerLayoutContext } from '../../DrawerLayout/DrawerLayoutContext/DrawerLayoutContext'; -import { getEmbeddedDrawerLayoutStyles } from './EmbeddedDrawerLayout.styles'; +import { + getEmbeddedDrawerLayoutStyles, + getEmbeddedDrawerWrapperStyles, +} from './EmbeddedDrawerLayout.styles'; import { EmbeddedDrawerLayoutProps } from './EmbeddedDrawerLayout.types'; +import { css } from '@leafygreen-ui/emotion'; +import { GRID_AREA } from '../../constants'; +import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; /** * @internal @@ -23,6 +29,7 @@ export const EmbeddedDrawerLayout = forwardRef< ) => { const { hasToolbar, isDrawerOpen, drawerWidth, isDrawerResizing, size } = useDrawerLayoutContext(); + const { theme } = useDarkMode(); return (
- {children} - {drawer} + {drawer !== undefined ? ( + <> +
+ {children} +
+
+ {drawer} +
+ + ) : ( + children + )}
); }, diff --git a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.styles.ts b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.styles.ts index d6dd2aac46..3086ce1085 100644 --- a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.styles.ts +++ b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.styles.ts @@ -2,7 +2,7 @@ import { DRAWER_TOOLBAR_WIDTH, GRID_AREA } from '../../constants'; import { css, cx, keyframes } from '@leafygreen-ui/emotion'; import { Theme } from '@leafygreen-ui/lib'; -import { addOverflowShadow, Side } from '@leafygreen-ui/tokens'; +import { addOverflowShadow, Side, breakpoints } from '@leafygreen-ui/tokens'; import { toolbarClassName } from '@leafygreen-ui/toolbar'; import { @@ -49,6 +49,7 @@ export const getOverlayDrawerLayoutStyles = ({ className, ); +const MOBILE_BREAKPOINT = breakpoints.Tablet; const SHADOW_WIDTH = 36; // Width of the shadow padding on the left side // This animation is used to animate the padding of the drawer when it closes, so that the padding does not block the content underneath it. @@ -66,6 +67,10 @@ const drawerPaddingOut = keyframes` const getOpenOverlayStyles = (size: number) => css` grid-template-columns: 0px ${size}px; + + @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { + grid-template-columns: 0px calc(100vw - ${DRAWER_TOOLBAR_WIDTH}px); + } `; const getClosedOverlayStyles = (size: number) => css` @@ -104,7 +109,7 @@ const baseWrapperStyles = css` transform: unset; overflow: hidden; opacity: 1; - border-left: 0; + /* border-left: 0; */ border-right: 0; height: 100%; animation: none; diff --git a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx index 4964da9b2a..09edd6d0a4 100644 --- a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx +++ b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx @@ -37,7 +37,6 @@ export const OverlayDrawerLayout = forwardRef< {drawer !== undefined ? ( <>
Date: Thu, 21 Aug 2025 11:30:57 -0400 Subject: [PATCH 08/36] refactor(Drawer): streamline styles by removing unused animations --- .../DrawerWithToolbarWrapper.styles.ts | 53 ++++--------------- .../DrawerWithToolbarWrapper.tsx | 7 +-- .../EmbeddedDrawerLayout.styles.ts | 4 -- .../EmbeddedDrawerLayout.tsx | 2 +- 4 files changed, 13 insertions(+), 53 deletions(-) diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts index 2bbf4b3c29..6c087fe529 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts @@ -1,4 +1,4 @@ -import { css, cx, keyframes } from '@leafygreen-ui/emotion'; +import { css, cx } from '@leafygreen-ui/emotion'; import { Theme } from '@leafygreen-ui/lib'; import { addOverflowShadow, breakpoints, Side } from '@leafygreen-ui/tokens'; import { toolbarClassName } from '@leafygreen-ui/toolbar'; @@ -17,19 +17,6 @@ import { getDrawerWidth } from '../../Drawer/Drawer.utils'; const MOBILE_BREAKPOINT = breakpoints.Tablet; const SHADOW_WIDTH = 36; // Width of the shadow padding on the left side -// This animation is used to animate the padding of the drawer when it closes, so that the padding does not block the content underneath it. -const drawerPaddingOut = keyframes` - 0% { - padding-left: ${SHADOW_WIDTH}px; - } - 99% { - padding-left: ${SHADOW_WIDTH}px; - } - 100% { - padding-left: 0px; - } -`; - const getOpenOverlayStyles = (size: number) => css` grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px ${size}px; @@ -63,14 +50,6 @@ const closedEmbeddedStyles = css` } `; -const baseEmbeddedStyles = css` - transition-property: grid-template-columns; - transition-duration: ${TRANSITION_DURATION}ms; - transition-timing-function: ${TRANSITION_TIMING_FUNCTION}; - grid-template-columns: 1fr auto; - width: 100%; -`; - const getOverlayShadowStyles = ({ theme }: { theme: Theme }) => css` ${addOverflowShadow({ isInside: false, side: Side.Left, theme })}; @@ -98,6 +77,10 @@ const baseStyles = css` height: 100%; overflow: hidden; position: relative; + transition-property: grid-template-columns; + transition-duration: ${TRANSITION_DURATION}ms; + transition-timing-function: ${TRANSITION_TIMING_FUNCTION}; + grid-template-columns: 1fr auto; .${toolbarClassName} { grid-area: ${GRID_AREA.toolbar}; @@ -113,6 +96,7 @@ const baseStyles = css` border-right: 0; height: 100%; animation: none; + width: 100%; > div::before { box-shadow: unset; @@ -120,22 +104,8 @@ const baseStyles = css` } `; -const baseOverlayStyles = css` - transition-property: grid-template-columns; - transition-duration: ${TRANSITION_DURATION}ms; - transition-timing-function: ${TRANSITION_TIMING_FUNCTION}; - grid-template-columns: 1fr auto; - - .${drawerClassName} { - width: 100%; - } -`; - const closedOverlayShadowStyles = css` padding-left: 0; - animation-name: ${drawerPaddingOut}; - animation-timing-function: ${TRANSITION_TIMING_FUNCTION}; - animation-duration: ${TRANSITION_DURATION}ms; ::before { opacity: 0; @@ -145,31 +115,30 @@ const closedOverlayShadowStyles = css` export const getDrawerWithToolbarWrapperStyles = ({ className, isDrawerOpen, - shouldAnimate, displayMode, theme, + hasToolbar, size: sizeProp = Size.Default, }: { className?: string; isDrawerOpen?: boolean; - shouldAnimate?: boolean; displayMode?: DisplayMode; theme: Theme; + hasToolbar: boolean; size?: Size; }) => { const isOverlay = displayMode === DisplayMode.Overlay; const isEmbedded = displayMode === DisplayMode.Embedded; - const size = getDrawerWidth({ size: sizeProp }).withToolbar; + const drawerWidth = getDrawerWidth({ size: sizeProp }); + const size = hasToolbar ? drawerWidth.withToolbar : drawerWidth.default; return cx( baseStyles, { [getOverlayShadowStyles({ theme })]: isOverlay, [closedOverlayShadowStyles]: isOverlay && !isDrawerOpen, - [baseOverlayStyles]: isOverlay, [getOpenOverlayStyles(size)]: isDrawerOpen && isOverlay, - [getClosedOverlayStyles(size)]: !isDrawerOpen && isOverlay, // This ensures that the drawer does not animate closed on initial render - [baseEmbeddedStyles]: isEmbedded, + [getClosedOverlayStyles(size)]: !isDrawerOpen && isOverlay, [openEmbeddedStyles]: isDrawerOpen && isEmbedded, [closedEmbeddedStyles]: !isDrawerOpen && isEmbedded, }, diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx index 3c4d2f701c..7e26ea9fd9 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx @@ -20,24 +20,19 @@ export const DrawerWithToolbarWrapper = forwardRef< DrawerWithToolbarWrapperProps >(({ children, className }: DrawerWithToolbarWrapperProps, forwardedRef) => { const { theme } = useDarkMode(); - const [shouldAnimate, setShouldAnimate] = useState(false); const { displayMode, size } = useDrawerLayoutContext(); const { isDrawerOpen } = useDrawerToolbarContext(); - useEffect(() => { - if (isDrawerOpen) setShouldAnimate(true); - }, [isDrawerOpen]); - return (
{children} diff --git a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.styles.ts b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.styles.ts index f5991c6c70..c62e337b14 100644 --- a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.styles.ts +++ b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.styles.ts @@ -26,7 +26,6 @@ const baseStyles = css` height: 100%; @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { - /* grid-template-areas: unset; */ } `; @@ -65,15 +64,12 @@ const withoutToolbarBaseStyles = css` ); @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { - /* grid-template-columns: unset; - grid-template-rows: 100% 0; */ grid-template-columns: auto 0; } `; const withoutToolbarOpenStyles = css` @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { - /* grid-template-rows: 50% 50%; */ grid-template-columns: auto 0; } `; diff --git a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx index e707711756..1ad75f94ab 100644 --- a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx +++ b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx @@ -41,7 +41,7 @@ export const EmbeddedDrawerLayout = forwardRef< isDrawerResizing, size, })} - // Prevents a new style class everytime the width changes + // Prevents a new style class every time the width changes style={{ '--drawer-width': `${drawerWidth}` } as React.CSSProperties} > {drawer !== undefined ? ( From 4e5a7ff487d4ee727535016f9251ca077c01406c Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 21 Aug 2025 13:32:38 -0400 Subject: [PATCH 09/36] refactor(Drawer): update context and layout components to use the same styles, wip --- .../DrawerToolbarContext.tsx | 17 ++- .../DrawerToolbarLayoutContent.tsx | 31 +++- .../DrawerWithToolbarWrapper.styles.ts | 64 ++++++--- .../DrawerWithToolbarWrapper.tsx | 13 +- .../EmbeddedDrawerLayout.styles.ts | 46 ------ .../EmbeddedDrawerLayout.tsx | 12 +- .../OverlayDrawerLayout.styles.ts | 132 +----------------- .../OverlayDrawerLayout.tsx | 23 ++- 8 files changed, 114 insertions(+), 224 deletions(-) diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarContext/DrawerToolbarContext.tsx b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarContext/DrawerToolbarContext.tsx index 956a8226d5..19329ad901 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarContext/DrawerToolbarContext.tsx +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarContext/DrawerToolbarContext.tsx @@ -14,8 +14,11 @@ import { DrawerToolbarProviderProps, } from './DrawerToolbarContext.types'; -export const DrawerToolbarContext = - createContext(null); +export const DrawerToolbarContext = createContext< + Partial +>({ + isDrawerOpen: undefined, +}); export const DrawerToolbarProvider = ({ children, @@ -89,11 +92,11 @@ export const DrawerToolbarProvider = ({ export const useDrawerToolbarContext = () => { const context = useContext(DrawerToolbarContext); - if (!context) { - throw new Error( - 'useDrawerToolbarContext must be used within a DrawerToolbarProvider', - ); - } + // if (!context) { + // throw new Error( + // 'useDrawerToolbarContext must be used within a DrawerToolbarProvider', + // ); + // } return context; }; diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx index 4e6e1e88f6..f7838086e8 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx @@ -128,9 +128,18 @@ export const DrawerToolbarLayoutContent = forwardRef< ); }; + const renderDrawerWithToolbar = () => { + return ( + <> + {shouldRenderToolbar && renderToolbar()} + {renderDrawer()} + + ); + }; + return ( <> - {shouldRenderToolbar ? ( + {/* {shouldRenderToolbar ? (
{children}
@@ -140,9 +149,25 @@ export const DrawerToolbarLayoutContent = forwardRef<
) : ( -
{children}
+ {children}
- )} + )} */} + + {/* +
{children}
+ + {shouldRenderToolbar && renderToolbar()} + {renderDrawer()} + +
*/} + + + {children} + ); }, diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts index 6c087fe529..40e181b8b8 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts @@ -17,36 +17,44 @@ import { getDrawerWidth } from '../../Drawer/Drawer.utils'; const MOBILE_BREAKPOINT = breakpoints.Tablet; const SHADOW_WIDTH = 36; // Width of the shadow padding on the left side -const getOpenOverlayStyles = (size: number) => css` - grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px ${size}px; +const getOpenOverlayStyles = (size: number, hasToolbar: boolean) => css` + grid-template-columns: ${hasToolbar + ? `${DRAWER_TOOLBAR_WIDTH}px ${size}px` + : `${size}px`}; @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { - grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px calc( - 100vw - ${DRAWER_TOOLBAR_WIDTH * 2}px - ); + grid-template-columns: ${hasToolbar + ? `${DRAWER_TOOLBAR_WIDTH}px calc(100vw - ${DRAWER_TOOLBAR_WIDTH * 2}px)` + : `calc(100vw - ${DRAWER_TOOLBAR_WIDTH}px)`}; } `; -const getClosedOverlayStyles = (size: number) => css` - grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px 0px; +const getClosedOverlayStyles = (hasToolbar: boolean) => css` + grid-template-columns: ${hasToolbar + ? `${DRAWER_TOOLBAR_WIDTH}px 0px` + : `0px`}; `; -const openEmbeddedStyles = css` - grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px auto; +const getOpenEmbeddedStyles = (hasToolbar: boolean) => css` + grid-template-columns: ${hasToolbar + ? `${DRAWER_TOOLBAR_WIDTH}px auto` + : `auto`}; // To show focus outline since the wrapper has overflow hidden padding-left: ${EMBEDDED_TOOLBAR_OVERFLOW_PADDING}px; margin-left: -${EMBEDDED_TOOLBAR_OVERFLOW_PADDING}px; @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { - grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px calc( - 100vw - ${DRAWER_TOOLBAR_WIDTH * 2}px - ); + grid-template-columns: ${hasToolbar + ? `${DRAWER_TOOLBAR_WIDTH}px calc(100vw - ${DRAWER_TOOLBAR_WIDTH * 2}px)` + : `calc(100vw - ${DRAWER_TOOLBAR_WIDTH}px)`}; } `; -const closedEmbeddedStyles = css` +const getClosedEmbeddedStyles = (hasToolbar: boolean) => css` @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { - grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px 0px; + grid-template-columns: ${hasToolbar + ? `${DRAWER_TOOLBAR_WIDTH}px 0px` + : `0px`}; } `; @@ -65,10 +73,20 @@ const getOverlayShadowStyles = ({ theme }: { theme: Theme }) => css` } `; -const baseStyles = css` +const getBaseStyles = (hasToolbar: boolean) => css` display: grid; - grid-template-columns: ${DRAWER_TOOLBAR_WIDTH}px 0px; - grid-template-areas: '${GRID_AREA.toolbar} ${GRID_AREA.innerDrawer}'; + grid-template-columns: ${hasToolbar + ? `${DRAWER_TOOLBAR_WIDTH}px 0px` + : `0px`}; + grid-template-areas: ${hasToolbar + ? `'${GRID_AREA.toolbar} ${GRID_AREA.innerDrawer}'` + : `'${GRID_AREA.innerDrawer}'`}; + @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { + grid-template-columns: ${hasToolbar + ? `${DRAWER_TOOLBAR_WIDTH}px 0px` + : `0px`}; + } + grid-area: ${GRID_AREA.drawer}; justify-self: end; animation-timing-function: ${TRANSITION_TIMING_FUNCTION}; @@ -92,11 +110,11 @@ const baseStyles = css` transform: unset; overflow: hidden; opacity: 1; - border-left: 0; border-right: 0; height: 100%; animation: none; width: 100%; + ${hasToolbar ? 'border-left: 0;' : ''} > div::before { box-shadow: unset; @@ -133,14 +151,14 @@ export const getDrawerWithToolbarWrapperStyles = ({ const size = hasToolbar ? drawerWidth.withToolbar : drawerWidth.default; return cx( - baseStyles, + getBaseStyles(hasToolbar), { [getOverlayShadowStyles({ theme })]: isOverlay, [closedOverlayShadowStyles]: isOverlay && !isDrawerOpen, - [getOpenOverlayStyles(size)]: isDrawerOpen && isOverlay, - [getClosedOverlayStyles(size)]: !isDrawerOpen && isOverlay, - [openEmbeddedStyles]: isDrawerOpen && isEmbedded, - [closedEmbeddedStyles]: !isDrawerOpen && isEmbedded, + [getOpenOverlayStyles(size, hasToolbar)]: isDrawerOpen && isOverlay, + [getClosedOverlayStyles(hasToolbar)]: !isDrawerOpen && isOverlay, + [getOpenEmbeddedStyles(hasToolbar)]: isDrawerOpen && isEmbedded, + [getClosedEmbeddedStyles(hasToolbar)]: !isDrawerOpen && isEmbedded, }, className, ); diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx index 7e26ea9fd9..713bf35ff3 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx @@ -20,8 +20,15 @@ export const DrawerWithToolbarWrapper = forwardRef< DrawerWithToolbarWrapperProps >(({ children, className }: DrawerWithToolbarWrapperProps, forwardedRef) => { const { theme } = useDarkMode(); - const { displayMode, size } = useDrawerLayoutContext(); - const { isDrawerOpen } = useDrawerToolbarContext(); + const { + displayMode, + size, + hasToolbar = false, + isDrawerOpen: isDrawerOpenLayout, + } = useDrawerLayoutContext(); + const { isDrawerOpen: isDrawerOpenToolbar } = useDrawerToolbarContext(); + + const isDrawerOpen = isDrawerOpenToolbar ?? isDrawerOpenLayout; return (
{children} diff --git a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.styles.ts b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.styles.ts index c62e337b14..dc02aefede 100644 --- a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.styles.ts +++ b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.styles.ts @@ -10,8 +10,6 @@ import { } from '../../constants'; import { Size } from '../../Drawer/Drawer.types'; import { getDrawerWidth } from '../../Drawer/Drawer.utils'; -import { Theme } from '@leafygreen-ui/lib'; -import { drawerClassName } from '../../Drawer/Drawer.styles'; const baseStyles = css` width: 100%; @@ -120,47 +118,3 @@ export const getEmbeddedDrawerLayoutStyles = ({ }, className, ); - -export const baseWrapperStyles = css` - display: grid; - grid-template-columns: 0px auto; - grid-template-areas: 'filler ${GRID_AREA.innerDrawer}'; - grid-area: ${GRID_AREA.drawer}; - justify-self: end; - z-index: 0; - height: 100%; - overflow: hidden; - position: relative; - transition-property: grid-template-columns; - transition-duration: ${TRANSITION_DURATION}ms; - transition-timing-function: ${TRANSITION_TIMING_FUNCTION}; - - @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { - grid-template-columns: 0px 0px; - } - - .${drawerClassName} { - grid-area: ${GRID_AREA.innerDrawer}; - - @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { - height: unset; - } - } -`; - -export const wrapperOpenStyles = css` - @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { - grid-template-columns: 0px calc(100vw - ${DRAWER_TOOLBAR_WIDTH}px); - } -`; - -export const getEmbeddedDrawerWrapperStyles = ({ - isDrawerOpen, - theme, -}: { - isDrawerOpen?: boolean; - theme: Theme; -}) => - cx(baseWrapperStyles, { - [wrapperOpenStyles]: isDrawerOpen, - }); diff --git a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx index 1ad75f94ab..8d27df7c4a 100644 --- a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx +++ b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx @@ -2,14 +2,13 @@ import React, { forwardRef } from 'react'; import { useDrawerLayoutContext } from '../../DrawerLayout/DrawerLayoutContext/DrawerLayoutContext'; -import { - getEmbeddedDrawerLayoutStyles, - getEmbeddedDrawerWrapperStyles, -} from './EmbeddedDrawerLayout.styles'; +import { getEmbeddedDrawerLayoutStyles } from './EmbeddedDrawerLayout.styles'; import { EmbeddedDrawerLayoutProps } from './EmbeddedDrawerLayout.types'; import { css } from '@leafygreen-ui/emotion'; import { GRID_AREA } from '../../constants'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; +import { DisplayMode } from '../../Drawer/Drawer.types'; +import { getDrawerWithToolbarWrapperStyles } from '../../DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles'; /** * @internal @@ -56,9 +55,12 @@ export const EmbeddedDrawerLayout = forwardRef< {children}
{drawer} diff --git a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.styles.ts b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.styles.ts index 3086ce1085..64f149cbdb 100644 --- a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.styles.ts +++ b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.styles.ts @@ -1,17 +1,6 @@ import { DRAWER_TOOLBAR_WIDTH, GRID_AREA } from '../../constants'; -import { css, cx, keyframes } from '@leafygreen-ui/emotion'; -import { Theme } from '@leafygreen-ui/lib'; -import { addOverflowShadow, Side, breakpoints } from '@leafygreen-ui/tokens'; -import { toolbarClassName } from '@leafygreen-ui/toolbar'; - -import { - TRANSITION_DURATION, - TRANSITION_TIMING_FUNCTION, -} from '../../constants'; -import { drawerClassName } from '../../Drawer/Drawer.styles'; -import { DisplayMode, Size } from '../../Drawer/Drawer.types'; -import { getDrawerWidth } from '../../Drawer/Drawer.utils'; +import { css, cx } from '@leafygreen-ui/emotion'; const baseStyles = css` width: 100%; @@ -48,122 +37,3 @@ export const getOverlayDrawerLayoutStyles = ({ }, className, ); - -const MOBILE_BREAKPOINT = breakpoints.Tablet; -const SHADOW_WIDTH = 36; // Width of the shadow padding on the left side - -// This animation is used to animate the padding of the drawer when it closes, so that the padding does not block the content underneath it. -const drawerPaddingOut = keyframes` - 0% { - padding-left: ${SHADOW_WIDTH}px; - } - 99% { - padding-left: ${SHADOW_WIDTH}px; - } - 100% { - padding-left: 0px; - } -`; - -const getOpenOverlayStyles = (size: number) => css` - grid-template-columns: 0px ${size}px; - - @media only screen and (max-width: ${MOBILE_BREAKPOINT}px) { - grid-template-columns: 0px calc(100vw - ${DRAWER_TOOLBAR_WIDTH}px); - } -`; - -const getClosedOverlayStyles = (size: number) => css` - grid-template-columns: 0px 0px; -`; - -const getOverlayShadowStyles = ({ theme }: { theme: Theme }) => css` - ${addOverflowShadow({ isInside: false, side: Side.Left, theme })}; - - // Need this to show the box shadow since we are using overflow: hidden - padding-left: ${SHADOW_WIDTH}px; - - &::before { - transition-property: opacity; - transition-duration: ${TRANSITION_DURATION}ms; - transition-timing-function: ${TRANSITION_TIMING_FUNCTION}; - opacity: 1; - left: ${SHADOW_WIDTH}px; - } -`; - -const baseWrapperStyles = css` - display: grid; - grid-template-columns: 0px 0px; - grid-template-areas: 'filler ${GRID_AREA.innerDrawer}'; - grid-area: ${GRID_AREA.drawer}; - justify-self: end; - z-index: 0; - height: 100%; - overflow: hidden; - position: relative; - - .${drawerClassName} { - grid-area: ${GRID_AREA.innerDrawer}; - position: unset; - transform: unset; - overflow: hidden; - opacity: 1; - /* border-left: 0; */ - border-right: 0; - height: 100%; - animation: none; - - > div::before { - box-shadow: unset; - } - } -`; - -const baseOverlayStyles = css` - transition-property: grid-template-columns; - transition-duration: ${TRANSITION_DURATION}ms; - transition-timing-function: ${TRANSITION_TIMING_FUNCTION}; - grid-template-columns: 1fr auto; - - .${drawerClassName} { - width: 100%; - } -`; - -const closedOverlayShadowStyles = css` - padding-left: 0; - animation-name: ${drawerPaddingOut}; - animation-timing-function: ${TRANSITION_TIMING_FUNCTION}; - animation-duration: ${TRANSITION_DURATION}ms; - - ::before { - opacity: 0; - } -`; - -export const getOverlayDrawerWrapperStyles = ({ - className, - isDrawerOpen, - theme, - size: sizeProp = Size.Default, -}: { - className?: string; - isDrawerOpen?: boolean; - theme: Theme; - size?: Size; -}) => { - const size = getDrawerWidth({ size: sizeProp }).default; - - return cx( - baseWrapperStyles, - getOverlayShadowStyles({ theme }), - baseOverlayStyles, - { - [closedOverlayShadowStyles]: !isDrawerOpen, - [getOpenOverlayStyles(size)]: isDrawerOpen, - [getClosedOverlayStyles(size)]: !isDrawerOpen, - }, - className, - ); -}; diff --git a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx index 09edd6d0a4..ff11be3185 100644 --- a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx +++ b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx @@ -2,14 +2,14 @@ import React, { forwardRef } from 'react'; import { useDrawerLayoutContext } from '../../DrawerLayout/DrawerLayoutContext/DrawerLayoutContext'; -import { - getOverlayDrawerLayoutStyles, - getOverlayDrawerWrapperStyles, -} from './OverlayDrawerLayout.styles'; +import { getOverlayDrawerLayoutStyles } from './OverlayDrawerLayout.styles'; import { OverlayDrawerLayoutProps } from './OverlayDrawerLayout.types'; import { css } from '@leafygreen-ui/emotion'; import { GRID_AREA } from '../../constants'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; +import { getDrawerWithToolbarWrapperStyles } from '../../DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles'; +import { DisplayMode } from '../../Drawer/Drawer.types'; +import { useDrawerToolbarContext } from '../../DrawerToolbarLayout/DrawerToolbarContext'; /** * @internal @@ -23,8 +23,17 @@ export const OverlayDrawerLayout = forwardRef< HTMLDivElement, OverlayDrawerLayoutProps >(({ children, className, drawer }: OverlayDrawerLayoutProps, forwardedRef) => { - const { hasToolbar, isDrawerOpen, size } = useDrawerLayoutContext(); + const { + hasToolbar, + isDrawerOpen: isDrawerOpenLayout, + size, + } = useDrawerLayoutContext(); const { theme } = useDarkMode(); + const { isDrawerOpen: isDrawerOpenToolbar } = useDrawerToolbarContext(); + + console.log('🦄', { isDrawerOpenLayout, isDrawerOpenToolbar }); + + const isDrawerOpen = isDrawerOpenToolbar ?? isDrawerOpenLayout; return (
{drawer} From 4353428ff2ee03d7844d681cbbf439ef8b95011e Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 21 Aug 2025 13:54:22 -0400 Subject: [PATCH 10/36] refactor(Drawer): improve context handling and layout structure for better drawer integration --- .../DrawerToolbarContext.tsx | 17 ++--- .../DrawerToolbarLayoutContent.tsx | 5 +- .../DrawerWithToolbarWrapper.tsx | 71 ++++++++++++------- .../DrawerWithToolbarWrapper.types.ts | 8 ++- .../EmbeddedDrawerLayout.tsx | 32 ++------- .../OverlayDrawerLayout.tsx | 44 ++---------- .../OverlayDrawerLayout.types.ts | 1 - 7 files changed, 71 insertions(+), 107 deletions(-) diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarContext/DrawerToolbarContext.tsx b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarContext/DrawerToolbarContext.tsx index 19329ad901..956a8226d5 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarContext/DrawerToolbarContext.tsx +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarContext/DrawerToolbarContext.tsx @@ -14,11 +14,8 @@ import { DrawerToolbarProviderProps, } from './DrawerToolbarContext.types'; -export const DrawerToolbarContext = createContext< - Partial ->({ - isDrawerOpen: undefined, -}); +export const DrawerToolbarContext = + createContext(null); export const DrawerToolbarProvider = ({ children, @@ -92,11 +89,11 @@ export const DrawerToolbarProvider = ({ export const useDrawerToolbarContext = () => { const context = useContext(DrawerToolbarContext); - // if (!context) { - // throw new Error( - // 'useDrawerToolbarContext must be used within a DrawerToolbarProvider', - // ); - // } + if (!context) { + throw new Error( + 'useDrawerToolbarContext must be used within a DrawerToolbarProvider', + ); + } return context; }; diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx index f7838086e8..9e1e14c27d 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx @@ -1,4 +1,4 @@ -import React, { forwardRef, useEffect, useLayoutEffect } from 'react'; +import React, { forwardRef, useLayoutEffect } from 'react'; import { Toolbar, ToolbarIconButton } from '@leafygreen-ui/toolbar'; @@ -50,7 +50,7 @@ export const DrawerToolbarLayoutContent = forwardRef< const lgIds = getLgIds(dataLgId); // This updates the drawer open state when the toolbar is inter - useEffect(() => { + useLayoutEffect(() => { setIsDrawerOpen(isDrawerOpen); }, [isDrawerOpen, setIsDrawerOpen]); @@ -165,6 +165,7 @@ export const DrawerToolbarLayoutContent = forwardRef< {...rest} drawer={renderDrawerWithToolbar()} ref={forwardRef} + key={shouldRenderToolbar ? 'toolbar' : 'no-toolbar'} > {children} diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx index 713bf35ff3..1db9e514b2 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx @@ -7,6 +7,8 @@ import { useDrawerToolbarContext } from '../DrawerToolbarContext'; import { getDrawerWithToolbarWrapperStyles } from './DrawerWithToolbarWrapper.styles'; import { DrawerWithToolbarWrapperProps } from './DrawerWithToolbarWrapper.types'; +import { GRID_AREA } from '../../constants'; +import { css } from '@leafygreen-ui/emotion'; /** * @internal @@ -18,33 +20,50 @@ import { DrawerWithToolbarWrapperProps } from './DrawerWithToolbarWrapper.types' export const DrawerWithToolbarWrapper = forwardRef< HTMLDivElement, DrawerWithToolbarWrapperProps ->(({ children, className }: DrawerWithToolbarWrapperProps, forwardedRef) => { - const { theme } = useDarkMode(); - const { - displayMode, - size, - hasToolbar = false, - isDrawerOpen: isDrawerOpenLayout, - } = useDrawerLayoutContext(); - const { isDrawerOpen: isDrawerOpenToolbar } = useDrawerToolbarContext(); +>( + ( + { children, className, drawer }: DrawerWithToolbarWrapperProps, + forwardedRef, + ) => { + const { theme } = useDarkMode(); + const { + displayMode, + size, + hasToolbar = false, + isDrawerOpen, + // isDrawerOpen: isDrawerOpenLayout, + } = useDrawerLayoutContext(); + // const { isDrawerOpen: isDrawerOpenToolbar } = useDrawerToolbarContext(); - const isDrawerOpen = isDrawerOpenToolbar ?? isDrawerOpenLayout; + // const isDrawerOpen = isDrawerOpenToolbar ?? isDrawerOpenLayout; - return ( -
- {children} -
- ); -}); + return ( + <> +
+ {children} +
+
+ {drawer} +
+ + ); + }, +); DrawerWithToolbarWrapper.displayName = 'DrawerWithToolbarWrapper'; diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.types.ts b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.types.ts index 688af72421..5a3d146192 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.types.ts +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.types.ts @@ -1,3 +1,9 @@ import { HTMLElementProps } from '@leafygreen-ui/lib'; -export type DrawerWithToolbarWrapperProps = HTMLElementProps<'div'>; +export type DrawerWithToolbarWrapperProps = Omit< + HTMLElementProps<'div'>, + 'children' +> & { + drawer: React.ReactNode; + children: React.ReactNode; +}; diff --git a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx index 8d27df7c4a..64d4baa6a8 100644 --- a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx +++ b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx @@ -4,11 +4,7 @@ import { useDrawerLayoutContext } from '../../DrawerLayout/DrawerLayoutContext/D import { getEmbeddedDrawerLayoutStyles } from './EmbeddedDrawerLayout.styles'; import { EmbeddedDrawerLayoutProps } from './EmbeddedDrawerLayout.types'; -import { css } from '@leafygreen-ui/emotion'; -import { GRID_AREA } from '../../constants'; -import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; -import { DisplayMode } from '../../Drawer/Drawer.types'; -import { getDrawerWithToolbarWrapperStyles } from '../../DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles'; +import { DrawerWithToolbarWrapper } from '../../DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper'; /** * @internal @@ -28,7 +24,6 @@ export const EmbeddedDrawerLayout = forwardRef< ) => { const { hasToolbar, isDrawerOpen, drawerWidth, isDrawerResizing, size } = useDrawerLayoutContext(); - const { theme } = useDarkMode(); return (
{drawer !== undefined ? ( - <> -
- {children} -
-
- {drawer} -
- + + {children} + ) : ( children )} diff --git a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx index ff11be3185..52601725fb 100644 --- a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx +++ b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx @@ -4,12 +4,7 @@ import { useDrawerLayoutContext } from '../../DrawerLayout/DrawerLayoutContext/D import { getOverlayDrawerLayoutStyles } from './OverlayDrawerLayout.styles'; import { OverlayDrawerLayoutProps } from './OverlayDrawerLayout.types'; -import { css } from '@leafygreen-ui/emotion'; -import { GRID_AREA } from '../../constants'; -import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; -import { getDrawerWithToolbarWrapperStyles } from '../../DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles'; -import { DisplayMode } from '../../Drawer/Drawer.types'; -import { useDrawerToolbarContext } from '../../DrawerToolbarLayout/DrawerToolbarContext'; +import { DrawerWithToolbarWrapper } from '../../DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper'; /** * @internal @@ -23,17 +18,7 @@ export const OverlayDrawerLayout = forwardRef< HTMLDivElement, OverlayDrawerLayoutProps >(({ children, className, drawer }: OverlayDrawerLayoutProps, forwardedRef) => { - const { - hasToolbar, - isDrawerOpen: isDrawerOpenLayout, - size, - } = useDrawerLayoutContext(); - const { theme } = useDarkMode(); - const { isDrawerOpen: isDrawerOpenToolbar } = useDrawerToolbarContext(); - - console.log('🦄', { isDrawerOpenLayout, isDrawerOpenToolbar }); - - const isDrawerOpen = isDrawerOpenToolbar ?? isDrawerOpenLayout; + const { hasToolbar } = useDrawerLayoutContext(); return (
{drawer !== undefined ? ( - <> -
- {children} -
-
- {drawer} -
- + + {children} + ) : ( children )} diff --git a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.types.ts b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.types.ts index 9fd349c46d..e005b972e7 100644 --- a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.types.ts +++ b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.types.ts @@ -1,4 +1,3 @@ import { LayoutComponentProps } from '../../LayoutComponent/LayoutComponent.types'; -// export type OverlayDrawerLayoutProps = Omit; export type OverlayDrawerLayoutProps = LayoutComponentProps; From 9034a7fa309540c165e98e616f3eee606dbee147 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 21 Aug 2025 14:25:36 -0400 Subject: [PATCH 11/36] refactor(Drawer): consolidate layout rendering and improve content styling --- .../DrawerToolbarLayoutContent.tsx | 27 +++++++++++++++++-- .../DrawerWithToolbarWrapper.styles.ts | 6 +++++ .../DrawerWithToolbarWrapper.tsx | 24 +++++------------ 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx index 9e1e14c27d..b6c2c10600 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx @@ -9,7 +9,6 @@ import { DEFAULT_LGID_ROOT, getLgIds } from '../../utils'; import { useDrawerToolbarContext } from '../DrawerToolbarContext/DrawerToolbarContext'; import { DrawerWithToolbarWrapper } from '../DrawerWithToolbarWrapper/DrawerWithToolbarWrapper'; -import { contentStyles } from './DrawerToolbarLayout.styles'; import { DrawerToolbarLayoutContentProps, LayoutData, @@ -161,13 +160,37 @@ export const DrawerToolbarLayoutContent = forwardRef< */} - {children} + */} + + {/* {shouldRenderToolbar ? ( + + + {children} + + + ) : ( + + + {children} + + + )} */} + + + + {children} + ); diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts index 40e181b8b8..8f3c74404e 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts @@ -130,6 +130,12 @@ const closedOverlayShadowStyles = css` } `; +export const contentStyles = css` + grid-area: ${GRID_AREA.content}; + overflow: scroll; + height: inherit; +`; + export const getDrawerWithToolbarWrapperStyles = ({ className, isDrawerOpen, diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx index 1db9e514b2..6fc20212fc 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx @@ -1,14 +1,14 @@ -import React, { forwardRef, useEffect, useState } from 'react'; +import React, { forwardRef } from 'react'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; import { useDrawerLayoutContext } from '../../DrawerLayout'; -import { useDrawerToolbarContext } from '../DrawerToolbarContext'; -import { getDrawerWithToolbarWrapperStyles } from './DrawerWithToolbarWrapper.styles'; +import { + contentStyles, + getDrawerWithToolbarWrapperStyles, +} from './DrawerWithToolbarWrapper.styles'; import { DrawerWithToolbarWrapperProps } from './DrawerWithToolbarWrapper.types'; -import { GRID_AREA } from '../../constants'; -import { css } from '@leafygreen-ui/emotion'; /** * @internal @@ -31,23 +31,11 @@ export const DrawerWithToolbarWrapper = forwardRef< size, hasToolbar = false, isDrawerOpen, - // isDrawerOpen: isDrawerOpenLayout, } = useDrawerLayoutContext(); - // const { isDrawerOpen: isDrawerOpenToolbar } = useDrawerToolbarContext(); - - // const isDrawerOpen = isDrawerOpenToolbar ?? isDrawerOpenLayout; return ( <> -
- {children} -
+
{children}
Date: Thu, 21 Aug 2025 15:05:57 -0400 Subject: [PATCH 12/36] feat(Drawer): introduce LayoutGrid component for improved drawer layout management --- .../DrawerToolbarLayout.tsx | 1 + .../DrawerToolbarLayoutContent.tsx | 77 ++++--------------- .../DrawerWithToolbarWrapper.tsx | 57 -------------- .../DrawerWithToolbarWrapper/index.ts | 1 - .../EmbeddedDrawerLayout.tsx | 10 +-- .../LayoutGrid/LayoutGrid.styles.ts} | 2 +- .../LayoutComponent/LayoutGrid/LayoutGrid.tsx | 55 +++++++++++++ .../LayoutGrid/LayoutGrid.types.ts} | 5 +- .../src/LayoutComponent/LayoutGrid/index.ts | 1 + .../OverlayDrawerLayout.tsx | 8 +- 10 files changed, 80 insertions(+), 137 deletions(-) delete mode 100644 packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx delete mode 100644 packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/index.ts rename packages/drawer/src/{DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts => LayoutComponent/LayoutGrid/LayoutGrid.styles.ts} (98%) create mode 100644 packages/drawer/src/LayoutComponent/LayoutGrid/LayoutGrid.tsx rename packages/drawer/src/{DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.types.ts => LayoutComponent/LayoutGrid/LayoutGrid.types.ts} (54%) create mode 100644 packages/drawer/src/LayoutComponent/LayoutGrid/index.ts diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.tsx b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.tsx index 6e81178069..11653face7 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.tsx +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.tsx @@ -20,6 +20,7 @@ export const DrawerToolbarLayout = forwardRef< ) => { return ( + {/* This extra content component allows us to use useDrawerToolbarContext since we can't use useDrawerToolbarContext in the same file that the provider is wrapped in */} { - return ( - <> - {shouldRenderToolbar && renderToolbar()} - {renderDrawer()} - - ); - }; + const renderDrawerWithToolbar = () => ( + <> + {renderToolbar()} + {renderDrawer()} + + ); return ( - <> - {/* {shouldRenderToolbar ? ( - -
{children}
- - {renderToolbar()} - {renderDrawer()} - -
- ) : ( - - {children} - - )} */} - - {/* -
{children}
- - {shouldRenderToolbar && renderToolbar()} - {renderDrawer()} - -
*/} - - {/* + {children} - */} - - {/* {shouldRenderToolbar ? ( - - - {children} - - - ) : ( - - - {children} - - - )} */} - - - - {children} - - - + + ); }, ); diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx deleted file mode 100644 index 6fc20212fc..0000000000 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import React, { forwardRef } from 'react'; - -import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; - -import { useDrawerLayoutContext } from '../../DrawerLayout'; - -import { - contentStyles, - getDrawerWithToolbarWrapperStyles, -} from './DrawerWithToolbarWrapper.styles'; -import { DrawerWithToolbarWrapperProps } from './DrawerWithToolbarWrapper.types'; - -/** - * @internal - * - * This layout wrapper is used to position the toolbar and drawer together. When the drawer is open, the toolbar and drawer will shift to the right. - * - * If the drawer is overlay, a box shadow will be applied to the left side of this component. - */ -export const DrawerWithToolbarWrapper = forwardRef< - HTMLDivElement, - DrawerWithToolbarWrapperProps ->( - ( - { children, className, drawer }: DrawerWithToolbarWrapperProps, - forwardedRef, - ) => { - const { theme } = useDarkMode(); - const { - displayMode, - size, - hasToolbar = false, - isDrawerOpen, - } = useDrawerLayoutContext(); - - return ( - <> -
{children}
-
- {drawer} -
- - ); - }, -); - -DrawerWithToolbarWrapper.displayName = 'DrawerWithToolbarWrapper'; diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/index.ts b/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/index.ts deleted file mode 100644 index f7179c70b1..0000000000 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { DrawerWithToolbarWrapper } from './DrawerWithToolbarWrapper'; diff --git a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx index 64d4baa6a8..c2e938552e 100644 --- a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx +++ b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx @@ -4,14 +4,14 @@ import { useDrawerLayoutContext } from '../../DrawerLayout/DrawerLayoutContext/D import { getEmbeddedDrawerLayoutStyles } from './EmbeddedDrawerLayout.styles'; import { EmbeddedDrawerLayoutProps } from './EmbeddedDrawerLayout.types'; -import { DrawerWithToolbarWrapper } from '../../DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper'; +import { LayoutGrid } from '../LayoutGrid'; /** * @internal * - * This layout wrapper is used to create a layout that has 2 grid columns. The main content is on the left and the drawer is on the right. + * This layout wrapper is used to create a layout that has 2 grid columns. The main content is on the left and the drawer and toolbar(if present) is on the right. * - * Since this layout is used for embedded drawers, when the drawer is open, the layout will shift to the right by the width of the drawer + toolbar if it exists. + * Since this layout is used for embedded drawers, when the drawer is open, the layout will shift to the right by the width of the drawer + toolbar(if present). * */ export const EmbeddedDrawerLayout = forwardRef< @@ -39,9 +39,7 @@ export const EmbeddedDrawerLayout = forwardRef< style={{ '--drawer-width': `${drawerWidth}` } as React.CSSProperties} > {drawer !== undefined ? ( - - {children} - + {children} ) : ( children )} diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts b/packages/drawer/src/LayoutComponent/LayoutGrid/LayoutGrid.styles.ts similarity index 98% rename from packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts rename to packages/drawer/src/LayoutComponent/LayoutGrid/LayoutGrid.styles.ts index 8f3c74404e..c446cb397b 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.styles.ts +++ b/packages/drawer/src/LayoutComponent/LayoutGrid/LayoutGrid.styles.ts @@ -136,7 +136,7 @@ export const contentStyles = css` height: inherit; `; -export const getDrawerWithToolbarWrapperStyles = ({ +export const getLayoutGridStyles = ({ className, isDrawerOpen, displayMode, diff --git a/packages/drawer/src/LayoutComponent/LayoutGrid/LayoutGrid.tsx b/packages/drawer/src/LayoutComponent/LayoutGrid/LayoutGrid.tsx new file mode 100644 index 0000000000..1b295f26d2 --- /dev/null +++ b/packages/drawer/src/LayoutComponent/LayoutGrid/LayoutGrid.tsx @@ -0,0 +1,55 @@ +import React, { forwardRef } from 'react'; + +import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; + +import { useDrawerLayoutContext } from '../../DrawerLayout'; + +import { contentStyles, getLayoutGridStyles } from './LayoutGrid.styles'; +import { LayoutGridProps } from './LayoutGrid.types'; + +/** + * @internal + * + * This layout component is used to wrap the toolbar(if present) and drawer in it's own grid. + * + * If there is a toolbar, there will be 2 grid columns. The toolbar will be in the first column and the drawer will be in the second column. + * + * If there is no toolbar, there will be 1 grid column. The drawer will be in the first column. + * + * If the drawer is overlay, the column width is increased and acts as a position absolute container. This gets around using transforms directly on the drawer element, which was causing unexpected behavior. + * A box shadow is also applied to the left side of the drawer. + * + * If the drawer is embedded, the grid width is set to auto and inherits the column size of the parent column. + */ +export const LayoutGrid = forwardRef( + ({ children, className, drawer }: LayoutGridProps, forwardedRef) => { + const { theme } = useDarkMode(); + const { + displayMode, + size, + hasToolbar = false, + isDrawerOpen, + } = useDrawerLayoutContext(); + + return ( + <> +
{children}
+
+ {drawer} +
+ + ); + }, +); + +LayoutGrid.displayName = 'LayoutGrid'; diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.types.ts b/packages/drawer/src/LayoutComponent/LayoutGrid/LayoutGrid.types.ts similarity index 54% rename from packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.types.ts rename to packages/drawer/src/LayoutComponent/LayoutGrid/LayoutGrid.types.ts index 5a3d146192..1a733e9dd1 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper.types.ts +++ b/packages/drawer/src/LayoutComponent/LayoutGrid/LayoutGrid.types.ts @@ -1,9 +1,6 @@ import { HTMLElementProps } from '@leafygreen-ui/lib'; -export type DrawerWithToolbarWrapperProps = Omit< - HTMLElementProps<'div'>, - 'children' -> & { +export type LayoutGridProps = Omit, 'children'> & { drawer: React.ReactNode; children: React.ReactNode; }; diff --git a/packages/drawer/src/LayoutComponent/LayoutGrid/index.ts b/packages/drawer/src/LayoutComponent/LayoutGrid/index.ts new file mode 100644 index 0000000000..9662a9b823 --- /dev/null +++ b/packages/drawer/src/LayoutComponent/LayoutGrid/index.ts @@ -0,0 +1 @@ +export { LayoutGrid } from './LayoutGrid'; diff --git a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx index 52601725fb..037926796d 100644 --- a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx +++ b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx @@ -4,12 +4,12 @@ import { useDrawerLayoutContext } from '../../DrawerLayout/DrawerLayoutContext/D import { getOverlayDrawerLayoutStyles } from './OverlayDrawerLayout.styles'; import { OverlayDrawerLayoutProps } from './OverlayDrawerLayout.types'; -import { DrawerWithToolbarWrapper } from '../../DrawerToolbarLayout/DrawerWithToolbarWrapper/DrawerWithToolbarWrapper'; +import { LayoutGrid } from '../LayoutGrid'; /** * @internal * - * This layout wrapper is used to create a layout that has 2 grid columns. The main content is on the left and the drawer is on the right. + * This layout wrapper is used to create a layout that has 2 grid columns. The main content is on the left and the drawer and toolbar(if present) is on the right. * * Since this layout is used for overlay drawers, when the drawer is open, the layout will not shift. Instead the shifting is handled by the children of this component. * @@ -29,9 +29,7 @@ export const OverlayDrawerLayout = forwardRef< })} > {drawer !== undefined ? ( - - {children} - + {children} ) : ( children )} From 5ddfc49c53a8a07931ac90e79b194a2d12257c47 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 21 Aug 2025 16:06:13 -0400 Subject: [PATCH 13/36] refactor(Drawer): clean up unused code and lint --- packages/drawer/src/Drawer/Drawer.tsx | 23 ++++--------------- .../drawer/src/DrawerLayout/DrawerLayout.tsx | 8 ------- .../DrawerToolbarLayout.stories.tsx | 8 +++---- .../DrawerToolbarLayoutContent.tsx | 2 +- .../EmbeddedDrawerLayout.tsx | 2 +- .../src/LayoutComponent/LayoutComponent.tsx | 8 +------ .../OverlayDrawerLayout.styles.ts | 4 ++-- .../OverlayDrawerLayout.tsx | 2 +- 8 files changed, 14 insertions(+), 43 deletions(-) diff --git a/packages/drawer/src/Drawer/Drawer.tsx b/packages/drawer/src/Drawer/Drawer.tsx index 30d6b6ef46..32856a0065 100644 --- a/packages/drawer/src/Drawer/Drawer.tsx +++ b/packages/drawer/src/Drawer/Drawer.tsx @@ -72,8 +72,6 @@ export const Drawer = forwardRef( const ref = useRef(null); const [previousWidth, setPreviousWidth] = useState(0); - // const [initialSize, setInitialSize] = useState(0); - // Returns the resolved displayMode, open state, and onClose function based on the component and context props. const { displayMode, open, onClose, size } = useResolvedDrawerProps({ componentDisplayMode: displayModeProp, @@ -90,15 +88,6 @@ export const Drawer = forwardRef( const { initialSize, resizableMinWidth, resizableMaxWidth } = getResolvedDrawerSizes(size, hasToolbar); - // const initialSizeEmbedded = - // drawerWidth === 0 - // ? initialSize - // : hasToolbar - // ? drawerWidth - 48 - // : drawerWidth; - - // console.log('🐙', { initialSizeEmbedded }); - const isEmbedded = displayMode === DisplayMode.Embedded; const isOverlay = displayMode === DisplayMode.Overlay; const isResizableEnabled = isEmbedded && !!resizable && open; @@ -168,7 +157,6 @@ export const Drawer = forwardRef( const { resizableRef, size: drawerSize, - setSize, getResizerProps, isResizing, } = useResizable({ @@ -179,18 +167,15 @@ export const Drawer = forwardRef( position: Position.Right, }); + /** + * On initial render, if the drawer is embedded and there was a previous width, that means that the previous drawer was open and may have been resized. This takes that previous width and uses it as the initial size. + */ useEffect(() => { - console.log('🥊drawer render', { - drawerWidth, - open, - hasToolbar, - initialSize, - }); if (open && isEmbedded && drawerWidth !== 0) { - console.log('😡'); const prevWidth = hasToolbar ? drawerWidth + 48 : drawerWidth - 48; setPreviousWidth(prevWidth); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { diff --git a/packages/drawer/src/DrawerLayout/DrawerLayout.tsx b/packages/drawer/src/DrawerLayout/DrawerLayout.tsx index 7560392044..26c18f0a7c 100644 --- a/packages/drawer/src/DrawerLayout/DrawerLayout.tsx +++ b/packages/drawer/src/DrawerLayout/DrawerLayout.tsx @@ -1,7 +1,5 @@ import React, { forwardRef } from 'react'; -import { consoleOnce } from '@leafygreen-ui/lib'; - import { DisplayMode, Size } from '../Drawer/Drawer.types'; import { DrawerToolbarLayout } from '../DrawerToolbarLayout'; import { LayoutComponent } from '../LayoutComponent'; @@ -29,12 +27,6 @@ export const DrawerLayout = forwardRef( ) => { const hasToolbar = toolbarData && toolbarData.length > 0; - // if (!hasToolbar) { - // consoleOnce.warn( - // 'Using a Drawer without a toolbar is not recommended. To include a toolbar, pass a toolbarData prop containing the desired toolbar items.', - // ); - // } - return ( = ({ ); const Component: StoryFn = ({ - toolbarData = DRAWER_TOOLBAR_DATA, + toolbarData: _toolbarDataProp, ...args }: DrawerLayoutProps) => { - const [toolbarDataArr, setToolbarDataArr] = useState(DRAWER_TOOLBAR_DATA); + const [toolbarData, setToolbarData] = useState(DRAWER_TOOLBAR_DATA); const MainContent = () => { const { openDrawer } = useDrawerToolbarContext(); @@ -209,7 +209,7 @@ const Component: StoryFn = ({
diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx index 1cf9ba62fc..3f1bd864b4 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx @@ -5,9 +5,9 @@ import { Toolbar, ToolbarIconButton } from '@leafygreen-ui/toolbar'; import { Drawer } from '../../Drawer/Drawer'; import { useDrawerLayoutContext } from '../../DrawerLayout'; import { LayoutComponent } from '../../LayoutComponent'; +import { LayoutGrid } from '../../LayoutComponent/LayoutGrid'; import { DEFAULT_LGID_ROOT, getLgIds } from '../../utils'; import { useDrawerToolbarContext } from '../DrawerToolbarContext/DrawerToolbarContext'; -import { LayoutGrid } from '../../LayoutComponent/LayoutGrid'; import { DrawerToolbarLayoutContentProps, diff --git a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx index c2e938552e..277e0c1dc7 100644 --- a/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx +++ b/packages/drawer/src/LayoutComponent/EmbeddedDrawerLayout/EmbeddedDrawerLayout.tsx @@ -1,10 +1,10 @@ import React, { forwardRef } from 'react'; import { useDrawerLayoutContext } from '../../DrawerLayout/DrawerLayoutContext/DrawerLayoutContext'; +import { LayoutGrid } from '../LayoutGrid'; import { getEmbeddedDrawerLayoutStyles } from './EmbeddedDrawerLayout.styles'; import { EmbeddedDrawerLayoutProps } from './EmbeddedDrawerLayout.types'; -import { LayoutGrid } from '../LayoutGrid'; /** * @internal diff --git a/packages/drawer/src/LayoutComponent/LayoutComponent.tsx b/packages/drawer/src/LayoutComponent/LayoutComponent.tsx index 95a4aadbf8..20743c85b6 100644 --- a/packages/drawer/src/LayoutComponent/LayoutComponent.tsx +++ b/packages/drawer/src/LayoutComponent/LayoutComponent.tsx @@ -1,4 +1,4 @@ -import React, { forwardRef, useEffect } from 'react'; +import React, { forwardRef } from 'react'; import LeafyGreenProvider, { useDarkMode, @@ -10,8 +10,6 @@ import { useDrawerLayoutContext } from '../DrawerLayout'; import { EmbeddedDrawerLayout } from './EmbeddedDrawerLayout'; import { LayoutComponentProps } from './LayoutComponent.types'; import { OverlayDrawerLayout } from './OverlayDrawerLayout'; -import { GRID_AREA } from '../constants'; -import { css } from '@leafygreen-ui/emotion'; /** * @internal @@ -27,10 +25,6 @@ export const LayoutComponent = forwardRef( const { darkMode } = useDarkMode(darkModeProp); const { displayMode } = useDrawerLayoutContext(); - useEffect(() => { - console.log('🥬 initial render'); - }, []); - const Component = displayMode === DisplayMode.Overlay ? OverlayDrawerLayout diff --git a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.styles.ts b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.styles.ts index 64f149cbdb..67811c7ad8 100644 --- a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.styles.ts +++ b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.styles.ts @@ -1,7 +1,7 @@ -import { DRAWER_TOOLBAR_WIDTH, GRID_AREA } from '../../constants'; - import { css, cx } from '@leafygreen-ui/emotion'; +import { DRAWER_TOOLBAR_WIDTH, GRID_AREA } from '../../constants'; + const baseStyles = css` width: 100%; position: relative; diff --git a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx index 037926796d..ce51c5a0bd 100644 --- a/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx +++ b/packages/drawer/src/LayoutComponent/OverlayDrawerLayout/OverlayDrawerLayout.tsx @@ -1,10 +1,10 @@ import React, { forwardRef } from 'react'; import { useDrawerLayoutContext } from '../../DrawerLayout/DrawerLayoutContext/DrawerLayoutContext'; +import { LayoutGrid } from '../LayoutGrid'; import { getOverlayDrawerLayoutStyles } from './OverlayDrawerLayout.styles'; import { OverlayDrawerLayoutProps } from './OverlayDrawerLayout.types'; -import { LayoutGrid } from '../LayoutGrid'; /** * @internal From dea7657b6cbc1cf204de0769f0c0dbee5ab51351 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 21 Aug 2025 16:43:56 -0400 Subject: [PATCH 14/36] feat(Drawer): add toolbar visibility toggle functionality and update test utils --- ...awerToolbarLayout.interactions.stories.tsx | 142 +++++++++++++++++- .../DrawerToolbarLayout.stories.tsx | 82 +--------- .../DrawerToolbarLayout.testutils.tsx | 68 +++++++-- .../LayoutGrid/LayoutGrid.styles.ts | 9 +- 4 files changed, 205 insertions(+), 96 deletions(-) diff --git a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.interactions.stories.tsx b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.interactions.stories.tsx index 9f8d29839e..ac3a10ba22 100644 --- a/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.interactions.stories.tsx +++ b/packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.interactions.stories.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { storybookExcludedControlParams } from '@lg-tools/storybook-utils'; import { StoryFn, StoryObj } from '@storybook/react'; import { expect, userEvent, waitFor, within } from '@storybook/test'; @@ -16,6 +16,7 @@ import { useDrawerToolbarContext } from '../DrawerToolbarContext/DrawerToolbarCo import { DrawerToolbarLayout } from './DrawerToolbarLayout'; import { DRAWER_TOOLBAR_DATA, + DRAWER_TOOLBAR_DATA_NOT_VISIBLE, LongContent, } from './DrawerToolbarLayout.testutils'; import { DrawerToolbarLayoutProps } from './DrawerToolbarLayout.types'; @@ -101,6 +102,57 @@ const Template: StoryFn = ({ ); }; +const TemplateWithToolbarToggle: StoryFn< + DrawerToolbarLayoutPropsWithDisplayMode +> = ({ + displayMode = DisplayMode.Embedded, +}: DrawerToolbarLayoutPropsWithDisplayMode) => { + const [toolbarData, setToolbarData] = useState(DRAWER_TOOLBAR_DATA); + + const MainContent = () => { + const { openDrawer } = useDrawerToolbarContext(); + + return ( +
+ + + + +
+ ); + }; + + return ( +
+ + + + + +
+ ); +}; + export const OverlayOpensFirstToolbarItem: StoryObj = { render: (args: DrawerToolbarLayoutProps) =>