diff options
author | dan <dan.abramov@gmail.com> | 2024-04-04 21:34:55 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-04 21:34:55 +0100 |
commit | 3915bb43169ae501d81571c5e1efa12cf0e24dbb (patch) | |
tree | be2f7bed7c842be71922f2793b4b4a20cd6fbc24 | |
parent | c190fd58ec82b36ea8124902cad34acc4a5b5ac0 (diff) | |
download | voidsky-3915bb43169ae501d81571c5e1efa12cf0e24dbb.tar.zst |
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
43 files changed, 430 insertions, 343 deletions
diff --git a/.eslintrc.js b/.eslintrc.js index 8ae91f346..92834fe68 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,5 +1,3 @@ -const bskyEslint = require('./eslint') - module.exports = { root: true, extends: [ @@ -27,29 +25,18 @@ module.exports = { { impliedTextComponents: [ 'Button', // TODO: Not always safe. - 'ButtonText', - 'DateField.Label', - 'Description', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', - 'InlineLink', - 'Label', 'P', - 'Prompt.Title', - 'Prompt.Description', 'Prompt.Cancel', // TODO: Not always safe. 'Prompt.Action', // TODO: Not always safe. - 'TextField.Label', - 'TextField.Suffix', - 'Title', - 'Toggle.Label', 'ToggleButton.Button', // TODO: Not always safe. ], - impliedTextProps: ['FormContainer title'], + impliedTextProps: [], }, ], 'simple-import-sort/imports': [ diff --git a/eslint/__tests__/avoid-unwrapped-text.test.js b/eslint/__tests__/avoid-unwrapped-text.test.js index 0fbc01123..7c667b4a8 100644 --- a/eslint/__tests__/avoid-unwrapped-text.test.js +++ b/eslint/__tests__/avoid-unwrapped-text.test.js @@ -246,6 +246,41 @@ describe('avoid-unwrapped-text', () => { </Foo> `, }, + + { + code: ` +function Stuff() { + return <Text>foo</Text> +} + `, + }, + + { + code: ` +function Stuff({ foo }) { + return <View>{foo}</View> +} + `, + }, + + { + code: ` +function MyText() { + return <Text>foo</Text> +} + `, + }, + + { + code: ` +function MyText({ foo }) { + if (foo) { + return <Text>foo</Text> + } + return <Text>foo</Text> +} + `, + }, ], invalid: [ @@ -390,6 +425,36 @@ describe('avoid-unwrapped-text', () => { `, errors: 1, }, + + { + code: ` +function MyText() { + return <Foo /> +} + `, + errors: 1, + }, + + { + code: ` +function MyText({ foo }) { + return <Foo>{foo}</Foo> +} + `, + errors: 1, + }, + + { + code: ` +function MyText({ foo }) { + if (foo) { + return <Foo>{foo}</Foo> + } + return <Text>foo</Text> +} + `, + errors: 1, + }, ], } diff --git a/eslint/avoid-unwrapped-text.js b/eslint/avoid-unwrapped-text.js index c9e72386e..79d099f00 100644 --- a/eslint/avoid-unwrapped-text.js +++ b/eslint/avoid-unwrapped-text.js @@ -35,6 +35,11 @@ exports.create = function create(context) { const impliedTextComponents = options.impliedTextComponents ?? [] const textProps = [...impliedTextProps] const textComponents = ['Text', ...impliedTextComponents] + + function isTextComponent(tagName) { + return textComponents.includes(tagName) || tagName.endsWith('Text') + } + return { JSXText(node) { if (typeof node.value !== 'string' || hasOnlyLineBreak(node.value)) { @@ -44,7 +49,7 @@ exports.create = function create(context) { while (parent) { if (parent.type === 'JSXElement') { const tagName = getTagName(parent) - if (textComponents.includes(tagName) || tagName.endsWith('Text')) { + if (isTextComponent(tagName)) { // We're good. return } @@ -107,5 +112,36 @@ exports.create = function create(context) { continue } }, + ReturnStatement(node) { + let fnScope = context.getScope() + while (fnScope && fnScope.type !== 'function') { + fnScope = fnScope.upper + } + if (!fnScope) { + return + } + const fn = fnScope.block + if (!fn.id || fn.id.type !== 'Identifier' || !fn.id.name) { + return + } + if (!/^[A-Z]\w*Text$/.test(fn.id.name)) { + return + } + if (!node.argument || node.argument.type !== 'JSXElement') { + return + } + const openingEl = node.argument.openingElement + if (openingEl.name.type !== 'JSXIdentifier') { + return + } + const returnedComponentName = openingEl.name.name + if (!isTextComponent(returnedComponentName)) { + context.report({ + node, + message: + 'Components ending with *Text must return <Text> or <SomeText>.', + }) + } + }, } } diff --git a/src/components/Link.tsx b/src/components/Link.tsx index 1a494626f..65a015ba3 100644 --- a/src/components/Link.tsx +++ b/src/components/Link.tsx @@ -250,7 +250,7 @@ export type InlineLinkProps = React.PropsWithChildren< BaseLinkProps & TextStyleProp & Pick<TextProps, 'selectable'> > -export function InlineLink({ +export function InlineLinkText({ children, to, action = 'push', diff --git a/src/components/Prompt.tsx b/src/components/Prompt.tsx index 37d1b700a..000d2a3cd 100644 --- a/src/components/Prompt.tsx +++ b/src/components/Prompt.tsx @@ -51,7 +51,7 @@ export function Outer({ ) } -export function Title({children}: React.PropsWithChildren<{}>) { +export function TitleText({children}: React.PropsWithChildren<{}>) { const {titleId} = React.useContext(Context) return ( <Text nativeID={titleId} style={[a.text_2xl, a.font_bold, a.pb_sm]}> @@ -60,7 +60,7 @@ export function Title({children}: React.PropsWithChildren<{}>) { ) } -export function Description({children}: React.PropsWithChildren<{}>) { +export function DescriptionText({children}: React.PropsWithChildren<{}>) { const t = useTheme() const {descriptionId} = React.useContext(Context) return ( @@ -175,8 +175,8 @@ export function Basic({ }>) { return ( <Outer control={control} testID="confirmModal"> - <Title>{title}</Title> - <Description>{description}</Description> + <TitleText>{title}</TitleText> + <DescriptionText>{description}</DescriptionText> <Actions> <Action cta={confirmButtonCta} diff --git a/src/components/RichText.tsx b/src/components/RichText.tsx index 0e89e13b7..5cfa0b24f 100644 --- a/src/components/RichText.tsx +++ b/src/components/RichText.tsx @@ -7,7 +7,7 @@ import {toShortUrl} from '#/lib/strings/url-helpers' import {isNative} from '#/platform/detection' import {atoms as a, flatten, native, TextStyleProp, useTheme, web} from '#/alf' import {useInteractionState} from '#/components/hooks/useInteractionState' -import {InlineLink} from '#/components/Link' +import {InlineLinkText} from '#/components/Link' import {TagMenu, useTagMenuControl} from '#/components/TagMenu' import {Text, TextProps} from '#/components/Typography' @@ -84,7 +84,7 @@ export function RichText({ !disableLinks ) { els.push( - <InlineLink + <InlineLinkText selectable={selectable} key={key} to={`/profile/${mention.did}`} @@ -92,14 +92,14 @@ export function RichText({ // @ts-ignore TODO dataSet={WORD_WRAP}> {segment.text} - </InlineLink>, + </InlineLinkText>, ) } else if (link && AppBskyRichtextFacet.validateLink(link).success) { if (disableLinks) { els.push(toShortUrl(segment.text)) } else { els.push( - <InlineLink + <InlineLinkText selectable={selectable} key={key} to={link.uri} @@ -108,7 +108,7 @@ export function RichText({ dataSet={WORD_WRAP} shareOnLongPress> {toShortUrl(segment.text)} - </InlineLink>, + </InlineLinkText>, ) } } else if ( diff --git a/src/components/dialogs/MutedWords.tsx b/src/components/dialogs/MutedWords.tsx index 46f319adf..0eced11e3 100644 --- a/src/components/dialogs/MutedWords.tsx +++ b/src/components/dialogs/MutedWords.tsx @@ -1,37 +1,36 @@ import React from 'react' import {Keyboard, View} from 'react-native' +import {AppBskyActorDefs, sanitizeMutedWordValue} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {AppBskyActorDefs, sanitizeMutedWordValue} from '@atproto/api' +import {logger} from '#/logger' +import {isNative} from '#/platform/detection' import { usePreferencesQuery, - useUpsertMutedWordsMutation, useRemoveMutedWordMutation, + useUpsertMutedWordsMutation, } from '#/state/queries/preferences' -import {isNative} from '#/platform/detection' import { atoms as a, - useTheme, + native, useBreakpoints, + useTheme, ViewStyleProp, web, - native, } from '#/alf' -import {Text} from '#/components/Typography' import {Button, ButtonIcon, ButtonText} from '#/components/Button' -import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' -import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times' +import * as Dialog from '#/components/Dialog' +import {useGlobalDialogsControlContext} from '#/components/dialogs/Context' +import {Divider} from '#/components/Divider' +import * as Toggle from '#/components/forms/Toggle' import {Hashtag_Stroke2_Corner0_Rounded as Hashtag} from '#/components/icons/Hashtag' import {PageText_Stroke2_Corner0_Rounded as PageText} from '#/components/icons/PageText' -import {Divider} from '#/components/Divider' +import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' +import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times' import {Loader} from '#/components/Loader' -import {logger} from '#/logger' -import * as Dialog from '#/components/Dialog' -import * as Toggle from '#/components/forms/Toggle' import * as Prompt from '#/components/Prompt' - -import {useGlobalDialogsControlContext} from '#/components/dialogs/Context' +import {Text} from '#/components/Typography' export function MutedWordsDialog() { const {mutedWordsDialogControl: control} = useGlobalDialogsControlContext() @@ -130,9 +129,9 @@ function MutedWordsInner({}: {control: Dialog.DialogOuterProps['control']}) { <TargetToggle> <View style={[a.flex_row, a.align_center, a.gap_sm]}> <Toggle.Radio /> - <Toggle.Label> + <Toggle.LabelText> <Trans>Mute in text & tags</Trans> - </Toggle.Label> + </Toggle.LabelText> </View> <PageText size="sm" /> </TargetToggle> @@ -145,9 +144,9 @@ function MutedWordsInner({}: {control: Dialog.DialogOuterProps['control']}) { <TargetToggle> <View style={[a.flex_row, a.align_center, a.gap_sm]}> <Toggle.Radio /> - <Toggle.Label> + <Toggle.LabelText> <Trans>Mute in tags only</Trans> - </Toggle.Label> + </Toggle.LabelText> </View> <Hashtag size="sm" /> </TargetToggle> diff --git a/src/components/forms/DateField/index.android.tsx b/src/components/forms/DateField/index.android.tsx index 700d15e6d..1830ca4bf 100644 --- a/src/components/forms/DateField/index.android.tsx +++ b/src/components/forms/DateField/index.android.tsx @@ -8,7 +8,7 @@ import * as TextField from '#/components/forms/TextField' import {DateFieldButton} from './index.shared' export * as utils from '#/components/forms/DateField/utils' -export const Label = TextField.Label +export const LabelText = TextField.LabelText export function DateField({ value, diff --git a/src/components/forms/DateField/index.tsx b/src/components/forms/DateField/index.tsx index 5662bb594..e231ac5ba 100644 --- a/src/components/forms/DateField/index.tsx +++ b/src/components/forms/DateField/index.tsx @@ -13,7 +13,7 @@ import * as TextField from '#/components/forms/TextField' import {DateFieldButton} from './index.shared' export * as utils from '#/components/forms/DateField/utils' -export const Label = TextField.Label +export const LabelText = TextField.LabelText /** * Date-only input. Accepts a date in the format YYYY-MM-DD, and reports date diff --git a/src/components/forms/DateField/index.web.tsx b/src/components/forms/DateField/index.web.tsx index 982d32711..b764620e3 100644 --- a/src/components/forms/DateField/index.web.tsx +++ b/src/components/forms/DateField/index.web.tsx @@ -9,7 +9,7 @@ import * as TextField from '#/components/forms/TextField' import {CalendarDays_Stroke2_Corner0_Rounded as CalendarDays} from '#/components/icons/CalendarDays' export * as utils from '#/components/forms/DateField/utils' -export const Label = TextField.Label +export const LabelText = TextField.LabelText const InputBase = React.forwardRef<HTMLInputElement, TextInputProps>( ({style, ...props}, ref) => { diff --git a/src/components/forms/TextField.tsx b/src/components/forms/TextField.tsx index 0bdeca645..73a660ea6 100644 --- a/src/components/forms/TextField.tsx +++ b/src/components/forms/TextField.tsx @@ -225,7 +225,7 @@ export function createInput(Component: typeof TextInput) { export const Input = createInput(TextInput) -export function Label({ +export function LabelText({ nativeID, children, }: React.PropsWithChildren<{nativeID?: string}>) { @@ -288,7 +288,7 @@ export function Icon({icon: Comp}: {icon: React.ComponentType<SVGIconProps>}) { ) } -export function Suffix({ +export function SuffixText({ children, label, accessibilityHint, diff --git a/src/components/forms/Toggle.tsx b/src/components/forms/Toggle.tsx index 7a4b5ac95..7285e5fac 100644 --- a/src/components/forms/Toggle.tsx +++ b/src/components/forms/Toggle.tsx @@ -3,16 +3,16 @@ import {Pressable, View, ViewStyle} from 'react-native' import {HITSLOP_10} from 'lib/constants' import { - useTheme, atoms as a, - native, flatten, - ViewStyleProp, + native, TextStyleProp, + useTheme, + ViewStyleProp, } from '#/alf' -import {Text} from '#/components/Typography' import {useInteractionState} from '#/components/hooks/useInteractionState' import {CheckThick_Stroke2_Corner0_Rounded as Checkmark} from '#/components/icons/Check' +import {Text} from '#/components/Typography' export type ItemState = { name: string @@ -234,7 +234,7 @@ export function Item({ ) } -export function Label({ +export function LabelText({ children, style, }: React.PropsWithChildren<TextStyleProp>) { diff --git a/src/components/moderation/LabelPreference.tsx b/src/components/moderation/LabelPreference.tsx index 028bd1a39..990e73622 100644 --- a/src/components/moderation/LabelPreference.tsx +++ b/src/components/moderation/LabelPreference.tsx @@ -13,7 +13,7 @@ import { } from '#/state/queries/preferences' import {atoms as a, useBreakpoints, useTheme} from '#/alf' import * as ToggleButton from '#/components/forms/ToggleButton' -import {InlineLink} from '#/components/Link' +import {InlineLinkText} from '#/components/Link' import {Text} from '#/components/Typography' import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '../icons/CircleInfo' @@ -243,9 +243,9 @@ export function LabelerLabelPreference({ ) : isGlobalLabel ? ( <Trans> Configured in{' '} - <InlineLink to="/moderation" style={a.text_sm}> + <InlineLinkText to="/moderation" style={a.text_sm}> moderation settings - </InlineLink> + </InlineLinkText> . </Trans> ) : null} diff --git a/src/components/moderation/LabelsOnMeDialog.tsx b/src/components/moderation/LabelsOnMeDialog.tsx index 6eddbc7ce..95e3d242b 100644 --- a/src/components/moderation/LabelsOnMeDialog.tsx +++ b/src/components/moderation/LabelsOnMeDialog.tsx @@ -1,20 +1,19 @@ import React from 'react' import {View} from 'react-native' +import {ComAtprotoLabelDefs, ComAtprotoModerationDefs} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {ComAtprotoLabelDefs, ComAtprotoModerationDefs} from '@atproto/api' import {useLabelInfo} from '#/lib/moderation/useLabelInfo' import {makeProfileLink} from '#/lib/routes/links' import {sanitizeHandle} from '#/lib/strings/handles' import {getAgent} from '#/state/session' - +import * as Toast from '#/view/com/util/Toast' import {atoms as a, useBreakpoints, useTheme} from '#/alf' -import {Text} from '#/components/Typography' -import * as Dialog from '#/components/Dialog' import {Button, ButtonText} from '#/components/Button' -import {InlineLink} from '#/components/Link' -import * as Toast from '#/view/com/util/Toast' +import * as Dialog from '#/components/Dialog' +import {InlineLinkText} from '#/components/Link' +import {Text} from '#/components/Typography' import {Divider} from '../Divider' export {useDialogControl as useLabelsOnMeDialogControl} from '#/components/Dialog' @@ -145,13 +144,13 @@ function Label({ <View style={[a.px_md, a.py_sm, t.atoms.bg_contrast_25]}> <Text style={[t.atoms.text_contrast_medium]}> <Trans>Source:</Trans>{' '} - <InlineLink + <InlineLinkText to={makeProfileLink( labeler ? labeler.creator : {did: label.src, handle: ''}, )} onPress={() => control.close()}> {labeler ? sanitizeHandle(labeler.creator.handle, '@') : label.src} - </InlineLink> + </InlineLinkText> </Text> </View> </View> @@ -204,14 +203,14 @@ function AppealForm({ <Text style={[a.text_md, a.leading_snug]}> <Trans> This appeal will be sent to{' '} - <InlineLink + <InlineLinkText to={makeProfileLink( labeler ? labeler.creator : {did: label.src, handle: ''}, )} onPress={() => control.close()} style={[a.text_md, a.leading_snug]}> {labeler ? sanitizeHandle(labeler.creator.handle, '@') : label.src} - </InlineLink> + </InlineLinkText> . </Trans> </Text> diff --git a/src/components/moderation/ModerationDetailsDialog.tsx b/src/components/moderation/ModerationDetailsDialog.tsx index da490cb43..da57de4df 100644 --- a/src/components/moderation/ModerationDetailsDialog.tsx +++ b/src/components/moderation/ModerationDetailsDialog.tsx @@ -1,19 +1,18 @@ import React from 'react' import {View} from 'react-native' +import {ModerationCause} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {ModerationCause} from '@atproto/api' -import {listUriToHref} from '#/lib/strings/url-helpers' import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription' import {makeProfileLink} from '#/lib/routes/links' - +import {listUriToHref} from '#/lib/strings/url-helpers' import {isNative} from '#/platform/detection' -import {useTheme, atoms as a} from '#/alf' -import {Text} from '#/components/Typography' +import {atoms as a, useTheme} from '#/alf' import * as Dialog from '#/components/Dialog' -import {InlineLink} from '#/components/Link' import {Divider} from '#/components/Divider' +import {InlineLinkText} from '#/components/Link' +import {Text} from '#/components/Typography' export {useDialogControl as useModerationDetailsDialogControl} from '#/components/Dialog' @@ -55,9 +54,9 @@ function ModerationDetailsDialogInner({ description = ( <Trans> This user is included in the{' '} - <InlineLink to={listUriToHref(list.uri)} style={[a.text_sm]}> + <InlineLinkText to={listUriToHref(list.uri)} style={[a.text_sm]}> {list.name} - </InlineLink>{' '} + </InlineLinkText>{' '} list which you have blocked. </Trans> ) @@ -84,9 +83,9 @@ function ModerationDetailsDialogInner({ description = ( <Trans> This user is included in the{' '} - <InlineLink to={listUriToHref(list.uri)} style={[a.text_sm]}> + <InlineLinkText to={listUriToHref(list.uri)} style={[a.text_sm]}> {list.name} - </InlineLink>{' '} + </InlineLinkText>{' '} list which you have muted. </Trans> ) @@ -127,12 +126,12 @@ function ModerationDetailsDialogInner({ {modcause.source.type === 'user' ? ( <Trans>the author</Trans> ) : ( - <InlineLink + <InlineLinkText to={makeProfileLink({did: modcause.label.src, handle: ''})} onPress={() => control.close()} style={a.text_md}> {desc.source} - </InlineLink> + </InlineLinkText> )} . </Trans> diff --git a/src/screens/Login/ChooseAccountForm.tsx b/src/screens/Login/ChooseAccountForm.tsx index 15c06dbe8..01eca1876 100644 --- a/src/screens/Login/ChooseAccountForm.tsx +++ b/src/screens/Login/ChooseAccountForm.tsx @@ -58,11 +58,11 @@ export const ChooseAccountForm = ({ return ( <FormContainer testID="chooseAccountForm" - title={<Trans>Select account</Trans>}> + titleText={<Trans>Select account</Trans>}> <View> - <TextField.Label> + <TextField.LabelText> <Trans>Sign in as...</Trans> - </TextField.Label> + </TextField.LabelText> <AccountList onSelectAccount={onSelect} onSelectOther={() => onSelectAccount()} diff --git a/src/screens/Login/ForgotPasswordForm.tsx b/src/screens/Login/ForgotPasswordForm.tsx index 580452e75..ec30bab4a 100644 --- a/src/screens/Login/ForgotPasswordForm.tsx +++ b/src/screens/Login/ForgotPasswordForm.tsx @@ -83,11 +83,11 @@ export const ForgotPasswordForm = ({ return ( <FormContainer testID="forgotPasswordForm" - title={<Trans>Reset password</Trans>}> + titleText={<Trans>Reset password</Trans>}> <View> - <TextField.Label> + <TextField.LabelText> <Trans>Hosting provider</Trans> - </TextField.Label> + </TextField.LabelText> <HostingProvider serviceUrl={serviceUrl} onSelectServiceUrl={setServiceUrl} @@ -95,9 +95,9 @@ export const ForgotPasswordForm = ({ /> </View> <View> - <TextField.Label> + <TextField.LabelText> <Trans>Email address</Trans> - </TextField.Label> + </TextField.LabelText> <TextField.Root> <TextField.Icon icon={At} /> <TextField.Input diff --git a/src/screens/Login/FormContainer.tsx b/src/screens/Login/FormContainer.tsx index 0144a8b5b..d5e075bdb 100644 --- a/src/screens/Login/FormContainer.tsx +++ b/src/screens/Login/FormContainer.tsx @@ -6,12 +6,12 @@ import {Text} from '#/components/Typography' export function FormContainer({ testID, - title, + titleText, children, style, }: { testID?: string - title?: React.ReactNode + titleText?: React.ReactNode children: React.ReactNode style?: StyleProp<ViewStyle> }) { @@ -21,9 +21,9 @@ export function FormContainer({ <View testID={testID} style={[a.gap_md, a.flex_1, !gtMobile && [a.px_lg, a.py_md], style]}> - {title && !gtMobile && ( + {titleText && !gtMobile && ( <Text style={[a.text_xl, a.font_bold, t.atoms.text_contrast_high]}> - {title} + {titleText} </Text> )} {children} diff --git a/src/screens/Login/LoginForm.tsx b/src/screens/Login/LoginForm.tsx index 6bf215ee5..6b1340b95 100644 --- a/src/screens/Login/LoginForm.tsx +++ b/src/screens/Login/LoginForm.tsx @@ -128,11 +128,11 @@ export const LoginForm = ({ const isReady = !!serviceDescription && !!identifier && !!password return ( - <FormContainer testID="loginForm" title={<Trans>Sign in</Trans>}> + <FormContainer testID="loginForm" titleText={<Trans>Sign in</Trans>}> <View> - <TextField.Label> + <TextField.LabelText> <Trans>Hosting provider</Trans> - </TextField.Label> + </TextField.LabelText> <HostingProvider serviceUrl={serviceUrl} onSelectServiceUrl={setServiceUrl} @@ -140,9 +140,9 @@ export const LoginForm = ({ /> </View> <View> - <TextField.Label> + <TextField.LabelText> <Trans>Account</Trans> - </TextField.Label> + </TextField.LabelText> <View style={[a.gap_sm]}> <TextField.Root> <TextField.Icon icon={At} /> diff --git a/src/screens/Login/SetNewPasswordForm.tsx b/src/screens/Login/SetNewPasswordForm.tsx index e7b488655..88f7ec541 100644 --- a/src/screens/Login/SetNewPasswordForm.tsx +++ b/src/screens/Login/SetNewPasswordForm.tsx @@ -99,7 +99,7 @@ export const SetNewPasswordForm = ({ return ( <FormContainer testID="setNewPasswordForm" - title={<Trans>Set new password</Trans>}> + titleText={<Trans>Set new password</Trans>}> <Text style={[a.leading_snug, a.mb_sm]}> <Trans> You will receive an email with a "reset code." Enter that code here, @@ -108,7 +108,7 @@ export const SetNewPasswordForm = ({ </Text> <View> - <TextField.Label>Reset code</TextField.Label> + <TextField.LabelText>Reset code</TextField.LabelText> <TextField.Root> <TextField.Icon icon={Ticket} /> <TextField.Input @@ -131,7 +131,7 @@ export const SetNewPasswordForm = ({ </View> <View> - <TextField.Label>New password</TextField.Label> + <TextField.LabelText>New password</TextField.LabelText> <TextField.Root> <TextField.Icon icon={Lock} /> <TextField.Input diff --git a/src/screens/Moderation/index.tsx b/src/screens/Moderation/index.tsx index 9d51a6197..a874e745c 100644 --- a/src/screens/Moderation/index.tsx +++ b/src/screens/Moderation/index.tsx @@ -40,7 +40,7 @@ import {Filter_Stroke2_Corner0_Rounded as Filter} from '#/components/icons/Filte import {Group3_Stroke2_Corner0_Rounded as Group} from '#/components/icons/Group' import {Person_Stroke2_Corner0_Rounded as Person} from '#/components/icons/Person' import * as LabelingService from '#/components/LabelingServiceCard' -import {InlineLink, Link} from '#/components/Link' +import {InlineLinkText, Link} from '#/components/Link' import {Loader} from '#/components/Loader' import {GlobalLabelPreference} from '#/components/moderation/LabelPreference' import {Text} from '#/components/Typography' @@ -518,11 +518,11 @@ function PwiOptOut() { msg`Discourage apps from showing my account to logged-out users`, )}> <Toggle.Switch /> - <Toggle.Label style={[a.text_md, a.flex_1]}> + <Toggle.LabelText style={[a.text_md, a.flex_1]}> <Trans> Discourage apps from showing my account to logged-out users </Trans> - </Toggle.Label> + </Toggle.LabelText> </Toggle.Item> {updateProfile.isPending && <Loader />} @@ -545,9 +545,9 @@ function PwiOptOut() { </Trans> </Text> - <InlineLink to="https://blueskyweb.zendesk.com/hc/en-us/articles/15835264007693-Data-Privacy"> + <InlineLinkText to="https://blueskyweb.zendesk.com/hc/en-us/articles/15835264007693-Data-Privacy"> <Trans>Learn more about what is public on Bluesky.</Trans> - </InlineLink> + </InlineLinkText> </View> </View> ) diff --git a/src/screens/Onboarding/Layout.tsx b/src/screens/Onboarding/Layout.tsx index 6337cee09..cfaf20ffe 100644 --- a/src/screens/Onboarding/Layout.tsx +++ b/src/screens/Onboarding/Layout.tsx @@ -1,29 +1,27 @@ import React from 'react' import {View} from 'react-native' import {useSafeAreaInsets} from 'react-native-safe-area-context' -import {useLingui} from '@lingui/react' import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' -import {IS_DEV} from '#/env' import {isWeb} from '#/platform/detection' import {useOnboardingDispatch} from '#/state/shell' - +import {ScrollView} from '#/view/com/util/Views' +import {Context} from '#/screens/Onboarding/state' import { - useTheme, atoms as a, - useBreakpoints, - web, - native, flatten, + native, TextStyleProp, + useBreakpoints, + useTheme, + web, } from '#/alf' -import {P, leading, Text} from '#/components/Typography' -import {ChevronLeft_Stroke2_Corner0_Rounded as ChevronLeft} from '#/components/icons/Chevron' import {Button, ButtonIcon} from '#/components/Button' -import {ScrollView} from '#/view/com/util/Views' +import {ChevronLeft_Stroke2_Corner0_Rounded as ChevronLeft} from '#/components/icons/Chevron' import {createPortalGroup} from '#/components/Portal' - -import {Context} from '#/screens/Onboarding/state' +import {leading, P, Text} from '#/components/Typography' +import {IS_DEV} from '#/env' const COL_WIDTH = 500 @@ -204,7 +202,7 @@ export function Layout({children}: React.PropsWithChildren<{}>) { ) } -export function Title({ +export function TitleText({ children, style, }: React.PropsWithChildren<TextStyleProp>) { @@ -224,7 +222,7 @@ export function Title({ ) } -export function Description({ +export function DescriptionText({ children, style, }: React.PropsWithChildren<TextStyleProp>) { diff --git a/src/screens/Onboarding/StepAlgoFeeds/index.tsx b/src/screens/Onboarding/StepAlgoFeeds/index.tsx index 35f525ef2..4ba61696f 100644 --- a/src/screens/Onboarding/StepAlgoFeeds/index.tsx +++ b/src/screens/Onboarding/StepAlgoFeeds/index.tsx @@ -6,9 +6,9 @@ import {useLingui} from '@lingui/react' import {useAnalytics} from '#/lib/analytics/analytics' import {logEvent} from '#/lib/statsig/statsig' import { - Description, + DescriptionText, OnboardingControls, - Title, + TitleText, } from '#/screens/Onboarding/Layout' import {Context} from '#/screens/Onboarding/state' import {FeedCard} from '#/screens/Onboarding/StepAlgoFeeds/FeedCard' @@ -105,15 +105,15 @@ export function StepAlgoFeeds() { <View style={[a.align_start]}> <IconCircle icon={ListSparkle} style={[a.mb_2xl]} /> - <Title> + <TitleText> <Trans>Choose your main feeds</Trans> - </Title> - <Description> + </TitleText> + <DescriptionText> <Trans> Custom feeds built by the community bring you new experiences and help you find the content you love. </Trans> - </Description> + </DescriptionText> <View style={[a.w_full, a.pb_2xl]}> <Toggle.Group diff --git a/src/screens/Onboarding/StepFinished.tsx b/src/screens/Onboarding/StepFinished.tsx index 0c81d2d25..ced80f391 100644 --- a/src/screens/Onboarding/StepFinished.tsx +++ b/src/screens/Onboarding/StepFinished.tsx @@ -10,9 +10,9 @@ import {useSetSaveFeedsMutation} from '#/state/queries/preferences' import {getAgent} from '#/state/session' import {useOnboardingDispatch} from '#/state/shell' import { - Description, + DescriptionText, OnboardingControls, - Title, + TitleText, } from '#/screens/Onboarding/Layout' import {Context} from '#/screens/Onboarding/state' import { @@ -87,12 +87,12 @@ export function StepFinished() { <View style={[a.align_start]}> <IconCircle icon={Check} style={[a.mb_2xl]} /> - <Title> + <TitleText> <Trans>You're ready to go!</Trans> - </Title> - <Description> + </TitleText> + <DescriptionText> <Trans>We hope you have a wonderful time. Remember, Bluesky is:</Trans> - </Description> + </DescriptionText> <View style={[a.pt_5xl, a.gap_3xl]}> <View style={[a.flex_row, a.align_center, a.w_full, a.gap_lg]}> diff --git a/src/screens/Onboarding/StepFollowingFeed.tsx b/src/screens/Onboarding/StepFollowingFeed.tsx index e886a0891..a1c7299f0 100644 --- a/src/screens/Onboarding/StepFollowingFeed.tsx +++ b/src/screens/Onboarding/StepFollowingFeed.tsx @@ -10,9 +10,9 @@ import { useSetFeedViewPreferencesMutation, } from 'state/queries/preferences' import { - Description, + DescriptionText, OnboardingControls, - Title, + TitleText, } from '#/screens/Onboarding/Layout' import {Context} from '#/screens/Onboarding/state' import {atoms as a} from '#/alf' @@ -58,12 +58,12 @@ export function StepFollowingFeed() { <View style={[a.align_start]}> <IconCircle icon={FilterTimeline} style={[a.mb_2xl]} /> - <Title> + <TitleText> <Trans>Your default feed is "Following"</Trans> - </Title> - <Description style={[a.mb_md]}> + </TitleText> + <DescriptionText style={[a.mb_md]}> <Trans>It shows posts from the people you follow as they happen.</Trans> - </Description> + </DescriptionText> <View style={[a.w_full]}> <Toggle.Item @@ -139,9 +139,9 @@ export function StepFollowingFeed() { </Toggle.Item> </View> - <Description style={[a.mt_lg]}> + <DescriptionText style={[a.mt_lg]}> <Trans>You can change these settings later.</Trans> - </Description> + </DescriptionText> <OnboardingControls.Portal> <Button diff --git a/src/screens/Onboarding/StepInterests/index.tsx b/src/screens/Onboarding/StepInterests/index.tsx index 8f34cced9..6afc3c07a 100644 --- a/src/screens/Onboarding/StepInterests/index.tsx +++ b/src/screens/Onboarding/StepInterests/index.tsx @@ -11,9 +11,9 @@ import {logger} from '#/logger' import {getAgent} from '#/state/session' import {useOnboardingDispatch} from '#/state/shell' import { - Description, + DescriptionText, OnboardingControls, - Title, + TitleText, } from '#/screens/Onboarding/Layout' import {ApiResponseMap, Context} from '#/screens/Onboarding/state' import {InterestButton} from '#/screens/Onboarding/StepInterests/InterestButton' @@ -163,8 +163,8 @@ export function StepInterests() { ]} /> - <Title>{title}</Title> - <Description>{description}</Description> + <TitleText>{title}</TitleText> + <DescriptionText>{description}</DescriptionText> <View style={[a.w_full, a.pt_2xl]}> {isLoading ? ( diff --git a/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx b/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx index 9e59c1db6..7563bece1 100644 --- a/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx +++ b/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx @@ -113,15 +113,15 @@ export function AdultContentEnabledPref({ )} <Prompt.Outer control={prompt}> - <Prompt.Title> + <Prompt.TitleText> <Trans>Adult Content</Trans> - </Prompt.Title> - <Prompt.Description> + </Prompt.TitleText> + <Prompt.DescriptionText> <Trans> Due to Apple policies, adult content can only be enabled on the web after completing sign up. </Trans> - </Prompt.Description> + </Prompt.DescriptionText> <Prompt.Actions> <Prompt.Action onPress={() => prompt.close()} cta={_(msg`OK`)} /> </Prompt.Actions> diff --git a/src/screens/Onboarding/StepModeration/index.tsx b/src/screens/Onboarding/StepModeration/index.tsx index c5bdf5622..d494f48dd 100644 --- a/src/screens/Onboarding/StepModeration/index.tsx +++ b/src/screens/Onboarding/StepModeration/index.tsx @@ -9,9 +9,9 @@ import {logEvent} from '#/lib/statsig/statsig' import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferencesSetAdultContentMutation} from 'state/queries/preferences' import { - Description, + DescriptionText, OnboardingControls, - Title, + TitleText, } from '#/screens/Onboarding/Layout' import {Context} from '#/screens/Onboarding/state' import {AdultContentEnabledPref} from '#/screens/Onboarding/StepModeration/AdultContentEnabledPref' @@ -56,14 +56,14 @@ export function StepModeration() { <View style={[a.align_start]}> <IconCircle icon={EyeSlash} style={[a.mb_2xl]} /> - <Title> + <TitleText> <Trans>You're in control</Trans> - </Title> - <Description style={[a.mb_xl]}> + </TitleText> + <DescriptionText style={[a.mb_xl]}> <Trans> Select what you want to see (or not see), and we’ll handle the rest. </Trans> - </Description> + </DescriptionText> {!preferences ? ( <View style={[a.pt_md]}> diff --git a/src/screens/Onboarding/StepSuggestedAccounts/index.tsx b/src/screens/Onboarding/StepSuggestedAccounts/index.tsx index 2e6161362..e9bc3f0fd 100644 --- a/src/screens/Onboarding/StepSuggestedAccounts/index.tsx +++ b/src/screens/Onboarding/StepSuggestedAccounts/index.tsx @@ -10,9 +10,9 @@ import {capitalize} from '#/lib/strings/capitalize' import {useModerationOpts} from '#/state/queries/preferences' import {useProfilesQuery} from '#/state/queries/profile' import { - Description, + DescriptionText, OnboardingControls, - Title, + TitleText, } from '#/screens/Onboarding/Layout' import {Context} from '#/screens/Onboarding/state' import { @@ -136,16 +136,16 @@ export function StepSuggestedAccounts() { <View style={[a.align_start]}> <IconCircle icon={At} style={[a.mb_2xl]} /> - <Title> + <TitleText> <Trans>Here are some accounts for you to follow</Trans> - </Title> - <Description> + </TitleText> + <DescriptionText> {state.interestsStepResults.selectedInterests.length ? ( <Trans>Based on your interest in {interestsText}</Trans> ) : ( <Trans>These are popular accounts you might like:</Trans> )} - </Description> + </DescriptionText> <View style={[a.w_full, a.pt_xl]}> {isLoading ? ( diff --git a/src/screens/Onboarding/StepTopicalFeeds.tsx b/src/screens/Onboarding/StepTopicalFeeds.tsx index 26b1c243b..bfc9e91d1 100644 --- a/src/screens/Onboarding/StepTopicalFeeds.tsx +++ b/src/screens/Onboarding/StepTopicalFeeds.tsx @@ -9,9 +9,9 @@ import {capitalize} from '#/lib/strings/capitalize' import {IS_TEST_USER} from 'lib/constants' import {useSession} from 'state/session' import { - Description, + DescriptionText, OnboardingControls, - Title, + TitleText, } from '#/screens/Onboarding/Layout' import {Context} from '#/screens/Onboarding/state' import {FeedCard} from '#/screens/Onboarding/StepAlgoFeeds/FeedCard' @@ -76,10 +76,10 @@ export function StepTopicalFeeds() { <View style={[a.align_start]}> <IconCircle icon={ListMagnifyingGlass} style={[a.mb_2xl]} /> - <Title> + <TitleText> <Trans>Feeds can be topical as well!</Trans> - </Title> - <Description> + </TitleText> + <DescriptionText> {state.interestsStepResults.selectedInterests.length ? ( <Trans> Here are some topical feeds based on your interests: {interestsText} @@ -91,7 +91,7 @@ export function StepTopicalFeeds() { many as you like. </Trans> )} - </Description> + </DescriptionText> <View style={[a.w_full, a.pb_2xl, a.pt_2xl]}> <Toggle.Group diff --git a/src/screens/Profile/Header/Metrics.tsx b/src/screens/Profile/Header/Metrics.tsx index d9a8a01a8..8789e0354 100644 --- a/src/screens/Profile/Header/Metrics.tsx +++ b/src/screens/Profile/Header/Metrics.tsx @@ -1,17 +1,16 @@ import React from 'react' import {View} from 'react-native' import {AppBskyActorDefs} from '@atproto/api' -import {Trans, msg} from '@lingui/macro' +import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {Shadow} from '#/state/cache/types' import {pluralize} from '#/lib/strings/helpers' +import {Shadow} from '#/state/cache/types' import {makeProfileLink} from 'lib/routes/links' import {formatCount} from 'view/com/util/numeric/format' - import {atoms as a, useTheme} from '#/alf' +import {InlineLinkText} from '#/components/Link' import {Text} from '#/components/Typography' -import {InlineLink} from '#/components/Link' export function ProfileHeaderMetrics({ profile, @@ -28,7 +27,7 @@ export function ProfileHeaderMetrics({ <View style={[a.flex_row, a.gap_sm, a.align_center, a.pb_md]} pointerEvents="box-none"> - <InlineLink + <InlineLinkText testID="profileHeaderFollowersButton" style={[a.flex_row, t.atoms.text]} to={makeProfileLink(profile, 'followers')} @@ -37,8 +36,8 @@ export function ProfileHeaderMetrics({ <Text style={[t.atoms.text_contrast_medium, a.text_md]}> {pluralizedFollowers} </Text> - </InlineLink> - <InlineLink + </InlineLinkText> + <InlineLinkText testID="profileHeaderFollowsButton" style={[a.flex_row, t.atoms.text]} to={makeProfileLink(profile, 'follows')} @@ -49,7 +48,7 @@ export function ProfileHeaderMetrics({ following </Text> </Trans> - </InlineLink> + </InlineLinkText> <Text style={[a.font_bold, t.atoms.text, a.text_md]}> {formatCount(profile.postsCount || 0)}{' '} <Text style={[t.atoms.text_contrast_medium, a.font_normal, a.text_md]}> diff --git a/src/screens/Profile/Header/ProfileHeaderLabeler.tsx b/src/screens/Profile/Header/ProfileHeaderLabeler.tsx index d8720c915..4d8dbad86 100644 --- a/src/screens/Profile/Header/ProfileHeaderLabeler.tsx +++ b/src/screens/Profile/Header/ProfileHeaderLabeler.tsx @@ -316,13 +316,13 @@ function CantSubscribePrompt({ const {_} = useLingui() return ( <Prompt.Outer control={control}> - <Prompt.Title>Unable to subscribe</Prompt.Title> - <Prompt.Description> + <Prompt.TitleText>Unable to subscribe</Prompt.TitleText> + <Prompt.DescriptionText> <Trans> We're sorry! You can only subscribe to ten labelers, and you've reached your limit of ten. </Trans> - </Prompt.Description> + </Prompt.DescriptionText> <Prompt.Actions> <Prompt.Action onPress={control.close} cta={_(msg`OK`)} /> </Prompt.Actions> diff --git a/src/screens/Signup/StepInfo/Policies.tsx b/src/screens/Signup/StepInfo/Policies.tsx index 4879ae7b3..f25bda274 100644 --- a/src/screens/Signup/StepInfo/Policies.tsx +++ b/src/screens/Signup/StepInfo/Policies.tsx @@ -6,7 +6,7 @@ import {useLingui} from '@lingui/react' import {atoms as a, useTheme} from '#/alf' import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' -import {InlineLink} from '#/components/Link' +import {InlineLinkText} from '#/components/Link' import {Text} from '#/components/Typography' export const Policies = ({ @@ -45,16 +45,16 @@ export const Policies = ({ const els = [] if (tos) { els.push( - <InlineLink key="tos" to={tos}> + <InlineLinkText key="tos" to={tos}> {_(msg`Terms of Service`)} - </InlineLink>, + </InlineLinkText>, ) } if (pp) { els.push( - <InlineLink key="pp" to={pp}> + <InlineLinkText key="pp" to={pp}> {_(msg`Privacy Policy`)} - </InlineLink>, + </InlineLinkText>, ) } if (els.length === 2) { diff --git a/src/screens/Signup/StepInfo/index.tsx b/src/screens/Signup/StepInfo/index.tsx index 136592a0b..d22d1323a 100644 --- a/src/screens/Signup/StepInfo/index.tsx +++ b/src/screens/Signup/StepInfo/index.tsx @@ -36,9 +36,9 @@ export function StepInfo() { <View style={[a.gap_md]}> <FormError error={state.error} /> <View> - <TextField.Label> + <TextField.LabelText> <Trans>Hosting provider</Trans> - </TextField.Label> + </TextField.LabelText> <HostingProvider serviceUrl={state.serviceUrl} onSelectServiceUrl={v => @@ -54,9 +54,9 @@ export function StepInfo() { <> {state.serviceDescription.inviteCodeRequired && ( <View> - <TextField.Label> + <TextField.LabelText> <Trans>Invite code</Trans> - </TextField.Label> + </TextField.LabelText> <TextField.Root> <TextField.Icon icon={Ticket} /> <TextField.Input @@ -76,9 +76,9 @@ export function StepInfo() { </View> )} <View> - <TextField.Label> + <TextField.LabelText> <Trans>Email</Trans> - </TextField.Label> + </TextField.LabelText> <TextField.Root> <TextField.Icon icon={Envelope} /> <TextField.Input @@ -97,9 +97,9 @@ export function StepInfo() { </TextField.Root> </View> <View> - <TextField.Label> + <TextField.LabelText> <Trans>Password</Trans> - </TextField.Label> + </TextField.LabelText> <TextField.Root> <TextField.Icon icon={Lock} /> <TextField.Input @@ -117,9 +117,9 @@ export function StepInfo() { </TextField.Root> </View> <View> - <DateField.Label> + <DateField.LabelText> <Trans>Your birth date</Trans> - </DateField.Label> + </DateField.LabelText> <DateField.DateField testID="date" value={DateField.utils.toSimpleDateString(state.dateOfBirth)} diff --git a/src/screens/Signup/index.tsx b/src/screens/Signup/index.tsx index a085fe44c..74674b0cb 100644 --- a/src/screens/Signup/index.tsx +++ b/src/screens/Signup/index.tsx @@ -24,7 +24,7 @@ import {StepInfo} from '#/screens/Signup/StepInfo' import {atoms as a, useBreakpoints, useTheme} from '#/alf' import {Button, ButtonText} from '#/components/Button' import {Divider} from '#/components/Divider' -import {InlineLink} from '#/components/Link' +import {InlineLinkText} from '#/components/Link' import {Text} from '#/components/Typography' export function Signup({onPressBack}: {onPressBack: () => void}) { @@ -215,9 +215,9 @@ export function Signup({onPressBack}: {onPressBack: () => void}) { <View style={[a.w_full, a.py_lg]}> <Text style={[t.atoms.text_contrast_medium]}> <Trans>Having trouble?</Trans>{' '} - <InlineLink to={FEEDBACK_FORM_URL({email: state.email})}> + <InlineLinkText to={FEEDBACK_FORM_URL({email: state.email})}> <Trans>Contact support</Trans> - </InlineLink> + </InlineLinkText> </Text> </View> </View> diff --git a/src/view/com/auth/SplashScreen.web.tsx b/src/view/com/auth/SplashScreen.web.tsx index cdb72cc04..7a2ee16cf 100644 --- a/src/view/com/auth/SplashScreen.web.tsx +++ b/src/view/com/auth/SplashScreen.web.tsx @@ -14,7 +14,7 @@ import {ErrorBoundary} from 'view/com/util/ErrorBoundary' import {atoms as a, useTheme} from '#/alf' import {Button, ButtonText} from '#/components/Button' import {ChevronBottom_Stroke2_Corner0_Rounded as ChevronDown} from '#/components/icons/Chevron' -import {InlineLink} from '#/components/Link' +import {InlineLinkText} from '#/components/Link' import {Text} from '#/components/Typography' import {CenteredView} from '../util/Views' @@ -162,15 +162,15 @@ function Footer() { a.flex_1, t.atoms.border_contrast_medium, ]}> - <InlineLink to="https://bsky.social"> + <InlineLinkText to="https://bsky.social"> <Trans>Business</Trans> - </InlineLink> - <InlineLink to="https://bsky.social/about/blog"> + </InlineLinkText> + <InlineLinkText to="https://bsky.social/about/blog"> <Trans>Blog</Trans> - </InlineLink> - <InlineLink to="https://bsky.social/about/join"> + </InlineLinkText> + <InlineLinkText to="https://bsky.social/about/join"> <Trans>Jobs</Trans> - </InlineLink> + </InlineLinkText> <View style={a.flex_1} /> diff --git a/src/view/com/auth/server-input/index.tsx b/src/view/com/auth/server-input/index.tsx index b26ac1dcb..8aa23c263 100644 --- a/src/view/com/auth/server-input/index.tsx +++ b/src/view/com/auth/server-input/index.tsx @@ -1,17 +1,17 @@ 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 {BSKY_SERVICE} from 'lib/constants' -import * as persisted from '#/state/persisted' +import * as persisted from '#/state/persisted' +import {BSKY_SERVICE} from 'lib/constants' 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 * as ToggleButton from '#/components/forms/ToggleButton' +import * as Dialog from '#/components/Dialog' import * as TextField from '#/components/forms/TextField' +import * as ToggleButton from '#/components/forms/ToggleButton' import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe' +import {P, Text} from '#/components/Typography' export function ServerInputDialog({ control, @@ -106,9 +106,9 @@ export function ServerInputDialog({ a.px_md, a.py_md, ]}> - <TextField.Label nativeID="address-input-label"> + <TextField.LabelText nativeID="address-input-label"> <Trans>Server address</Trans> - </TextField.Label> + </TextField.LabelText> <TextField.Root> <TextField.Icon icon={Globe} /> <Dialog.Input diff --git a/src/view/screens/DebugMod.tsx b/src/view/screens/DebugMod.tsx index 64f2376a4..1387c6202 100644 --- a/src/view/screens/DebugMod.tsx +++ b/src/view/screens/DebugMod.tsx @@ -1,51 +1,51 @@ import React from 'react' -import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types' import {View} from 'react-native' import { - LABELS, - mock, - moderatePost, - moderateProfile, - ModerationOpts, AppBskyActorDefs, AppBskyFeedDefs, AppBskyFeedPost, + ComAtprotoLabelDefs, + interpretLabelValueDefinition, LabelPreference, - ModerationDecision, + LABELS, + mock, + moderatePost, + moderateProfile, 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> diff --git a/src/view/screens/ProfileFeed.tsx b/src/view/screens/ProfileFeed.tsx index 8eeeb5d90..4560e14eb 100644 --- a/src/view/screens/ProfileFeed.tsx +++ b/src/view/screens/ProfileFeed.tsx @@ -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 React, {useCallback, useMemo} from 'react' +import {Pressable, StyleSheet, View} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' 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 {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 { + 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 {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 {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 {Text} from 'view/com/util/text/Text' -import {RichText} from '#/components/RichText' +import {ListRef} from 'view/com/util/List' 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 {Text} from 'view/com/util/text/Text' 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 {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 {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 {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_Stroke2_Corner0_Rounded as HeartOutline, Heart2_Filled_Stroke2_Corner0_Rounded as HeartFilled, + Heart2_Stroke2_Corner0_Rounded as HeartOutline, } from '#/components/icons/Heart2' -import {Button as NewButton, ButtonText} from '#/components/Button' +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> diff --git a/src/view/screens/Settings/ExportCarDialog.tsx b/src/view/screens/Settings/ExportCarDialog.tsx index ba8fad2df..3ec37e85e 100644 --- a/src/view/screens/Settings/ExportCarDialog.tsx +++ b/src/view/screens/Settings/ExportCarDialog.tsx @@ -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 {getAgent, useSession} from '#/state/session' 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 * 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> diff --git a/src/view/screens/Storybook/Dialogs.tsx b/src/view/screens/Storybook/Dialogs.tsx index c2eaf19ac..41863bd9c 100644 --- a/src/view/screens/Storybook/Dialogs.tsx +++ b/src/view/screens/Storybook/Dialogs.tsx @@ -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> diff --git a/src/view/screens/Storybook/Forms.tsx b/src/view/screens/Storybook/Forms.tsx index 2d5495d70..182eacfde 100644 --- a/src/view/screens/Storybook/Forms.tsx +++ b/src/view/screens/Storybook/Forms.tsx @@ -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> diff --git a/src/view/screens/Storybook/Links.tsx b/src/view/screens/Storybook/Links.tsx index f9ecfba55..d35db79bc 100644 --- a/src/view/screens/Storybook/Links.tsx +++ b/src/view/screens/Storybook/Links.tsx @@ -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" |