@urbint/cl 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/rules +313 -0
- package/.rnstorybook/index.ts +11 -0
- package/.rnstorybook/main.ts +8 -0
- package/.rnstorybook/preview.tsx +14 -0
- package/.rnstorybook/storybook.requires.ts +49 -0
- package/.storybook/main.ts +16 -0
- package/.storybook/preview.ts +32 -0
- package/.storybook/vitest.setup.ts +7 -0
- package/App.tsx +422 -0
- package/README.md +229 -0
- package/app.json +33 -0
- package/assets/adaptive-icon.png +0 -0
- package/assets/favicon.png +0 -0
- package/assets/icon.png +0 -0
- package/assets/splash-icon.png +0 -0
- package/babel.config.js +16 -0
- package/docs/components/CodeBlock.tsx +80 -0
- package/docs/components/PropTable.tsx +93 -0
- package/docs/components/Sidebar.tsx +199 -0
- package/docs/components/index.ts +8 -0
- package/docs/data/colorTokens.ts +70 -0
- package/docs/data/componentData.tsx +1685 -0
- package/docs/data/index.ts +7 -0
- package/docs/index.ts +19 -0
- package/docs/navigation.ts +94 -0
- package/docs/pages/ColorsPage.tsx +226 -0
- package/docs/pages/ComponentPage.tsx +235 -0
- package/docs/pages/InstallationPage.tsx +232 -0
- package/docs/pages/IntroductionPage.tsx +163 -0
- package/docs/pages/ThemingPage.tsx +251 -0
- package/docs/pages/index.ts +10 -0
- package/docs/theme.ts +64 -0
- package/docs/types.ts +54 -0
- package/index.ts +8 -0
- package/llms.txt +1893 -0
- package/mcp-config.example.json +10 -0
- package/mcp-server/README.md +192 -0
- package/mcp-server/package-lock.json +1707 -0
- package/mcp-server/package.json +38 -0
- package/mcp-server/src/index.ts +1136 -0
- package/mcp-server/src/registry/components.ts +1446 -0
- package/mcp-server/src/registry/index.ts +3 -0
- package/mcp-server/src/registry/tokens.ts +256 -0
- package/mcp-server/tsconfig.json +19 -0
- package/package.json +92 -0
- package/src/components/Accordion/Accordion.stories.tsx +226 -0
- package/src/components/Accordion/Accordion.tsx +255 -0
- package/src/components/Accordion/index.ts +12 -0
- package/src/components/ActionSheet/ActionSheet.stories.tsx +393 -0
- package/src/components/ActionSheet/ActionSheet.tsx +258 -0
- package/src/components/ActionSheet/index.ts +2 -0
- package/src/components/Alert/Alert.stories.tsx +165 -0
- package/src/components/Alert/Alert.tsx +164 -0
- package/src/components/Alert/index.ts +2 -0
- package/src/components/AlertDialog/AlertDialog.stories.tsx +330 -0
- package/src/components/AlertDialog/AlertDialog.tsx +234 -0
- package/src/components/AlertDialog/index.ts +2 -0
- package/src/components/Avatar/Avatar.stories.tsx +154 -0
- package/src/components/Avatar/Avatar.tsx +219 -0
- package/src/components/Avatar/index.ts +2 -0
- package/src/components/Badge/Badge.stories.tsx +146 -0
- package/src/components/Badge/Badge.tsx +125 -0
- package/src/components/Badge/index.ts +2 -0
- package/src/components/Box/Box.stories.tsx +192 -0
- package/src/components/Box/Box.tsx +184 -0
- package/src/components/Box/index.ts +2 -0
- package/src/components/Button/Button.stories.tsx +157 -0
- package/src/components/Button/Button.tsx +180 -0
- package/src/components/Button/index.ts +2 -0
- package/src/components/Card/Card.stories.tsx +145 -0
- package/src/components/Card/Card.tsx +169 -0
- package/src/components/Card/index.ts +11 -0
- package/src/components/Center/Center.stories.tsx +215 -0
- package/src/components/Center/Center.tsx +29 -0
- package/src/components/Center/index.ts +2 -0
- package/src/components/Checkbox/Checkbox.stories.tsx +94 -0
- package/src/components/Checkbox/Checkbox.tsx +242 -0
- package/src/components/Checkbox/index.ts +2 -0
- package/src/components/DatePicker/DatePicker.stories.tsx +623 -0
- package/src/components/DatePicker/DatePicker.tsx +1228 -0
- package/src/components/DatePicker/index.ts +8 -0
- package/src/components/Divider/Divider.stories.tsx +224 -0
- package/src/components/Divider/Divider.tsx +73 -0
- package/src/components/Divider/index.ts +2 -0
- package/src/components/Drawer/Drawer.stories.tsx +414 -0
- package/src/components/Drawer/Drawer.tsx +342 -0
- package/src/components/Drawer/index.ts +11 -0
- package/src/components/Fab/Fab.stories.tsx +360 -0
- package/src/components/Fab/Fab.tsx +185 -0
- package/src/components/Fab/index.ts +2 -0
- package/src/components/FormControl/FormControl.stories.tsx +276 -0
- package/src/components/FormControl/FormControl.tsx +185 -0
- package/src/components/FormControl/index.ts +12 -0
- package/src/components/Grid/Grid.stories.tsx +244 -0
- package/src/components/Grid/Grid.tsx +93 -0
- package/src/components/Grid/index.ts +2 -0
- package/src/components/HStack/HStack.stories.tsx +230 -0
- package/src/components/HStack/HStack.tsx +80 -0
- package/src/components/HStack/index.ts +2 -0
- package/src/components/Heading/Heading.stories.tsx +111 -0
- package/src/components/Heading/Heading.tsx +85 -0
- package/src/components/Heading/index.ts +2 -0
- package/src/components/Icon/Icon.stories.tsx +320 -0
- package/src/components/Icon/Icon.tsx +117 -0
- package/src/components/Icon/index.ts +2 -0
- package/src/components/Image/Image.stories.tsx +357 -0
- package/src/components/Image/Image.tsx +168 -0
- package/src/components/Image/index.ts +2 -0
- package/src/components/Input/Input.stories.tsx +164 -0
- package/src/components/Input/Input.tsx +274 -0
- package/src/components/Input/index.ts +2 -0
- package/src/components/Link/Link.stories.tsx +187 -0
- package/src/components/Link/Link.tsx +104 -0
- package/src/components/Link/index.ts +2 -0
- package/src/components/Menu/Menu.stories.tsx +363 -0
- package/src/components/Menu/Menu.tsx +238 -0
- package/src/components/Menu/index.ts +2 -0
- package/src/components/Modal/Modal.stories.tsx +156 -0
- package/src/components/Modal/Modal.tsx +280 -0
- package/src/components/Modal/index.ts +11 -0
- package/src/components/Popover/Popover.stories.tsx +330 -0
- package/src/components/Popover/Popover.tsx +315 -0
- package/src/components/Popover/index.ts +11 -0
- package/src/components/Portal/Portal.stories.tsx +376 -0
- package/src/components/Portal/Portal.tsx +100 -0
- package/src/components/Portal/index.ts +2 -0
- package/src/components/Pressable/Pressable.stories.tsx +338 -0
- package/src/components/Pressable/Pressable.tsx +71 -0
- package/src/components/Pressable/index.ts +2 -0
- package/src/components/Progress/Progress.stories.tsx +131 -0
- package/src/components/Progress/Progress.tsx +219 -0
- package/src/components/Progress/index.ts +2 -0
- package/src/components/Radio/Radio.stories.tsx +101 -0
- package/src/components/Radio/Radio.tsx +234 -0
- package/src/components/Radio/index.ts +2 -0
- package/src/components/Select/Select.stories.tsx +908 -0
- package/src/components/Select/Select.tsx +659 -0
- package/src/components/Select/index.ts +8 -0
- package/src/components/Skeleton/Skeleton.stories.tsx +154 -0
- package/src/components/Skeleton/Skeleton.tsx +192 -0
- package/src/components/Skeleton/index.ts +8 -0
- package/src/components/Slider/Slider.stories.tsx +363 -0
- package/src/components/Slider/Slider.tsx +209 -0
- package/src/components/Slider/index.ts +2 -0
- package/src/components/Spinner/Spinner.stories.tsx +108 -0
- package/src/components/Spinner/Spinner.tsx +121 -0
- package/src/components/Spinner/index.ts +2 -0
- package/src/components/Switch/Switch.stories.tsx +116 -0
- package/src/components/Switch/Switch.tsx +172 -0
- package/src/components/Switch/index.ts +2 -0
- package/src/components/Table/Table.stories.tsx +417 -0
- package/src/components/Table/Table.tsx +233 -0
- package/src/components/Table/index.ts +2 -0
- package/src/components/Text/Text.stories.tsx +93 -0
- package/src/components/Text/Text.tsx +119 -0
- package/src/components/Text/index.ts +2 -0
- package/src/components/Textarea/Textarea.stories.tsx +280 -0
- package/src/components/Textarea/Textarea.tsx +212 -0
- package/src/components/Textarea/index.ts +2 -0
- package/src/components/Toast/Toast.stories.tsx +446 -0
- package/src/components/Toast/Toast.tsx +221 -0
- package/src/components/Toast/index.ts +2 -0
- package/src/components/Tooltip/Tooltip.stories.tsx +354 -0
- package/src/components/Tooltip/Tooltip.tsx +261 -0
- package/src/components/Tooltip/index.ts +2 -0
- package/src/components/VStack/VStack.stories.tsx +183 -0
- package/src/components/VStack/VStack.tsx +76 -0
- package/src/components/VStack/index.ts +2 -0
- package/src/components/index.ts +62 -0
- package/src/hooks/index.ts +7 -0
- package/src/hooks/useControllableState.ts +41 -0
- package/src/hooks/useDisclosure.ts +51 -0
- package/src/index.ts +22 -0
- package/src/stories/Button.stories.tsx +53 -0
- package/src/stories/Button.tsx +101 -0
- package/src/stories/Configure.mdx +364 -0
- package/src/stories/Header.stories.tsx +33 -0
- package/src/stories/Header.tsx +75 -0
- package/src/stories/Page.stories.tsx +25 -0
- package/src/stories/Page.tsx +154 -0
- package/src/stories/assets/accessibility.png +0 -0
- package/src/stories/assets/accessibility.svg +1 -0
- package/src/stories/assets/addon-library.png +0 -0
- package/src/stories/assets/assets.png +0 -0
- package/src/stories/assets/avif-test-image.avif +0 -0
- package/src/stories/assets/context.png +0 -0
- package/src/stories/assets/discord.svg +1 -0
- package/src/stories/assets/docs.png +0 -0
- package/src/stories/assets/figma-plugin.png +0 -0
- package/src/stories/assets/github.svg +1 -0
- package/src/stories/assets/share.png +0 -0
- package/src/stories/assets/styling.png +0 -0
- package/src/stories/assets/testing.png +0 -0
- package/src/stories/assets/theming.png +0 -0
- package/src/stories/assets/tutorials.svg +1 -0
- package/src/stories/assets/youtube.svg +1 -0
- package/src/styles/index.ts +7 -0
- package/src/styles/tokens.ts +318 -0
- package/src/styles/unistyles.ts +254 -0
- package/src/utils/createContext.tsx +25 -0
- package/src/utils/index.ts +7 -0
- package/src/utils/mergeRefs.ts +21 -0
- package/tsconfig.json +26 -0
- package/urbint-cl-1.0.0.tgz +0 -0
- package/vitest.config.ts +37 -0
- package/vitest.shims.d.ts +1 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { Pressable } from './Pressable';
|
|
3
|
+
import { VStack } from '../VStack';
|
|
4
|
+
import { HStack } from '../HStack';
|
|
5
|
+
import { Text } from '../Text';
|
|
6
|
+
import { Box } from '../Box';
|
|
7
|
+
import { colors, spacing, borderRadius, elevation } from '../../styles/tokens';
|
|
8
|
+
|
|
9
|
+
const meta: Meta<typeof Pressable> = {
|
|
10
|
+
title: 'Action/Pressable',
|
|
11
|
+
component: Pressable,
|
|
12
|
+
argTypes: {
|
|
13
|
+
pressedOpacity: { control: { type: 'range', min: 0, max: 1, step: 0.1 } },
|
|
14
|
+
pressedScale: { control: { type: 'range', min: 0.8, max: 1, step: 0.02 } },
|
|
15
|
+
},
|
|
16
|
+
args: {
|
|
17
|
+
pressedOpacity: 0.7,
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default meta;
|
|
22
|
+
|
|
23
|
+
type Story = StoryObj<typeof Pressable>;
|
|
24
|
+
|
|
25
|
+
export const Default: Story = {
|
|
26
|
+
render: (args) => (
|
|
27
|
+
<Pressable {...args} onPress={() => console.log('Pressed')}>
|
|
28
|
+
<Box p={spacing.lg} bg={colors.brand.blue} rounded="md">
|
|
29
|
+
<Text style={{ color: 'white' }}>Press Me</Text>
|
|
30
|
+
</Box>
|
|
31
|
+
</Pressable>
|
|
32
|
+
),
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const OpacityFeedback: Story = {
|
|
36
|
+
render: () => (
|
|
37
|
+
<VStack space={spacing.lg}>
|
|
38
|
+
<Text weight="semiBold">Opacity Feedback</Text>
|
|
39
|
+
<HStack space={spacing.lg}>
|
|
40
|
+
<VStack space={spacing.xs} alignItems="center">
|
|
41
|
+
<Pressable pressedOpacity={0.3} onPress={() => console.log('Pressed')}>
|
|
42
|
+
<Box p={spacing.lg} bg={colors.brand.blue} rounded="md">
|
|
43
|
+
<Text style={{ color: 'white' }}>0.3</Text>
|
|
44
|
+
</Box>
|
|
45
|
+
</Pressable>
|
|
46
|
+
<Text size="sm" color={colors.text.secondary}>opacity: 0.3</Text>
|
|
47
|
+
</VStack>
|
|
48
|
+
<VStack space={spacing.xs} alignItems="center">
|
|
49
|
+
<Pressable pressedOpacity={0.5} onPress={() => console.log('Pressed')}>
|
|
50
|
+
<Box p={spacing.lg} bg={colors.brand.blue} rounded="md">
|
|
51
|
+
<Text style={{ color: 'white' }}>0.5</Text>
|
|
52
|
+
</Box>
|
|
53
|
+
</Pressable>
|
|
54
|
+
<Text size="sm" color={colors.text.secondary}>opacity: 0.5</Text>
|
|
55
|
+
</VStack>
|
|
56
|
+
<VStack space={spacing.xs} alignItems="center">
|
|
57
|
+
<Pressable pressedOpacity={0.7} onPress={() => console.log('Pressed')}>
|
|
58
|
+
<Box p={spacing.lg} bg={colors.brand.blue} rounded="md">
|
|
59
|
+
<Text style={{ color: 'white' }}>0.7</Text>
|
|
60
|
+
</Box>
|
|
61
|
+
</Pressable>
|
|
62
|
+
<Text size="sm" color={colors.text.secondary}>opacity: 0.7</Text>
|
|
63
|
+
</VStack>
|
|
64
|
+
<VStack space={spacing.xs} alignItems="center">
|
|
65
|
+
<Pressable pressedOpacity={1} onPress={() => console.log('Pressed')}>
|
|
66
|
+
<Box p={spacing.lg} bg={colors.brand.blue} rounded="md">
|
|
67
|
+
<Text style={{ color: 'white' }}>1.0</Text>
|
|
68
|
+
</Box>
|
|
69
|
+
</Pressable>
|
|
70
|
+
<Text size="sm" color={colors.text.secondary}>opacity: 1.0</Text>
|
|
71
|
+
</VStack>
|
|
72
|
+
</HStack>
|
|
73
|
+
</VStack>
|
|
74
|
+
),
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export const ScaleFeedback: Story = {
|
|
78
|
+
render: () => (
|
|
79
|
+
<VStack space={spacing.lg}>
|
|
80
|
+
<Text weight="semiBold">Scale Feedback</Text>
|
|
81
|
+
<HStack space={spacing.lg}>
|
|
82
|
+
<VStack space={spacing.xs} alignItems="center">
|
|
83
|
+
<Pressable pressedScale={0.9} pressedOpacity={1} onPress={() => console.log('Pressed')}>
|
|
84
|
+
<Box p={spacing.lg} bg={colors.feedback.success.content} rounded="md">
|
|
85
|
+
<Text style={{ color: 'white' }}>0.9</Text>
|
|
86
|
+
</Box>
|
|
87
|
+
</Pressable>
|
|
88
|
+
<Text size="sm" color={colors.text.secondary}>scale: 0.9</Text>
|
|
89
|
+
</VStack>
|
|
90
|
+
<VStack space={spacing.xs} alignItems="center">
|
|
91
|
+
<Pressable pressedScale={0.95} pressedOpacity={1} onPress={() => console.log('Pressed')}>
|
|
92
|
+
<Box p={spacing.lg} bg={colors.feedback.success.content} rounded="md">
|
|
93
|
+
<Text style={{ color: 'white' }}>0.95</Text>
|
|
94
|
+
</Box>
|
|
95
|
+
</Pressable>
|
|
96
|
+
<Text size="sm" color={colors.text.secondary}>scale: 0.95</Text>
|
|
97
|
+
</VStack>
|
|
98
|
+
<VStack space={spacing.xs} alignItems="center">
|
|
99
|
+
<Pressable pressedScale={0.98} pressedOpacity={1} onPress={() => console.log('Pressed')}>
|
|
100
|
+
<Box p={spacing.lg} bg={colors.feedback.success.content} rounded="md">
|
|
101
|
+
<Text style={{ color: 'white' }}>0.98</Text>
|
|
102
|
+
</Box>
|
|
103
|
+
</Pressable>
|
|
104
|
+
<Text size="sm" color={colors.text.secondary}>scale: 0.98</Text>
|
|
105
|
+
</VStack>
|
|
106
|
+
</HStack>
|
|
107
|
+
</VStack>
|
|
108
|
+
),
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export const CombinedFeedback: Story = {
|
|
112
|
+
render: () => (
|
|
113
|
+
<VStack space={spacing.lg}>
|
|
114
|
+
<Text weight="semiBold">Combined Opacity + Scale</Text>
|
|
115
|
+
<Pressable
|
|
116
|
+
pressedOpacity={0.8}
|
|
117
|
+
pressedScale={0.95}
|
|
118
|
+
onPress={() => console.log('Pressed')}
|
|
119
|
+
>
|
|
120
|
+
<Box p={20} bg={colors.badge.purple} rounded="lg">
|
|
121
|
+
<Text style={{ color: 'white' }}>Press for combined effect</Text>
|
|
122
|
+
</Box>
|
|
123
|
+
</Pressable>
|
|
124
|
+
</VStack>
|
|
125
|
+
),
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export const CustomPressedStyle: Story = {
|
|
129
|
+
render: () => (
|
|
130
|
+
<VStack space={spacing.lg}>
|
|
131
|
+
<Text weight="semiBold">Custom Pressed Style</Text>
|
|
132
|
+
<Pressable
|
|
133
|
+
pressedOpacity={1}
|
|
134
|
+
pressedStyle={{ backgroundColor: colors.brand.blue }}
|
|
135
|
+
onPress={() => console.log('Pressed')}
|
|
136
|
+
>
|
|
137
|
+
<Box p={spacing.lg} bg={colors.brand.blue} rounded="md">
|
|
138
|
+
<Text style={{ color: 'white' }}>Background changes on press</Text>
|
|
139
|
+
</Box>
|
|
140
|
+
</Pressable>
|
|
141
|
+
</VStack>
|
|
142
|
+
),
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export const CardPressable: Story = {
|
|
146
|
+
render: () => (
|
|
147
|
+
<VStack space={spacing.lg}>
|
|
148
|
+
<Text weight="semiBold">Pressable Cards</Text>
|
|
149
|
+
<VStack space={spacing.md}>
|
|
150
|
+
<Pressable
|
|
151
|
+
pressedOpacity={0.9}
|
|
152
|
+
pressedScale={0.98}
|
|
153
|
+
onPress={() => console.log('Card 1 pressed')}
|
|
154
|
+
>
|
|
155
|
+
<Box p={spacing.lg} bg={colors.white} rounded="lg" shadow="10">
|
|
156
|
+
<VStack space={spacing.sm}>
|
|
157
|
+
<Text weight="semiBold">Clickable Card</Text>
|
|
158
|
+
<Text size="sm" color={colors.text.secondary}>
|
|
159
|
+
Press this card to navigate somewhere
|
|
160
|
+
</Text>
|
|
161
|
+
</VStack>
|
|
162
|
+
</Box>
|
|
163
|
+
</Pressable>
|
|
164
|
+
<Pressable
|
|
165
|
+
pressedOpacity={0.9}
|
|
166
|
+
pressedScale={0.98}
|
|
167
|
+
onPress={() => console.log('Card 2 pressed')}
|
|
168
|
+
>
|
|
169
|
+
<Box p={spacing.lg} bg={colors.white} rounded="lg" shadow="10">
|
|
170
|
+
<VStack space={spacing.sm}>
|
|
171
|
+
<Text weight="semiBold">Another Card</Text>
|
|
172
|
+
<Text size="sm" color={colors.text.secondary}>
|
|
173
|
+
This card also responds to press
|
|
174
|
+
</Text>
|
|
175
|
+
</VStack>
|
|
176
|
+
</Box>
|
|
177
|
+
</Pressable>
|
|
178
|
+
</VStack>
|
|
179
|
+
</VStack>
|
|
180
|
+
),
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
export const ListItems: Story = {
|
|
184
|
+
render: () => (
|
|
185
|
+
<VStack space={spacing.lg}>
|
|
186
|
+
<Text weight="semiBold">Pressable List Items</Text>
|
|
187
|
+
<Box bg={colors.white} rounded="lg" shadow="10" overflow="hidden">
|
|
188
|
+
{['Notifications', 'Privacy', 'Security', 'Help & Support'].map((item, index, arr) => (
|
|
189
|
+
<Pressable
|
|
190
|
+
key={item}
|
|
191
|
+
pressedOpacity={1}
|
|
192
|
+
pressedStyle={{ backgroundColor: colors.background.secondary }}
|
|
193
|
+
onPress={() => console.log(`${item} pressed`)}
|
|
194
|
+
>
|
|
195
|
+
<Box p={spacing.lg} borderBottomWidth={index < arr.length - 1 ? 1 : 0} borderColor={colors.border.default}>
|
|
196
|
+
<HStack justifyContent="space-between" alignItems="center">
|
|
197
|
+
<Text>{item}</Text>
|
|
198
|
+
<Text color={colors.text.disabled}>›</Text>
|
|
199
|
+
</HStack>
|
|
200
|
+
</Box>
|
|
201
|
+
</Pressable>
|
|
202
|
+
))}
|
|
203
|
+
</Box>
|
|
204
|
+
</VStack>
|
|
205
|
+
),
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
export const IconButtons: Story = {
|
|
209
|
+
render: () => (
|
|
210
|
+
<VStack space={spacing.lg}>
|
|
211
|
+
<Text weight="semiBold">Icon Button Style</Text>
|
|
212
|
+
<HStack space={spacing.sm}>
|
|
213
|
+
<Pressable
|
|
214
|
+
pressedOpacity={0.6}
|
|
215
|
+
pressedScale={0.9}
|
|
216
|
+
onPress={() => console.log('Like')}
|
|
217
|
+
>
|
|
218
|
+
<Box p={spacing.md} bg={colors.feedback.error.background} rounded="full">
|
|
219
|
+
<Text>❤️</Text>
|
|
220
|
+
</Box>
|
|
221
|
+
</Pressable>
|
|
222
|
+
<Pressable
|
|
223
|
+
pressedOpacity={0.6}
|
|
224
|
+
pressedScale={0.9}
|
|
225
|
+
onPress={() => console.log('Comment')}
|
|
226
|
+
>
|
|
227
|
+
<Box p={spacing.md} bg={colors.feedback.info.background} rounded="full">
|
|
228
|
+
<Text>💬</Text>
|
|
229
|
+
</Box>
|
|
230
|
+
</Pressable>
|
|
231
|
+
<Pressable
|
|
232
|
+
pressedOpacity={0.6}
|
|
233
|
+
pressedScale={0.9}
|
|
234
|
+
onPress={() => console.log('Share')}
|
|
235
|
+
>
|
|
236
|
+
<Box p={spacing.md} bg={colors.feedback.success.background} rounded="full">
|
|
237
|
+
<Text>🔗</Text>
|
|
238
|
+
</Box>
|
|
239
|
+
</Pressable>
|
|
240
|
+
<Pressable
|
|
241
|
+
pressedOpacity={0.6}
|
|
242
|
+
pressedScale={0.9}
|
|
243
|
+
onPress={() => console.log('Bookmark')}
|
|
244
|
+
>
|
|
245
|
+
<Box p={spacing.md} bg={colors.feedback.warning.background} rounded="full">
|
|
246
|
+
<Text>🔖</Text>
|
|
247
|
+
</Box>
|
|
248
|
+
</Pressable>
|
|
249
|
+
</HStack>
|
|
250
|
+
</VStack>
|
|
251
|
+
),
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
export const Tags: Story = {
|
|
255
|
+
render: () => (
|
|
256
|
+
<VStack space={spacing.lg}>
|
|
257
|
+
<Text weight="semiBold">Pressable Tags</Text>
|
|
258
|
+
<HStack space={spacing.sm} wrap>
|
|
259
|
+
{['React', 'TypeScript', 'JavaScript', 'Node.js', 'GraphQL'].map((tag) => (
|
|
260
|
+
<Pressable
|
|
261
|
+
key={tag}
|
|
262
|
+
pressedOpacity={0.7}
|
|
263
|
+
pressedScale={0.95}
|
|
264
|
+
onPress={() => console.log(`${tag} selected`)}
|
|
265
|
+
>
|
|
266
|
+
<Box px={spacing.md} py={6} bg={colors.brand.blue + '20'} rounded="full">
|
|
267
|
+
<Text size="sm" color={colors.brand.blue}>{tag}</Text>
|
|
268
|
+
</Box>
|
|
269
|
+
</Pressable>
|
|
270
|
+
))}
|
|
271
|
+
</HStack>
|
|
272
|
+
</VStack>
|
|
273
|
+
),
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
export const AvatarPressable: Story = {
|
|
277
|
+
render: () => (
|
|
278
|
+
<VStack space={spacing.lg}>
|
|
279
|
+
<Text weight="semiBold">Pressable Avatars</Text>
|
|
280
|
+
<HStack space={-8}>
|
|
281
|
+
{['A', 'B', 'C', 'D', '+2'].map((letter, i) => (
|
|
282
|
+
<Pressable
|
|
283
|
+
key={i}
|
|
284
|
+
pressedScale={1.1}
|
|
285
|
+
pressedOpacity={1}
|
|
286
|
+
onPress={() => console.log(`Avatar ${letter} pressed`)}
|
|
287
|
+
>
|
|
288
|
+
<Box
|
|
289
|
+
w={40}
|
|
290
|
+
h={40}
|
|
291
|
+
rounded="full"
|
|
292
|
+
bg={letter === '+2' ? colors.border.default : colors.brand.blue + '30'}
|
|
293
|
+
alignItems="center"
|
|
294
|
+
justifyContent="center"
|
|
295
|
+
borderWidth={2}
|
|
296
|
+
borderColor="white"
|
|
297
|
+
>
|
|
298
|
+
<Text weight="semiBold" size="sm">{letter}</Text>
|
|
299
|
+
</Box>
|
|
300
|
+
</Pressable>
|
|
301
|
+
))}
|
|
302
|
+
</HStack>
|
|
303
|
+
</VStack>
|
|
304
|
+
),
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
export const MediaCard: Story = {
|
|
308
|
+
render: () => (
|
|
309
|
+
<VStack space={spacing.lg}>
|
|
310
|
+
<Text weight="semiBold">Media Card</Text>
|
|
311
|
+
<Pressable
|
|
312
|
+
pressedOpacity={0.95}
|
|
313
|
+
pressedScale={0.98}
|
|
314
|
+
onPress={() => console.log('Play video')}
|
|
315
|
+
>
|
|
316
|
+
<Box w={300} bg="#1e293b" rounded="lg" overflow="hidden">
|
|
317
|
+
<Box h={170} bg="#0f172a" alignItems="center" justifyContent="center">
|
|
318
|
+
<Box
|
|
319
|
+
w={50}
|
|
320
|
+
h={50}
|
|
321
|
+
rounded="full"
|
|
322
|
+
bg="rgba(255,255,255,0.9)"
|
|
323
|
+
alignItems="center"
|
|
324
|
+
justifyContent="center"
|
|
325
|
+
>
|
|
326
|
+
<Text size="lg">▶</Text>
|
|
327
|
+
</Box>
|
|
328
|
+
</Box>
|
|
329
|
+
<Box p={12}>
|
|
330
|
+
<Text style={{ color: 'white' }} weight="semiBold">Video Title</Text>
|
|
331
|
+
<Text size="sm" style={{ color: '#94a3b8' }}>12.5K views • 2 days ago</Text>
|
|
332
|
+
</Box>
|
|
333
|
+
</Box>
|
|
334
|
+
</Pressable>
|
|
335
|
+
</VStack>
|
|
336
|
+
),
|
|
337
|
+
};
|
|
338
|
+
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pressable Component
|
|
3
|
+
* Enhanced pressable with feedback states
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React, { forwardRef, useState } from 'react';
|
|
7
|
+
import {
|
|
8
|
+
Pressable as RNPressable,
|
|
9
|
+
PressableProps as RNPressableProps,
|
|
10
|
+
View,
|
|
11
|
+
ViewStyle,
|
|
12
|
+
StyleSheet,
|
|
13
|
+
} from 'react-native';
|
|
14
|
+
|
|
15
|
+
export interface PressableProps extends Omit<RNPressableProps, 'style'> {
|
|
16
|
+
/** Style */
|
|
17
|
+
style?: ViewStyle;
|
|
18
|
+
/** Opacity when pressed */
|
|
19
|
+
pressedOpacity?: number;
|
|
20
|
+
/** Scale when pressed */
|
|
21
|
+
pressedScale?: number;
|
|
22
|
+
/** Custom pressed style */
|
|
23
|
+
pressedStyle?: ViewStyle;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const Pressable = forwardRef<View, PressableProps>(
|
|
27
|
+
(
|
|
28
|
+
{
|
|
29
|
+
style,
|
|
30
|
+
pressedOpacity = 0.7,
|
|
31
|
+
pressedScale,
|
|
32
|
+
pressedStyle,
|
|
33
|
+
onPressIn,
|
|
34
|
+
onPressOut,
|
|
35
|
+
children,
|
|
36
|
+
...props
|
|
37
|
+
},
|
|
38
|
+
ref
|
|
39
|
+
) => {
|
|
40
|
+
const [isPressed, setIsPressed] = useState(false);
|
|
41
|
+
|
|
42
|
+
const handlePressIn = (e: any) => {
|
|
43
|
+
setIsPressed(true);
|
|
44
|
+
onPressIn?.(e);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const handlePressOut = (e: any) => {
|
|
48
|
+
setIsPressed(false);
|
|
49
|
+
onPressOut?.(e);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<RNPressable
|
|
54
|
+
ref={ref}
|
|
55
|
+
onPressIn={handlePressIn}
|
|
56
|
+
onPressOut={handlePressOut}
|
|
57
|
+
style={[
|
|
58
|
+
style,
|
|
59
|
+
isPressed && { opacity: pressedOpacity },
|
|
60
|
+
isPressed && pressedScale && { transform: [{ scale: pressedScale }] },
|
|
61
|
+
isPressed && pressedStyle,
|
|
62
|
+
]}
|
|
63
|
+
{...props}
|
|
64
|
+
>
|
|
65
|
+
{children}
|
|
66
|
+
</RNPressable>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
Pressable.displayName = 'Pressable';
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { View, StyleSheet } from 'react-native';
|
|
3
|
+
import { Progress } from './Progress';
|
|
4
|
+
import { VStack } from '../VStack';
|
|
5
|
+
import { HStack } from '../HStack';
|
|
6
|
+
import { Text } from '../Text';
|
|
7
|
+
import { colors, spacing, borderRadius } from '../../styles/tokens';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Story container with design system tokens
|
|
11
|
+
*/
|
|
12
|
+
const StoryContainer: React.FC<{ children: React.ReactNode }> = ({ children }) => (
|
|
13
|
+
<View style={styles.container}>{children}</View>
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const meta: Meta<typeof Progress> = {
|
|
17
|
+
title: 'Components/Progress',
|
|
18
|
+
component: Progress,
|
|
19
|
+
decorators: [
|
|
20
|
+
(Story) => (
|
|
21
|
+
<StoryContainer>
|
|
22
|
+
<Story />
|
|
23
|
+
</StoryContainer>
|
|
24
|
+
),
|
|
25
|
+
],
|
|
26
|
+
args: {
|
|
27
|
+
value: 65,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default meta;
|
|
32
|
+
|
|
33
|
+
type Story = StoryObj<typeof Progress>;
|
|
34
|
+
|
|
35
|
+
export const Default: Story = {};
|
|
36
|
+
|
|
37
|
+
export const Sizes: Story = {
|
|
38
|
+
render: () => (
|
|
39
|
+
<VStack space={spacing.lg}>
|
|
40
|
+
<Text weight="semiBold">Progress Sizes</Text>
|
|
41
|
+
<Progress value={50} size="sm" />
|
|
42
|
+
<Progress value={50} size="md" />
|
|
43
|
+
<Progress value={50} size="lg" />
|
|
44
|
+
</VStack>
|
|
45
|
+
),
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const ColorSchemes: Story = {
|
|
49
|
+
render: () => (
|
|
50
|
+
<VStack space={spacing.lg}>
|
|
51
|
+
<Text weight="semiBold">Color Schemes</Text>
|
|
52
|
+
<Progress value={75} colorScheme="primary" />
|
|
53
|
+
<Progress value={75} colorScheme="success" />
|
|
54
|
+
<Progress value={75} colorScheme="warning" />
|
|
55
|
+
<Progress value={75} colorScheme="danger" />
|
|
56
|
+
</VStack>
|
|
57
|
+
),
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const WithLabel: Story = {
|
|
61
|
+
render: () => (
|
|
62
|
+
<VStack space={spacing.lg}>
|
|
63
|
+
<Text weight="semiBold">With Label</Text>
|
|
64
|
+
<Progress value={45} showLabel />
|
|
65
|
+
<Progress value={80} showLabel size="lg" labelPosition="inside" />
|
|
66
|
+
</VStack>
|
|
67
|
+
),
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const Indeterminate: Story = {
|
|
71
|
+
render: () => (
|
|
72
|
+
<VStack space={spacing.lg}>
|
|
73
|
+
<Text weight="semiBold">Indeterminate Progress</Text>
|
|
74
|
+
<Progress isIndeterminate />
|
|
75
|
+
</VStack>
|
|
76
|
+
),
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export const Circular: Story = {
|
|
80
|
+
render: () => (
|
|
81
|
+
<VStack space={spacing.lg}>
|
|
82
|
+
<Text weight="semiBold">Circular Progress</Text>
|
|
83
|
+
<HStack space={spacing.lg}>
|
|
84
|
+
<Progress variant="circular" value={25} size="sm" showLabel />
|
|
85
|
+
<Progress variant="circular" value={50} size="md" showLabel />
|
|
86
|
+
<Progress variant="circular" value={75} size="lg" showLabel />
|
|
87
|
+
</HStack>
|
|
88
|
+
</VStack>
|
|
89
|
+
),
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export const UsageExample: Story = {
|
|
93
|
+
render: () => (
|
|
94
|
+
<VStack space={spacing.lg}>
|
|
95
|
+
<Text weight="semiBold">File Upload Progress</Text>
|
|
96
|
+
<VStack space={spacing.xs}>
|
|
97
|
+
<HStack justifyContent="space-between">
|
|
98
|
+
<Text variant="caption">document.pdf</Text>
|
|
99
|
+
<Text variant="caption" color={colors.feedback.success.content}>Complete</Text>
|
|
100
|
+
</HStack>
|
|
101
|
+
<Progress value={100} colorScheme="success" size="sm" />
|
|
102
|
+
</VStack>
|
|
103
|
+
<VStack space={spacing.xs}>
|
|
104
|
+
<HStack justifyContent="space-between">
|
|
105
|
+
<Text variant="caption">image.png</Text>
|
|
106
|
+
<Text variant="caption">65%</Text>
|
|
107
|
+
</HStack>
|
|
108
|
+
<Progress value={65} size="sm" />
|
|
109
|
+
</VStack>
|
|
110
|
+
<VStack space={spacing.xs}>
|
|
111
|
+
<HStack justifyContent="space-between">
|
|
112
|
+
<Text variant="caption">video.mp4</Text>
|
|
113
|
+
<Text variant="caption">Starting...</Text>
|
|
114
|
+
</HStack>
|
|
115
|
+
<Progress isIndeterminate size="sm" />
|
|
116
|
+
</VStack>
|
|
117
|
+
</VStack>
|
|
118
|
+
),
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Styles using design system tokens
|
|
123
|
+
*/
|
|
124
|
+
const styles = StyleSheet.create({
|
|
125
|
+
container: {
|
|
126
|
+
padding: spacing.lg,
|
|
127
|
+
backgroundColor: colors.background.default,
|
|
128
|
+
borderRadius: borderRadius.lg,
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
|