bsky-app/src/view/com/util/post-ctrls/RepostButton.tsx
Ansh 3b8b562268
[APP-737] Accessible native dropdown menu (#988)
* fix comments

* add zeego package

* get basic native dropdown working

* add separator and icon components

* refined native dropdown component

* add android build properties to app.json

* move `PostDropdownBtn` to its own component

* fix selectors issue

* move `PostDropdownBtn` to its own component

* fix hitslop

* fix post dropdown hitslop

* fix android dropdown icons

* move `UserAvatar.tsx` to native dropdown

* use native dropdown in `ProfileHeader.tsx`

* use native dropdown in `PostThreadItem.tsx`

* use native dropdown in `UserBanner.tsx`

* use native dropdown in `CustomFeed.tsx`

* replace `testId` with `testID` (which is what is used everywhere)

* move `Settings.tsx` to use native dropdown

* create jest mocks for zeego

* create jest mock for `zeego/dropdown-menu`

* web styles for native dropdown

* remove example native dropdown

* adjust web styles

* fix propagation

* fix pressable in `Settings.tsx`

* animate dropdown on web

* add keyboard nav and hover styles

* add hitslop to constants

* add comments to NativeDropdown component

* temporarily removed android icons

* add testID to PostDropdownBtn

* add testID back to all NativeDropdown button implementations

* add postDropdownBtn testID

* add testID to dropdown items

* remove testID from dropdown menu item

* refactor home-screen tests for native dropdown

* refactor profile-screen tests for native dropdown

* refactor thread-muting tests for native dropdown

* refactor thread-screen tests for native dropdown

* fix dropdown color for post dropdown button

* remove icons from android dropdown menu

* fix `create-account.test.ts`

* fix `invite-codes.test.ts`
2023-07-28 16:00:37 -05:00

95 lines
2.2 KiB
TypeScript

import React, {useCallback} from 'react'
import {StyleProp, StyleSheet, TouchableOpacity, ViewStyle} from 'react-native'
import {RepostIcon} from 'lib/icons'
import {s, colors} from 'lib/styles'
import {useTheme} from 'lib/ThemeContext'
import {Text} from '../text/Text'
import {pluralize} from 'lib/strings/helpers'
import {useStores} from 'state/index'
import {createHitslop} from 'lib/constants'
const HITSLOP = createHitslop(5)
interface Props {
isReposted: boolean
repostCount?: number
big?: boolean
onRepost: () => void
onQuote: () => void
}
export const RepostButton = ({
isReposted,
repostCount,
big,
onRepost,
onQuote,
}: Props) => {
const store = useStores()
const theme = useTheme()
const defaultControlColor = React.useMemo(
() => ({
color: theme.palette.default.postCtrl,
}),
[theme],
)
const onPressToggleRepostWrapper = useCallback(() => {
store.shell.openModal({
name: 'repost',
onRepost: onRepost,
onQuote: onQuote,
isReposted,
})
}, [onRepost, onQuote, isReposted, store.shell])
return (
<TouchableOpacity
testID="repostBtn"
hitSlop={HITSLOP}
onPress={onPressToggleRepostWrapper}
style={styles.control}
accessibilityRole="button"
accessibilityLabel={`${
isReposted ? 'Undo repost' : 'Repost'
} (${repostCount} ${pluralize(repostCount || 0, 'repost')})`}
accessibilityHint="">
<RepostIcon
style={
isReposted
? (styles.reposted as StyleProp<ViewStyle>)
: defaultControlColor
}
strokeWidth={2.4}
size={big ? 24 : 20}
/>
{typeof repostCount !== 'undefined' ? (
<Text
testID="repostCount"
style={
isReposted
? [s.bold, s.green3, s.f15, s.ml5]
: [defaultControlColor, s.f15, s.ml5]
}>
{repostCount}
</Text>
) : undefined}
</TouchableOpacity>
)
}
const styles = StyleSheet.create({
control: {
flexDirection: 'row',
alignItems: 'center',
padding: 5,
margin: -5,
},
reposted: {
color: colors.green3,
},
repostCount: {
color: 'currentColor',
},
})