From f3d134557b6e30e2a2e6090f5b2f4ac9333f2df1 Mon Sep 17 00:00:00 2001 From: YuChuHB Date: Mon, 1 Dec 2025 17:31:09 +0800 Subject: [PATCH 1/3] Support Orientation property in Menubar --- .../stories/menubar.stories.module.css | 5 ++ apps/storybook/stories/menubar.stories.tsx | 46 +++++++++++++++---- packages/react/menubar/src/menubar.tsx | 13 ++++-- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/apps/storybook/stories/menubar.stories.module.css b/apps/storybook/stories/menubar.stories.module.css index a4dc616ea2..cf485e5334 100644 --- a/apps/storybook/stories/menubar.stories.module.css +++ b/apps/storybook/stories/menubar.stories.module.css @@ -4,6 +4,11 @@ padding: 2px; } +.rootVertical { + display: flex; + flex-direction: column; +} + .trigger { padding: 6px 16px; border: 0; diff --git a/apps/storybook/stories/menubar.stories.tsx b/apps/storybook/stories/menubar.stories.tsx index f68667e28b..7901c6d0a1 100644 --- a/apps/storybook/stories/menubar.stories.tsx +++ b/apps/storybook/stories/menubar.stories.tsx @@ -10,7 +10,10 @@ export default { title: 'Components/Menubar' }; export const Styled = () => { const [loop, setLoop] = React.useState(false); const [rtl, setRtl] = React.useState(false); + const [vertical, setVertical] = React.useState(false); const dir = rtl ? 'rtl' : 'ltr'; + const orientation = vertical ? 'vertical' : 'horizontal'; + const menubarContentSide = vertical ? 'right' : 'bottom'; const checkOptions = [ 'Always Show Bookmarks Bar', 'Always Show Toolbar in Fullscreen', @@ -49,14 +52,24 @@ export const Styled = () => { /> Loop + +
- + File - + New Tab New Window New Incognito Window @@ -82,7 +95,7 @@ export const Styled = () => { Edit - + Undo Redo @@ -124,7 +137,7 @@ export const Styled = () => { View - + {checkOptions.map((option) => ( { Profiles - + {radioOptions.map((option) => ( @@ -176,7 +189,7 @@ export const Styled = () => { History - + Work Radix Github @@ -197,7 +210,10 @@ export const Styled = () => { export const Cypress = () => { const [loop, setLoop] = React.useState(false); const [rtl, setRtl] = React.useState(false); + const [vertical, setVertical] = React.useState(false); const [portalled, setPortalled] = React.useState(false); + const orientation = vertical ? 'vertical' : 'horizontal'; + const menubarContentSide = vertical ? 'right' : 'bottom'; const dir = rtl ? 'rtl' : 'ltr'; const Portal = portalled ? Menubar.Portal : React.Fragment; @@ -231,6 +247,15 @@ export const Cypress = () => { Loop + +
- + File - + New Tab New Window New Incognito Window @@ -269,7 +295,7 @@ export const Cypress = () => { Edit - + Undo @@ -336,7 +362,7 @@ export const Cypress = () => { History - + Radix Github WorkOS diff --git a/packages/react/menubar/src/menubar.tsx b/packages/react/menubar/src/menubar.tsx index 483405eeed..4225934825 100644 --- a/packages/react/menubar/src/menubar.tsx +++ b/packages/react/menubar/src/menubar.tsx @@ -14,6 +14,7 @@ import { useControllableState } from '@radix-ui/react-use-controllable-state'; import type { Scope } from '@radix-ui/react-context'; +type Orientation = 'vertical' | 'horizontal'; type Direction = 'ltr' | 'rtl'; /* ------------------------------------------------------------------------------------------------- @@ -41,6 +42,7 @@ type MenubarContextValue = { value: string; dir: Direction; loop: boolean; + orientation: Orientation; onMenuOpen(value: string): void; onMenuClose(): void; onMenuToggle(value: string): void; @@ -57,6 +59,7 @@ interface MenubarProps extends PrimitiveDivProps { defaultValue?: string; onValueChange?: (value: string) => void; loop?: RovingFocusGroupProps['loop']; + orientation?: Orientation; dir?: RovingFocusGroupProps['dir']; } @@ -68,6 +71,7 @@ const Menubar = React.forwardRef( onValueChange, defaultValue, loop = true, + orientation = 'horizontal', dir, ...menubarProps } = props; @@ -108,13 +112,14 @@ const Menubar = React.forwardRef( )} dir={direction} loop={loop} + orientation={orientation} > { if (disabled) return; if (['Enter', ' '].includes(event.key)) context.onMenuToggle(menuContext.value); - if (event.key === 'ArrowDown') context.onMenuOpen(menuContext.value); + if (event.key === (context.orientation === 'vertical' ? 'ArrowRight' : 'ArrowDown')) context.onMenuOpen(menuContext.value); // prevent keydown from scrolling window / first focused item to execute // that keydown (inadvertently closing the menu) - if (['Enter', ' ', 'ArrowDown'].includes(event.key)) { + if (['Enter', ' ', context.orientation === 'vertical' ? 'ArrowRight' : 'ArrowDown'].includes(event.key)) { menuContext.wasKeyboardTriggerOpenRef.current = true; event.preventDefault(); } @@ -349,7 +354,7 @@ const MenubarContent = React.forwardRef { - if (['ArrowRight', 'ArrowLeft'].includes(event.key)) { + if (context.orientation !== 'vertical' && ['ArrowRight', 'ArrowLeft'].includes(event.key)) { const target = event.target as HTMLElement; const targetIsSubTrigger = target.hasAttribute('data-radix-menubar-subtrigger'); const isKeyDownInsideSubMenu = From 075715e40a6e730ccada26c11849023e265369ab Mon Sep 17 00:00:00 2001 From: YuChuHB Date: Mon, 1 Dec 2025 17:36:56 +0800 Subject: [PATCH 2/3] Add comments for prevent navigation --- packages/react/menubar/src/menubar.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react/menubar/src/menubar.tsx b/packages/react/menubar/src/menubar.tsx index 4225934825..6b0ece171a 100644 --- a/packages/react/menubar/src/menubar.tsx +++ b/packages/react/menubar/src/menubar.tsx @@ -354,6 +354,7 @@ const MenubarContent = React.forwardRef { + // Prevent navigation when orientation is vertical and menubar content is triggered. if (context.orientation !== 'vertical' && ['ArrowRight', 'ArrowLeft'].includes(event.key)) { const target = event.target as HTMLElement; const targetIsSubTrigger = target.hasAttribute('data-radix-menubar-subtrigger'); From fc0118aa9521b91f683c9d7c38217beaf7b0009b Mon Sep 17 00:00:00 2001 From: YuChuHB Date: Mon, 1 Dec 2025 17:46:52 +0800 Subject: [PATCH 3/3] bump version and add change log --- packages/react/menubar/CHANGELOG.md | 4 ++++ packages/react/menubar/package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/react/menubar/CHANGELOG.md b/packages/react/menubar/CHANGELOG.md index da0e6fa856..ccb15e8b65 100644 --- a/packages/react/menubar/CHANGELOG.md +++ b/packages/react/menubar/CHANGELOG.md @@ -1,5 +1,9 @@ # @radix-ui/react-menubar +## 1.1.17 + +- Support new property `orientation (vertical | horizontal)` in `Menubar.Root` + ## 1.1.16 - Updated dependencies: `@radix-ui/primitive@1.1.3`, `@radix-ui/react-context@1.1.3`, `@radix-ui/react-menu@2.1.16`, `@radix-ui/react-collection@1.1.8`, `@radix-ui/react-primitive@2.1.4`, `@radix-ui/react-roving-focus@1.1.11` diff --git a/packages/react/menubar/package.json b/packages/react/menubar/package.json index 7d2996c4e5..c8d61184a7 100644 --- a/packages/react/menubar/package.json +++ b/packages/react/menubar/package.json @@ -1,6 +1,6 @@ { "name": "@radix-ui/react-menubar", - "version": "1.1.16", + "version": "1.1.17", "license": "MIT", "source": "./src/index.ts", "main": "./src/index.ts",