Skip to content

Commit

Permalink
fix(vertical-menu-full-screen): register Fullscreen subcomponent as a…
Browse files Browse the repository at this point in the history
… Carbon modal

component is now using useModalManager to register as a modal

fixes: #7073
  • Loading branch information
mihai-albu-sage committed Dec 5, 2024
1 parent 6675b86 commit ed49a9e
Show file tree
Hide file tree
Showing 4 changed files with 236 additions and 0 deletions.
100 changes: 100 additions & 0 deletions src/components/vertical-menu/components.test-pw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
VerticalMenuProps,
VerticalMenuItemProps,
} from ".";
import Confirm from "../confirm/confirm.component";
import Box from "../box";
import Pill from "../pill";

Expand Down Expand Up @@ -269,6 +270,105 @@ export const VerticalMenuFullScreenCustom = (
return <VerticalMenu>{menuItems}</VerticalMenu>;
};

export const VerticalMenuFullScreenCustomWithDialog = (
props: Partial<VerticalMenuFullScreenProps>,
) => {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [isModalOpen, setIsModalOpen] = useState(false);

const fullscreenViewBreakPoint = useMediaQuery("(max-width: 1200px)");

const menuItems = (
<>
<VerticalMenuItem iconType="analysis" title="Item 1">
<VerticalMenuItem
title="ChildItem 1"
href="/child-item-1"
adornment={
<Pill borderColor="#fff" fill size="S">
10
</Pill>
}
/>
<VerticalMenuItem href="/child-item-2" title="ChildItem 2" />
</VerticalMenuItem>

<VerticalMenuItem iconType="admin" href="/item1" title="Item 2" />

<VerticalMenuItem iconType="home" title="Item 3">
<VerticalMenuItem
title="Very long text that will be wrapped"
href="/very-long-text-that-will-be-wrapped"
adornment={
<Pill borderColor="#fff" fill size="S">
100
</Pill>
}
/>
<VerticalMenuItem
title="Active item"
href="/active-item"
active
adornment={
<Pill borderColor="#fff" fill size="S">
29
</Pill>
}
/>
</VerticalMenuItem>

<VerticalMenuItem iconType="alert" title="Item 4" href="/item-4" />

<VerticalMenuItem iconType="bank" title="Item 5">
<VerticalMenuItem title="ChildItem 1" href="/child-item-1" />
<VerticalMenuItem title="ChildItem 2" href="/child-item-2" />
</VerticalMenuItem>

<VerticalMenuItem iconType="basket" title="Item 6" href="/item-6" />

<VerticalMenuItem
iconType="calendar"
title="Item 7 - More text to wrap the whole title. More text to wrap the whole title. More text to wrap the whole title. More text to wrap the whole title. "
>
<VerticalMenuItem title="ChildItem 1" href="/child-item-1" />
<VerticalMenuItem title="ChildItem 2" href="/child-item-2" />
</VerticalMenuItem>
</>
);

if (fullscreenViewBreakPoint) {
return (
<>
<VerticalMenuTrigger
onClick={() => {
setIsMenuOpen(!isMenuOpen);
setIsModalOpen(true);
}}
>
Menu
</VerticalMenuTrigger>
<VerticalMenuFullScreen
isOpen={isMenuOpen}
onClose={() => setIsMenuOpen(false)}
{...props}
>
{menuItems}
</VerticalMenuFullScreen>
<Confirm
cancelButtonDestructive
title="Are you sure?"
open={isModalOpen}
onConfirm={() => setIsModalOpen(false)}
onCancel={() => setIsModalOpen(false)}
>
Do you want to leave before saving?
</Confirm>
</>
);
}
return <VerticalMenu>{menuItems}</VerticalMenu>;
};

export const VerticalMenuFullScreenBackgroundScrollTest = () => {
return (
<Box height="2000px" position="relative">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
} from "../vertical-menu.style";
import VerticalMenuFullScreenContext from "./__internal__/vertical-menu-full-screen.context";
import Events from "../../../__internal__/utils/helpers/events/events";
import useModalManager from "../../../hooks/__internal__/useModalManager";

export interface VerticalMenuFullScreenProps extends TagProps {
/** An aria-label attribute for the menu */
Expand Down Expand Up @@ -55,6 +56,13 @@ export const VerticalMenuFullScreen = ({
[onClose],
);

useModalManager({
open: isOpen,
closeModal: handleKeyDown,
modalRef: menuWrapperRef,
topModalOverride: true,
});

// TODO remove this as part of FE-5650
if (!isOpen) return null;

Expand Down
28 changes: 28 additions & 0 deletions src/components/vertical-menu/vertical-menu.pw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
VerticalMenuTriggerCustom,
VerticalMenuItemCustomHref,
VerticalMenuFullScreenCustom,
VerticalMenuFullScreenCustomWithDialog,
VerticalMenuFullScreenBackgroundScrollTest,
ClosedVerticalMenuFullScreenWithButtons,
CustomComponent,
Expand Down Expand Up @@ -602,6 +603,33 @@ test.describe("Events test", () => {
await expect(callbackCount).toBe(1);
});

test(`should be available when a Dialog is opened in the background`, async ({
mount,
page,
}) => {
let callbackCount = 0;
await page.setViewportSize({
width: 320,
height: 599,
});
await mount(
<VerticalMenuFullScreenCustomWithDialog
onClose={() => {
callbackCount += 1;
}}
/>,
);

await verticalMenuTrigger(page).click();

await closeIconButton(page).click();

await expect(callbackCount).toBe(1);

const dialogText = page.getByText("Do you want to leave before saving?");
await expect(dialogText).toBeInViewport();
});

[...keysToTrigger].forEach((key) => {
test(`should call onClose callback when a ${key} key event is triggered`, async ({
mount,
Expand Down
100 changes: 100 additions & 0 deletions src/components/vertical-menu/vertical-menu.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
VerticalMenuTrigger,
} from ".";

import Confirm from "../confirm/confirm.component";

const defaultOpenState = isChromatic();

const meta: Meta<typeof VerticalMenu> = {
Expand Down Expand Up @@ -320,3 +322,101 @@ export const FullScreen: Story = () => {
);
};
FullScreen.storyName = "Full Screen";

export const FullScreenWithModal: Story = () => {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [isModalOpen, setIsModalOpen] = useState(false);
const [disableAutoFocus, setDisableAutoFocus] = useState(false);

const menuItems = (
<>
<VerticalMenuItem iconType="analysis" title="Item 1">
<VerticalMenuItem
title="ChildItem 1"
href="/child-item-1"
adornment={
<Pill borderColor="#fff" fill size="S">
10
</Pill>
}
/>
<VerticalMenuItem href="/child-item-2" title="ChildItem 2" />
</VerticalMenuItem>

<VerticalMenuItem iconType="admin" href="/item1" title="Item 2" />

<VerticalMenuItem iconType="home" title="Item 3">
<VerticalMenuItem
title="Very long text that will be wrapped"
href="/very-long-text-that-will-be-wrapped"
adornment={
<Pill borderColor="#fff" fill size="S">
100
</Pill>
}
/>
<VerticalMenuItem
title="Active item"
href="/active-item"
active
adornment={
<Pill borderColor="#fff" fill size="S">
29
</Pill>
}
/>
</VerticalMenuItem>

<VerticalMenuItem iconType="alert" title="Item 4" href="/item-4" />

<VerticalMenuItem iconType="bank" title="Item 5">
<VerticalMenuItem title="ChildItem 1" href="/child-item-1" />
<VerticalMenuItem title="ChildItem 2" href="/child-item-2" />
</VerticalMenuItem>

<VerticalMenuItem iconType="basket" title="Item 6" href="/item-6" />

<VerticalMenuItem
iconType="calendar"
title="Item 7 - More text to wrap the whole title. More text to wrap the whole title. More text to wrap the whole title. More text to wrap the whole title. "
>
<VerticalMenuItem title="ChildItem 1" href="/child-item-1" />
<VerticalMenuItem title="ChildItem 2" href="/child-item-2" />
</VerticalMenuItem>
</>
);

return (
<>
<VerticalMenuTrigger
onClick={() => {
setDisableAutoFocus(true);
setIsModalOpen(true);
setIsMenuOpen(true);
}}
>
Menu
</VerticalMenuTrigger>
<VerticalMenuFullScreen
isOpen={isMenuOpen}
onClose={() => {
setIsMenuOpen(false);
setDisableAutoFocus(false);
}}
>
{menuItems}
</VerticalMenuFullScreen>
<Confirm
disableAutoFocus={disableAutoFocus}
cancelButtonDestructive
title="Are you sure?"
open={isModalOpen}
onConfirm={() => setIsModalOpen(false)}
onCancel={() => setIsModalOpen(false)}
>
Do you want to leave before saving??
</Confirm>
</>
);
};
FullScreenWithModal.storyName = "Full Screen With Modal";

0 comments on commit ed49a9e

Please sign in to comment.