diff options
Diffstat (limited to 'src/view/com/util/Link.tsx')
-rw-r--r-- | src/view/com/util/Link.tsx | 83 |
1 files changed, 44 insertions, 39 deletions
diff --git a/src/view/com/util/Link.tsx b/src/view/com/util/Link.tsx index 489fbc59c..3a0bf6f6d 100644 --- a/src/view/com/util/Link.tsx +++ b/src/view/com/util/Link.tsx @@ -1,20 +1,20 @@ -import React, {ComponentProps, memo, useMemo} from 'react' +import {memo, useCallback, useMemo} from 'react' import { - GestureResponderEvent, + type GestureResponderEvent, Platform, Pressable, - StyleProp, - TextProps, - TextStyle, - TouchableOpacity, + type StyleProp, + type TextProps, + type TextStyle, + type TouchableOpacity, View, - ViewStyle, + type ViewStyle, } from 'react-native' import {sanitizeUrl} from '@braintree/sanitize-url' -import {StackActions, useLinkProps} from '@react-navigation/native' +import {StackActions} from '@react-navigation/native' import { - DebouncedNavigationProp, + type DebouncedNavigationProp, useNavigationDeduped, } from '#/lib/hooks/useNavigationDeduped' import {useOpenLink} from '#/lib/hooks/useOpenLink' @@ -24,7 +24,7 @@ import { isExternalUrl, linkRequiresWarning, } from '#/lib/strings/url-helpers' -import {TypographyVariant} from '#/lib/ThemeContext' +import {type TypographyVariant} from '#/lib/ThemeContext' import {isAndroid, isWeb} from '#/platform/detection' import {emitSoftReset} from '#/state/events' import {useModalControls} from '#/state/modals' @@ -38,7 +38,7 @@ type Event = | React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent -interface Props extends ComponentProps<typeof TouchableOpacity> { +interface Props extends React.ComponentProps<typeof TouchableOpacity> { testID?: string style?: StyleProp<ViewStyle> href?: string @@ -47,7 +47,7 @@ interface Props extends ComponentProps<typeof TouchableOpacity> { hoverStyle?: StyleProp<ViewStyle> noFeedback?: boolean asAnchor?: boolean - dataSet?: Object | undefined + dataSet?: any anchorNoUnderline?: boolean navigationAction?: 'push' | 'replace' | 'navigate' onPointerEnter?: () => void @@ -69,6 +69,7 @@ export const Link = memo(function Link({ onBeforePress, accessibilityActions, onAccessibilityAction, + dataSet: dataSetProp, ...props }: Props) { const t = useTheme() @@ -77,7 +78,7 @@ export const Link = memo(function Link({ const anchorHref = asAnchor ? sanitizeUrl(href) : undefined const openLink = useOpenLink() - const onPress = React.useCallback( + const onPress = useCallback( (e?: Event) => { onBeforePress?.() if (typeof href === 'string') { @@ -99,6 +100,14 @@ export const Link = memo(function Link({ {name: 'activate', label: title}, ] + const dataSet = useMemo(() => { + const ds = {...dataSetProp} + if (anchorNoUnderline) { + ds.noUnderline = 1 + } + return ds + }, [dataSetProp, anchorNoUnderline]) + if (noFeedback) { return ( <WebAuxClickWrapper> @@ -129,17 +138,6 @@ export const Link = memo(function Link({ ) } - if (anchorNoUnderline) { - // @ts-ignore web only -prf - props.dataSet = props.dataSet || {} - // @ts-ignore web only -prf - props.dataSet.noUnderline = 1 - } - - if (title && !props.accessibilityLabel) { - props.accessibilityLabel = title - } - const Com = props.hoverStyle ? PressableWithHover : Pressable return ( <Com @@ -148,8 +146,11 @@ export const Link = memo(function Link({ onPress={onPress} accessible={accessible} accessibilityRole="link" + accessibilityLabel={props.accessibilityLabel ?? title} + accessibilityHint={props.accessibilityHint} // @ts-ignore web only -prf href={anchorHref} + dataSet={dataSet} {...props}> {children ? children : <Text>{title || 'link'}</Text>} </Com> @@ -164,14 +165,14 @@ export const TextLink = memo(function TextLink({ text, numberOfLines, lineHeight, - dataSet, + dataSet: dataSetProp, title, - onPress, + onPress: onPressProp, onBeforePress, disableMismatchWarning, navigationAction, anchorNoUnderline, - ...orgProps + ...props }: { testID?: string type?: TypographyVariant @@ -187,7 +188,6 @@ export const TextLink = memo(function TextLink({ anchorNoUnderline?: boolean onBeforePress?: () => void } & TextProps) { - const {...props} = useLinkProps({to: sanitizeUrl(href)}) const navigation = useNavigationDeduped() const {openModal, closeModal} = useModalControls() const openLink = useOpenLink() @@ -196,12 +196,15 @@ export const TextLink = memo(function TextLink({ console.error('Unable to detect mismatching label') } - if (anchorNoUnderline) { - dataSet = dataSet ?? {} - dataSet.noUnderline = 1 - } + const dataSet = useMemo(() => { + const ds = {...dataSetProp} + if (anchorNoUnderline) { + ds.noUnderline = 1 + } + return ds + }, [dataSetProp, anchorNoUnderline]) - props.onPress = React.useCallback( + const onPress = useCallback( (e?: Event) => { const requiresWarning = !disableMismatchWarning && @@ -224,10 +227,10 @@ export const TextLink = memo(function TextLink({ return } onBeforePress?.() - if (onPress) { + if (onPressProp) { e?.preventDefault?.() - // @ts-ignore function signature differs by platform -prf - return onPress() + // @ts-expect-error function signature differs by platform -prf + return onPressProp() } return onPressInner( closeModal, @@ -240,7 +243,7 @@ export const TextLink = memo(function TextLink({ }, [ onBeforePress, - onPress, + onPressProp, closeModal, openModal, navigation, @@ -273,8 +276,10 @@ export const TextLink = memo(function TextLink({ title={title} // @ts-ignore web only -prf hrefAttrs={hrefAttrs} // hack to get open in new tab to work on safari. without this, safari will open in a new window - {...props} - {...orgProps}> + onPress={onPress} + accessibilityRole="link" + href={convertBskyAppUrlIfNeeded(sanitizeUrl(href))} + {...props}> {text} </Text> ) |