Add system messages (#356)

* add DynamicButton component

* add AnchorActions component

* add AnchorActions to web app
This commit is contained in:
Pavel 2023-03-22 14:42:04 +01:00 committed by GitHub
parent 25eb3f24f3
commit a167396062
No known key found for this signature in database
GPG Key ID: 0EB8D75C775AB6F1
7 changed files with 152 additions and 0 deletions

View File

@ -1,6 +1,7 @@
import { useMemo, useRef, useState } from 'react' import { useMemo, useRef, useState } from 'react'
import { import {
AnchorActions,
CHANNEL_GROUPS, CHANNEL_GROUPS,
Composer, Composer,
Messages, Messages,
@ -69,6 +70,9 @@ function App() {
<Messages /> <Messages />
</div> </div>
<div id="composer"> <div id="composer">
<div id="anchor-actions">
<AnchorActions scrolled={shouldBlurBottom} />
</div>
<Composer blur={shouldBlurBottom} /> <Composer blur={shouldBlurBottom} />
</div> </div>
</div> </div>

View File

@ -52,6 +52,12 @@ body,
padding: 32px 8px; padding: 32px 8px;
} }
#anchor-actions {
position: absolute;
right: 20px;
transform: translateY(calc(-100% - 12px));
}
#composer { #composer {
position: sticky; position: sticky;
bottom: 0; bottom: 0;

View File

@ -0,0 +1,20 @@
import { Stack } from 'tamagui'
import { DynamicButton } from '../dynamic-button'
type Props = {
scrolled: boolean
}
const AnchorActions = (props: Props) => {
const { scrolled } = props
return (
<Stack flexDirection="row" space={8}>
{scrolled && <DynamicButton type="mention" count={1} />}
{scrolled && <DynamicButton type="notification" count={0} />}
</Stack>
)
}
export { AnchorActions }

View File

@ -0,0 +1,27 @@
import { XStack } from 'tamagui'
import { DynamicButton } from './dynamic-button'
import type { Meta, StoryObj } from '@storybook/react'
// More on how to set up stories at: https://storybook.js.org/docs/7.0/react/writing-stories/introduction
const meta: Meta<typeof DynamicButton> = {
title: 'DynamicButton',
component: DynamicButton,
args: {},
argTypes: {},
}
type Story = StoryObj<typeof DynamicButton>
export const Default: Story = {
render: () => (
<XStack space={4}>
<DynamicButton type="mention" count={7} />
<DynamicButton type="notification" count={8} />
<DynamicButton type="notification" count={0} />
</XStack>
),
}
export default meta

View File

@ -0,0 +1,92 @@
import { forwardRef } from 'react'
import { ArrowDownIcon, MentionIcon } from '@status-im/icons/12'
import { Stack, styled } from '@tamagui/core'
import { Shadow } from '../shadow'
import { Text } from '../text'
import type { GetVariants } from '../types'
import type { ColorTokens, StackProps } from '@tamagui/core'
import type { Ref } from 'react'
import type { PressableProps } from 'react-native'
type Variants = GetVariants<typeof Button>
type Props = PressableProps & {
type: Variants['type']
count: number
}
const DynamicButton = (props: Props, ref: Ref<HTMLButtonElement>) => {
const { type, count, ...pressableProps } = props
const color: ColorTokens = '$white-100'
const showCount = Boolean(count)
return (
<Shadow variant="$2" borderRadius={999}>
<Button
{...(pressableProps as unknown as StackProps)} // TODO: Tamagui has incorrect types for PressableProps
ref={ref}
type={type}
iconOnly={showCount === false}
>
{type === 'mention' && <MentionIcon color={color} />}
{showCount && (
<Text size={13} weight="medium" color={color} wrap={false}>
{count}
</Text>
)}
{type === 'notification' && <ArrowDownIcon color={color} />}
</Button>
</Shadow>
)
}
const _DynamicButton = forwardRef(DynamicButton)
export { _DynamicButton as DynamicButton }
export type { Props as DynamicButtonProps }
const Button = styled(Stack, {
name: 'DynamicButton',
accessibilityRole: 'button',
tag: 'button',
cursor: 'pointer',
userSelect: 'none',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
flexShrink: 0,
height: 24,
borderRadius: 999,
animation: 'fast',
space: 3,
variants: {
type: {
mention: {
backgroundColor: '$primary-50',
hoverStyle: { backgroundColor: '$primary-60' },
pressStyle: { backgroundColor: '$primary-50' },
},
notification: {
backgroundColor: '$neutral-80-opa-70',
hoverStyle: { backgroundColor: '$neutral-90-opa-70' },
pressStyle: { backgroundColor: '$neutral-80-opa-80' },
},
},
iconOnly: {
true: {
width: 24,
},
false: {
paddingHorizontal: 8,
},
},
} as const,
})

View File

@ -0,0 +1 @@
export { DynamicButton, type DynamicButtonProps } from './dynamic-button'

View File

@ -1,7 +1,9 @@
export * from './anchor-actions'
export * from './button' export * from './button'
export * from './composer' export * from './composer'
export * from './divider' export * from './divider'
export * from './divider-label' export * from './divider-label'
export * from './dynamic-button'
export * from './icon-button' export * from './icon-button'
export * from './image' export * from './image'
export * from './input' export * from './input'