Add mobile navigation & Composer (#333)
* feat: add composer component * feat: complete composer component and few minor fixes * feat: add several improvements and new features * fix: change icon button in composer
This commit is contained in:
parent
067389a3f5
commit
33eef5c2aa
|
@ -2,27 +2,26 @@
|
|||
/* eslint-disable import/namespace */
|
||||
import 'expo-dev-client'
|
||||
|
||||
import { useState } from 'react'
|
||||
import { useMemo, useState } from 'react'
|
||||
|
||||
import {
|
||||
Code,
|
||||
Heading,
|
||||
Label,
|
||||
Messages,
|
||||
Paragraph,
|
||||
Shape,
|
||||
Sidebar,
|
||||
} from '@status-im/components'
|
||||
import { Stack, TamaguiProvider } from '@tamagui/core'
|
||||
import { createNativeStackNavigator } from '@react-navigation/native-stack'
|
||||
import { Heading } from '@status-im/components'
|
||||
import { Avatar } from '@status-im/components/src/avatar'
|
||||
import { Stack as View, TamaguiProvider } from '@tamagui/core'
|
||||
import { useFonts } from 'expo-font'
|
||||
import { SafeAreaView, ScrollView, TouchableOpacity } from 'react-native'
|
||||
import { SafeAreaProvider } from 'react-native-safe-area-context'
|
||||
import { AnimatePresence } from 'tamagui'
|
||||
|
||||
import { NavigationProvider } from './navigation/provider'
|
||||
import { ChannelScreen } from './screens/channel'
|
||||
import { HomeScreen } from './screens/home'
|
||||
import tamaguiConfig from './tamagui.config'
|
||||
|
||||
type ThemeVars = 'light' | 'dark'
|
||||
const Stack = createNativeStackNavigator()
|
||||
|
||||
export default function App() {
|
||||
const [theme, setTheme] = useState<ThemeVars>('light')
|
||||
const [position, setPosition] = useState(0)
|
||||
|
||||
const [loaded] = useFonts({
|
||||
Inter: require('@tamagui/font-inter/otf/Inter-Medium.otf'),
|
||||
InterBold: require('@tamagui/font-inter/otf/Inter-Bold.otf'),
|
||||
|
@ -30,56 +29,95 @@ export default function App() {
|
|||
UbuntuMono: require('./assets/fonts/UbuntuMono.ttf'),
|
||||
})
|
||||
|
||||
const onScroll = event => {
|
||||
if (event.nativeEvent.contentOffset.y > 90) {
|
||||
setPosition(event.nativeEvent.contentOffset.y)
|
||||
} else {
|
||||
setPosition(0)
|
||||
}
|
||||
}
|
||||
|
||||
const showMinimizedHeader = useMemo(() => {
|
||||
return position > 90
|
||||
}, [position])
|
||||
|
||||
if (!loaded) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<TamaguiProvider config={tamaguiConfig} defaultTheme={theme}>
|
||||
<SafeAreaView>
|
||||
<ScrollView>
|
||||
<Sidebar
|
||||
name="Rarible"
|
||||
description="Multichain community-centric NFT marketplace. Create, buy and sell your NFTs."
|
||||
membersCount={123}
|
||||
/>
|
||||
<Stack
|
||||
flexDirection="column"
|
||||
justifyContent="center"
|
||||
<TamaguiProvider config={tamaguiConfig} defaultTheme="light">
|
||||
<NavigationProvider>
|
||||
<SafeAreaProvider>
|
||||
<Stack.Navigator>
|
||||
<Stack.Screen
|
||||
name="Home"
|
||||
options={{
|
||||
headerBlurEffect: 'systemUltraThinMaterialLight',
|
||||
headerTransparent: true,
|
||||
headerShadowVisible: true,
|
||||
header: () => (
|
||||
<View
|
||||
height={100}
|
||||
animation="fast"
|
||||
backgroundColor={
|
||||
showMinimizedHeader ? '$background' : 'transparent'
|
||||
}
|
||||
padding={16}
|
||||
paddingTop={48}
|
||||
flexDirection="row"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
paddingTop={20}
|
||||
paddingHorizontal={12}
|
||||
>
|
||||
<AnimatePresence>
|
||||
{showMinimizedHeader && (
|
||||
<View
|
||||
key="header"
|
||||
animation={[
|
||||
'fast',
|
||||
{
|
||||
opacity: {
|
||||
overshootClamping: true,
|
||||
},
|
||||
},
|
||||
]}
|
||||
enterStyle={{ opacity: 0 }}
|
||||
exitStyle={{ opacity: 0 }}
|
||||
opacity={1}
|
||||
flexDirection="row"
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
width="100%"
|
||||
backgroundColor="$background"
|
||||
>
|
||||
<Heading weight="semibold" marginBottom={12}>
|
||||
Communities
|
||||
</Heading>
|
||||
<Heading heading="h2" marginBottom={12}>
|
||||
This is an Heading 2
|
||||
</Heading>
|
||||
<Paragraph weight="semibold" marginBottom={12} uppercase>
|
||||
Paragraph uppercased and bolded
|
||||
</Paragraph>
|
||||
<Paragraph marginBottom={12} uppercase>
|
||||
This is a paragraph
|
||||
</Paragraph>
|
||||
<Label marginBottom={12}>This is a label</Label>
|
||||
<Code marginBottom={12}>This is a code line</Code>
|
||||
<Paragraph fontWeight="400">0x213abc190 ... 121ah4a9e</Paragraph>
|
||||
<Shape marginVertical={20} />
|
||||
|
||||
<Paragraph>Theme selected - {theme}</Paragraph>
|
||||
<TouchableOpacity
|
||||
onPress={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
|
||||
<Heading color="$textPrimary">Rarible</Heading>
|
||||
<Avatar
|
||||
withOutline
|
||||
src="https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fi.seadn.io%2Fgae%2FFG0QJ00fN3c_FWuPeUr9-T__iQl63j9hn5d6svW8UqOmia5zp3lKHPkJuHcvhZ0f_Pd6P2COo9tt9zVUvdPxG_9BBw%3Fw%3D500%26auto%3Dformat&f=1&nofb=1&ipt=c177cd71d8d0114080cfc6efd3f9e098ddaeb1b347919bd3089bf0aacb003b3e&ipo=images"
|
||||
size={48}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</View>
|
||||
),
|
||||
}}
|
||||
>
|
||||
<Paragraph>Toogle theme</Paragraph>
|
||||
</TouchableOpacity>
|
||||
|
||||
<Messages />
|
||||
</Stack>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
{props => (
|
||||
<HomeScreen
|
||||
{...props}
|
||||
onScroll={onScroll}
|
||||
isMinimized={showMinimizedHeader}
|
||||
/>
|
||||
)}
|
||||
</Stack.Screen>
|
||||
<Stack.Screen
|
||||
name="Channel"
|
||||
component={ChannelScreen}
|
||||
options={{ title: 'Messages' }}
|
||||
/>
|
||||
</Stack.Navigator>
|
||||
</SafeAreaProvider>
|
||||
</NavigationProvider>
|
||||
</TamaguiProvider>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import { NavigationContainer } from '@react-navigation/native'
|
||||
|
||||
export function NavigationProvider({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
return <NavigationContainer>{children}</NavigationContainer>
|
||||
}
|
|
@ -10,6 +10,8 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.18.9",
|
||||
"@react-navigation/native": "^6.1.2",
|
||||
"@react-navigation/native-stack": "^6.9.8",
|
||||
"@status-im/components": "*",
|
||||
"expo": "^47.0.12",
|
||||
"expo-constants": "^14.0.2",
|
||||
|
@ -21,6 +23,8 @@
|
|||
"react": "18.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"react-native": "0.70.5",
|
||||
"react-native-safe-area-context": "4.4.1",
|
||||
"react-native-screens": "~3.18.0",
|
||||
"react-native-web": "~0.18.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
// eslint-disable-next-line eslint-comments/disable-enable-pair
|
||||
/* eslint-disable import/namespace */
|
||||
import { Composer, Messages } from '@status-im/components'
|
||||
import { Stack, useTheme } from '@tamagui/core'
|
||||
import {
|
||||
Keyboard,
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
TouchableWithoutFeedback,
|
||||
} from 'react-native'
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
||||
import { ScrollView } from 'tamagui'
|
||||
|
||||
export const ChannelScreen = () => {
|
||||
const insets = useSafeAreaInsets()
|
||||
const theme = useTheme()
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView
|
||||
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
|
||||
keyboardVerticalOffset={Platform.select({ ios: 60 })}
|
||||
style={{ height: '100%', flex: 1, backgroundColor: theme.background.val }}
|
||||
>
|
||||
<ScrollView paddingHorizontal={12} width="100%">
|
||||
<Messages py={20} />
|
||||
</ScrollView>
|
||||
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
||||
<Stack pb={insets.bottom}>
|
||||
<Composer />
|
||||
</Stack>
|
||||
</TouchableWithoutFeedback>
|
||||
</KeyboardAvoidingView>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
// eslint-disable-next-line eslint-comments/disable-enable-pair
|
||||
/* eslint-disable import/namespace */
|
||||
import { useState } from 'react'
|
||||
|
||||
import { Sidebar } from '@status-im/components'
|
||||
import { Stack } from '@tamagui/core'
|
||||
import { StatusBar } from 'expo-status-bar'
|
||||
import { ScrollView } from 'tamagui'
|
||||
|
||||
export const HomeScreen = ({ navigation, onScroll, isMinimized }) => {
|
||||
const [selectedChannel, setSelectedChannel] = useState<string>('welcome')
|
||||
|
||||
const onChannelPress = (id: string) => {
|
||||
setSelectedChannel(id)
|
||||
navigation.navigate('Channel')
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack flex={1} backgroundColor="$background">
|
||||
<StatusBar style={isMinimized ? 'dark' : 'light'} animated />
|
||||
<ScrollView onScroll={onScroll} scrollEventThrottle={16} flex={1}>
|
||||
<Stack pb={40}>
|
||||
<Sidebar
|
||||
name="Rarible"
|
||||
description="Multichain community-centric NFT marketplace. Create, buy and sell your NFTs."
|
||||
membersCount={123}
|
||||
onChannelPress={onChannelPress}
|
||||
selectedChannel={selectedChannel}
|
||||
/>
|
||||
</Stack>
|
||||
</ScrollView>
|
||||
</Stack>
|
||||
)
|
||||
}
|
|
@ -3,6 +3,7 @@ import { useState } from 'react'
|
|||
import {
|
||||
Button,
|
||||
Code,
|
||||
Composer,
|
||||
Heading,
|
||||
Label,
|
||||
Messages,
|
||||
|
@ -10,17 +11,41 @@ import {
|
|||
Shape,
|
||||
Sidebar,
|
||||
} from '@status-im/components'
|
||||
import { Stack, TamaguiProvider } from '@tamagui/core'
|
||||
import { Stack, styled, TamaguiProvider } from '@tamagui/core'
|
||||
import { AnimatePresence } from 'tamagui'
|
||||
|
||||
import tamaguiConfig from '../tamagui.config'
|
||||
import { Topbar } from './components/topbar'
|
||||
|
||||
type ThemeVars = 'light' | 'dark'
|
||||
|
||||
const AnimatableDrawer = styled(Stack, {
|
||||
variants: {
|
||||
fromRight: {
|
||||
true: {
|
||||
x: 500,
|
||||
width: 0,
|
||||
},
|
||||
},
|
||||
fromLeft: {
|
||||
true: {
|
||||
x: 500,
|
||||
width: 250,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
function App() {
|
||||
const [theme, setTheme] = useState<ThemeVars>('light')
|
||||
const [showMembers, setShowMembers] = useState(false)
|
||||
|
||||
const [selectedChannel, setSelectedChannel] = useState<string>('welcome')
|
||||
|
||||
const onChannelPress = (id: string) => {
|
||||
setSelectedChannel(id)
|
||||
}
|
||||
|
||||
return (
|
||||
<TamaguiProvider config={tamaguiConfig} defaultTheme={theme}>
|
||||
<div id="app">
|
||||
|
@ -29,9 +54,10 @@ function App() {
|
|||
name="Rarible"
|
||||
description="Multichain community-centric NFT marketplace. Create, buy and sell your NFTs."
|
||||
membersCount={123}
|
||||
onChannelPress={onChannelPress}
|
||||
selectedChannel={selectedChannel}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<main id="main">
|
||||
<Topbar
|
||||
membersVisisble={showMembers}
|
||||
|
@ -71,16 +97,30 @@ function App() {
|
|||
</Stack>
|
||||
</Stack>
|
||||
</div>
|
||||
<Stack
|
||||
backgroundColor="$background"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
>
|
||||
<Paragraph weight="semibold">Composer</Paragraph>
|
||||
</Stack>
|
||||
<Composer />
|
||||
</main>
|
||||
|
||||
{showMembers && <div id="members">members</div>}
|
||||
<AnimatePresence>
|
||||
{showMembers && (
|
||||
<AnimatableDrawer
|
||||
id="members"
|
||||
key="members"
|
||||
animation={[
|
||||
'fast',
|
||||
{
|
||||
opacity: {
|
||||
overshootClamping: true,
|
||||
},
|
||||
},
|
||||
]}
|
||||
enterStyle={{ opacity: 0 }}
|
||||
exitStyle={{ opacity: 0 }}
|
||||
opacity={1}
|
||||
>
|
||||
members
|
||||
</AnimatableDrawer>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
</TamaguiProvider>
|
||||
)
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import '../styles/reset.css'
|
||||
import '../styles/app.css'
|
||||
import '@tamagui/core/reset.css'
|
||||
import '@tamagui/font-inter/css/400.css'
|
||||
import '@tamagui/font-inter/css/700.css'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
|
|
|
@ -15,13 +15,9 @@ body,
|
|||
display: grid;
|
||||
grid-template-rows: 56px 1fr 100px;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
#main,
|
||||
#sidebar,
|
||||
#members,
|
||||
#main > div {
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
border-width: 0 1px;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import React from 'react'
|
||||
|
||||
import { ChevronIcon } from '@status-im/icons'
|
||||
import { Stack } from '@tamagui/core'
|
||||
import { AnimatePresence } from 'tamagui'
|
||||
|
||||
import { Chevron } from '../icon'
|
||||
import { Label, Paragraph } from '../typography'
|
||||
|
||||
import type { GetProps } from '@tamagui/core'
|
||||
|
@ -48,9 +48,17 @@ const Accordion = ({
|
|||
<Stack flexDirection="row" alignItems="center">
|
||||
<Stack
|
||||
animation="fast"
|
||||
transform={[{ rotateZ: isExpanded ? '90deg' : '0deg' }]}
|
||||
justifyContent="center"
|
||||
transform={[
|
||||
{
|
||||
rotateZ: isExpanded ? '90deg' : '0deg',
|
||||
},
|
||||
{
|
||||
translateY: isExpanded ? -4 : 0,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Chevron color="$neutral-50" size={16} />
|
||||
<ChevronIcon color="$neutral-50" size={16} />
|
||||
</Stack>
|
||||
<Paragraph
|
||||
marginLeft={4}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { MutedIcon } from '@status-im/icons'
|
||||
import { Stack } from '@tamagui/core'
|
||||
|
||||
import { Muted } from '../icon'
|
||||
import { Label, Paragraph } from '../typography'
|
||||
|
||||
import type { GetProps } from '@tamagui/core'
|
||||
|
@ -42,7 +42,10 @@ const AccordionItem = ({
|
|||
},
|
||||
},
|
||||
]}
|
||||
backgroundColor={isSelected ? '$turquoise-50-opa-10' : 'transparent'}
|
||||
backgroundColor={isSelected ? '$primary-50-opa-10' : 'transparent'}
|
||||
hoverStyle={{
|
||||
backgroundColor: '$primary-50-opa-5',
|
||||
}}
|
||||
borderRadius="$4"
|
||||
padding={8}
|
||||
width="100%"
|
||||
|
@ -105,7 +108,9 @@ const AccordionItem = ({
|
|||
/>
|
||||
</Stack>
|
||||
)}
|
||||
{channelStatus === 'muted' && <Muted size={20} color="$neutral-40" />}
|
||||
{channelStatus === 'muted' && (
|
||||
<MutedIcon size={20} color="$neutral-40" />
|
||||
)}
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
|
|
|
@ -24,6 +24,11 @@ const Base = styled(Stack, {
|
|||
|
||||
variants: {
|
||||
size: {
|
||||
80: {
|
||||
width: 80,
|
||||
height: 80,
|
||||
borderRadius: 80 / 2,
|
||||
},
|
||||
56: {
|
||||
width: 56,
|
||||
height: 56,
|
||||
|
@ -80,10 +85,15 @@ const Indicator = styled(Stack, {
|
|||
|
||||
variants: {
|
||||
size: {
|
||||
80: {
|
||||
width: 10,
|
||||
height: 10,
|
||||
borderRadius: '50%',
|
||||
},
|
||||
56: {
|
||||
width: 10,
|
||||
height: 10,
|
||||
borderRadius: 10 / 2,
|
||||
borderRadius: '50%',
|
||||
},
|
||||
// FIXME: use catch all variant
|
||||
52: {
|
||||
|
|
|
@ -24,6 +24,7 @@ const ChatMessage = (props: Props) => {
|
|||
space={10}
|
||||
position="relative"
|
||||
alignItems="flex-start"
|
||||
justifyContent="center"
|
||||
paddingHorizontal={8}
|
||||
paddingVertical={12}
|
||||
borderRadius={16}
|
||||
|
@ -50,7 +51,7 @@ const ChatMessage = (props: Props) => {
|
|||
<Paragraph weight="semibold" color="$neutral-100">
|
||||
Alisher Yakupov
|
||||
</Paragraph>
|
||||
<Paragraph fontFamily="$mono" color="$neutral-50" fontSize={11}>
|
||||
<Paragraph color="$neutral-50" fontSize={11}>
|
||||
zQ3...9d4Gs0
|
||||
</Paragraph>
|
||||
<Paragraph color="$neutral-50" variant={11}>
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Stack } from 'tamagui'
|
|||
import { Paragraph } from '../../typography'
|
||||
|
||||
interface Props {
|
||||
onClick: VoidFunction
|
||||
onClick?: VoidFunction
|
||||
}
|
||||
|
||||
export const Actions = (_props: Props) => {
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
import { Stack } from '@tamagui/core'
|
||||
|
||||
import { ChatMessage } from './chat-message'
|
||||
|
||||
import type { GetProps } from '@tamagui/core'
|
||||
|
||||
export * from './chat-message'
|
||||
|
||||
export const Messages = () => {
|
||||
type BaseProps = GetProps<typeof Stack>
|
||||
|
||||
export const Messages = (props: BaseProps) => {
|
||||
return (
|
||||
<>
|
||||
<Stack {...props}>
|
||||
<ChatMessage text="fsdjkf kasldjf ksdlfjksdlfj asdklfj sdkljf" />
|
||||
<ChatMessage text="fsdjkf kasldjf ksdlfjksdlfj asdklfj sdkljf" />
|
||||
<ChatMessage text="fsdjkf kasldjf ksdlfjksdlfj asdklfj sdkljf" />
|
||||
|
@ -21,6 +27,6 @@ export const Messages = () => {
|
|||
<ChatMessage text="fsdjkf kasldjf ksdlfjksdlfj asdklfj sdkljf" />
|
||||
<ChatMessage text="fsdjkf kasldjf ksdlfjksdlfj asdklfj sdkljf" />
|
||||
<ChatMessage text="fsdjkf kasldjf ksdlfjksdlfj asdklfj sdkljf" />
|
||||
</>
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
import {
|
||||
AudioIcon,
|
||||
FormatIcon,
|
||||
ImageIcon,
|
||||
ReactionIcon,
|
||||
} from '@status-im/icons'
|
||||
import { Stack, XStack, YStack } from 'tamagui'
|
||||
|
||||
import { IconButton } from '../icon-button'
|
||||
import { Input } from '../input'
|
||||
|
||||
import type { GetProps } from '@tamagui/core'
|
||||
|
||||
type BaseProps = GetProps<typeof YStack>
|
||||
|
||||
const Composer = (props: BaseProps) => {
|
||||
return (
|
||||
<YStack
|
||||
backgroundColor="$background"
|
||||
shadowColor="rgba(9, 16, 28, 0.08)"
|
||||
shadowOffset={{ width: 0, height: -4 }}
|
||||
shadowRadius={20}
|
||||
borderTopLeftRadius={20}
|
||||
borderTopRightRadius={20}
|
||||
elevation={0}
|
||||
px={16}
|
||||
pt={8}
|
||||
pb={12}
|
||||
width="100%"
|
||||
{...props}
|
||||
>
|
||||
<YStack>
|
||||
<Input
|
||||
elevation={10}
|
||||
placeholder="Type something..."
|
||||
borderWidth={0}
|
||||
px={0}
|
||||
/>
|
||||
</YStack>
|
||||
<XStack alignItems="center" justifyContent="space-between" pt={8}>
|
||||
<Stack space={12} flexDirection="row">
|
||||
<IconButton noBackground icon={<ImageIcon />} />
|
||||
<IconButton noBackground icon={<ReactionIcon />} />
|
||||
<IconButton noBackground icon={<FormatIcon />} />
|
||||
</Stack>
|
||||
<IconButton noBackground icon={<AudioIcon />} />
|
||||
</XStack>
|
||||
</YStack>
|
||||
)
|
||||
}
|
||||
|
||||
export { Composer }
|
|
@ -0,0 +1 @@
|
|||
export { Composer } from './composer'
|
|
@ -13,9 +13,10 @@ const Base = styled(Stack, {
|
|||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
animation: 'fast',
|
||||
|
||||
width: 31,
|
||||
height: 31,
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderWidth: 1,
|
||||
backgroundColor: '$neutral-10',
|
||||
borderColor: '$neutral-10',
|
||||
|
@ -24,7 +25,27 @@ const Base = styled(Stack, {
|
|||
backgroundColor: '$neutral-20',
|
||||
},
|
||||
|
||||
pressStyle: {
|
||||
backgroundColor: '$neutral-20',
|
||||
},
|
||||
|
||||
variants: {
|
||||
noBackground: {
|
||||
true: {
|
||||
backgroundColor: 'transparent',
|
||||
borderColor: '$neutral-20',
|
||||
|
||||
hoverStyle: {
|
||||
backgroundColor: 'transparent',
|
||||
borderColor: '$neutral-30',
|
||||
},
|
||||
|
||||
pressStyle: {
|
||||
backgroundColor: 'transparent',
|
||||
borderColor: '$neutral-30',
|
||||
},
|
||||
},
|
||||
},
|
||||
selected: {
|
||||
true: {
|
||||
backgroundColor: '$neutral-30',
|
||||
|
@ -56,14 +77,17 @@ interface Props {
|
|||
icon: React.ReactElement
|
||||
onPress?: () => void
|
||||
selected?: boolean
|
||||
noBackground?: boolean
|
||||
}
|
||||
|
||||
const IconButton = (props: Props) => {
|
||||
const { icon, selected, onPress } = props
|
||||
const { icon, noBackground, selected, onPress } = props
|
||||
|
||||
return (
|
||||
<Base selected={selected} onPress={onPress}>
|
||||
<Icon selected={selected}>{icon}</Icon>
|
||||
<Base selected={selected} onPress={onPress} noBackground={noBackground}>
|
||||
<Icon selected={selected} pointerEvents="none">
|
||||
{icon}
|
||||
</Icon>
|
||||
</Base>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
import type {
|
||||
SizeTokens,
|
||||
StyleObject,
|
||||
ThemeParsed,
|
||||
Tokens,
|
||||
} from '@tamagui/core'
|
||||
import type { SvgProps } from 'react-native-svg'
|
||||
|
||||
type GetTokenString<A> = A extends string ? `$${A}` : `$${string}`
|
||||
export type ColorTokens =
|
||||
| GetTokenString<keyof Tokens['color']>
|
||||
| GetTokenString<keyof ThemeParsed>
|
||||
|
||||
export type IconProps = SvgProps & {
|
||||
size?: number | SizeTokens
|
||||
color?: ColorTokens
|
||||
style?: StyleObject
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
export { Chevron } from './icons/chevron'
|
||||
export { Group } from './icons/group'
|
||||
export { Muted } from './icons/muted'
|
|
@ -1,6 +1,8 @@
|
|||
/* eslint-disable eslint-comments/disable-enable-pair */
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
import * as icons from '@status-im/icons'
|
||||
|
||||
import { Text } from '../typography'
|
||||
import { Paragraph } from '../typography'
|
||||
|
||||
import type { IconProps } from '@status-im/icons'
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
@ -35,8 +37,8 @@ export const All: Story = {
|
|||
key={name}
|
||||
style={{ display: 'flex', flexDirection: 'column' }}
|
||||
>
|
||||
<Icon color="black" />
|
||||
<Text>{unpascal(name)}</Text>
|
||||
<Icon color="$background" />
|
||||
<Paragraph>{unpascal(name)}</Paragraph>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
export * from './button'
|
||||
export * from './chat-message'
|
||||
export * from './composer'
|
||||
export * from './divider'
|
||||
export * from './icon-button'
|
||||
export * from './image'
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
import { Basketball, Collaboration, Fire, Peach, Play, Unicorn } from '../emoji'
|
||||
|
||||
interface Channels {
|
||||
id: string
|
||||
title: string
|
||||
icon?: React.ReactNode
|
||||
channelStatus?: 'muted' | 'normal' | 'withMessages' | 'withMentions'
|
||||
numberOfMessages?: number
|
||||
}
|
||||
|
||||
export interface CommunityProps {
|
||||
id: string
|
||||
title: string
|
||||
numberOfNewMessages?: number
|
||||
channels: Channels[]
|
||||
}
|
||||
|
||||
// MOCK DATA
|
||||
export const COMMUNITIES: CommunityProps[] = [
|
||||
{
|
||||
id: 'welcome',
|
||||
title: 'Welcome',
|
||||
numberOfNewMessages: 3,
|
||||
channels: [
|
||||
{
|
||||
id: 'welcome',
|
||||
title: '# welcome',
|
||||
icon: <Collaboration hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'general-welcome',
|
||||
title: '# general',
|
||||
icon: <Play hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'random',
|
||||
title: '# random',
|
||||
icon: <Fire hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'onboarding',
|
||||
title: '# onboarding',
|
||||
icon: <Unicorn hasBackground />,
|
||||
channelStatus: 'withMentions',
|
||||
numberOfMessages: 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'community',
|
||||
title: 'Community',
|
||||
numberOfNewMessages: 5,
|
||||
channels: [
|
||||
{
|
||||
id: 'announcements',
|
||||
title: '# announcements',
|
||||
icon: <Peach hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'jobs',
|
||||
title: '# jobs',
|
||||
channelStatus: 'withMentions',
|
||||
numberOfMessages: 3,
|
||||
icon: <Play hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'events',
|
||||
title: '# events',
|
||||
channelStatus: 'withMentions',
|
||||
numberOfMessages: 2,
|
||||
icon: <Fire hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'meetups',
|
||||
title: '# meetups',
|
||||
icon: <Unicorn hasBackground />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'design',
|
||||
title: 'Design',
|
||||
channels: [
|
||||
{
|
||||
id: 'design',
|
||||
title: '# design',
|
||||
icon: <Collaboration hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'ux',
|
||||
title: '# ux',
|
||||
icon: <Play hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'ui',
|
||||
title: '# ui',
|
||||
icon: <Fire hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'figma',
|
||||
title: '# figma',
|
||||
icon: <Unicorn hasBackground />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'General',
|
||||
title: 'General',
|
||||
channels: [
|
||||
{
|
||||
id: 'general',
|
||||
title: '# general',
|
||||
icon: <Collaboration hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'people-ops',
|
||||
title: '# people-ops',
|
||||
icon: <Basketball hasBackground />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'Frontend',
|
||||
title: 'Frontend',
|
||||
channels: [
|
||||
{
|
||||
id: 'react',
|
||||
title: '# react',
|
||||
icon: <Collaboration hasBackground />,
|
||||
channelStatus: 'withMessages',
|
||||
},
|
||||
{
|
||||
id: 'vue',
|
||||
title: '# vue',
|
||||
icon: <Play hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'angular',
|
||||
title: '# angular',
|
||||
channelStatus: 'muted',
|
||||
icon: <Fire hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'svelte',
|
||||
title: '# svelte',
|
||||
icon: <Unicorn hasBackground />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'Backend',
|
||||
title: 'Backend',
|
||||
channels: [
|
||||
{
|
||||
id: 'node',
|
||||
title: '# node',
|
||||
icon: <Collaboration hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'python',
|
||||
title: '# python',
|
||||
icon: <Play hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'ruby',
|
||||
title: '# ruby',
|
||||
icon: <Fire hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'php',
|
||||
title: '# php',
|
||||
channelStatus: 'muted',
|
||||
icon: <Unicorn hasBackground />,
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
|
@ -1,213 +1,53 @@
|
|||
import { useState } from 'react'
|
||||
|
||||
import { GroupIcon } from '@status-im/icons'
|
||||
import { Stack } from '@tamagui/core'
|
||||
|
||||
import { Accordion } from '../accordion/accordion'
|
||||
import { AccordionItem } from '../accordion/accordionItem'
|
||||
import { Avatar } from '../avatar'
|
||||
import { Button } from '../button'
|
||||
// import { Button } from '../button'
|
||||
import { Basketball, Collaboration, Fire, Peach, Play, Unicorn } from '../emoji'
|
||||
import { Group } from '../icon'
|
||||
import { Image } from '../image'
|
||||
import { Heading, Paragraph } from '../typography'
|
||||
import { COMMUNITIES } from './mock-data'
|
||||
|
||||
interface Props {
|
||||
import type { CommunityProps } from './mock-data'
|
||||
import type { GetProps } from '@tamagui/core'
|
||||
|
||||
type BaseProps = GetProps<typeof Stack>
|
||||
|
||||
type Props = {
|
||||
name: string
|
||||
description: string
|
||||
membersCount: number
|
||||
}
|
||||
selectedChannel?: string
|
||||
communities?: CommunityProps[]
|
||||
onChannelPress: (channelId: string) => void
|
||||
} & BaseProps
|
||||
|
||||
interface Channels {
|
||||
id: string
|
||||
title: string
|
||||
icon?: React.ReactNode
|
||||
channelStatus?: 'muted' | 'normal' | 'withMessages' | 'withMentions'
|
||||
numberOfMessages?: number
|
||||
}
|
||||
interface CommunitiesProps {
|
||||
id: string
|
||||
title: string
|
||||
numberOfNewMessages?: number
|
||||
channels: Channels[]
|
||||
}
|
||||
const Sidebar = (props: Props) => {
|
||||
const {
|
||||
name,
|
||||
description,
|
||||
membersCount,
|
||||
communities = COMMUNITIES,
|
||||
selectedChannel,
|
||||
onChannelPress,
|
||||
} = props
|
||||
|
||||
// MOCK DATA
|
||||
const COMMUNITIES: CommunitiesProps[] = [
|
||||
{
|
||||
id: 'welcome',
|
||||
title: 'Welcome',
|
||||
numberOfNewMessages: 3,
|
||||
channels: [
|
||||
{
|
||||
id: 'welcome',
|
||||
title: '# welcome',
|
||||
icon: <Collaboration hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'general-welcome',
|
||||
title: '# general',
|
||||
icon: <Play hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'random',
|
||||
title: '# random',
|
||||
icon: <Fire hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'onboarding',
|
||||
title: '# onboarding',
|
||||
icon: <Unicorn hasBackground />,
|
||||
channelStatus: 'withMentions',
|
||||
numberOfMessages: 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'community',
|
||||
title: 'Community',
|
||||
numberOfNewMessages: 5,
|
||||
channels: [
|
||||
{
|
||||
id: 'announcements',
|
||||
title: '# announcements',
|
||||
icon: <Peach hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'jobs',
|
||||
title: '# jobs',
|
||||
channelStatus: 'withMentions',
|
||||
numberOfMessages: 3,
|
||||
icon: <Play hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'events',
|
||||
title: '# events',
|
||||
channelStatus: 'withMentions',
|
||||
numberOfMessages: 2,
|
||||
icon: <Fire hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'meetups',
|
||||
title: '# meetups',
|
||||
icon: <Unicorn hasBackground />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'Design',
|
||||
title: 'Design',
|
||||
channels: [
|
||||
{
|
||||
id: 'design',
|
||||
title: '# design',
|
||||
icon: <Collaboration hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'ux',
|
||||
title: '# ux',
|
||||
icon: <Play hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'ui',
|
||||
title: '# ui',
|
||||
icon: <Fire hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'figma',
|
||||
title: '# figma',
|
||||
icon: <Unicorn hasBackground />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'General',
|
||||
title: 'General',
|
||||
channels: [
|
||||
{
|
||||
id: 'general',
|
||||
title: '# general',
|
||||
icon: <Collaboration hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'people-ops',
|
||||
title: '# people-ops',
|
||||
icon: <Basketball hasBackground />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'Frontend',
|
||||
title: 'Frontend',
|
||||
channels: [
|
||||
{
|
||||
id: 'react',
|
||||
title: '# react',
|
||||
icon: <Collaboration hasBackground />,
|
||||
channelStatus: 'withMessages',
|
||||
},
|
||||
{
|
||||
id: 'vue',
|
||||
title: '# vue',
|
||||
icon: <Play hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'angular',
|
||||
title: '# angular',
|
||||
channelStatus: 'muted',
|
||||
icon: <Fire hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'svelte',
|
||||
title: '# svelte',
|
||||
icon: <Unicorn hasBackground />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'Backend',
|
||||
title: 'Backend',
|
||||
channels: [
|
||||
{
|
||||
id: 'node',
|
||||
title: '# node',
|
||||
icon: <Collaboration hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'python',
|
||||
title: '# python',
|
||||
icon: <Play hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'ruby',
|
||||
title: '# ruby',
|
||||
icon: <Fire hasBackground />,
|
||||
},
|
||||
{
|
||||
id: 'php',
|
||||
title: '# php',
|
||||
channelStatus: 'muted',
|
||||
icon: <Unicorn hasBackground />,
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const COMMUNITIES_EXPAND_CONTROL = COMMUNITIES.reduce(
|
||||
const communitiesExpandControl = communities.reduce(
|
||||
(o, key) => ({ ...o, [key.id]: false }),
|
||||
|
||||
{} as Record<string, boolean>[]
|
||||
)
|
||||
|
||||
const Sidebar = (props: Props) => {
|
||||
const { name, description, membersCount } = props
|
||||
const [isExpanded, setIsExpanded] = useState({
|
||||
...COMMUNITIES_EXPAND_CONTROL,
|
||||
...communitiesExpandControl,
|
||||
welcome: true,
|
||||
community: true,
|
||||
design: true,
|
||||
})
|
||||
|
||||
const [selectedChannel, setSelectedChannel] = useState('welcome')
|
||||
|
||||
const handleToggle = (id: string) => {
|
||||
setIsExpanded(prev => ({
|
||||
...prev,
|
||||
|
@ -231,23 +71,23 @@ const Sidebar = (props: Props) => {
|
|||
zIndex={10}
|
||||
>
|
||||
<Stack paddingHorizontal={16} paddingBottom={16}>
|
||||
<Stack marginTop={-32} marginBottom={12}>
|
||||
<Stack marginTop={-40} marginBottom={12}>
|
||||
<Avatar
|
||||
withOutline
|
||||
src="https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fi.seadn.io%2Fgae%2FFG0QJ00fN3c_FWuPeUr9-T__iQl63j9hn5d6svW8UqOmia5zp3lKHPkJuHcvhZ0f_Pd6P2COo9tt9zVUvdPxG_9BBw%3Fw%3D500%26auto%3Dformat&f=1&nofb=1&ipt=c177cd71d8d0114080cfc6efd3f9e098ddaeb1b347919bd3089bf0aacb003b3e&ipo=images"
|
||||
size={56}
|
||||
size={80}
|
||||
/>
|
||||
</Stack>
|
||||
<Heading marginBottom={16}>{name}</Heading>
|
||||
<Paragraph marginBottom={12}>{description}</Paragraph>
|
||||
<Stack flexDirection="row" alignItems="center" mb={12}>
|
||||
<Group color="$neutral-100" size={16} />
|
||||
<GroupIcon color="$neutral-100" size={16} />
|
||||
<Paragraph ml={8}>{membersCount}</Paragraph>
|
||||
</Stack>
|
||||
|
||||
<Button>Join community</Button>
|
||||
</Stack>
|
||||
{COMMUNITIES.map(community => (
|
||||
{communities.map(community => (
|
||||
<Accordion
|
||||
key={community.id}
|
||||
isExpanded={!!isExpanded[community.id as keyof typeof isExpanded]}
|
||||
|
@ -258,7 +98,10 @@ const Sidebar = (props: Props) => {
|
|||
!isExpanded[community.id as keyof typeof isExpanded]
|
||||
}
|
||||
>
|
||||
{community.channels.map(channel => (
|
||||
{community.channels.map((channel, index) => {
|
||||
const isLastChannelOfTheList =
|
||||
index === community.channels.length - 1
|
||||
return (
|
||||
<AccordionItem
|
||||
key={channel.id}
|
||||
icon={channel.icon}
|
||||
|
@ -266,9 +109,11 @@ const Sidebar = (props: Props) => {
|
|||
channelStatus={channel.channelStatus}
|
||||
numberOfMessages={channel.numberOfMessages}
|
||||
isSelected={selectedChannel === channel.id}
|
||||
onPress={() => setSelectedChannel(channel.id)}
|
||||
onPress={() => onChannelPress(channel.id)}
|
||||
mb={isLastChannelOfTheList ? 8 : 0}
|
||||
/>
|
||||
))}
|
||||
)
|
||||
})}
|
||||
</Accordion>
|
||||
))}
|
||||
<Stack borderBottomColor="$neutral-10" borderBottomWidth={1} />
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
import { memo } from 'react'
|
||||
|
||||
import { Path, Svg } from 'react-native-svg'
|
||||
|
||||
import { themed } from './themed'
|
||||
|
||||
import type { IconProps } from './types'
|
||||
|
||||
function Icon(props: IconProps) {
|
||||
const { color, size = 20, ...rest } = props
|
||||
|
||||
return (
|
||||
<Svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox={`0 0 ${size} ${size}`}
|
||||
fill="none"
|
||||
{...rest}
|
||||
>
|
||||
<Path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M10 2.35A3.65 3.65 0 0 0 6.35 6v3a3.65 3.65 0 0 0 7.3 0V6A3.65 3.65 0 0 0 10 2.35ZM7.65 6a2.35 2.35 0 1 1 4.7 0v3a2.35 2.35 0 0 1-4.7 0V6Zm-2.5 1.5V9a4.85 4.85 0 1 0 9.7 0V7.5h1.3V9a6.15 6.15 0 0 1-5.5 6.116v1.234H12v1.3H8v-1.3h1.35v-1.234A6.15 6.15 0 0 1 3.85 9V7.5h1.3Z"
|
||||
fill={color}
|
||||
/>
|
||||
</Svg>
|
||||
)
|
||||
}
|
||||
|
||||
export const AudioIcon = memo<IconProps>(themed(Icon))
|
|
@ -1,12 +1,11 @@
|
|||
import { memo } from 'react'
|
||||
|
||||
import { themed } from '@status-im/icons/src/themed'
|
||||
import { Path, Svg } from 'react-native-svg'
|
||||
|
||||
import { themed } from '../themed'
|
||||
import type { IconProps } from './types'
|
||||
|
||||
import type { IconProps } from '../IconProps'
|
||||
|
||||
const Icon = (props: IconProps) => {
|
||||
function Icon(props: IconProps) {
|
||||
const { color, size = 16, ...otherProps } = props
|
||||
|
||||
return (
|
||||
|
@ -22,6 +21,4 @@ const Icon = (props: IconProps) => {
|
|||
)
|
||||
}
|
||||
|
||||
Icon.displayName = 'Chevron'
|
||||
|
||||
export const Chevron = memo<IconProps>(themed(Icon))
|
||||
export const ChevronIcon = memo<IconProps>(themed(Icon))
|
|
@ -0,0 +1,32 @@
|
|||
import { memo } from 'react'
|
||||
|
||||
import { ClipPath, Defs, G, Path, Svg } from 'react-native-svg'
|
||||
|
||||
import { themed } from './themed'
|
||||
|
||||
import type { IconProps } from './types'
|
||||
|
||||
function Icon(props: IconProps) {
|
||||
const { color, size = 20, ...rest } = props
|
||||
|
||||
return (
|
||||
<Svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox={`0 0 ${size} ${size}`}
|
||||
fill="none"
|
||||
{...rest}
|
||||
>
|
||||
<G clipPath="url(#format-icon-a)" fill={color}>
|
||||
<Path d="M4.343 14.047a.858.858 0 1 1-1.622-.558l2.575-7.314a1.493 1.493 0 0 1 2.817 0l2.578 7.314a.858.858 0 1 1-1.621.559L6.753 7.15a.051.051 0 0 0-.098 0l-2.312 6.896Zm-.137-2.434c0-.38.308-.688.688-.688h3.61a.688.688 0 0 1 0 1.376h-3.61a.688.688 0 0 1-.688-.688ZM13.82 14.823c-.449 0-.857-.085-1.223-.254a2.1 2.1 0 0 1-.872-.744c-.216-.326-.324-.72-.324-1.181 0-.407.08-.736.24-.988.16-.256.374-.456.642-.6.268-.145.563-.253.886-.324.327-.073.654-.132.984-.175.43-.055.78-.097 1.048-.125.27-.03.467-.081.59-.152.127-.07.19-.194.19-.37v-.036c0-.456-.125-.81-.374-1.062-.246-.252-.62-.379-1.122-.379-.52 0-.928.114-1.223.342-.13.1-.244.204-.34.311-.193.213-.49.344-.76.248-.303-.108-.457-.453-.275-.717.133-.192.285-.355.456-.488.311-.243.65-.413 1.016-.508.37-.099.732-.148 1.09-.148.227 0 .489.028.784.083.299.053.586.162.863.328.28.166.513.417.697.752.185.336.277.785.277 1.349v4.127c0 .3-.244.544-.544.544h-.065a.48.48 0 0 1-.48-.48v-.446a.034.034 0 0 0-.034-.034.035.035 0 0 0-.03.02 1.96 1.96 0 0 1-.36.474 2.131 2.131 0 0 1-.689.448c-.286.123-.635.185-1.048.185Zm.167-.98c.43 0 .794-.084 1.09-.253a1.729 1.729 0 0 0 .904-1.5v-.653c0-.117-.193-.225-.305-.192a5.124 5.124 0 0 1-.535.115 24.109 24.109 0 0 1-1.044.139 4.158 4.158 0 0 0-.794.18c-.243.08-.44.201-.59.364-.148.16-.222.379-.222.656 0 .379.14.665.42.859.283.19.642.286 1.076.286Z" />
|
||||
</G>
|
||||
<Defs>
|
||||
<ClipPath id="format-icon-a">
|
||||
<Path d="M0 0h20v20H0z" />
|
||||
</ClipPath>
|
||||
</Defs>
|
||||
</Svg>
|
||||
)
|
||||
}
|
||||
|
||||
export const FormatIcon = memo<IconProps>(themed(Icon))
|
|
@ -1,12 +1,11 @@
|
|||
import { memo } from 'react'
|
||||
|
||||
import { themed } from '@status-im/icons/src/themed'
|
||||
import { Path, Svg } from 'react-native-svg'
|
||||
|
||||
import { themed } from '../themed'
|
||||
import type { IconProps } from './types'
|
||||
|
||||
import type { IconProps } from '../IconProps'
|
||||
|
||||
const Icon = (props: IconProps) => {
|
||||
function Icon(props: IconProps) {
|
||||
const { color, size = 16, ...otherProps } = props
|
||||
|
||||
return (
|
||||
|
@ -24,16 +23,14 @@ const Icon = (props: IconProps) => {
|
|||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M4.6 5a1.9 1.9 0 1 1 3.8 0 1.9 1.9 0 0 1-3.8 0Zm1.9-3.1a3.1 3.1 0 1 0 0 6.2 3.1 3.1 0 0 0 0-6.2ZM5 8.9a3.6 3.6 0 0 0-3.6 3.6A1.6 1.6 0 0 0 3 14.1h6a1.6 1.6 0 0 0 1.6-1.6A3.6 3.6 0 0 0 7 8.9H5Zm-2.4 3.6A2.4 2.4 0 0 1 5 10.1h2a2.4 2.4 0 0 1 2.4 2.4.4.4 0 0 1-.4.4H3a.4.4 0 0 1-.4-.4Z"
|
||||
fill={`${color}`}
|
||||
fill={color}
|
||||
/>
|
||||
<Path
|
||||
d="M10 3.1a1.9 1.9 0 0 1 0 3.8v1.2a3.1 3.1 0 0 0 0-6.2v1.2ZM11 10.1h.5a2.4 2.4 0 0 1 2.4 2.4.4.4 0 0 1-.4.4h-2v1.2h2a1.6 1.6 0 0 0 1.6-1.6 3.6 3.6 0 0 0-3.6-3.6H11v1.2Z"
|
||||
fill={`${color}`}
|
||||
fill={color}
|
||||
/>
|
||||
</Svg>
|
||||
)
|
||||
}
|
||||
|
||||
Icon.displayName = 'Group'
|
||||
|
||||
export const Group = memo<IconProps>(themed(Icon))
|
||||
export const GroupIcon = memo<IconProps>(themed(Icon))
|
|
@ -0,0 +1,24 @@
|
|||
import { memo } from 'react'
|
||||
|
||||
import { Path, Svg } from 'react-native-svg'
|
||||
|
||||
import { themed } from './themed'
|
||||
|
||||
import type { IconProps } from './types'
|
||||
|
||||
function Icon(props: IconProps) {
|
||||
const { color, size = 20, ...rest } = props
|
||||
|
||||
return (
|
||||
<Svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} {...rest}>
|
||||
<Path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M9.9 2.85h-.029c-1.096 0-1.958 0-2.651.057-.707.057-1.296.177-1.831.45a4.65 4.65 0 0 0-2.032 2.032c-.273.535-.393 1.124-.45 1.83-.057.694-.057 1.556-.057 2.652v.258c0 1.096 0 1.958.057 2.651.057.707.177 1.296.45 1.831a4.65 4.65 0 0 0 2.032 2.032c.535.273 1.124.393 1.83.45.694.057 1.556.057 2.652.057h.258c1.096 0 1.958 0 2.651-.057.707-.057 1.296-.177 1.831-.45a4.65 4.65 0 0 0 2.032-2.032c.273-.535.393-1.124.45-1.83.057-.694.057-1.556.057-2.652V9.87c0-1.096 0-1.958-.057-2.651-.057-.707-.177-1.296-.45-1.831a4.65 4.65 0 0 0-2.032-2.032c-.535-.273-1.124-.393-1.83-.45-.694-.057-1.556-.057-2.652-.057H9.9ZM5.98 4.515c.32-.163.719-.261 1.346-.313.634-.051 1.443-.052 2.574-.052h.2c1.13 0 1.94 0 2.574.052.627.052 1.026.15 1.347.313a3.35 3.35 0 0 1 1.464 1.464c.163.321.261.72.313 1.347.052.634.052 1.443.052 2.574v.2c0 1.13 0 1.94-.052 2.574a8.05 8.05 0 0 1-.024.243 5.089 5.089 0 0 0-2.754-.549 5.197 5.197 0 0 0-2.284.763 8.646 8.646 0 0 0-6.58-4.703c.007-.424.02-.785.046-1.102.052-.627.15-1.026.313-1.347A3.35 3.35 0 0 1 5.98 4.515Zm5.256 9.841c.155.483.268.98.336 1.487.424-.006.785-.02 1.102-.045.627-.052 1.026-.15 1.347-.313a3.35 3.35 0 0 0 1.372-1.296 3.818 3.818 0 0 0-2.263-.525 3.936 3.936 0 0 0-1.894.692Zm-3.039-2.553a7.35 7.35 0 0 1 2.063 4.047H9.9c-1.13 0-1.94 0-2.574-.052-.627-.052-1.026-.15-1.347-.313a3.35 3.35 0 0 1-1.464-1.464c-.163-.321-.261-.72-.313-1.347-.051-.634-.052-1.443-.052-2.574v-.36a7.35 7.35 0 0 1 4.047 2.063ZM11.15 8a.85.85 0 1 1 1.7 0 .85.85 0 0 1-1.7 0ZM12 5.85a2.15 2.15 0 1 0 0 4.3 2.15 2.15 0 0 0 0-4.3Z"
|
||||
fill={color}
|
||||
/>
|
||||
</Svg>
|
||||
)
|
||||
}
|
||||
|
||||
export const ImageIcon = memo<IconProps>(themed(Icon))
|
|
@ -1,4 +1,11 @@
|
|||
export { AudioIcon } from './audio-icon'
|
||||
export { ChevronIcon } from './chevron-icon'
|
||||
export { FormatIcon } from './format-icon'
|
||||
export { GroupIcon } from './group-icon'
|
||||
export { ImageIcon } from './image-icon'
|
||||
export { LockedIcon } from './lock-icon'
|
||||
export { MembersIcon } from './members-icon'
|
||||
export { MutedIcon } from './muted-icon'
|
||||
export { OptionsIcon } from './options-icon'
|
||||
export { ReactionIcon } from './reaction-icon'
|
||||
export type { IconProps } from './types'
|
||||
|
|
|
@ -1,24 +1,25 @@
|
|||
import { memo } from 'react'
|
||||
|
||||
import { Path, Svg } from 'react-native-svg'
|
||||
|
||||
import { themed } from './themed'
|
||||
|
||||
import type { IconProps } from './types'
|
||||
|
||||
export function LockedIcon(props: IconProps) {
|
||||
function Icon(props: IconProps) {
|
||||
const { color = 'currentColor', size = 20, ...rest } = props
|
||||
|
||||
// FIXME: not need to differentiate sizes in the designs
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...rest}
|
||||
>
|
||||
<path
|
||||
<Svg width={size} height={size} viewBox="0 0 16 16" fill="none" {...rest}>
|
||||
<Path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M8 .9h-.012c-.081 0-.137 0-.186.002a3 3 0 00-2.9 2.9c-.002.05-.002.105-.002.186v1.175a3.6 3.6 0 00-2.127 2.405c-.123.46-.123.998-.123 1.832v.2c0 .834 0 1.373.123 1.832a3.6 3.6 0 002.545 2.545c.46.123.998.123 1.832.123H8.85c.834 0 1.373 0 1.832-.123a3.6 3.6 0 002.545-2.545c.123-.46.123-.998.123-1.832v-.2c0-.834 0-1.373-.123-1.832A3.6 3.6 0 0011.1 5.163V3.988c0-.081 0-.137-.002-.186A3 3 0 008.012.9H8zm.75 5.2h-1.5c-.969 0-1.335.005-1.621.082a2.4 2.4 0 00-1.697 1.697c-.077.286-.082.652-.082 1.621s.005 1.335.082 1.621a2.4 2.4 0 001.697 1.697c.286.077.652.082 1.621.082h1.5c.969 0 1.335-.005 1.621-.082a2.4 2.4 0 001.697-1.697c.077-.286.082-.652.082-1.621s-.005-1.335-.082-1.621a2.4 2.4 0 00-1.697-1.697C10.085 6.105 9.72 6.1 8.75 6.1zm.288-1.2H9.9V4v-.159a1.8 1.8 0 00-1.741-1.74 5.726 5.726 0 00-.318 0 1.8 1.8 0 00-1.74 1.74V4.9H9.037zM7.4 8.25h1.2v2.5H7.4v-2.5z"
|
||||
fill={color}
|
||||
/>
|
||||
</svg>
|
||||
</Svg>
|
||||
)
|
||||
}
|
||||
|
||||
export const LockedIcon = memo<IconProps>(themed(Icon))
|
||||
|
|
|
@ -1,29 +1,30 @@
|
|||
import { memo } from 'react'
|
||||
|
||||
import { Path, Svg } from 'react-native-svg'
|
||||
|
||||
import { themed } from './themed'
|
||||
|
||||
import type { IconProps } from './types'
|
||||
|
||||
export function MembersIcon(props: IconProps) {
|
||||
function Icon(props: IconProps) {
|
||||
const { color = 'currentColor', size = 20, ...rest } = props
|
||||
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...rest}
|
||||
>
|
||||
<path
|
||||
<Svg width={size} height={size} viewBox="0 0 20 20" fill="none" {...rest}>
|
||||
<Path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M6.15 6a1.85 1.85 0 113.7 0 1.85 1.85 0 01-3.7 0zM8 2.85a3.15 3.15 0 100 6.3 3.15 3.15 0 000-6.3zm-1.25 7.5a4.4 4.4 0 00-4.4 4.4c0 1.049.85 1.9 1.9 1.9h7.5a1.9 1.9 0 001.9-1.9 4.4 4.4 0 00-4.4-4.4h-2.5zm-3.1 4.4a3.1 3.1 0 013.1-3.1h2.5a3.1 3.1 0 013.1 3.1.6.6 0 01-.6.6h-7.5a.6.6 0 01-.6-.6z"
|
||||
fill={color}
|
||||
/>
|
||||
<path
|
||||
<Path
|
||||
d="M13.5 11h.25a3.75 3.75 0 013.75 3.75v0c0 .69-.56 1.25-1.25 1.25H14.5M11.809 8c1.153 0 2.087-.895 2.087-2s-.934-2-2.087-2"
|
||||
stroke={color}
|
||||
strokeWidth={1.3}
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
</Svg>
|
||||
)
|
||||
}
|
||||
|
||||
export const MembersIcon = memo<IconProps>(themed(Icon))
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import { memo } from 'react'
|
||||
|
||||
import { themed } from '@status-im/icons/src/themed'
|
||||
import { Path, Svg } from 'react-native-svg'
|
||||
|
||||
import { themed } from '../themed'
|
||||
import type { IconProps } from './types'
|
||||
|
||||
import type { IconProps } from '../IconProps'
|
||||
|
||||
const Icon = (props: IconProps) => {
|
||||
function Icon(props: IconProps) {
|
||||
const { color, size = 16, ...otherProps } = props
|
||||
|
||||
return (
|
||||
|
@ -27,6 +26,4 @@ const Icon = (props: IconProps) => {
|
|||
)
|
||||
}
|
||||
|
||||
Icon.displayName = 'Muted'
|
||||
|
||||
export const Muted = memo<IconProps>(themed(Icon))
|
||||
export const MutedIcon = memo<IconProps>(themed(Icon))
|
|
@ -1,20 +1,21 @@
|
|||
import { memo } from 'react'
|
||||
|
||||
import { Circle, Svg } from 'react-native-svg'
|
||||
|
||||
import { themed } from './themed'
|
||||
|
||||
import type { IconProps } from './types'
|
||||
|
||||
export function OptionsIcon(props: IconProps) {
|
||||
function Icon(props: IconProps) {
|
||||
const { color = 'currentColor', size = 20, ...rest } = props
|
||||
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...rest}
|
||||
>
|
||||
<circle cx={4.5} cy={10} r={1.5} fill={color} />
|
||||
<circle cx={10} cy={10} r={1.5} fill={color} />
|
||||
<circle cx={15.5} cy={10} r={1.5} fill={color} />
|
||||
</svg>
|
||||
<Svg width={size} height={size} viewBox="0 0 20 20" fill="none" {...rest}>
|
||||
<Circle cx={4.5} cy={10} r={1.5} fill={color} />
|
||||
<Circle cx={10} cy={10} r={1.5} fill={color} />
|
||||
<Circle cx={15.5} cy={10} r={1.5} fill={color} />
|
||||
</Svg>
|
||||
)
|
||||
}
|
||||
|
||||
export const OptionsIcon = memo<IconProps>(themed(Icon))
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import { memo } from 'react'
|
||||
|
||||
import { Circle, Path, Svg } from 'react-native-svg'
|
||||
|
||||
import { themed } from './themed'
|
||||
|
||||
import type { IconProps } from './types'
|
||||
|
||||
export function Icon(props: IconProps) {
|
||||
const { color = 'currentColor', size = 20, ...rest } = props
|
||||
|
||||
return (
|
||||
<Svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox={`0 0 ${size} ${size}`}
|
||||
fill="none"
|
||||
{...rest}
|
||||
>
|
||||
<Circle cx="10" cy="10" r="6.75" stroke={color} strokeWidth="1.3" />
|
||||
<Path
|
||||
d="M7.525 12a3.5 3.5 0 0 0 4.95 0"
|
||||
stroke={color}
|
||||
strokeWidth="1.3"
|
||||
/>
|
||||
<Circle cx="8" cy="8.5" r="1" fill={color} />
|
||||
<Circle cx="12" cy="8.5" r="1" fill={color} />
|
||||
</Svg>
|
||||
)
|
||||
}
|
||||
|
||||
export const ReactionIcon = memo<IconProps>(themed(Icon))
|
|
@ -1,6 +1,6 @@
|
|||
import { useCurrentColor } from 'tamagui'
|
||||
|
||||
import type { IconProps } from './IconProps'
|
||||
import type { IconProps } from './types'
|
||||
import type React from 'react'
|
||||
|
||||
export function themed(Component: React.ElementType) {
|
|
@ -1,9 +1,18 @@
|
|||
import type { SVGAttributes } from 'react'
|
||||
import type {
|
||||
SizeTokens,
|
||||
StyleObject,
|
||||
ThemeParsed,
|
||||
Tokens,
|
||||
} from '@tamagui/core'
|
||||
import type { SvgProps } from 'react-native-svg'
|
||||
|
||||
export interface IconProps extends SVGAttributes<SVGElement> {
|
||||
children?: never
|
||||
width?: never
|
||||
height?: never
|
||||
color?: string
|
||||
size?: number
|
||||
type GetTokenString<A> = A extends string ? `$${A}` : `$${string}`
|
||||
export type ColorTokens =
|
||||
| GetTokenString<keyof Tokens['color']>
|
||||
| GetTokenString<keyof ThemeParsed>
|
||||
|
||||
export type IconProps = SvgProps & {
|
||||
size?: number | SizeTokens
|
||||
color?: ColorTokens
|
||||
style?: StyleObject
|
||||
}
|
||||
|
|
101
yarn.lock
101
yarn.lock
|
@ -4421,6 +4421,48 @@
|
|||
resolved "https://registry.yarnpkg.com/@react-native/polyfills/-/polyfills-2.0.0.tgz#4c40b74655c83982c8cf47530ee7dc13d957b6aa"
|
||||
integrity sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ==
|
||||
|
||||
"@react-navigation/core@^6.4.6":
|
||||
version "6.4.6"
|
||||
resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-6.4.6.tgz#b0738667dec5927b01c4c496c2f4c73ef8a5e4dd"
|
||||
integrity sha512-6zaAgUT5k4vhJlddUk2l52RZyMkMelHdrRv1cL57ALi2RZzERdgmbiMKhJerxFLn9S8E3PUe8vwxHzjHOZKG4w==
|
||||
dependencies:
|
||||
"@react-navigation/routers" "^6.1.6"
|
||||
escape-string-regexp "^4.0.0"
|
||||
nanoid "^3.1.23"
|
||||
query-string "^7.1.3"
|
||||
react-is "^16.13.0"
|
||||
use-latest-callback "^0.1.5"
|
||||
|
||||
"@react-navigation/elements@^1.3.13":
|
||||
version "1.3.13"
|
||||
resolved "https://registry.yarnpkg.com/@react-navigation/elements/-/elements-1.3.13.tgz#5105fa26df8d32810cd9f14d6ec5a3d2c2bb26d2"
|
||||
integrity sha512-LqqK5s2ZfYHn2cQ376jC5V9dQztLH5ixkkJj9WR7JY2g4SghDd39WJhL3Jillw1Mu3F3b9sZwvAK+QkXhnDeAA==
|
||||
|
||||
"@react-navigation/native-stack@^6.9.8":
|
||||
version "6.9.8"
|
||||
resolved "https://registry.yarnpkg.com/@react-navigation/native-stack/-/native-stack-6.9.8.tgz#c953a169918a4bdde56f7d2dc1073da4726b4cb7"
|
||||
integrity sha512-74dje939lflsTXJQwCAdznbJ4B6V8sA5CSzuHwbiogL8B6EVXNa/qliXtB7DBAvzeyWDWT3u+gM2vOYJOeXYhA==
|
||||
dependencies:
|
||||
"@react-navigation/elements" "^1.3.13"
|
||||
warn-once "^0.1.0"
|
||||
|
||||
"@react-navigation/native@^6.1.2":
|
||||
version "6.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-6.1.2.tgz#6fffbf4787c233687fff8fe9ce7364ffce696d38"
|
||||
integrity sha512-qLUe0asHofr5EhxKjvUBJ9DrPPmR4535IEwmW3oU4DRb3cLbNysjajJKHL8kcYtqPvn9Bx9QZG2x0PMb2vN23A==
|
||||
dependencies:
|
||||
"@react-navigation/core" "^6.4.6"
|
||||
escape-string-regexp "^4.0.0"
|
||||
fast-deep-equal "^3.1.3"
|
||||
nanoid "^3.1.23"
|
||||
|
||||
"@react-navigation/routers@^6.1.6":
|
||||
version "6.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@react-navigation/routers/-/routers-6.1.6.tgz#f57f2a73855d329255aa225fdad75ae8e7700c6d"
|
||||
integrity sha512-Z5DeCW3pUvMafbU9Cjy1qJYC2Bvl8iy3+PfsB0DsAwQ6zZ3WAXW5FTMX4Gb9H+Jg6qHWGbMFFwlYpS3UJ3tlVQ==
|
||||
dependencies:
|
||||
nanoid "^3.1.23"
|
||||
|
||||
"@rollup/pluginutils@^4.2.0", "@rollup/pluginutils@^4.2.1":
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d"
|
||||
|
@ -8636,7 +8678,7 @@ decamelize@^5.0.0:
|
|||
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-5.0.1.tgz#db11a92e58c741ef339fb0a2868d8a06a9a7b1e9"
|
||||
integrity sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==
|
||||
|
||||
decode-uri-component@^0.2.0:
|
||||
decode-uri-component@^0.2.0, decode-uri-component@^0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9"
|
||||
integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==
|
||||
|
@ -10734,6 +10776,11 @@ fill-range@^7.0.1:
|
|||
dependencies:
|
||||
to-regex-range "^5.0.1"
|
||||
|
||||
filter-obj@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b"
|
||||
integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==
|
||||
|
||||
finalhandler@1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
|
||||
|
@ -13980,7 +14027,7 @@ nanoid@^3.0.2:
|
|||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35"
|
||||
integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==
|
||||
|
||||
nanoid@^3.3.1, nanoid@^3.3.4:
|
||||
nanoid@^3.1.23, nanoid@^3.3.1, nanoid@^3.3.4:
|
||||
version "3.3.4"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
|
||||
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
|
||||
|
@ -15281,6 +15328,16 @@ qs@6.11.0, qs@^6.10.0, qs@^6.4.0:
|
|||
dependencies:
|
||||
side-channel "^1.0.4"
|
||||
|
||||
query-string@^7.1.3:
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.3.tgz#a1cf90e994abb113a325804a972d98276fe02328"
|
||||
integrity sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==
|
||||
dependencies:
|
||||
decode-uri-component "^0.2.2"
|
||||
filter-obj "^1.1.0"
|
||||
split-on-first "^1.0.0"
|
||||
strict-uri-encode "^2.0.0"
|
||||
|
||||
querystringify@^2.1.1:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
|
||||
|
@ -15387,6 +15444,11 @@ react-element-to-jsx-string@^15.0.0:
|
|||
is-plain-object "5.0.0"
|
||||
react-is "18.1.0"
|
||||
|
||||
react-freeze@^1.0.0:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/react-freeze/-/react-freeze-1.0.3.tgz#5e3ca90e682fed1d73a7cb50c2c7402b3e85618d"
|
||||
integrity sha512-ZnXwLQnGzrDpHBHiC56TXFXvmolPeMjTn1UOm610M4EXGzbEDR7oOIyS2ZiItgbs6eZc4oU/a0hpk8PrcKvv5g==
|
||||
|
||||
react-inspector@^6.0.0:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-6.0.1.tgz#1a37f0165d9df81ee804d63259eaaeabe841287d"
|
||||
|
@ -15402,7 +15464,7 @@ react-is@18.1.0:
|
|||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
|
||||
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
|
||||
|
||||
react-is@^16.13.1:
|
||||
react-is@^16.13.0, react-is@^16.13.1:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||
|
@ -15427,6 +15489,19 @@ react-native-gradle-plugin@^0.70.3:
|
|||
resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.70.3.tgz#cbcf0619cbfbddaa9128701aa2d7b4145f9c4fc8"
|
||||
integrity sha512-oOanj84fJEXUg9FoEAQomA8ISG+DVIrTZ3qF7m69VQUJyOGYyDZmPqKcjvRku4KXlEH6hWO9i4ACLzNBh8gC0A==
|
||||
|
||||
react-native-safe-area-context@4.4.1:
|
||||
version "4.4.1"
|
||||
resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-4.4.1.tgz#239c60b8a9a80eac70a38a822b04c0f1d15ffc01"
|
||||
integrity sha512-N9XTjiuD73ZpVlejHrUWIFZc+6Z14co1K/p1IFMkImU7+avD69F3y+lhkqA2hN/+vljdZrBSiOwXPkuo43nFQA==
|
||||
|
||||
react-native-screens@~3.18.0:
|
||||
version "3.18.2"
|
||||
resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-3.18.2.tgz#d7ab2d145258d3db9fa630fa5379dc4474117866"
|
||||
integrity sha512-ANUEuvMUlsYJ1QKukEhzhfrvOUO9BVH9Nzg+6eWxpn3cfD/O83yPBOF8Mx6x5H/2+sMy+VS5x/chWOOo/U7QJw==
|
||||
dependencies:
|
||||
react-freeze "^1.0.0"
|
||||
warn-once "^0.1.0"
|
||||
|
||||
react-native-svg@^13.7.0:
|
||||
version "13.7.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-13.7.0.tgz#be2ffb935e996762543dd7376bdc910722f7a43c"
|
||||
|
@ -16566,6 +16641,11 @@ spdx-license-ids@^3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95"
|
||||
integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==
|
||||
|
||||
split-on-first@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f"
|
||||
integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==
|
||||
|
||||
split-string@^3.0.1, split-string@^3.0.2:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2"
|
||||
|
@ -16658,6 +16738,11 @@ stream-transform@^2.1.3:
|
|||
dependencies:
|
||||
mixme "^0.5.1"
|
||||
|
||||
strict-uri-encode@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546"
|
||||
integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==
|
||||
|
||||
string-argv@^0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da"
|
||||
|
@ -17866,6 +17951,11 @@ use-isomorphic-layout-effect@^1.1.1:
|
|||
resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb"
|
||||
integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==
|
||||
|
||||
use-latest-callback@^0.1.5:
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/use-latest-callback/-/use-latest-callback-0.1.5.tgz#a4a836c08fa72f6608730b5b8f4bbd9c57c04f51"
|
||||
integrity sha512-HtHatS2U4/h32NlkhupDsPlrbiD27gSH5swBdtXbCAlc6pfOFzaj0FehW/FO12rx8j2Vy4/lJScCiJyM01E+bQ==
|
||||
|
||||
use-sidecar@^1.0.1:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.0.5.tgz#ffff2a17c1df42e348624b699ba6e5c220527f2b"
|
||||
|
@ -18081,6 +18171,11 @@ walker@^1.0.7, walker@^1.0.8:
|
|||
dependencies:
|
||||
makeerror "1.0.12"
|
||||
|
||||
warn-once@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/warn-once/-/warn-once-0.1.1.tgz#952088f4fb56896e73fd4e6a3767272a3fccce43"
|
||||
integrity sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q==
|
||||
|
||||
watchpack@^2.2.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d"
|
||||
|
|
Loading…
Reference in New Issue