Unify typography and enforce only valid variants (#354)

* unify typography under Text component

* migrate from paragraph/heading to text

* update font configuration
This commit is contained in:
Pavel 2023-03-22 10:57:25 +01:00 committed by GitHub
parent 6474b39bac
commit db7befaec2
No known key found for this signature in database
GPG Key ID: 0EB8D75C775AB6F1
25 changed files with 315 additions and 427 deletions

View File

@ -5,7 +5,7 @@
<link rel="icon" type="image/png" href="/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap"
rel="stylesheet"
/>
<title>Status</title>

View File

@ -60,7 +60,7 @@ function App() {
<Topbar
blur={shouldBlurTop}
channel={selectedChannel}
membersVisisble={showMembers}
showMembers={showMembers}
onMembersPress={() => setShowMembers(show => !show)}
/>

View File

@ -4,7 +4,7 @@ import { ChevronRightIcon } from '@status-im/icons/20'
import { Stack } from '@tamagui/core'
import { AnimatePresence } from 'tamagui'
import { Label, Paragraph } from '../typography'
import { Text } from '../text'
type Props = {
children: React.ReactElement[] | React.ReactElement
@ -38,7 +38,7 @@ const Accordion = (props: Props) => {
cursor="pointer"
py={8}
>
<Stack flexDirection="row" alignItems="center">
<Stack flexDirection="row" alignItems="center" gap={4}>
<Stack
animation="fast"
justifyContent="center"
@ -53,14 +53,9 @@ const Accordion = (props: Props) => {
>
<ChevronRightIcon color="$neutral-50" />
</Stack>
<Paragraph
marginLeft={4}
color="$neutral-50"
weight="medium"
variant="smaller"
>
<Text size={13} color="$neutral-50" weight="medium">
{title}
</Paragraph>
</Text>
</Stack>
<AnimatePresence>
{!isExpanded && unreadCount !== 0 && (
@ -90,9 +85,9 @@ const Accordion = (props: Props) => {
justifyContent="center"
alignItems="center"
>
<Label color="$white-100" weight="medium">
<Text size={11} color="$white-100" weight="medium">
{unreadCount}
</Label>
</Text>
</Stack>
</Stack>
)}

View File

@ -1,9 +1,10 @@
import { MutedIcon } from '@status-im/icons/20'
import { Stack, Text } from '@tamagui/core'
import { Stack, Text as RNText } from '@tamagui/core'
import { Label, Paragraph } from '../typography'
import { Text } from '../text'
import type { Channel } from '../sidebar/mock-data'
import type { ColorTokens } from '@tamagui/core'
type Props = {
selected?: boolean
@ -11,7 +12,7 @@ type Props = {
channel: Channel
}
const textColor = {
const textColors: Record<NonNullable<Channel['channelStatus']>, ColorTokens> = {
muted: '$neutral-40',
normal: '$neutral-50',
withMessages: '$neutral-100',
@ -65,17 +66,14 @@ const AccordionItem = (props: Props) => {
backgroundColor="$turquoise-50-opa-10"
justifyContent="center"
alignItems="center"
marginRight={8}
>
<Text>{emoji}</Text>
<RNText>{emoji}</RNText>
</Stack>
)}
<Paragraph
color={textColor[channelStatus]}
weight="medium"
marginLeft={emoji ? 8 : 0}
>
<Text size={15} color={textColors[channelStatus]} weight="medium">
{title}
</Paragraph>
</Text>
</Stack>
{channelStatus !== 'normal' && (
<Stack>
@ -89,9 +87,9 @@ const AccordionItem = (props: Props) => {
justifyContent="center"
alignItems="center"
>
<Label color="$white-100" weight="medium">
<Text size={11} color="$white-100" weight="medium">
{unreadCount}
</Label>
</Text>
</Stack>
</Stack>
)}

View File

@ -5,7 +5,7 @@ import {
} from '@status-im/icons/12'
import { XStack } from 'tamagui'
import { Paragraph } from '../typography'
import { Text } from '../text'
interface Props {
name: string
@ -22,19 +22,19 @@ const Author = (props: Props) => {
return (
<XStack space={8} alignItems="center">
<XStack space={4} alignItems="center">
<Paragraph weight="semibold" variant="smaller" color="$neutral-100">
<Text size={13} weight="semibold">
{name}
</Paragraph>
</Text>
{status === 'contact' && <ContactIcon />}
{status === 'verified' && <VerifiedIcon />}
{status === 'untrustworthy' && <UntrustworthyIcon />}
</XStack>
{address && (
<Paragraph color="$neutral-50" fontSize={11}>
<Text size={11} color="$neutral-50">
{address}
{time && ` · ${time}`}
</Paragraph>
</Text>
)}
</XStack>
)

View File

@ -2,8 +2,9 @@ import { cloneElement, forwardRef } from 'react'
import { Stack, styled } from '@tamagui/core'
import { Paragraph } from '../typography'
import { Text } from '../text'
import type { TextProps } from '../text'
import type { GetVariants, MapVariant, PressableProps } from '../types'
import type { StackProps } from '@tamagui/core'
import type { Ref } from 'react'
@ -30,24 +31,32 @@ const textColors: MapVariant<typeof Base, 'variant'> = {
danger: '$white-100',
}
const textSizes: Record<NonNullable<Props['size']>, TextProps['size']> = {
'40': 15,
'32': 15,
'24': 13,
}
const Button = (props: Props, ref: Ref<HTMLButtonElement>) => {
const {
variant = 'primary',
shape = 'default',
size = 40,
icon = null,
iconAfter = null,
children,
...buttonProps
icon,
iconAfter,
...rest
} = props
// TODO: provider aria-label if button has only icon
const iconOnly = !children && Boolean(icon)
const textColor = textColors[variant]
const textSize = textSizes[size]
return (
<Base
{...(buttonProps as unknown as StackProps)} // TODO: Tamagui has incorrect types for PressableProps
{...rest}
ref={ref}
variant={variant}
radius={shape === 'circle' ? 'full' : size}
@ -55,9 +64,9 @@ const Button = (props: Props, ref: Ref<HTMLButtonElement>) => {
iconOnly={iconOnly}
>
{icon ? cloneElement(icon, { color: textColor }) : null}
<ButtonText color={textColor} size={size}>
<Text color={textColor} size={textSize}>
{children}
</ButtonText>
</Text>
{iconAfter ? cloneElement(iconAfter, { color: textColor }) : null}
</Base>
)
@ -174,24 +183,3 @@ const Base = styled(Stack, {
},
} as const,
})
const ButtonText = styled(Paragraph, {
display: 'flex',
alignItems: 'center',
space: 4,
weight: 'medium',
variants: {
size: {
40: {
variant: 'normal',
},
32: {
variant: 'normal',
},
24: {
variant: 'smaller',
},
},
} as const,
})

View File

@ -1,6 +1,6 @@
import { Stack } from '@tamagui/core'
import { Paragraph } from '../typography'
import { Text } from '../text'
type Props = {
label: string
@ -18,9 +18,9 @@ const DividerLabel = (props: Props) => {
borderColor="$neutral-10"
borderTopWidth={1}
>
<Paragraph color="$neutral-50" weight="medium" variant="smaller">
<Text size={13} color="$neutral-50" weight="medium">
{label}
</Paragraph>
</Text>
</Stack>
)
}

View File

@ -11,7 +11,7 @@ import {
} from '@radix-ui/react-dropdown-menu'
import { Stack, styled } from 'tamagui'
import { Paragraph } from '../typography'
import { Text } from '../text'
const Content = styled(DropdownMenuContent, {
name: 'DropdownMenuContent',
@ -93,9 +93,9 @@ const DropdownMenuItem = (props: DropdownMenuItemProps) => {
return (
<Item onSelect={onSelect}>
<Stack marginRight={12}>{cloneElement(icon, { color: iconColor })}</Stack>
<Paragraph weight="medium" color={textColor}>
<Text size={15} weight="medium" color={textColor}>
{label}
</Paragraph>
</Text>
</Item>
)
}

View File

@ -5,7 +5,7 @@ import * as icons16 from '@status-im/icons/16'
import * as icons20 from '@status-im/icons/20'
import * as reactions from '@status-im/icons/reactions'
import { Paragraph } from '../typography'
import { Text } from '../text'
import type { IconProps } from '@status-im/icons/types'
import type { Meta, StoryObj } from '@storybook/react'
@ -42,7 +42,7 @@ export const All: Story = {
style={{ display: 'flex', flexDirection: 'column' }}
>
<Icon color="$background" />
<Paragraph>{unpascal(name)}</Paragraph>
<Text size={15}>{unpascal(name)}</Text>
</div>
)
})}
@ -59,7 +59,7 @@ export const All: Story = {
style={{ display: 'flex', flexDirection: 'column' }}
>
<Icon color="$background" />
<Paragraph>{unpascal(name)}</Paragraph>
<Text size={15}>{unpascal(name)}</Text>
</div>
)
})}
@ -76,7 +76,7 @@ export const All: Story = {
style={{ display: 'flex', flexDirection: 'column' }}
>
<Icon color="$background" />
<Paragraph>{unpascal(name)}</Paragraph>
<Text size={15}>{unpascal(name)}</Text>
</div>
)
})}
@ -93,7 +93,7 @@ export const All: Story = {
style={{ display: 'flex', flexDirection: 'column' }}
>
<Icon color="$background" />
<Paragraph>{unpascal(name)}</Paragraph>
<Text size={15}>{unpascal(name)}</Text>
</div>
)
})}

View File

@ -9,8 +9,8 @@ export * from './messages'
export * from './provider'
export * from './sidebar'
export * from './sidebar-members'
export * from './text'
export * from './topbar'
export * from './typography'
export * from './user-list'
// MOCK DATA

View File

@ -8,7 +8,7 @@ import { Avatar } from '../avatar'
import { Image } from '../image'
import { useChatDispatch } from '../provider'
import { Reply } from '../reply'
import { Paragraph } from '../typography'
import { Text } from '../text'
import { Actions } from './components/actions'
import { Reactions } from './components/reactions'
@ -92,9 +92,9 @@ const Message = (props: Props) => {
space={2}
>
<PinIcon color="$blue-50" />
<Paragraph variant={11} weight="medium" color="$blue-50">
<Text size={11} weight="medium" color="$blue-50">
Steve
</Paragraph>
</Text>
</Stack>
)}
@ -114,14 +114,13 @@ const Message = (props: Props) => {
/>
{text && (
<Paragraph
flexGrow={0}
weight="regular"
color="$neutral-100"
userSelect="text"
<Text
size={15}
// flexGrow={0}
// userSelect="text"
>
{text}
</Paragraph>
</Text>
)}
{images?.map(image => (

View File

@ -11,7 +11,7 @@ import {
} from '@status-im/icons/reactions'
import { Stack, styled } from '@tamagui/core'
import { Paragraph } from '../typography'
import { Text } from '../text'
import type { GetVariants } from '../types'
import type { StackProps } from '@tamagui/core'
@ -66,9 +66,9 @@ const ReactButton = (props: Props, ref: Ref<HTMLButtonElement>) => {
>
<Icon color="$neutral-100" />
{count && (
<Paragraph weight="medium" variant="smaller" whiteSpace="nowrap">
<Text size={13} weight="medium" wrap={false}>
{count}
</Paragraph>
</Text>
)}
</Button>
)

View File

@ -5,7 +5,7 @@ import { Stack, Unspaced, XStack } from 'tamagui'
import { Avatar } from '../avatar'
import { Button } from '../button'
import { Paragraph } from '../typography'
import { Text } from '../text'
interface Props {
type: 'text' | 'gif' | 'image' | 'deleted'
@ -29,15 +29,15 @@ const Reply = (props: Props) => {
<Avatar size={16} src={src} />
<Paragraph variant="smaller" weight="semibold" color="$neutral-100">
<Text size={13} weight="semibold">
{name}
</Paragraph>
</Text>
<Paragraph variant={11} weight="regular" color="$neutral-50">
<Text size={11} color="$neutral-50">
{type === 'text' && 'What is the meaning of life? '}
{type === 'gif' && 'GIF'}
{type === 'image' && '5 photos'}
</Paragraph>
</Text>
</XStack>
) : (
<XStack position="relative" space={4} alignItems="center" height={24}>
@ -49,9 +49,9 @@ const Reply = (props: Props) => {
<SadIcon color="$neutral-50" />
<Paragraph variant="smaller" weight="medium" color="$neutral-50">
<Text size={13} weight="medium" color="$neutral-50">
Message deleted
</Paragraph>
</Text>
</XStack>
)

View File

@ -6,7 +6,7 @@ import { AccordionItem } from '../accordion/accordionItem'
import { Avatar } from '../avatar'
import { Button } from '../button'
import { Image } from '../image'
import { Heading, Paragraph } from '../typography'
import { Text } from '../text'
import { CHANNEL_GROUPS } from './mock-data'
import type { ChannelGroup } from './mock-data'
@ -58,11 +58,15 @@ const Sidebar = (props: Props) => {
size={80}
/>
</Stack>
<Heading marginBottom={16}>{name}</Heading>
<Paragraph marginBottom={12}>{description}</Paragraph>
<Stack flexDirection="row" alignItems="center" mb={12}>
<Stack gap={8} marginBottom={12}>
<Text size={27} weight="semibold">
{name}
</Text>
<Text size={15}>{description}</Text>
</Stack>
<Stack flexDirection="row" alignItems="center" mb={12} space={8}>
<GroupIcon color="$neutral-100" />
<Paragraph ml={8}>{membersCount}</Paragraph>
<Text size={15}>{membersCount}</Text>
</Stack>
<Button>Join community</Button>

View File

@ -7,6 +7,12 @@ import { animations } from './animations'
import { themes } from './themes'
import { tokens } from './tokens'
import type {
ColorTokens,
GetStyledVariants,
TamaguiComponent,
} from '@tamagui/core'
export type Conf = typeof config
declare module '@tamagui/core' {
@ -14,81 +20,25 @@ declare module '@tamagui/core' {
interface TamaguiCustomConfig extends Conf {}
}
const interFont = createInterFont({
size: {
6: 11,
7: 13,
8: 15,
9: 19,
10: 27,
},
weight: {
6: '400',
7: '500',
8: '600',
},
letterSpacing: {
5: 2,
6: 1,
7: 0,
8: -1,
9: -2,
10: -3,
12: -4,
14: -5,
15: -6,
},
export const config = createTamagui({
fonts: {
sans: createInterFont({
size: {},
weight: {},
letterSpacing: {},
face: {
400: { normal: 'Inter' },
500: { normal: 'Inter' },
600: { normal: 'InterBold' },
},
})
const monoFont = createFont({
}),
mono: createFont({
family: 'UbuntuMono',
weight: {
1: '500',
},
letterSpacing: {
5: 2,
6: 1,
7: 0,
8: -1,
9: -2,
10: -3,
12: -4,
14: -5,
15: -6,
},
size: {
1: 11,
2: 12,
3: 13,
4: 14,
5: 16,
6: 18,
7: 20,
8: 22,
9: 30,
10: 42,
11: 52,
12: 62,
13: 72,
14: 92,
15: 114,
16: 124,
},
lineHeight: {
1: 14,
2: 15,
},
})
export const config = createTamagui({
fonts: {
inter: interFont,
mono: monoFont,
weight: {},
letterSpacing: {},
size: {},
lineHeight: {},
}),
},
themes,
tokens: {
@ -117,3 +67,11 @@ export const config = createTamagui({
shorthands,
animations,
})
export type TextColor<
C extends TamaguiComponent,
K extends keyof V,
V extends GetStyledVariants<C> = GetStyledVariants<C>
> = {
[P in V[K] & string]: ColorTokens
}

View File

@ -0,0 +1 @@
export { Text, type TextProps } from './text'

View File

@ -0,0 +1,61 @@
import { Stack } from '@tamagui/core'
import { Text } from './text'
import type { Meta, StoryObj } from '@storybook/react'
const meta: Meta = {
title: 'Text',
args: {
children: 'The quick brown fox jumped over the lazy dog.',
},
argTypes: {},
parameters: {
design: {
type: 'figma',
url: 'https://www.figma.com/file/v98g9ZiaSHYUdKWrbFg9eM/Foundations?node-id=617-208&t=ppNe6QC4ntgNciqw-11',
},
},
}
export const TextStory: StoryObj<typeof Text> = {
name: 'TextNew',
render: args => (
<Stack gap={24}>
<Stack gap={8}>
<Text {...args} size={27} weight="regular" />
<Text {...args} size={27} weight="medium" />
<Text {...args} size={27} weight="semibold" />
</Stack>
<Stack gap={8}>
<Text {...args} size={19} weight="regular" />
<Text {...args} size={19} weight="medium" />
<Text {...args} size={19} weight="semibold" />
</Stack>
<Stack gap={8}>
<Text {...args} size={15} weight="regular" />
<Text {...args} size={15} weight="medium" />
<Text {...args} size={15} weight="semibold" />
</Stack>
<Stack gap={8}>
<Text {...args} size={13} weight="regular" />
<Text {...args} size={13} weight="medium" />
<Text {...args} size={13} weight="semibold" />
</Stack>
<Stack gap={8}>
<Text {...args} size={11} weight="regular" />
<Text {...args} size={11} weight="medium" />
<Text {...args} size={11} weight="semibold" />
<Text {...args} size={11} weight="regular" uppercase />
<Text {...args} size={11} weight="medium" uppercase />
<Text {...args} size={11} weight="semibold" uppercase />
</Stack>
</Stack>
),
}
export default meta

View File

@ -0,0 +1,119 @@
import { forwardRef } from 'react'
import { styled, Text as BaseText } from '@tamagui/core'
import type { ColorTokens, GetProps } from '@tamagui/core'
import type { Ref } from 'react'
import type { Text as RNText } from 'react-native'
type Variants = GetProps<typeof Base>
type Type = NonNullable<Variants['type']>
type Weight = NonNullable<Variants['weight']>
type Props = {
children: React.ReactNode
color?: ColorTokens
truncate?: boolean
wrap?: false
} & (
| { size: 27; weight?: Weight }
| { size: 19; weight?: Weight }
| { size: 15; weight?: Weight; type?: Type }
| { size: 13; weight?: Weight; type?: Type }
| { size: 11; weight?: Weight; type?: Type; uppercase?: boolean }
)
// TODO: monospace should be used only for variant. Extract to separate <Address> component?
// TODO: Ubuntu Mono should be used only for code snippets. Extract to separate <Code> component?
const Text = (props: Props, ref: Ref<RNText>) => {
const { color = '$neutral-100', ...rest } = props
return <Base {...rest} ref={ref} color={color} />
}
const Base = styled(BaseText, {
name: 'Text',
variants: {
type: {
default: {
fontFamily: '$sans',
},
monospace: {
fontFamily: '$mono',
},
},
size: {
27: {
fontSize: 27,
lineHeight: 32,
letterSpacing: -0.021,
},
19: {
fontSize: 19,
lineHeight: 26,
letterSpacing: -0.016,
},
15: {
fontSize: 15,
lineHeight: 22,
letterSpacing: -0.009,
},
13: {
fontSize: 13,
lineHeight: 18,
letterSpacing: -0.003,
},
11: {
fontSize: 11,
lineHeight: 18,
letterSpacing: -0.003,
},
},
weight: {
regular: {
fontWeight: '400',
},
medium: {
fontWeight: '500',
},
semibold: {
fontWeight: '600',
},
},
uppercase: {
true: {
textTransform: 'uppercase',
},
},
wrap: {
false: {
whiteSpace: 'nowrap',
},
},
truncate: {
true: {
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
wordWrap: 'normal',
maxWidth: '100%',
minWidth: 0,
},
},
} as const,
defaultVariants: {
type: 'default',
weight: 'regular',
},
})
const _Text = forwardRef(Text)
export { _Text as Text }
export type { Props as TextProps }

View File

@ -10,7 +10,7 @@ import {
} from '@radix-ui/react-tooltip'
import { Stack } from 'tamagui'
import { Paragraph } from '../typography'
import { Text } from '../text'
import type { TooltipContentProps } from '@radix-ui/react-tooltip'
import type { Ref } from 'react'
@ -62,9 +62,9 @@ const Tooltip = (props: Props, ref: Ref<HTMLButtonElement>) => {
shadowColor="rgba(9, 16, 28, 0.12)"
>
{typeof content === 'string' ? (
<Paragraph variant="smaller" weight="medium" color="$white-100">
<Text size={13} weight="medium" color="$white-100">
{content}
</Paragraph>
</Text>
) : (
content
)}

View File

@ -38,7 +38,7 @@ export const Default: Story = {
export const WithMembersSelected: Story = {
args: {
...Default.args,
membersVisisble: true,
showMembers: true,
},
}

View File

@ -10,18 +10,18 @@ import {
ShareIcon,
UpToDateIcon,
} from '@status-im/icons/20'
import { Stack, Text } from '@tamagui/core'
import { Stack, Text as RNText } from '@tamagui/core'
import { BlurView } from 'expo-blur'
import { Divider } from '../divider'
import { DropdownMenu } from '../dropdown-menu'
import { IconButton } from '../icon-button'
import { Paragraph } from '../typography'
import { Text } from '../text'
import type { Channel } from '../sidebar/mock-data'
type Props = {
membersVisisble: boolean
showMembers: boolean
onMembersPress: () => void
goBack?: () => void
channel: Channel
@ -29,7 +29,7 @@ type Props = {
}
const Topbar = (props: Props) => {
const { membersVisisble, onMembersPress, goBack, blur, channel } = props
const { showMembers, onMembersPress, goBack, blur, channel } = props
const { title, description, emoji } = channel
@ -57,14 +57,14 @@ const Topbar = (props: Props) => {
{emoji && (
<Stack marginRight={12}>
<Text>{emoji}</Text>
<RNText>{emoji}</RNText>
</Stack>
)}
{title && (
<Paragraph weight="semibold" marginRight={4}>
<Text size={15} weight="semibold">
{title}
</Paragraph>
</Text>
)}
<LockedIcon color="$neutral-80-opa-40" />
@ -81,24 +81,21 @@ const Topbar = (props: Props) => {
$sm={{ justifyContent: 'flex-end' }}
>
{description && (
<Paragraph
<Stack flexGrow={1} flexShrink={1} $sm={{ display: 'none' }}>
<Text
weight="medium"
color="$neutral-80-opa-50"
variant="smaller"
$sm={{ display: 'none' }}
flexShrink={1}
flexGrow={1}
whiteSpace="nowrap"
overflow="hidden"
textOverflow="ellipsis"
size={13}
truncate
>
{description}
</Paragraph>
</Text>
</Stack>
)}
<Stack $sm={{ display: 'none' }}>
<IconButton
icon={<MembersIcon />}
selected={membersVisisble}
selected={showMembers}
onPress={onMembersPress}
blur={blur}
/>

View File

@ -1 +0,0 @@
export * from './typography'

View File

@ -1,60 +0,0 @@
import { Stack } from '@tamagui/core'
import { Code, Heading, Paragraph } from '.'
import type { Meta, StoryObj } from '@storybook/react'
const meta: Meta = {
title: 'typography',
argTypes: {},
}
export const HeadingStory: StoryObj<typeof Heading> = {
name: 'Heading',
args: {
children: 'The quick brown fox jumped over the lazy dog.',
},
render: args => (
<Stack>
<Heading {...args} weight="regular" />
<Heading {...args} weight="medium" />
<Heading {...args} weight="semibold" />
<Heading {...args} weight="regular" heading="h2" />
<Heading {...args} weight="medium" heading="h2" />
<Heading {...args} weight="semibold" heading="h2" />
</Stack>
),
}
export const TextStory: StoryObj<typeof Paragraph> = {
name: 'Text',
args: {
children: 'The quick brown fox jumped over the lazy dog.',
},
render: args => (
<Stack>
<Paragraph {...args} weight="regular" />
<Paragraph {...args} weight="medium" />
<Paragraph {...args} weight="semibold" />
<Paragraph {...args} weight="regular" variant="smaller" />
<Paragraph {...args} weight="medium" variant="smaller" />
<Paragraph {...args} weight="semibold" variant="smaller" />
</Stack>
),
}
export const CodeStory: StoryObj<typeof Code> = {
name: 'Code',
args: {
children: '// How to create variables:',
},
render: () => (
<Stack>
<Code weight="regular">
The quick brown fox jumped over the lazy dog.
</Code>
</Stack>
),
}
export default meta

View File

@ -1,171 +0,0 @@
import { styled } from '@tamagui/core'
import { SizableText } from 'tamagui'
export const Heading = styled(SizableText, {
name: 'Heading',
fontFamily: '$inter',
color: '$textPrimary',
variants: {
heading: {
h1: {
fontSize: 27,
lineHeight: 32,
letterSpacing: -0.021,
},
h2: {
fontSize: 19,
lineHeight: 26,
letterSpacing: -0.016,
},
},
uppercase: {
true: {
textTransform: 'uppercase',
},
},
weight: {
regular: {
fontWeight: '400',
},
medium: {
fontWeight: '500',
},
semibold: {
fontWeight: '600',
},
},
} as const,
defaultVariants: {
// note tamagui uses a generic "true" token that your sizes should set to be the same as the default on your scale
size: '$true',
heading: 'h1',
},
})
export const Paragraph = styled(SizableText, {
name: 'Paragraph',
fontFamily: '$inter',
color: '$textPrimary',
variants: {
variant: {
normal: {
fontSize: 15,
lineHeight: 22,
letterSpacing: -0.009,
},
smaller: {
fontSize: 13,
lineHeight: 18,
letterSpacing: -0.003,
},
11: {
fontSize: 11,
lineHeight: 18,
letterSpacing: -0.003,
},
},
uppercase: {
true: {
textTransform: 'uppercase',
},
},
weight: {
regular: {
fontWeight: '400',
},
medium: {
fontWeight: '500',
},
semibold: {
fontWeight: '600',
},
},
} as const,
defaultVariants: {
// note tamagui uses a generic "true" token that your sizes should set to be the same as the default on your scale
size: '$true',
variant: 'normal',
weight: 'regular',
},
})
export const Label = styled(SizableText, {
name: 'Label',
fontFamily: '$inter',
color: '$textPrimary',
fontSize: 11,
lineHeight: 16,
letterSpacing: -0.005,
variants: {
uppercase: {
true: {
textTransform: 'uppercase',
},
},
weight: {
regular: {
fontWeight: '400',
},
medium: {
fontWeight: '500',
},
semibold: {
fontWeight: '600',
},
},
} as const,
defaultVariants: {
// note tamagui uses a generic "true" token that your sizes should set to be the same as the default on your scale
size: '$true',
weight: 'regular',
},
})
export const Code = styled(SizableText, {
name: 'Code',
fontFamily: '$mono',
color: '$textPrimary',
fontSize: 11,
lineHeight: 16,
letterSpacing: -0.005,
variants: {
normal: {
fontSize: 15,
lineHeight: 22,
letterSpacing: -0.009,
},
smaller: {
fontSize: 13,
lineHeight: 18,
letterSpacing: -0.003,
},
uppercase: {
true: {
textTransform: 'uppercase',
},
},
weight: {
regular: {
fontWeight: '400',
},
medium: {
fontWeight: '500',
},
semibold: {
fontWeight: '600',
},
},
} as const,
defaultVariants: {
// note tamagui uses a generic "true" token that your sizes should set to be the same as the default on your scale
size: '$true',
variant: 'normal',
weight: 'regular',
},
})

View File

@ -2,7 +2,7 @@ import { XStack, YStack } from 'tamagui'
import { Author } from '../author/author'
import { Avatar } from '../avatar'
import { Paragraph } from '../typography'
import { Text } from '../text'
import type { AuthorProps } from '../author/author'
import type { AvatarProps } from '../avatar'
@ -37,9 +37,9 @@ const UserList = (props: Props) => {
status={user.status}
orientation="vertical"
/>
<Paragraph variant="smaller" color="$neutral-50">
<Text size={13} color="$neutral-50">
{user.address}
</Paragraph>
</Text>
</YStack>
</XStack>
)