From 1df8c16091d6d9098dba32eb13bfafcbaaf7931d Mon Sep 17 00:00:00 2001 From: Jakub Kotula <520927+jkbktl@users.noreply.github.com> Date: Tue, 25 Apr 2023 12:02:58 +0200 Subject: [PATCH] Refactor Context tag component (#379) * switch * context tag refactor * merge conflicts * use new Avatar component * clean up * clean up * simplify * fix * fix * omg final fix * pr fixes * type fix * fix positioning * clean up --- packages/components/package.json | 2 +- packages/components/src/avatar/avatar.tsx | 8 +- .../src/context-tag/context-tag.stories.tsx | 550 +++++++++++++++++- .../src/context-tag/context-tag.tsx | 283 ++++++--- .../src/pinned-message/pinned-message.tsx | 9 +- 5 files changed, 735 insertions(+), 117 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index a8145bba..94e0ce2b 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -37,8 +37,8 @@ "@radix-ui/react-tabs": "^1.0.3", "@radix-ui/react-toast": "^1.1.3", "@radix-ui/react-tooltip": "^1.0.5", - "@status-im/icons": "*", "@status-im/colors": "*", + "@status-im/icons": "*", "@tamagui/animations-css": "1.11.1", "@tamagui/animations-react-native": "1.11.1", "@tamagui/core": "1.11.1", diff --git a/packages/components/src/avatar/avatar.tsx b/packages/components/src/avatar/avatar.tsx index 5446edb6..0715edd7 100644 --- a/packages/components/src/avatar/avatar.tsx +++ b/packages/components/src/avatar/avatar.tsx @@ -41,7 +41,7 @@ type WalletAvatarProps = { type ChannelAvatarProps = { type: 'channel' - size: 80 | 32 | 24 | 20 + size: 80 | 32 | 28 | 24 | 20 emoji: string backgroundColor?: ColorTokens background?: ColorTokens @@ -50,7 +50,7 @@ type ChannelAvatarProps = { type CommunityAvatarProps = { type: 'community' - size: 80 | 32 | 24 | 20 + size: 80 | 32 | 28 | 24 | 20 name: string src?: string backgroundColor?: ColorTokens @@ -66,7 +66,7 @@ type AccountAvatarProps = { type IconAvatarProps = { type: 'icon' - size: 48 | 32 | 20 + size: 48 | 32 | 28 | 24 | 20 icon: React.ReactElement backgroundColor?: ColorTokens color?: ColorTokens @@ -108,6 +108,7 @@ const channelEmojiSizes: Record = // todo: design review '80': 27, '32': 15, + '28': 13, '24': 13, '20': 11, } @@ -145,6 +146,7 @@ const channelLockIconVariants: Record< // todo: design review '80': { baseVariant: 80, iconSize: 40 }, '32': { baseVariant: 24, iconSize: 12 }, + '28': { baseVariant: 24, iconSize: 12 }, '24': { baseVariant: 24, iconSize: 12 }, '20': { baseVariant: 20, iconSize: 12 }, } diff --git a/packages/components/src/context-tag/context-tag.stories.tsx b/packages/components/src/context-tag/context-tag.stories.tsx index 32da2347..ee5d1c7e 100644 --- a/packages/components/src/context-tag/context-tag.stories.tsx +++ b/packages/components/src/context-tag/context-tag.stories.tsx @@ -1,5 +1,5 @@ -import { PendingIcon } from '@status-im/icons' -import { Stack } from '@tamagui/core' +import { MembersIcon, PendingIcon } from '@status-im/icons' +import { Stack } from 'tamagui' import { ContextTag } from './context-tag' @@ -8,9 +8,19 @@ import type { Meta, StoryObj } from '@storybook/react' const meta: Meta = { component: ContextTag, argTypes: { - label: { - control: ['Rarible', '# channel-name'], - }, + type: [ + 'default', + 'account', + 'group', + 'community', + 'channel', + 'token', + 'network', + 'collectible', + 'address', + 'icon', + 'audio', + ], size: [24, 32], outline: [true, false], blur: [true, false], @@ -19,8 +29,14 @@ const meta: Meta = { type Story = StoryObj -export const Base: Story = { - args: { label: 'Name', size: 24, outline: false, blur: false }, +export const Default: Story = { + args: { + type: 'account', + user: { name: 'user name ', emoji: '🐷' }, + size: 24, + outline: false, + blur: false, + }, } export const AllVariants: Story = { @@ -28,31 +44,501 @@ export const AllVariants: Story = { render: () => ( - - - - - - - - - - } - type="icon" - label="Context" - outline - /> - + + + , + }} + size={24} + /> + + + + + + + + } + type="icon" + label="Context" + size={24} + /> + + + + + + , + }} + size={32} + /> + + + + + + + + } + type="icon" + label="Context" + size={32} + /> + + + + + + + + , + }} + size={24} + outline + /> + + + + + + + + } + type="icon" + label="Context" + size={24} + outline + /> + + + + + + , + }} + size={32} + outline + /> + + + + + + + + } + type="icon" + label="Context" + size={32} + outline + /> + + + + + + + + , + }} + size={24} + blur + /> + + + + + + + + } + type="icon" + label="Context" + size={24} + blur + /> + + + + + + , + }} + size={32} + blur + /> + + + + + + + + } + type="icon" + label="Context" + size={32} + blur + /> + + ), diff --git a/packages/components/src/context-tag/context-tag.tsx b/packages/components/src/context-tag/context-tag.tsx index b8ebfcaa..a8961469 100644 --- a/packages/components/src/context-tag/context-tag.tsx +++ b/packages/components/src/context-tag/context-tag.tsx @@ -1,93 +1,228 @@ -import { cloneElement, Fragment } from 'react' - -import { ChevronRightIcon } from '@status-im/icons' -import { styled } from '@tamagui/core' +import { ChevronRightIcon, PlayIcon } from '@status-im/icons' +import { Stack, styled } from '@tamagui/core' import { View } from 'react-native' import { Avatar } from '../avatar' import { Text } from '../text' -import type { AvatarProps } from '../avatar' import type { TextProps } from '../text' -type ContextTagType = - | 'default' - | 'group' - | 'channel' - | 'community' - | 'token' - | 'network' - | 'account' - | 'collectible' - | 'address' - | 'icon' - | 'audio' - type Props = { children?: React.ReactNode - src?: string - icon?: React.ReactElement - label: string | [string, string] - type?: ContextTagType size?: 24 | 32 blur?: boolean outline?: boolean -} +} & ( + | { type: 'default'; user: { name: string; src: string } } + | { type: 'account'; user: { name: string; emoji: string } } + | { + type: 'group' + group: { + name: string + icon: React.ReactElement + } + } + | { type: 'community'; community: { name: string; src: string } } + | { + type: 'channel' + channel: { communityName: string; src: string; name: string } + } + | { type: 'token'; token: { name: string; src: string } } + | { type: 'network'; network: { name: string; src: string } } + | { type: 'collectible'; collectible: { name: string; src: string } } + | { type: 'address'; address: string } + | { type: 'icon'; icon: React.ReactElement; label: string } + | { type: 'audio'; audioLength: string } +) const textSizes: Record, TextProps['size']> = { '32': 15, '24': 13, } -const avatarSizes: Record, AvatarProps['size']> = { +const avatarSizes: Record, 28 | 20> = { '32': 28, '24': 20, } -const Label = ({ children, size }: { children: string; size: 24 | 32 }) => ( - +const Label = ({ + children, + size, + type = 'default', +}: { + children: string + size: 24 | 32 + type?: 'default' | 'monospace' +}) => ( + {children} ) const ContextTag = (props: Props) => { - const { - src, - icon, - label, - // type = 'default', // this is commented because it's not being used - size = 24, - blur = false, - outline, - } = props + const { size = 24, blur = false, outline, type } = props - const hasImg = Boolean(src || icon) + const rounded = type === 'account' || type === 'collectible' + const hasAvatar = type !== 'address' + + const renderContent = () => { + switch (type) { + case 'default': { + return ( + <> + + + + ) + } + case 'community': { + return ( + <> + + + + ) + } + case 'channel': { + return ( + <> + + + + + + + + ) + } + case 'token': { + return ( + <> + + + + ) + } + case 'address': { + return ( + + ) + } + case 'audio': { + return ( + <> + } + backgroundColor="$primary-50" + color="$white-100" + /> + + + ) + } + case 'account': { + return ( + <> + + + + ) + } + case 'group': { + return ( + <> + + + + ) + } + case 'network': { + return ( + <> + + + + ) + } + case 'collectible': { + return ( + <> + + + + ) + } + case 'icon': { + return ( + <> + + + + ) + } + } + } return ( - - {src && } - {icon && cloneElement(icon, { color: '$neutral-50' })} - - {Array.isArray(label) ? ( - label.map((item, i) => { - if (i !== 0) { - return ( - - - - - ) - } else { - return ( - - ) - } - }) - ) : ( - - )} + + {renderContent()} ) } @@ -97,8 +232,6 @@ export type { Props as ContextTagProps } const Base = styled(View, { backgroundColor: '$neutral-10', - paddingVertical: 1, - borderRadius: '$20', display: 'inline-flex', flexDirection: 'row', alignItems: 'center', @@ -124,24 +257,16 @@ const Base = styled(View, { }, }, size: { - 24: props => { - // there is only first param which is "size" and hasImg doesn't exist here - return { - space: 4, - paddingLeft: props.hasImg ? 8 : 2, - paddingRight: 8, - } + 24: { + height: 24, + gap: 4, + paddingHorizontal: 8, + }, + 32: { + height: 32, + gap: 8, + paddingHorizontal: 12, }, - 32: ({ hasImg }) => ({ - // this therefore doesn't work as well - space: 8, - paddingLeft: hasImg ? 12 : 2, - paddingRight: 12, - }), }, - hasImg: { - true: {}, - false: {}, - }, // to correctly infer the type of the variant } as const, }) diff --git a/packages/components/src/pinned-message/pinned-message.tsx b/packages/components/src/pinned-message/pinned-message.tsx index c64d234f..1a2583e8 100644 --- a/packages/components/src/pinned-message/pinned-message.tsx +++ b/packages/components/src/pinned-message/pinned-message.tsx @@ -36,8 +36,13 @@ const PinnedMessage = (props: Props) => { Pinned Messages