Add dismiss backdrop to native dropdowns (#4711)

zio/stable
dan 2024-07-01 18:45:15 +01:00 committed by GitHub
parent 1a037d3542
commit a9fe87b842
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 100 additions and 67 deletions

View File

@ -1,13 +1,15 @@
import React from 'react'
import {Platform, Pressable, StyleSheet, View, ViewStyle} from 'react-native'
import {IconProp} from '@fortawesome/fontawesome-svg-core'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import * as DropdownMenu from 'zeego/dropdown-menu'
import {Pressable, StyleSheet, Platform, View, ViewStyle} from 'react-native'
import {IconProp} from '@fortawesome/fontawesome-svg-core'
import {MenuItemCommonProps} from 'zeego/lib/typescript/menu'
import {usePalette} from 'lib/hooks/usePalette'
import {isWeb} from 'platform/detection'
import {useTheme} from 'lib/ThemeContext'
import {HITSLOP_10} from 'lib/constants'
import {usePalette} from 'lib/hooks/usePalette'
import {useTheme} from 'lib/ThemeContext'
import {isIOS, isWeb} from 'platform/detection'
import {Portal} from '#/components/Portal'
// Custom Dropdown Menu Components
// ==
@ -169,11 +171,18 @@ export function NativeDropdown({
}: React.PropsWithChildren<Props>) {
const pal = usePalette('default')
const theme = useTheme()
const [isOpen, setIsOpen] = React.useState(false)
const dropDownBackgroundColor =
theme.colorScheme === 'dark' ? pal.btn : pal.viewLight
return (
<DropdownMenuRoot>
<>
{isIOS && isOpen && (
<Portal>
<Backdrop />
</Portal>
)}
<DropdownMenuRoot onOpenWillChange={setIsOpen}>
<DropdownMenuTrigger
action="press"
testID={testID}
@ -194,7 +203,8 @@ export function NativeDropdown({
}
if (index > 1 && items[index - 1].label === 'separator') {
return (
<DropdownMenu.Group key={getKey(item.label, index, item.testID)}>
<DropdownMenu.Group
key={getKey(item.label, index, item.testID)}>
<DropdownMenuItem
key={getKey(item.label, index, item.testID)}
onSelect={item.onPress}>
@ -237,6 +247,29 @@ export function NativeDropdown({
})}
</DropdownMenuContent>
</DropdownMenuRoot>
</>
)
}
function Backdrop() {
// Not visible but it eats the click outside.
// Only necessary for iOS.
return (
<Pressable
accessibilityRole="button"
accessibilityLabel="Dialog backdrop"
accessibilityHint="Press the backdrop to close the dialog"
style={{
top: 0,
left: 0,
right: 0,
bottom: 0,
position: 'absolute',
}}
onPress={() => {
/* noop */
}}
/>
)
}