@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
package/llms.txt ADDED
@@ -0,0 +1,1893 @@
1
+ # Urbint Component Library (@urbint/cl) - LLM Documentation
2
+
3
+ > This documentation is designed for LLM consumption to assist developers using the Urbint Component Library.
4
+
5
+ ## Overview
6
+
7
+ Urbint Component Library (`@urbint/cl`) is an enterprise-ready React Native component library built with Unistyles 3.0. It provides 40+ production-ready components for B2B SAAS applications across iOS, Android, and Web platforms.
8
+
9
+ **Key Features:**
10
+ - Cross-platform: iOS, Android, Web
11
+ - Full TypeScript support
12
+ - Light and Dark themes
13
+ - Accessible (WCAG 2.1 compliant)
14
+ - Built with Unistyles 3.0
15
+
16
+ **Tech Stack:**
17
+ - React Native 0.81+
18
+ - Unistyles 3.0+
19
+ - TypeScript 5.0+
20
+ - Expo SDK 54+
21
+
22
+ ---
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ # Install the library and peer dependencies
28
+ npm install @urbint/cl react-native-unistyles
29
+
30
+ # Or with yarn
31
+ yarn add @urbint/cl react-native-unistyles
32
+
33
+ # Or link locally during development
34
+ npm link ../path-to-urbint-cl
35
+ ```
36
+
37
+ ### Babel Configuration
38
+
39
+ Add the Unistyles Babel plugin to `babel.config.js`:
40
+
41
+ ```javascript
42
+ module.exports = function (api) {
43
+ api.cache(true);
44
+ return {
45
+ presets: ['babel-preset-expo'],
46
+ plugins: [
47
+ ['react-native-unistyles/plugin', { root: 'src' }],
48
+ ],
49
+ };
50
+ };
51
+ ```
52
+
53
+ ### Setup
54
+
55
+ Import styles in your app entry point before any components:
56
+
57
+ ```tsx
58
+ // App.tsx
59
+ import '@urbint/cl/styles';
60
+ import { Box, Text, Button } from '@urbint/cl';
61
+
62
+ export default function App() {
63
+ return (
64
+ <Box p="lg">
65
+ <Text>Hello World</Text>
66
+ <Button variant="primary">Click Me</Button>
67
+ </Box>
68
+ );
69
+ }
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Design Tokens
75
+
76
+ ### Colors
77
+
78
+ #### Brand Colors
79
+ - `brand.navy`: #0D2B3E - Primary dark brand color
80
+ - `brand.blue`: #00A0CC - Primary action color
81
+
82
+ #### Text Colors
83
+ - `text.primary`: #1F2937 - Primary text
84
+ - `text.secondary`: #6B7280 - Secondary text
85
+ - `text.disabled`: #9CA3AF - Disabled text
86
+ - `text.inverse`: #FFFFFF - Text on dark backgrounds
87
+
88
+ #### Background Colors
89
+ - `background.primary`: #FFFFFF - Main background
90
+ - `background.secondary`: #F9FAFB - Subtle background
91
+ - `background.tertiary`: #F3F4F6 - Elevated surfaces
92
+ - `background.inverse`: #111827 - Dark background
93
+
94
+ #### Border Colors
95
+ - `border.disabled`: #E5E7EB - Subtle borders
96
+ - `border.default`: #D1D5DB - Standard borders
97
+ - `border.hover`: #9CA3AF - Hover state
98
+ - `border.active`: #00A0CC - Focus/active state
99
+
100
+ #### Feedback Colors
101
+ - `feedback.info`: #3B82F6
102
+ - `feedback.success`: #22C55E
103
+ - `feedback.warning`: #F59E0B
104
+ - `feedback.error`: #EF4444
105
+
106
+ #### Badge Colors
107
+ - `badge.gray`: #6B7280
108
+ - `badge.red`: #DC2626
109
+ - `badge.orange`: #EA580C
110
+ - `badge.yellow`: #CA8A04
111
+ - `badge.green`: #16A34A
112
+ - `badge.blue`: #2563EB
113
+ - `badge.purple`: #7C3AED
114
+
115
+ ### Spacing Tokens
116
+
117
+ Spacing props accept **token names** (recommended) or raw numbers for backward compatibility.
118
+
119
+ | Token | Value | Description |
120
+ |-------|-------|-------------|
121
+ | `'none'` | 0px | No spacing |
122
+ | `'xs'` | 4px | Extra small |
123
+ | `'sm'` | 8px | Small |
124
+ | `'md'` | 12px | Medium |
125
+ | `'lg'` | 16px | Large |
126
+ | `'xl'` | 24px | Extra large |
127
+ | `'2xl'` | 32px | 2x extra large |
128
+ | `'3xl'` | 48px | 3x extra large |
129
+ | `'4xl'` | 64px | 4x extra large |
130
+ | `'5xl'` | 72px | 5x extra large |
131
+
132
+ **Legacy multiplier tokens (also supported):**
133
+ - `'0.5x'`: 2px, `'base'`: 4px, `'2x'`: 8px, `'3x'`: 12px, `'4x'`: 16px, `'6x'`: 24px, `'8x'`: 32px, `'12x'`: 48px, `'18x'`: 72px
134
+
135
+ ### Typography Scale
136
+ - `h1`: 32px, bold (700)
137
+ - `h2`: 24px, semibold (600)
138
+ - `h3`: 20px, semibold (600)
139
+ - `h4`: 18px, semibold (600)
140
+ - `body`: 16px, regular (400)
141
+ - `label`: 14px, regular (400)
142
+ - `caption`: 13px, regular (400)
143
+ - `small`: 12px, regular (400)
144
+
145
+ ### Border Radius
146
+ - `none`: 0
147
+ - `sm`: 2px
148
+ - `md`: 4px
149
+ - `lg`: 8px
150
+ - `xl`: 12px
151
+ - `2xl`: 16px
152
+ - `3xl`: 24px
153
+ - `full`: 9999px
154
+
155
+ ### Elevation (Shadows)
156
+ - `5`: Subtle shadow
157
+ - `10`: Light shadow
158
+ - `20`: Medium shadow
159
+ - `30`: Strong shadow
160
+ - `40`: Heavy shadow
161
+
162
+ ---
163
+
164
+ ## Components Reference
165
+
166
+ ### Layout Components
167
+
168
+ #### Box
169
+ The most fundamental layout component. A polymorphic container with style props.
170
+
171
+ ```tsx
172
+ import { Box } from '@urbint/cl';
173
+
174
+ // Using spacing tokens (recommended)
175
+ <Box p="lg" bg="brand.blue" rounded="md" shadow="10">
176
+ <Text color="white">Content</Text>
177
+ </Box>
178
+
179
+ // You can also use raw numbers for backward compatibility
180
+ <Box p={16} m="sm" gap="md">
181
+ <Text>Mixed usage</Text>
182
+ </Box>
183
+ ```
184
+
185
+ **Props:**
186
+ | Prop | Type | Default | Description |
187
+ |------|------|---------|-------------|
188
+ | p | SpacingToken \| number | - | Padding all sides ('xs', 'sm', 'md', 'lg', 'xl', '2xl', etc.) |
189
+ | px | SpacingToken \| number | - | Horizontal padding |
190
+ | py | SpacingToken \| number | - | Vertical padding |
191
+ | pt, pb, pl, pr | SpacingToken \| number | - | Individual padding |
192
+ | m | SpacingToken \| number | - | Margin all sides |
193
+ | mx, my | SpacingToken \| number | - | Horizontal/vertical margin |
194
+ | mt, mb, ml, mr | SpacingToken \| number | - | Individual margin |
195
+ | gap | SpacingToken \| number | - | Gap between children |
196
+ | bg | string | - | Background color |
197
+ | rounded | 'none' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| '3xl' \| 'full' | - | Border radius |
198
+ | w | number \| string | - | Width |
199
+ | h | number \| string | - | Height |
200
+ | minW, maxW | number \| string | - | Min/max width |
201
+ | minH, maxH | number \| string | - | Min/max height |
202
+ | flex | number | - | Flex value |
203
+ | flexDirection | 'row' \| 'column' | - | Flex direction |
204
+ | alignItems | FlexAlignType | - | Align items |
205
+ | justifyContent | FlexJustify | - | Justify content |
206
+ | shadow | '5' \| '10' \| '20' \| '30' \| '40' | - | Shadow elevation |
207
+
208
+ ---
209
+
210
+ #### HStack
211
+ Horizontal stack layout with consistent spacing.
212
+
213
+ ```tsx
214
+ import { HStack } from '@urbint/cl';
215
+
216
+ // Using spacing tokens (recommended)
217
+ <HStack space="sm" alignItems="center">
218
+ <Avatar name="John" />
219
+ <Text>John Doe</Text>
220
+ </HStack>
221
+
222
+ // Using larger spacing
223
+ <HStack space="xl">
224
+ <Button>Cancel</Button>
225
+ <Button variant="primary">Submit</Button>
226
+ </HStack>
227
+ ```
228
+
229
+ **Props:**
230
+ | Prop | Type | Default | Description |
231
+ |------|------|---------|-------------|
232
+ | space | SpacingToken \| number | 'none' | Gap between children ('xs', 'sm', 'md', 'lg', 'xl', etc.) |
233
+ | px | SpacingToken \| number | - | Horizontal padding ('xs', 'sm', 'md', 'lg', 'xl', etc.) |
234
+ | py | SpacingToken \| number | - | Vertical padding ('xs', 'sm', 'md', 'lg', 'xl', etc.) |
235
+ | alignItems | FlexAlignType | 'center' | Cross-axis alignment |
236
+ | justifyContent | FlexJustify | 'flex-start' | Main-axis alignment |
237
+ | wrap | boolean | false | Allow wrapping |
238
+ | reversed | boolean | false | Reverse order |
239
+
240
+ ---
241
+
242
+ #### VStack
243
+ Vertical stack layout with consistent spacing.
244
+
245
+ ```tsx
246
+ import { VStack } from '@urbint/cl';
247
+
248
+ // Using spacing tokens (recommended)
249
+ <VStack space="lg">
250
+ <Heading as="h2">Title</Heading>
251
+ <Text>Description</Text>
252
+ <Button>Action</Button>
253
+ </VStack>
254
+
255
+ // Form layout with medium spacing
256
+ <VStack space="md">
257
+ <Input label="Email" />
258
+ <Input label="Password" isPassword />
259
+ <Button>Sign In</Button>
260
+ </VStack>
261
+ ```
262
+
263
+ **Props:**
264
+ | Prop | Type | Default | Description |
265
+ |------|------|---------|-------------|
266
+ | space | SpacingToken \| number | 'none' | Gap between children ('xs', 'sm', 'md', 'lg', 'xl', etc.) |
267
+ | px | SpacingToken \| number | - | Horizontal padding ('xs', 'sm', 'md', 'lg', 'xl', etc.) |
268
+ | py | SpacingToken \| number | - | Vertical padding ('xs', 'sm', 'md', 'lg', 'xl', etc.) |
269
+ | alignItems | FlexAlignType | 'stretch' | Cross-axis alignment |
270
+ | justifyContent | FlexJustify | 'flex-start' | Main-axis alignment |
271
+
272
+ ---
273
+
274
+ #### Center
275
+ Centers children horizontally and vertically.
276
+
277
+ ```tsx
278
+ import { Center } from '@urbint/cl';
279
+
280
+ <Center h={200}>
281
+ <Spinner />
282
+ </Center>
283
+ ```
284
+
285
+ ---
286
+
287
+ #### Grid
288
+ Grid layout for arranging items in rows and columns.
289
+
290
+ ```tsx
291
+ import { Grid, GridItem } from '@urbint/cl';
292
+
293
+ // Using spacing tokens (recommended)
294
+ <Grid columns={3} gap="lg">
295
+ <GridItem><Card>1</Card></GridItem>
296
+ <GridItem><Card>2</Card></GridItem>
297
+ <GridItem><Card>3</Card></GridItem>
298
+ </Grid>
299
+
300
+ // Different row and column gaps
301
+ <Grid columns={2} rowGap="xl" columnGap="md">
302
+ <GridItem><Card>A</Card></GridItem>
303
+ <GridItem><Card>B</Card></GridItem>
304
+ </Grid>
305
+ ```
306
+
307
+ **Props:**
308
+ | Prop | Type | Default | Description |
309
+ |------|------|---------|-------------|
310
+ | columns | number | 1 | Number of columns |
311
+ | gap | SpacingToken \| number | 'none' | Gap between items ('xs', 'sm', 'md', 'lg', etc.) |
312
+ | rowGap | SpacingToken \| number | - | Gap between rows |
313
+ | columnGap | SpacingToken \| number | - | Gap between columns |
314
+
315
+ ---
316
+
317
+ #### Divider
318
+ Visual separator between content.
319
+
320
+ ```tsx
321
+ import { Divider } from '@urbint/cl';
322
+
323
+ <VStack>
324
+ <Text>Above</Text>
325
+ <Divider />
326
+ <Text>Below</Text>
327
+ </VStack>
328
+
329
+ <HStack>
330
+ <Text>Left</Text>
331
+ <Divider orientation="vertical" />
332
+ <Text>Right</Text>
333
+ </HStack>
334
+ ```
335
+
336
+ **Props:**
337
+ | Prop | Type | Default | Description |
338
+ |------|------|---------|-------------|
339
+ | orientation | 'horizontal' \| 'vertical' | 'horizontal' | Direction |
340
+ | thickness | number | 1 | Line thickness |
341
+ | color | string | border.disabled | Divider color |
342
+
343
+ ---
344
+
345
+ ### Typography Components
346
+
347
+ #### Text
348
+ Primary text component with variants.
349
+
350
+ ```tsx
351
+ import { Text } from '@urbint/cl';
352
+
353
+ <Text variant="body">Regular body text</Text>
354
+ <Text variant="caption" color="text.secondary">Secondary caption</Text>
355
+ <Text weight="bold" align="center">Bold centered</Text>
356
+ ```
357
+
358
+ **Props:**
359
+ | Prop | Type | Default | Description |
360
+ |------|------|---------|-------------|
361
+ | variant | 'body' \| 'caption' \| 'label' \| 'small' | 'body' | Text style |
362
+ | weight | 'regular' \| 'medium' \| 'semiBold' \| 'bold' | 'regular' | Font weight |
363
+ | color | string | text.primary | Text color |
364
+ | align | 'left' \| 'center' \| 'right' | 'left' | Alignment |
365
+ | numberOfLines | number | - | Max lines |
366
+
367
+ ---
368
+
369
+ #### Heading
370
+ Semantic heading component.
371
+
372
+ ```tsx
373
+ import { Heading } from '@urbint/cl';
374
+
375
+ <Heading as="h1">Page Title</Heading>
376
+ <Heading as="h2">Section Title</Heading>
377
+ <Heading as="h3" color="brand.blue">Colored Heading</Heading>
378
+ ```
379
+
380
+ **Props:**
381
+ | Prop | Type | Default | Description |
382
+ |------|------|---------|-------------|
383
+ | as | 'h1' \| 'h2' \| 'h3' \| 'h4' | 'h2' | Heading level |
384
+ | color | string | text.primary | Text color |
385
+ | align | 'left' \| 'center' \| 'right' | 'left' | Alignment |
386
+
387
+ ---
388
+
389
+ #### Link
390
+ Interactive text link.
391
+
392
+ ```tsx
393
+ import { Link } from '@urbint/cl';
394
+
395
+ <Link href="/about">About Us</Link>
396
+ <Link href="https://example.com" isExternal>External Link</Link>
397
+ <Link onPress={() => navigate('/home')}>Go Home</Link>
398
+ ```
399
+
400
+ **Props:**
401
+ | Prop | Type | Default | Description |
402
+ |------|------|---------|-------------|
403
+ | href | string | - | URL to navigate |
404
+ | onPress | () => void | - | Press handler |
405
+ | isExternal | boolean | false | Open in new tab |
406
+ | color | string | brand.blue | Link color |
407
+
408
+ ---
409
+
410
+ ### Form Components
411
+
412
+ #### Button
413
+ Primary action component.
414
+
415
+ ```tsx
416
+ import { Button } from '@urbint/cl';
417
+
418
+ <Button variant="primary" onPress={handleSubmit}>Submit</Button>
419
+ <Button variant="secondary">Cancel</Button>
420
+ <Button variant="ghost">Learn More</Button>
421
+ <Button variant="danger" onPress={handleDelete}>Delete</Button>
422
+ <Button variant="outline">Outline</Button>
423
+ <Button isLoading>Saving...</Button>
424
+ <Button isDisabled>Disabled</Button>
425
+ <Button size="sm">Small</Button>
426
+ <Button size="lg">Large</Button>
427
+ <Button leftIcon={<Icon name="plus" />}>Add Item</Button>
428
+ ```
429
+
430
+ **Props:**
431
+ | Prop | Type | Default | Description |
432
+ |------|------|---------|-------------|
433
+ | variant | 'primary' \| 'secondary' \| 'ghost' \| 'danger' \| 'outline' | 'primary' | Style variant |
434
+ | size | 'sm' \| 'md' \| 'lg' | 'md' | Button size |
435
+ | isLoading | boolean | false | Show loading spinner |
436
+ | isDisabled | boolean | false | Disable button |
437
+ | leftIcon | ReactNode | - | Icon before text |
438
+ | rightIcon | ReactNode | - | Icon after text |
439
+ | onPress | () => void | - | Press handler |
440
+
441
+ ---
442
+
443
+ #### Input
444
+ Text input field.
445
+
446
+ ```tsx
447
+ import { Input } from '@urbint/cl';
448
+
449
+ <Input
450
+ label="Email"
451
+ placeholder="Enter your email"
452
+ value={email}
453
+ onChange={setEmail}
454
+ />
455
+
456
+ <Input
457
+ label="Password"
458
+ isPassword
459
+ placeholder="Enter password"
460
+ />
461
+
462
+ <Input
463
+ label="Username"
464
+ isInvalid
465
+ errorMessage="Username is already taken"
466
+ />
467
+
468
+ <Input
469
+ label="Disabled"
470
+ isDisabled
471
+ value="Cannot edit"
472
+ />
473
+
474
+ <Input
475
+ leftElement={<Icon name="search" />}
476
+ placeholder="Search..."
477
+ />
478
+ ```
479
+
480
+ **Props:**
481
+ | Prop | Type | Default | Description |
482
+ |------|------|---------|-------------|
483
+ | label | string | - | Input label |
484
+ | placeholder | string | - | Placeholder text |
485
+ | value | string | - | Controlled value |
486
+ | onChange | (value: string) => void | - | Change handler |
487
+ | isInvalid | boolean | false | Error state |
488
+ | errorMessage | string | - | Error message |
489
+ | isDisabled | boolean | false | Disable input |
490
+ | isPassword | boolean | false | Password type |
491
+ | leftElement | ReactNode | - | Left icon/element |
492
+ | rightElement | ReactNode | - | Right icon/element |
493
+ | showFocusBorder | boolean | false | Show border highlight on focus |
494
+ | borderColor | string | - | Custom border color |
495
+ | focusBorderColor | string | - | Custom focus border color |
496
+ | backgroundColor | string | - | Custom background color |
497
+
498
+ ---
499
+
500
+ #### Textarea
501
+ Multi-line text input.
502
+
503
+ ```tsx
504
+ import { Textarea } from '@urbint/cl';
505
+
506
+ <Textarea
507
+ label="Description"
508
+ placeholder="Enter description..."
509
+ rows={4}
510
+ value={description}
511
+ onChange={setDescription}
512
+ />
513
+
514
+ <Textarea
515
+ label="Notes"
516
+ maxLength={500}
517
+ showCount
518
+ />
519
+ ```
520
+
521
+ **Props:**
522
+ | Prop | Type | Default | Description |
523
+ |------|------|---------|-------------|
524
+ | label | string | - | Textarea label |
525
+ | placeholder | string | - | Placeholder |
526
+ | rows | number | 4 | Visible rows |
527
+ | maxLength | number | - | Max characters |
528
+ | showCount | boolean | false | Show character count |
529
+ | value | string | - | Controlled value |
530
+ | onChange | (value: string) => void | - | Change handler |
531
+
532
+ ---
533
+
534
+ #### Checkbox
535
+ Boolean selection control.
536
+
537
+ ```tsx
538
+ import { Checkbox } from '@urbint/cl';
539
+
540
+ <Checkbox
541
+ label="I accept the terms"
542
+ isChecked={accepted}
543
+ onChange={setAccepted}
544
+ />
545
+
546
+ <Checkbox label="Remember me" defaultChecked />
547
+ <Checkbox label="Disabled" isDisabled />
548
+ <Checkbox label="Indeterminate" isIndeterminate />
549
+ ```
550
+
551
+ **Props:**
552
+ | Prop | Type | Default | Description |
553
+ |------|------|---------|-------------|
554
+ | label | string | - | Checkbox label |
555
+ | isChecked | boolean | - | Controlled state |
556
+ | defaultChecked | boolean | false | Initial state |
557
+ | onChange | (checked: boolean) => void | - | Change handler |
558
+ | isDisabled | boolean | false | Disable checkbox |
559
+ | isIndeterminate | boolean | false | Partial selection |
560
+
561
+ ---
562
+
563
+ #### Radio & RadioGroup
564
+ Single selection from options.
565
+
566
+ ```tsx
567
+ import { Radio, RadioGroup } from '@urbint/cl';
568
+
569
+ <RadioGroup
570
+ label="Select size"
571
+ value={size}
572
+ onChange={setSize}
573
+ >
574
+ <Radio value="sm" label="Small" />
575
+ <Radio value="md" label="Medium" />
576
+ <Radio value="lg" label="Large" />
577
+ </RadioGroup>
578
+ ```
579
+
580
+ **RadioGroup Props:**
581
+ | Prop | Type | Default | Description |
582
+ |------|------|---------|-------------|
583
+ | label | string | - | Group label |
584
+ | value | string | - | Selected value |
585
+ | onChange | (value: string) => void | - | Change handler |
586
+
587
+ **Radio Props:**
588
+ | Prop | Type | Default | Description |
589
+ |------|------|---------|-------------|
590
+ | value | string | required | Radio value |
591
+ | label | string | - | Radio label |
592
+ | isDisabled | boolean | false | Disable radio |
593
+
594
+ ---
595
+
596
+ #### Switch
597
+ Toggle switch for binary states.
598
+
599
+ ```tsx
600
+ import { Switch } from '@urbint/cl';
601
+
602
+ <Switch
603
+ label="Enable notifications"
604
+ isChecked={enabled}
605
+ onChange={setEnabled}
606
+ />
607
+
608
+ <Switch label="Dark mode" colorScheme="primary" />
609
+ <Switch label="Auto-save" colorScheme="success" defaultChecked />
610
+ ```
611
+
612
+ **Props:**
613
+ | Prop | Type | Default | Description |
614
+ |------|------|---------|-------------|
615
+ | label | string | - | Switch label |
616
+ | isChecked | boolean | - | Controlled state |
617
+ | defaultChecked | boolean | false | Initial state |
618
+ | onChange | (checked: boolean) => void | - | Change handler |
619
+ | colorScheme | 'primary' \| 'success' \| 'danger' | 'primary' | Active color |
620
+ | isDisabled | boolean | false | Disable switch |
621
+
622
+ ---
623
+
624
+ #### Select
625
+ Dropdown selection with popover-style dropdown. Supports single select, multi-select, and searchable modes with hover states.
626
+
627
+ ```tsx
628
+ import { Select } from '@urbint/cl';
629
+
630
+ // Basic usage
631
+ <Select
632
+ label="Country"
633
+ placeholder="Select country"
634
+ options={[
635
+ { value: 'us', label: 'United States' },
636
+ { value: 'uk', label: 'United Kingdom' },
637
+ { value: 'ca', label: 'Canada' },
638
+ ]}
639
+ value={country}
640
+ onChange={setCountry}
641
+ />
642
+
643
+ // Multi-select
644
+ <Select
645
+ label="Technologies"
646
+ placeholder="Select technologies..."
647
+ isMultiple
648
+ options={[
649
+ { value: 'react', label: 'React' },
650
+ { value: 'vue', label: 'Vue' },
651
+ { value: 'angular', label: 'Angular' },
652
+ ]}
653
+ value={selectedTechs}
654
+ onChange={setSelectedTechs}
655
+ />
656
+
657
+ // Searchable select
658
+ <Select
659
+ label="Country"
660
+ placeholder="Search countries..."
661
+ isSearchable
662
+ searchPlaceholder="Type to search..."
663
+ options={countryOptions}
664
+ />
665
+
666
+ // Searchable multi-select
667
+ <Select
668
+ label="Tags"
669
+ placeholder="Search and select tags..."
670
+ isSearchable
671
+ isMultiple
672
+ noResultsText="No tags found"
673
+ options={tagOptions}
674
+ />
675
+
676
+ // With custom filter function
677
+ <Select
678
+ label="Technologies"
679
+ isSearchable
680
+ isMultiple
681
+ options={techOptions}
682
+ filterOption={(option, query) =>
683
+ option.label.toLowerCase().includes(query.toLowerCase()) ||
684
+ option.category?.toLowerCase().includes(query.toLowerCase())
685
+ }
686
+ />
687
+
688
+ // With custom option rendering
689
+ <Select
690
+ options={[
691
+ { value: 'us', label: 'United States', flag: '🇺🇸' },
692
+ { value: 'uk', label: 'United Kingdom', flag: '🇬🇧' },
693
+ ]}
694
+ renderOption={({ option, isSelected, isHovered, searchQuery }) => (
695
+ <HStack space="sm" style={{ flex: 1 }}>
696
+ <Text>{option.flag}</Text>
697
+ <Text style={{ color: isSelected ? '#00A0CC' : '#000' }}>
698
+ {option.label}
699
+ </Text>
700
+ </HStack>
701
+ )}
702
+ renderSelectedValue={({ option, selectedOptions, placeholder, isMultiple }) => (
703
+ option ? (
704
+ <HStack space="sm">
705
+ <Text>{option.flag}</Text>
706
+ <Text>{option.label}</Text>
707
+ </HStack>
708
+ ) : (
709
+ <Text style={{ color: '#9CA3AF' }}>{placeholder}</Text>
710
+ )
711
+ )}
712
+ />
713
+ ```
714
+
715
+ **Props:**
716
+ | Prop | Type | Default | Description |
717
+ |------|------|---------|-------------|
718
+ | label | string | - | Select label |
719
+ | placeholder | string | 'Select an option' | Placeholder text |
720
+ | options | SelectOption[] | required | Options array |
721
+ | value | string \| string[] | - | Selected value(s) |
722
+ | defaultValue | string \| string[] | - | Default selected value(s) |
723
+ | onChange | (value: string \| string[]) => void | - | Change handler |
724
+ | isDisabled | boolean | false | Disable select |
725
+ | isMultiple | boolean | false | Enable multiple selection |
726
+ | isSearchable | boolean | false | Enable search/filter |
727
+ | searchPlaceholder | string | 'Search...' | Search input placeholder |
728
+ | noResultsText | string | 'No results found' | Text when no options match |
729
+ | filterOption | (option, query) => boolean | - | Custom filter function |
730
+ | size | 'sm' \| 'md' \| 'lg' | 'md' | Select size |
731
+ | variant | 'outline' \| 'filled' | 'outline' | Select variant |
732
+ | renderOption | (props: RenderOptionProps) => ReactNode | - | Custom option renderer |
733
+ | renderSelectedValue | (props: RenderSelectedValueProps) => ReactNode | - | Custom selected value renderer |
734
+
735
+ **SelectOption:**
736
+ ```ts
737
+ interface SelectOption {
738
+ label: string;
739
+ value: string;
740
+ disabled?: boolean;
741
+ [key: string]: any; // Custom data for rendering
742
+ }
743
+ ```
744
+
745
+ **RenderOptionProps:**
746
+ ```ts
747
+ interface RenderOptionProps {
748
+ option: SelectOption;
749
+ isSelected: boolean;
750
+ isDisabled: boolean;
751
+ isHovered?: boolean;
752
+ searchQuery?: string; // Current search query for highlighting
753
+ }
754
+ ```
755
+
756
+ **RenderSelectedValueProps:**
757
+ ```ts
758
+ interface RenderSelectedValueProps {
759
+ option: SelectOption | undefined; // First selected option
760
+ selectedOptions: SelectOption[]; // All selected options (for multi-select)
761
+ placeholder: string;
762
+ isMultiple: boolean;
763
+ }
764
+ ```
765
+
766
+ ---
767
+
768
+ #### DatePicker
769
+ Date and time picker with multiple modes. Supports date only, time only, or date and time selection (side by side).
770
+
771
+ ```tsx
772
+ import { DatePicker } from '@urbint/cl';
773
+
774
+ // Date only
775
+ <DatePicker
776
+ label="Date of Birth"
777
+ mode="date"
778
+ placeholder="Select date"
779
+ value={date}
780
+ onChange={setDate}
781
+ />
782
+
783
+ // Time only
784
+ <DatePicker
785
+ label="Appointment Time"
786
+ mode="time"
787
+ placeholder="Select time"
788
+ use24HourFormat={false}
789
+ />
790
+
791
+ // Date and time (side by side layout)
792
+ <DatePicker
793
+ label="Event Start"
794
+ mode="datetime"
795
+ placeholder="Select date & time"
796
+ value={datetime}
797
+ onChange={setDatetime}
798
+ showNowButton={true}
799
+ />
800
+
801
+ // With min/max constraints
802
+ <DatePicker
803
+ label="Future Date"
804
+ mode="date"
805
+ minDate={new Date()}
806
+ maxDate={new Date(2026, 11, 31)}
807
+ />
808
+
809
+ // With custom format
810
+ <DatePicker
811
+ label="European Format"
812
+ mode="date"
813
+ formatDate={(date) => {
814
+ const d = date.getDate().toString().padStart(2, '0');
815
+ const m = (date.getMonth() + 1).toString().padStart(2, '0');
816
+ return `${d}/${m}/${date.getFullYear()}`;
817
+ }}
818
+ />
819
+
820
+ // 24-hour time format
821
+ <DatePicker
822
+ label="Time (24h)"
823
+ mode="time"
824
+ use24HourFormat={true}
825
+ />
826
+
827
+ // Monday as first day of week
828
+ <DatePicker
829
+ label="Week starts Monday"
830
+ mode="date"
831
+ firstDayOfWeek={1}
832
+ />
833
+ ```
834
+
835
+ **Props:**
836
+ | Prop | Type | Default | Description |
837
+ |------|------|---------|-------------|
838
+ | mode | 'date' \| 'time' \| 'datetime' | 'date' | Picker mode |
839
+ | value | Date | - | Controlled value |
840
+ | defaultValue | Date | - | Default value |
841
+ | onChange | (date: Date) => void | - | Change handler |
842
+ | placeholder | string | Auto-generated | Placeholder text |
843
+ | label | string | - | Label text |
844
+ | helperText | string | - | Helper text |
845
+ | errorMessage | string | - | Error message |
846
+ | isInvalid | boolean | false | Error state |
847
+ | isDisabled | boolean | false | Disable picker |
848
+ | isRequired | boolean | false | Required field |
849
+ | minDate | Date | - | Minimum selectable date |
850
+ | maxDate | Date | - | Maximum selectable date |
851
+ | size | 'sm' \| 'md' \| 'lg' | 'md' | Picker size |
852
+ | variant | 'outline' \| 'filled' | 'outline' | Visual variant |
853
+ | formatDate | (date: Date, mode: DatePickerMode) => string | Default formatter | Custom format function |
854
+ | use24HourFormat | boolean | false | Use 24-hour time format |
855
+ | firstDayOfWeek | 0 \| 1 | 0 | First day (0=Sunday, 1=Monday) |
856
+ | showNowButton | boolean | true | Show "Now" button in time/datetime modes |
857
+
858
+ **Mode Details:**
859
+ - `date`: Shows calendar only, closes on date selection
860
+ - `time`: Shows hour/minute/AM-PM columns with "Now" and "OK" buttons
861
+ - `datetime`: Shows calendar and time picker side by side with "Now" and "OK" buttons
862
+
863
+ ---
864
+
865
+ #### Slider
866
+ Range value selector.
867
+
868
+ ```tsx
869
+ import { Slider } from '@urbint/cl';
870
+
871
+ <Slider
872
+ label="Volume"
873
+ value={volume}
874
+ onChange={setVolume}
875
+ min={0}
876
+ max={100}
877
+ showValue
878
+ />
879
+
880
+ <Slider
881
+ label="Price range"
882
+ min={0}
883
+ max={1000}
884
+ step={10}
885
+ />
886
+ ```
887
+
888
+ **Props:**
889
+ | Prop | Type | Default | Description |
890
+ |------|------|---------|-------------|
891
+ | label | string | - | Slider label |
892
+ | value | number | - | Current value |
893
+ | onChange | (value: number) => void | - | Change handler |
894
+ | min | number | 0 | Minimum value |
895
+ | max | number | 100 | Maximum value |
896
+ | step | number | 1 | Step increment |
897
+ | showValue | boolean | false | Show current value |
898
+
899
+ ---
900
+
901
+ #### FormControl
902
+ Wrapper for form elements with label and error handling.
903
+
904
+ ```tsx
905
+ import { FormControl, Input } from '@urbint/cl';
906
+
907
+ <FormControl
908
+ label="Email"
909
+ helperText="We'll never share your email"
910
+ isRequired
911
+ >
912
+ <Input placeholder="Enter email" />
913
+ </FormControl>
914
+
915
+ <FormControl
916
+ label="Password"
917
+ isInvalid
918
+ errorMessage="Password must be at least 8 characters"
919
+ >
920
+ <Input isPassword />
921
+ </FormControl>
922
+ ```
923
+
924
+ **Props:**
925
+ | Prop | Type | Default | Description |
926
+ |------|------|---------|-------------|
927
+ | label | string | - | Form label |
928
+ | helperText | string | - | Helper text |
929
+ | errorMessage | string | - | Error message |
930
+ | isRequired | boolean | false | Show required indicator |
931
+ | isInvalid | boolean | false | Error state |
932
+
933
+ ---
934
+
935
+ ### Feedback Components
936
+
937
+ #### Alert
938
+ Status messages.
939
+
940
+ ```tsx
941
+ import { Alert } from '@urbint/cl';
942
+
943
+ <Alert status="info" title="Update available" description="A new version is ready." />
944
+ <Alert status="success" title="Saved!" />
945
+ <Alert status="warning" title="Warning" description="Please review before continuing." />
946
+ <Alert status="error" title="Error" description="Something went wrong." isClosable onClose={handleClose} />
947
+ ```
948
+
949
+ **Props:**
950
+ | Prop | Type | Default | Description |
951
+ |------|------|---------|-------------|
952
+ | status | 'info' \| 'success' \| 'warning' \| 'error' | 'info' | Alert type |
953
+ | title | string | required | Alert title |
954
+ | description | string | - | Alert description |
955
+ | isClosable | boolean | false | Show close button |
956
+ | onClose | () => void | - | Close handler |
957
+
958
+ ---
959
+
960
+ #### Toast
961
+ Non-blocking notifications.
962
+
963
+ ```tsx
964
+ import { useToast, ToastProvider } from '@urbint/cl';
965
+
966
+ // Wrap app with ToastProvider
967
+ <ToastProvider>
968
+ <App />
969
+ </ToastProvider>
970
+
971
+ // Use in components
972
+ function MyComponent() {
973
+ const toast = useToast();
974
+
975
+ const handleSave = () => {
976
+ toast.show({
977
+ title: 'Saved successfully',
978
+ status: 'success',
979
+ duration: 3000,
980
+ });
981
+ };
982
+
983
+ const handleError = () => {
984
+ toast.show({
985
+ title: 'Error',
986
+ description: 'Failed to save changes',
987
+ status: 'error',
988
+ });
989
+ };
990
+ }
991
+ ```
992
+
993
+ **toast.show() Options:**
994
+ | Option | Type | Default | Description |
995
+ |--------|------|---------|-------------|
996
+ | title | string | required | Toast title |
997
+ | description | string | - | Toast description |
998
+ | status | 'info' \| 'success' \| 'warning' \| 'error' | 'info' | Toast type |
999
+ | duration | number | 5000 | Auto-dismiss (ms) |
1000
+ | position | 'top' \| 'bottom' | 'top' | Screen position |
1001
+
1002
+ ---
1003
+
1004
+ #### Progress
1005
+ Progress indicator.
1006
+
1007
+ ```tsx
1008
+ import { Progress } from '@urbint/cl';
1009
+
1010
+ // Linear progress
1011
+ <Progress value={75} />
1012
+ <Progress value={50} size="lg" colorScheme="success" />
1013
+ <Progress value={25} showLabel />
1014
+ <Progress isIndeterminate />
1015
+
1016
+ // Circular progress
1017
+ <Progress variant="circular" value={75} />
1018
+ <Progress variant="circular" value={50} size="lg" showLabel />
1019
+ ```
1020
+
1021
+ **Props:**
1022
+ | Prop | Type | Default | Description |
1023
+ |------|------|---------|-------------|
1024
+ | value | number | - | Progress 0-100 |
1025
+ | variant | 'linear' \| 'circular' | 'linear' | Progress style |
1026
+ | size | 'sm' \| 'md' \| 'lg' | 'md' | Progress size |
1027
+ | colorScheme | 'primary' \| 'success' \| 'warning' | 'primary' | Color |
1028
+ | showLabel | boolean | false | Show percentage |
1029
+ | isIndeterminate | boolean | false | Indeterminate mode |
1030
+
1031
+ ---
1032
+
1033
+ #### Spinner
1034
+ Loading indicator.
1035
+
1036
+ ```tsx
1037
+ import { Spinner } from '@urbint/cl';
1038
+
1039
+ <Spinner />
1040
+ <Spinner size="lg" />
1041
+ <Spinner size="sm" color="brand.blue" />
1042
+ ```
1043
+
1044
+ **Props:**
1045
+ | Prop | Type | Default | Description |
1046
+ |------|------|---------|-------------|
1047
+ | size | 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' | 'md' | Spinner size |
1048
+ | color | string | brand.blue | Spinner color |
1049
+ | label | string | 'Loading' | Accessibility label |
1050
+
1051
+ ---
1052
+
1053
+ #### Skeleton
1054
+ Loading placeholder.
1055
+
1056
+ ```tsx
1057
+ import { Skeleton, SkeletonText, SkeletonCircle } from '@urbint/cl';
1058
+
1059
+ // Basic skeleton
1060
+ <Skeleton height={20} width="60%" />
1061
+ <Skeleton height={100} />
1062
+
1063
+ // Text skeleton
1064
+ <SkeletonText noOfLines={3} />
1065
+
1066
+ // Circle skeleton (for avatars)
1067
+ <SkeletonCircle size={48} />
1068
+
1069
+ // Combined loading state
1070
+ <HStack space={12}>
1071
+ <SkeletonCircle size={48} />
1072
+ <VStack space={8} flex={1}>
1073
+ <Skeleton height={16} width="70%" />
1074
+ <Skeleton height={14} width="40%" />
1075
+ </VStack>
1076
+ </HStack>
1077
+ ```
1078
+
1079
+ **Skeleton Props:**
1080
+ | Prop | Type | Default | Description |
1081
+ |------|------|---------|-------------|
1082
+ | width | number \| string | '100%' | Skeleton width |
1083
+ | height | number | 16 | Skeleton height |
1084
+ | animation | 'pulse' \| 'wave' \| 'none' | 'pulse' | Animation type |
1085
+
1086
+ ---
1087
+
1088
+ ### Data Display Components
1089
+
1090
+ #### Avatar
1091
+ User profile image.
1092
+
1093
+ ```tsx
1094
+ import { Avatar, AvatarGroup } from '@urbint/cl';
1095
+
1096
+ <Avatar name="John Doe" />
1097
+ <Avatar src="https://example.com/avatar.jpg" name="Jane" />
1098
+ <Avatar name="Bob Smith" size="lg" showBadge badgeColor="success" />
1099
+
1100
+ // Avatar group
1101
+ <AvatarGroup max={3}>
1102
+ <Avatar name="John" />
1103
+ <Avatar name="Jane" />
1104
+ <Avatar name="Bob" />
1105
+ <Avatar name="Alice" />
1106
+ </AvatarGroup>
1107
+ ```
1108
+
1109
+ **Props:**
1110
+ | Prop | Type | Default | Description |
1111
+ |------|------|---------|-------------|
1112
+ | src | string | - | Image URL |
1113
+ | name | string | - | Name for initials |
1114
+ | size | 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' | 'md' | Avatar size |
1115
+ | showBadge | boolean | false | Show status badge |
1116
+ | badgeColor | string | success | Badge color |
1117
+
1118
+ ---
1119
+
1120
+ #### Badge
1121
+ Status indicator labels.
1122
+
1123
+ ```tsx
1124
+ import { Badge } from '@urbint/cl';
1125
+
1126
+ <Badge variant="gray">Default</Badge>
1127
+ <Badge variant="red">Critical</Badge>
1128
+ <Badge variant="orange">Warning</Badge>
1129
+ <Badge variant="yellow">Pending</Badge>
1130
+ <Badge variant="green">Active</Badge>
1131
+ <Badge variant="blue">Info</Badge>
1132
+ <Badge variant="purple">New</Badge>
1133
+ ```
1134
+
1135
+ **Props:**
1136
+ | Prop | Type | Default | Description |
1137
+ |------|------|---------|-------------|
1138
+ | variant | 'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'blue' \| 'purple' | 'gray' | Badge color |
1139
+ | size | 'sm' \| 'md' | 'md' | Badge size |
1140
+
1141
+ ---
1142
+
1143
+ #### Card
1144
+ Content container.
1145
+
1146
+ ```tsx
1147
+ import { Card, CardHeader, CardBody, CardFooter } from '@urbint/cl';
1148
+
1149
+ <Card variant="elevated">
1150
+ <CardHeader>
1151
+ <Heading as="h3">Card Title</Heading>
1152
+ </CardHeader>
1153
+ <CardBody>
1154
+ <Text>Card content goes here.</Text>
1155
+ </CardBody>
1156
+ <CardFooter>
1157
+ <Button variant="ghost">Cancel</Button>
1158
+ <Button>Submit</Button>
1159
+ </CardFooter>
1160
+ </Card>
1161
+
1162
+ <Card variant="outline" padding="lg">
1163
+ <Text>Simple outline card</Text>
1164
+ </Card>
1165
+
1166
+ // Card with custom elevation
1167
+ <Card shadow="40">
1168
+ <Text>High elevation card</Text>
1169
+ </Card>
1170
+
1171
+ <Card variant="filled" shadow="10">
1172
+ <Text>Filled card with subtle shadow</Text>
1173
+ </Card>
1174
+ ```
1175
+
1176
+ **Props:**
1177
+ | Prop | Type | Default | Description |
1178
+ |------|------|---------|-------------|
1179
+ | variant | 'elevated' \| 'outline' \| 'filled' | 'elevated' | Card style |
1180
+ | padding | 'none' \| 'sm' \| 'md' \| 'lg' | 'md' | Internal padding |
1181
+ | shadow | '5' \| '10' \| '20' \| '30' \| '40' | '20' (for elevated) | Shadow elevation level |
1182
+ | isPressable | boolean | false | Make card tappable |
1183
+ | onPress | () => void | - | Press handler (requires isPressable) |
1184
+
1185
+ ---
1186
+
1187
+ #### Table
1188
+ Data table.
1189
+
1190
+ ```tsx
1191
+ import { Table, TableHead, TableBody, TableRow, TableCell } from '@urbint/cl';
1192
+
1193
+ <Table>
1194
+ <TableHead>
1195
+ <TableRow>
1196
+ <TableCell isHeader>Name</TableCell>
1197
+ <TableCell isHeader>Status</TableCell>
1198
+ <TableCell isHeader>Role</TableCell>
1199
+ </TableRow>
1200
+ </TableHead>
1201
+ <TableBody>
1202
+ <TableRow>
1203
+ <TableCell>John Doe</TableCell>
1204
+ <TableCell><Badge variant="green">Active</Badge></TableCell>
1205
+ <TableCell>Admin</TableCell>
1206
+ </TableRow>
1207
+ </TableBody>
1208
+ </Table>
1209
+ ```
1210
+
1211
+ ---
1212
+
1213
+ #### Icon
1214
+ SVG icons.
1215
+
1216
+ ```tsx
1217
+ import { Icon } from '@urbint/cl';
1218
+
1219
+ <Icon name="check" />
1220
+ <Icon name="close" size="lg" color="error" />
1221
+ <Icon name="search" size="sm" />
1222
+ <Icon name="user" />
1223
+ <Icon name="settings" />
1224
+ <Icon name="bell" />
1225
+ <Icon name="heart" color="red" />
1226
+ <Icon name="star" color="yellow" />
1227
+ ```
1228
+
1229
+ **Available Icons:** check, close, search, user, settings, bell, heart, star, plus, minus, edit, delete, chevron-down, chevron-up, chevron-left, chevron-right, arrow-left, arrow-right, info, warning, error, success
1230
+
1231
+ **Props:**
1232
+ | Prop | Type | Default | Description |
1233
+ |------|------|---------|-------------|
1234
+ | name | IconName | required | Icon name |
1235
+ | size | 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' | 'md' | Icon size |
1236
+ | color | string | text.primary | Icon color |
1237
+
1238
+ ---
1239
+
1240
+ ### Overlay Components
1241
+
1242
+ #### Modal
1243
+ Dialog overlay.
1244
+
1245
+ ```tsx
1246
+ import { Modal, ModalHeader, ModalBody, ModalFooter, useDisclosure } from '@urbint/cl';
1247
+
1248
+ function MyComponent() {
1249
+ const { isOpen, onOpen, onClose } = useDisclosure();
1250
+
1251
+ return (
1252
+ <>
1253
+ <Button onPress={onOpen}>Open Modal</Button>
1254
+
1255
+ <Modal isOpen={isOpen} onClose={onClose} size="md">
1256
+ <ModalHeader>Modal Title</ModalHeader>
1257
+ <ModalBody>
1258
+ <Text>Modal content goes here.</Text>
1259
+ </ModalBody>
1260
+ <ModalFooter>
1261
+ <Button variant="ghost" onPress={onClose}>Cancel</Button>
1262
+ <Button onPress={handleConfirm}>Confirm</Button>
1263
+ </ModalFooter>
1264
+ </Modal>
1265
+ </>
1266
+ );
1267
+ }
1268
+ ```
1269
+
1270
+ **Props:**
1271
+ | Prop | Type | Default | Description |
1272
+ |------|------|---------|-------------|
1273
+ | isOpen | boolean | required | Open state |
1274
+ | onClose | () => void | required | Close handler |
1275
+ | size | 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full' | 'md' | Modal size |
1276
+ | closeOnOverlayClick | boolean | true | Close on backdrop |
1277
+
1278
+ ---
1279
+
1280
+ #### Drawer
1281
+ Slide-out panel.
1282
+
1283
+ ```tsx
1284
+ import { Drawer, DrawerHeader, DrawerBody, useDisclosure } from '@urbint/cl';
1285
+
1286
+ function MyComponent() {
1287
+ const { isOpen, onOpen, onClose } = useDisclosure();
1288
+
1289
+ return (
1290
+ <>
1291
+ <Button onPress={onOpen}>Open Menu</Button>
1292
+
1293
+ <Drawer isOpen={isOpen} onClose={onClose} title="Menu" placement="right">
1294
+ <DrawerBody>
1295
+ <VStack space={16}>
1296
+ <Link>Profile</Link>
1297
+ <Link>Settings</Link>
1298
+ <Link>Logout</Link>
1299
+ </VStack>
1300
+ </DrawerBody>
1301
+ </Drawer>
1302
+ </>
1303
+ );
1304
+ }
1305
+ ```
1306
+
1307
+ **Props:**
1308
+ | Prop | Type | Default | Description |
1309
+ |------|------|---------|-------------|
1310
+ | isOpen | boolean | required | Open state |
1311
+ | onClose | () => void | required | Close handler |
1312
+ | title | string | - | Drawer title displayed in header |
1313
+ | placement | 'left' \| 'right' \| 'top' \| 'bottom' | 'right' | Position |
1314
+ | size | 'sm' \| 'md' \| 'lg' \| 'full' | 'md' | Drawer size |
1315
+
1316
+ ---
1317
+
1318
+ #### AlertDialog
1319
+ Confirmation dialog.
1320
+
1321
+ ```tsx
1322
+ import { AlertDialog, useDisclosure } from '@urbint/cl';
1323
+
1324
+ function DeleteButton() {
1325
+ const { isOpen, onOpen, onClose } = useDisclosure();
1326
+
1327
+ return (
1328
+ <>
1329
+ <Button variant="danger" onPress={onOpen}>Delete</Button>
1330
+
1331
+ <AlertDialog
1332
+ isOpen={isOpen}
1333
+ onClose={onClose}
1334
+ onConfirm={handleDelete}
1335
+ title="Delete Item?"
1336
+ description="This action cannot be undone."
1337
+ confirmLabel="Delete"
1338
+ confirmVariant="danger"
1339
+ />
1340
+ </>
1341
+ );
1342
+ }
1343
+ ```
1344
+
1345
+ **Props:**
1346
+ | Prop | Type | Default | Description |
1347
+ |------|------|---------|-------------|
1348
+ | isOpen | boolean | required | Open state |
1349
+ | onClose | () => void | required | Close handler |
1350
+ | onConfirm | () => void | required | Confirm handler |
1351
+ | title | string | required | Dialog title |
1352
+ | description | string | - | Dialog description |
1353
+ | confirmLabel | string | 'Confirm' | Confirm button text |
1354
+ | confirmVariant | ButtonVariant | 'primary' | Confirm button style |
1355
+
1356
+ ---
1357
+
1358
+ #### Popover
1359
+ Floating content.
1360
+
1361
+ ```tsx
1362
+ import { Popover, PopoverTrigger, PopoverContent } from '@urbint/cl';
1363
+
1364
+ <Popover placement="bottom">
1365
+ <PopoverTrigger>
1366
+ <Button>Open Popover</Button>
1367
+ </PopoverTrigger>
1368
+ <PopoverContent>
1369
+ <Text>Popover content here</Text>
1370
+ </PopoverContent>
1371
+ </Popover>
1372
+ ```
1373
+
1374
+ **Props:**
1375
+ | Prop | Type | Default | Description |
1376
+ |------|------|---------|-------------|
1377
+ | placement | 'top' \| 'bottom' \| 'left' \| 'right' | 'bottom' | Position |
1378
+ | isOpen | boolean | - | Controlled state |
1379
+ | onClose | () => void | - | Close handler |
1380
+
1381
+ ---
1382
+
1383
+ #### Tooltip
1384
+ Hover hints.
1385
+
1386
+ ```tsx
1387
+ import { Tooltip } from '@urbint/cl';
1388
+
1389
+ <Tooltip label="This is a helpful tip">
1390
+ <Button>Hover me</Button>
1391
+ </Tooltip>
1392
+
1393
+ <Tooltip label="Delete item" placement="left">
1394
+ <Icon name="delete" />
1395
+ </Tooltip>
1396
+ ```
1397
+
1398
+ **Props:**
1399
+ | Prop | Type | Default | Description |
1400
+ |------|------|---------|-------------|
1401
+ | label | string | required | Tooltip text |
1402
+ | placement | 'top' \| 'bottom' \| 'left' \| 'right' | 'top' | Position |
1403
+ | hasArrow | boolean | true | Show arrow |
1404
+
1405
+ ---
1406
+
1407
+ #### Menu
1408
+ Dropdown menu.
1409
+
1410
+ ```tsx
1411
+ import { Menu, MenuTrigger, MenuContent, MenuItem } from '@urbint/cl';
1412
+
1413
+ <Menu>
1414
+ <MenuTrigger>
1415
+ <Button rightIcon={<Icon name="chevron-down" />}>Options</Button>
1416
+ </MenuTrigger>
1417
+ <MenuContent>
1418
+ <MenuItem onPress={handleEdit}>Edit</MenuItem>
1419
+ <MenuItem onPress={handleDuplicate}>Duplicate</MenuItem>
1420
+ <MenuItem onPress={handleDelete} isDestructive>Delete</MenuItem>
1421
+ </MenuContent>
1422
+ </Menu>
1423
+ ```
1424
+
1425
+ ---
1426
+
1427
+ #### ActionSheet
1428
+ Bottom sheet (mobile).
1429
+
1430
+ ```tsx
1431
+ import { ActionSheet, useDisclosure } from '@urbint/cl';
1432
+
1433
+ function MyComponent() {
1434
+ const { isOpen, onOpen, onClose } = useDisclosure();
1435
+
1436
+ return (
1437
+ <>
1438
+ <Button onPress={onOpen}>Show Actions</Button>
1439
+
1440
+ <ActionSheet
1441
+ isOpen={isOpen}
1442
+ onClose={onClose}
1443
+ actions={[
1444
+ { label: 'Edit', onPress: handleEdit },
1445
+ { label: 'Share', onPress: handleShare },
1446
+ { label: 'Delete', onPress: handleDelete, isDestructive: true },
1447
+ ]}
1448
+ />
1449
+ </>
1450
+ );
1451
+ }
1452
+ ```
1453
+
1454
+ ---
1455
+
1456
+ ### Action Components
1457
+
1458
+ #### Pressable
1459
+ Base pressable with feedback.
1460
+
1461
+ ```tsx
1462
+ import { Pressable } from '@urbint/cl';
1463
+
1464
+ <Pressable onPress={handlePress} onLongPress={handleLongPress}>
1465
+ <Card>
1466
+ <Text>Tap me</Text>
1467
+ </Card>
1468
+ </Pressable>
1469
+ ```
1470
+
1471
+ ---
1472
+
1473
+ #### Fab
1474
+ Floating action button.
1475
+
1476
+ ```tsx
1477
+ import { Fab } from '@urbint/cl';
1478
+
1479
+ <Fab
1480
+ icon={<Icon name="plus" color="white" />}
1481
+ onPress={handleAdd}
1482
+ position="bottom-right"
1483
+ />
1484
+
1485
+ <Fab
1486
+ icon={<Icon name="plus" />}
1487
+ label="Add Item"
1488
+ position="bottom-right"
1489
+ />
1490
+ ```
1491
+
1492
+ **Props:**
1493
+ | Prop | Type | Default | Description |
1494
+ |------|------|---------|-------------|
1495
+ | icon | ReactNode | required | FAB icon |
1496
+ | label | string | - | Extended FAB text |
1497
+ | position | 'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left' | 'bottom-right' | Screen position |
1498
+ | size | 'sm' \| 'md' \| 'lg' | 'md' | FAB size |
1499
+ | onPress | () => void | - | Press handler |
1500
+
1501
+ ---
1502
+
1503
+ #### Accordion
1504
+ Expandable sections with configurable icon position.
1505
+
1506
+ ```tsx
1507
+ import { Accordion, AccordionItem, AccordionButton, AccordionPanel } from '@urbint/cl';
1508
+
1509
+ // Basic usage (icon on right by default)
1510
+ <Accordion defaultIndex={['faq-1']} allowMultiple>
1511
+ <AccordionItem value="faq-1">
1512
+ <AccordionButton>What is Urbint CL?</AccordionButton>
1513
+ <AccordionPanel>
1514
+ <Text>Enterprise-ready React Native component library.</Text>
1515
+ </AccordionPanel>
1516
+ </AccordionItem>
1517
+ <AccordionItem value="faq-2">
1518
+ <AccordionButton>How do I install it?</AccordionButton>
1519
+ <AccordionPanel>
1520
+ <Text>npm install @urbint/cl</Text>
1521
+ </AccordionPanel>
1522
+ </AccordionItem>
1523
+ </Accordion>
1524
+
1525
+ // Icon on left for all items
1526
+ <Accordion iconPosition="left" defaultIndex={['item-1']}>
1527
+ <AccordionItem value="item-1">
1528
+ <AccordionButton>Site Conditions</AccordionButton>
1529
+ <AccordionPanel>
1530
+ <Text>Site conditions content...</Text>
1531
+ </AccordionPanel>
1532
+ </AccordionItem>
1533
+ <AccordionItem value="item-2">
1534
+ <AccordionButton>Activities</AccordionButton>
1535
+ <AccordionPanel>
1536
+ <Text>Activities content...</Text>
1537
+ </AccordionPanel>
1538
+ </AccordionItem>
1539
+ </Accordion>
1540
+
1541
+ // Per-item icon position override
1542
+ <Accordion iconPosition="right">
1543
+ <AccordionItem value="item-1">
1544
+ <AccordionButton iconPosition="left">Override to left</AccordionButton>
1545
+ <AccordionPanel>
1546
+ <Text>This item has icon on left.</Text>
1547
+ </AccordionPanel>
1548
+ </AccordionItem>
1549
+ <AccordionItem value="item-2">
1550
+ <AccordionButton>Uses default (right)</AccordionButton>
1551
+ <AccordionPanel>
1552
+ <Text>This item uses default position.</Text>
1553
+ </AccordionPanel>
1554
+ </AccordionItem>
1555
+ </Accordion>
1556
+ ```
1557
+
1558
+ **Accordion Props:**
1559
+ | Prop | Type | Default | Description |
1560
+ |------|------|---------|-------------|
1561
+ | defaultIndex | string[] | [] | Initially expanded |
1562
+ | allowMultiple | boolean | false | Multiple open sections |
1563
+ | allowToggle | boolean | true | Allow toggling items |
1564
+ | iconPosition | 'left' \| 'right' | 'right' | Position of expand/collapse icon for all items |
1565
+ | onChange | (index: string[]) => void | - | Change handler |
1566
+
1567
+ **AccordionButton Props:**
1568
+ | Prop | Type | Default | Description |
1569
+ |------|------|---------|-------------|
1570
+ | iconPosition | 'left' \| 'right' | - | Override icon position for this button (inherits from Accordion if not set) |
1571
+
1572
+ ---
1573
+
1574
+ ### Utility Components
1575
+
1576
+ #### Portal
1577
+ Render outside parent hierarchy.
1578
+
1579
+ ```tsx
1580
+ import { Portal } from '@urbint/cl';
1581
+
1582
+ <Portal>
1583
+ <Modal>...</Modal>
1584
+ </Portal>
1585
+ ```
1586
+
1587
+ ---
1588
+
1589
+ ## Hooks
1590
+
1591
+ ### useDisclosure
1592
+ Manage open/close state.
1593
+
1594
+ ```tsx
1595
+ import { useDisclosure } from '@urbint/cl';
1596
+
1597
+ const { isOpen, onOpen, onClose, onToggle } = useDisclosure();
1598
+ const { isOpen, onOpen, onClose } = useDisclosure({ defaultOpen: true });
1599
+ ```
1600
+
1601
+ ### useControllableState
1602
+ Controlled/uncontrolled state management.
1603
+
1604
+ ```tsx
1605
+ import { useControllableState } from '@urbint/cl';
1606
+
1607
+ const [value, setValue] = useControllableState({
1608
+ value: controlledValue,
1609
+ defaultValue: 'default',
1610
+ onChange: onValueChange,
1611
+ });
1612
+ ```
1613
+
1614
+ ### useUnistyles
1615
+ Access theme and breakpoints.
1616
+
1617
+ ```tsx
1618
+ import { useUnistyles } from 'react-native-unistyles';
1619
+
1620
+ const { theme, breakpoint } = useUnistyles();
1621
+
1622
+ <Box bg={theme.colors.background.primary}>
1623
+ <Text style={{ fontSize: breakpoint === 'xs' ? 14 : 16 }}>
1624
+ Responsive text
1625
+ </Text>
1626
+ </Box>
1627
+ ```
1628
+
1629
+ ---
1630
+
1631
+ ## Theming
1632
+
1633
+ ### Creating a Custom Theme
1634
+
1635
+ ```tsx
1636
+ // src/styles/customTheme.ts
1637
+ import { lightTheme, darkTheme } from '@urbint/cl';
1638
+
1639
+ export const myLightTheme = {
1640
+ ...lightTheme,
1641
+ colors: {
1642
+ ...lightTheme.colors,
1643
+ brand: {
1644
+ primary: '#YOUR_PRIMARY_COLOR',
1645
+ secondary: '#YOUR_SECONDARY_COLOR',
1646
+ },
1647
+ },
1648
+ };
1649
+
1650
+ export const myDarkTheme = {
1651
+ ...darkTheme,
1652
+ colors: {
1653
+ ...darkTheme.colors,
1654
+ brand: {
1655
+ primary: '#YOUR_DARK_PRIMARY',
1656
+ secondary: '#YOUR_DARK_SECONDARY',
1657
+ },
1658
+ },
1659
+ };
1660
+ ```
1661
+
1662
+ ### Configuring Themes
1663
+
1664
+ ```tsx
1665
+ // src/styles/unistyles.ts
1666
+ import { StyleSheet } from 'react-native-unistyles';
1667
+ import { myLightTheme, myDarkTheme } from './customTheme';
1668
+
1669
+ StyleSheet.configure({
1670
+ themes: {
1671
+ light: myLightTheme,
1672
+ dark: myDarkTheme,
1673
+ },
1674
+ settings: {
1675
+ adaptiveThemes: true, // Auto-switch based on OS preference
1676
+ },
1677
+ });
1678
+ ```
1679
+
1680
+ ### Switching Themes
1681
+
1682
+ ```tsx
1683
+ import { UnistylesRuntime } from 'react-native-unistyles';
1684
+
1685
+ // Get current theme
1686
+ const currentTheme = UnistylesRuntime.themeName;
1687
+
1688
+ // Set theme
1689
+ UnistylesRuntime.setTheme('dark');
1690
+
1691
+ // Toggle theme
1692
+ const toggleTheme = () => {
1693
+ UnistylesRuntime.setTheme(
1694
+ UnistylesRuntime.themeName === 'light' ? 'dark' : 'light'
1695
+ );
1696
+ };
1697
+ ```
1698
+
1699
+ ---
1700
+
1701
+ ## Best Practices
1702
+
1703
+ ### Component Composition
1704
+ ```tsx
1705
+ // ✅ Good - compose components with spacing tokens
1706
+ <Card>
1707
+ <CardHeader>
1708
+ <HStack space="md">
1709
+ <Avatar name="John" />
1710
+ <VStack>
1711
+ <Text weight="semiBold">John Doe</Text>
1712
+ <Text variant="caption">Software Engineer</Text>
1713
+ </VStack>
1714
+ </HStack>
1715
+ </CardHeader>
1716
+ <CardBody>
1717
+ <Text>Content here</Text>
1718
+ </CardBody>
1719
+ </Card>
1720
+ ```
1721
+
1722
+ ### Form Handling
1723
+ ```tsx
1724
+ // ✅ Good - use FormControl with spacing tokens
1725
+ <VStack space="lg">
1726
+ <FormControl label="Name" isRequired>
1727
+ <Input value={name} onChange={setName} />
1728
+ </FormControl>
1729
+
1730
+ <FormControl label="Email" isInvalid={!!emailError} errorMessage={emailError}>
1731
+ <Input value={email} onChange={setEmail} />
1732
+ </FormControl>
1733
+
1734
+ <Button onPress={handleSubmit}>Submit</Button>
1735
+ </VStack>
1736
+ ```
1737
+
1738
+ ### Loading States
1739
+ ```tsx
1740
+ // ✅ Good - show loading placeholders with spacing tokens
1741
+ {isLoading ? (
1742
+ <HStack space="md">
1743
+ <SkeletonCircle size={48} />
1744
+ <VStack space="sm" flex={1}>
1745
+ <Skeleton height={16} width="60%" />
1746
+ <Skeleton height={14} width="40%" />
1747
+ </VStack>
1748
+ </HStack>
1749
+ ) : (
1750
+ <HStack space="md">
1751
+ <Avatar src={user.avatar} name={user.name} />
1752
+ <VStack>
1753
+ <Text weight="semiBold">{user.name}</Text>
1754
+ <Text variant="caption">{user.role}</Text>
1755
+ </VStack>
1756
+ </HStack>
1757
+ )}
1758
+ ```
1759
+
1760
+ ### Accessibility
1761
+ ```tsx
1762
+ // ✅ Good - provide accessible labels
1763
+ <Button accessibilityLabel="Submit form">Submit</Button>
1764
+ <Icon name="delete" accessibilityLabel="Delete item" />
1765
+ <Input label="Email" accessibilityHint="Enter your email address" />
1766
+ ```
1767
+
1768
+ ---
1769
+
1770
+ ## TypeScript Support
1771
+
1772
+ All components are fully typed. Import types as needed:
1773
+
1774
+ ```tsx
1775
+ import type {
1776
+ ButtonProps,
1777
+ InputProps,
1778
+ CardProps,
1779
+ ModalProps,
1780
+ ToastOptions,
1781
+ SpacingToken, // Type for spacing tokens
1782
+ } from '@urbint/cl';
1783
+ ```
1784
+
1785
+ ### SpacingToken Type
1786
+ The `SpacingToken` type represents all valid spacing token names:
1787
+
1788
+ ```tsx
1789
+ type SpacingToken =
1790
+ | 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl'
1791
+ | '0.5x' | 'base' | '2x' | '3x' | '4x' | '6x' | '8x' | '12x' | '18x';
1792
+ ```
1793
+
1794
+ Components that accept spacing (Box, HStack, VStack, Grid) use `SpacingToken | number` so you can use either tokens or raw pixel values.
1795
+
1796
+ ---
1797
+
1798
+ ## Troubleshooting
1799
+
1800
+ ### Metro bundler issues
1801
+ ```bash
1802
+ # Clear cache and restart
1803
+ npx expo start --clear
1804
+ ```
1805
+
1806
+ ### Unistyles not working
1807
+ 1. Ensure Babel plugin is configured
1808
+ 2. Restart Metro bundler
1809
+ 3. Check import order (styles before components)
1810
+
1811
+ ### Theme not applying
1812
+ ```tsx
1813
+ // Make sure to import styles first
1814
+ import '@urbint/cl/styles';
1815
+ // Then import components
1816
+ import { Button } from '@urbint/cl';
1817
+ ```
1818
+
1819
+ ---
1820
+
1821
+ ## MCP Server Integration
1822
+
1823
+ The Urbint Component Library includes an MCP (Model Context Protocol) server that enables AI assistants to discover and use the design system programmatically.
1824
+
1825
+ ### Setup
1826
+
1827
+ ```bash
1828
+ # Install MCP server dependencies
1829
+ npm run mcp:install
1830
+
1831
+ # Build the MCP server
1832
+ npm run mcp:build
1833
+ ```
1834
+
1835
+ ### Configure in Cursor IDE
1836
+
1837
+ Add to your Cursor MCP settings (`~/.cursor/mcp.json`):
1838
+
1839
+ ```json
1840
+ {
1841
+ "mcpServers": {
1842
+ "urbint-cl": {
1843
+ "command": "node",
1844
+ "args": ["/path/to/urbint-cl/mcp-server/dist/index.js"]
1845
+ }
1846
+ }
1847
+ }
1848
+ ```
1849
+
1850
+ ### Available MCP Tools
1851
+
1852
+ | Tool | Description |
1853
+ |------|-------------|
1854
+ | `list_components` | List all components, optionally filter by category |
1855
+ | `get_component` | Get detailed component documentation |
1856
+ | `search_components` | Search components by name, description, or tags |
1857
+ | `get_design_tokens` | Get design tokens (colors, spacing, etc.) |
1858
+ | `search_tokens` | Search for specific design tokens |
1859
+ | `generate_component_code` | Generate code snippets for components |
1860
+ | `get_form_pattern` | Generate form pattern code with validation |
1861
+ | `get_layout_pattern` | Generate layout pattern code |
1862
+
1863
+ ### Example Usage
1864
+
1865
+ Once configured, ask your AI assistant:
1866
+
1867
+ - "List all form components in the Urbint design system"
1868
+ - "Show me how to use the Select component with multi-select"
1869
+ - "What colors are available in the design system?"
1870
+ - "Generate a login form with email and password"
1871
+ - "Show me a dashboard layout pattern"
1872
+
1873
+ ### Available MCP Resources
1874
+
1875
+ - `urbint://docs/overview` - Library overview
1876
+ - `urbint://docs/components` - All components
1877
+ - `urbint://docs/tokens` - Design tokens
1878
+ - `urbint://docs/installation` - Installation guide
1879
+ - `urbint://component/{name}` - Individual component docs
1880
+
1881
+ ---
1882
+
1883
+ ## Version Compatibility
1884
+
1885
+ | urbint-cl | React Native | Expo SDK | Unistyles |
1886
+ |-----------|--------------|----------|-----------|
1887
+ | 1.x | 0.81+ | 54+ | 3.0+ |
1888
+
1889
+ ---
1890
+
1891
+ *Last updated: January 2026*
1892
+ *Documentation version: 1.1.0*
1893
+