فهرست منبع

Avoid closing nested menu on click (#30479)

GitOrigin-RevId: 0f966b53ee5bfd8b4bacdf7b259f3e8cab2858c8
Alf Eaton 7 ماه پیش
والد
کامیت
5badb39259

+ 16 - 13
services/web/frontend/js/shared/components/menu-bar/menu-bar-dropdown.tsx

@@ -39,13 +39,9 @@ export const MenuBarDropdown: FC<
     })
   }, [id, setSelected])
 
+  const active = selected === id
   return (
-    <Dropdown
-      show={selected === id}
-      align={align}
-      onToggle={onToggle}
-      autoClose
-    >
+    <Dropdown show={active} align={align} onToggle={onToggle} autoClose>
       <DropdownToggle
         id={`${menuId}-${id}`}
         variant="secondary"
@@ -54,9 +50,11 @@ export const MenuBarDropdown: FC<
       >
         {title}
       </DropdownToggle>
-      <NestableDropdownMenu renderOnMount id={`${menuId}-${id}`}>
-        {children}
-      </NestableDropdownMenu>
+      {active && (
+        <NestableDropdownMenu renderOnMount id={`${menuId}-${id}`}>
+          {children}
+        </NestableDropdownMenu>
+      )}
     </Dropdown>
   )
 }
@@ -109,7 +107,10 @@ export const NestedMenuBarDropdown: FC<
   }, [id, setSelected])
   const onToggle = useCallback(
     (show: boolean) => {
-      setSelected(show ? id : null)
+      // Only handle opening
+      if (show) {
+        setSelected(id)
+      }
     },
     [setSelected, id]
   )
@@ -130,9 +131,11 @@ export const NestedMenuBarDropdown: FC<
       >
         {title}
       </DropdownToggle>
-      <NestableDropdownMenu renderOnMount id={`${menuId}-${id}`}>
-        {children}
-      </NestableDropdownMenu>
+      {active && (
+        <NestableDropdownMenu renderOnMount id={`${menuId}-${id}`}>
+          {children}
+        </NestableDropdownMenu>
+      )}
     </Dropdown>
   )
 }

+ 16 - 1
services/web/frontend/js/shared/context/nestable-dropdown-context.tsx

@@ -1,4 +1,11 @@
-import { createContext, Dispatch, FC, SetStateAction, useState } from 'react'
+import {
+  createContext,
+  Dispatch,
+  FC,
+  SetStateAction,
+  useEffect,
+  useState,
+} from 'react'
 
 export type NestableDropdownContextType = {
   selected: string | null
@@ -14,6 +21,14 @@ export const NestableDropdownContextProvider: FC<
   React.PropsWithChildren<{ id: string }>
 > = ({ id, children }) => {
   const [selected, setSelected] = useState<string | null>(null)
+
+  useEffect(() => {
+    return () => {
+      // unset selection on unmount
+      setSelected(null)
+    }
+  }, [])
+
   return (
     <NestableDropdownContext.Provider
       value={{ selected, setSelected, menuId: id }}

+ 7 - 3
services/web/frontend/stylesheets/components/dropdown-menu.scss

@@ -120,8 +120,12 @@ $dropdown-item-min-height: 36px;
     color: var(--dropdown-text-color);
   }
 
+  &:focus {
+    background: none;
+  }
+
   &:hover:not(.active),
-  &:focus:not(.active),
+  &:focus-visible:not(.active),
   &.nested-dropdown-toggle-shown {
     color: var(--dropdown-text-hover);
     background-color: var(--dropdown-background-hover);
@@ -133,7 +137,7 @@ $dropdown-item-min-height: 36px;
     color: var(--dropdown-text-danger);
 
     &:hover:not(.active),
-    &:focus:not(.active) {
+    &:focus-visible:not(.active) {
       color: var(--dropdown-text-danger-hover);
       background-color: var(--dropdown-background-danger-hover);
     }
@@ -148,7 +152,7 @@ $dropdown-item-min-height: 36px;
     text-decoration: none;
 
     &:hover,
-    &:focus {
+    &:focus-visible {
       color: inherit;
     }
   }