Enforce Text suffix for Text-rendering components (#3407)

* Rm unused

* Add Text suffix to Title/Description

* Add Text suffix to text components

* Add Text suffix to props

* Validate Text components returns
This commit is contained in:
dan 2024-04-04 21:34:55 +01:00 committed by GitHub
parent c190fd58ec
commit 3915bb4316
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
43 changed files with 453 additions and 366 deletions

View file

@ -1,51 +1,51 @@
import React from 'react'
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
import {View} from 'react-native'
import {
AppBskyActorDefs,
AppBskyFeedDefs,
AppBskyFeedPost,
ComAtprotoLabelDefs,
interpretLabelValueDefinition,
LabelPreference,
LABELS,
mock,
moderatePost,
moderateProfile,
ModerationOpts,
AppBskyActorDefs,
AppBskyFeedDefs,
AppBskyFeedPost,
LabelPreference,
ModerationDecision,
ModerationBehavior,
ModerationDecision,
ModerationOpts,
RichText,
ComAtprotoLabelDefs,
interpretLabelValueDefinition,
} from '@atproto/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {moderationOptsOverrideContext} from '#/state/queries/preferences'
import {useSession} from '#/state/session'
import {useGlobalLabelStrings} from '#/lib/moderation/useGlobalLabelStrings'
import {FeedNotification} from '#/state/queries/notifications/types'
import {
groupNotifications,
shouldFilterNotif,
} from '#/state/queries/notifications/util'
import {atoms as a, useTheme} from '#/alf'
import {moderationOptsOverrideContext} from '#/state/queries/preferences'
import {useSession} from '#/state/session'
import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
import {CenteredView, ScrollView} from '#/view/com/util/Views'
import {H1, H3, P, Text} from '#/components/Typography'
import {useGlobalLabelStrings} from '#/lib/moderation/useGlobalLabelStrings'
import {ProfileHeaderStandard} from '#/screens/Profile/Header/ProfileHeaderStandard'
import {atoms as a, useTheme} from '#/alf'
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import {Divider} from '#/components/Divider'
import * as Toggle from '#/components/forms/Toggle'
import * as ToggleButton from '#/components/forms/ToggleButton'
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check'
import {
ChevronBottom_Stroke2_Corner0_Rounded as ChevronBottom,
ChevronTop_Stroke2_Corner0_Rounded as ChevronTop,
} from '#/components/icons/Chevron'
import {H1, H3, P, Text} from '#/components/Typography'
import {ScreenHider} from '../../components/moderation/ScreenHider'
import {ProfileHeaderStandard} from '#/screens/Profile/Header/ProfileHeaderStandard'
import {ProfileCard} from '../com/profile/ProfileCard'
import {FeedItem} from '../com/posts/FeedItem'
import {FeedItem as NotifFeedItem} from '../com/notifications/FeedItem'
import {PostThreadItem} from '../com/post-thread/PostThreadItem'
import {Divider} from '#/components/Divider'
import {FeedItem} from '../com/posts/FeedItem'
import {ProfileCard} from '../com/profile/ProfileCard'
const LABEL_VALUES: (keyof typeof LABELS)[] = Object.keys(
LABELS,
@ -320,7 +320,7 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
disabled={disabled}
style={disabled ? {opacity: 0.5} : undefined}>
<Toggle.Radio />
<Toggle.Label>{labelValue}</Toggle.Label>
<Toggle.LabelText>{labelValue}</Toggle.LabelText>
</Toggle.Item>
)
})}
@ -330,7 +330,7 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
disabled={isSelfLabel}
style={isSelfLabel ? {opacity: 0.5} : undefined}>
<Toggle.Radio />
<Toggle.Label>Custom label</Toggle.Label>
<Toggle.LabelText>Custom label</Toggle.LabelText>
</Toggle.Item>
</View>
</Toggle.Group>
@ -358,23 +358,23 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
<View style={[a.gap_md, a.flex_row, a.flex_wrap, a.pt_md]}>
<Toggle.Item name="targetMe" label="Target is me">
<Toggle.Checkbox />
<Toggle.Label>Target is me</Toggle.Label>
<Toggle.LabelText>Target is me</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="following" label="Following target">
<Toggle.Checkbox />
<Toggle.Label>Following target</Toggle.Label>
<Toggle.LabelText>Following target</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="selfLabel" label="Self label">
<Toggle.Checkbox />
<Toggle.Label>Self label</Toggle.Label>
<Toggle.LabelText>Self label</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="noAdult" label="Adult disabled">
<Toggle.Checkbox />
<Toggle.Label>Adult disabled</Toggle.Label>
<Toggle.LabelText>Adult disabled</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="loggedOut" label="Logged out">
<Toggle.Checkbox />
<Toggle.Label>Logged out</Toggle.Label>
<Toggle.LabelText>Logged out</Toggle.LabelText>
</Toggle.Item>
</View>
</Toggle.Group>
@ -400,15 +400,15 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
]}>
<Toggle.Item name="hide" label="Hide">
<Toggle.Radio />
<Toggle.Label>Hide</Toggle.Label>
<Toggle.LabelText>Hide</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="warn" label="Warn">
<Toggle.Radio />
<Toggle.Label>Warn</Toggle.Label>
<Toggle.LabelText>Warn</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="ignore" label="Ignore">
<Toggle.Radio />
<Toggle.Label>Ignore</Toggle.Label>
<Toggle.LabelText>Ignore</Toggle.LabelText>
</Toggle.Item>
</View>
</Toggle.Group>
@ -446,19 +446,19 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
<View style={[a.flex_row, a.gap_md, a.flex_wrap]}>
<Toggle.Item name="account" label="Account">
<Toggle.Radio />
<Toggle.Label>Account</Toggle.Label>
<Toggle.LabelText>Account</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="profile" label="Profile">
<Toggle.Radio />
<Toggle.Label>Profile</Toggle.Label>
<Toggle.LabelText>Profile</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="post" label="Post">
<Toggle.Radio />
<Toggle.Label>Post</Toggle.Label>
<Toggle.LabelText>Post</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="embed" label="Embed">
<Toggle.Radio />
<Toggle.Label>Embed</Toggle.Label>
<Toggle.LabelText>Embed</Toggle.LabelText>
</Toggle.Item>
</View>
</Toggle.Group>
@ -623,15 +623,15 @@ function CustomLabelForm({
<View style={[a.flex_row, a.gap_md, a.flex_wrap]}>
<Toggle.Item name="content" label="Content">
<Toggle.Radio />
<Toggle.Label>Content</Toggle.Label>
<Toggle.LabelText>Content</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="media" label="Media">
<Toggle.Radio />
<Toggle.Label>Media</Toggle.Label>
<Toggle.LabelText>Media</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="none" label="None">
<Toggle.Radio />
<Toggle.Label>None</Toggle.Label>
<Toggle.LabelText>None</Toggle.LabelText>
</Toggle.Item>
</View>
</Toggle.Group>
@ -658,15 +658,15 @@ function CustomLabelForm({
<View style={[a.flex_row, a.gap_md, a.flex_wrap, a.align_center]}>
<Toggle.Item name="alert" label="Alert">
<Toggle.Radio />
<Toggle.Label>Alert</Toggle.Label>
<Toggle.LabelText>Alert</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="inform" label="Inform">
<Toggle.Radio />
<Toggle.Label>Inform</Toggle.Label>
<Toggle.LabelText>Inform</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="none" label="None">
<Toggle.Radio />
<Toggle.Label>None</Toggle.Label>
<Toggle.LabelText>None</Toggle.LabelText>
</Toggle.Item>
</View>
</Toggle.Group>

View file

@ -1,70 +1,71 @@
import React, {useMemo, useCallback} from 'react'
import {StyleSheet, View, Pressable} from 'react-native'
import {NativeStackScreenProps} from '@react-navigation/native-stack'
import {useIsFocused, useNavigation} from '@react-navigation/native'
import {useQueryClient} from '@tanstack/react-query'
import {usePalette} from 'lib/hooks/usePalette'
import {CommonNavigatorParams} from 'lib/routes/types'
import {makeRecordUri} from 'lib/strings/url-helpers'
import {s} from 'lib/styles'
import {FeedDescriptor} from '#/state/queries/post-feed'
import {PagerWithHeader} from 'view/com/pager/PagerWithHeader'
import {ProfileSubpageHeader} from 'view/com/profile/ProfileSubpageHeader'
import {Feed} from 'view/com/posts/Feed'
import {InlineLink} from '#/components/Link'
import {ListRef} from 'view/com/util/List'
import {Button} from 'view/com/util/forms/Button'
import {Text} from 'view/com/util/text/Text'
import {RichText} from '#/components/RichText'
import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn'
import {FAB} from 'view/com/util/fab/FAB'
import {EmptyState} from 'view/com/util/EmptyState'
import {LoadingScreen} from 'view/com/util/LoadingScreen'
import * as Toast from 'view/com/util/Toast'
import {useSetTitle} from 'lib/hooks/useSetTitle'
import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
import {shareUrl} from 'lib/sharing'
import {toShareUrl} from 'lib/strings/url-helpers'
import {Haptics} from 'lib/haptics'
import {useAnalytics} from 'lib/analytics/analytics'
import {makeCustomFeedLink} from 'lib/routes/links'
import {pluralize} from 'lib/strings/helpers'
import {CenteredView} from 'view/com/util/Views'
import {NavigationProp} from 'lib/routes/types'
import {ComposeIcon2} from 'lib/icons'
import {logger} from '#/logger'
import {Trans, msg} from '@lingui/macro'
import React, {useCallback, useMemo} from 'react'
import {Pressable, StyleSheet, View} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog'
import {useFeedSourceInfoQuery, FeedSourceFeedInfo} from '#/state/queries/feed'
import {useResolveUriQuery} from '#/state/queries/resolve-uri'
import {
UsePreferencesQueryResponse,
usePreferencesQuery,
useSaveFeedMutation,
useRemoveFeedMutation,
usePinFeedMutation,
useUnpinFeedMutation,
} from '#/state/queries/preferences'
import {useSession} from '#/state/session'
import {useLikeMutation, useUnlikeMutation} from '#/state/queries/like'
import {useComposerControls} from '#/state/shell/composer'
import {truncateAndInvalidate} from '#/state/queries/util'
import {useIsFocused, useNavigation} from '@react-navigation/native'
import {NativeStackScreenProps} from '@react-navigation/native-stack'
import {useQueryClient} from '@tanstack/react-query'
import {HITSLOP_20} from '#/lib/constants'
import {logger} from '#/logger'
import {isNative} from '#/platform/detection'
import {listenSoftReset} from '#/state/events'
import {atoms as a, useTheme} from '#/alf'
import * as Menu from '#/components/Menu'
import {HITSLOP_20} from '#/lib/constants'
import {DotGrid_Stroke2_Corner0_Rounded as Ellipsis} from '#/components/icons/DotGrid'
import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash'
import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
import {ArrowOutOfBox_Stroke2_Corner0_Rounded as Share} from '#/components/icons/ArrowOutOfBox'
import {FeedSourceFeedInfo, useFeedSourceInfoQuery} from '#/state/queries/feed'
import {useLikeMutation, useUnlikeMutation} from '#/state/queries/like'
import {FeedDescriptor} from '#/state/queries/post-feed'
import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
import {
Heart2_Stroke2_Corner0_Rounded as HeartOutline,
Heart2_Filled_Stroke2_Corner0_Rounded as HeartFilled,
} from '#/components/icons/Heart2'
usePinFeedMutation,
usePreferencesQuery,
UsePreferencesQueryResponse,
useRemoveFeedMutation,
useSaveFeedMutation,
useUnpinFeedMutation,
} from '#/state/queries/preferences'
import {useResolveUriQuery} from '#/state/queries/resolve-uri'
import {truncateAndInvalidate} from '#/state/queries/util'
import {useSession} from '#/state/session'
import {useComposerControls} from '#/state/shell/composer'
import {useAnalytics} from 'lib/analytics/analytics'
import {Haptics} from 'lib/haptics'
import {usePalette} from 'lib/hooks/usePalette'
import {useSetTitle} from 'lib/hooks/useSetTitle'
import {ComposeIcon2} from 'lib/icons'
import {makeCustomFeedLink} from 'lib/routes/links'
import {CommonNavigatorParams} from 'lib/routes/types'
import {NavigationProp} from 'lib/routes/types'
import {shareUrl} from 'lib/sharing'
import {pluralize} from 'lib/strings/helpers'
import {makeRecordUri} from 'lib/strings/url-helpers'
import {toShareUrl} from 'lib/strings/url-helpers'
import {s} from 'lib/styles'
import {PagerWithHeader} from 'view/com/pager/PagerWithHeader'
import {Feed} from 'view/com/posts/Feed'
import {ProfileSubpageHeader} from 'view/com/profile/ProfileSubpageHeader'
import {EmptyState} from 'view/com/util/EmptyState'
import {FAB} from 'view/com/util/fab/FAB'
import {Button} from 'view/com/util/forms/Button'
import {ListRef} from 'view/com/util/List'
import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn'
import {LoadingScreen} from 'view/com/util/LoadingScreen'
import {Text} from 'view/com/util/text/Text'
import * as Toast from 'view/com/util/Toast'
import {CenteredView} from 'view/com/util/Views'
import {atoms as a, useTheme} from '#/alf'
import {Button as NewButton, ButtonText} from '#/components/Button'
import {ArrowOutOfBox_Stroke2_Corner0_Rounded as Share} from '#/components/icons/ArrowOutOfBox'
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
import {DotGrid_Stroke2_Corner0_Rounded as Ellipsis} from '#/components/icons/DotGrid'
import {
Heart2_Filled_Stroke2_Corner0_Rounded as HeartFilled,
Heart2_Stroke2_Corner0_Rounded as HeartOutline,
} from '#/components/icons/Heart2'
import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash'
import {InlineLinkText} from '#/components/Link'
import * as Menu from '#/components/Menu'
import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog'
import {RichText} from '#/components/RichText'
const SECTION_TITLES = ['Posts']
@ -580,12 +581,12 @@ function AboutSection({
)}
</NewButton>
{typeof likeCount === 'number' && (
<InlineLink
<InlineLinkText
label={_(msg`View users who like this feed`)}
to={makeCustomFeedLink(feedOwnerDid, feedRkey, 'liked-by')}
style={[t.atoms.text_contrast_medium, a.font_bold]}>
{_(msg`Liked by ${likeCount} ${pluralize(likeCount, 'user')}`)}
</InlineLink>
</InlineLinkText>
)}
</View>
</View>

View file

@ -1,14 +1,14 @@
import React from 'react'
import {View} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {Trans, msg} from '@lingui/macro'
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
import * as Dialog from '#/components/Dialog'
import {Text, P} from '#/components/Typography'
import {Button, ButtonText} from '#/components/Button'
import {InlineLink, Link} from '#/components/Link'
import {getAgent, useSession} from '#/state/session'
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
import {Button, ButtonText} from '#/components/Button'
import * as Dialog from '#/components/Dialog'
import {InlineLinkText, Link} from '#/components/Link'
import {P, Text} from '#/components/Typography'
export function ExportCarDialog({
control,
@ -75,11 +75,11 @@ export function ExportCarDialog({
<Trans>
This feature is in beta. You can read more about repository
exports in{' '}
<InlineLink
<InlineLinkText
to="https://docs.bsky.app/blog/repo-export"
style={[a.text_sm]}>
this blogpost
</InlineLink>
</InlineLinkText>
.
</Trans>
</P>

View file

@ -1,12 +1,12 @@
import React from 'react'
import {View} from 'react-native'
import {useDialogStateControlContext} from '#/state/dialogs'
import {atoms as a} from '#/alf'
import {Button} from '#/components/Button'
import {H3, P} from '#/components/Typography'
import * as Dialog from '#/components/Dialog'
import * as Prompt from '#/components/Prompt'
import {useDialogStateControlContext} from '#/state/dialogs'
import {H3, P} from '#/components/Typography'
export function Dialogs() {
const scrollable = Dialog.useDialogControl()
@ -61,11 +61,11 @@ export function Dialogs() {
</Button>
<Prompt.Outer control={prompt}>
<Prompt.Title>This is a prompt</Prompt.Title>
<Prompt.Description>
<Prompt.TitleText>This is a prompt</Prompt.TitleText>
<Prompt.DescriptionText>
This is a generic prompt component. It accepts a title and a
description, as well as two actions.
</Prompt.Description>
</Prompt.DescriptionText>
<Prompt.Actions>
<Prompt.Cancel>Cancel</Prompt.Cancel>
<Prompt.Action onPress={() => {}}>Confirm</Prompt.Action>

View file

@ -2,13 +2,13 @@ import React from 'react'
import {View} from 'react-native'
import {atoms as a} from '#/alf'
import {H1, H3} from '#/components/Typography'
import {Button} from '#/components/Button'
import {DateField, LabelText} from '#/components/forms/DateField'
import * as TextField from '#/components/forms/TextField'
import {DateField, Label} from '#/components/forms/DateField'
import * as Toggle from '#/components/forms/Toggle'
import * as ToggleButton from '#/components/forms/ToggleButton'
import {Button} from '#/components/Button'
import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe'
import {H1, H3} from '#/components/Typography'
export function Forms() {
const [toggleGroupAValues, setToggleGroupAValues] = React.useState(['a'])
@ -42,7 +42,7 @@ export function Forms() {
</TextField.Root>
<View style={[a.w_full]}>
<TextField.Label>Text field</TextField.Label>
<TextField.LabelText>Text field</TextField.LabelText>
<TextField.Root>
<TextField.Icon icon={Globe} />
<TextField.Input
@ -50,12 +50,14 @@ export function Forms() {
onChangeText={setValue}
label="Text field"
/>
<TextField.Suffix label="@gmail.com">@gmail.com</TextField.Suffix>
<TextField.SuffixText label="@gmail.com">
@gmail.com
</TextField.SuffixText>
</TextField.Root>
</View>
<View style={[a.w_full]}>
<TextField.Label>Textarea</TextField.Label>
<TextField.LabelText>Textarea</TextField.LabelText>
<TextField.Input
multiline
numberOfLines={4}
@ -68,7 +70,7 @@ export function Forms() {
<H3>DateField</H3>
<View style={[a.w_full]}>
<Label>Date</Label>
<LabelText>Date</LabelText>
<DateField
testID="date"
value={date}
@ -86,7 +88,7 @@ export function Forms() {
<Toggle.Item name="a" label="Click me">
<Toggle.Checkbox />
<Toggle.Label>Uncontrolled toggle</Toggle.Label>
<Toggle.LabelText>Uncontrolled toggle</Toggle.LabelText>
</Toggle.Item>
<Toggle.Group
@ -98,23 +100,23 @@ export function Forms() {
<View style={[a.gap_md]}>
<Toggle.Item name="a" label="Click me">
<Toggle.Switch />
<Toggle.Label>Click me</Toggle.Label>
<Toggle.LabelText>Click me</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="b" label="Click me">
<Toggle.Switch />
<Toggle.Label>Click me</Toggle.Label>
<Toggle.LabelText>Click me</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="c" label="Click me">
<Toggle.Switch />
<Toggle.Label>Click me</Toggle.Label>
<Toggle.LabelText>Click me</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="d" disabled label="Click me">
<Toggle.Switch />
<Toggle.Label>Click me</Toggle.Label>
<Toggle.LabelText>Click me</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="e" isInvalid label="Click me">
<Toggle.Switch />
<Toggle.Label>Click me</Toggle.Label>
<Toggle.LabelText>Click me</Toggle.LabelText>
</Toggle.Item>
</View>
</Toggle.Group>
@ -128,23 +130,23 @@ export function Forms() {
<View style={[a.gap_md]}>
<Toggle.Item name="a" label="Click me">
<Toggle.Checkbox />
<Toggle.Label>Click me</Toggle.Label>
<Toggle.LabelText>Click me</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="b" label="Click me">
<Toggle.Checkbox />
<Toggle.Label>Click me</Toggle.Label>
<Toggle.LabelText>Click me</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="c" label="Click me">
<Toggle.Checkbox />
<Toggle.Label>Click me</Toggle.Label>
<Toggle.LabelText>Click me</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="d" disabled label="Click me">
<Toggle.Checkbox />
<Toggle.Label>Click me</Toggle.Label>
<Toggle.LabelText>Click me</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="e" isInvalid label="Click me">
<Toggle.Checkbox />
<Toggle.Label>Click me</Toggle.Label>
<Toggle.LabelText>Click me</Toggle.LabelText>
</Toggle.Item>
</View>
</Toggle.Group>
@ -157,23 +159,23 @@ export function Forms() {
<View style={[a.gap_md]}>
<Toggle.Item name="a" label="Click me">
<Toggle.Radio />
<Toggle.Label>Click me</Toggle.Label>
<Toggle.LabelText>Click me</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="b" label="Click me">
<Toggle.Radio />
<Toggle.Label>Click me</Toggle.Label>
<Toggle.LabelText>Click me</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="c" label="Click me">
<Toggle.Radio />
<Toggle.Label>Click me</Toggle.Label>
<Toggle.LabelText>Click me</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="d" disabled label="Click me">
<Toggle.Radio />
<Toggle.Label>Click me</Toggle.Label>
<Toggle.LabelText>Click me</Toggle.LabelText>
</Toggle.Item>
<Toggle.Item name="e" isInvalid label="Click me">
<Toggle.Radio />
<Toggle.Label>Click me</Toggle.Label>
<Toggle.LabelText>Click me</Toggle.LabelText>
</Toggle.Item>
</View>
</Toggle.Group>

View file

@ -1,9 +1,9 @@
import React from 'react'
import {View} from 'react-native'
import {useTheme, atoms as a} from '#/alf'
import {atoms as a, useTheme} from '#/alf'
import {ButtonText} from '#/components/Button'
import {InlineLink, Link} from '#/components/Link'
import {InlineLinkText, Link} from '#/components/Link'
import {H1, Text} from '#/components/Typography'
export function Links() {
@ -13,20 +13,22 @@ export function Links() {
<H1>Links</H1>
<View style={[a.gap_md, a.align_start]}>
<InlineLink to="https://google.com" style={[a.text_lg]}>
<InlineLinkText to="https://google.com" style={[a.text_lg]}>
https://google.com
</InlineLink>
<InlineLink to="https://google.com" style={[a.text_lg]}>
</InlineLinkText>
<InlineLinkText to="https://google.com" style={[a.text_lg]}>
External with custom children (google.com)
</InlineLink>
<InlineLink
</InlineLinkText>
<InlineLinkText
to="https://bsky.social"
style={[a.text_md, t.atoms.text_contrast_low]}>
Internal (bsky.social)
</InlineLink>
<InlineLink to="https://bsky.app/profile/bsky.app" style={[a.text_md]}>
</InlineLinkText>
<InlineLinkText
to="https://bsky.app/profile/bsky.app"
style={[a.text_md]}>
Internal (bsky.app)
</InlineLink>
</InlineLinkText>
<Link
variant="solid"