about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Bailey <git@esb.lol>2024-03-12 19:25:58 -0500
committerGitHub <noreply@github.com>2024-03-12 19:25:58 -0500
commit202adb6d7b076e2837169bd7585ca76e78e86a1f (patch)
tree9e13d08f398161821e30451109b5ae5c4732a19a
parent5c771050bc3a807fb45abbf47af823e0ea69cf81 (diff)
downloadvoidsky-202adb6d7b076e2837169bd7585ca76e78e86a1f.tar.zst
Fix dropdown close via a portaled backdrop (#3191)
-rw-r--r--src/alf/atoms.ts3
-rw-r--r--src/components/Menu/index.web.tsx16
2 files changed, 18 insertions, 1 deletions
diff --git a/src/alf/atoms.ts b/src/alf/atoms.ts
index 6d73cd307..5088e3aac 100644
--- a/src/alf/atoms.ts
+++ b/src/alf/atoms.ts
@@ -1,3 +1,4 @@
+import {Platform} from 'react-native'
 import {web, native} from '#/alf/util/platform'
 import * as tokens from '#/alf/tokens'
 
@@ -6,7 +7,7 @@ export const atoms = {
    * Positioning
    */
   fixed: {
-    position: 'fixed',
+    position: Platform.select({web: 'fixed', native: 'absolute'}) as 'absolute',
   },
   absolute: {
     position: 'absolute',
diff --git a/src/components/Menu/index.web.tsx b/src/components/Menu/index.web.tsx
index 47193bce0..f4b03f680 100644
--- a/src/components/Menu/index.web.tsx
+++ b/src/components/Menu/index.web.tsx
@@ -3,6 +3,8 @@
 import React from 'react'
 import {View, Pressable, ViewStyle, StyleProp} from 'react-native'
 import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
+import {msg} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
 
 import * as Dialog from '#/components/Dialog'
 import {useInteractionState} from '#/components/hooks/useInteractionState'
@@ -19,6 +21,7 @@ import {
   RadixPassThroughTriggerProps,
 } from '#/components/Menu/types'
 import {Context} from '#/components/Menu/context'
+import {Portal} from '#/components/Portal'
 
 export function useMenuControl(): Dialog.DialogControlProps {
   const id = React.useId()
@@ -50,6 +53,7 @@ export function Root({
 }: React.PropsWithChildren<{
   control?: Dialog.DialogOuterProps['control']
 }>) {
+  const {_} = useLingui()
   const defaultControl = useMenuControl()
   const context = React.useMemo<ContextType>(
     () => ({
@@ -70,6 +74,18 @@ export function Root({
 
   return (
     <Context.Provider value={context}>
+      {context.control.isOpen && (
+        <Portal>
+          <Pressable
+            style={[a.fixed, a.inset_0, a.z_50]}
+            onPress={() => context.control.close()}
+            accessibilityHint=""
+            accessibilityLabel={_(
+              msg`Context menu backdrop, click to close the menu.`,
+            )}
+          />
+        </Portal>
+      )}
       <DropdownMenu.Root
         open={context.control.isOpen}
         onOpenChange={onOpenChange}>