Swap `RichText` (#2934)
* Switch to new RT * Allow early exit from links * Build in tracking to text atoms * Clean up FeedSourceCard * Clean up leading after new default * Add deprecated noticezio/stable
parent
8a169dc6a1
commit
df5a8f1542
|
@ -176,43 +176,59 @@ export const atoms = {
|
|||
},
|
||||
text_2xs: {
|
||||
fontSize: tokens.fontSize._2xs,
|
||||
letterSpacing: 0.25,
|
||||
},
|
||||
text_xs: {
|
||||
fontSize: tokens.fontSize.xs,
|
||||
letterSpacing: 0.25,
|
||||
},
|
||||
text_sm: {
|
||||
fontSize: tokens.fontSize.sm,
|
||||
letterSpacing: 0.25,
|
||||
},
|
||||
text_md: {
|
||||
fontSize: tokens.fontSize.md,
|
||||
letterSpacing: 0.25,
|
||||
},
|
||||
text_lg: {
|
||||
fontSize: tokens.fontSize.lg,
|
||||
letterSpacing: 0.25,
|
||||
},
|
||||
text_xl: {
|
||||
fontSize: tokens.fontSize.xl,
|
||||
letterSpacing: 0.25,
|
||||
},
|
||||
text_2xl: {
|
||||
fontSize: tokens.fontSize._2xl,
|
||||
letterSpacing: 0.25,
|
||||
},
|
||||
text_3xl: {
|
||||
fontSize: tokens.fontSize._3xl,
|
||||
letterSpacing: 0.25,
|
||||
},
|
||||
text_4xl: {
|
||||
fontSize: tokens.fontSize._4xl,
|
||||
letterSpacing: 0.25,
|
||||
},
|
||||
text_5xl: {
|
||||
fontSize: tokens.fontSize._5xl,
|
||||
letterSpacing: 0.25,
|
||||
},
|
||||
leading_tight: {
|
||||
lineHeight: 1.15,
|
||||
},
|
||||
leading_snug: {
|
||||
lineHeight: 1.25,
|
||||
lineHeight: 1.3,
|
||||
},
|
||||
leading_normal: {
|
||||
lineHeight: 1.5,
|
||||
},
|
||||
tracking_normal: {
|
||||
letterSpacing: 0,
|
||||
},
|
||||
tracking_wide: {
|
||||
letterSpacing: 0.25,
|
||||
},
|
||||
font_normal: {
|
||||
fontWeight: tokens.fontWeight.normal,
|
||||
},
|
||||
|
|
|
@ -51,11 +51,12 @@ type BaseLinkProps = Pick<
|
|||
warnOnMismatchingTextChild?: boolean
|
||||
|
||||
/**
|
||||
* Callback for when the link is pressed.
|
||||
* Callback for when the link is pressed. Prevent default and return `false`
|
||||
* to exit early and prevent navigation.
|
||||
*
|
||||
* DO NOT use this for navigation, that's what the `to` prop is for.
|
||||
*/
|
||||
onPress?: (e: GestureResponderEvent) => void
|
||||
onPress?: (e: GestureResponderEvent) => void | false
|
||||
|
||||
/**
|
||||
* Web-only attribute. Sets `download` attr on web.
|
||||
|
@ -82,7 +83,9 @@ export function useLink({
|
|||
|
||||
const onPress = React.useCallback(
|
||||
(e: GestureResponderEvent) => {
|
||||
outerOnPress?.(e)
|
||||
const exitEarlyIfFalse = outerOnPress?.(e)
|
||||
|
||||
if (exitEarlyIfFalse === false) return
|
||||
|
||||
const requiresWarning = Boolean(
|
||||
warnOnMismatchingTextChild &&
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react'
|
||||
import {RichText as RichTextAPI, AppBskyRichtextFacet} from '@atproto/api'
|
||||
|
||||
import {atoms as a, TextStyleProp} from '#/alf'
|
||||
import {atoms as a, TextStyleProp, flatten} from '#/alf'
|
||||
import {InlineLink} from '#/components/Link'
|
||||
import {Text, TextProps} from '#/components/Typography'
|
||||
import {toShortUrl} from 'lib/strings/url-helpers'
|
||||
|
@ -29,7 +29,7 @@ export function RichText({
|
|||
const [richText, setRichText] = React.useState<RichTextAPI>(() =>
|
||||
value instanceof RichTextAPI ? value : new RichTextAPI({text: value}),
|
||||
)
|
||||
const styles = [a.leading_normal, style]
|
||||
const styles = [a.leading_snug, flatten(style)]
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!resolveFacets) return
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react'
|
|||
import {Pressable, StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||
import {Text} from '../util/text/Text'
|
||||
import {RichText} from '../util/text/RichText'
|
||||
import {RichText} from '#/components/RichText'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {s} from 'lib/styles'
|
||||
import {UserAvatar} from '../util/UserAvatar'
|
||||
|
@ -25,6 +25,7 @@ import {
|
|||
} from '#/state/queries/preferences'
|
||||
import {useFeedSourceInfoQuery, FeedSourceInfo} from '#/state/queries/feed'
|
||||
import {FeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
|
||||
import {useTheme} from '#/alf'
|
||||
|
||||
export function FeedSourceCard({
|
||||
feedUri,
|
||||
|
@ -82,6 +83,7 @@ export function FeedSourceCardLoaded({
|
|||
pinOnSave?: boolean
|
||||
showMinimalPlaceholder?: boolean
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
const navigation = useNavigation<NavigationProp>()
|
||||
|
@ -266,8 +268,8 @@ export function FeedSourceCardLoaded({
|
|||
|
||||
{showDescription && feed.description ? (
|
||||
<RichText
|
||||
style={[pal.textLight, styles.description]}
|
||||
richText={feed.description}
|
||||
style={[t.atoms.text_contrast_high, styles.description]}
|
||||
value={feed.description}
|
||||
numberOfLines={3}
|
||||
/>
|
||||
) : null}
|
||||
|
|
|
@ -3,7 +3,7 @@ import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
|
|||
import {AtUri, AppBskyGraphDefs, RichText} from '@atproto/api'
|
||||
import {Link} from '../util/Link'
|
||||
import {Text} from '../util/text/Text'
|
||||
import {RichText as RichTextCom} from '../util/text/RichText'
|
||||
import {RichText as RichTextCom} from '#/components/RichText'
|
||||
import {UserAvatar} from '../util/UserAvatar'
|
||||
import {s} from 'lib/styles'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
|
@ -12,6 +12,7 @@ import {sanitizeDisplayName} from 'lib/strings/display-names'
|
|||
import {sanitizeHandle} from 'lib/strings/handles'
|
||||
import {makeProfileLink} from 'lib/routes/links'
|
||||
import {Trans} from '@lingui/macro'
|
||||
import {atoms as a} from '#/alf'
|
||||
|
||||
export const ListCard = ({
|
||||
testID,
|
||||
|
@ -119,9 +120,9 @@ export const ListCard = ({
|
|||
{descriptionRichText ? (
|
||||
<View style={styles.details}>
|
||||
<RichTextCom
|
||||
style={[pal.text, s.flex1]}
|
||||
style={[a.flex_1]}
|
||||
numberOfLines={20}
|
||||
richText={descriptionRichText}
|
||||
value={descriptionRichText}
|
||||
/>
|
||||
</View>
|
||||
) : undefined}
|
||||
|
|
|
@ -11,7 +11,7 @@ import {moderatePost_wrapped as moderatePost} from '#/lib/moderatePost_wrapped'
|
|||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||
import {PostThreadFollowBtn} from 'view/com/post-thread/PostThreadFollowBtn'
|
||||
import {Link, TextLink} from '../util/Link'
|
||||
import {RichText} from '../util/text/RichText'
|
||||
import {RichText} from '#/components/RichText'
|
||||
import {Text} from '../util/text/Text'
|
||||
import {PreviewableUserAvatar} from '../util/UserAvatar'
|
||||
import {s} from 'lib/styles'
|
||||
|
@ -44,6 +44,7 @@ import {ThreadPost} from '#/state/queries/post-thread'
|
|||
import {useSession} from 'state/session'
|
||||
import {WhoCanReply} from '../threadgate/WhoCanReply'
|
||||
import {LoadingPlaceholder} from '../util/LoadingPlaceholder'
|
||||
import {atoms as a} from '#/alf'
|
||||
|
||||
export function PostThreadItem({
|
||||
post,
|
||||
|
@ -326,10 +327,8 @@ let PostThreadItemLoaded = ({
|
|||
styles.postTextLargeContainer,
|
||||
]}>
|
||||
<RichText
|
||||
type="post-text-lg"
|
||||
richText={richText}
|
||||
lineHeight={1.3}
|
||||
style={s.flex1}
|
||||
value={richText}
|
||||
style={[a.flex_1, a.text_xl]}
|
||||
selectable
|
||||
/>
|
||||
</View>
|
||||
|
@ -522,10 +521,8 @@ let PostThreadItemLoaded = ({
|
|||
{richText?.text ? (
|
||||
<View style={styles.postTextContainer}>
|
||||
<RichText
|
||||
type="post-text"
|
||||
richText={richText}
|
||||
style={[pal.text, s.flex1]}
|
||||
lineHeight={1.3}
|
||||
value={richText}
|
||||
style={[a.flex_1, a.text_md]}
|
||||
numberOfLines={limitLines ? MAX_POST_LINES : undefined}
|
||||
/>
|
||||
</View>
|
||||
|
|
|
@ -20,7 +20,7 @@ import {PostCtrls} from '../util/post-ctrls/PostCtrls'
|
|||
import {PostEmbeds} from '../util/post-embeds'
|
||||
import {ContentHider} from '../util/moderation/ContentHider'
|
||||
import {PostAlerts} from '../util/moderation/PostAlerts'
|
||||
import {RichText} from '../util/text/RichText'
|
||||
import {RichText} from '#/components/RichText'
|
||||
import {PreviewableUserAvatar} from '../util/UserAvatar'
|
||||
import {s} from 'lib/styles'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
|
@ -36,6 +36,7 @@ import {FeedNameText} from '../util/FeedInfoText'
|
|||
import {useSession} from '#/state/session'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {atoms as a} from '#/alf'
|
||||
|
||||
export function FeedItem({
|
||||
post,
|
||||
|
@ -347,11 +348,9 @@ let PostContent = ({
|
|||
<View style={styles.postTextContainer}>
|
||||
<RichText
|
||||
testID="postText"
|
||||
type="post-text"
|
||||
richText={richText}
|
||||
lineHeight={1.3}
|
||||
value={richText}
|
||||
numberOfLines={limitLines ? MAX_POST_LINES : undefined}
|
||||
style={s.flex1}
|
||||
style={[a.flex_1, a.text_md]}
|
||||
/>
|
||||
</View>
|
||||
) : undefined}
|
||||
|
|
|
@ -23,7 +23,7 @@ import * as Toast from '../util/Toast'
|
|||
import {LoadingPlaceholder} from '../util/LoadingPlaceholder'
|
||||
import {Text} from '../util/text/Text'
|
||||
import {ThemedText} from '../util/text/ThemedText'
|
||||
import {RichText} from '../util/text/RichText'
|
||||
import {RichText} from '#/components/RichText'
|
||||
import {UserAvatar} from '../util/UserAvatar'
|
||||
import {UserBanner} from '../util/UserBanner'
|
||||
import {ProfileHeaderAlerts} from '../util/moderation/ProfileHeaderAlerts'
|
||||
|
@ -56,6 +56,7 @@ import {Shadow} from '#/state/cache/types'
|
|||
import {useRequireAuth} from '#/state/session'
|
||||
import {LabelInfo} from '../util/moderation/LabelInfo'
|
||||
import {useProfileShadow} from 'state/cache/profile-shadow'
|
||||
import {atoms as a} from '#/alf'
|
||||
|
||||
let ProfileHeaderLoading = (_props: {}): React.ReactNode => {
|
||||
const pal = usePalette('default')
|
||||
|
@ -608,12 +609,12 @@ let ProfileHeader = ({
|
|||
</Text>
|
||||
</View>
|
||||
{descriptionRT && !moderation.profile.blur ? (
|
||||
<View pointerEvents="auto">
|
||||
<View pointerEvents="auto" style={[styles.description]}>
|
||||
<RichText
|
||||
testID="profileHeaderDescription"
|
||||
style={[styles.description, pal.text]}
|
||||
style={[a.text_md]}
|
||||
numberOfLines={15}
|
||||
richText={descriptionRT}
|
||||
value={descriptionRT}
|
||||
/>
|
||||
</View>
|
||||
) : undefined}
|
||||
|
|
|
@ -20,7 +20,8 @@ import {PostAlerts} from '../moderation/PostAlerts'
|
|||
import {makeProfileLink} from 'lib/routes/links'
|
||||
import {InfoCircleIcon} from 'lib/icons'
|
||||
import {Trans} from '@lingui/macro'
|
||||
import {RichText} from 'view/com/util/text/RichText'
|
||||
import {RichText} from '#/components/RichText'
|
||||
import {atoms as a} from '#/alf'
|
||||
|
||||
export function MaybeQuoteEmbed({
|
||||
embed,
|
||||
|
@ -127,11 +128,10 @@ export function QuoteEmbed({
|
|||
) : null}
|
||||
{richText ? (
|
||||
<RichText
|
||||
richText={richText}
|
||||
type="post-text"
|
||||
style={pal.text}
|
||||
value={richText}
|
||||
style={[a.text_md]}
|
||||
numberOfLines={20}
|
||||
noLinks
|
||||
disableLinks
|
||||
/>
|
||||
) : null}
|
||||
{embed && <PostEmbeds embed={embed} moderation={{}} />}
|
||||
|
|
|
@ -10,6 +10,9 @@ import {usePalette} from 'lib/hooks/usePalette'
|
|||
|
||||
const WORD_WRAP = {wordWrap: 1}
|
||||
|
||||
/**
|
||||
* @deprecated use `#/components/RichText`
|
||||
*/
|
||||
export function RichText({
|
||||
testID,
|
||||
type = 'md',
|
||||
|
|
|
@ -17,7 +17,7 @@ import {TextLink} from 'view/com/util/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 'view/com/util/text/RichText'
|
||||
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'
|
||||
|
@ -59,6 +59,7 @@ 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} from '#/alf'
|
||||
|
||||
const SECTION_TITLES = ['Posts', 'About']
|
||||
|
||||
|
@ -575,9 +576,8 @@ function AboutSection({
|
|||
{feedInfo.description ? (
|
||||
<RichText
|
||||
testID="listDescription"
|
||||
type="lg"
|
||||
style={pal.text}
|
||||
richText={feedInfo.description}
|
||||
style={[a.text_md]}
|
||||
value={feedInfo.description}
|
||||
/>
|
||||
) : (
|
||||
<Text type="lg" style={[{fontStyle: 'italic'}, pal.textLight]}>
|
||||
|
|
|
@ -14,7 +14,7 @@ import {NativeDropdown, DropdownItem} from 'view/com/util/forms/NativeDropdown'
|
|||
import {CenteredView} from 'view/com/util/Views'
|
||||
import {EmptyState} from 'view/com/util/EmptyState'
|
||||
import {LoadingScreen} from 'view/com/util/LoadingScreen'
|
||||
import {RichText} from 'view/com/util/text/RichText'
|
||||
import {RichText} from '#/components/RichText'
|
||||
import {Button} from 'view/com/util/forms/Button'
|
||||
import {TextLink} from 'view/com/util/Link'
|
||||
import {ListRef} from 'view/com/util/List'
|
||||
|
@ -60,6 +60,7 @@ import {
|
|||
import {logger} from '#/logger'
|
||||
import {useAnalytics} from '#/lib/analytics/analytics'
|
||||
import {listenSoftReset} from '#/state/events'
|
||||
import {atoms as a} from '#/alf'
|
||||
|
||||
const SECTION_TITLES_CURATE = ['Posts', 'About']
|
||||
const SECTION_TITLES_MOD = ['About']
|
||||
|
@ -742,9 +743,8 @@ const AboutSection = React.forwardRef<SectionRef, AboutSectionProps>(
|
|||
{descriptionRT ? (
|
||||
<RichText
|
||||
testID="listDescription"
|
||||
type="lg"
|
||||
style={pal.text}
|
||||
richText={descriptionRT}
|
||||
style={[a.text_md]}
|
||||
value={descriptionRT}
|
||||
/>
|
||||
) : (
|
||||
<Text
|
||||
|
|
Loading…
Reference in New Issue