Repository: Sage/carbon (ts)

Issue:
submenu overflow on Safari
### Description

When a Menu is rendered with a Submenu and various width-related props provided, and the width of the submenu items is greater than that of the parent item, on Chrome (and Firefox) this renders correctly with the submenu the appropriate width 
![image](https://github.com/user-attachments/assets/4e803e49-8592-4b7b-a303-38d6fe7f89dd)

On Safari, the same is rendered only as wide as the parent item, with horizontal overflow:
![image](https://github.com/user-attachments/assets/579a7079-5e81-4e27-8d1e-e5cff16057cb)


### Reproduction

https://stackblitz.com/edit/parsium-carbon-starter-nqzjqy?file=src%2FApp.tsx%3AL5

### Steps to reproduce

_No response_

### JIRA ticket numbers (Sage only)

_No response_

### Suggested solution

_No response_

### Carbon version

144.9.2

### Design tokens version

_No response_

### Relevant browsers

Safari

### Relevant OSs

MacOS

### Additional context

_No response_

### Confidentiality

- [X] I confirm there is no confidential or commercially sensitive information included.

Pull request:
fix(submenu): ensure submenu has expected width in Safari
fix #7112

### Proposed behaviour

<!--
A clear and concise description of what changes this PR makes. If applicable, include any UI screenshots to help explain your request. If you are a Sage contributor, please DO NOT share any commercially sensitive information, such as UI screenshots or code from Sage products.
-->

MenuItem within a submenu extends to the expected width. 

![image](https://github.com/user-attachments/assets/16ac6404-040e-4f6e-9f8a-05112df6a2fb)

### Current behaviour

<!--
A clear and concise description of the behaviour before this change. If applicable, include any UI screenshots to help explain your request. If you are a Sage contributor, please DO NOT share any commercially sensitive information, such as UI screenshots or code from Sage products.
-->

MenuItem within a submenu with overflow gets cut off in Safari. 

![image](https://github.com/user-attachments/assets/1ee12a32-0f32-467a-b581-38df5443901c)

### Checklist

<!-- Each PR should include the following -->

- [x] Commits follow our style guide
- [x] Related issues linked in commit messages if required
- [x] Screenshots are included in the PR if useful
- [ ] All themes are supported if required
- [ ] Unit tests added or updated if required
- [ ] Playwright automation tests added or updated if required
- [ ] Storybook added or updated if required
- [ ] Translations added or updated (including creating or amending translation keys table in storybook) if required
- [ ] Typescript `d.ts` file added or updated if required
- [ ] Related docs have been updated if required

#### QA

- [ ] Tested in provided StackBlitz sandbox/Storybook
- [ ] Add new Playwright test coverage if required
- [ ] Carbon implementation matches Design System/designs
- [ ] UI Tests GitHub check reviewed if required

### Additional context

<!-- Add any other context or links about the pull request here. -->

### Testing instructions

<!--
How can a reviewer test this PR?

If this PR addresses a pre-existing bug, please include a link to a sandbox that reproduces the original bug. A starter template has been provided to help you do this:
<https://stackblitz.com/fork/github/Parsium/carbon-starter>
-->

- See added MenuItem in "submenus with long item labels" test story. 


Patch:
diff --git a/src/components/menu/__internal__/submenu/submenu.style.ts b/src/components/menu/__internal__/submenu/submenu.style.ts
index ad31867c6..a694f8300 100644
--- a/src/components/menu/__internal__/submenu/submenu.style.ts
+++ b/src/components/menu/__internal__/submenu/submenu.style.ts
@@ -88,8 +88,13 @@ const StyledSubmenu = styled.ul<StyledSubmenuProps>`
 
       ${submenuMaxWidth &&
       css`
+        width: max-content;
         max-width: ${submenuMaxWidth};
 
+        li {
+          max-width: ${submenuMaxWidth};
+        }
+
         &&& {
           a,
           button,
diff --git a/src/components/menu/menu-item/menu-item.component.tsx b/src/components/menu/menu-item/menu-item.component.tsx
index a9d339311..583f0346f 100644
--- a/src/components/menu/menu-item/menu-item.component.tsx
+++ b/src/components/menu/menu-item/menu-item.component.tsx
@@ -169,6 +169,7 @@ export const MenuItem = ({
     updateFocusId: updateSubmenuFocusId,
     handleKeyDown: handleSubmenuKeyDown,
     shiftTabPressed,
+    submenuHasMaxWidth,
   } = submenuContext;
   const ref = useRef<HTMLAnchorElement & HTMLButtonElement & HTMLDivElement>(
     null,
@@ -355,7 +356,7 @@ export const MenuItem = ({
         {...elementProps}
         menuItemVariant={variant}
         ariaLabel={ariaLabel}
-        maxWidth={maxWidth}
+        maxWidth={!submenuHasMaxWidth ? itemMaxWidth : undefined}
         inFullscreenView={inFullscreenView}
         asPassiveItem={asPassiveItem}
         placeholderTabIndex={asPassiveItem}
diff --git a/src/components/menu/menu.mdx b/src/components/menu/menu.mdx
index fe65f4990..9c01ef5fc 100644
--- a/src/components/menu/menu.mdx
+++ b/src/components/menu/menu.mdx
@@ -86,7 +86,7 @@ import {
 The example below has set the `showDropdownArrow` to false for the MenuItem with a submenu which means no dropdown arrow
 is rendered.
 
-<Canvas of={MenuStories.NoDropdwonArrowOnSubmenuStory} />
+<Canvas of={MenuStories.NoDropdownArrowOnSubmenuStory} />
 
 ### Split submenu into separate component
 
@@ -112,11 +112,11 @@ Note that only one `ScrollableBlock` can be used within a single submenu.
 This is an example of using the `parent` prop of `ScrollableBlock` to render a scrollable sublist of a parent item. The `parentVariant`
 prop can be used to give it a variant that's different from that used in the `ScrollableBlock`.
 
-Note that the result shown here, for those interacting with the page without assisistive technology, is the same as that which
+Note that the result shown here, for those interacting with the page without assistive technology, is the same as that which
 would be produced by leaving out the `parent` prop and putting the `Search` component inside a separate `MenuItem` just before the
 `ScrollableBlock`. However the rendered HTML would be different, with the `ScrollableBlock` becoming a sublist inside its own list
 item that is not connected to the Search - in this example there is a clear semantic relationship between the search input and the
-scrollable list so the `parent` prop should be used to ensure screenreaders make the relationship clear to their users.
+scrollable list so the `parent` prop should be used to ensure screen readers make the relationship clear to their users.
 
 <Canvas of={MenuStories.ScrollableSubmenuWithParent} />
 
diff --git a/src/components/menu/menu.stories.tsx b/src/components/menu/menu.stories.tsx
index fda8bbeb7..17be8f2bf 100644
--- a/src/components/menu/menu.stories.tsx
+++ b/src/components/menu/menu.stories.tsx
@@ -330,7 +330,7 @@ export const WithIconStory: Story = () => {
 WithIconStory.storyName = "With Icon";
 WithIconStory.parameters = { chromatic: { disableSnapshot: true } };
 
-export const NoDropdwonArrowOnSubmenuStory: Story = () => {
+export const NoDropdownArrowOnSubmenuStory: Story = () => {
   return (
     <Box minHeight="150px">
       <Menu>
@@ -344,8 +344,8 @@ export const NoDropdwonArrowOnSubmenuStory: Story = () => {
     </Box>
   );
 };
-NoDropdwonArrowOnSubmenuStory.storyName = "No Dropdwon Arrow on Submenu";
-NoDropdwonArrowOnSubmenuStory.parameters = {
+NoDropdownArrowOnSubmenuStory.storyName = "No Dropdown Arrow on Submenu";
+NoDropdownArrowOnSubmenuStory.parameters = {
   chromatic: { disableSnapshot: true },
 };
 
@@ -395,7 +395,7 @@ export const SubmenuIconAndTextAlignment: Story = () => {
     </Box>
   );
 };
-SubmenuIconAndTextAlignment.storyName = "Submeu Icon and Text Alignment";
+SubmenuIconAndTextAlignment.storyName = "Submenu Icon and Text Alignment";
 SubmenuIconAndTextAlignment.parameters = {
   chromatic: { disableSnapshot: true },
 };


Test patch:
diff --git a/src/components/menu/__internal__/submenu/submenu.test.tsx b/src/components/menu/__internal__/submenu/submenu.test.tsx
index 3aee0ef73..b9beced2b 100644
--- a/src/components/menu/__internal__/submenu/submenu.test.tsx
+++ b/src/components/menu/__internal__/submenu/submenu.test.tsx
@@ -489,3 +489,23 @@ test("should render the menu with a max-height set when the `maxHeight` prop is
     maxHeight: "80px",
   });
 });
+
+test("should override submenu children's `maxWidth` if `submenuMaxWidth` is set", async () => {
+  const user = userEvent.setup();
+  render(
+    <MenuContext.Provider value={menuContextValues}>
+      <Submenu title="title" submenuMaxWidth="300px">
+        <MenuItem maxWidth="400px">Apple</MenuItem>
+        <MenuItem minWidth="400px">Banana</MenuItem>
+      </Submenu>
+    </MenuContext.Provider>,
+  );
+  const menuItem = screen.getByRole("button", { name: "title" });
+  await user.hover(menuItem);
+  const submenu = screen.getByRole("list");
+  const submenuChildren = screen.getAllByRole("listitem");
+
+  expect(submenu).toHaveStyle({ maxWidth: "300px" });
+  expect(submenuChildren[0]).toHaveStyle({ maxWidth: "300px" });
+  expect(submenuChildren[1]).toHaveStyle({ maxWidth: "300px" });
+});
diff --git a/src/components/menu/menu-test.stories.tsx b/src/components/menu/menu-test.stories.tsx
index b11033cee..5ddc5ff9d 100644
--- a/src/components/menu/menu-test.stories.tsx
+++ b/src/components/menu/menu-test.stories.tsx
@@ -267,6 +267,12 @@ export const LongLabelsStory = () => {
         <MenuItem>Child B</MenuItem>
         <MenuItem>Child C</MenuItem>
       </MenuItem>
+      <MenuItem submenu="Parent Menu C with overflow" submenuMaxWidth="300px">
+        <MenuItem minWidth="max-content">
+          Child with a very long label that should wrap onto the next line and
+          not get cut off
+        </MenuItem>
+      </MenuItem>
     </Menu>
   );
 };