Link updates, add atoms
This commit is contained in:
@@ -122,6 +122,9 @@ export const atoms = {
|
|||||||
flex_shrink: {
|
flex_shrink: {
|
||||||
flexShrink: 1,
|
flexShrink: 1,
|
||||||
},
|
},
|
||||||
|
justify_start: {
|
||||||
|
justifyContent: 'flex-start',
|
||||||
|
},
|
||||||
justify_center: {
|
justify_center: {
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
},
|
},
|
||||||
@@ -140,10 +143,31 @@ export const atoms = {
|
|||||||
align_end: {
|
align_end: {
|
||||||
alignItems: 'flex-end',
|
alignItems: 'flex-end',
|
||||||
},
|
},
|
||||||
|
self_auto: {
|
||||||
|
alignSelf: 'auto',
|
||||||
|
},
|
||||||
|
self_start: {
|
||||||
|
alignSelf: 'flex-start',
|
||||||
|
},
|
||||||
|
self_end: {
|
||||||
|
alignSelf: 'flex-end',
|
||||||
|
},
|
||||||
|
self_center: {
|
||||||
|
alignSelf: 'center',
|
||||||
|
},
|
||||||
|
self_stretch: {
|
||||||
|
alignSelf: 'stretch',
|
||||||
|
},
|
||||||
|
self_baseline: {
|
||||||
|
alignSelf: 'baseline',
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Text
|
* Text
|
||||||
*/
|
*/
|
||||||
|
text_left: {
|
||||||
|
textAlign: 'left',
|
||||||
|
},
|
||||||
text_center: {
|
text_center: {
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
},
|
},
|
||||||
@@ -195,10 +219,16 @@ export const atoms = {
|
|||||||
font_bold: {
|
font_bold: {
|
||||||
fontWeight: tokens.fontWeight.semibold,
|
fontWeight: tokens.fontWeight.semibold,
|
||||||
},
|
},
|
||||||
|
italic: {
|
||||||
|
fontStyle: 'italic',
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Border
|
* Border
|
||||||
*/
|
*/
|
||||||
|
border_0: {
|
||||||
|
borderWidth: 0,
|
||||||
|
},
|
||||||
border: {
|
border: {
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
},
|
},
|
||||||
@@ -208,6 +238,12 @@ export const atoms = {
|
|||||||
border_b: {
|
border_b: {
|
||||||
borderBottomWidth: 1,
|
borderBottomWidth: 1,
|
||||||
},
|
},
|
||||||
|
border_l: {
|
||||||
|
borderLeftWidth: 1,
|
||||||
|
},
|
||||||
|
border_r: {
|
||||||
|
borderRightWidth: 1,
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Shadow
|
* Shadow
|
||||||
|
|||||||
+32
-14
@@ -13,7 +13,7 @@ import {sanitizeUrl} from '@braintree/sanitize-url'
|
|||||||
|
|
||||||
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
||||||
import {isWeb} from '#/platform/detection'
|
import {isWeb} from '#/platform/detection'
|
||||||
import {useTheme, web, flatten, TextStyleProp} from '#/alf'
|
import {useTheme, web, flatten, TextStyleProp, atoms as a} from '#/alf'
|
||||||
import {Button, ButtonProps} from '#/components/Button'
|
import {Button, ButtonProps} from '#/components/Button'
|
||||||
import {AllNavigatorParams, NavigationProp} from '#/lib/routes/types'
|
import {AllNavigatorParams, NavigationProp} from '#/lib/routes/types'
|
||||||
import {
|
import {
|
||||||
@@ -35,6 +35,8 @@ type BaseLinkProps = Pick<
|
|||||||
Parameters<typeof useLinkProps<AllNavigatorParams>>[0],
|
Parameters<typeof useLinkProps<AllNavigatorParams>>[0],
|
||||||
'to'
|
'to'
|
||||||
> & {
|
> & {
|
||||||
|
testID?: string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The React Navigation `StackAction` to perform when the link is pressed.
|
* The React Navigation `StackAction` to perform when the link is pressed.
|
||||||
*/
|
*/
|
||||||
@@ -46,6 +48,13 @@ type BaseLinkProps = Pick<
|
|||||||
* Note: atm this only works for `InlineLink`s with a string child.
|
* Note: atm this only works for `InlineLink`s with a string child.
|
||||||
*/
|
*/
|
||||||
warnOnMismatchingTextChild?: boolean
|
warnOnMismatchingTextChild?: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for when the link is pressed.
|
||||||
|
*
|
||||||
|
* DO NOT use this for navigation, that's what the `to` prop is for.
|
||||||
|
*/
|
||||||
|
onPress?: (e: GestureResponderEvent) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useLink({
|
export function useLink({
|
||||||
@@ -53,6 +62,7 @@ export function useLink({
|
|||||||
displayText,
|
displayText,
|
||||||
action = 'push',
|
action = 'push',
|
||||||
warnOnMismatchingTextChild,
|
warnOnMismatchingTextChild,
|
||||||
|
onPress: outerOnPress,
|
||||||
}: BaseLinkProps & {
|
}: BaseLinkProps & {
|
||||||
displayText: string
|
displayText: string
|
||||||
}) {
|
}) {
|
||||||
@@ -66,6 +76,8 @@ export function useLink({
|
|||||||
|
|
||||||
const onPress = React.useCallback(
|
const onPress = React.useCallback(
|
||||||
(e: GestureResponderEvent) => {
|
(e: GestureResponderEvent) => {
|
||||||
|
outerOnPress?.(e)
|
||||||
|
|
||||||
const requiresWarning = Boolean(
|
const requiresWarning = Boolean(
|
||||||
warnOnMismatchingTextChild &&
|
warnOnMismatchingTextChild &&
|
||||||
displayText &&
|
displayText &&
|
||||||
@@ -132,6 +144,7 @@ export function useLink({
|
|||||||
displayText,
|
displayText,
|
||||||
closeModal,
|
closeModal,
|
||||||
openModal,
|
openModal,
|
||||||
|
outerOnPress,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -143,15 +156,11 @@ export function useLink({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type LinkProps = Omit<BaseLinkProps, 'warnOnMismatchingTextChild'> &
|
export type LinkProps = Omit<BaseLinkProps, 'warnOnMismatchingTextChild'> &
|
||||||
Omit<ButtonProps, 'style' | 'onPress' | 'disabled' | 'label'> & {
|
Omit<ButtonProps, 'onPress' | 'disabled' | 'label'> & {
|
||||||
/**
|
/**
|
||||||
* Label for a11y. Defaults to the href.
|
* Label for a11y. Defaults to the href.
|
||||||
*/
|
*/
|
||||||
label?: string
|
label?: string
|
||||||
/**
|
|
||||||
* Web-only attribute. Sets `download` attr on web.
|
|
||||||
*/
|
|
||||||
download?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -166,19 +175,21 @@ export function Link({
|
|||||||
children,
|
children,
|
||||||
to,
|
to,
|
||||||
action = 'push',
|
action = 'push',
|
||||||
download,
|
onPress: outerOnPress,
|
||||||
...rest
|
...rest
|
||||||
}: LinkProps) {
|
}: LinkProps) {
|
||||||
const {href, isExternal, onPress} = useLink({
|
const {href, isExternal, onPress} = useLink({
|
||||||
to,
|
to,
|
||||||
displayText: typeof children === 'string' ? children : '',
|
displayText: typeof children === 'string' ? children : '',
|
||||||
action,
|
action,
|
||||||
|
onPress: outerOnPress,
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
label={href}
|
label={href}
|
||||||
{...rest}
|
{...rest}
|
||||||
|
style={[a.justify_start, flatten(rest.style)]}
|
||||||
role="link"
|
role="link"
|
||||||
accessibilityRole="link"
|
accessibilityRole="link"
|
||||||
href={href}
|
href={href}
|
||||||
@@ -187,7 +198,6 @@ export function Link({
|
|||||||
hrefAttrs: {
|
hrefAttrs: {
|
||||||
target: isExternal ? 'blank' : undefined,
|
target: isExternal ? 'blank' : undefined,
|
||||||
rel: isExternal ? 'noopener noreferrer' : undefined,
|
rel: isExternal ? 'noopener noreferrer' : undefined,
|
||||||
download,
|
|
||||||
},
|
},
|
||||||
dataSet: {
|
dataSet: {
|
||||||
// default to no underline, apply this ourselves
|
// default to no underline, apply this ourselves
|
||||||
@@ -215,6 +225,7 @@ export function InlineLink({
|
|||||||
action = 'push',
|
action = 'push',
|
||||||
warnOnMismatchingTextChild,
|
warnOnMismatchingTextChild,
|
||||||
style,
|
style,
|
||||||
|
onPress: outerOnPress,
|
||||||
...rest
|
...rest
|
||||||
}: InlineLinkProps) {
|
}: InlineLinkProps) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
@@ -224,13 +235,20 @@ export function InlineLink({
|
|||||||
displayText: stringChildren ? children : '',
|
displayText: stringChildren ? children : '',
|
||||||
action,
|
action,
|
||||||
warnOnMismatchingTextChild,
|
warnOnMismatchingTextChild,
|
||||||
|
onPress: outerOnPress,
|
||||||
})
|
})
|
||||||
|
const {
|
||||||
|
state: hovered,
|
||||||
|
onIn: onHoverIn,
|
||||||
|
onOut: onHoverOut,
|
||||||
|
} = useInteractionState()
|
||||||
const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState()
|
const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState()
|
||||||
const {
|
const {
|
||||||
state: pressed,
|
state: pressed,
|
||||||
onIn: onPressIn,
|
onIn: onPressIn,
|
||||||
onOut: onPressOut,
|
onOut: onPressOut,
|
||||||
} = useInteractionState()
|
} = useInteractionState()
|
||||||
|
const flattenedStyle = flatten(style)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TouchableWithoutFeedback
|
<TouchableWithoutFeedback
|
||||||
@@ -245,14 +263,16 @@ export function InlineLink({
|
|||||||
{...rest}
|
{...rest}
|
||||||
style={[
|
style={[
|
||||||
{color: t.palette.primary_500},
|
{color: t.palette.primary_500},
|
||||||
(focused || pressed) && {
|
(hovered || focused || pressed) && {
|
||||||
outline: 0,
|
outline: 0,
|
||||||
textDecorationLine: 'underline',
|
textDecorationLine: 'underline',
|
||||||
textDecorationColor: t.palette.primary_500,
|
textDecorationColor: flattenedStyle.color ?? t.palette.primary_500,
|
||||||
},
|
},
|
||||||
flatten(style),
|
flattenedStyle,
|
||||||
]}
|
]}
|
||||||
role="link"
|
role="link"
|
||||||
|
onMouseEnter={onHoverIn}
|
||||||
|
onMouseLeave={onHoverOut}
|
||||||
accessibilityRole="link"
|
accessibilityRole="link"
|
||||||
href={href}
|
href={href}
|
||||||
{...web({
|
{...web({
|
||||||
@@ -260,9 +280,7 @@ export function InlineLink({
|
|||||||
target: isExternal ? 'blank' : undefined,
|
target: isExternal ? 'blank' : undefined,
|
||||||
rel: isExternal ? 'noopener noreferrer' : undefined,
|
rel: isExternal ? 'noopener noreferrer' : undefined,
|
||||||
},
|
},
|
||||||
dataSet: stringChildren
|
dataSet: {
|
||||||
? {}
|
|
||||||
: {
|
|
||||||
// default to no underline, apply this ourselves
|
// default to no underline, apply this ourselves
|
||||||
noUnderline: '1',
|
noUnderline: '1',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -19,9 +19,14 @@ export function Links() {
|
|||||||
style={[a.text_md]}>
|
style={[a.text_md]}>
|
||||||
External
|
External
|
||||||
</InlineLink>
|
</InlineLink>
|
||||||
<InlineLink to="https://bsky.social" style={[a.text_md]}>
|
<InlineLink to="https://bsky.social" style={[a.text_md, t.atoms.text]}>
|
||||||
<H3>External with custom children</H3>
|
<H3>External with custom children</H3>
|
||||||
</InlineLink>
|
</InlineLink>
|
||||||
|
<InlineLink
|
||||||
|
to="https://bsky.social"
|
||||||
|
style={[a.text_md, t.atoms.text_contrast_low]}>
|
||||||
|
External with custom children
|
||||||
|
</InlineLink>
|
||||||
<InlineLink
|
<InlineLink
|
||||||
to="https://bsky.social"
|
to="https://bsky.social"
|
||||||
warnOnMismatchingTextChild
|
warnOnMismatchingTextChild
|
||||||
|
|||||||
Reference in New Issue
Block a user