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" /> <link rel="icon" type="image/png" href="/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link <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" rel="stylesheet"
/> />
<title>Status</title> <title>Status</title>

View File

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

View File

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

View File

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

View File

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

View File

@ -2,8 +2,9 @@ import { cloneElement, forwardRef } from 'react'
import { Stack, styled } from '@tamagui/core' 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 { GetVariants, MapVariant, PressableProps } from '../types'
import type { StackProps } from '@tamagui/core' import type { StackProps } from '@tamagui/core'
import type { Ref } from 'react' import type { Ref } from 'react'
@ -30,24 +31,32 @@ const textColors: MapVariant<typeof Base, 'variant'> = {
danger: '$white-100', 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 Button = (props: Props, ref: Ref<HTMLButtonElement>) => {
const { const {
variant = 'primary', variant = 'primary',
shape = 'default', shape = 'default',
size = 40, size = 40,
icon = null,
iconAfter = null,
children, children,
...buttonProps icon,
iconAfter,
...rest
} = props } = props
// TODO: provider aria-label if button has only icon // TODO: provider aria-label if button has only icon
const iconOnly = !children && Boolean(icon) const iconOnly = !children && Boolean(icon)
const textColor = textColors[variant] const textColor = textColors[variant]
const textSize = textSizes[size]
return ( return (
<Base <Base
{...(buttonProps as unknown as StackProps)} // TODO: Tamagui has incorrect types for PressableProps {...rest}
ref={ref} ref={ref}
variant={variant} variant={variant}
radius={shape === 'circle' ? 'full' : size} radius={shape === 'circle' ? 'full' : size}
@ -55,9 +64,9 @@ const Button = (props: Props, ref: Ref<HTMLButtonElement>) => {
iconOnly={iconOnly} iconOnly={iconOnly}
> >
{icon ? cloneElement(icon, { color: textColor }) : null} {icon ? cloneElement(icon, { color: textColor }) : null}
<ButtonText color={textColor} size={size}> <Text color={textColor} size={textSize}>
{children} {children}
</ButtonText> </Text>
{iconAfter ? cloneElement(iconAfter, { color: textColor }) : null} {iconAfter ? cloneElement(iconAfter, { color: textColor }) : null}
</Base> </Base>
) )
@ -174,24 +183,3 @@ const Base = styled(Stack, {
}, },
} as const, } 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 { Stack } from '@tamagui/core'
import { Paragraph } from '../typography' import { Text } from '../text'
type Props = { type Props = {
label: string label: string
@ -18,9 +18,9 @@ const DividerLabel = (props: Props) => {
borderColor="$neutral-10" borderColor="$neutral-10"
borderTopWidth={1} borderTopWidth={1}
> >
<Paragraph color="$neutral-50" weight="medium" variant="smaller"> <Text size={13} color="$neutral-50" weight="medium">
{label} {label}
</Paragraph> </Text>
</Stack> </Stack>
) )
} }

View File

@ -11,7 +11,7 @@ import {
} from '@radix-ui/react-dropdown-menu' } from '@radix-ui/react-dropdown-menu'
import { Stack, styled } from 'tamagui' import { Stack, styled } from 'tamagui'
import { Paragraph } from '../typography' import { Text } from '../text'
const Content = styled(DropdownMenuContent, { const Content = styled(DropdownMenuContent, {
name: 'DropdownMenuContent', name: 'DropdownMenuContent',
@ -93,9 +93,9 @@ const DropdownMenuItem = (props: DropdownMenuItemProps) => {
return ( return (
<Item onSelect={onSelect}> <Item onSelect={onSelect}>
<Stack marginRight={12}>{cloneElement(icon, { color: iconColor })}</Stack> <Stack marginRight={12}>{cloneElement(icon, { color: iconColor })}</Stack>
<Paragraph weight="medium" color={textColor}> <Text size={15} weight="medium" color={textColor}>
{label} {label}
</Paragraph> </Text>
</Item> </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 icons20 from '@status-im/icons/20'
import * as reactions from '@status-im/icons/reactions' 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 { IconProps } from '@status-im/icons/types'
import type { Meta, StoryObj } from '@storybook/react' import type { Meta, StoryObj } from '@storybook/react'
@ -42,7 +42,7 @@ export const All: Story = {
style={{ display: 'flex', flexDirection: 'column' }} style={{ display: 'flex', flexDirection: 'column' }}
> >
<Icon color="$background" /> <Icon color="$background" />
<Paragraph>{unpascal(name)}</Paragraph> <Text size={15}>{unpascal(name)}</Text>
</div> </div>
) )
})} })}
@ -59,7 +59,7 @@ export const All: Story = {
style={{ display: 'flex', flexDirection: 'column' }} style={{ display: 'flex', flexDirection: 'column' }}
> >
<Icon color="$background" /> <Icon color="$background" />
<Paragraph>{unpascal(name)}</Paragraph> <Text size={15}>{unpascal(name)}</Text>
</div> </div>
) )
})} })}
@ -76,7 +76,7 @@ export const All: Story = {
style={{ display: 'flex', flexDirection: 'column' }} style={{ display: 'flex', flexDirection: 'column' }}
> >
<Icon color="$background" /> <Icon color="$background" />
<Paragraph>{unpascal(name)}</Paragraph> <Text size={15}>{unpascal(name)}</Text>
</div> </div>
) )
})} })}
@ -93,7 +93,7 @@ export const All: Story = {
style={{ display: 'flex', flexDirection: 'column' }} style={{ display: 'flex', flexDirection: 'column' }}
> >
<Icon color="$background" /> <Icon color="$background" />
<Paragraph>{unpascal(name)}</Paragraph> <Text size={15}>{unpascal(name)}</Text>
</div> </div>
) )
})} })}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,6 +7,12 @@ import { animations } from './animations'
import { themes } from './themes' import { themes } from './themes'
import { tokens } from './tokens' import { tokens } from './tokens'
import type {
ColorTokens,
GetStyledVariants,
TamaguiComponent,
} from '@tamagui/core'
export type Conf = typeof config export type Conf = typeof config
declare module '@tamagui/core' { declare module '@tamagui/core' {
@ -14,81 +20,25 @@ declare module '@tamagui/core' {
interface TamaguiCustomConfig extends Conf {} 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,
},
face: {
400: { normal: 'Inter' },
500: { normal: 'Inter' },
600: { normal: 'InterBold' },
},
})
const monoFont = 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({ export const config = createTamagui({
fonts: { fonts: {
inter: interFont, sans: createInterFont({
mono: monoFont, size: {},
weight: {},
letterSpacing: {},
face: {
400: { normal: 'Inter' },
500: { normal: 'Inter' },
600: { normal: 'InterBold' },
},
}),
mono: createFont({
family: 'UbuntuMono',
weight: {},
letterSpacing: {},
size: {},
lineHeight: {},
}),
}, },
themes, themes,
tokens: { tokens: {
@ -117,3 +67,11 @@ export const config = createTamagui({
shorthands, shorthands,
animations, 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' } from '@radix-ui/react-tooltip'
import { Stack } from 'tamagui' import { Stack } from 'tamagui'
import { Paragraph } from '../typography' import { Text } from '../text'
import type { TooltipContentProps } from '@radix-ui/react-tooltip' import type { TooltipContentProps } from '@radix-ui/react-tooltip'
import type { Ref } from 'react' import type { Ref } from 'react'
@ -62,9 +62,9 @@ const Tooltip = (props: Props, ref: Ref<HTMLButtonElement>) => {
shadowColor="rgba(9, 16, 28, 0.12)" shadowColor="rgba(9, 16, 28, 0.12)"
> >
{typeof content === 'string' ? ( {typeof content === 'string' ? (
<Paragraph variant="smaller" weight="medium" color="$white-100"> <Text size={13} weight="medium" color="$white-100">
{content} {content}
</Paragraph> </Text>
) : ( ) : (
content content
)} )}

View File

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

View File

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