Add system messages (#356)
* add DynamicButton component * add AnchorActions component * add AnchorActions to web app
This commit is contained in:
parent
25eb3f24f3
commit
a167396062
|
@ -1,6 +1,7 @@
|
|||
import { useMemo, useRef, useState } from 'react'
|
||||
|
||||
import {
|
||||
AnchorActions,
|
||||
CHANNEL_GROUPS,
|
||||
Composer,
|
||||
Messages,
|
||||
|
@ -69,6 +70,9 @@ function App() {
|
|||
<Messages />
|
||||
</div>
|
||||
<div id="composer">
|
||||
<div id="anchor-actions">
|
||||
<AnchorActions scrolled={shouldBlurBottom} />
|
||||
</div>
|
||||
<Composer blur={shouldBlurBottom} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -52,6 +52,12 @@ body,
|
|||
padding: 32px 8px;
|
||||
}
|
||||
|
||||
#anchor-actions {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
transform: translateY(calc(-100% - 12px));
|
||||
}
|
||||
|
||||
#composer {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
|
|
|
@ -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 }
|
|
@ -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
|
|
@ -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,
|
||||
})
|
|
@ -0,0 +1 @@
|
|||
export { DynamicButton, type DynamicButtonProps } from './dynamic-button'
|
|
@ -1,7 +1,9 @@
|
|||
export * from './anchor-actions'
|
||||
export * from './button'
|
||||
export * from './composer'
|
||||
export * from './divider'
|
||||
export * from './divider-label'
|
||||
export * from './dynamic-button'
|
||||
export * from './icon-button'
|
||||
export * from './image'
|
||||
export * from './input'
|
||||
|
|
Loading…
Reference in New Issue