···11import React from 'react'
22-import {Text as RNText, TextStyle, TextProps} from 'react-native'
22+import {Text as RNText, TextStyle, TextProps as RNTextProps} from 'react-native'
33+import {UITextView} from 'react-native-ui-text-view'
3445import {useTheme, atoms, web, flatten} from '#/alf'
66+import {isIOS} from '#/platform/detection'
77+88+export type TextProps = RNTextProps & {
99+ /**
1010+ * Lets the user select text, to use the native copy and paste functionality.
1111+ */
1212+ selectable?: boolean
1313+}
514615/**
716 * Util to calculate lineHeight from a text size atom and a leading atom
···4453/**
4554 * Our main text component. Use this most of the time.
4655 */
4747-export function Text({style, ...rest}: TextProps) {
5656+export function Text({style, selectable, ...rest}: TextProps) {
4857 const t = useTheme()
4958 const s = normalizeTextStyles([atoms.text_sm, t.atoms.text, flatten(style)])
5050- return <RNText style={s} {...rest} />
5959+ return selectable && isIOS ? (
6060+ <UITextView style={s} {...rest} />
6161+ ) : (
6262+ <RNText selectable={selectable} style={s} {...rest} />
6363+ )
5164}
52655366export function createHeadingElement({level}: {level: number}) {
5467 return function HeadingElement({style, ...rest}: TextProps) {
5555- const t = useTheme()
5668 const attr =
5769 web({
5870 role: 'heading',
5971 'aria-level': level,
6072 }) || {}
6161- return (
6262- <RNText
6363- {...attr}
6464- {...rest}
6565- style={normalizeTextStyles([t.atoms.text, flatten(style)])}
6666- />
6767- )
7373+ return <Text {...attr} {...rest} style={style} />
6874 }
6975}
7076···7884export const H5 = createHeadingElement({level: 5})
7985export const H6 = createHeadingElement({level: 6})
8086export function P({style, ...rest}: TextProps) {
8181- const t = useTheme()
8287 const attr =
8388 web({
8489 role: 'paragraph',
8590 }) || {}
8691 return (
8787- <RNText
9292+ <Text
8893 {...attr}
8994 {...rest}
9090- style={normalizeTextStyles([
9191- atoms.text_md,
9292- atoms.leading_normal,
9393- t.atoms.text,
9494- flatten(style),
9595- ])}
9595+ style={[atoms.text_md, atoms.leading_normal, flatten(style)]}
9696 />
9797 )
9898}
+4-1
src/view/screens/Storybook/Typography.tsx
···88export function Typography() {
99 return (
1010 <View style={[a.gap_md]}>
1111- <Text style={[a.text_5xl]}>atoms.text_5xl</Text>
1111+ <Text selectable style={[a.text_5xl]}>
1212+ atoms.text_5xl
1313+ </Text>
1214 <Text style={[a.text_4xl]}>atoms.text_4xl</Text>
1315 <Text style={[a.text_3xl]}>atoms.text_3xl</Text>
1416 <Text style={[a.text_2xl]}>atoms.text_2xl</Text>
···2426 value={`This is rich text. It can have mentions like @bsky.app or links like https://bsky.social`}
2527 />
2628 <RichText
2929+ selectable
2730 resolveFacets
2831 value={`This is rich text. It can have mentions like @bsky.app or links like https://bsky.social`}
2932 style={[a.text_xl]}