- {
- switch (event.code) {
- case 'Escape':
- case 'Tab':
- event.preventDefault()
- closeMenu()
- break
- }
- }}
- >
- {menuItems.map((menuItem, index) => (
-
- {menuItem.separatorAbove && }
-
- menuItem.handler()}
- disabled={menuItem.disabled}
- trailingIcon={
- menuItem.shortcut ? (
- {menuItem.shortcut}
- ) : undefined
- }
- >
- {menuItem.label}
-
-
-
- ))}
-
-
+ event.preventDefault()}>
+ {
+ switch (event.code) {
+ case 'Escape':
+ case 'Tab':
+ event.preventDefault()
+ closeMenu()
+ break
+ }
+ }}
+ >
+ {menuItems.map((menuItem, index) => (
+
+ {menuItem.separatorAbove && }
+
+ menuItem.handler()}
+ disabled={menuItem.disabled}
+ trailingIcon={
+ menuItem.shortcut ? (
+ {menuItem.shortcut}
+ ) : undefined
+ }
+ >
+ {menuItem.label}
+
+
+
+ ))}
+
+
+
)
})
diff --git a/services/web/frontend/stylesheets/components/dropdown-menu.scss b/services/web/frontend/stylesheets/components/dropdown-menu.scss
index 725ddf7561..ef3da5c97c 100644
--- a/services/web/frontend/stylesheets/components/dropdown-menu.scss
+++ b/services/web/frontend/stylesheets/components/dropdown-menu.scss
@@ -133,6 +133,10 @@ $dropdown-item-min-height: 36px;
&:focus {
background: none;
+
+ // Bootstrap sets the hover text colour on plain :focus too; reset it so a
+ // mouse-focused (not :focus-visible), non-hovered item stays readable.
+ color: var(--dropdown-text-color);
}
&:focus-visible {
diff --git a/services/web/test/frontend/features/source-editor/components/codemirror-editor-context-menu.spec.tsx b/services/web/test/frontend/features/source-editor/components/codemirror-editor-context-menu.spec.tsx
index 372f1ac202..22ec6e1a99 100644
--- a/services/web/test/frontend/features/source-editor/components/codemirror-editor-context-menu.spec.tsx
+++ b/services/web/test/frontend/features/source-editor/components/codemirror-editor-context-menu.spec.tsx
@@ -1288,4 +1288,40 @@ describe('editor context menu', { scrollBehavior: false }, function () {
cy.findByRole('menu').should('not.exist')
})
})
+
+ describe('when right-clicking inside the open menu', function () {
+ it('should suppress the native menu and stay open', function () {
+ const scope = mockScope()
+
+ cy.mount(
+