simplify pressable changes

This commit is contained in:
Hailey
2024-10-02 10:56:19 -07:00
parent 1ca6d360eb
commit b5a5113678
6 changed files with 138 additions and 113 deletions
+6 -104
View File
@@ -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<ButtonContext>(
() => ({
...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 (
<BlueskyBottomSheetPressable
style={[
a.flex_row,
a.align_center,
a.justify_center,
baseStyles,
style as ViewStyle,
...(state.hovered || state.pressed ? [hoverStyles] : []),
]}
aria-label={label}
aria-pressed={state.pressed}
accessibilityLabel={label}
accessibilityHint={undefined}
accessibilityState={{
disabled: disabled || false,
}}
onPressIn={onPressIn}
onPressOut={onPressOut}
{...rest}>
<ButtonContext.Provider value={context}>
{typeof children === 'function' ? children(context) : children}
</ButtonContext.Provider>
</BlueskyBottomSheetPressable>
<Button {...rest} Component={NormalizedPressable}>
{children}
</Button>
)
}
+4 -2
View File
@@ -87,6 +87,7 @@ export type ButtonProps = Pick<
style?: StyleProp<ViewStyle>
hoverStyle?: StyleProp<ViewStyle>
children: NonTextElements | ((context: ButtonContext) => NonTextElements)
Component?: React.ComponentType<PressableProps>
}
export type ButtonTextProps = TextProps &
@@ -116,6 +117,7 @@ export const Button = React.forwardRef<View, ButtonProps>(
disabled = false,
style,
hoverStyle: hoverStyleProp,
Component = Pressable,
...rest
},
ref,
@@ -237,7 +239,7 @@ export const Button = React.forwardRef<View, ButtonProps>(
const flattenedBaseStyles = flatten([baseStyles, style])
return (
<Pressable
<Component
role="button"
accessibilityHint={undefined} // optional
{...rest}
@@ -288,7 +290,7 @@ export const Button = React.forwardRef<View, ButtonProps>(
<Context.Provider value={context}>
{typeof children === 'function' ? children(context) : children}
</Context.Provider>
</Pressable>
</Component>
)
},
)
+3 -3
View File
@@ -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 (
<Pressable
<NormalizedPressable
{...rest}
accessibilityHint=""
accessibilityLabel={label}
@@ -151,7 +151,7 @@ export function Item({children, label, style, onPress, ...rest}: ItemProps) {
<ItemContext.Provider value={{disabled: Boolean(rest.disabled)}}>
{children}
</ItemContext.Provider>
</Pressable>
</NormalizedPressable>
)
}
+2 -4
View File
@@ -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<BlueskyBottomSheetPressableProps, 'style'> &
Omit<PressableProps, 'style'> &
ViewStyleProp & {
label: string
onPress: (e: PressableEvent | GestureResponderEvent) => void
onPress: (e: GestureResponderEvent) => void
}
>
+120
View File
@@ -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<NativeMouseEvent> {
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<View, PressableProps>(
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 (
<View ref={ref}>
<BSPressable
onPress={onNormalizedPress}
onLongPress={onNormalizedLongPress}
onPressIn={onNormalizedPressIn}
onPressOut={onNormalizedPressOut}
onHoverIn={onNormalizedHoverIn}
onHoverOut={onNormalizedHoverOut}
{...rest}
/>
</View>
)
},
)
@@ -0,0 +1,3 @@
import {Pressable as NormalizedPressable} from 'react-native'
export {NormalizedPressable}