diff --git a/src/components/BottomSheetButton.tsx b/src/components/BottomSheetButton.tsx index a2efa2c49b..38fdf598ba 100644 --- a/src/components/BottomSheetButton.tsx +++ b/src/components/BottomSheetButton.tsx @@ -1,110 +1,12 @@ import React from 'react' -import {AccessibilityProps, ViewStyle} from 'react-native' -import {PressableEvent} from 'react-native-gesture-handler/lib/typescript/components/Pressable/PressableProps' -import { - BlueskyBottomSheetPressable, - BlueskyBottomSheetPressableProps, -} from '@haileyok/bluesky-bottom-sheet' -import {atoms as a} from '#/alf' -import { - ButtonContext, - useSharedButtonStyles, - VariantProps, -} from '#/components/Button' - -export function BottomSheetButton({ - children, - label, - color, - variant, - shape = 'default', - size, - disabled, - style, - ...rest -}: BlueskyBottomSheetPressableProps & - AccessibilityProps & - VariantProps & { - /** - * For a11y, try to make this descriptive and clear - */ - label: string - }) { - const [state, setState] = React.useState({ - pressed: false, - hovered: false, - focused: false, - }) - - const onPressInOuter = rest.onPressIn - const onPressIn = React.useCallback( - (e: PressableEvent) => { - setState(s => ({ - ...s, - pressed: true, - })) - onPressInOuter?.(e) - }, - [setState, onPressInOuter], - ) - const onPressOutOuter = rest.onPressOut - const onPressOut = React.useCallback( - (e: PressableEvent) => { - setState(s => ({ - ...s, - pressed: false, - })) - onPressOutOuter?.(e) - }, - [setState, onPressOutOuter], - ) - - const {baseStyles, hoverStyles} = useSharedButtonStyles({ - /** - * For a11y, try to make this descriptive and clear - */ - color, - variant, - shape, - size, - disabled, - }) - - const context = React.useMemo( - () => ({ - ...state, - variant, - color, - size, - disabled: disabled || false, - }), - [state, variant, color, size, disabled], - ) +import {Button, ButtonProps} from '#/components/Button' +import {NormalizedPressable} from '#/components/NormalizedPressable' +export function BottomSheetButton({children, ...rest}: ButtonProps) { return ( - - - {typeof children === 'function' ? children(context) : children} - - + ) } diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 17db0332e0..ae03323cff 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -87,6 +87,7 @@ export type ButtonProps = Pick< style?: StyleProp hoverStyle?: StyleProp children: NonTextElements | ((context: ButtonContext) => NonTextElements) + Component?: React.ComponentType } export type ButtonTextProps = TextProps & @@ -116,6 +117,7 @@ export const Button = React.forwardRef( disabled = false, style, hoverStyle: hoverStyleProp, + Component = Pressable, ...rest }, ref, @@ -237,7 +239,7 @@ export const Button = React.forwardRef( const flattenedBaseStyles = flatten([baseStyles, style]) return ( - ( {typeof children === 'function' ? children(context) : children} - + ) }, ) diff --git a/src/components/Menu/index.tsx b/src/components/Menu/index.tsx index c48d6f9bd0..298e0d91f7 100644 --- a/src/components/Menu/index.tsx +++ b/src/components/Menu/index.tsx @@ -1,6 +1,5 @@ import React from 'react' import {StyleProp, View, ViewStyle} from 'react-native' -import {BlueskyBottomSheetPressable as Pressable} from '@haileyok/bluesky-bottom-sheet' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import flattenReactChildren from 'react-keyed-flatten-children' @@ -19,6 +18,7 @@ import { ItemTextProps, TriggerProps, } from '#/components/Menu/types' +import {NormalizedPressable} from '#/components/NormalizedPressable' import {Text} from '#/components/Typography' export { @@ -117,7 +117,7 @@ export function Item({children, label, style, onPress, ...rest}: ItemProps) { } = useInteractionState() return ( - {children} - + ) } diff --git a/src/components/Menu/types.ts b/src/components/Menu/types.ts index 75cc613679..2f7aea5de5 100644 --- a/src/components/Menu/types.ts +++ b/src/components/Menu/types.ts @@ -4,8 +4,6 @@ import { GestureResponderEvent, PressableProps, } from 'react-native' -import {PressableEvent} from 'react-native-gesture-handler/lib/typescript/components/Pressable/PressableProps' -import {BlueskyBottomSheetPressableProps} from '@haileyok/bluesky-bottom-sheet' import {TextStyleProp, ViewStyleProp} from '#/alf' import * as Dialog from '#/components/Dialog' @@ -89,10 +87,10 @@ export type TriggerChildProps = } export type ItemProps = React.PropsWithChildren< - Omit & + Omit & ViewStyleProp & { label: string - onPress: (e: PressableEvent | GestureResponderEvent) => void + onPress: (e: GestureResponderEvent) => void } > diff --git a/src/components/NormalizedPressable.tsx b/src/components/NormalizedPressable.tsx new file mode 100644 index 0000000000..75d6a197e2 --- /dev/null +++ b/src/components/NormalizedPressable.tsx @@ -0,0 +1,120 @@ +import React from 'react' +import { + GestureResponderEvent, + NativeMouseEvent, + NativeSyntheticEvent, + PressableProps, + View, +} from 'react-native' +import {Pressable as BSPressable} from 'react-native-gesture-handler' +import {PressableEvent} from 'react-native-gesture-handler/lib/typescript/components/Pressable/PressableProps' + +function pressableEventToGestureResponderEvent( + event: PressableEvent, +): GestureResponderEvent { + return { + nativeEvent: { + ...event.nativeEvent, + touches: [], + changedTouches: [], + identifier: event.nativeEvent.identifier.toString(), + target: event.nativeEvent.target.toString(), + }, + target: null, + currentTarget: null, + preventDefault() {}, + stopPropagation() {}, + cancelable: false, + defaultPrevented: false, + eventPhase: 0, + isTrusted: false, + bubbles: false, + timeStamp: event.nativeEvent.timestamp, + isDefaultPrevented(): boolean { + return false + }, + isPropagationStopped(): boolean { + return false + }, + persist() {}, + type: 'press', + } +} + +function pressableEventToMouseEvent( + event: PressableEvent, +): MouseEvent & NativeSyntheticEvent { + return { + ...event.nativeEvent, + target: null, + currentTarget: null, + preventDefault() {}, + stopPropagation() {}, + cancelable: false, + defaultPrevented: false, + eventPhase: 0, + isTrusted: false, + bubbles: false, + timeStamp: event.nativeEvent.timestamp, + } +} + +export const NormalizedPressable = React.forwardRef( + function NormalizedPressable( + { + onPress, + onLongPress, + onPressIn, + onPressOut, + onHoverIn, + onHoverOut, + onFocus: _onFocus, + ...rest + }, + ref, + ) { + const onNormalizedPress = (event: PressableEvent) => { + if (!onPress) return + onPress(pressableEventToGestureResponderEvent(event)) + } + + const onNormalizedLongPress = (event: PressableEvent) => { + if (!onLongPress) return + onLongPress(pressableEventToGestureResponderEvent(event)) + } + + const onNormalizedPressIn = (event: PressableEvent) => { + if (!onPressIn) return + onPressIn(pressableEventToGestureResponderEvent(event)) + } + + const onNormalizedPressOut = (event: PressableEvent) => { + if (!onPressOut) return + onPressOut(pressableEventToGestureResponderEvent(event)) + } + + const onNormalizedHoverIn = (event: PressableEvent) => { + if (!onHoverIn) return + onHoverIn(pressableEventToMouseEvent(event)) + } + + const onNormalizedHoverOut = (event: PressableEvent) => { + if (!onHoverOut) return + onHoverOut(pressableEventToMouseEvent(event)) + } + + return ( + + + + ) + }, +) diff --git a/src/components/NormalizedPressable.web.tsx b/src/components/NormalizedPressable.web.tsx new file mode 100644 index 0000000000..fa786a6070 --- /dev/null +++ b/src/components/NormalizedPressable.web.tsx @@ -0,0 +1,3 @@ +import {Pressable as NormalizedPressable} from 'react-native' + +export {NormalizedPressable}