@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.
Files changed (206) hide show
  1. package/.cursor/rules +313 -0
  2. package/.rnstorybook/index.ts +11 -0
  3. package/.rnstorybook/main.ts +8 -0
  4. package/.rnstorybook/preview.tsx +14 -0
  5. package/.rnstorybook/storybook.requires.ts +49 -0
  6. package/.storybook/main.ts +16 -0
  7. package/.storybook/preview.ts +32 -0
  8. package/.storybook/vitest.setup.ts +7 -0
  9. package/App.tsx +422 -0
  10. package/README.md +229 -0
  11. package/app.json +33 -0
  12. package/assets/adaptive-icon.png +0 -0
  13. package/assets/favicon.png +0 -0
  14. package/assets/icon.png +0 -0
  15. package/assets/splash-icon.png +0 -0
  16. package/babel.config.js +16 -0
  17. package/docs/components/CodeBlock.tsx +80 -0
  18. package/docs/components/PropTable.tsx +93 -0
  19. package/docs/components/Sidebar.tsx +199 -0
  20. package/docs/components/index.ts +8 -0
  21. package/docs/data/colorTokens.ts +70 -0
  22. package/docs/data/componentData.tsx +1685 -0
  23. package/docs/data/index.ts +7 -0
  24. package/docs/index.ts +19 -0
  25. package/docs/navigation.ts +94 -0
  26. package/docs/pages/ColorsPage.tsx +226 -0
  27. package/docs/pages/ComponentPage.tsx +235 -0
  28. package/docs/pages/InstallationPage.tsx +232 -0
  29. package/docs/pages/IntroductionPage.tsx +163 -0
  30. package/docs/pages/ThemingPage.tsx +251 -0
  31. package/docs/pages/index.ts +10 -0
  32. package/docs/theme.ts +64 -0
  33. package/docs/types.ts +54 -0
  34. package/index.ts +8 -0
  35. package/llms.txt +1893 -0
  36. package/mcp-config.example.json +10 -0
  37. package/mcp-server/README.md +192 -0
  38. package/mcp-server/package-lock.json +1707 -0
  39. package/mcp-server/package.json +38 -0
  40. package/mcp-server/src/index.ts +1136 -0
  41. package/mcp-server/src/registry/components.ts +1446 -0
  42. package/mcp-server/src/registry/index.ts +3 -0
  43. package/mcp-server/src/registry/tokens.ts +256 -0
  44. package/mcp-server/tsconfig.json +19 -0
  45. package/package.json +92 -0
  46. package/src/components/Accordion/Accordion.stories.tsx +226 -0
  47. package/src/components/Accordion/Accordion.tsx +255 -0
  48. package/src/components/Accordion/index.ts +12 -0
  49. package/src/components/ActionSheet/ActionSheet.stories.tsx +393 -0
  50. package/src/components/ActionSheet/ActionSheet.tsx +258 -0
  51. package/src/components/ActionSheet/index.ts +2 -0
  52. package/src/components/Alert/Alert.stories.tsx +165 -0
  53. package/src/components/Alert/Alert.tsx +164 -0
  54. package/src/components/Alert/index.ts +2 -0
  55. package/src/components/AlertDialog/AlertDialog.stories.tsx +330 -0
  56. package/src/components/AlertDialog/AlertDialog.tsx +234 -0
  57. package/src/components/AlertDialog/index.ts +2 -0
  58. package/src/components/Avatar/Avatar.stories.tsx +154 -0
  59. package/src/components/Avatar/Avatar.tsx +219 -0
  60. package/src/components/Avatar/index.ts +2 -0
  61. package/src/components/Badge/Badge.stories.tsx +146 -0
  62. package/src/components/Badge/Badge.tsx +125 -0
  63. package/src/components/Badge/index.ts +2 -0
  64. package/src/components/Box/Box.stories.tsx +192 -0
  65. package/src/components/Box/Box.tsx +184 -0
  66. package/src/components/Box/index.ts +2 -0
  67. package/src/components/Button/Button.stories.tsx +157 -0
  68. package/src/components/Button/Button.tsx +180 -0
  69. package/src/components/Button/index.ts +2 -0
  70. package/src/components/Card/Card.stories.tsx +145 -0
  71. package/src/components/Card/Card.tsx +169 -0
  72. package/src/components/Card/index.ts +11 -0
  73. package/src/components/Center/Center.stories.tsx +215 -0
  74. package/src/components/Center/Center.tsx +29 -0
  75. package/src/components/Center/index.ts +2 -0
  76. package/src/components/Checkbox/Checkbox.stories.tsx +94 -0
  77. package/src/components/Checkbox/Checkbox.tsx +242 -0
  78. package/src/components/Checkbox/index.ts +2 -0
  79. package/src/components/DatePicker/DatePicker.stories.tsx +623 -0
  80. package/src/components/DatePicker/DatePicker.tsx +1228 -0
  81. package/src/components/DatePicker/index.ts +8 -0
  82. package/src/components/Divider/Divider.stories.tsx +224 -0
  83. package/src/components/Divider/Divider.tsx +73 -0
  84. package/src/components/Divider/index.ts +2 -0
  85. package/src/components/Drawer/Drawer.stories.tsx +414 -0
  86. package/src/components/Drawer/Drawer.tsx +342 -0
  87. package/src/components/Drawer/index.ts +11 -0
  88. package/src/components/Fab/Fab.stories.tsx +360 -0
  89. package/src/components/Fab/Fab.tsx +185 -0
  90. package/src/components/Fab/index.ts +2 -0
  91. package/src/components/FormControl/FormControl.stories.tsx +276 -0
  92. package/src/components/FormControl/FormControl.tsx +185 -0
  93. package/src/components/FormControl/index.ts +12 -0
  94. package/src/components/Grid/Grid.stories.tsx +244 -0
  95. package/src/components/Grid/Grid.tsx +93 -0
  96. package/src/components/Grid/index.ts +2 -0
  97. package/src/components/HStack/HStack.stories.tsx +230 -0
  98. package/src/components/HStack/HStack.tsx +80 -0
  99. package/src/components/HStack/index.ts +2 -0
  100. package/src/components/Heading/Heading.stories.tsx +111 -0
  101. package/src/components/Heading/Heading.tsx +85 -0
  102. package/src/components/Heading/index.ts +2 -0
  103. package/src/components/Icon/Icon.stories.tsx +320 -0
  104. package/src/components/Icon/Icon.tsx +117 -0
  105. package/src/components/Icon/index.ts +2 -0
  106. package/src/components/Image/Image.stories.tsx +357 -0
  107. package/src/components/Image/Image.tsx +168 -0
  108. package/src/components/Image/index.ts +2 -0
  109. package/src/components/Input/Input.stories.tsx +164 -0
  110. package/src/components/Input/Input.tsx +274 -0
  111. package/src/components/Input/index.ts +2 -0
  112. package/src/components/Link/Link.stories.tsx +187 -0
  113. package/src/components/Link/Link.tsx +104 -0
  114. package/src/components/Link/index.ts +2 -0
  115. package/src/components/Menu/Menu.stories.tsx +363 -0
  116. package/src/components/Menu/Menu.tsx +238 -0
  117. package/src/components/Menu/index.ts +2 -0
  118. package/src/components/Modal/Modal.stories.tsx +156 -0
  119. package/src/components/Modal/Modal.tsx +280 -0
  120. package/src/components/Modal/index.ts +11 -0
  121. package/src/components/Popover/Popover.stories.tsx +330 -0
  122. package/src/components/Popover/Popover.tsx +315 -0
  123. package/src/components/Popover/index.ts +11 -0
  124. package/src/components/Portal/Portal.stories.tsx +376 -0
  125. package/src/components/Portal/Portal.tsx +100 -0
  126. package/src/components/Portal/index.ts +2 -0
  127. package/src/components/Pressable/Pressable.stories.tsx +338 -0
  128. package/src/components/Pressable/Pressable.tsx +71 -0
  129. package/src/components/Pressable/index.ts +2 -0
  130. package/src/components/Progress/Progress.stories.tsx +131 -0
  131. package/src/components/Progress/Progress.tsx +219 -0
  132. package/src/components/Progress/index.ts +2 -0
  133. package/src/components/Radio/Radio.stories.tsx +101 -0
  134. package/src/components/Radio/Radio.tsx +234 -0
  135. package/src/components/Radio/index.ts +2 -0
  136. package/src/components/Select/Select.stories.tsx +908 -0
  137. package/src/components/Select/Select.tsx +659 -0
  138. package/src/components/Select/index.ts +8 -0
  139. package/src/components/Skeleton/Skeleton.stories.tsx +154 -0
  140. package/src/components/Skeleton/Skeleton.tsx +192 -0
  141. package/src/components/Skeleton/index.ts +8 -0
  142. package/src/components/Slider/Slider.stories.tsx +363 -0
  143. package/src/components/Slider/Slider.tsx +209 -0
  144. package/src/components/Slider/index.ts +2 -0
  145. package/src/components/Spinner/Spinner.stories.tsx +108 -0
  146. package/src/components/Spinner/Spinner.tsx +121 -0
  147. package/src/components/Spinner/index.ts +2 -0
  148. package/src/components/Switch/Switch.stories.tsx +116 -0
  149. package/src/components/Switch/Switch.tsx +172 -0
  150. package/src/components/Switch/index.ts +2 -0
  151. package/src/components/Table/Table.stories.tsx +417 -0
  152. package/src/components/Table/Table.tsx +233 -0
  153. package/src/components/Table/index.ts +2 -0
  154. package/src/components/Text/Text.stories.tsx +93 -0
  155. package/src/components/Text/Text.tsx +119 -0
  156. package/src/components/Text/index.ts +2 -0
  157. package/src/components/Textarea/Textarea.stories.tsx +280 -0
  158. package/src/components/Textarea/Textarea.tsx +212 -0
  159. package/src/components/Textarea/index.ts +2 -0
  160. package/src/components/Toast/Toast.stories.tsx +446 -0
  161. package/src/components/Toast/Toast.tsx +221 -0
  162. package/src/components/Toast/index.ts +2 -0
  163. package/src/components/Tooltip/Tooltip.stories.tsx +354 -0
  164. package/src/components/Tooltip/Tooltip.tsx +261 -0
  165. package/src/components/Tooltip/index.ts +2 -0
  166. package/src/components/VStack/VStack.stories.tsx +183 -0
  167. package/src/components/VStack/VStack.tsx +76 -0
  168. package/src/components/VStack/index.ts +2 -0
  169. package/src/components/index.ts +62 -0
  170. package/src/hooks/index.ts +7 -0
  171. package/src/hooks/useControllableState.ts +41 -0
  172. package/src/hooks/useDisclosure.ts +51 -0
  173. package/src/index.ts +22 -0
  174. package/src/stories/Button.stories.tsx +53 -0
  175. package/src/stories/Button.tsx +101 -0
  176. package/src/stories/Configure.mdx +364 -0
  177. package/src/stories/Header.stories.tsx +33 -0
  178. package/src/stories/Header.tsx +75 -0
  179. package/src/stories/Page.stories.tsx +25 -0
  180. package/src/stories/Page.tsx +154 -0
  181. package/src/stories/assets/accessibility.png +0 -0
  182. package/src/stories/assets/accessibility.svg +1 -0
  183. package/src/stories/assets/addon-library.png +0 -0
  184. package/src/stories/assets/assets.png +0 -0
  185. package/src/stories/assets/avif-test-image.avif +0 -0
  186. package/src/stories/assets/context.png +0 -0
  187. package/src/stories/assets/discord.svg +1 -0
  188. package/src/stories/assets/docs.png +0 -0
  189. package/src/stories/assets/figma-plugin.png +0 -0
  190. package/src/stories/assets/github.svg +1 -0
  191. package/src/stories/assets/share.png +0 -0
  192. package/src/stories/assets/styling.png +0 -0
  193. package/src/stories/assets/testing.png +0 -0
  194. package/src/stories/assets/theming.png +0 -0
  195. package/src/stories/assets/tutorials.svg +1 -0
  196. package/src/stories/assets/youtube.svg +1 -0
  197. package/src/styles/index.ts +7 -0
  198. package/src/styles/tokens.ts +318 -0
  199. package/src/styles/unistyles.ts +254 -0
  200. package/src/utils/createContext.tsx +25 -0
  201. package/src/utils/index.ts +7 -0
  202. package/src/utils/mergeRefs.ts +21 -0
  203. package/tsconfig.json +26 -0
  204. package/urbint-cl-1.0.0.tgz +0 -0
  205. package/vitest.config.ts +37 -0
  206. package/vitest.shims.d.ts +1 -0
@@ -0,0 +1,154 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import React from 'react';
3
+ import { View, StyleSheet } from 'react-native';
4
+ import { Skeleton, SkeletonText, SkeletonCircle } from './Skeleton';
5
+ import { VStack } from '../VStack';
6
+ import { HStack } from '../HStack';
7
+ import { Text } from '../Text';
8
+ import { colors, spacing, borderRadius } from '../../styles/tokens';
9
+
10
+ /**
11
+ * Story container with design system tokens
12
+ */
13
+ const StoryContainer: React.FC<{ children: React.ReactNode }> = ({ children }) => (
14
+ <View style={styles.container}>{children}</View>
15
+ );
16
+
17
+ const meta: Meta<typeof Skeleton> = {
18
+ title: 'Components/Skeleton',
19
+ component: Skeleton,
20
+ decorators: [
21
+ (Story) => (
22
+ <StoryContainer>
23
+ <Story />
24
+ </StoryContainer>
25
+ ),
26
+ ],
27
+ args: {
28
+ width: '100%',
29
+ height: 20,
30
+ },
31
+ };
32
+
33
+ export default meta;
34
+
35
+ type Story = StoryObj<typeof Skeleton>;
36
+
37
+ export const Default: Story = {};
38
+
39
+ export const Variants: Story = {
40
+ render: () => (
41
+ <VStack space={spacing.lg}>
42
+ <Text weight="semiBold">Skeleton Variants</Text>
43
+ <Skeleton variant="text" height={16} width="80%" />
44
+ <Skeleton variant="rectangular" height={100} />
45
+ <Skeleton variant="rounded" height={100} />
46
+ <HStack space={spacing.sm}>
47
+ <Skeleton variant="circular" width={48} height={48} />
48
+ <Skeleton variant="circular" width={48} height={48} />
49
+ <Skeleton variant="circular" width={48} height={48} />
50
+ </HStack>
51
+ </VStack>
52
+ ),
53
+ };
54
+
55
+ export const TextSkeleton: Story = {
56
+ render: () => (
57
+ <VStack space={spacing.lg}>
58
+ <Text weight="semiBold">Text Skeleton</Text>
59
+ <SkeletonText noOfLines={3} spacing={spacing.sm} />
60
+ <SkeletonText noOfLines={5} spacing={6} />
61
+ </VStack>
62
+ ),
63
+ };
64
+
65
+ export const CardSkeleton: Story = {
66
+ render: () => (
67
+ <VStack space={spacing.md} style={styles.cardSkeleton}>
68
+ <HStack space={spacing.md}>
69
+ <SkeletonCircle size={48} />
70
+ <VStack space={spacing.sm} style={{ flex: 1 }}>
71
+ <Skeleton variant="text" height={16} width="60%" />
72
+ <Skeleton variant="text" height={14} width="40%" />
73
+ </VStack>
74
+ </HStack>
75
+ <Skeleton variant="rectangular" height={120} />
76
+ <SkeletonText noOfLines={2} />
77
+ <HStack space={spacing.sm} justifyContent="flex-end">
78
+ <Skeleton variant="rounded" height={32} width={80} />
79
+ <Skeleton variant="rounded" height={32} width={80} />
80
+ </HStack>
81
+ </VStack>
82
+ ),
83
+ };
84
+
85
+ export const ListSkeleton: Story = {
86
+ render: () => (
87
+ <VStack space={spacing.md}>
88
+ <Text weight="semiBold">List Loading State</Text>
89
+ {[1, 2, 3, 4].map((item) => (
90
+ <HStack key={item} space={spacing.md} style={styles.listItem}>
91
+ <SkeletonCircle size={40} />
92
+ <VStack space={6} style={{ flex: 1 }}>
93
+ <Skeleton variant="text" height={14} width="70%" />
94
+ <Skeleton variant="text" height={12} width="50%" />
95
+ </VStack>
96
+ <Skeleton variant="rounded" height={24} width={60} />
97
+ </HStack>
98
+ ))}
99
+ </VStack>
100
+ ),
101
+ };
102
+
103
+ export const WithContent: Story = {
104
+ render: () => {
105
+ const [isLoaded, setIsLoaded] = React.useState(false);
106
+
107
+ React.useEffect(() => {
108
+ const timer = setTimeout(() => setIsLoaded(true), 3000);
109
+ return () => clearTimeout(timer);
110
+ }, []);
111
+
112
+ return (
113
+ <VStack space={spacing.md}>
114
+ <Text weight="semiBold">Loaded State (wait 3s)</Text>
115
+ <HStack space={spacing.md}>
116
+ <SkeletonCircle size={48} isLoaded={isLoaded}>
117
+ <Text>JD</Text>
118
+ </SkeletonCircle>
119
+ <VStack space={spacing.xs} style={{ flex: 1 }}>
120
+ <Skeleton variant="text" height={16} isLoaded={isLoaded}>
121
+ <Text weight="semiBold">John Doe</Text>
122
+ </Skeleton>
123
+ <Skeleton variant="text" height={14} width="60%" isLoaded={isLoaded}>
124
+ <Text variant="caption" color={colors.text.secondary}>Software Engineer</Text>
125
+ </Skeleton>
126
+ </VStack>
127
+ </HStack>
128
+ </VStack>
129
+ );
130
+ },
131
+ };
132
+
133
+ /**
134
+ * Styles using design system tokens
135
+ */
136
+ const styles = StyleSheet.create({
137
+ container: {
138
+ padding: spacing.lg,
139
+ backgroundColor: colors.background.default,
140
+ borderRadius: borderRadius.lg,
141
+ },
142
+ cardSkeleton: {
143
+ padding: spacing.lg,
144
+ borderRadius: borderRadius.lg,
145
+ borderWidth: 1,
146
+ borderColor: colors.border.disabled,
147
+ },
148
+ listItem: {
149
+ padding: spacing.md,
150
+ borderBottomWidth: 1,
151
+ borderBottomColor: colors.border.disabled,
152
+ },
153
+ });
154
+
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Skeleton Component
3
+ * Loading placeholder with shimmer effect
4
+ */
5
+
6
+ import React, { forwardRef, useEffect, useRef } from 'react';
7
+ import { View, ViewProps, Animated, Dimensions, StyleSheet } from 'react-native';
8
+ import { colors, borderRadius } from '../../styles/tokens';
9
+
10
+ export interface SkeletonProps extends ViewProps {
11
+ /** Is loading */
12
+ isLoaded?: boolean;
13
+ /** Width */
14
+ width?: number | string;
15
+ /** Height */
16
+ height?: number | string;
17
+ /** Border radius */
18
+ borderRadius?: number;
19
+ /** Variant */
20
+ variant?: 'text' | 'circular' | 'rectangular' | 'rounded';
21
+ /** Start color */
22
+ startColor?: string;
23
+ /** End color */
24
+ endColor?: string;
25
+ /** Animation speed */
26
+ speed?: number;
27
+ }
28
+
29
+ export const Skeleton = forwardRef<View, SkeletonProps>(
30
+ (
31
+ {
32
+ style,
33
+ isLoaded = false,
34
+ width = '100%',
35
+ height = 20,
36
+ borderRadius: customBorderRadius,
37
+ variant = 'rectangular',
38
+ startColor,
39
+ endColor,
40
+ speed = 800,
41
+ children,
42
+ ...props
43
+ },
44
+ ref
45
+ ) => {
46
+ const shimmerAnim = useRef(new Animated.Value(0)).current;
47
+ const screenWidth = Dimensions.get('window').width;
48
+
49
+ const bgStartColor = startColor || colors.background.secondary;
50
+ const bgEndColor = endColor || colors.background.tertiary;
51
+
52
+ useEffect(() => {
53
+ if (!isLoaded) {
54
+ Animated.loop(
55
+ Animated.timing(shimmerAnim, {
56
+ toValue: 1,
57
+ duration: speed,
58
+ useNativeDriver: true,
59
+ })
60
+ ).start();
61
+ }
62
+ }, [isLoaded, speed]);
63
+
64
+ if (isLoaded) {
65
+ return <>{children}</>;
66
+ }
67
+
68
+ const getVariantStyle = () => {
69
+ switch (variant) {
70
+ case 'text':
71
+ return { borderRadius: borderRadius.sm };
72
+ case 'circular':
73
+ return { borderRadius: 9999 };
74
+ case 'rounded':
75
+ return { borderRadius: borderRadius.lg };
76
+ default:
77
+ return { borderRadius: customBorderRadius || borderRadius.md };
78
+ }
79
+ };
80
+
81
+ const translateX = shimmerAnim.interpolate({
82
+ inputRange: [0, 1],
83
+ outputRange: [-screenWidth, screenWidth],
84
+ });
85
+
86
+ return (
87
+ <View
88
+ ref={ref}
89
+ style={[
90
+ styles.skeleton,
91
+ { width, height, backgroundColor: bgStartColor },
92
+ getVariantStyle(),
93
+ style,
94
+ ]}
95
+ {...props}
96
+ >
97
+ <Animated.View
98
+ style={[
99
+ styles.shimmer,
100
+ {
101
+ backgroundColor: bgEndColor,
102
+ transform: [{ translateX }],
103
+ },
104
+ ]}
105
+ />
106
+ </View>
107
+ );
108
+ }
109
+ );
110
+
111
+ Skeleton.displayName = 'Skeleton';
112
+
113
+ export interface SkeletonTextProps extends ViewProps {
114
+ /** Number of lines */
115
+ noOfLines?: number;
116
+ /** Line spacing */
117
+ spacing?: number;
118
+ /** Start color */
119
+ startColor?: string;
120
+ /** End color */
121
+ endColor?: string;
122
+ /** Is loaded */
123
+ isLoaded?: boolean;
124
+ }
125
+
126
+ export const SkeletonText = forwardRef<View, SkeletonTextProps>(
127
+ (
128
+ {
129
+ style,
130
+ noOfLines = 3,
131
+ spacing = 8,
132
+ startColor,
133
+ endColor,
134
+ isLoaded = false,
135
+ children,
136
+ ...props
137
+ },
138
+ ref
139
+ ) => {
140
+ if (isLoaded) {
141
+ return <>{children}</>;
142
+ }
143
+
144
+ return (
145
+ <View ref={ref} style={[styles.textContainer, style]} {...props}>
146
+ {Array.from({ length: noOfLines }).map((_, index) => (
147
+ <Skeleton
148
+ key={index}
149
+ variant="text"
150
+ height={14}
151
+ width={index === noOfLines - 1 ? '70%' : '100%'}
152
+ startColor={startColor}
153
+ endColor={endColor}
154
+ style={{ marginBottom: index < noOfLines - 1 ? spacing : 0 }}
155
+ />
156
+ ))}
157
+ </View>
158
+ );
159
+ }
160
+ );
161
+
162
+ SkeletonText.displayName = 'SkeletonText';
163
+
164
+ export const SkeletonCircle = forwardRef<View, SkeletonProps>(
165
+ ({ size = 40, ...props }, ref) => (
166
+ <Skeleton
167
+ ref={ref}
168
+ variant="circular"
169
+ width={size as number}
170
+ height={size as number}
171
+ {...props}
172
+ />
173
+ )
174
+ );
175
+
176
+ SkeletonCircle.displayName = 'SkeletonCircle';
177
+
178
+ const styles = StyleSheet.create({
179
+ skeleton: {
180
+ overflow: 'hidden',
181
+ },
182
+ shimmer: {
183
+ position: 'absolute',
184
+ top: 0,
185
+ bottom: 0,
186
+ width: '100%',
187
+ opacity: 0.5,
188
+ },
189
+ textContainer: {
190
+ width: '100%',
191
+ },
192
+ });
@@ -0,0 +1,8 @@
1
+ export {
2
+ Skeleton,
3
+ SkeletonText,
4
+ SkeletonCircle,
5
+ type SkeletonProps,
6
+ type SkeletonTextProps,
7
+ } from './Skeleton';
8
+
@@ -0,0 +1,363 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { useState } from 'react';
3
+ import { View, StyleSheet } from 'react-native';
4
+ import { Slider } from './Slider';
5
+ import { VStack } from '../VStack';
6
+ import { HStack } from '../HStack';
7
+ import { Text } from '../Text';
8
+ import { Box } from '../Box';
9
+ import { colors, spacing, borderRadius } from '../../styles/tokens';
10
+
11
+ /**
12
+ * Story container with design system tokens
13
+ */
14
+ const StoryContainer: React.FC<{ children: React.ReactNode }> = ({ children }) => (
15
+ <View style={styles.container}>{children}</View>
16
+ );
17
+
18
+ const meta: Meta<typeof Slider> = {
19
+ title: 'Forms/Slider',
20
+ component: Slider,
21
+ decorators: [
22
+ (Story) => (
23
+ <StoryContainer>
24
+ <Story />
25
+ </StoryContainer>
26
+ ),
27
+ ],
28
+ argTypes: {
29
+ size: {
30
+ control: 'select',
31
+ options: ['sm', 'md', 'lg'],
32
+ },
33
+ colorScheme: {
34
+ control: 'select',
35
+ options: ['primary', 'success', 'danger'],
36
+ },
37
+ min: { control: 'number' },
38
+ max: { control: 'number' },
39
+ step: { control: 'number' },
40
+ isDisabled: { control: 'boolean' },
41
+ showValue: { control: 'boolean' },
42
+ },
43
+ args: {
44
+ min: 0,
45
+ max: 100,
46
+ defaultValue: 50,
47
+ size: 'md',
48
+ colorScheme: 'primary',
49
+ },
50
+ };
51
+
52
+ export default meta;
53
+
54
+ type Story = StoryObj<typeof Slider>;
55
+
56
+ export const Default: Story = {
57
+ render: (args) => <Slider {...args} />,
58
+ };
59
+
60
+ export const WithLabel: Story = {
61
+ render: () => (
62
+ <VStack space={spacing.xl}>
63
+ <Slider
64
+ label="Volume"
65
+ defaultValue={70}
66
+ showValue
67
+ />
68
+ <Slider
69
+ label="Brightness"
70
+ defaultValue={50}
71
+ showValue
72
+ />
73
+ </VStack>
74
+ ),
75
+ };
76
+
77
+ export const Sizes: Story = {
78
+ render: () => (
79
+ <VStack space={spacing.xl}>
80
+ <Text weight="semiBold">Slider Sizes</Text>
81
+ <Slider
82
+ label="Small"
83
+ size="sm"
84
+ defaultValue={30}
85
+ showValue
86
+ />
87
+ <Slider
88
+ label="Medium"
89
+ size="md"
90
+ defaultValue={50}
91
+ showValue
92
+ />
93
+ <Slider
94
+ label="Large"
95
+ size="lg"
96
+ defaultValue={70}
97
+ showValue
98
+ />
99
+ </VStack>
100
+ ),
101
+ };
102
+
103
+ export const ColorSchemes: Story = {
104
+ render: () => (
105
+ <VStack space={spacing.xl}>
106
+ <Text weight="semiBold">Color Schemes</Text>
107
+ <Slider
108
+ label="Primary"
109
+ colorScheme="primary"
110
+ defaultValue={60}
111
+ showValue
112
+ />
113
+ <Slider
114
+ label="Success"
115
+ colorScheme="success"
116
+ defaultValue={80}
117
+ showValue
118
+ />
119
+ <Slider
120
+ label="Danger"
121
+ colorScheme="danger"
122
+ defaultValue={40}
123
+ showValue
124
+ />
125
+ </VStack>
126
+ ),
127
+ };
128
+
129
+ export const CustomRange: Story = {
130
+ render: () => (
131
+ <VStack space={spacing.xl}>
132
+ <Text weight="semiBold">Custom Ranges</Text>
133
+ <Slider
134
+ label="Temperature (°F)"
135
+ min={32}
136
+ max={100}
137
+ defaultValue={72}
138
+ showValue
139
+ />
140
+ <Slider
141
+ label="Year"
142
+ min={1990}
143
+ max={2024}
144
+ defaultValue={2020}
145
+ showValue
146
+ />
147
+ <Slider
148
+ label="Percentage"
149
+ min={0}
150
+ max={100}
151
+ defaultValue={75}
152
+ showValue
153
+ />
154
+ </VStack>
155
+ ),
156
+ };
157
+
158
+ export const Steps: Story = {
159
+ render: () => (
160
+ <VStack space={spacing.xl}>
161
+ <Text weight="semiBold">Different Step Values</Text>
162
+ <Slider
163
+ label="Step 1 (default)"
164
+ min={0}
165
+ max={100}
166
+ step={1}
167
+ defaultValue={50}
168
+ showValue
169
+ />
170
+ <Slider
171
+ label="Step 5"
172
+ min={0}
173
+ max={100}
174
+ step={5}
175
+ defaultValue={50}
176
+ showValue
177
+ />
178
+ <Slider
179
+ label="Step 10"
180
+ min={0}
181
+ max={100}
182
+ step={10}
183
+ defaultValue={50}
184
+ showValue
185
+ />
186
+ <Slider
187
+ label="Step 25"
188
+ min={0}
189
+ max={100}
190
+ step={25}
191
+ defaultValue={50}
192
+ showValue
193
+ />
194
+ </VStack>
195
+ ),
196
+ };
197
+
198
+ export const States: Story = {
199
+ render: () => (
200
+ <VStack space={spacing.xl}>
201
+ <Text weight="semiBold">Slider States</Text>
202
+ <Slider
203
+ label="Normal"
204
+ defaultValue={50}
205
+ showValue
206
+ />
207
+ <Slider
208
+ label="Disabled"
209
+ defaultValue={50}
210
+ isDisabled
211
+ showValue
212
+ />
213
+ </VStack>
214
+ ),
215
+ };
216
+
217
+ export const Controlled: Story = {
218
+ render: () => {
219
+ const ControlledSlider = () => {
220
+ const [value, setValue] = useState(50);
221
+
222
+ return (
223
+ <VStack space={spacing.lg}>
224
+ <Text weight="semiBold">Controlled Slider</Text>
225
+ <Slider
226
+ label="Controlled Value"
227
+ value={value}
228
+ onChange={setValue}
229
+ showValue
230
+ />
231
+ <HStack space={spacing.sm}>
232
+ <Text variant="small" color={colors.text.secondary}>Current value: {value}</Text>
233
+ </HStack>
234
+ <HStack space={spacing.sm}>
235
+ <Box
236
+ p={spacing.sm}
237
+ bg={colors.feedback.info.background}
238
+ rounded="md"
239
+ style={{ cursor: 'pointer' }}
240
+ onTouchEnd={() => setValue(0)}
241
+ >
242
+ <Text variant="small">Set to 0</Text>
243
+ </Box>
244
+ <Box
245
+ p={spacing.sm}
246
+ bg={colors.feedback.info.background}
247
+ rounded="md"
248
+ style={{ cursor: 'pointer' }}
249
+ onTouchEnd={() => setValue(50)}
250
+ >
251
+ <Text variant="small">Set to 50</Text>
252
+ </Box>
253
+ <Box
254
+ p={spacing.sm}
255
+ bg={colors.feedback.info.background}
256
+ rounded="md"
257
+ style={{ cursor: 'pointer' }}
258
+ onTouchEnd={() => setValue(100)}
259
+ >
260
+ <Text variant="small">Set to 100</Text>
261
+ </Box>
262
+ </HStack>
263
+ </VStack>
264
+ );
265
+ };
266
+
267
+ return <ControlledSlider />;
268
+ },
269
+ };
270
+
271
+ export const VolumeControl: Story = {
272
+ render: () => (
273
+ <VStack space={spacing.lg}>
274
+ <Text weight="semiBold">Volume Control</Text>
275
+ <Box p={spacing.lg} bg={colors.background.secondary} rounded="lg">
276
+ <VStack space={spacing.lg}>
277
+ <HStack space={spacing.md} alignItems="center">
278
+ <Text>🔈</Text>
279
+ <Box flex={1}>
280
+ <Slider
281
+ min={0}
282
+ max={100}
283
+ defaultValue={70}
284
+ />
285
+ </Box>
286
+ <Text>🔊</Text>
287
+ </HStack>
288
+ </VStack>
289
+ </Box>
290
+ </VStack>
291
+ ),
292
+ };
293
+
294
+ export const SettingsPanel: Story = {
295
+ render: () => (
296
+ <VStack space={spacing.lg}>
297
+ <Text weight="semiBold">Display Settings</Text>
298
+ <Box p={spacing.lg} bg={colors.background.default} rounded="lg" shadow="10">
299
+ <VStack space={spacing.xl}>
300
+ <Slider
301
+ label="Brightness"
302
+ defaultValue={80}
303
+ showValue
304
+ colorScheme="primary"
305
+ />
306
+ <Slider
307
+ label="Contrast"
308
+ defaultValue={50}
309
+ showValue
310
+ colorScheme="primary"
311
+ />
312
+ <Slider
313
+ label="Saturation"
314
+ defaultValue={60}
315
+ showValue
316
+ colorScheme="primary"
317
+ />
318
+ <Slider
319
+ label="Sharpness"
320
+ defaultValue={40}
321
+ showValue
322
+ colorScheme="primary"
323
+ />
324
+ </VStack>
325
+ </Box>
326
+ </VStack>
327
+ ),
328
+ };
329
+
330
+ export const PriceRange: Story = {
331
+ render: () => (
332
+ <VStack space={spacing.lg}>
333
+ <Text weight="semiBold">Price Range Filter</Text>
334
+ <Box p={spacing.lg} bg={colors.background.secondary} rounded="lg">
335
+ <VStack space={spacing.lg}>
336
+ <Slider
337
+ label="Max Price"
338
+ min={0}
339
+ max={1000}
340
+ step={50}
341
+ defaultValue={500}
342
+ showValue
343
+ />
344
+ <Text variant="small" color={colors.text.secondary}>
345
+ Showing products up to $500
346
+ </Text>
347
+ </VStack>
348
+ </Box>
349
+ </VStack>
350
+ ),
351
+ };
352
+
353
+ /**
354
+ * Styles using design system tokens
355
+ */
356
+ const styles = StyleSheet.create({
357
+ container: {
358
+ padding: spacing.lg,
359
+ backgroundColor: colors.background.default,
360
+ borderRadius: borderRadius.lg,
361
+ },
362
+ });
363
+