Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
81b4834
wip
shaneeza Aug 19, 2025
7d5c51a
Merge branch 'main' of github.com:mongodb/leafygreen-ui into LG-5460/…
shaneeza Aug 19, 2025
4425a92
feat(DrawerToolbar): enhance toolbar visibility management and add to…
shaneeza Aug 19, 2025
765cb0e
wip, not complete
shaneeza Aug 20, 2025
8fbac68
remove resolvedInitialState
shaneeza Aug 20, 2025
239f230
actually remove resolvedInitialState
shaneeza Aug 20, 2025
722285b
maybe a fix?
shaneeza Aug 20, 2025
4f4c940
refactor(Drawer): remove unused animations and update layout styles f…
shaneeza Aug 21, 2025
d647c0c
refactor(Drawer): streamline styles by removing unused animations
shaneeza Aug 21, 2025
4e5a7ff
refactor(Drawer): update context and layout components to use the sam…
shaneeza Aug 21, 2025
4353428
refactor(Drawer): improve context handling and layout structure for b…
shaneeza Aug 21, 2025
9034a7f
refactor(Drawer): consolidate layout rendering and improve content st…
shaneeza Aug 21, 2025
80bf409
feat(Drawer): introduce LayoutGrid component for improved drawer layo…
shaneeza Aug 21, 2025
5ddfc49
refactor(Drawer): clean up unused code and lint
shaneeza Aug 21, 2025
dea7657
feat(Drawer): add toolbar visibility toggle functionality and update …
shaneeza Aug 21, 2025
8a79d90
refactor(Drawer): update constants and styles
shaneeza Aug 21, 2025
a848942
refactor(Drawer): adjust mobile layout styles for toolbar visibility
shaneeza Aug 21, 2025
20d3c4b
refactor(Drawer): rename story exports for clarity and enhance toolba…
shaneeza Aug 21, 2025
492e04a
Merge branch 'main' of github.com:mongodb/leafygreen-ui into LG-5460/…
shaneeza Aug 21, 2025
dd40b81
refactor(Drawer): enhance layout styles and logic for drawer visibili…
shaneeza Aug 21, 2025
edb5b16
refactor(Drawer): update drawer width calculation and enhance toolbar…
shaneeza Aug 21, 2025
071d3d1
test(Drawer): add unit test for setHasToolbar functionality in Drawer…
shaneeza Aug 22, 2025
d3a1678
refactor(Drawer): improve embedded styles and overlay handling for dr…
shaneeza Aug 22, 2025
baea4e8
Merge branch 'main' of github.com:mongodb/leafygreen-ui into LG-5460/…
shaneeza Aug 22, 2025
e8be639
docs(Drawer): update README
shaneeza Aug 22, 2025
9a47eb2
refactor(Drawer): remove empty media query from embedded drawer styles
shaneeza Aug 22, 2025
805d104
docs(Drawer): add changesets
shaneeza Aug 22, 2025
a7ffe95
feat(Drawer): replace layoutGird with PanelGrid component and update …
shaneeza Aug 26, 2025
6464ed9
refactor(Drawer): remove unused contentStyles from DrawerToolbarLayou…
shaneeza Aug 26, 2025
7d8d6af
fix(Drawer): update initial width calculation to consider resizable s…
shaneeza Aug 26, 2025
9415f08
Merge branch 'main' of github.com:mongodb/leafygreen-ui into LG-5460/…
shaneeza Aug 27, 2025
5df0a8c
feat(Drawer): refactor styling logic for embedded drawer layout with …
shaneeza Aug 27, 2025
58074f7
fix(Drawer): simplify props handling in DrawerToolbarLayout story
shaneeza Aug 27, 2025
7cf355e
feat(Drawer): enhance DrawerToolbarLayout with dynamic toolbar visibi…
shaneeza Aug 27, 2025
12518b3
feat(Drawer): implement useCallback for data retrieval and add test f…
shaneeza Aug 27, 2025
8f9b60b
feat(Drawer): introduce useToolbarData hook for managing toolbar stat…
shaneeza Aug 27, 2025
ee3b879
fix(Drawer): refine drawer closing logic
shaneeza Aug 27, 2025
c64b534
fix(Drawer): update useToolbarData dependencies to include hasToolbar…
shaneeza Aug 27, 2025
960bfce
docs(Drawer): add changeset
shaneeza Aug 28, 2025
8017dd5
merge conflict
shaneeza Aug 28, 2025
9569c7f
Merge branch 'LG-5460/hide-drawer-toolbar' of github.com:mongodb/leaf…
shaneeza Aug 28, 2025
831438d
fix(DrawerToolbarLayout): improve drawer closing logic based on activ…
shaneeza Aug 28, 2025
6cbabcc
merge conflict
shaneeza Aug 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/violet-drinks-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@leafygreen-ui/drawer': patch
---

Fixes bug where the drawer would not close when the active toolbar item became hidden.
When a drawer with a toolbar is open and its corresponding active toolbar item's visibility is set to false, the drawer will now automatically close.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';

Check warning on line 1 in packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.interactions.stories.tsx

View workflow job for this annotation

GitHub Actions / Check lints

'useState' is defined but never used. Allowed unused vars must match /^_/u
import { storybookExcludedControlParams } from '@lg-tools/storybook-utils';
import { StoryFn, StoryObj } from '@storybook/react';
import { expect, userEvent, waitFor, within } from '@storybook/test';
Expand All @@ -17,14 +17,11 @@
import {
getDrawerToolbarData,
LongContent,
useToolbarData,
} from './DrawerToolbarLayout.testutils';
import { DrawerToolbarLayoutProps } from './DrawerToolbarLayout.types';

const DRAWER_TOOLBAR_DATA = getDrawerToolbarData({ hasStaticContent: true });
const DRAWER_TOOLBAR_DATA_NOT_VISIBLE = getDrawerToolbarData({
hasStaticContent: true,
isToolbarHidden: true,
});

// The tooltip sometimes lingers after the drawer closes, which can cause
// snapshot tests to fail if the tooltip is not in the correct position.
Expand Down Expand Up @@ -112,7 +109,8 @@
> = ({
displayMode = DisplayMode.Embedded,
}: DrawerToolbarLayoutPropsWithDisplayMode) => {
const [toolbarData, setToolbarData] = useState(DRAWER_TOOLBAR_DATA);
const { toolbarData, setHasToolbarData, setHasHiddenToolbarItem } =
useToolbarData(DRAWER_TOOLBAR_DATA);

const MainContent = () => {
const { openDrawer } = useDrawerToolbarContext();
Expand All @@ -124,17 +122,12 @@
`}
>
<Button onClick={() => openDrawer('Code')}>Open Code Drawer</Button>
<Button
onClick={() =>
setToolbarData(prevData =>
prevData === DRAWER_TOOLBAR_DATA
? DRAWER_TOOLBAR_DATA_NOT_VISIBLE
: DRAWER_TOOLBAR_DATA,
)
}
>
<Button onClick={() => setHasToolbarData(prev => !prev)}>
Toggle Toolbar visibility
</Button>
<Button onClick={() => setHasHiddenToolbarItem(prev => !prev)}>
Toggle Toolbar item
</Button>
<LongContent />
<LongContent />
</main>
Expand Down Expand Up @@ -250,6 +243,99 @@
},
};

export const OverlayRemovesToolbarWhenAllItemsAreHidden: StoryObj<DrawerToolbarLayoutPropsWithDisplayMode> =
{
render: (args: DrawerToolbarLayoutPropsWithDisplayMode) => (
<TemplateWithToolbarToggle {...args} />
),
args: {
displayMode: DisplayMode.Overlay,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const { getToolbarTestUtils, isOpen } = getTestUtils();
const { getToolbarIconButtonByLabel, queryToolbar } =
getToolbarTestUtils();

// Verify toolbar is initially visible
const toolbar = queryToolbar();
expect(toolbar).toBeInTheDocument();

const codeButton = getToolbarIconButtonByLabel('Code')?.getElement();
expect(codeButton).toBeInTheDocument();

// Open the drawer
expect(isOpen()).toBe(false);
userEvent.click(codeButton!);

await waitFor(() => {
expect(isOpen()).toBe(true);
expect(canvas.getByText('Code Title')).toBeVisible();
});

// Click the toggle button to hide toolbar
const toggleButton = canvas.getByText('Toggle Toolbar visibility');
userEvent.click(toggleButton);

// Verify toolbar element is removed but drawer remains open
await waitFor(() => {
const hiddenToolbar = queryToolbar();
expect(hiddenToolbar).not.toBeInTheDocument();
expect(isOpen()).toBe(true);
expect(canvas.getByText('Code Title')).toBeVisible();
});
},
};

export const OverlayClosesDrawerWhenActiveItemIsHidden: StoryObj<DrawerToolbarLayoutPropsWithDisplayMode> =
{
render: (args: DrawerToolbarLayoutPropsWithDisplayMode) => (
<TemplateWithToolbarToggle {...args} />
),
args: {
displayMode: DisplayMode.Overlay,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const { getToolbarTestUtils, isOpen } = getTestUtils();
const {
getToolbarIconButtonByLabel,
queryToolbar,
getAllToolbarIconButtons,
} = getToolbarTestUtils();

// Verify toolbar is initially visible
const toolbar = queryToolbar();
expect(toolbar).toBeInTheDocument();
expect(getAllToolbarIconButtons().length).toBe(5);

const activeButton = getToolbarIconButtonByLabel('Apps')?.getElement();
expect(activeButton).toBeInTheDocument();

// Open the drawer
expect(isOpen()).toBe(false);
userEvent.click(activeButton!);

await waitFor(() => {
expect(isOpen()).toBe(true);
expect(canvas.getByText('Apps Title')).toBeVisible();
});

// Click the toggle button remove 'Apps' item from toolbar
const toggleButton = canvas.getByText('Toggle Toolbar item');
userEvent.click(toggleButton);

// Verify toolbar element is visible but drawer is closed
await waitFor(() => {
const hiddenToolbar = queryToolbar();
expect(hiddenToolbar).toBeInTheDocument();
expect(isOpen()).toBe(false);
expect(canvas.getByText('Apps Title')).not.toBeVisible();
expect(getAllToolbarIconButtons().length).toBe(4);
});
},
};

export const EmbeddedOpensFirstToolbarItem: StoryObj<DrawerToolbarLayoutPropsWithDisplayMode> =
{
render: (args: DrawerToolbarLayoutPropsWithDisplayMode) => (
Expand Down Expand Up @@ -344,13 +430,13 @@
},
};

export const OverlayRemovesToolbarWhenAllItemsAreHidden: StoryObj<DrawerToolbarLayoutPropsWithDisplayMode> =
export const EmbeddedRemovesToolbarWhenAllItemsAreHidden: StoryObj<DrawerToolbarLayoutPropsWithDisplayMode> =
{
render: (args: DrawerToolbarLayoutPropsWithDisplayMode) => (
<TemplateWithToolbarToggle {...args} />
),
args: {
displayMode: DisplayMode.Overlay,
displayMode: DisplayMode.Embedded,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
Expand Down Expand Up @@ -388,7 +474,7 @@
},
};

export const EmbeddedRemovesToolbarWhenAllItemsAreHidden: StoryObj<DrawerToolbarLayoutPropsWithDisplayMode> =
export const EmbeddedClosesDrawerWhenActiveItemIsHidden: StoryObj<DrawerToolbarLayoutPropsWithDisplayMode> =
{
render: (args: DrawerToolbarLayoutPropsWithDisplayMode) => (
<TemplateWithToolbarToggle {...args} />
Expand All @@ -399,35 +485,40 @@
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const { getToolbarTestUtils, isOpen } = getTestUtils();
const { getToolbarIconButtonByLabel, queryToolbar } =
getToolbarTestUtils();
const {
getToolbarIconButtonByLabel,
queryToolbar,
getAllToolbarIconButtons,
} = getToolbarTestUtils();

// Verify toolbar is initially visible
const toolbar = queryToolbar();
expect(toolbar).toBeInTheDocument();
expect(getAllToolbarIconButtons().length).toBe(5);

const codeButton = getToolbarIconButtonByLabel('Code')?.getElement();
expect(codeButton).toBeInTheDocument();
const activeButton = getToolbarIconButtonByLabel('Apps')?.getElement();
expect(activeButton).toBeInTheDocument();

// Open the drawer
expect(isOpen()).toBe(false);
userEvent.click(codeButton!);
userEvent.click(activeButton!);

await waitFor(() => {
expect(isOpen()).toBe(true);
expect(canvas.getByText('Code Title')).toBeVisible();
expect(canvas.getByText('Apps Title')).toBeVisible();
});

// Click the toggle button to hide toolbar
const toggleButton = canvas.getByText('Toggle Toolbar visibility');
// Click the toggle button remove 'Apps' item from toolbar
const toggleButton = canvas.getByText('Toggle Toolbar item');
userEvent.click(toggleButton);

// Verify toolbar element is removed but drawer remains open
// Verify toolbar element is visible but drawer is closed
await waitFor(() => {
const hiddenToolbar = queryToolbar();
expect(hiddenToolbar).not.toBeInTheDocument();
expect(isOpen()).toBe(true);
expect(canvas.getByText('Code Title')).toBeVisible();
expect(hiddenToolbar).toBeInTheDocument();
expect(isOpen()).toBe(false);
expect(canvas.getByText('Apps Title')).not.toBeVisible();
expect(getAllToolbarIconButtons().length).toBe(4);
});
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -195,4 +195,40 @@ describe('packages/DrawerToolbarLayout', () => {

expect(queryToolbar()).not.toBeInTheDocument();
});

test('closes the drawer when the active item is hidden', () => {
const { rerender } = render(<Component />);

const { getToolbarTestUtils, isOpen } = getTestUtils();

const { getToolbarIconButtonByLabel } = getToolbarTestUtils();
const codeButton = getToolbarIconButtonByLabel('Code')?.getElement();
userEvent.click(codeButton!);

expect(isOpen()).toBe(true);

rerender(
<Component
data={[
{
id: 'Code',
label: 'Code',
content: 'Rerendered Drawer Content',
title: `Rerendered Drawer Title`,
glyph: 'Code',
visible: false,
},
{
id: 'Code2',
label: 'Code2',
content: 'Drawer Content2',
title: `Drawer Title2`,
glyph: 'Code',
},
]}
/>,
);

expect(isOpen()).toBe(false);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@ import { useDrawerToolbarContext } from '../DrawerToolbarContext/DrawerToolbarCo
import {
getDrawerToolbarData,
LongContent,
useToolbarData,
} from './DrawerToolbarLayout.testutils';

const DRAWER_TOOLBAR_DATA = getDrawerToolbarData({});
const DRAWER_TOOLBAR_DATA_NOT_VISIBLE = getDrawerToolbarData({
isToolbarHidden: true,
});

const defaultExcludedControls = [
...storybookExcludedControlParams,
Expand Down Expand Up @@ -127,7 +125,8 @@ const Component: StoryFn<DrawerLayoutProps> = ({
toolbarData: _toolbarDataProp,
...args
}: DrawerLayoutProps) => {
const [toolbarData, setToolbarData] = useState(DRAWER_TOOLBAR_DATA);
const { toolbarData, setHasToolbarData, setHasHiddenToolbarItem } =
useToolbarData(DRAWER_TOOLBAR_DATA);

const props = {
...args,
Expand All @@ -144,17 +143,12 @@ const Component: StoryFn<DrawerLayoutProps> = ({
`}
>
<Button onClick={() => openDrawer('Code')}>Open Code Drawer</Button>
<Button
onClick={() =>
setToolbarData(prevData =>
prevData === DRAWER_TOOLBAR_DATA
? DRAWER_TOOLBAR_DATA_NOT_VISIBLE
: DRAWER_TOOLBAR_DATA,
)
}
>
<Button onClick={() => setHasToolbarData(prev => !prev)}>
Toggle Toolbar visibility
</Button>
<Button onClick={() => setHasHiddenToolbarItem(prev => !prev)}>
Toggle Toolbar item
</Button>
<LongContent />
<LongContent />
</main>
Expand Down
Loading