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 { 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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 './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'
|
||||||
|
|
Loading…
Reference in New Issue