Fix dropdown close via a portaled backdrop (#3191)

zio/stable
Eric Bailey 2024-03-12 19:25:58 -05:00 committed by GitHub
parent 5c771050bc
commit 202adb6d7b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 18 additions and 1 deletions

View File

@ -1,3 +1,4 @@
import {Platform} from 'react-native'
import {web, native} from '#/alf/util/platform' import {web, native} from '#/alf/util/platform'
import * as tokens from '#/alf/tokens' import * as tokens from '#/alf/tokens'
@ -6,7 +7,7 @@ export const atoms = {
* Positioning * Positioning
*/ */
fixed: { fixed: {
position: 'fixed', position: Platform.select({web: 'fixed', native: 'absolute'}) as 'absolute',
}, },
absolute: { absolute: {
position: 'absolute', position: 'absolute',

View File

@ -3,6 +3,8 @@
import React from 'react' import React from 'react'
import {View, Pressable, ViewStyle, StyleProp} from 'react-native' import {View, Pressable, ViewStyle, StyleProp} from 'react-native'
import * as DropdownMenu from '@radix-ui/react-dropdown-menu' 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 * as Dialog from '#/components/Dialog'
import {useInteractionState} from '#/components/hooks/useInteractionState' import {useInteractionState} from '#/components/hooks/useInteractionState'
@ -19,6 +21,7 @@ import {
RadixPassThroughTriggerProps, RadixPassThroughTriggerProps,
} from '#/components/Menu/types' } from '#/components/Menu/types'
import {Context} from '#/components/Menu/context' import {Context} from '#/components/Menu/context'
import {Portal} from '#/components/Portal'
export function useMenuControl(): Dialog.DialogControlProps { export function useMenuControl(): Dialog.DialogControlProps {
const id = React.useId() const id = React.useId()
@ -50,6 +53,7 @@ export function Root({
}: React.PropsWithChildren<{ }: React.PropsWithChildren<{
control?: Dialog.DialogOuterProps['control'] control?: Dialog.DialogOuterProps['control']
}>) { }>) {
const {_} = useLingui()
const defaultControl = useMenuControl() const defaultControl = useMenuControl()
const context = React.useMemo<ContextType>( const context = React.useMemo<ContextType>(
() => ({ () => ({
@ -70,6 +74,18 @@ export function Root({
return ( return (
<Context.Provider value={context}> <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 <DropdownMenu.Root
open={context.control.isOpen} open={context.control.isOpen}
onOpenChange={onOpenChange}> onOpenChange={onOpenChange}>