about summary refs log tree commit diff
path: root/src/components/Menu
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/Menu')
-rw-r--r--src/components/Menu/index.tsx6
-rw-r--r--src/components/Menu/index.web.tsx22
-rw-r--r--src/components/Menu/types.ts5
3 files changed, 30 insertions, 3 deletions
diff --git a/src/components/Menu/index.tsx b/src/components/Menu/index.tsx
index 9be9dd86b..051e95b95 100644
--- a/src/components/Menu/index.tsx
+++ b/src/components/Menu/index.tsx
@@ -17,7 +17,7 @@ import {
   ItemIconProps,
 } from '#/components/Menu/types'
 import {Button, ButtonText} from '#/components/Button'
-import {msg} from '@lingui/macro'
+import {Trans, msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {isNative} from 'platform/detection'
 
@@ -209,7 +209,9 @@ function Cancel() {
       variant="ghost"
       color="secondary"
       onPress={() => control.close()}>
-      <ButtonText>Cancel</ButtonText>
+      <ButtonText>
+        <Trans>Cancel</Trans>
+      </ButtonText>
     </Button>
   )
 }
diff --git a/src/components/Menu/index.web.tsx b/src/components/Menu/index.web.tsx
index 2004ee7c6..60b234203 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}>
@@ -119,6 +135,10 @@ export function Trigger({children, label}: TriggerProps) {
             },
             props: {
               ...props,
+              // disable on web, use `onPress`
+              onPointerDown: () => false,
+              onPress: () =>
+                control.isOpen ? control.close() : control.open(),
               onFocus: onFocus,
               onBlur: onBlur,
               onMouseEnter,
@@ -203,7 +223,7 @@ export function Item({children, label, onPress, ...rest}: ItemProps) {
         style={flatten([
           a.flex_row,
           a.align_center,
-          a.gap_sm,
+          a.gap_lg,
           a.py_sm,
           a.rounded_xs,
           {minHeight: 32, paddingHorizontal: 10},
diff --git a/src/components/Menu/types.ts b/src/components/Menu/types.ts
index 7d04a3344..e710971ee 100644
--- a/src/components/Menu/types.ts
+++ b/src/components/Menu/types.ts
@@ -23,6 +23,10 @@ export type RadixPassThroughTriggerProps = {
   ['aria-haspopup']?: boolean
   ['aria-expanded']?: AccessibilityProps['aria-expanded']
   onKeyDown: (e: React.KeyboardEvent) => void
+  /**
+   * Radix provides this, but we override on web to use `onPress` instead,
+   * which is less sensitive while scrolling.
+   */
   onPointerDown: PressableProps['onPointerDown']
 }
 export type TriggerProps = {
@@ -69,6 +73,7 @@ export type TriggerChildProps =
         pressed: false
       }
       props: RadixPassThroughTriggerProps & {
+        onPress: () => void
         onFocus: () => void
         onBlur: () => void
         onMouseEnter: () => void