diff options
author | Ansh <anshnanda10@gmail.com> | 2023-07-28 14:00:37 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-28 16:00:37 -0500 |
commit | 3b8b5622688807f6d04c52cbd4d6977b203b75b3 (patch) | |
tree | d14739a4cf680efead0f7dc63428f9ad88d7d5ef /src/view/com/util/forms/DropdownButton.tsx | |
parent | eec300d77241925e6b42e5e7e51894f2cba50e18 (diff) | |
download | voidsky-3b8b5622688807f6d04c52cbd4d6977b203b75b3.tar.zst |
[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`
Diffstat (limited to 'src/view/com/util/forms/DropdownButton.tsx')
-rw-r--r-- | src/view/com/util/forms/DropdownButton.tsx | 125 |
1 files changed, 8 insertions, 117 deletions
diff --git a/src/view/com/util/forms/DropdownButton.tsx b/src/view/com/util/forms/DropdownButton.tsx index 046610b29..a1ee3d589 100644 --- a/src/view/com/util/forms/DropdownButton.tsx +++ b/src/view/com/util/forms/DropdownButton.tsx @@ -14,14 +14,10 @@ import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {Text} from '../text/Text' import {Button, ButtonType} from './Button' import {colors} from 'lib/styles' -import {toShareUrl} from 'lib/strings/url-helpers' -import {useStores} from 'state/index' import {usePalette} from 'lib/hooks/usePalette' import {useTheme} from 'lib/ThemeContext' -import {isWeb} from 'platform/detection' -import {shareUrl} from 'lib/sharing' +import {HITSLOP_10} from 'lib/constants' -const HITSLOP = {left: 10, top: 10, right: 10, bottom: 10} const ESTIMATED_BTN_HEIGHT = 50 const ESTIMATED_SEP_HEIGHT = 16 const ESTIMATED_HEADING_HEIGHT = 60 @@ -140,7 +136,7 @@ export function DropdownButton({ testID={testID} style={style} onPress={onPress} - hitSlop={HITSLOP} + hitSlop={HITSLOP_10} ref={ref1} accessibilityRole="button" accessibilityLabel={accessibilityLabel || `Opens ${numItems} options`} @@ -163,112 +159,6 @@ export function DropdownButton({ ) } -export function PostDropdownBtn({ - testID, - style, - children, - itemUri, - itemCid, - itemHref, - isAuthor, - isThreadMuted, - onCopyPostText, - onOpenTranslate, - onToggleThreadMute, - onDeletePost, -}: { - testID?: string - style?: StyleProp<ViewStyle> - children?: React.ReactNode - itemUri: string - itemCid: string - itemHref: string - itemTitle: string - isAuthor: boolean - isThreadMuted: boolean - onCopyPostText: () => void - onOpenTranslate: () => void - onToggleThreadMute: () => void - onDeletePost: () => void -}) { - const store = useStores() - - const dropdownItems: DropdownItem[] = [ - { - testID: 'postDropdownTranslateBtn', - icon: 'language', - label: 'Translate...', - onPress() { - onOpenTranslate() - }, - }, - { - testID: 'postDropdownCopyTextBtn', - icon: ['far', 'paste'], - label: 'Copy post text', - onPress() { - onCopyPostText() - }, - }, - { - testID: 'postDropdownShareBtn', - icon: 'share', - label: 'Share...', - onPress() { - const url = toShareUrl(itemHref) - shareUrl(url) - }, - }, - {sep: true}, - { - testID: 'postDropdownMuteThreadBtn', - icon: 'comment-slash', - label: isThreadMuted ? 'Unmute thread' : 'Mute thread', - onPress() { - onToggleThreadMute() - }, - }, - {sep: true}, - !isAuthor && { - testID: 'postDropdownReportBtn', - icon: 'circle-exclamation', - label: 'Report post', - onPress() { - store.shell.openModal({ - name: 'report-post', - postUri: itemUri, - postCid: itemCid, - }) - }, - }, - isAuthor && { - testID: 'postDropdownDeleteBtn', - icon: ['far', 'trash-can'], - label: 'Delete post', - onPress() { - store.shell.openModal({ - name: 'confirm', - title: 'Delete this post?', - message: 'Are you sure? This can not be undone.', - onPressConfirm: onDeletePost, - }) - }, - }, - ].filter(Boolean) as DropdownItem[] - - return ( - <DropdownButton - testID={testID} - style={style} - items={dropdownItems} - menuWidth={isWeb ? 220 : 200} - accessibilityLabel="Additional post actions" - accessibilityHint=""> - {children} - </DropdownButton> - ) -} - function createDropdownMenu( x: number, y: number, @@ -324,15 +214,16 @@ const DropdownItems = ({ const numItems = items.filter(isBtn).length + // TODO: Refactor dropdown components to: + // - (On web, if not handled by React Native) use semantic <select /> + // and <option /> elements for keyboard navigation out of the box + // - (On mobile) be buttons by default, accept `label` and `nativeID` + // props, and always have an explicit label return ( <> + {/* This TouchableWithoutFeedback renders the background so if the user clicks outside, the dropdown closes */} <TouchableWithoutFeedback onPress={onOuterPress} - // TODO: Refactor dropdown components to: - // - (On web, if not handled by React Native) use semantic <select /> - // and <option /> elements for keyboard navigation out of the box - // - (On mobile) be buttons by default, accept `label` and `nativeID` - // props, and always have an explicit label accessibilityRole="button" accessibilityLabel="Toggle dropdown" accessibilityHint=""> |