Unwrap Menu.Trigger on web (#3182)
parent
17d921fd9d
commit
b8afb935f4
|
@ -1,3 +1,5 @@
|
|||
/* eslint-disable react/prop-types */
|
||||
|
||||
import React from 'react'
|
||||
import {View, Pressable} from 'react-native'
|
||||
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
||||
|
@ -14,6 +16,7 @@ import {
|
|||
GroupProps,
|
||||
ItemTextProps,
|
||||
ItemIconProps,
|
||||
RadixPassThroughTriggerProps,
|
||||
} from '#/components/Menu/types'
|
||||
import {Context} from '#/components/Menu/context'
|
||||
|
||||
|
@ -76,7 +79,24 @@ export function Root({
|
|||
)
|
||||
}
|
||||
|
||||
export function Trigger({children, label, style}: TriggerProps) {
|
||||
const RadixTriggerPassThrough = React.forwardRef(
|
||||
(
|
||||
props: {
|
||||
children: (
|
||||
props: RadixPassThroughTriggerProps & {
|
||||
ref: React.Ref<any>
|
||||
},
|
||||
) => React.ReactNode
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
// @ts-expect-error Radix provides no types of this stuff
|
||||
return props.children({...props, ref})
|
||||
},
|
||||
)
|
||||
RadixTriggerPassThrough.displayName = 'RadixTriggerPassThrough'
|
||||
|
||||
export function Trigger({children, label}: TriggerProps) {
|
||||
const {control} = React.useContext(Context)
|
||||
const {
|
||||
state: hovered,
|
||||
|
@ -87,28 +107,27 @@ export function Trigger({children, label, style}: TriggerProps) {
|
|||
|
||||
return (
|
||||
<DropdownMenu.Trigger asChild>
|
||||
<Pressable
|
||||
accessibilityHint=""
|
||||
accessibilityLabel={label}
|
||||
onFocus={onFocus}
|
||||
onBlur={onBlur}
|
||||
style={flatten([style, focused && web({outline: 0})])}
|
||||
onPointerDown={() => control.open()}
|
||||
{...web({
|
||||
onMouseEnter,
|
||||
onMouseLeave,
|
||||
})}>
|
||||
{children({
|
||||
isNative: false,
|
||||
control,
|
||||
state: {
|
||||
hovered,
|
||||
focused,
|
||||
pressed: false,
|
||||
},
|
||||
props: {},
|
||||
})}
|
||||
</Pressable>
|
||||
<RadixTriggerPassThrough>
|
||||
{props =>
|
||||
children({
|
||||
isNative: false,
|
||||
control,
|
||||
state: {
|
||||
hovered,
|
||||
focused,
|
||||
pressed: false,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
onFocus: onFocus,
|
||||
onBlur: onBlur,
|
||||
onMouseEnter,
|
||||
onMouseLeave,
|
||||
accessibilityLabel: label,
|
||||
},
|
||||
})
|
||||
}
|
||||
</RadixTriggerPassThrough>
|
||||
</DropdownMenu.Trigger>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
import React from 'react'
|
||||
import {GestureResponderEvent, PressableProps} from 'react-native'
|
||||
import {
|
||||
GestureResponderEvent,
|
||||
PressableProps,
|
||||
AccessibilityProps,
|
||||
} from 'react-native'
|
||||
|
||||
import {Props as SVGIconProps} from '#/components/icons/common'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
|
@ -9,7 +13,19 @@ export type ContextType = {
|
|||
control: Dialog.DialogOuterProps['control']
|
||||
}
|
||||
|
||||
export type TriggerProps = ViewStyleProp & {
|
||||
export type RadixPassThroughTriggerProps = {
|
||||
id: string
|
||||
type: 'button'
|
||||
disabled: boolean
|
||||
['data-disabled']: boolean
|
||||
['data-state']: string
|
||||
['aria-controls']?: string
|
||||
['aria-haspopup']?: boolean
|
||||
['aria-expanded']?: AccessibilityProps['aria-expanded']
|
||||
onKeyDown: (e: React.KeyboardEvent) => void
|
||||
onPointerDown: PressableProps['onPointerDown']
|
||||
}
|
||||
export type TriggerProps = {
|
||||
children(props: TriggerChildProps): React.ReactNode
|
||||
label: string
|
||||
}
|
||||
|
@ -52,7 +68,13 @@ export type TriggerChildProps =
|
|||
*/
|
||||
pressed: false
|
||||
}
|
||||
props: {}
|
||||
props: RadixPassThroughTriggerProps & {
|
||||
onFocus: () => void
|
||||
onBlur: () => void
|
||||
onMouseEnter: () => void
|
||||
onMouseLeave: () => void
|
||||
accessibilityLabel: string
|
||||
}
|
||||
}
|
||||
|
||||
export type ItemProps = React.PropsWithChildren<
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
import React, {memo} from 'react'
|
||||
import {
|
||||
StyleProp,
|
||||
ViewStyle,
|
||||
Pressable,
|
||||
View,
|
||||
PressableProps,
|
||||
} from 'react-native'
|
||||
import {StyleProp, ViewStyle, Pressable, PressableProps} from 'react-native'
|
||||
import Clipboard from '@react-native-clipboard/clipboard'
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||
import {useNavigation} from '@react-navigation/native'
|
||||
|
@ -38,7 +32,7 @@ import {isWeb} from '#/platform/detection'
|
|||
import {richTextToString} from '#/lib/strings/rich-text-helpers'
|
||||
import {useGlobalDialogsControlContext} from '#/components/dialogs/Context'
|
||||
|
||||
import {atoms as a, useTheme as useAlf, web} from '#/alf'
|
||||
import {atoms as a, useTheme as useAlf} from '#/alf'
|
||||
import * as Menu from '#/components/Menu'
|
||||
import {Clipboard_Stroke2_Corner2_Rounded as ClipboardIcon} from '#/components/icons/Clipboard'
|
||||
import {Filter_Stroke2_Corner0_Rounded as Filter} from '#/components/icons/Filter'
|
||||
|
@ -174,29 +168,18 @@ let PostDropdownBtn = ({
|
|||
<Menu.Root>
|
||||
<Menu.Trigger label={_(msg`Open post options menu`)}>
|
||||
{({props, state}) => {
|
||||
const styles = [
|
||||
style,
|
||||
a.rounded_full,
|
||||
(state.hovered || state.focused || state.pressed) && [
|
||||
web({outline: 0}),
|
||||
alf.atoms.bg_contrast_25,
|
||||
],
|
||||
]
|
||||
return isWeb ? (
|
||||
<View {...props} testID={testID} style={styles}>
|
||||
<FontAwesomeIcon
|
||||
icon="ellipsis"
|
||||
size={20}
|
||||
color={defaultCtrlColor}
|
||||
style={{pointerEvents: 'none'}}
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
return (
|
||||
<Pressable
|
||||
{...props}
|
||||
hitSlop={hitSlop}
|
||||
testID={testID}
|
||||
style={styles}>
|
||||
style={[
|
||||
style,
|
||||
a.rounded_full,
|
||||
(state.hovered || state.pressed) && [
|
||||
alf.atoms.bg_contrast_50,
|
||||
],
|
||||
]}>
|
||||
<FontAwesomeIcon
|
||||
icon="ellipsis"
|
||||
size={20}
|
||||
|
|
|
@ -16,7 +16,7 @@ export function Menus() {
|
|||
<View style={[a.gap_md]}>
|
||||
<View style={[a.flex_row, a.align_start]}>
|
||||
<Menu.Root control={menuControl}>
|
||||
<Menu.Trigger label="Open basic menu" style={[a.flex_1]}>
|
||||
<Menu.Trigger label="Open basic menu">
|
||||
{({state, props}) => {
|
||||
return (
|
||||
<Text
|
||||
|
|
Loading…
Reference in New Issue