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:
parent
646cf3d3b2
commit
1f4dd2afca
|
@ -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>
|
||||
|
|
|
@ -60,7 +60,7 @@ function App() {
|
|||
<Topbar
|
||||
blur={shouldBlurTop}
|
||||
channel={selectedChannel}
|
||||
membersVisisble={showMembers}
|
||||
showMembers={showMembers}
|
||||
onMembersPress={() => setShowMembers(show => !show)}
|
||||
/>
|
||||
|
||||
|
|
|
@ -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>
|
||||
)}
|
||||
|
|
|
@ -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>
|
||||
)}
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
})}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 => (
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
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({
|
||||
fonts: {
|
||||
inter: interFont,
|
||||
mono: monoFont,
|
||||
sans: createInterFont({
|
||||
size: {},
|
||||
weight: {},
|
||||
letterSpacing: {},
|
||||
face: {
|
||||
400: { normal: 'Inter' },
|
||||
500: { normal: 'Inter' },
|
||||
600: { normal: 'InterBold' },
|
||||
},
|
||||
}),
|
||||
mono: createFont({
|
||||
family: 'UbuntuMono',
|
||||
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
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export { Text, type TextProps } from './text'
|
|
@ -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
|
|
@ -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 }
|
|
@ -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
|
||||
)}
|
||||
|
|
|
@ -38,7 +38,7 @@ export const Default: Story = {
|
|||
export const WithMembersSelected: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
membersVisisble: true,
|
||||
showMembers: true,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
weight="medium"
|
||||
color="$neutral-80-opa-50"
|
||||
variant="smaller"
|
||||
$sm={{ display: 'none' }}
|
||||
flexShrink={1}
|
||||
flexGrow={1}
|
||||
whiteSpace="nowrap"
|
||||
overflow="hidden"
|
||||
textOverflow="ellipsis"
|
||||
>
|
||||
{description}
|
||||
</Paragraph>
|
||||
<Stack flexGrow={1} flexShrink={1} $sm={{ display: 'none' }}>
|
||||
<Text
|
||||
weight="medium"
|
||||
color="$neutral-80-opa-50"
|
||||
size={13}
|
||||
truncate
|
||||
>
|
||||
{description}
|
||||
</Text>
|
||||
</Stack>
|
||||
)}
|
||||
<Stack $sm={{ display: 'none' }}>
|
||||
<IconButton
|
||||
icon={<MembersIcon />}
|
||||
selected={membersVisisble}
|
||||
selected={showMembers}
|
||||
onPress={onMembersPress}
|
||||
blur={blur}
|
||||
/>
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
export * from './typography'
|
|
@ -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
|
|
@ -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',
|
||||
},
|
||||
})
|
|
@ -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>
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue