Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Sheets] [Pt. 7] Replace all buttons with BottomSheetButton #5565

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions src/components/AccountList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import {useProfileQuery} from '#/state/queries/profile'
import {type SessionAccount, useSession} from '#/state/session'
import {UserAvatar} from '#/view/com/util/UserAvatar'
import {atoms as a, useTheme} from '#/alf'
import {BottomSheetButton} from '#/components/BottomSheetButton'
import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check'
import {ChevronRight_Stroke2_Corner0_Rounded as Chevron} from '#/components/icons/Chevron'
import {Button} from './Button'
import {Text} from './Typography'

export function AccountList({
Expand Down Expand Up @@ -51,19 +51,19 @@ export function AccountList({
<View style={[{borderBottomWidth: 1}, t.atoms.border_contrast_low]} />
</React.Fragment>
))}
<Button
<BottomSheetButton
testID="chooseAddAccountBtn"
style={[a.flex_1]}
onPress={pendingDid ? undefined : onPressAddAccount}
label={_(msg`Login to account that is not listed`)}>
{({hovered, pressed}) => (
{({pressed}) => (
<View
style={[
a.flex_1,
a.flex_row,
a.align_center,
{height: 48},
(hovered || pressed) && t.atoms.bg_contrast_25,
pressed && t.atoms.bg_contrast_25,
]}>
<Text
style={[
Expand All @@ -78,7 +78,7 @@ export function AccountList({
<Chevron size="sm" style={[t.atoms.text, a.mr_md]} />
</View>
)}
</Button>
</BottomSheetButton>
</View>
)
}
Expand All @@ -103,7 +103,7 @@ function AccountItem({
}, [account, onSelect])

return (
<Button
<BottomSheetButton
testID={`chooseAccountBtn-${account.handle}`}
key={account.did}
style={[a.flex_1]}
Expand All @@ -113,14 +113,14 @@ function AccountItem({
? _(msg`Continue as ${account.handle} (currently signed in)`)
: _(msg`Sign in as ${account.handle}`)
}>
{({hovered, pressed}) => (
{({pressed}) => (
<View
style={[
a.flex_1,
a.flex_row,
a.align_center,
{height: 48},
(hovered || pressed || isPendingAccount) && t.atoms.bg_contrast_25,
(pressed || isPendingAccount) && t.atoms.bg_contrast_25,
]}>
<View style={a.p_md}>
<UserAvatar avatar={profile?.avatar} size={24} />
Expand All @@ -143,6 +143,6 @@ function AccountItem({
)}
</View>
)}
</Button>
</BottomSheetButton>
)
}
110 changes: 110 additions & 0 deletions src/components/BottomSheetButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import React from 'react'
import {AccessibilityProps, ViewStyle} from 'react-native'
import {PressableEvent} from 'react-native-gesture-handler/lib/typescript/components/Pressable/PressableProps'
import {
BlueskyBottomSheetPressable,
BueskyBottomSheetPressableProps,
} 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
}: BueskyBottomSheetPressableProps &
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],
)

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>
)
}
3 changes: 3 additions & 0 deletions src/components/BottomSheetButton.web.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import {Button as BottomSheetButton} from '#/components/Button'

export {BottomSheetButton}
92 changes: 92 additions & 0 deletions src/components/BottomSheetLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import React from 'react'
import {BlueskyBottomSheetPressable} from '@haileyok/bluesky-bottom-sheet'
import {StackActions, useNavigation} from '@react-navigation/native'

import {NavigationProp} from '#/lib/routes/types'
import {flatten, useTheme} from '#/alf'
import {useDialogContext} from '#/components/Dialog'
import {useInteractionState} from '#/components/hooks/useInteractionState'
import {InlineLinkProps, useLink} from '#/components/Link'
import {Text} from '#/components/Typography'
import {router} from '#/routes'

export function BottomSheetInlineLinkText({
children,
to,
action = 'push',
disableMismatchWarning,
style,
onPress: outerOnPress,
label,
shareOnLongPress,
disableUnderline,
...rest
}: InlineLinkProps) {
const t = useTheme()
const stringChildren = typeof children === 'string'
const navigation = useNavigation<NavigationProp>()
const dialog = useDialogContext()

const {href, isExternal, onLongPress} = useLink({
to,
displayText: stringChildren ? children : '',
action,
disableMismatchWarning,
onPress: outerOnPress,
shareOnLongPress,
})
const {
state: pressed,
onIn: onPressIn,
onOut: onPressOut,
} = useInteractionState()

const onPress = () => {
if (isExternal) {
return
}

dialog.close()

if (action === 'push') {
navigation.dispatch(StackActions.push(...router.matchPath(href)))
} else if (action === 'replace') {
navigation.dispatch(StackActions.replace(...router.matchPath(href)))
} else if (action === 'navigate') {
// @ts-ignore
navigation.navigate(...router.matchPath(href))
} else {
throw Error('Unsupported navigator action.')
}
}

const flattenedStyle = flatten(style) || {}

// eslint-disable-next-line bsky-internal/avoid-unwrapped-text
return (
<BlueskyBottomSheetPressable
onPress={onPress}
onLongPress={onLongPress}
onPressIn={onPressIn}
onPressOut={onPressOut}
role="link"
accessibilityLabel={label}
accessibilityHint=""
style={{flexDirection: 'row'}}>
<Text
{...rest}
style={[
{color: t.palette.primary_500},
pressed &&
!disableUnderline && {
textDecorationLine: 'underline',
textDecorationColor:
flattenedStyle.color ?? t.palette.primary_500,
},
flattenedStyle,
]}>
{children}
</Text>
</BlueskyBottomSheetPressable>
)
}
3 changes: 3 additions & 0 deletions src/components/BottomSheetLink.web.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import {Link as BottomSheetLink} from './Link'

export {BottomSheetLink}
Loading
Loading