Button context, icons
This commit is contained in:
+91
-86
@@ -6,10 +6,14 @@ import {
|
|||||||
TextProps,
|
TextProps,
|
||||||
ViewStyle,
|
ViewStyle,
|
||||||
AccessibilityProps,
|
AccessibilityProps,
|
||||||
|
View,
|
||||||
|
TextStyle,
|
||||||
|
StyleSheet,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import LinearGradient from 'react-native-linear-gradient'
|
import LinearGradient from 'react-native-linear-gradient'
|
||||||
|
|
||||||
import {useTheme, atoms, tokens, web, native} from '#/alf'
|
import {useTheme, atoms as a, tokens, web, native} from '#/alf'
|
||||||
|
import {Props as SVGIconProps} from '#/components/icons/common'
|
||||||
|
|
||||||
export type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'gradient'
|
export type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'gradient'
|
||||||
export type ButtonColor =
|
export type ButtonColor =
|
||||||
@@ -38,26 +42,33 @@ export type VariantProps = {
|
|||||||
size?: ButtonSize
|
size?: ButtonSize
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ButtonProps = Pick<PressableProps, 'disabled' | 'onPress'> &
|
export type ButtonProps = React.PropsWithChildren<
|
||||||
AccessibilityProps &
|
Pick<PressableProps, 'disabled' | 'onPress'> &
|
||||||
VariantProps & {
|
AccessibilityProps &
|
||||||
children:
|
VariantProps & {
|
||||||
| ((props: {
|
label: string
|
||||||
state: {
|
}
|
||||||
pressed: boolean
|
>
|
||||||
hovered: boolean
|
|
||||||
focused: boolean
|
|
||||||
}
|
|
||||||
props: VariantProps & {
|
|
||||||
disabled?: boolean
|
|
||||||
}
|
|
||||||
}) => React.ReactNode)
|
|
||||||
| React.ReactNode
|
|
||||||
| string
|
|
||||||
label: string
|
|
||||||
}
|
|
||||||
export type ButtonTextProps = TextProps & VariantProps & {disabled?: boolean}
|
export type ButtonTextProps = TextProps & VariantProps & {disabled?: boolean}
|
||||||
|
|
||||||
|
const Context = React.createContext<
|
||||||
|
VariantProps & {
|
||||||
|
hovered: boolean
|
||||||
|
focused: boolean
|
||||||
|
pressed: boolean
|
||||||
|
disabled: boolean
|
||||||
|
}
|
||||||
|
>({
|
||||||
|
hovered: false,
|
||||||
|
focused: false,
|
||||||
|
pressed: false,
|
||||||
|
disabled: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
export function useButtonContext() {
|
||||||
|
return React.useContext(Context)
|
||||||
|
}
|
||||||
|
|
||||||
export function Button({
|
export function Button({
|
||||||
children,
|
children,
|
||||||
variant,
|
variant,
|
||||||
@@ -131,21 +142,21 @@ export function Button({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else if (variant === 'outline') {
|
} else if (variant === 'outline') {
|
||||||
baseStyles.push(atoms.border, t.atoms.bg, {
|
baseStyles.push(a.border, t.atoms.bg, {
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!disabled) {
|
if (!disabled) {
|
||||||
baseStyles.push(atoms.border, {
|
baseStyles.push(a.border, {
|
||||||
borderColor: tokens.color.blue_500,
|
borderColor: tokens.color.blue_500,
|
||||||
})
|
})
|
||||||
hoverStyles.push(atoms.border, {
|
hoverStyles.push(a.border, {
|
||||||
backgroundColor: light
|
backgroundColor: light
|
||||||
? t.palette.primary_100
|
? t.palette.primary_100
|
||||||
: t.palette.primary_900,
|
: t.palette.primary_900,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
baseStyles.push(atoms.border, {
|
baseStyles.push(a.border, {
|
||||||
borderColor: light ? tokens.color.blue_200 : tokens.color.blue_900,
|
borderColor: light ? tokens.color.blue_200 : tokens.color.blue_900,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -180,17 +191,17 @@ export function Button({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else if (variant === 'outline') {
|
} else if (variant === 'outline') {
|
||||||
baseStyles.push(atoms.border, t.atoms.bg, {
|
baseStyles.push(a.border, t.atoms.bg, {
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!disabled) {
|
if (!disabled) {
|
||||||
baseStyles.push(atoms.border, {
|
baseStyles.push(a.border, {
|
||||||
borderColor: light ? tokens.color.gray_500 : tokens.color.gray_500,
|
borderColor: light ? tokens.color.gray_500 : tokens.color.gray_500,
|
||||||
})
|
})
|
||||||
hoverStyles.push(atoms.border, t.atoms.bg_contrast_50)
|
hoverStyles.push(a.border, t.atoms.bg_contrast_50)
|
||||||
} else {
|
} else {
|
||||||
baseStyles.push(atoms.border, {
|
baseStyles.push(a.border, {
|
||||||
borderColor: light ? tokens.color.gray_200 : tokens.color.gray_800,
|
borderColor: light ? tokens.color.gray_200 : tokens.color.gray_800,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -219,19 +230,19 @@ export function Button({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else if (variant === 'outline') {
|
} else if (variant === 'outline') {
|
||||||
baseStyles.push(atoms.border, t.atoms.bg, {
|
baseStyles.push(a.border, t.atoms.bg, {
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!disabled) {
|
if (!disabled) {
|
||||||
baseStyles.push(atoms.border, {
|
baseStyles.push(a.border, {
|
||||||
borderColor: t.palette.negative_600,
|
borderColor: t.palette.negative_600,
|
||||||
})
|
})
|
||||||
hoverStyles.push(atoms.border, {
|
hoverStyles.push(a.border, {
|
||||||
backgroundColor: light ? t.palette.negative_50 : '#2D0614', // darker red
|
backgroundColor: light ? t.palette.negative_50 : '#2D0614', // darker red
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
baseStyles.push(atoms.border, {
|
baseStyles.push(a.border, {
|
||||||
borderColor: light
|
borderColor: light
|
||||||
? t.palette.negative_200
|
? t.palette.negative_200
|
||||||
: t.palette.negative_900,
|
: t.palette.negative_900,
|
||||||
@@ -248,19 +259,9 @@ export function Button({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (size === 'large') {
|
if (size === 'large') {
|
||||||
baseStyles.push(
|
baseStyles.push({paddingVertical: 15}, a.px_2xl, a.rounded_sm, a.gap_sm)
|
||||||
{paddingVertical: 15},
|
|
||||||
atoms.px_2xl,
|
|
||||||
atoms.rounded_sm,
|
|
||||||
atoms.gap_sm,
|
|
||||||
)
|
|
||||||
} else if (size === 'small') {
|
} else if (size === 'small') {
|
||||||
baseStyles.push(
|
baseStyles.push({paddingVertical: 9}, a.px_md, a.rounded_sm, a.gap_sm)
|
||||||
{paddingVertical: 9},
|
|
||||||
atoms.px_md,
|
|
||||||
atoms.rounded_sm,
|
|
||||||
atoms.gap_xs,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -305,15 +306,13 @@ export function Button({
|
|||||||
}
|
}
|
||||||
}, [variant, color])
|
}, [variant, color])
|
||||||
|
|
||||||
const childProps = React.useMemo(
|
const context = React.useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
state,
|
...state,
|
||||||
props: {
|
variant,
|
||||||
variant,
|
color,
|
||||||
color,
|
size,
|
||||||
size,
|
disabled: disabled || false,
|
||||||
disabled: disabled || false,
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
[state, variant, color, size, disabled],
|
[state, variant, color, size, disabled],
|
||||||
)
|
)
|
||||||
@@ -331,9 +330,9 @@ export function Button({
|
|||||||
disabled: disabled || false,
|
disabled: disabled || false,
|
||||||
}}
|
}}
|
||||||
style={[
|
style={[
|
||||||
atoms.flex_row,
|
a.flex_row,
|
||||||
atoms.align_center,
|
a.align_center,
|
||||||
atoms.overflow_hidden,
|
a.overflow_hidden,
|
||||||
...baseStyles,
|
...baseStyles,
|
||||||
...(state.hovered || state.pressed ? hoverStyles : []),
|
...(state.hovered || state.pressed ? hoverStyles : []),
|
||||||
...(state.focused ? focusStyles : []),
|
...(state.focused ? focusStyles : []),
|
||||||
@@ -354,39 +353,25 @@ export function Button({
|
|||||||
locations={gradientLocations}
|
locations={gradientLocations}
|
||||||
start={{x: 0, y: 0}}
|
start={{x: 0, y: 0}}
|
||||||
end={{x: 1, y: 1}}
|
end={{x: 1, y: 1}}
|
||||||
style={[atoms.absolute, atoms.inset_0]}
|
style={[a.absolute, a.inset_0]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{typeof children === 'string' ? (
|
<Context.Provider value={context}>
|
||||||
<ButtonText
|
{typeof children === 'string' ? (
|
||||||
variant={variant}
|
<ButtonText>{children}</ButtonText>
|
||||||
color={color}
|
) : (
|
||||||
size={size}
|
children
|
||||||
disabled={disabled || false}>
|
)}
|
||||||
{children}
|
</Context.Provider>
|
||||||
</ButtonText>
|
|
||||||
) : typeof children === 'function' ? (
|
|
||||||
children(childProps)
|
|
||||||
) : (
|
|
||||||
children
|
|
||||||
)}
|
|
||||||
</Pressable>
|
</Pressable>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ButtonText({
|
export function useSharedButtonTextStyles() {
|
||||||
children,
|
|
||||||
style,
|
|
||||||
variant,
|
|
||||||
color,
|
|
||||||
size,
|
|
||||||
disabled,
|
|
||||||
...rest
|
|
||||||
}: ButtonTextProps) {
|
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
|
const {color, variant, disabled, size} = useButtonContext()
|
||||||
const textStyles = React.useMemo(() => {
|
return React.useMemo(() => {
|
||||||
const baseStyles = []
|
const baseStyles: TextStyle[] = []
|
||||||
const light = t.name === 'light'
|
const light = t.name === 'light'
|
||||||
|
|
||||||
if (color === 'primary') {
|
if (color === 'primary') {
|
||||||
@@ -473,26 +458,46 @@ export function ButtonText({
|
|||||||
|
|
||||||
if (size === 'large') {
|
if (size === 'large') {
|
||||||
baseStyles.push(
|
baseStyles.push(
|
||||||
atoms.text_md,
|
a.text_md,
|
||||||
web({paddingBottom: 1}),
|
web({paddingBottom: 1}),
|
||||||
native({marginTop: 2}),
|
native({marginTop: 2}),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
baseStyles.push(
|
baseStyles.push(
|
||||||
atoms.text_md,
|
a.text_md,
|
||||||
web({paddingBottom: 1}),
|
web({paddingBottom: 1}),
|
||||||
native({marginTop: 2}),
|
native({marginTop: 2}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return baseStyles
|
return StyleSheet.flatten(baseStyles)
|
||||||
}, [t, variant, color, size, disabled])
|
}, [t, variant, color, size, disabled])
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ButtonText({children, style, ...rest}: ButtonTextProps) {
|
||||||
|
const textStyles = useSharedButtonTextStyles()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Text
|
<Text {...rest} style={[a.font_bold, a.text_center, textStyles, style]}>
|
||||||
{...rest}
|
|
||||||
style={[atoms.font_bold, atoms.text_center, ...textStyles, style]}>
|
|
||||||
{children}
|
{children}
|
||||||
</Text>
|
</Text>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function ButtonIcon({
|
||||||
|
icon: Comp,
|
||||||
|
}: {
|
||||||
|
icon: React.ComponentType<SVGIconProps>
|
||||||
|
}) {
|
||||||
|
const {size} = useButtonContext()
|
||||||
|
const textStyles = useSharedButtonTextStyles()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={[a.z_20]}>
|
||||||
|
<Comp
|
||||||
|
size={size === 'large' ? 'md' : 'sm'}
|
||||||
|
style={[{color: textStyles.color, pointerEvents: 'none'}]}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
+41
-24
@@ -14,8 +14,8 @@ import {
|
|||||||
import {sanitizeUrl} from '@braintree/sanitize-url'
|
import {sanitizeUrl} from '@braintree/sanitize-url'
|
||||||
|
|
||||||
import {isWeb} from '#/platform/detection'
|
import {isWeb} from '#/platform/detection'
|
||||||
import {useTheme, web} from '#/alf'
|
import {useTheme, web, flatten} from '#/alf'
|
||||||
import {Button, ButtonProps} from '#/components/Button'
|
import {Button, ButtonProps, useButtonContext} from '#/components/Button'
|
||||||
import {AllNavigatorParams, NavigationProp} from '#/lib/routes/types'
|
import {AllNavigatorParams, NavigationProp} from '#/lib/routes/types'
|
||||||
import {
|
import {
|
||||||
convertBskyAppUrlIfNeeded,
|
convertBskyAppUrlIfNeeded,
|
||||||
@@ -25,7 +25,10 @@ import {
|
|||||||
import {useModalControls} from '#/state/modals'
|
import {useModalControls} from '#/state/modals'
|
||||||
import {router} from '#/routes'
|
import {router} from '#/routes'
|
||||||
|
|
||||||
export type LinkProps = Omit<ButtonProps, 'style' | 'onPress' | 'disabled'> & {
|
export type LinkProps = Omit<
|
||||||
|
ButtonProps,
|
||||||
|
'style' | 'onPress' | 'disabled' | 'label'
|
||||||
|
> & {
|
||||||
/**
|
/**
|
||||||
* `TextStyle` to apply to the anchor element itself. Does not apply to any children.
|
* `TextStyle` to apply to the anchor element itself. Does not apply to any children.
|
||||||
*/
|
*/
|
||||||
@@ -39,6 +42,7 @@ export type LinkProps = Omit<ButtonProps, 'style' | 'onPress' | 'disabled'> & {
|
|||||||
* works for Links with children that are strings i.e. text links.
|
* works for Links with children that are strings i.e. text links.
|
||||||
*/
|
*/
|
||||||
warnOnMismatchingTextChild?: boolean
|
warnOnMismatchingTextChild?: boolean
|
||||||
|
label?: ButtonProps['label']
|
||||||
} & Pick<Parameters<typeof useLinkProps<AllNavigatorParams>>[0], 'to'>
|
} & Pick<Parameters<typeof useLinkProps<AllNavigatorParams>>[0], 'to'>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,12 +56,11 @@ export type LinkProps = Omit<ButtonProps, 'style' | 'onPress' | 'disabled'> & {
|
|||||||
export function Link({
|
export function Link({
|
||||||
children,
|
children,
|
||||||
to,
|
to,
|
||||||
style,
|
|
||||||
action = 'push',
|
action = 'push',
|
||||||
warnOnMismatchingTextChild,
|
warnOnMismatchingTextChild,
|
||||||
|
style,
|
||||||
...rest
|
...rest
|
||||||
}: LinkProps) {
|
}: LinkProps) {
|
||||||
const t = useTheme()
|
|
||||||
const navigation = useNavigation<NavigationProp>()
|
const navigation = useNavigation<NavigationProp>()
|
||||||
const {href} = useLinkProps<AllNavigatorParams>({
|
const {href} = useLinkProps<AllNavigatorParams>({
|
||||||
to:
|
to:
|
||||||
@@ -67,12 +70,12 @@ export function Link({
|
|||||||
const {openModal, closeModal} = useModalControls()
|
const {openModal, closeModal} = useModalControls()
|
||||||
const onPress = React.useCallback(
|
const onPress = React.useCallback(
|
||||||
(e: GestureResponderEvent) => {
|
(e: GestureResponderEvent) => {
|
||||||
const label = typeof children === 'string' ? children : ''
|
const stringChildren = typeof children === 'string' ? children : ''
|
||||||
const requiresWarning = Boolean(
|
const requiresWarning = Boolean(
|
||||||
warnOnMismatchingTextChild &&
|
warnOnMismatchingTextChild &&
|
||||||
label &&
|
stringChildren &&
|
||||||
isExternal &&
|
isExternal &&
|
||||||
linkRequiresWarning(href, label),
|
linkRequiresWarning(href, stringChildren),
|
||||||
)
|
)
|
||||||
|
|
||||||
if (requiresWarning) {
|
if (requiresWarning) {
|
||||||
@@ -80,7 +83,7 @@ export function Link({
|
|||||||
|
|
||||||
openModal({
|
openModal({
|
||||||
name: 'link-warning',
|
name: 'link-warning',
|
||||||
text: label,
|
text: stringChildren,
|
||||||
href: href,
|
href: href,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@@ -139,6 +142,7 @@ export function Link({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
|
label={href}
|
||||||
{...rest}
|
{...rest}
|
||||||
role="link"
|
role="link"
|
||||||
accessibilityRole="link"
|
accessibilityRole="link"
|
||||||
@@ -154,21 +158,34 @@ export function Link({
|
|||||||
noUnderline: '1',
|
noUnderline: '1',
|
||||||
},
|
},
|
||||||
})}>
|
})}>
|
||||||
{typeof children === 'string'
|
{typeof children === 'string' ? (
|
||||||
? ({state}) => (
|
<LinkText style={style}>{children}</LinkText>
|
||||||
<Text
|
) : (
|
||||||
style={[
|
children
|
||||||
style,
|
)}
|
||||||
{color: t.palette.primary_500},
|
|
||||||
state.hovered && {
|
|
||||||
textDecorationLine: 'underline',
|
|
||||||
textDecorationColor: t.palette.primary_500,
|
|
||||||
},
|
|
||||||
]}>
|
|
||||||
{children as string}
|
|
||||||
</Text>
|
|
||||||
)
|
|
||||||
: children}
|
|
||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function LinkText({
|
||||||
|
children,
|
||||||
|
style,
|
||||||
|
}: React.PropsWithChildren<{
|
||||||
|
style?: StyleProp<TextStyle>
|
||||||
|
}>) {
|
||||||
|
const t = useTheme()
|
||||||
|
const {hovered} = useButtonContext()
|
||||||
|
return (
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
{color: t.palette.primary_500},
|
||||||
|
hovered && {
|
||||||
|
textDecorationLine: 'underline',
|
||||||
|
textDecorationColor: t.palette.primary_500,
|
||||||
|
},
|
||||||
|
flatten(style),
|
||||||
|
]}>
|
||||||
|
{children as string}
|
||||||
|
</Text>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,8 +2,16 @@ import React from 'react'
|
|||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
|
|
||||||
import {atoms as a} from '#/alf'
|
import {atoms as a} from '#/alf'
|
||||||
import {Button, ButtonVariant, ButtonColor} from '#/components/Button'
|
import {
|
||||||
|
Button,
|
||||||
|
ButtonVariant,
|
||||||
|
ButtonColor,
|
||||||
|
ButtonIcon,
|
||||||
|
ButtonText,
|
||||||
|
} from '#/components/Button'
|
||||||
import {H1} from '#/components/Typography'
|
import {H1} from '#/components/Typography'
|
||||||
|
import {ArrowTopRight_Stroke2_Corner0_Rounded as ArrowTopRight} from '#/components/icons/ArrowTopRight'
|
||||||
|
import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe'
|
||||||
|
|
||||||
export function Buttons() {
|
export function Buttons() {
|
||||||
return (
|
return (
|
||||||
@@ -83,6 +91,33 @@ export function Buttons() {
|
|||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant="gradient"
|
||||||
|
color="gradient_sky"
|
||||||
|
size="large"
|
||||||
|
label="Link out">
|
||||||
|
<ButtonText>Link out</ButtonText>
|
||||||
|
<ButtonIcon icon={ArrowTopRight} />
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant="gradient"
|
||||||
|
color="gradient_sky"
|
||||||
|
size="small"
|
||||||
|
label="Link out">
|
||||||
|
<ButtonText>Link out</ButtonText>
|
||||||
|
<ButtonIcon icon={ArrowTopRight} />
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant="gradient"
|
||||||
|
color="gradient_sky"
|
||||||
|
size="small"
|
||||||
|
label="Link out">
|
||||||
|
<ButtonIcon icon={Globe} />
|
||||||
|
<ButtonText>See the world</ButtonText>
|
||||||
|
</Button>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -13,27 +13,21 @@ export function Links() {
|
|||||||
|
|
||||||
<View style={[a.gap_md, a.align_start]}>
|
<View style={[a.gap_md, a.align_start]}>
|
||||||
<Link
|
<Link
|
||||||
label="Click here"
|
|
||||||
to="https://blueskyweb.xyz"
|
to="https://blueskyweb.xyz"
|
||||||
warnOnMismatchingTextChild
|
warnOnMismatchingTextChild
|
||||||
style={[a.text_md]}>
|
style={[a.text_md]}>
|
||||||
External
|
External
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link to="https://blueskyweb.xyz" style={[a.text_md]}>
|
||||||
label="Click here"
|
|
||||||
to="https://blueskyweb.xyz"
|
|
||||||
style={[a.text_md]}>
|
|
||||||
<H3>External with custom children</H3>
|
<H3>External with custom children</H3>
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
label="Click here"
|
|
||||||
to="https://blueskyweb.xyz"
|
to="https://blueskyweb.xyz"
|
||||||
warnOnMismatchingTextChild
|
warnOnMismatchingTextChild
|
||||||
style={[a.text_md]}>
|
style={[a.text_lg]}>
|
||||||
https://blueskyweb.xyz
|
https://blueskyweb.xyz
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
label="Click here"
|
|
||||||
to="https://bsky.app/profile/bsky.app"
|
to="https://bsky.app/profile/bsky.app"
|
||||||
warnOnMismatchingTextChild
|
warnOnMismatchingTextChild
|
||||||
style={[a.text_md]}>
|
style={[a.text_md]}>
|
||||||
@@ -41,12 +35,12 @@ export function Links() {
|
|||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
label="Click here"
|
|
||||||
variant="solid"
|
variant="solid"
|
||||||
color="primary"
|
color="primary"
|
||||||
size="large"
|
size="large"
|
||||||
|
label="View @bsky.app's profile"
|
||||||
to="https://bsky.app/profile/bsky.app">
|
to="https://bsky.app/profile/bsky.app">
|
||||||
{({props}) => <ButtonText {...props}>Link as a button</ButtonText>}
|
<ButtonText>Link as a button</ButtonText>
|
||||||
</Link>
|
</Link>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
Reference in New Issue
Block a user