@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,192 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { View, StyleSheet } from 'react-native';
3
+ import { Box } from './Box';
4
+ import { Text } from '../Text';
5
+ import { VStack } from '../VStack';
6
+ import { colors, spacing, borderRadius } from '../../styles/tokens';
7
+
8
+ /**
9
+ * Story container with design system tokens
10
+ */
11
+ const StoryContainer: React.FC<{ children: React.ReactNode }> = ({ children }) => (
12
+ <View style={styles.container}>{children}</View>
13
+ );
14
+
15
+ const meta: Meta<typeof Box> = {
16
+ title: 'Layout/Box',
17
+ component: Box,
18
+ decorators: [
19
+ (Story) => (
20
+ <StoryContainer>
21
+ <Story />
22
+ </StoryContainer>
23
+ ),
24
+ ],
25
+ argTypes: {
26
+ p: { control: 'number' },
27
+ m: { control: 'number' },
28
+ bg: { control: 'color' },
29
+ rounded: {
30
+ control: 'select',
31
+ options: ['none', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', 'full'],
32
+ },
33
+ shadow: {
34
+ control: 'select',
35
+ options: ['5', '10', '20', '30', '40'],
36
+ },
37
+ },
38
+ args: {
39
+ p: spacing.lg,
40
+ bg: colors.feedback.info.background,
41
+ rounded: 'md',
42
+ },
43
+ };
44
+
45
+ export default meta;
46
+
47
+ type Story = StoryObj<typeof Box>;
48
+
49
+ export const Default: Story = {
50
+ render: (args) => (
51
+ <Box {...args}>
52
+ <Text>This is a Box component</Text>
53
+ </Box>
54
+ ),
55
+ };
56
+
57
+ export const Padding: Story = {
58
+ render: () => (
59
+ <VStack space={spacing.md}>
60
+ <Text weight="semiBold">Padding Variations</Text>
61
+ <Box p={spacing.sm} bg={colors.feedback.info.background} rounded="md">
62
+ <Text>p={spacing.sm}</Text>
63
+ </Box>
64
+ <Box p={spacing.lg} bg={colors.feedback.info.background} rounded="md">
65
+ <Text>p={spacing.lg}</Text>
66
+ </Box>
67
+ <Box p={spacing.xl} bg={colors.feedback.info.background} rounded="md">
68
+ <Text>p={spacing.xl}</Text>
69
+ </Box>
70
+ <Box px={spacing['2xl']} py={spacing.sm} bg={colors.feedback.info.background} rounded="md">
71
+ <Text>px={spacing['2xl']} py={spacing.sm}</Text>
72
+ </Box>
73
+ </VStack>
74
+ ),
75
+ };
76
+
77
+ export const BorderRadius: Story = {
78
+ render: () => (
79
+ <VStack space={spacing.md}>
80
+ <Text weight="semiBold">Border Radius Variations</Text>
81
+ <Box p={spacing.lg} bg={colors.feedback.error.background} rounded="none">
82
+ <Text>rounded="none"</Text>
83
+ </Box>
84
+ <Box p={spacing.lg} bg={colors.feedback.error.background} rounded="sm">
85
+ <Text>rounded="sm"</Text>
86
+ </Box>
87
+ <Box p={spacing.lg} bg={colors.feedback.error.background} rounded="md">
88
+ <Text>rounded="md"</Text>
89
+ </Box>
90
+ <Box p={spacing.lg} bg={colors.feedback.error.background} rounded="lg">
91
+ <Text>rounded="lg"</Text>
92
+ </Box>
93
+ <Box p={spacing.lg} bg={colors.feedback.error.background} rounded="xl">
94
+ <Text>rounded="xl"</Text>
95
+ </Box>
96
+ <Box p={spacing.lg} bg={colors.feedback.error.background} rounded="2xl">
97
+ <Text>rounded="2xl"</Text>
98
+ </Box>
99
+ </VStack>
100
+ ),
101
+ };
102
+
103
+ export const Shadows: Story = {
104
+ render: () => (
105
+ <VStack space={spacing.lg}>
106
+ <Text weight="semiBold">Shadow Elevations</Text>
107
+ <Box p={spacing.lg} bg={colors.background.default} rounded="lg" shadow="5">
108
+ <Text>shadow="5"</Text>
109
+ </Box>
110
+ <Box p={spacing.lg} bg={colors.background.default} rounded="lg" shadow="10">
111
+ <Text>shadow="10"</Text>
112
+ </Box>
113
+ <Box p={spacing.lg} bg={colors.background.default} rounded="lg" shadow="20">
114
+ <Text>shadow="20"</Text>
115
+ </Box>
116
+ <Box p={spacing.lg} bg={colors.background.default} rounded="lg" shadow="30">
117
+ <Text>shadow="30"</Text>
118
+ </Box>
119
+ <Box p={spacing.lg} bg={colors.background.default} rounded="lg" shadow="40">
120
+ <Text>shadow="40"</Text>
121
+ </Box>
122
+ </VStack>
123
+ ),
124
+ };
125
+
126
+ export const Sizing: Story = {
127
+ render: () => (
128
+ <VStack space={spacing.md}>
129
+ <Text weight="semiBold">Fixed Sizes</Text>
130
+ <Box w={100} h={100} bg={colors.feedback.info.border} rounded="md" alignItems="center" justifyContent="center">
131
+ <Text>100x100</Text>
132
+ </Box>
133
+ <Box w={200} h={60} bg={colors.feedback.info.border} rounded="md" alignItems="center" justifyContent="center">
134
+ <Text>200x60</Text>
135
+ </Box>
136
+ <Box w="100%" h={80} bg={colors.feedback.info.border} rounded="md" alignItems="center" justifyContent="center">
137
+ <Text>100% width</Text>
138
+ </Box>
139
+ </VStack>
140
+ ),
141
+ };
142
+
143
+ export const Borders: Story = {
144
+ render: () => (
145
+ <VStack space={spacing.md}>
146
+ <Text weight="semiBold">Border Styles</Text>
147
+ <Box p={spacing.lg} borderWidth={1} borderColor={colors.border.default} rounded="md">
148
+ <Text>1px border</Text>
149
+ </Box>
150
+ <Box p={spacing.lg} borderWidth={2} borderColor={colors.border.active} rounded="md">
151
+ <Text>2px active border</Text>
152
+ </Box>
153
+ <Box p={spacing.lg} borderWidth={3} borderColor={colors.border.danger} rounded="lg">
154
+ <Text>3px danger border</Text>
155
+ </Box>
156
+ </VStack>
157
+ ),
158
+ };
159
+
160
+ export const FlexLayout: Story = {
161
+ render: () => (
162
+ <VStack space={spacing.md}>
163
+ <Text weight="semiBold">Flex Layout</Text>
164
+ <Box flexDirection="row" justifyContent="space-between" p={spacing.lg} bg={colors.feedback.success.background} rounded="md">
165
+ <Box p={spacing.sm} bg={colors.feedback.success.border} rounded="sm">
166
+ <Text>Item 1</Text>
167
+ </Box>
168
+ <Box p={spacing.sm} bg={colors.feedback.success.border} rounded="sm">
169
+ <Text>Item 2</Text>
170
+ </Box>
171
+ <Box p={spacing.sm} bg={colors.feedback.success.border} rounded="sm">
172
+ <Text>Item 3</Text>
173
+ </Box>
174
+ </Box>
175
+ <Box flexDirection="row" alignItems="center" justifyContent="center" h={100} bg={colors.feedback.warning.background} rounded="md">
176
+ <Text>Centered Content</Text>
177
+ </Box>
178
+ </VStack>
179
+ ),
180
+ };
181
+
182
+ /**
183
+ * Styles using design system tokens
184
+ */
185
+ const styles = StyleSheet.create({
186
+ container: {
187
+ padding: spacing.lg,
188
+ backgroundColor: colors.background.default,
189
+ borderRadius: borderRadius.lg,
190
+ },
191
+ });
192
+
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Box Component
3
+ * The most fundamental layout component - a div equivalent with styling props
4
+ */
5
+
6
+ import React, { forwardRef } from 'react';
7
+ import { View, ViewProps, ViewStyle } from 'react-native';
8
+ import { StyleSheet } from 'react-native-unistyles';
9
+ import { spacing, SpacingToken, elevation } from '../../styles/tokens';
10
+
11
+ /** Spacing value can be a token name or raw number */
12
+ type SpacingValue = SpacingToken | number;
13
+
14
+ /** Resolve spacing value to pixels */
15
+ const resolveSpacing = (value: SpacingValue | undefined): number | undefined => {
16
+ if (value === undefined) return undefined;
17
+ if (typeof value === 'number') return value;
18
+ return spacing[value];
19
+ };
20
+
21
+ export interface BoxProps extends ViewProps {
22
+ /** Padding - accepts token ('sm', 'md', 'lg') or number */
23
+ p?: SpacingValue;
24
+ px?: SpacingValue;
25
+ py?: SpacingValue;
26
+ pt?: SpacingValue;
27
+ pb?: SpacingValue;
28
+ pl?: SpacingValue;
29
+ pr?: SpacingValue;
30
+ /** Margin - accepts token ('sm', 'md', 'lg') or number */
31
+ m?: SpacingValue;
32
+ mx?: SpacingValue;
33
+ my?: SpacingValue;
34
+ mt?: SpacingValue;
35
+ mb?: SpacingValue;
36
+ ml?: SpacingValue;
37
+ mr?: SpacingValue;
38
+ /** Gap between children - accepts token or number */
39
+ gap?: SpacingValue;
40
+ /** Background color */
41
+ bg?: string;
42
+ /** Border radius */
43
+ rounded?: keyof typeof borderRadiusMap;
44
+ /** Width */
45
+ w?: ViewStyle['width'];
46
+ /** Height */
47
+ h?: ViewStyle['height'];
48
+ /** Min width */
49
+ minW?: ViewStyle['minWidth'];
50
+ /** Min height */
51
+ minH?: ViewStyle['minHeight'];
52
+ /** Max width */
53
+ maxW?: ViewStyle['maxWidth'];
54
+ /** Max height */
55
+ maxH?: ViewStyle['maxHeight'];
56
+ /** Flex */
57
+ flex?: number;
58
+ /** Flex direction */
59
+ flexDirection?: ViewStyle['flexDirection'];
60
+ /** Align items */
61
+ alignItems?: ViewStyle['alignItems'];
62
+ /** Justify content */
63
+ justifyContent?: ViewStyle['justifyContent'];
64
+ /** Position */
65
+ position?: ViewStyle['position'];
66
+ /** Overflow */
67
+ overflow?: ViewStyle['overflow'];
68
+ /** Border width */
69
+ borderWidth?: number;
70
+ /** Border color */
71
+ borderColor?: string;
72
+ /** Shadow level */
73
+ shadow?: '5' | '10' | '20' | '30' | '40';
74
+ }
75
+
76
+ const borderRadiusMap = {
77
+ none: 0,
78
+ sm: 2,
79
+ md: 4,
80
+ lg: 8,
81
+ xl: 12,
82
+ '2xl': 16,
83
+ '3xl': 24,
84
+ full: 9999,
85
+ } as const;
86
+
87
+ const shadowMap = {
88
+ '5': elevation['5'],
89
+ '10': elevation['10'],
90
+ '20': elevation['20'],
91
+ '30': elevation['30'],
92
+ '40': elevation['40'],
93
+ } as const;
94
+
95
+ export const Box = forwardRef<View, BoxProps>(
96
+ (
97
+ {
98
+ style,
99
+ p,
100
+ px,
101
+ py,
102
+ pt,
103
+ pb,
104
+ pl,
105
+ pr,
106
+ m,
107
+ mx,
108
+ my,
109
+ mt,
110
+ mb,
111
+ ml,
112
+ mr,
113
+ gap,
114
+ bg,
115
+ rounded,
116
+ w,
117
+ h,
118
+ minW,
119
+ minH,
120
+ maxW,
121
+ maxH,
122
+ flex,
123
+ flexDirection,
124
+ alignItems,
125
+ justifyContent,
126
+ position,
127
+ overflow,
128
+ borderWidth,
129
+ borderColor,
130
+ shadow,
131
+ children,
132
+ ...props
133
+ },
134
+ ref
135
+ ) => {
136
+ const boxStyle: ViewStyle = {
137
+ ...(p !== undefined && { padding: resolveSpacing(p) }),
138
+ ...(px !== undefined && { paddingHorizontal: resolveSpacing(px) }),
139
+ ...(py !== undefined && { paddingVertical: resolveSpacing(py) }),
140
+ ...(pt !== undefined && { paddingTop: resolveSpacing(pt) }),
141
+ ...(pb !== undefined && { paddingBottom: resolveSpacing(pb) }),
142
+ ...(pl !== undefined && { paddingLeft: resolveSpacing(pl) }),
143
+ ...(pr !== undefined && { paddingRight: resolveSpacing(pr) }),
144
+ ...(m !== undefined && { margin: resolveSpacing(m) }),
145
+ ...(mx !== undefined && { marginHorizontal: resolveSpacing(mx) }),
146
+ ...(my !== undefined && { marginVertical: resolveSpacing(my) }),
147
+ ...(mt !== undefined && { marginTop: resolveSpacing(mt) }),
148
+ ...(mb !== undefined && { marginBottom: resolveSpacing(mb) }),
149
+ ...(ml !== undefined && { marginLeft: resolveSpacing(ml) }),
150
+ ...(mr !== undefined && { marginRight: resolveSpacing(mr) }),
151
+ ...(gap !== undefined && { gap: resolveSpacing(gap) }),
152
+ ...(bg !== undefined && { backgroundColor: bg }),
153
+ ...(rounded !== undefined && { borderRadius: borderRadiusMap[rounded] }),
154
+ ...(w !== undefined && { width: w }),
155
+ ...(h !== undefined && { height: h }),
156
+ ...(minW !== undefined && { minWidth: minW }),
157
+ ...(minH !== undefined && { minHeight: minH }),
158
+ ...(maxW !== undefined && { maxWidth: maxW }),
159
+ ...(maxH !== undefined && { maxHeight: maxH }),
160
+ ...(flex !== undefined && { flex }),
161
+ ...(flexDirection !== undefined && { flexDirection }),
162
+ ...(alignItems !== undefined && { alignItems }),
163
+ ...(justifyContent !== undefined && { justifyContent }),
164
+ ...(position !== undefined && { position }),
165
+ ...(overflow !== undefined && { overflow }),
166
+ ...(borderWidth !== undefined && { borderWidth }),
167
+ ...(borderColor !== undefined && { borderColor }),
168
+ ...(shadow !== undefined && shadowMap[shadow]),
169
+ };
170
+
171
+ return (
172
+ <View
173
+ ref={ref}
174
+ style={[boxStyle, style]}
175
+ {...props}
176
+ >
177
+ {children}
178
+ </View>
179
+ );
180
+ }
181
+ );
182
+
183
+ Box.displayName = 'Box';
184
+
@@ -0,0 +1,2 @@
1
+ export { Box, type BoxProps } from './Box';
2
+
@@ -0,0 +1,157 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { Button } from './Button';
3
+ import { View, StyleSheet } from 'react-native';
4
+ import { VStack } from '../VStack';
5
+ import { HStack } from '../HStack';
6
+ import { Text } from '../Text';
7
+ import Svg, { Path } from 'react-native-svg';
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 Button> = {
18
+ title: 'Components/Button',
19
+ component: Button,
20
+ decorators: [
21
+ (Story) => (
22
+ <StoryContainer>
23
+ <Story />
24
+ </StoryContainer>
25
+ ),
26
+ ],
27
+ argTypes: {
28
+ variant: {
29
+ control: 'select',
30
+ options: ['primary', 'secondary', 'ghost', 'danger', 'outline'],
31
+ },
32
+ size: {
33
+ control: 'select',
34
+ options: ['sm', 'md', 'lg'],
35
+ },
36
+ isLoading: {
37
+ control: 'boolean',
38
+ },
39
+ isDisabled: {
40
+ control: 'boolean',
41
+ },
42
+ fullWidth: {
43
+ control: 'boolean',
44
+ },
45
+ },
46
+ args: {
47
+ children: 'Button',
48
+ variant: 'primary',
49
+ size: 'md',
50
+ isLoading: false,
51
+ isDisabled: false,
52
+ fullWidth: false,
53
+ },
54
+ };
55
+
56
+ export default meta;
57
+
58
+ type Story = StoryObj<typeof Button>;
59
+
60
+ export const Default: Story = {};
61
+
62
+ export const Variants: Story = {
63
+ render: () => (
64
+ <VStack space={spacing.md}>
65
+ <Text weight="semiBold">Button Variants</Text>
66
+ <HStack space={spacing.sm} wrap>
67
+ <Button variant="primary">Primary</Button>
68
+ <Button variant="secondary">Secondary</Button>
69
+ <Button variant="ghost">Ghost</Button>
70
+ <Button variant="danger">Danger</Button>
71
+ <Button variant="outline">Outline</Button>
72
+ </HStack>
73
+ </VStack>
74
+ ),
75
+ };
76
+
77
+ export const Sizes: Story = {
78
+ render: () => (
79
+ <VStack space={spacing.md}>
80
+ <Text weight="semiBold">Button Sizes</Text>
81
+ <HStack space={spacing.sm} alignItems="center">
82
+ <Button size="sm">Small</Button>
83
+ <Button size="md">Medium</Button>
84
+ <Button size="lg">Large</Button>
85
+ </HStack>
86
+ </VStack>
87
+ ),
88
+ };
89
+
90
+ export const States: Story = {
91
+ render: () => (
92
+ <VStack space={spacing.md}>
93
+ <Text weight="semiBold">Button States</Text>
94
+ <HStack space={spacing.sm}>
95
+ <Button>Normal</Button>
96
+ <Button isLoading>Loading</Button>
97
+ <Button isDisabled>Disabled</Button>
98
+ </HStack>
99
+ </VStack>
100
+ ),
101
+ };
102
+
103
+ export const WithIcons: Story = {
104
+ render: () => {
105
+ const PlusIcon = (
106
+ <Svg width={16} height={16} viewBox="0 0 24 24" fill="none">
107
+ <Path
108
+ d="M12 5v14M5 12h14"
109
+ stroke={colors.white}
110
+ strokeWidth={2}
111
+ strokeLinecap="round"
112
+ />
113
+ </Svg>
114
+ );
115
+ const ArrowIcon = (
116
+ <Svg width={16} height={16} viewBox="0 0 24 24" fill="none">
117
+ <Path
118
+ d="M5 12h14M12 5l7 7-7 7"
119
+ stroke={colors.white}
120
+ strokeWidth={2}
121
+ strokeLinecap="round"
122
+ strokeLinejoin="round"
123
+ />
124
+ </Svg>
125
+ );
126
+ return (
127
+ <VStack space={spacing.md}>
128
+ <Text weight="semiBold">Buttons with Icons</Text>
129
+ <HStack space={spacing.sm}>
130
+ <Button leftIcon={PlusIcon}>Add Item</Button>
131
+ <Button rightIcon={ArrowIcon}>Continue</Button>
132
+ </HStack>
133
+ </VStack>
134
+ );
135
+ },
136
+ };
137
+
138
+ export const FullWidth: Story = {
139
+ render: () => (
140
+ <VStack space={spacing.md}>
141
+ <Text weight="semiBold">Full Width Button</Text>
142
+ <Button fullWidth>Full Width Button</Button>
143
+ </VStack>
144
+ ),
145
+ };
146
+
147
+ /**
148
+ * Styles using design system tokens
149
+ */
150
+ const styles = StyleSheet.create({
151
+ container: {
152
+ padding: spacing.lg,
153
+ backgroundColor: colors.background.default,
154
+ borderRadius: borderRadius.lg,
155
+ },
156
+ });
157
+