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,
+64 -56
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,
onLongPress,
onPressIn,
onPressOut,
onHoverIn,
onHoverOut,
onFocus: _onFocus,
...rest
},
ref,
) {
const onNormalizedPress = (event: PressableEvent) => {
if (!onPress) return
onPress(pressableEventToGestureResponderEvent(event))
}
const onNormalizedLongPress = (event: PressableEvent) => { measure = (_: MeasureOnSuccessCallback) => {}
if (!onLongPress) return
onLongPress(pressableEventToGestureResponderEvent(event))
}
const onNormalizedPressIn = (event: PressableEvent) => { measureLayout = (_: number) => {}
if (!onPressIn) return
onPressIn(pressableEventToGestureResponderEvent(event))
}
const onNormalizedPressOut = (event: PressableEvent) => { measureInWindow = (
if (!onPressOut) return _: (x: number, y: number, width: number, height: number) => void,
onPressOut(pressableEventToGestureResponderEvent(event)) ) => {}
}
const onNormalizedHoverIn = (event: PressableEvent) => { setNativeProps = (_: PressableProps) => {}
if (!onHoverIn) return
onHoverIn(pressableEventToMouseEvent(event))
}
const onNormalizedHoverOut = (event: PressableEvent) => { focus = () => {}
if (!onHoverOut) return
onHoverOut(pressableEventToMouseEvent(event))
}
blur = () => {}
onPress = (event: PressableEvent) => {
if (!this.props.onPress) return
this.props.onPress(pressableEventToGestureResponderEvent(event, this))
}
onLongPress = (event: PressableEvent) => {
if (!this.props.onLongPress) return
this.props.onLongPress(pressableEventToGestureResponderEvent(event, this))
}
onPressIn = (event: PressableEvent) => {
if (!this.props.onPressIn) return
this.props.onPressIn(pressableEventToGestureResponderEvent(event, this))
}
onPressOut = (event: PressableEvent) => {
if (!this.props.onPressOut) return
this.props.onPressOut(pressableEventToGestureResponderEvent(event, this))
}
onHoverIn = (event: PressableEvent) => {
if (!this.props.onHoverIn) return
this.props.onHoverIn(pressableEventToMouseEvent(event, this))
}
onHoverOut = (event: PressableEvent) => {
if (!this.props.onHoverOut) return
this.props.onHoverOut(pressableEventToMouseEvent(event, this))
}
render() {
return ( return (
<View ref={ref}> <BSPressable
<BSPressable {...this.props}
onPress={onNormalizedPress} onPress={this.onPress}
onLongPress={onNormalizedLongPress} onLongPress={this.onLongPress}
onPressIn={onNormalizedPressIn} onPressIn={this.onPressIn}
onPressOut={onNormalizedPressOut} onPressOut={this.onPressOut}
onHoverIn={onNormalizedHoverIn} onHoverIn={this.onHoverIn}
onHoverOut={onNormalizedHoverOut} onHoverOut={this.onHoverOut}
{...rest} />
/>
</View>
) )
}, }
) }