Add blur and IconButton variants (#340)

* feat: add blurview to topbar and composer with scroll position

* fix: icon button component and adds scrolls var position for the top bar

* fix: changes from review
This commit is contained in:
marcelines 2023-02-10 16:25:13 +00:00 committed by GitHub
parent fe31f2f59c
commit 1757f62b34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
295 changed files with 956 additions and 485 deletions

View File

@ -2,7 +2,7 @@
"expo": {
"name": "mobile",
"slug": "status-poc",
"version": "1.0.2",
"version": "1.0.3",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",

View File

@ -11,6 +11,7 @@
"@status-im/components": "*",
"@status-im/icons": "*",
"@tamagui/core": "1.0.15",
"expo-blur": "~12.0.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-native-web": "^0.18.6"

View File

@ -1,4 +1,4 @@
import { useState } from 'react'
import { cloneElement, useRef, useState } from 'react'
import {
Composer,
@ -7,11 +7,15 @@ import {
SidebarMembers,
Topbar,
} from '@status-im/components'
import { useBlur } from '@status-im/components/hooks'
import { COMMUNITIES } from '@status-im/components/src/sidebar/mock-data'
import { Stack, styled, TamaguiProvider } from '@tamagui/core'
import { AnimatePresence } from 'tamagui'
import tamaguiConfig from '../tamagui.config'
import type { ReactElement, ReactNode } from 'react'
type ThemeVars = 'light' | 'dark'
const AnimatableDrawer = styled(Stack, {
@ -36,15 +40,28 @@ function App() {
const [showMembers, setShowMembers] = useState(false)
const [selectedChannel, setSelectedChannel] = useState<string>('welcome')
const refMessagesContainer = useRef<HTMLDivElement>(null)
const onChannelPress = (id: string) => {
// TODO - this is a hack to get the icon to show up in the topbar when a channel is selected on mount
const [icon, setIcon] = useState<ReactNode>(
cloneElement(COMMUNITIES[0].channels[0].icon as ReactElement, {
hasBackground: false,
})
)
const onChannelPress = (id: string, icon?: ReactNode) => {
setSelectedChannel(id)
setIcon(icon)
}
const { shouldBlurTop, shouldBlurBottom } = useBlur({
ref: refMessagesContainer,
})
return (
<TamaguiProvider config={tamaguiConfig} defaultTheme={'light'}>
<div id="app">
<div id="sidebar">
<div id="sidebar" style={{ zIndex: 200 }}>
<Sidebar
name="Rarible"
description="Multichain community-centric NFT marketplace. Create, buy and sell your NFTs."
@ -55,15 +72,28 @@ function App() {
</div>
<main id="main">
<Topbar
isBlurred={shouldBlurTop}
backgroundColor="$blurBackground"
icon={
icon &&
cloneElement(icon as ReactElement, { hasBackground: false })
}
title={`#${selectedChannel}`}
description="Share random funny stuff with the community. Play nice."
membersVisisble={showMembers}
onMembersPress={() => setShowMembers(show => !show)}
/>
<div id="content">
<div id="content" ref={refMessagesContainer}>
<Messages />
</div>
<Composer />
<Composer
backgroundColor="$blurBackground"
paddingBottom={56}
isBlurred={shouldBlurBottom}
style={{ marginTop: -112 }}
/>
</main>
<AnimatePresence enterVariant="fromRight" exitVariant="fromLeft">
{showMembers && (

View File

@ -29,6 +29,10 @@ body,
border: 1px solid rgba(0, 0, 0, 0.1);
} */
.composer-input::placeholder {
transition: color 0.2s ease-in-out;
}
#sidebar {
overflow: auto;
height: 100vh;
@ -36,7 +40,9 @@ body,
#content {
overflow: auto;
padding: 8px;
padding: 72px 8px 132px 8px;
height: 100vh;
margin-top: -56px;
}
#members {

28
eas.json Normal file
View File

@ -0,0 +1,28 @@
{
"cli": {
"version": ">= 3.4.1"
},
"build": {
"development": {
"developmentClient": true,
"distribution": "internal",
"ios": {
"resourceClass": "m1-medium"
}
},
"preview": {
"distribution": "internal",
"ios": {
"resourceClass": "m1-medium"
}
},
"production": {
"ios": {
"resourceClass": "m1-medium"
}
}
},
"submit": {
"production": {}
}
}

View File

@ -0,0 +1,2 @@
export { useBlur } from './use-blur'
export { useThrottle } from './use-throttle'

View File

@ -0,0 +1,68 @@
import { useEffect, useState } from 'react'
import { useThrottle } from './use-throttle'
interface UseBlurReturn {
shouldBlurBottom: boolean
shouldBlurTop: boolean
}
type UseBlurProps = {
ref: React.RefObject<HTMLDivElement>
marginBlurBottom?: number
heightTop?: number
throttle?: number
}
const useBlur = (props: UseBlurProps): UseBlurReturn => {
const {
marginBlurBottom = 32,
heightTop = 56,
throttle = 100,
ref,
} = props || {}
const [shouldBlurTop, setShouldBlurTop] = useState(false)
const [shouldBlurBottom, setShouldBlurBottom] = useState(false)
const handleScroll = useThrottle(() => {
const scrollPosition = ref.current!.scrollTop
const elementHeight = ref.current!.clientHeight
const scrollHeight = ref.current?.scrollHeight || 0
if (scrollPosition >= heightTop) {
setShouldBlurTop(true)
}
if (scrollPosition < heightTop) {
setShouldBlurTop(false)
}
if (scrollPosition < scrollHeight - (elementHeight + marginBlurBottom)) {
setShouldBlurBottom(true)
}
if (scrollPosition >= scrollHeight - (elementHeight + marginBlurBottom)) {
setShouldBlurBottom(false)
}
}, throttle)
useEffect(() => {
const element = props.ref
if (!element.current) {
throw new Error('useBlur ref not set correctly')
}
element.current!.addEventListener('scroll', handleScroll, { passive: true })
handleScroll()
return () => {
element.current!.removeEventListener('scroll', handleScroll)
}
}, [handleScroll, props.ref])
return { shouldBlurBottom, shouldBlurTop }
}
export { useBlur }

View File

@ -0,0 +1,38 @@
import { useMemo } from 'react'
const throttle = <Args extends unknown[]>(
fn: (...args: Args) => void,
cooldown: number
) => {
let lastArgs: Args | undefined
const run = () => {
if (lastArgs) {
fn(...lastArgs)
lastArgs = undefined
}
}
const throttled = (...args: Args) => {
const isOnCooldown = !!lastArgs
lastArgs = args
if (isOnCooldown) {
return
}
window.setTimeout(run, cooldown)
}
return throttled
}
const useThrottle = <Args extends unknown[]>(
cb: (...args: Args) => void,
cooldown: number
) => {
return useMemo(() => throttle(cb, cooldown), [cb, cooldown])
}
export { useThrottle }

View File

@ -26,6 +26,7 @@ const Accordion = ({
const [isExpanded, setIsExpanded] = useState(initialExpanded)
return (
<Stack
accessibilityRole="button"
width="100%"
borderRadius="$0"
borderTopWidth={1}

View File

@ -34,6 +34,7 @@ const AccordionItem = ({
return (
<Stack
{...rest}
accessibilityRole="button"
animation={[
'fast',
{

View File

@ -1,45 +1,108 @@
import { useState } from 'react'
import {
AudioIcon,
FormatIcon,
ImageIcon,
ReactionIcon,
} from '@status-im/icons/20'
import { BlurView } from 'expo-blur'
import { Stack, XStack, YStack } from 'tamagui'
import { IconButton } from '../icon-button'
import { Input } from '../input'
import type { GetProps } from '@tamagui/core'
import type { ViewProps } from 'react-native'
type BaseProps = GetProps<typeof YStack>
const Composer = (props: BaseProps) => {
const Composer = (
props: Omit<BaseProps, 'style'> & {
placeholderTextColor?: BaseProps['backgroundColor']
iconOptionsColor?: BaseProps['backgroundColor']
isBlurred?: boolean
style?: ViewProps['style']
}
) => {
const { backgroundColor, isBlurred, style: styleFromProps, ...rest } = props
const style = styleFromProps ? Object.assign(styleFromProps) : {}
const [isFocused, setIsFocused] = useState(false)
const applyVariantStyles:
| {
blurred: boolean
}
| undefined = isBlurred && !isFocused ? { blurred: true } : undefined
return (
<YStack
backgroundColor="$background"
shadowColor="rgba(9, 16, 28, 0.08)"
shadowOffset={{ width: 0, height: -4 }}
shadowRadius={20}
borderTopLeftRadius={20}
borderTopRightRadius={20}
px={16}
pt={8}
width="100%"
<BlurView
intensity={40}
style={{
elevation: 10,
zIndex: 100,
borderRadius: 20,
...style,
}}
{...props}
>
<Input placeholder="Type something..." borderWidth={0} px={0} />
<XStack alignItems="center" justifyContent="space-between" pt={8}>
<Stack space={12} flexDirection="row">
<IconButton icon={<ImageIcon />} transparent />
<IconButton icon={<ReactionIcon />} transparent />
<IconButton icon={<FormatIcon />} transparent />
</Stack>
<IconButton icon={<AudioIcon />} transparent />
</XStack>
</YStack>
<YStack
animation="fast"
backgroundColor={isFocused ? '$background' : backgroundColor}
shadowColor={!isBlurred || isFocused ? 'rgba(9, 16, 28, 0.08)' : 'none'}
shadowOffset={{ width: 4, height: !isBlurred || isFocused ? 4 : 0 }}
shadowRadius={20}
borderTopLeftRadius={20}
borderTopRightRadius={20}
px={16}
pt={8}
width="100%"
style={{
elevation: 10,
}}
{...rest}
>
<Input
className="composer-input"
placeholder="Type something..."
px={0}
borderWidth={0}
blurred={isBlurred}
onBlur={() => setIsFocused(false)}
onFocus={() => setIsFocused(true)}
/>
<XStack
alignItems="center"
justifyContent="space-between"
pt={8}
backgroundColor="transparent"
>
<Stack space={12} flexDirection="row" backgroundColor="transparent">
<IconButton
variant="outline"
icon={<ImageIcon />}
{...applyVariantStyles}
selected
/>
<IconButton
variant="outline"
icon={<ReactionIcon />}
{...applyVariantStyles}
/>
<IconButton
variant="outline"
icon={<FormatIcon />}
disabled
{...applyVariantStyles}
/>
</Stack>
<IconButton
variant="outline"
icon={<AudioIcon />}
{...applyVariantStyles}
/>
</XStack>
</YStack>
</BlurView>
)
}

View File

@ -2,7 +2,7 @@ import { Stack, styled } from '@tamagui/core'
export const Divider = styled(Stack, {
name: 'Divider',
backgroundColor: '$neutral-10',
backgroundColor: '$neutral-80-opa-10',
flexShrink: 0,
// borderWidth: 0,
flex: 1,

View File

@ -1,6 +1,6 @@
import { cloneElement } from 'react'
import { Stack, styled, Text } from '@tamagui/core'
import { Stack, styled } from '@tamagui/core'
import type React from 'react'
@ -20,40 +20,81 @@ const Base = styled(Stack, {
height: 30,
borderWidth: 1,
padding: 4,
backgroundColor: '$neutral-10',
borderColor: '$neutral-10',
hoverStyle: {
backgroundColor: '$neutral-20',
},
pressStyle: {
backgroundColor: '$neutral-20',
},
variants: {
selected: {
true: {
backgroundColor: '$neutral-30',
borderColor: '$neutral-30',
},
},
transparent: {
true: {
backgroundColor: 'transparent',
borderColor: '$neutral-20',
variant: {
default: {
backgroundColor: '$iconButtonBackground',
borderColor: 'transparent',
hoverStyle: {
backgroundColor: 'transparent',
borderColor: '$neutral-30',
backgroundColor: '$iconButtonBackgroundHover',
},
pressStyle: {
backgroundColor: 'transparent',
borderColor: '$neutral-30',
backgroundColor: '$iconButtonBackgroundHover',
},
},
outline: {
backgroundColor: 'transparent',
borderColor: '$iconButtonOutlineBorder',
hoverStyle: {
borderColor: '$iconButtonOutlineBorderHover',
},
pressStyle: {
borderColor: '$iconButtonOutlineBorderHover',
},
},
},
blurred: {
default: {
backgroundColor: '$iconButtonBackgroundBlurred',
hoverStyle: {
backgroundColor: '$iconButtonBackgroundBlurredHover',
},
pressStyle: {
backgroundColor: 'iconButtonBackgroundBlurredHover',
},
},
outline: {
borderColor: '$iconButtonOutlineBorderBlurred',
hoverStyle: {
borderColor: '$iconButtonOutlineBorderBlurredHover',
},
pressStyle: {
borderColor: '$iconButtonOutlineBorderBlurredHover',
},
},
},
selected: {
default: {
backgroundColor: '$iconButtonBackgroundSelected',
borderColor: '$iconButtonBorderSelected',
},
defaultWithBlur: {
backgroundColor: '$iconButtonBackgroundBlurredSelected',
borderColor: '$iconButtonBorderBlurredSelected',
},
outline: {
backgroundColor: '$iconButtonOutlineBackgroundSelected',
borderColor: '$iconButtonOutlineBorderSelected',
},
outlineWithBlur: {
backgroundColor: '$iconButtonOutBackgroundBlurredSelected',
borderColor: '$iconButtonOutlineBorderBlurredSelected',
},
},
disabled: {
true: {
opacity: 0.3,
cursor: 'default',
},
},
} as const,
})
@ -62,20 +103,92 @@ interface Props {
icon: React.ReactElement
onPress?: () => void
selected?: boolean
transparent?: boolean
blurred?: boolean
variant?: 'default' | 'outline'
disabled?: boolean
// FIXME: enforce aria-label for accessibility
// 'aria-label'?: string
}
const iconColor = {
default: {
default: '$iconButtonColor',
defaultBlurred: '$iconButtonColorBlurred',
selected: '$iconButtonColorSelected',
selectedBlurred: '$iconButtonColorBlurred',
},
outline: {
default: '$iconButtonColorOutline',
defaultBlurred: '$iconButtonColorOutlineBlurred',
selected: '$iconButtonColorOutlineSelected',
selectedBlurred: '$iconButtonColorOutlineBlurred',
},
}
const getStateForIconColor = ({
blurred,
selected,
}: {
blurred?: boolean
selected?: boolean
}) => {
if (!selected && blurred) {
return 'defaultBlurred'
}
if (selected && blurred) {
return 'selectedBlurred'
}
if (selected && !blurred) {
return 'selected'
}
return 'default'
}
const getSelectedVariant = ({
selected,
blurred,
variant,
}: {
selected?: boolean
blurred?: boolean
variant?: 'default' | 'outline'
}) => {
if (!selected) {
return undefined
}
if (blurred && variant === 'default') {
return 'defaultWithBlur'
}
if (blurred && variant === 'outline') {
return 'outlineWithBlur'
}
return variant
}
const IconButton = (props: Props) => {
const { icon, transparent, selected, onPress } = props
const {
icon,
selected,
blurred,
onPress,
variant = 'default',
disabled,
} = props
const state = getStateForIconColor({ blurred, selected })
const selectedVariant = getSelectedVariant({ selected, variant, blurred })
return (
<Base selected={selected} onPress={onPress} transparent={transparent}>
<Base
variant={variant}
selected={selectedVariant}
onPress={onPress}
blurred={blurred ? variant : undefined}
disabled={disabled}
>
{cloneElement(icon, {
color: selected ? '$neutral-100' : '$neutral-50',
color: iconColor[variant][state],
size: 20,
pressEvents: 'none',
})}
</Base>
)

View File

@ -1,13 +1,9 @@
// eslint-disable-next-line eslint-comments/disable-enable-pair
/* eslint-disable import/namespace */
import { setupReactNative, styled } from '@tamagui/core'
// import { focusableInputHOC } from '@tamagui/focusable'
import { focusableInputHOC } from '@tamagui/focusable'
import { TextInput } from 'react-native'
import type { GetProps } from '@tamagui/core'
// import { inputSizeVariant } from '../helpers/inputHelpers'
setupReactNative({
TextInput,
})
@ -17,55 +13,50 @@ export const InputFrame = styled(
{
tag: 'input',
name: 'Input',
// fontFamily: '$body',
borderWidth: 1,
outlineWidth: 0,
borderColor: 'rgba(0, 200, 0, 1)',
paddingHorizontal: 30,
color: 'hsla(218, 51%, 7%, 1)',
placeholderTextColor: 'hsla(219, 17%, 69%, 1)',
// color: 'red',
// color: '$color',
// focusable: true,
// borderColor: '$borderColor',
// backgroundColor: '$background',
// placeholderTextColor: '$placeholderColor',
placeholderTextColor: '$placeHolderColor',
backgroundColor: 'rgb(255, 255, 255)',
backgroundColor: 'transparent',
height: 40,
borderRadius: 12,
animation: 'fast',
// this fixes a flex bug where it overflows container
minWidth: 0,
// hoverStyle: {
// borderColor: '$borderColorHover',
// },/
hoverStyle: {
borderColor: '$beigeHover',
},
// focusStyle: {
focusStyle: {
borderColor: '$blueHover',
},
// borderWidth: 2,
// marginHorizontal: -1,
// },
variants: {
blurred: {
true: {
placeholderTextColor: '$placeHolderColorBlurred',
},
},
},
// variants: {
// size: {
// // '...size': inputSizeVariant,
// },
// } as const,
// defaultVariants: {
// size: '$true',
// },
defaultVariants: {
blurred: '$false',
},
},
{
isInput: true,
}
// {
// isInput: true,
// }
)
export type InputProps = GetProps<typeof InputFrame>
// export const Input = focusableInputHOC(InputFrame)
export const Input = InputFrame
export const Input = focusableInputHOC(InputFrame)

View File

@ -79,8 +79,6 @@ type Props = {
export const Reactions = (props: Props) => {
const { reactions } = props
console.log(reactions)
return (
<XStack space={8} flexWrap="wrap">
<ReactionButton count={1} icon={<LoveIcon />} selected />

View File

@ -15,6 +15,8 @@ export const Messages = () => {
},
]}
/>
<ChatMessage text="fsdjkf kasldjf ksdlfjksdlfj asdklfj sdkljf" />
<ChatMessage text="fsdjkf kasldjf ksdlfjksdlfj asdklfj sdkljf" />
<ChatMessage
text="fsdjkf kasldjf ksdlfjksdlfj asdklfj sdkljf"
reactions={['123']}
@ -30,6 +32,20 @@ export const Messages = () => {
text="fsdjkf kasldjf ksdlfjksdlfj asdklfj sdkljf"
reactions={['123']}
/>
<ChatMessage
images={[
{
url: 'https://images.unsplash.com/photo-1673433107234-14d1a4424658?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80',
},
]}
/>
<ChatMessage
images={[
{
url: 'https://images.unsplash.com/photo-1673433107234-14d1a4424658?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80',
},
]}
/>
</>
)
}

View File

@ -11,6 +11,7 @@ import { COMMUNITIES } from './mock-data'
import type { CommunityProps } from './mock-data'
import type { GetProps } from '@tamagui/core'
import type { ReactNode } from 'react'
type BaseProps = GetProps<typeof Stack>
@ -20,7 +21,7 @@ type Props = {
membersCount: number
selectedChannel?: string
communities?: CommunityProps[]
onChannelPress: (channelId: string) => void
onChannelPress: (channelId: string, channelIcon?: ReactNode) => void
} & BaseProps
const Sidebar = (props: Props) => {
@ -90,7 +91,7 @@ const Sidebar = (props: Props) => {
channelStatus={channel.channelStatus}
numberOfMessages={channel.numberOfMessages}
isSelected={selectedChannel === channel.id}
onPress={() => onChannelPress(channel.id)}
onPress={() => onChannelPress(channel.id, channel.icon)}
mb={isLastChannelOfTheList ? 8 : 0}
/>
)

View File

@ -95,7 +95,13 @@ export const config = createTamagui({
mono: monoFont,
},
themes,
tokens,
tokens: {
colors: {
...tokens.color,
},
...tokens,
},
shouldAddPrefersColorThemes: true,
media: createMedia({
xs: { maxWidth: 660 },
sm: { maxWidth: 800 },

View File

@ -33,6 +33,31 @@ const light = createTheme({
brownHover: tokens.color['brown-60'],
beige: tokens.color['beige-50'],
beigeHover: tokens.color['beige-60'],
placeHolderColor: tokens.color['neutral-40'],
placeHolderColorBlurred: tokens.color['neutral-80-opa-40'],
iconButtonBackground: tokens.color['neutral-10'],
iconButtonBackgroundHover: tokens.color['neutral-20'],
iconButtonBackgroundSelected: tokens.color['neutral-20'],
iconButtonBorderSelected: tokens.color['neutral-30'],
iconButtonBackgroundBlurred: tokens.color['neutral-80-opa-5'],
iconButtonBackgroundBlurredHover: tokens.color['neutral-80-opa-10'],
iconButtonBackgroundBlurredSelected: tokens.color['neutral-80-opa-10'],
iconButtonBorderBlurredSelected: tokens.color['neutral-80-opa-5'],
iconButtonOutlineBackgroundSelected: tokens.color['neutral-10'],
iconButtonOutlineBorder: tokens.color['neutral-20'],
iconButtonOutlineBorderHover: tokens.color['neutral-30'],
iconButtonOutlineBorderSelected: tokens.color['neutral-20'],
iconButtonOutBackgroundBlurredSelected: tokens.color['neutral-10'],
iconButtonOutlineBorderBlurred: tokens.color['neutral-80-opa-10'],
iconButtonOutlineBorderBlurredHover: tokens.color['neutral-80-opa-20'],
iconButtonOutlineBorderBlurredSelected: tokens.color['neutral-80-opa-10'],
iconButtonColor: tokens.color['neutral-50'],
iconButtonColorSelected: tokens.color['neutral-100'],
iconButtonColorBlurred: tokens.color['neutral-100'],
iconButtonColorOutline: tokens.color['neutral-50'],
iconButtonColorOutlineSelected: tokens.color['neutral-100'],
iconButtonColorOutlineBlurred: tokens.color['neutral-80-opa-70'],
blurBackground: tokens.color['white-70'],
})
// note: we set up a single consistent base type to validate the rest:
@ -69,6 +94,31 @@ const dark: BaseTheme = createTheme({
brownHover: tokens.color['brown-50'],
beige: tokens.color['beige-60'],
beigeHover: tokens.color['beige-50'],
placeHolderColor: tokens.color['neutral-50'],
placeHolderColorBlurred: tokens.color['white-30'],
iconButtonBackground: tokens.color['neutral-90'],
iconButtonBackgroundHover: tokens.color['neutral-80'],
iconButtonBackgroundSelected: tokens.color['neutral-80'],
iconButtonBorderSelected: tokens.color['neutral-60'],
iconButtonBackgroundBlurred: tokens.color['white-5'],
iconButtonBackgroundBlurredHover: tokens.color['white-10'],
iconButtonBackgroundBlurredSelected: tokens.color['white-10'],
iconButtonBorderBlurredSelected: tokens.color['white-5'],
iconButtonOutlineBackgroundSelected: tokens.color['neutral-80-opa-70'],
iconButtonOutlineBorder: tokens.color['neutral-80'],
iconButtonOutlineBorderHover: tokens.color['neutral-70'],
iconButtonOutlineBorderSelected: tokens.color['neutral-70'],
iconButtonOutBackgroundBlurredSelected: tokens.color['white-5'],
iconButtonOutlineBorderBlurred: tokens.color['white-10'],
iconButtonOutlineBorderBlurredHover: tokens.color['white-20'],
iconButtonOutlineBorderBlurredSelected: tokens.color['white-10'],
iconButtonColor: tokens.color['neutral-40'],
iconButtonColorSelected: tokens.color['white-100'],
iconButtonColorBlurred: tokens.color['white-100'],
iconButtonColorOutline: tokens.color['neutral-40'],
iconButtonColorOutlineSelected: tokens.color['white-100'],
iconButtonColorOutlineBlurred: tokens.color['white-100'],
blurBackground: tokens.color['neutral-80-opa-70'],
})
const allThemes = {

View File

@ -6,6 +6,11 @@ import {
OptionsIcon,
} from '@status-im/icons/20'
import { Stack } from '@tamagui/core'
import { BlurView } from 'expo-blur'
import type { GetProps, StackProps } from '@tamagui/core'
type BaseProps = GetProps<typeof Stack>
type Props = {
membersVisisble: boolean
@ -13,58 +18,96 @@ type Props = {
goBack?: () => void
title?: string
description?: string
}
icon?: React.ReactNode
refForScroll?: React.RefObject<HTMLDivElement>
backgroundColor?: StackProps['backgroundColor']
isBlurred?: boolean
} & BaseProps
const Topbar = (props: Props) => {
const { membersVisisble, onMembersPress, goBack, title, description } = props
const {
membersVisisble,
onMembersPress,
goBack,
title,
description,
icon,
backgroundColor,
isBlurred,
...rest
} = props
return (
<Stack
flexDirection="row"
height={56}
alignItems="center"
justifyContent="space-between"
padding={16}
borderBottomWidth={1}
borderColor="$neutral-10"
width="100%"
>
<Stack flexDirection="row" alignItems="center" flexWrap="wrap">
<Stack mr={12} $gtSm={{ display: 'none' }}>
<IconButton icon={<ArrowLeftIcon />} onPress={() => goBack?.()} />
<BlurView intensity={40} style={{ zIndex: 100 }}>
<Stack
flexDirection="row"
height={56}
alignItems="center"
justifyContent="space-between"
padding={16}
backgroundColor={backgroundColor || '$background'}
borderBottomWidth={1}
borderColor={isBlurred ? 'transparent' : '$neutral-80-opa-10'}
width="100%"
{...rest}
>
<Stack flexDirection="row" alignItems="center" flexWrap="wrap">
<Stack mr={12} $gtSm={{ display: 'none' }}>
<IconButton
icon={<ArrowLeftIcon />}
onPress={() => goBack?.()}
blurred={isBlurred}
/>
</Stack>
{icon && <Stack marginRight={12}>{icon}</Stack>}
{title && (
<Paragraph weight="semibold" marginRight={4}>
{title}
</Paragraph>
)}
<LockedIcon color="$neutral-80-opa-40" />
<Divider height={16} $sm={{ display: 'none' }} />
</Stack>
{title && (
<Paragraph weight="semibold" marginRight={4}>
{title}
</Paragraph>
)}
<LockedIcon color="$neutral-80-opa-40" />
<Divider height={16} $sm={{ display: 'none' }} />
{description && (
<Paragraph
weight="medium"
color="$neutral-80-opa-50"
variant="smaller"
$sm={{ display: 'none' }}
>
{description}
</Paragraph>
)}
</Stack>
<Stack space={12} flexDirection="row">
<Stack $sm={{ display: 'none' }}>
<IconButton
icon={<MembersIcon />}
selected={membersVisisble}
onPress={onMembersPress}
/>
<Stack
space={12}
flexDirection="row"
alignItems="center"
justifyContent={description ? 'space-between' : 'flex-end'}
flexGrow={1}
flexShrink={1}
$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 $sm={{ display: 'none' }}>
<IconButton
icon={<MembersIcon />}
selected={membersVisisble}
onPress={onMembersPress}
blurred={isBlurred}
/>
</Stack>
<IconButton icon={<OptionsIcon />} blurred={isBlurred} />
</Stack>
<IconButton icon={<OptionsIcon />} />
</Stack>
</Stack>
</BlurView>
)
}

View File

@ -12,7 +12,7 @@ const SvgAddIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
fillRule="evenodd"

View File

@ -12,7 +12,7 @@ const SvgAddReactionIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#add-reaction-icon_svg__a)">
<Path d="M7.294 1.17A5 5 0 1 0 11 6" stroke={color} strokeWidth={1.1} />

View File

@ -12,7 +12,7 @@ const SvgAlertIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Circle cx={6} cy={6} r={4.45} stroke={color} strokeWidth={1.1} />
<Path d="M6 6.5v-3M6 8.5v-1" stroke={color} strokeWidth={1.1} />

View File

@ -12,7 +12,7 @@ const SvgArrowDownIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
fillRule="evenodd"

View File

@ -12,7 +12,7 @@ const SvgArrowRightIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
fillRule="evenodd"

View File

@ -12,7 +12,7 @@ const SvgArrowUpIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
fillRule="evenodd"

View File

@ -12,14 +12,14 @@ const SvgBlockIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#block-icon_svg__a)">
<Path
fillRule="evenodd"
clipRule="evenodd"
d="M2.05 6a3.95 3.95 0 0 1 6.327-3.155L2.845 8.377A3.933 3.933 0 0 1 2.05 6Zm1.573 3.155a3.95 3.95 0 0 0 5.532-5.532L3.623 9.155ZM6 .95a5.05 5.05 0 1 0 0 10.1A5.05 5.05 0 0 0 6 .95Z"
fill="#E65F5C"
fill={color}
/>
</G>
<Defs>

View File

@ -12,7 +12,7 @@ const SvgCameraIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#camera-icon_svg__a)" stroke={color} strokeWidth={1.1}>
<Path d="M1 4.2c0-.94.76-1.7 1.7-1.7h.211c.514 0 .984-.29 1.214-.75.23-.46.7-.75 1.214-.75H6.66c.514 0 .984.29 1.214.75.23.46.7.75 1.214.75H9.3c.94 0 1.7.76 1.7 1.7v2.55c0 1.164 0 1.745-.16 2.214a3 3 0 0 1-1.876 1.877C8.495 11 7.914 11 6.75 11h-1.5c-1.164 0-1.745 0-2.214-.16a3 3 0 0 1-1.877-1.876C1 8.495 1 7.914 1 6.75V4.2Z" />

View File

@ -12,7 +12,7 @@ const SvgCardsIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#cards-icon_svg__a)" stroke={color} strokeWidth={1.1}>
<Path d="M1 4.2c0-1.12 0-1.68.218-2.108a2 2 0 0 1 .874-.874C2.52 1 3.08 1 4.2 1h3.6c1.12 0 1.68 0 2.108.218a2 2 0 0 1 .874.874C11 2.52 11 3.08 11 4.2v3.6c0 1.12 0 1.68-.218 2.108a2 2 0 0 1-.874.874C9.48 11 8.92 11 7.8 11H4.2c-1.12 0-1.68 0-2.108-.218a2 2 0 0 1-.874-.874C1 9.48 1 8.92 1 7.8V4.2Z" />

View File

@ -12,7 +12,7 @@ const SvgCheckIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Circle cx={6} cy={6} r={4.45} stroke={color} strokeWidth={1.1} />
<Path d="m4 6.3 1.333 1.2L8 4.5" stroke={color} strokeWidth={1.1} />

View File

@ -12,7 +12,7 @@ const SvgCheckLargeIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path d="m1.5 6 3 3 6-7" stroke={color} strokeWidth={1.3} />
</Svg>

View File

@ -12,7 +12,7 @@ const SvgChevronBottomIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path d="m3 4.5 3 3 3-3" stroke={color} strokeWidth={1.1} />
</Svg>

View File

@ -12,7 +12,7 @@ const SvgChevronLeftIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path d="m7.5 3-3 3 3 3" stroke={color} strokeWidth={1.1} />
</Svg>

View File

@ -12,7 +12,7 @@ const SvgChevronRightIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path d="m4.5 9 3-3-3-3" stroke={color} strokeWidth={1.1} />
</Svg>

View File

@ -12,7 +12,7 @@ const SvgChevronTopIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path d="m9 7.5-3-3-3 3" stroke={color} strokeWidth={1.1} />
</Svg>

View File

@ -12,7 +12,7 @@ const SvgCloseIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="M2.5 9.5 6 6 2.5 2.5M9.5 9.5 6 6l3.5-3.5"

View File

@ -12,7 +12,7 @@ const SvgColorIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="M9 6.4C9 8.9 7.212 10 6 10S3 9 3 6.5 6 2 6 2s3 1.9 3 4.4Z"

View File

@ -12,7 +12,7 @@ const SvgCommunitiesIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#communities-icon_svg__a)">
<Path

View File

@ -12,15 +12,15 @@ const SvgContactIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Circle cx={6} cy={6} r={5} fill="#4360DF" />
<Circle cx={6} cy={6} r={5} fill={color} />
<Path
d="M9 9.5A3.369 3.369 0 0 0 6.197 8h-.394A3.369 3.369 0 0 0 3 9.5"
stroke="#fff"
strokeLinejoin="round"
/>
<Circle cx={6} cy={6} r={4.25} stroke="#4360DF" strokeWidth={1.5} />
<Circle cx={6} cy={6} r={4.25} stroke={color} strokeWidth={1.5} />
<Circle cx={6} cy={4.5} r={1.5} stroke="#fff" strokeLinejoin="round" />
</Svg>
)

View File

@ -12,7 +12,7 @@ const SvgCopyIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#copy-icon_svg__a)" strokeWidth={1.1}>
<Path

View File

@ -12,7 +12,7 @@ const SvgDeliveredIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
fillRule="evenodd"

View File

@ -12,7 +12,7 @@ const SvgDropdownIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#dropdown-icon_svg__a)">
<Circle cx={6} cy={6} r={6} fill="#E7EAEE" />

View File

@ -12,7 +12,7 @@ const SvgEditIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="M5.94 3.182c.396-.396.594-.594.822-.669a1 1 0 0 1 .618 0c.228.075.426.273.822.669l.566.565c.396.396.594.594.668.823a1 1 0 0 1 0 .618c-.074.228-.272.426-.668.822l-2.85 2.85c-.2.2-.3.3-.417.367a1 1 0 0 1-.337.118c-.133.021-.274.005-.554-.026l-1.782-.198-.198-1.78c-.03-.282-.046-.422-.025-.555a1 1 0 0 1 .118-.337c.067-.117.167-.217.366-.417l2.85-2.85ZM4.839 3.575l3.535 3.536"

View File

@ -12,7 +12,7 @@ const SvgGasIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#gas-icon_svg__a)" strokeWidth={1.1}>
<Path

View File

@ -12,11 +12,11 @@ const SvgHoldIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#hold-icon_svg__a)">
<Circle cx={6} cy={6} r={6} fill="#647084" />
<Path d="M3.333 6.4 5.111 8l3.556-4" stroke="#fff" strokeWidth={1.1} />
<Path d="M3.333 6.4 5.111 8l3.556-4" stroke={color} strokeWidth={1.1} />
</G>
<Defs>
<ClipPath id="hold-icon_svg__a">

View File

@ -12,7 +12,7 @@ const SvgInfo1Icon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
fillRule="evenodd"

View File

@ -12,9 +12,9 @@ const SvgInfoIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Circle cx={6} cy={6} r={5} fill="#4360DF" />
<Circle cx={6} cy={6} r={5} fill={color} />
<Path d="M6 5v4M6 3v1" stroke="#fff" strokeWidth={1.1} />
</Svg>
)

View File

@ -12,7 +12,7 @@ const SvgJumpToIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path d="M4.575 2.525h4.95v4.95" stroke={color} strokeWidth={1.1} />
<Path

View File

@ -12,7 +12,7 @@ const SvgLightningIcon = (props: SvgProps) => {
height={14}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="M7 1.5V6h2.5L5 12.5v-5H2.5l4.5-6Z"

View File

@ -12,7 +12,7 @@ const SvgListIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#list-icon_svg__a)" stroke={color} strokeWidth={1.1}>
<Path d="M1 2.5c0-.465 0-.697.051-.888a1.5 1.5 0 0 1 1.06-1.06C2.304.5 2.536.5 3 .5h6c.465 0 .697 0 .888.051a1.5 1.5 0 0 1 1.06 1.06c.052.192.052.424.052.889s0 .697-.051.888a1.5 1.5 0 0 1-1.06 1.06C9.696 4.5 9.464 4.5 9 4.5H3c-.465 0-.697 0-.888-.051a1.5 1.5 0 0 1-1.06-1.06C1 3.196 1 2.964 1 2.5ZM1 9.5c0-.465 0-.697.051-.888a1.5 1.5 0 0 1 1.06-1.06C2.304 7.5 2.536 7.5 3 7.5h6c.465 0 .697 0 .888.051a1.5 1.5 0 0 1 1.06 1.06c.052.192.052.424.052.889s0 .697-.051.888a1.5 1.5 0 0 1-1.06 1.06c-.192.052-.424.052-.889.052H3c-.465 0-.697 0-.888-.051a1.5 1.5 0 0 1-1.06-1.06C1 10.197 1 9.964 1 9.5Z" />

View File

@ -20,7 +20,7 @@ const SvgLoadingIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#loading-icon_svg__a)">
<Path

View File

@ -12,7 +12,7 @@ const SvgLockedIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="M2.5 7.75c0-.465 0-.697.038-.89A2 2 0 0 1 4.11 5.288c.193-.038.425-.038.89-.038h2c.465 0 .697 0 .89.038A2 2 0 0 1 9.462 6.86c.038.193.038.425.038.89s0 .697-.038.89a2 2 0 0 1-1.572 1.572c-.193.038-.425.038-.89.038H5c-.465 0-.697 0-.89-.038A2 2 0 0 1 2.538 8.64C2.5 8.447 2.5 8.215 2.5 7.75ZM4 3.75a2 2 0 1 1 4 0v1.5H4v-1.5Z"

View File

@ -12,7 +12,7 @@ const SvgMentionIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#mention-icon_svg__a)" stroke={color} strokeWidth={1.1}>
<Path d="M11 6a5 5 0 1 0-2.5 4.33" />

View File

@ -12,7 +12,7 @@ const SvgMoreIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Circle cx={2.5} cy={6} r={1} fill={color} />
<Circle cx={6} cy={6} r={1} fill={color} />

View File

@ -12,9 +12,9 @@ const SvgNegativeIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#negative-icon_svg__a)" stroke="#E65F5C">
<G clipPath="url(#negative-icon_svg__a)" stroke={color}>
<Circle cx={6} cy={6} r={5.5} strokeOpacity={0.4} />
<Path d="M6 8.5V3M3 5.5l3 3 3-3" strokeWidth={1.2} />
</G>

View File

@ -12,9 +12,9 @@ const SvgNotificationIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Circle cx={6} cy={6} r={4} fill="#4360DF" />
<Circle cx={6} cy={6} r={4} fill={color} />
</Svg>
)
}

View File

@ -12,7 +12,7 @@ const SvgPauseIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Rect x={2} y={2} width={8} height={8} rx={2} fill={color} />
</Svg>

View File

@ -12,10 +12,10 @@ const SvgPendingIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Circle cx={3} cy={6} r={1} fill="#000" fillOpacity={0.4} />
<Circle cx={6} cy={6} r={1} fill="#1B273D" fillOpacity={0.3} />
<Circle cx={6} cy={6} r={1} fill={color} fillOpacity={0.3} />
<Circle cx={9} cy={6} r={1} fill="#000" fillOpacity={0.2} />
</Svg>
)

View File

@ -12,7 +12,7 @@ const SvgPickIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#pick-icon_svg__a)">
<Path

View File

@ -12,7 +12,7 @@ const SvgPlaceholderIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
fillRule="evenodd"

View File

@ -12,7 +12,7 @@ const SvgPlayIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="M3.5 4.73c0-1.205 0-1.807.25-2.131a1.2 1.2 0 0 1 .906-.466c.408-.016.899.335 1.88 1.036l1.777 1.269c.737.527 1.106.79 1.237 1.117a1.2 1.2 0 0 1 0 .89c-.13.327-.5.59-1.237 1.117l-1.777 1.27c-.981.7-1.472 1.05-1.88 1.035a1.2 1.2 0 0 1-.906-.466c-.25-.324-.25-.926-.25-2.132V4.731Z"

View File

@ -12,9 +12,9 @@ const SvgPositiveIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#positive-icon_svg__a)" stroke="#26A69A">
<G clipPath="url(#positive-icon_svg__a)" stroke={color}>
<Circle cx={6} cy={6} r={5.5} strokeOpacity={0.4} />
<Path d="M6 3.5V9M9 6.5l-3-3-3 3" strokeWidth={1.2} />
</G>

View File

@ -12,7 +12,7 @@ const SvgProgressIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#progress-icon_svg__a)" strokeWidth={1.1}>
<Path d="M6 1a5 5 0 1 1 0 10A5 5 0 0 1 6 1Z" stroke="#E7EAEE" />

View File

@ -12,7 +12,7 @@ const SvgPullupIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#pullup-icon_svg__a)">
<Circle

View File

@ -12,10 +12,10 @@ const SvgRemoveIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#remove-icon_svg__a)">
<Circle cx={6} cy={6} r={6} fill="#647084" />
<Circle cx={6} cy={6} r={6} fill={color} />
<Path
d="M3.879 3.879 8.12 8.12M8.121 3.879 3.88 8.12"
stroke="#fff"

View File

@ -12,7 +12,7 @@ const SvgSearchIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
fillRule="evenodd"

View File

@ -12,11 +12,11 @@ const SvgSendMessageIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G
clipPath="url(#send-message-icon_svg__a)"
stroke="#000"
stroke={color}
strokeWidth={1.1}
>
<Path d="m2.495 5.511 5.466-3.609a1 1 0 0 1 1.55.894l-.393 6.539c-.055.918-1.216 1.28-1.784.558L5.63 7.728l-2.727-.393c-.91-.13-1.175-1.317-.408-1.824ZM9.13 1.666l-3.5 6.062" />

View File

@ -12,7 +12,7 @@ const SvgSentIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path d="M2.5 6.25 5 8.75l4.5-5.5" stroke={color} strokeWidth={1.3} />
</Svg>

View File

@ -12,7 +12,7 @@ const SvgTimeoutIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#timeout-icon_svg__a)">
<Path

View File

@ -12,7 +12,7 @@ const SvgTotalMembersIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="M3 9.25A2.25 2.25 0 0 1 5.25 7h1.5A2.25 2.25 0 0 1 9 9.25a.75.75 0 0 1-.75.75h-4.5A.75.75 0 0 1 3 9.25Z"

View File

@ -12,7 +12,7 @@ const SvgTrashIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#trash-icon_svg__a)" stroke={color} strokeWidth={1.1}>
<Path d="M2.5 3.5v4.3c0 1.12 0 1.68.218 2.108a2 2 0 0 0 .874.874C4.02 11 4.58 11 5.7 11h.6c1.12 0 1.68 0 2.108-.218a2 2 0 0 0 .874-.874C9.5 9.48 9.5 8.92 9.5 7.8V3.5M8 3a2 2 0 1 0-4 0M5 5.5V8M7 5.5V8" />

View File

@ -12,7 +12,7 @@ const SvgUnlockedIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="M2.5 7.75c0-.465 0-.697.038-.89A2 2 0 0 1 4.11 5.288c.193-.038.425-.038.89-.038h2c.465 0 .697 0 .89.038A2 2 0 0 1 9.462 6.86c.038.193.038.425.038.89s0 .697-.038.89a2 2 0 0 1-1.572 1.572c-.193.038-.425.038-.89.038H5c-.465 0-.697 0-.89-.038A2 2 0 0 1 2.538 8.64C2.5 8.447 2.5 8.215 2.5 7.75ZM8 5.25v-1.5a2 2 0 1 0-4 0"

View File

@ -12,9 +12,9 @@ const SvgUntrustworthyIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Circle cx={6} cy={6} r={5} fill="#E65F5C" />
<Circle cx={6} cy={6} r={5} fill={color} />
<Path d="M6 7V3M6 9V8" stroke="#fff" strokeWidth={1.1} />
</Svg>
)

View File

@ -12,7 +12,7 @@ const SvgVerified1Icon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<G clipPath="url(#verified-1-icon_svg__a)">
<Path

View File

@ -12,9 +12,9 @@ const SvgVerifiedIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Circle cx={6} cy={6} r={5} fill="#26A69A" />
<Circle cx={6} cy={6} r={5} fill={color} />
<Path d="m4 6.3 1.333 1.2L8 4.5" stroke="#fff" strokeWidth={1.1} />
</Svg>
)

View File

@ -12,7 +12,7 @@ const SvgWhistleIcon = (props: SvgProps) => {
height={12}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="M7.128 7.696A3 3 0 0 0 6.732 6l1.232-1.866-1-1.732-4.33 2.5a3 3 0 1 0 4.494 2.794Z"

View File

@ -12,7 +12,7 @@ const SvgAddIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path d="M8 13V3M3 8h10" stroke={color} strokeWidth={1.2} />
</Svg>

View File

@ -12,7 +12,7 @@ const SvgAddUserIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="M8.5 10H6a3 3 0 0 0-3 3 1 1 0 0 0 1 1h4.5"

View File

@ -12,7 +12,7 @@ const SvgAlertIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Circle
cx={8}

View File

@ -12,7 +12,7 @@ const SvgArrowDownIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path d="m4 9 4 4 4-4M8 3v10" stroke={color} strokeWidth={1.2} />
</Svg>

View File

@ -12,7 +12,7 @@ const SvgArrowRightIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path d="m9 12 4-4-4-4M3 8h10" stroke={color} strokeWidth={1.2} />
</Svg>

View File

@ -12,7 +12,7 @@ const SvgCalendarIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="M14 9.2c0 1.68 0 2.52-.327 3.162a3 3 0 0 1-1.311 1.311C11.72 14 10.88 14 9.2 14H6.8c-1.68 0-2.52 0-3.162-.327a3 3 0 0 1-1.311-1.311C2 11.72 2 10.88 2 9.2V7.8c0-1.68 0-2.52.327-3.162a3 3 0 0 1 1.311-1.311C4.28 3 5.12 3 6.8 3h2.4c1.68 0 2.52 0 3.162.327a3 3 0 0 1 1.311 1.311C14 5.28 14 6.12 14 7.8v1.4Z"

View File

@ -12,7 +12,7 @@ const SvgCheckCircleIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Circle cx={8} cy={8} r={6} stroke={color} strokeWidth={1.2} />
<Path d="m5 8 2 2 4-4" stroke={color} strokeWidth={1.2} />

View File

@ -12,7 +12,7 @@ const SvgChevronDownIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path d="m5 6.5 3 3 3-3" stroke={color} strokeWidth={1.2} />
</Svg>

View File

@ -12,7 +12,7 @@ const SvgChevronLeftIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path d="m9.5 5-3 3 3 3" stroke={color} strokeWidth={1.2} />
</Svg>

View File

@ -12,7 +12,7 @@ const SvgChevronRightIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path d="m6.5 11 3-3-3-3" stroke={color} strokeWidth={1.2} />
</Svg>

View File

@ -12,7 +12,7 @@ const SvgChevronTopIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path d="m11 9.5-3-3-3 3" stroke={color} strokeWidth={1.2} />
</Svg>

View File

@ -12,7 +12,7 @@ const SvgCloseIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="m4.464 11.536 7.072-7.072M4.464 4.464l7.072 7.072"

View File

@ -12,17 +12,17 @@ const SvgConnectionIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="M11 14H5l3-7 3 7Z"
stroke="#000"
stroke={color}
strokeWidth={1.2}
strokeLinejoin="round"
/>
<Path
d="M8 7V5M4.61 2a3.6 3.6 0 0 0 0 6M5.8 3.531a2.1 2.1 0 0 0 0 2.939M11.39 8a3.601 3.601 0 0 0 0-6M10.2 6.469a2.1 2.1 0 0 0 0-2.939"
stroke="#000"
stroke={color}
strokeWidth={1.2}
strokeLinecap="square"
strokeLinejoin="round"

View File

@ -12,7 +12,7 @@ const SvgContactBookIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="M6 10.625c0-1.036.84-1.875 1.875-1.875h1.25c1.036 0 1.875.84 1.875 1.875 0 .345-.28.625-.625.625h-3.75A.625.625 0 0 1 6 10.625Z"

View File

@ -12,7 +12,7 @@ const SvgDeleteIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="M3.5 4h9l-.348 6.96c-.053 1.069-.08 1.604-.305 2.01a2 2 0 0 1-.868.825c-.417.205-.952.205-2.023.205H7.044c-1.07 0-1.606 0-2.023-.204a2 2 0 0 1-.868-.826c-.225-.406-.252-.94-.305-2.01L3.5 4Z"

View File

@ -12,7 +12,7 @@ const SvgEmailIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="M9.2 13H6.8c-1.68 0-2.52 0-3.162-.327a3 3 0 0 1-1.311-1.311C2 10.72 2 9.88 2 8.2v-.4c0-1.68 0-2.52.327-3.162a3 3 0 0 1 1.311-1.311C4.28 3 5.12 3 6.8 3h2.4c1.68 0 2.52 0 3.162.327a3 3 0 0 1 1.311 1.311C14 5.28 14 6.12 14 7.8v.4c0 1.68 0 2.52-.327 3.162a3 3 0 0 1-1.311 1.311C11.72 13 10.88 13 9.2 13Z"

View File

@ -12,14 +12,14 @@ const SvgForwardIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="M14 8H8.4c-2.24 0-3.36 0-4.216.436a4 4 0 0 0-1.748 1.748C2 11.04 2 12.16 2 14.4v.1"
stroke="#000"
stroke={color}
strokeWidth={1.2}
/>
<Path d="M10 11.5 14 8l-4-3.5" stroke="#000" strokeWidth={1.2} />
<Path d="M10 11.5 14 8l-4-3.5" stroke={color} strokeWidth={1.2} />
</Svg>
)
}

View File

@ -12,7 +12,7 @@ const SvgGifIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="M9.2 14H6.8c-1.68 0-2.52 0-3.162-.327a3 3 0 0 1-1.311-1.311C2 11.72 2 10.88 2 9.2V6.8c0-1.68 0-2.52.327-3.162a3 3 0 0 1 1.311-1.311C4.28 2 5.12 2 6.8 2h2.4c1.68 0 2.52 0 3.162.327a3 3 0 0 1 1.311 1.311C14 4.28 14 5.12 14 6.8v2.4c0 1.68 0 2.52-.327 3.162a3 3 0 0 1-1.311 1.311C11.72 14 10.88 14 9.2 14Z"

View File

@ -12,7 +12,7 @@ const SvgGroupIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
fillRule="evenodd"

View File

@ -12,15 +12,15 @@ const SvgHistoryIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
fillRule="evenodd"
clipRule="evenodd"
d="M2.6 4.204V3H1.4v3.6h3.1V5.4H3.266a5.4 5.4 0 1 1-.534 3.792l-1.165.291A6.6 6.6 0 1 0 2.6 4.204Z"
fill="#000"
fill={color}
/>
<Path d="M7.5 5v3l2.5 2.5" stroke="#000" strokeWidth={1.2} />
<Path d="M7.5 5v3l2.5 2.5" stroke={color} strokeWidth={1.2} />
</Svg>
)
}

View File

@ -12,7 +12,7 @@ const SvgInfoIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Circle cx={8} cy={8} r={6} stroke={color} strokeWidth={1.2} />
<Path d="M8 7v4M8 5v1.25" stroke={color} strokeWidth={1.2} />

View File

@ -12,7 +12,7 @@ const SvgLightningIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
d="M9 2v5h3l-5 7V9H4l5-7Z"

View File

@ -12,7 +12,7 @@ const SvgLockedIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
fillRule="evenodd"

View File

@ -12,7 +12,7 @@ const SvgMentionIcon = (props: SvgProps) => {
height={16}
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
{...rest}
>
<Path
fillRule="evenodd"

Some files were not shown because too many files have changed in this diff Show More