diff --git a/src/view/com/util/EventStopper.tsx b/src/view/com/util/EventStopper.tsx new file mode 100644 index 00000000..1e672e94 --- /dev/null +++ b/src/view/com/util/EventStopper.tsx @@ -0,0 +1,22 @@ +import React from 'react' +import {View} from 'react-native' + +/** + * This utility function captures events and stops + * them from propagating upwards. + */ +export function EventStopper({children}: React.PropsWithChildren<{}>) { + const stop = (e: any) => { + e.stopPropagation() + } + return ( + true} + onTouchEnd={stop} + // @ts-ignore web only -prf + onClick={stop} + onKeyDown={stop}> + {children} + + ) +} diff --git a/src/view/com/util/forms/NativeDropdown.tsx b/src/view/com/util/forms/NativeDropdown.tsx index d8f16ce1..9e6fcaa4 100644 --- a/src/view/com/util/forms/NativeDropdown.tsx +++ b/src/view/com/util/forms/NativeDropdown.tsx @@ -1,13 +1,7 @@ import React from 'react' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import * as DropdownMenu from 'zeego/dropdown-menu' -import { - Pressable, - StyleSheet, - Platform, - StyleProp, - ViewStyle, -} from 'react-native' +import {Pressable, StyleSheet, Platform, View} from 'react-native' import {IconProp} from '@fortawesome/fontawesome-svg-core' import {MenuItemCommonProps} from 'zeego/lib/typescript/menu' import {usePalette} from 'lib/hooks/usePalette' @@ -18,16 +12,71 @@ import {HITSLOP_10} from 'lib/constants' // Custom Dropdown Menu Components // == export const DropdownMenuRoot = DropdownMenu.Root -export const DropdownMenuTrigger = DropdownMenu.Trigger +// export const DropdownMenuTrigger = DropdownMenu.Trigger export const DropdownMenuContent = DropdownMenu.Content + +type TriggerProps = Omit< + React.ComponentProps<(typeof DropdownMenu)['Trigger']>, + 'children' +> & + React.PropsWithChildren<{ + testID?: string + accessibilityLabel?: string + accessibilityHint?: string + }> +export const DropdownMenuTrigger = DropdownMenu.create( + (props: TriggerProps) => { + const theme = useTheme() + const defaultCtrlColor = theme.palette.default.postCtrl + const ref = React.useRef(null) + + // HACK + // fire a click event on the keyboard press to trigger the dropdown + // -prf + const onPress = isWeb + ? (evt: any) => { + if (evt instanceof KeyboardEvent) { + // @ts-ignore web only -prf + ref.current?.click() + } + } + : undefined + + return ( + [{opacity: pressed ? 0.5 : 1}]} + hitSlop={HITSLOP_10} + onPress={onPress}> + + + {props.children ? ( + props.children + ) : ( + + )} + + + + ) + }, + 'Trigger', +) + type ItemProps = React.ComponentProps<(typeof DropdownMenu)['Item']> export const DropdownMenuItem = DropdownMenu.create( (props: ItemProps & {testID?: string}) => { - const pal = usePalette('default') const theme = useTheme() const [focused, setFocused] = React.useState(false) - const {borderColor: backgroundColor} = - theme.colorScheme === 'dark' ? pal.borderDark : pal.border + const backgroundColor = theme.colorScheme === 'dark' ? '#fff1' : '#0001' return ( export const DropdownMenuItemTitle = DropdownMenu.create( (props: TitleProps) => { @@ -59,10 +109,12 @@ export const DropdownMenuItemTitle = DropdownMenu.create( }, 'ItemTitle', ) + type IconProps = React.ComponentProps<(typeof DropdownMenu)['ItemIcon']> export const DropdownMenuItemIcon = DropdownMenu.create((props: IconProps) => { return }, 'ItemIcon') + type SeparatorProps = React.ComponentProps<(typeof DropdownMenu)['Separator']> export const DropdownMenuSeparator = DropdownMenu.create( (props: SeparatorProps) => { @@ -97,8 +149,9 @@ export type DropdownItem = { } type Props = { items: DropdownItem[] - children?: React.ReactNode testID?: string + accessibilityLabel?: string + accessibilityHint?: string } /* The `NativeDropdown` function uses native iOS and Android dropdown menus. @@ -107,36 +160,26 @@ type Props = { * @prop {DropdownItem[]} items - An array of dropdown items * @prop {React.ReactNode} children - A custom dropdown trigger */ -export function NativeDropdown({items, children, testID}: Props) { +export function NativeDropdown({ + items, + children, + testID, + accessibilityLabel, + accessibilityHint, +}: React.PropsWithChildren) { const pal = usePalette('default') const theme = useTheme() const dropDownBackgroundColor = theme.colorScheme === 'dark' ? pal.btn : pal.viewLight - const defaultCtrlColor = React.useMemo( - () => ({ - color: theme.palette.default.postCtrl, - }), - [theme], - ) as StyleProp return ( - - [{opacity: pressed ? 0.5 : 1}]} - hitSlop={HITSLOP_10}> - {children ? ( - children - ) : ( - - )} - + + {children} - - + + + ) }