This commit is contained in:
Hailey
2024-10-02 11:45:58 -07:00
parent 839d6dc5ce
commit 1d5a3efe34
2 changed files with 78 additions and 57 deletions
+14 -1
View File
@@ -15,7 +15,9 @@ import {
import {LinearGradient} from 'expo-linear-gradient' import {LinearGradient} from 'expo-linear-gradient'
import {atoms as a, flatten, select, tokens, useTheme, web} from '#/alf' import {atoms as a, flatten, select, tokens, useTheme, web} from '#/alf'
import {useDialogContext} from '#/components/Dialog'
import {Props as SVGIconProps} from '#/components/icons/common' import {Props as SVGIconProps} from '#/components/icons/common'
import {NormalizedRNGHPressable} from '#/components/NormalizedRNGHPressable'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
export type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'gradient' export type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'gradient'
@@ -115,11 +117,22 @@ export const Button = React.forwardRef<View, ButtonProps>(
disabled = false, disabled = false,
style, style,
hoverStyle: hoverStyleProp, hoverStyle: hoverStyleProp,
Component = Pressable, Component,
...rest ...rest
}, },
ref, ref,
) => { ) => {
// This will pick the correct default pressable to use. If we are inside a dialog, we need to use the RNGH
// pressable so that it is usable inside the dialog.
const dialogContext = useDialogContext()
if (!Component) {
if (dialogContext) {
Component = NormalizedRNGHPressable
} else {
Component = Pressable
}
}
const t = useTheme() const t = useTheme()
const [state, setState] = React.useState({ const [state, setState] = React.useState({
pressed: false, pressed: false,
+56 -48
View File
@@ -1,16 +1,17 @@
import React from 'react' import React from 'react'
import { import {
GestureResponderEvent, GestureResponderEvent,
MeasureOnSuccessCallback,
NativeMouseEvent, NativeMouseEvent,
NativeSyntheticEvent, NativeSyntheticEvent,
PressableProps, PressableProps,
View,
} from 'react-native' } from 'react-native'
import {Pressable as BSPressable} from 'react-native-gesture-handler' import {Pressable as BSPressable} from 'react-native-gesture-handler'
import {PressableEvent} from 'react-native-gesture-handler/lib/typescript/components/Pressable/PressableProps' import {PressableEvent} from 'react-native-gesture-handler/lib/typescript/components/Pressable/PressableProps'
function pressableEventToGestureResponderEvent( function pressableEventToGestureResponderEvent(
event: PressableEvent, event: PressableEvent,
target: NormalizedRNGHPressable,
): GestureResponderEvent { ): GestureResponderEvent {
return { return {
nativeEvent: { nativeEvent: {
@@ -20,8 +21,10 @@ function pressableEventToGestureResponderEvent(
identifier: event.nativeEvent.identifier.toString(), identifier: event.nativeEvent.identifier.toString(),
target: event.nativeEvent.target.toString(), target: event.nativeEvent.target.toString(),
}, },
target: null, // @ts-expect-error
currentTarget: null, target: target,
// @ts-expect-error
currentTarget: target,
preventDefault() {}, preventDefault() {},
stopPropagation() {}, stopPropagation() {},
cancelable: false, cancelable: false,
@@ -43,11 +46,14 @@ function pressableEventToGestureResponderEvent(
function pressableEventToMouseEvent( function pressableEventToMouseEvent(
event: PressableEvent, event: PressableEvent,
target: NormalizedRNGHPressable,
): MouseEvent & NativeSyntheticEvent<NativeMouseEvent> { ): MouseEvent & NativeSyntheticEvent<NativeMouseEvent> {
return { return {
...event.nativeEvent, ...event.nativeEvent,
target: null, // @ts-expect-error
currentTarget: null, target: target,
// @ts-expect-error
currentTarget: target,
preventDefault() {}, preventDefault() {},
stopPropagation() {}, stopPropagation() {},
cancelable: false, cancelable: false,
@@ -59,62 +65,64 @@ function pressableEventToMouseEvent(
} }
} }
export const NormalizedRNGHPressable = React.forwardRef<View, PressableProps>( export class NormalizedRNGHPressable extends React.Component<PressableProps> {
function NormalizedPressable( static displayName = 'Pressable'
{
onPress, measure = (_: MeasureOnSuccessCallback) => {}
onLongPress,
onPressIn, measureLayout = (_: number) => {}
onPressOut,
onHoverIn, measureInWindow = (
onHoverOut, _: (x: number, y: number, width: number, height: number) => void,
onFocus: _onFocus, ) => {}
...rest
}, setNativeProps = (_: PressableProps) => {}
ref,
) { focus = () => {}
const onNormalizedPress = (event: PressableEvent) => {
if (!onPress) return blur = () => {}
onPress(pressableEventToGestureResponderEvent(event))
onPress = (event: PressableEvent) => {
if (!this.props.onPress) return
this.props.onPress(pressableEventToGestureResponderEvent(event, this))
} }
const onNormalizedLongPress = (event: PressableEvent) => { onLongPress = (event: PressableEvent) => {
if (!onLongPress) return if (!this.props.onLongPress) return
onLongPress(pressableEventToGestureResponderEvent(event)) this.props.onLongPress(pressableEventToGestureResponderEvent(event, this))
} }
const onNormalizedPressIn = (event: PressableEvent) => { onPressIn = (event: PressableEvent) => {
if (!onPressIn) return if (!this.props.onPressIn) return
onPressIn(pressableEventToGestureResponderEvent(event)) this.props.onPressIn(pressableEventToGestureResponderEvent(event, this))
} }
const onNormalizedPressOut = (event: PressableEvent) => { onPressOut = (event: PressableEvent) => {
if (!onPressOut) return if (!this.props.onPressOut) return
onPressOut(pressableEventToGestureResponderEvent(event)) this.props.onPressOut(pressableEventToGestureResponderEvent(event, this))
} }
const onNormalizedHoverIn = (event: PressableEvent) => { onHoverIn = (event: PressableEvent) => {
if (!onHoverIn) return if (!this.props.onHoverIn) return
onHoverIn(pressableEventToMouseEvent(event)) this.props.onHoverIn(pressableEventToMouseEvent(event, this))
} }
const onNormalizedHoverOut = (event: PressableEvent) => { onHoverOut = (event: PressableEvent) => {
if (!onHoverOut) return if (!this.props.onHoverOut) return
onHoverOut(pressableEventToMouseEvent(event)) this.props.onHoverOut(pressableEventToMouseEvent(event, this))
} }
render() {
return ( return (
<View ref={ref}>
<BSPressable <BSPressable
onPress={onNormalizedPress} {...this.props}
onLongPress={onNormalizedLongPress} onPress={this.onPress}
onPressIn={onNormalizedPressIn} onLongPress={this.onLongPress}
onPressOut={onNormalizedPressOut} onPressIn={this.onPressIn}
onHoverIn={onNormalizedHoverIn} onPressOut={this.onPressOut}
onHoverOut={onNormalizedHoverOut} onHoverIn={this.onHoverIn}
{...rest} onHoverOut={this.onHoverOut}
/> />
</View>
) )
}, }
) }