@frosted-ui/react-native 0.0.1-canary.91 → 0.0.1-canary.94

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 (172) hide show
  1. package/README.md +72 -14
  2. package/dist/components/accordion.js +2 -2
  3. package/dist/components/accordion.js.map +1 -1
  4. package/dist/components/alert-dialog.js +2 -2
  5. package/dist/components/alert-dialog.js.map +1 -1
  6. package/dist/components/avatar.d.ts.map +1 -1
  7. package/dist/components/avatar.js +5 -20
  8. package/dist/components/avatar.js.map +1 -1
  9. package/dist/components/badge.d.ts +2 -4
  10. package/dist/components/badge.d.ts.map +1 -1
  11. package/dist/components/badge.js +8 -22
  12. package/dist/components/badge.js.map +1 -1
  13. package/dist/components/button.d.ts +1 -1
  14. package/dist/components/button.d.ts.map +1 -1
  15. package/dist/components/button.js +13 -17
  16. package/dist/components/button.js.map +1 -1
  17. package/dist/components/callout.d.ts +2 -4
  18. package/dist/components/callout.d.ts.map +1 -1
  19. package/dist/components/callout.js +6 -24
  20. package/dist/components/callout.js.map +1 -1
  21. package/dist/components/card.d.ts +1 -2
  22. package/dist/components/card.d.ts.map +1 -1
  23. package/dist/components/card.js +4 -4
  24. package/dist/components/card.js.map +1 -1
  25. package/dist/components/checkbox.d.ts +1 -2
  26. package/dist/components/checkbox.d.ts.map +1 -1
  27. package/dist/components/checkbox.js +5 -21
  28. package/dist/components/checkbox.js.map +1 -1
  29. package/dist/components/code.d.ts +6 -8
  30. package/dist/components/code.d.ts.map +1 -1
  31. package/dist/components/code.js +7 -7
  32. package/dist/components/code.js.map +1 -1
  33. package/dist/components/context-menu.js +9 -9
  34. package/dist/components/context-menu.js.map +1 -1
  35. package/dist/components/dialog.js +2 -2
  36. package/dist/components/dialog.js.map +1 -1
  37. package/dist/components/dropdown-menu.js +9 -9
  38. package/dist/components/dropdown-menu.js.map +1 -1
  39. package/dist/components/heading.d.ts +6 -6
  40. package/dist/components/heading.d.ts.map +1 -1
  41. package/dist/components/heading.js +2 -2
  42. package/dist/components/heading.js.map +1 -1
  43. package/dist/components/hover-card.js +2 -2
  44. package/dist/components/hover-card.js.map +1 -1
  45. package/dist/components/icon-button.d.ts +2 -2
  46. package/dist/components/icon-button.d.ts.map +1 -1
  47. package/dist/components/icon-button.js +13 -17
  48. package/dist/components/icon-button.js.map +1 -1
  49. package/dist/components/icon.d.ts +6 -7
  50. package/dist/components/icon.d.ts.map +1 -1
  51. package/dist/components/icon.js +9 -24
  52. package/dist/components/icon.js.map +1 -1
  53. package/dist/components/index.d.ts +2 -0
  54. package/dist/components/index.d.ts.map +1 -1
  55. package/dist/components/index.js +2 -0
  56. package/dist/components/index.js.map +1 -1
  57. package/dist/components/label.js +2 -2
  58. package/dist/components/label.js.map +1 -1
  59. package/dist/components/link.d.ts +19 -0
  60. package/dist/components/link.d.ts.map +1 -0
  61. package/dist/components/link.js +68 -0
  62. package/dist/components/link.js.map +1 -0
  63. package/dist/components/list.d.ts +37 -0
  64. package/dist/components/list.d.ts.map +1 -0
  65. package/dist/components/list.js +112 -0
  66. package/dist/components/list.js.map +1 -0
  67. package/dist/components/native-only-animated-view.d.ts +0 -4
  68. package/dist/components/native-only-animated-view.d.ts.map +1 -1
  69. package/dist/components/popover.js +2 -2
  70. package/dist/components/popover.js.map +1 -1
  71. package/dist/components/progress.d.ts +1 -2
  72. package/dist/components/progress.d.ts.map +1 -1
  73. package/dist/components/progress.js +5 -21
  74. package/dist/components/progress.js.map +1 -1
  75. package/dist/components/radio-group.d.ts +1 -2
  76. package/dist/components/radio-group.d.ts.map +1 -1
  77. package/dist/components/radio-group.js +7 -23
  78. package/dist/components/radio-group.js.map +1 -1
  79. package/dist/components/segmented-control.js +3 -3
  80. package/dist/components/segmented-control.js.map +1 -1
  81. package/dist/components/select.d.ts.map +1 -1
  82. package/dist/components/select.js +11 -13
  83. package/dist/components/select.js.map +1 -1
  84. package/dist/components/separator.d.ts +1 -1
  85. package/dist/components/separator.d.ts.map +1 -1
  86. package/dist/components/separator.js +4 -21
  87. package/dist/components/separator.js.map +1 -1
  88. package/dist/components/skeleton.d.ts.map +1 -1
  89. package/dist/components/skeleton.js +10 -26
  90. package/dist/components/skeleton.js.map +1 -1
  91. package/dist/components/spinner.js +2 -2
  92. package/dist/components/spinner.js.map +1 -1
  93. package/dist/components/switch.d.ts +1 -2
  94. package/dist/components/switch.d.ts.map +1 -1
  95. package/dist/components/switch.js +5 -21
  96. package/dist/components/switch.js.map +1 -1
  97. package/dist/components/tabs.d.ts +4 -3
  98. package/dist/components/tabs.d.ts.map +1 -1
  99. package/dist/components/tabs.js +10 -9
  100. package/dist/components/tabs.js.map +1 -1
  101. package/dist/components/text-area.d.ts.map +1 -1
  102. package/dist/components/text-area.js +13 -9
  103. package/dist/components/text-area.js.map +1 -1
  104. package/dist/components/text-field.d.ts.map +1 -1
  105. package/dist/components/text-field.js +62 -18
  106. package/dist/components/text-field.js.map +1 -1
  107. package/dist/components/text.d.ts +6 -6
  108. package/dist/components/text.d.ts.map +1 -1
  109. package/dist/components/text.js +22 -11
  110. package/dist/components/text.js.map +1 -1
  111. package/dist/components/tooltip.js +2 -2
  112. package/dist/components/tooltip.js.map +1 -1
  113. package/dist/index.d.ts +6 -1
  114. package/dist/index.d.ts.map +1 -1
  115. package/dist/index.js +11 -1
  116. package/dist/index.js.map +1 -1
  117. package/dist/lib/button-styles.d.ts +6 -6
  118. package/dist/lib/button-styles.d.ts.map +1 -1
  119. package/dist/lib/button-styles.js +1 -17
  120. package/dist/lib/button-styles.js.map +1 -1
  121. package/dist/lib/color-utils.d.ts +19 -14
  122. package/dist/lib/color-utils.d.ts.map +1 -1
  123. package/dist/lib/color-utils.js +37 -73
  124. package/dist/lib/color-utils.js.map +1 -1
  125. package/dist/lib/full-window-overlay.d.ts +11 -0
  126. package/dist/lib/full-window-overlay.d.ts.map +1 -0
  127. package/dist/lib/full-window-overlay.js +16 -0
  128. package/dist/lib/full-window-overlay.js.map +1 -0
  129. package/dist/lib/text-input-styles.d.ts +9 -8
  130. package/dist/lib/text-input-styles.d.ts.map +1 -1
  131. package/dist/lib/text-input-styles.js +4 -23
  132. package/dist/lib/text-input-styles.js.map +1 -1
  133. package/dist/lib/theme-context.d.ts +80 -0
  134. package/dist/lib/theme-context.d.ts.map +1 -0
  135. package/dist/lib/theme-context.js +97 -0
  136. package/dist/lib/theme-context.js.map +1 -0
  137. package/dist/lib/{theme-vars.d.ts → theme-tokens.d.ts} +2 -2
  138. package/dist/lib/theme-tokens.d.ts.map +1 -0
  139. package/dist/lib/{theme-vars.js → theme-tokens.js} +4 -19
  140. package/dist/lib/theme-tokens.js.map +1 -0
  141. package/dist/lib/theme.d.ts +14 -54
  142. package/dist/lib/theme.d.ts.map +1 -1
  143. package/dist/lib/theme.js +98 -66
  144. package/dist/lib/theme.js.map +1 -1
  145. package/dist/lib/types.d.ts +6 -2
  146. package/dist/lib/types.d.ts.map +1 -1
  147. package/dist/lib/use-theme-tokens.d.ts +593 -0
  148. package/dist/lib/use-theme-tokens.d.ts.map +1 -0
  149. package/dist/lib/use-theme-tokens.js +44 -0
  150. package/dist/lib/use-theme-tokens.js.map +1 -0
  151. package/docs/llm/COLOR_SYSTEM.md +799 -0
  152. package/docs/llm/COMPONENTS.md +1183 -0
  153. package/docs/llm/DESIGN_PATTERNS.md +2466 -0
  154. package/docs/llm/README.md +117 -0
  155. package/docs/llm/TYPOGRAPHY.md +516 -0
  156. package/package.json +11 -21
  157. package/dist/lib/native-colors.d.ts +0 -8
  158. package/dist/lib/native-colors.d.ts.map +0 -1
  159. package/dist/lib/native-colors.js +0 -67
  160. package/dist/lib/native-colors.js.map +0 -1
  161. package/dist/lib/theme-vars.d.ts.map +0 -1
  162. package/dist/lib/theme-vars.js.map +0 -1
  163. package/dist/lib/use-theme-vars.d.ts +0 -325
  164. package/dist/lib/use-theme-vars.d.ts.map +0 -1
  165. package/dist/lib/use-theme-vars.js +0 -17
  166. package/dist/lib/use-theme-vars.js.map +0 -1
  167. package/dist/lib/utils.d.ts +0 -3
  168. package/dist/lib/utils.d.ts.map +0 -1
  169. package/dist/lib/utils.js +0 -17
  170. package/dist/lib/utils.js.map +0 -1
  171. package/global.css +0 -1813
  172. package/tailwind-preset.js +0 -310
@@ -0,0 +1,1183 @@
1
+ # Frosted UI Components Reference
2
+
3
+ > **Critical**: Always import components from `@frosted-ui/react-native`, never from React Native directly for UI elements.
4
+
5
+ ```tsx
6
+ import { Button, Text, Card, Dialog } from '@frosted-ui/react-native';
7
+ ```
8
+
9
+ ---
10
+
11
+ ## Component Types
12
+
13
+ Frosted UI has two component patterns:
14
+
15
+ 1. **Simple Components** — Single import, use directly with props
16
+ 2. **Compound Components** — Dot notation (e.g., `Dialog.Root`, `Dialog.Content`)
17
+
18
+ ---
19
+
20
+ ## Text Handling in Components
21
+
22
+ Some components automatically wrap text, others require explicit `<Text>` components:
23
+
24
+ ### Components that auto-wrap text (pass plain strings):
25
+
26
+ These components internally render `<Text>`, so **do NOT wrap children in `<Text>`**:
27
+
28
+ | Component | Children |
29
+ | --------------------------- | ------------------ |
30
+ | `Link` | Plain string |
31
+ | `List.ItemTitle` | Plain string |
32
+ | `List.ItemDescription` | Plain string |
33
+ | `Select.Item` | Plain string |
34
+ | `Select.Label` | Plain string |
35
+ | `DropdownMenu.Item` | Plain string |
36
+ | `DropdownMenu.CheckboxItem` | Plain string |
37
+ | `DropdownMenu.RadioItem` | Plain string |
38
+ | `DropdownMenu.SubTrigger` | Plain string |
39
+ | `DropdownMenu.Label` | Plain string |
40
+ | `ContextMenu.Item` | Plain string |
41
+ | `ContextMenu.CheckboxItem` | Plain string |
42
+ | `ContextMenu.RadioItem` | Plain string |
43
+ | `ContextMenu.SubTrigger` | Plain string |
44
+ | `ContextMenu.Label` | Plain string |
45
+ | `Tabs.Trigger` | String or `<Text>` |
46
+ | `SegmentedControl.Trigger` | String or `<Text>` |
47
+ | `Accordion.Trigger` | Plain string |
48
+
49
+ ```tsx
50
+ // ✅ Correct
51
+ <Link onPress={() => {}}>Click here</Link>
52
+ <Select.Item value="1" label="Option 1">Option 1</Select.Item>
53
+ <DropdownMenu.Item>Edit</DropdownMenu.Item>
54
+
55
+ // ❌ Wrong - double-wrapped text
56
+ <Link onPress={() => {}}><Text>Click here</Text></Link>
57
+ <Select.Item value="1" label="Option 1"><Text>Option 1</Text></Select.Item>
58
+ <DropdownMenu.Item><Text>Edit</Text></DropdownMenu.Item>
59
+ ```
60
+
61
+ ### Components that style children via context:
62
+
63
+ These use `TextStyleContext` to auto-style nested `<Text>` and `<Icon>`. **You must explicitly use `<Text>` for text content:**
64
+
65
+ | Component | Children |
66
+ | -------------- | --------------------------- |
67
+ | `Button` | `<Text>`, `<Icon>`, or both |
68
+ | `IconButton` | `<Icon>` only (no text) |
69
+ | `Badge` | `<Text>`, `<Icon>`, or both |
70
+ | `Callout.Root` | `<Text>`, `<Icon>`, etc. |
71
+
72
+ ```tsx
73
+ // ✅ Correct - Text/Icon auto-styled by parent
74
+ <Button variant="solid">
75
+ <Text>Submit</Text>
76
+ </Button>
77
+
78
+ <IconButton variant="soft">
79
+ <Icon as={Settings} />
80
+ </IconButton>
81
+
82
+ <Badge color="success">
83
+ <Text>Active</Text>
84
+ </Badge>
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Simple Components
90
+
91
+ ### Button
92
+
93
+ Interactive button with variants and sizes.
94
+
95
+ ```tsx
96
+ <Button variant="solid" size="2" color="accent" onPress={handlePress}>
97
+ <Text>Click me</Text>
98
+ </Button>
99
+ ```
100
+
101
+ | Prop | Type | Default | Description |
102
+ | ---------- | ------------------------------------------- | ----------- | -------------- |
103
+ | `variant` | `'solid' \| 'soft' \| 'surface' \| 'ghost'` | `'surface'` | Visual style |
104
+ | `size` | `'1' \| '2' \| '3' \| '4'` | `'3'` | Button size |
105
+ | `color` | `Color` | `'accent'` | Color theme |
106
+ | `disabled` | `boolean` | `false` | Disabled state |
107
+
108
+ **Note**: Child `<Text>` components automatically receive correct styling.
109
+
110
+ #### Button Variants Guide
111
+
112
+ **Recommended pattern for most UIs:**
113
+
114
+ - **Primary action**: `variant="solid"`
115
+ - **Secondary action**: `variant="soft" color="gray"`
116
+
117
+ | Variant | Visual Style | When to Use |
118
+ | --------- | ---------------------------------------------- | -------------------------------------------------------------------- |
119
+ | `solid` | Vivid colored background, contrast text | **Primary CTA**: "Submit", "Save", "Continue". One per view. |
120
+ | `soft` | Tinted translucent background | **Secondary** (with `color="gray"`): "Cancel", "Back", "Dismiss" |
121
+ | `surface` | Neutral background, gray border, subtle shadow | Toolbar buttons, settings ("Edit", "Manage"), pairs with form inputs |
122
+ | `ghost` | Transparent, no border | Tertiary/inline actions, text-links, minimal UI |
123
+
124
+ > **Note**: `soft` with a non-gray color (e.g., `color="accent"`) is used for colored but less prominent actions like filter chips or toggle buttons.
125
+
126
+ > **IconButton**: Supports all the same variants as Button. Choose variant based on the same hierarchy rules above.
127
+
128
+ **Choosing the right variant:**
129
+
130
+ ```tsx
131
+ {
132
+ /* Primary action — use solid */
133
+ }
134
+ <Button variant="solid" color="accent">
135
+ <Text>Save Changes</Text>
136
+ </Button>;
137
+
138
+ {
139
+ /* Secondary action — use soft (often gray) */
140
+ }
141
+ <Button variant="soft" color="gray">
142
+ <Text>Cancel</Text>
143
+ </Button>;
144
+
145
+ {
146
+ /* Neutral/toolbar — use surface (default) */
147
+ }
148
+ <Button variant="surface">
149
+ <Text>Edit Profile</Text>
150
+ </Button>;
151
+
152
+ {
153
+ /* Tertiary/inline — use ghost */
154
+ }
155
+ <Button variant="ghost">
156
+ <Text>Learn more</Text>
157
+ </Button>;
158
+ ```
159
+
160
+ **Common pairings:**
161
+
162
+ - **Dialog actions**: `solid` (confirm) + `soft color="gray"` (cancel)
163
+ - **Toolbars**: `surface` buttons alongside `TextField.Input` and `Select`
164
+ - **Inline text actions**: `ghost` for link-style buttons
165
+ - **Destructive actions**: Any variant with `color="danger"`
166
+
167
+ ---
168
+
169
+ ### IconButton
170
+
171
+ Square button for icons only. Same API as Button.
172
+
173
+ ```tsx
174
+ import { X } from 'lucide-react-native';
175
+
176
+ <IconButton variant="ghost" onPress={handleClose}>
177
+ <Icon as={X} />
178
+ </IconButton>;
179
+ ```
180
+
181
+ ---
182
+
183
+ ### Icon
184
+
185
+ Wrapper for Lucide icons with automatic color inheritance.
186
+
187
+ ```tsx
188
+ import { ArrowRight } from 'lucide-react-native';
189
+
190
+ <Icon as={ArrowRight} size={16} />;
191
+ ```
192
+
193
+ | Prop | Type | Default | Description |
194
+ | ------- | ------------ | --------- | ------------------------- |
195
+ | `as` | `LucideIcon` | required | The Lucide icon component |
196
+ | `size` | `number` | `14` | Icon size in pixels |
197
+ | `color` | `string` | inherited | Override color |
198
+
199
+ **Note**: Inside Button, Badge, or Callout, Icon inherits the parent's text color automatically.
200
+
201
+ ---
202
+
203
+ ### Badge
204
+
205
+ Small label for status or categories.
206
+
207
+ ```tsx
208
+ <Badge variant="soft" size="1" color="success">
209
+ <Text>Active</Text>
210
+ </Badge>
211
+ ```
212
+
213
+ | Prop | Type | Default | Description |
214
+ | --------- | --------------------------------------------- | ---------- | ------------ |
215
+ | `variant` | `'solid' \| 'soft' \| 'surface' \| 'outline'` | `'soft'` | Visual style |
216
+ | `size` | `'1' \| '2'` | `'1'` | Badge size |
217
+ | `color` | `Color` | `'accent'` | Color theme |
218
+
219
+ ---
220
+
221
+ ### Link
222
+
223
+ Pressable text link with accent color.
224
+
225
+ ```tsx
226
+ <Link onPress={() => navigation.navigate('Terms')}>Terms of Service</Link>
227
+
228
+ <Text>
229
+ Read our <Link onPress={() => {}}>Privacy Policy</Link>.
230
+ </Text>
231
+ ```
232
+
233
+ | Prop | Type | Default | Description |
234
+ | ----------- | ------------------------------- | ---------- | --------------------------- |
235
+ | `size` | `'0'-'9'` | `'3'` | Text size |
236
+ | `weight` | `'light' \| ... \| 'bold'` | — | Font weight |
237
+ | `color` | `Color` | `'accent'` | Link color (uses a11 shade) |
238
+ | `underline` | `'auto' \| 'hover' \| 'always'` | `'auto'` | Underline behavior |
239
+ | `onPress` | `() => void` | — | Press handler |
240
+ | `disabled` | `boolean` | `false` | Disabled state |
241
+
242
+ > **Note**: `underline="auto"` shows underline on press (mobile equivalent of hover). Use `underline="always"` for always-visible underlines.
243
+
244
+ > **Inheritance**: When nested inside `<Text>`, Link inherits the parent's `size` and `weight`. This makes inline links match the surrounding text automatically.
245
+
246
+ ---
247
+
248
+ ### Avatar
249
+
250
+ User avatar with image or fallback initials.
251
+
252
+ ```tsx
253
+ <Avatar src="https://example.com/photo.jpg" fallback="John Doe" size="3" shape="circle" />
254
+ ```
255
+
256
+ | Prop | Type | Default | Description |
257
+ | ---------- | ---------------------- | ---------- | ---------------------------- |
258
+ | `src` | `string` | — | Image URL |
259
+ | `fallback` | `string \| ReactNode` | required | Initials or fallback content |
260
+ | `size` | `'0'-'9'` | `'3'` | Avatar size (16px to 160px) |
261
+ | `shape` | `'circle' \| 'square'` | `'circle'` | Avatar shape |
262
+ | `color` | `Color` | `'gray'` | Fallback background color |
263
+
264
+ ---
265
+
266
+ ### Card
267
+
268
+ Container with optional border and shadow.
269
+
270
+ ```tsx
271
+ <Card variant="surface">
272
+ <Text>Card content</Text>
273
+ </Card>
274
+ ```
275
+
276
+ | Prop | Type | Default | Description |
277
+ | --------- | -------------------------------- | ----------- | ------------ |
278
+ | `variant` | `'soft' \| 'surface' \| 'ghost'` | `'surface'` | Visual style |
279
+
280
+ #### Card Variants
281
+
282
+ | Variant | Visual Style | Use Case |
283
+ | --------- | ----------------------------------- | -------------------------------------------------- |
284
+ | `surface` | Solid bg, border, shadow | **Default** — Messages, profiles, elevated content |
285
+ | `soft` | Translucent tinted background | Tips, promotions, feature highlights |
286
+ | `ghost` | No background/border (padding only) | Section grouping, layout containers |
287
+
288
+ ---
289
+
290
+ ### List
291
+
292
+ Structured list container with items, slots, and separators. Renders a `Card` internally.
293
+
294
+ ```tsx
295
+ <List.Root variant="surface">
296
+ <List.Item onPress={() => {}}>
297
+ <List.ItemSlot>
298
+ <Icon as={Bell} size={20} />
299
+ </List.ItemSlot>
300
+ <List.ItemContent>
301
+ <List.ItemTitle>Notifications</List.ItemTitle>
302
+ <List.ItemDescription>Manage alerts and sounds</List.ItemDescription>
303
+ </List.ItemContent>
304
+ <List.ItemSlot>
305
+ <Icon as={ChevronRight} size={16} />
306
+ </List.ItemSlot>
307
+ </List.Item>
308
+ <List.Separator />
309
+ <List.Item onPress={() => {}}>
310
+ <List.ItemSlot>
311
+ <Avatar fallback="JD" size="3" />
312
+ </List.ItemSlot>
313
+ <List.ItemContent>
314
+ <List.ItemTitle>John Doe</List.ItemTitle>
315
+ <List.ItemDescription>john@example.com</List.ItemDescription>
316
+ </List.ItemContent>
317
+ <List.ItemSlot>
318
+ <Badge color="success" size="1">
319
+ <Text>Active</Text>
320
+ </Badge>
321
+ </List.ItemSlot>
322
+ </List.Item>
323
+ </List.Root>
324
+ ```
325
+
326
+ #### List Components
327
+
328
+ | Component | Purpose |
329
+ | ---------------------- | ---------------------------------------------- |
330
+ | `List.Root` | Container (renders Card with `padding: 0`) |
331
+ | `List.Item` | Pressable row with hover/press states |
332
+ | `List.ItemSlot` | Left/right slot for icons, avatars, controls |
333
+ | `List.ItemContent` | Flexible center area for title and description |
334
+ | `List.ItemTitle` | Primary text (medium weight, auto-styled) |
335
+ | `List.ItemDescription` | Secondary text (gray, auto-styled) |
336
+ | `List.Separator` | Full-width divider between items |
337
+
338
+ #### List.Root Props
339
+
340
+ | Prop | Type | Default | Description |
341
+ | --------- | -------------------------------- | ----------- | ----------------- |
342
+ | `variant` | `'soft' \| 'surface' \| 'ghost'` | `'surface'` | Card visual style |
343
+
344
+ #### List.Item Props
345
+
346
+ | Prop | Type | Default | Description |
347
+ | ---------- | ------------ | ------- | ---------------------------------- |
348
+ | `onPress` | `() => void` | — | Makes item interactive (pressable) |
349
+ | `disabled` | `boolean` | `false` | Disables press handling |
350
+ | `style` | `ViewStyle` | — | Custom styles |
351
+
352
+ #### List.ItemTitle & List.ItemDescription
353
+
354
+ These render styled `<Text>` directly — pass plain strings:
355
+
356
+ ```tsx
357
+ // ✅ Correct
358
+ <List.ItemTitle>Settings</List.ItemTitle>
359
+ <List.ItemDescription>Manage your preferences</List.ItemDescription>
360
+
361
+ // ❌ Wrong - don't wrap in Text
362
+ <List.ItemTitle><Text>Settings</Text></List.ItemTitle>
363
+ ```
364
+
365
+ #### Common List Patterns
366
+
367
+ **Settings List:**
368
+
369
+ ```tsx
370
+ <List.Root>
371
+ <List.Item>
372
+ <List.ItemSlot>
373
+ <View style={iconBoxStyle}>
374
+ <Icon as={Bell} size={20} color={colors.palettes.blue.a11} />
375
+ </View>
376
+ </List.ItemSlot>
377
+ <List.ItemContent>
378
+ <List.ItemTitle>Notifications</List.ItemTitle>
379
+ </List.ItemContent>
380
+ <List.ItemSlot>
381
+ <Switch checked={enabled} onCheckedChange={setEnabled} />
382
+ </List.ItemSlot>
383
+ </List.Item>
384
+ </List.Root>
385
+ ```
386
+
387
+ **Contact List with Avatars:**
388
+
389
+ ```tsx
390
+ <List.Root>
391
+ <List.Item onPress={() => {}}>
392
+ <List.ItemSlot>
393
+ <Avatar fallback="AK" size="3" color="blue" />
394
+ </List.ItemSlot>
395
+ <List.ItemContent>
396
+ <List.ItemTitle>Alex Kim</List.ItemTitle>
397
+ <List.ItemDescription>alex@example.com</List.ItemDescription>
398
+ </List.ItemContent>
399
+ <List.ItemSlot>
400
+ <Badge color="success" size="1">
401
+ <Text>Online</Text>
402
+ </Badge>
403
+ </List.ItemSlot>
404
+ </List.Item>
405
+ </List.Root>
406
+ ```
407
+
408
+ **With RadioGroup (Shipping Options):**
409
+
410
+ ```tsx
411
+ <RadioGroup.Root value={selected} onValueChange={setSelected}>
412
+ <List.Root>
413
+ <List.Item onPress={() => setSelected('standard')}>
414
+ <List.ItemSlot>
415
+ <RadioGroup.Item value="standard" />
416
+ </List.ItemSlot>
417
+ <List.ItemContent>
418
+ <List.ItemTitle>Standard Shipping</List.ItemTitle>
419
+ <List.ItemDescription>5-7 business days</List.ItemDescription>
420
+ </List.ItemContent>
421
+ <List.ItemSlot>
422
+ <Text weight="medium" color="success">
423
+ Free
424
+ </Text>
425
+ </List.ItemSlot>
426
+ </List.Item>
427
+ </List.Root>
428
+ </RadioGroup.Root>
429
+ ```
430
+
431
+ ---
432
+
433
+ ### Separator
434
+
435
+ Visual divider between content.
436
+
437
+ ```tsx
438
+ <Separator size="4" orientation="horizontal" />
439
+ ```
440
+
441
+ | Prop | Type | Default | Description |
442
+ | ------------- | ---------------------------- | -------------- | ------------------------------- |
443
+ | `size` | `'1' \| '2' \| '3' \| '4'` | `'1'` | Length (16px, 32px, 64px, 100%) |
444
+ | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Direction |
445
+ | `color` | `Color` | `'gray'` | Separator color |
446
+
447
+ ---
448
+
449
+ ### Checkbox
450
+
451
+ Controlled checkbox input.
452
+
453
+ ```tsx
454
+ <Checkbox checked={isChecked} onCheckedChange={setIsChecked} size="2" color="accent" />
455
+ ```
456
+
457
+ | Prop | Type | Default | Description |
458
+ | ----------------- | ---------------------------- | ---------- | ------------------------ |
459
+ | `checked` | `boolean` | — | Controlled checked state |
460
+ | `onCheckedChange` | `(checked: boolean) => void` | — | Change handler |
461
+ | `size` | `'1' \| '2' \| '3'` | `'2'` | Checkbox size |
462
+ | `color` | `Color` | `'accent'` | Checked color |
463
+ | `disabled` | `boolean` | `false` | Disabled state |
464
+
465
+ ---
466
+
467
+ ### Switch
468
+
469
+ Toggle switch input.
470
+
471
+ ```tsx
472
+ <Switch checked={isEnabled} onCheckedChange={setIsEnabled} size="2" color="accent" />
473
+ ```
474
+
475
+ | Prop | Type | Default | Description |
476
+ | ----------------- | ---------------------------- | ---------- | ------------------------ |
477
+ | `checked` | `boolean` | — | Controlled checked state |
478
+ | `onCheckedChange` | `(checked: boolean) => void` | — | Change handler |
479
+ | `size` | `'1' \| '2' \| '3'` | `'2'` | Switch size |
480
+ | `color` | `Color` | `'accent'` | Active color |
481
+ | `disabled` | `boolean` | `false` | Disabled state |
482
+
483
+ ---
484
+
485
+ ### Progress
486
+
487
+ Progress bar indicator.
488
+
489
+ ```tsx
490
+ <Progress value={75} max={100} size="2" color="accent" />
491
+ ```
492
+
493
+ | Prop | Type | Default | Description |
494
+ | ------- | --------- | ---------- | ------------------------ |
495
+ | `value` | `number` | `0` | Current progress |
496
+ | `max` | `number` | `100` | Maximum value |
497
+ | `size` | `'1'-'6'` | `'6'` | Bar height (2px to 16px) |
498
+ | `color` | `Color` | `'accent'` | Fill color |
499
+
500
+ ---
501
+
502
+ ### Spinner
503
+
504
+ Loading indicator.
505
+
506
+ ```tsx
507
+ <Spinner size="2" />;
508
+
509
+ {
510
+ /* Or wrap content to show spinner while loading */
511
+ }
512
+ <Spinner loading={isLoading}>
513
+ <Text>Content</Text>
514
+ </Spinner>;
515
+ ```
516
+
517
+ | Prop | Type | Default | Description |
518
+ | ---------- | ----------- | ------- | ----------------------------- |
519
+ | `size` | `'1'-'6'` | `'2'` | Spinner size |
520
+ | `loading` | `boolean` | `true` | Show spinner |
521
+ | `children` | `ReactNode` | — | Content to hide while loading |
522
+
523
+ ---
524
+
525
+ ### Tooltip
526
+
527
+ Hover/press tooltip.
528
+
529
+ ```tsx
530
+ <Tooltip content="Helpful information">
531
+ <Button>
532
+ <Text>Hover me</Text>
533
+ </Button>
534
+ </Tooltip>
535
+ ```
536
+
537
+ | Prop | Type | Default | Description |
538
+ | --------------- | ---------------------------------------- | -------- | ------------------------- |
539
+ | `content` | `ReactNode` | required | Tooltip content |
540
+ | `delayDuration` | `number` | `400` | Delay before showing (ms) |
541
+ | `side` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'top'` | Position |
542
+ | `sideOffset` | `number` | `4` | Offset from trigger |
543
+
544
+ ---
545
+
546
+ ### AspectRatio
547
+
548
+ Maintains aspect ratio for child content.
549
+
550
+ ```tsx
551
+ <AspectRatio ratio={16 / 9}>
552
+ <Image source={{ uri: '...' }} style={{ width: '100%', height: '100%' }} />
553
+ </AspectRatio>
554
+ ```
555
+
556
+ ---
557
+
558
+ ## Compound Components
559
+
560
+ ### TextField
561
+
562
+ Text input with optional slots for icons/buttons.
563
+
564
+ ```tsx
565
+ {
566
+ /* Simple usage */
567
+ }
568
+ <TextField.Input placeholder="Enter text..." />;
569
+
570
+ {
571
+ /* With slots */
572
+ }
573
+ <TextField.Root variant="surface">
574
+ <TextField.Slot>
575
+ <Icon as={Search} size={16} />
576
+ </TextField.Slot>
577
+ <TextField.Input placeholder="Search..." />
578
+ <TextField.Slot>
579
+ <IconButton variant="ghost" size="1">
580
+ <Icon as={X} size={14} />
581
+ </IconButton>
582
+ </TextField.Slot>
583
+ </TextField.Root>;
584
+ ```
585
+
586
+ **TextField.Root Props:**
587
+ | Prop | Type | Default |
588
+ |------|------|---------|
589
+ | `size` | `'1' \| '2' \| '3' \| '4'` | `'3'` |
590
+ | `variant` | `'surface' \| 'soft'` | `'surface'` |
591
+ | `color` | `Color` | — |
592
+ | `disabled` | `boolean` | `false` |
593
+
594
+ **TextField.Input**: Accepts all React Native `TextInput` props.
595
+
596
+ ---
597
+
598
+ ### TextArea
599
+
600
+ Multi-line text input.
601
+
602
+ ```tsx
603
+ <TextArea placeholder="Write a message..." />
604
+ ```
605
+
606
+ | Prop | Type | Default |
607
+ | --------- | -------------------------- | ----------- |
608
+ | `size` | `'1' \| '2' \| '3' \| '4'` | `'3'` |
609
+ | `variant` | `'surface' \| 'soft'` | `'surface'` |
610
+ | `color` | `Color` | — |
611
+
612
+ ---
613
+
614
+ ### Select
615
+
616
+ Dropdown selection.
617
+
618
+ ```tsx
619
+ <Select.Root value={value} onValueChange={setValue}>
620
+ <Select.Trigger>
621
+ <Select.Value placeholder="Choose option..." />
622
+ </Select.Trigger>
623
+ <Select.Content>
624
+ <Select.Item value="option1" label="Option 1">
625
+ Option 1
626
+ </Select.Item>
627
+ <Select.Item value="option2" label="Option 2">
628
+ Option 2
629
+ </Select.Item>
630
+ <Select.Separator />
631
+ <Select.Group>
632
+ <Select.Label>More Options</Select.Label>
633
+ <Select.Item value="option3" label="Option 3">
634
+ Option 3
635
+ </Select.Item>
636
+ </Select.Group>
637
+ </Select.Content>
638
+ </Select.Root>
639
+ ```
640
+
641
+ > **Note**: `Select.Item` children should be plain text, not wrapped in `<Text>`. The component handles text styling internally.
642
+
643
+ **Select.Root Props:**
644
+ | Prop | Type | Default |
645
+ |------|------|---------|
646
+ | `size` | `'1' \| '2' \| '3' \| '4'` | `'3'` |
647
+ | `value` | `{ value: string; label: string }` | — |
648
+ | `onValueChange` | `(value) => void` | — |
649
+
650
+ **Select.Trigger Props:**
651
+ | Prop | Type | Default |
652
+ |------|------|---------|
653
+ | `variant` | `'surface' \| 'soft' \| 'ghost'` | `'surface'` |
654
+ | `color` | `Color` | — |
655
+
656
+ **Select.Content Props:**
657
+ | Prop | Type | Default |
658
+ |------|------|---------|
659
+ | `align` | `'start' \| 'center' \| 'end'` | `'start'` |
660
+
661
+ **Select.Item Props:**
662
+ | Prop | Type | Required |
663
+ |------|------|----------|
664
+ | `value` | `string` | Yes |
665
+ | `label` | `string` | Yes |
666
+ | `children` | `string` (plain text) | Yes |
667
+
668
+ > **Tip**: Use `align="end"` when the trigger is on the right side of the screen, `align="start"` when on the left.
669
+
670
+ ---
671
+
672
+ ### RadioGroup
673
+
674
+ Radio button group.
675
+
676
+ ```tsx
677
+ <RadioGroup.Root value={selected} onValueChange={setSelected}>
678
+ <View style={{ gap: 8 }}>
679
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
680
+ <RadioGroup.Item value="option1" />
681
+ <Text>Option 1</Text>
682
+ </View>
683
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
684
+ <RadioGroup.Item value="option2" />
685
+ <Text>Option 2</Text>
686
+ </View>
687
+ </View>
688
+ </RadioGroup.Root>
689
+ ```
690
+
691
+ **RadioGroup.Root Props:**
692
+ | Prop | Type | Default |
693
+ |------|------|---------|
694
+ | `value` | `string` | — |
695
+ | `onValueChange` | `(value: string) => void` | — |
696
+ | `size` | `'1' \| '2' \| '3'` | `'2'` |
697
+ | `color` | `Color` | `'accent'` |
698
+
699
+ ---
700
+
701
+ ### Dialog
702
+
703
+ Modal dialog.
704
+
705
+ ```tsx
706
+ <Dialog.Root open={isOpen} onOpenChange={setIsOpen}>
707
+ <Dialog.Trigger>
708
+ <Button>
709
+ <Text>Open Dialog</Text>
710
+ </Button>
711
+ </Dialog.Trigger>
712
+ <Dialog.Content size="3">
713
+ <Dialog.Title>Dialog Title</Dialog.Title>
714
+ <Dialog.Description>This is a description of the dialog.</Dialog.Description>
715
+
716
+ {/* Your content here */}
717
+
718
+ <View style={{ flexDirection: 'row', gap: 8, justifyContent: 'flex-end' }}>
719
+ <Dialog.Close>
720
+ <Button variant="soft" color="gray">
721
+ <Text>Cancel</Text>
722
+ </Button>
723
+ </Dialog.Close>
724
+ <Dialog.Close>
725
+ <Button variant="solid">
726
+ <Text>Confirm</Text>
727
+ </Button>
728
+ </Dialog.Close>
729
+ </View>
730
+ </Dialog.Content>
731
+ </Dialog.Root>
732
+ ```
733
+
734
+ **Dialog.Content Props:**
735
+ | Prop | Type | Default |
736
+ |------|------|---------|
737
+ | `size` | `'1' \| '2' \| '3' \| '4'` | `'3'` |
738
+
739
+ ---
740
+
741
+ ### AlertDialog
742
+
743
+ Confirmation dialog with action/cancel pattern.
744
+
745
+ ```tsx
746
+ <AlertDialog.Root>
747
+ <AlertDialog.Trigger>
748
+ <Button color="danger">
749
+ <Text>Delete</Text>
750
+ </Button>
751
+ </AlertDialog.Trigger>
752
+ <AlertDialog.Content>
753
+ <AlertDialog.Header>
754
+ <AlertDialog.Title>Delete Item</AlertDialog.Title>
755
+ <AlertDialog.Description>This action cannot be undone.</AlertDialog.Description>
756
+ </AlertDialog.Header>
757
+ <AlertDialog.Footer>
758
+ <AlertDialog.Cancel>
759
+ <Button variant="soft" color="gray">
760
+ <Text>Cancel</Text>
761
+ </Button>
762
+ </AlertDialog.Cancel>
763
+ <AlertDialog.Action>
764
+ <Button variant="solid" color="danger">
765
+ <Text>Delete</Text>
766
+ </Button>
767
+ </AlertDialog.Action>
768
+ </AlertDialog.Footer>
769
+ </AlertDialog.Content>
770
+ </AlertDialog.Root>
771
+ ```
772
+
773
+ ---
774
+
775
+ ### Popover
776
+
777
+ Floating content panel.
778
+
779
+ ```tsx
780
+ <Popover.Root>
781
+ <Popover.Trigger>
782
+ <Button>
783
+ <Text>Open Popover</Text>
784
+ </Button>
785
+ </Popover.Trigger>
786
+ <Popover.Content align="start">
787
+ <View style={{ padding: 16 }}>
788
+ <Text>Popover content</Text>
789
+ </View>
790
+ </Popover.Content>
791
+ </Popover.Root>
792
+ ```
793
+
794
+ **Popover.Content Props:**
795
+ | Prop | Type | Default |
796
+ |------|------|---------|
797
+ | `align` | `'start' \| 'center' \| 'end'` | `'center'` |
798
+
799
+ > **Tip**: Use `align="end"` when trigger is on the right, `align="start"` when on the left.
800
+
801
+ ---
802
+
803
+ ### DropdownMenu
804
+
805
+ Menu triggered by button press.
806
+
807
+ ```tsx
808
+ <DropdownMenu.Root>
809
+ <DropdownMenu.Trigger>
810
+ <Button>
811
+ <Text>Actions</Text>
812
+ </Button>
813
+ </DropdownMenu.Trigger>
814
+ <DropdownMenu.Content align="end">
815
+ <DropdownMenu.Item onSelect={() => handleEdit()}>Edit</DropdownMenu.Item>
816
+ <DropdownMenu.Item onSelect={() => handleDuplicate()}>Duplicate</DropdownMenu.Item>
817
+ <DropdownMenu.Separator />
818
+ <DropdownMenu.Item onSelect={() => handleDelete()} color="danger">
819
+ Delete
820
+ </DropdownMenu.Item>
821
+ </DropdownMenu.Content>
822
+ </DropdownMenu.Root>
823
+ ```
824
+
825
+ > **Note**: `DropdownMenu.Item` children should be plain text, not wrapped in `<Text>`. The component handles text styling internally.
826
+
827
+ **DropdownMenu.Content Props:**
828
+ | Prop | Type | Default |
829
+ |------|------|---------|
830
+ | `align` | `'start' \| 'center' \| 'end'` | `'start'` |
831
+
832
+ > **Tip**: Use `align="end"` when trigger is on the right, `align="start"` when on the left.
833
+
834
+ ---
835
+
836
+ ### ContextMenu
837
+
838
+ Long-press menu (mobile) or right-click menu (web).
839
+
840
+ ```tsx
841
+ <ContextMenu.Root>
842
+ <ContextMenu.Trigger>
843
+ <Card>
844
+ <Text>Long press me</Text>
845
+ </Card>
846
+ </ContextMenu.Trigger>
847
+ <ContextMenu.Content>
848
+ <ContextMenu.Item onSelect={() => handleAction()}>Action</ContextMenu.Item>
849
+ </ContextMenu.Content>
850
+ </ContextMenu.Root>
851
+ ```
852
+
853
+ > **Note**: `ContextMenu.Item` children should be plain text, not wrapped in `<Text>`. The component handles text styling internally.
854
+
855
+ ---
856
+
857
+ ### Tabs
858
+
859
+ Tabbed content panels.
860
+
861
+ ```tsx
862
+ <Tabs.Root value={activeTab} onValueChange={setActiveTab}>
863
+ <Tabs.List>
864
+ <Tabs.Trigger value="tab1">Tab 1</Tabs.Trigger>
865
+ <Tabs.Trigger value="tab2">Tab 2</Tabs.Trigger>
866
+ </Tabs.List>
867
+ <Tabs.Content value="tab1">
868
+ <Text>Content for tab 1</Text>
869
+ </Tabs.Content>
870
+ <Tabs.Content value="tab2">
871
+ <Text>Content for tab 2</Text>
872
+ </Tabs.Content>
873
+ </Tabs.Root>
874
+ ```
875
+
876
+ > **Note**: `Tabs.Trigger` auto-wraps string children in `<Text>`. You can pass plain strings or `<Text>` components.
877
+
878
+ **Tabs.Root Props:**
879
+ | Prop | Type | Default |
880
+ |------|------|---------|
881
+ | `value` | `string` | — |
882
+ | `onValueChange` | `(value: string) => void` | — |
883
+ | `size` | `'1' \| '2'` | `'2'` |
884
+ | `color` | `Color` | `'accent'` |
885
+
886
+ ---
887
+
888
+ ### SegmentedControl
889
+
890
+ Segmented selection control.
891
+
892
+ ```tsx
893
+ <SegmentedControl.Root value={view} onValueChange={setView}>
894
+ <SegmentedControl.List>
895
+ <SegmentedControl.Trigger value="list">List</SegmentedControl.Trigger>
896
+ <SegmentedControl.Trigger value="grid">Grid</SegmentedControl.Trigger>
897
+ </SegmentedControl.List>
898
+ </SegmentedControl.Root>
899
+ ```
900
+
901
+ > **Note**: `SegmentedControl.Trigger` auto-wraps string children in `<Text>`. You can pass plain strings or `<Text>` components.
902
+
903
+ ---
904
+
905
+ ### Accordion
906
+
907
+ Collapsible content sections.
908
+
909
+ ```tsx
910
+ <Accordion.Root type="single" collapsible>
911
+ <Accordion.Item value="item1">
912
+ <Accordion.Trigger>Section 1</Accordion.Trigger>
913
+ <Accordion.Content>
914
+ <Text>Content for section 1</Text>
915
+ </Accordion.Content>
916
+ </Accordion.Item>
917
+ <Accordion.Item value="item2">
918
+ <Accordion.Trigger>Section 2</Accordion.Trigger>
919
+ <Accordion.Content>
920
+ <Text>Content for section 2</Text>
921
+ </Accordion.Content>
922
+ </Accordion.Item>
923
+ </Accordion.Root>
924
+ ```
925
+
926
+ > **Note**: `Accordion.Trigger` internally wraps children in `<Text>`. Pass plain strings, not `<Text>` components.
927
+
928
+ ---
929
+
930
+ ### Callout
931
+
932
+ Highlighted message box.
933
+
934
+ ```tsx
935
+ import { Info } from 'lucide-react-native';
936
+
937
+ <Callout.Root variant="soft" color="info">
938
+ <Callout.Icon>
939
+ <Icon as={Info} size={16} />
940
+ </Callout.Icon>
941
+ <Callout.Text>
942
+ <Text>This is an informational message.</Text>
943
+ </Callout.Text>
944
+ </Callout.Root>;
945
+ ```
946
+
947
+ **Callout.Root Props:**
948
+ | Prop | Type | Default |
949
+ |------|------|---------|
950
+ | `variant` | `'soft' \| 'surface' \| 'outline'` | `'soft'` |
951
+ | `size` | `'1' \| '2' \| '3'` | `'2'` |
952
+ | `color` | `Color` | `'accent'` |
953
+
954
+ ---
955
+
956
+ ### Skeleton
957
+
958
+ Loading placeholder that matches actual component dimensions.
959
+
960
+ **Skeleton.Avatar** — Uses the same `size` and `shape` props as `<Avatar>`. The skeleton will have identical dimensions to a real avatar.
961
+
962
+ ```tsx
963
+ {/* These have identical dimensions */}
964
+ <Avatar fallback="JD" size="3" shape="circle" />
965
+ <Skeleton.Avatar size="3" shape="circle" />
966
+ ```
967
+
968
+ **Skeleton.Text** — Uses the same `size` scale as `<Text>` and `<Heading>`. The skeleton height matches the text's `lineHeight`, and the inner bar matches the `fontSize`.
969
+
970
+ ```tsx
971
+ {/* These align perfectly when swapped */}
972
+ <Text size="2">Loading complete</Text>
973
+ <Skeleton.Text size="2" />
974
+
975
+ {/* Match a Heading */}
976
+ <Heading size="6">Page Title</Heading>
977
+ <Skeleton.Text size="6" />
978
+ ```
979
+
980
+ **Skeleton.Rect** — For custom shapes. Define dimensions via `style`.
981
+
982
+ ```tsx
983
+ <Skeleton.Rect style={{ width: 200, height: 100, borderRadius: 8 }} />
984
+ ```
985
+
986
+ | Component | Props | Matches |
987
+ | ----------------- | --------------------------- | ---------------------------------- |
988
+ | `Skeleton.Avatar` | `size` (`'0'-'9'`), `shape` | `<Avatar>` dimensions exactly |
989
+ | `Skeleton.Text` | `size` (`'0'-'9'`) | `<Text>` / `<Heading>` line height |
990
+ | `Skeleton.Rect` | `style` | Custom dimensions |
991
+
992
+ ---
993
+
994
+ ### HoverCard
995
+
996
+ Card shown on hover (web) or press (mobile).
997
+
998
+ ```tsx
999
+ <HoverCard.Root>
1000
+ <HoverCard.Trigger>
1001
+ <Text>@username</Text>
1002
+ </HoverCard.Trigger>
1003
+ <HoverCard.Content>
1004
+ <View style={{ padding: 16 }}>
1005
+ <Avatar fallback="U" />
1006
+ <Text>User profile info</Text>
1007
+ </View>
1008
+ </HoverCard.Content>
1009
+ </HoverCard.Root>
1010
+ ```
1011
+
1012
+ ---
1013
+
1014
+ ## Quick Reference: Sizes
1015
+
1016
+ | Component | Sizes Available |
1017
+ | ---------------------------- | -------------------------- |
1018
+ | Button, IconButton | `'1'`, `'2'`, `'3'`, `'4'` |
1019
+ | Badge | `'1'`, `'2'` |
1020
+ | Avatar | `'0'` - `'9'` |
1021
+ | Checkbox, Switch, RadioGroup | `'1'`, `'2'`, `'3'` |
1022
+ | TextField, TextArea, Select | `'1'`, `'2'`, `'3'`, `'4'` |
1023
+ | Progress, Spinner | `'1'` - `'6'` |
1024
+ | Tabs | `'1'`, `'2'` |
1025
+ | Callout | `'1'`, `'2'`, `'3'` |
1026
+ | Dialog | `'1'`, `'2'`, `'3'`, `'4'` |
1027
+
1028
+ ---
1029
+
1030
+ ## Size Dimensions (pixels)
1031
+
1032
+ Use this table to choose the right size for your layout.
1033
+
1034
+ ### Button / IconButton / Select / TextField
1035
+
1036
+ All share the same height scale. IconButton is square (width = height).
1037
+
1038
+ | Size | Height | Use Case |
1039
+ | ----- | ------ | -------------------------------------------------- |
1040
+ | `'1'` | 24px | Compact UI, inline actions, table rows |
1041
+ | `'2'` | 32px | Smaller forms, secondary areas |
1042
+ | `'3'` | 40px | **Default** — mobile-first, touch-friendly |
1043
+ | `'4'` | 48px | Hero CTAs, buy buttons, prominent conversion flows |
1044
+
1045
+ ### Badge
1046
+
1047
+ | Size | Height | Use Case |
1048
+ | ----- | ------ | -------------------------------------- |
1049
+ | `'1'` | 20px | **Default** — inline status indicators |
1050
+ | `'2'` | 28px | Emphasized badges, standalone labels |
1051
+
1052
+ ### Avatar
1053
+
1054
+ | Size | Dimensions | Use Case |
1055
+ | ----- | ---------- | -------------------------------------- |
1056
+ | `'0'` | 16×16px | Tiny indicators |
1057
+ | `'1'` | 24×24px | Inline mentions, compact lists |
1058
+ | `'2'` | 32×32px | List items, comments |
1059
+ | `'3'` | 40×40px | **Default** — standard profile display |
1060
+ | `'4'` | 48×48px | Card headers, user info |
1061
+ | `'5'` | 64×64px | Profile sections |
1062
+ | `'6'` | 80×80px | Profile pages |
1063
+ | `'7'` | 96×96px | Large profile display |
1064
+ | `'8'` | 128×128px | Hero profile |
1065
+ | `'9'` | 160×160px | Full profile page |
1066
+
1067
+ ### Checkbox / RadioGroup
1068
+
1069
+ | Size | Dimensions | Use Case |
1070
+ | ----- | ---------- | ----------------------------- |
1071
+ | `'1'` | 16×16px | Compact forms, dense lists |
1072
+ | `'2'` | 20×20px | **Default** — standard forms |
1073
+ | `'3'` | 24×24px | Touch-friendly, accessibility |
1074
+
1075
+ ### Switch
1076
+
1077
+ | Size | Dimensions (W×H) | Use Case |
1078
+ | ----- | ---------------- | --------------------------------- |
1079
+ | `'1'` | 28×16px | Compact settings |
1080
+ | `'2'` | 42×24px | **Default** — standard toggles |
1081
+ | `'3'` | 56×32px | Touch-friendly, prominent toggles |
1082
+
1083
+ ### Spinner
1084
+
1085
+ | Size | Dimensions | Use Case |
1086
+ | ----- | ---------- | ----------------------------- |
1087
+ | `'1'` | 12×12px | Inline loading indicators |
1088
+ | `'2'` | 16×16px | **Default** — button spinners |
1089
+ | `'3'` | 20×20px | Small loading states |
1090
+ | `'4'` | 24×24px | Card loading |
1091
+ | `'5'` | 32×32px | Section loading |
1092
+ | `'6'` | 40×40px | Page loading |
1093
+
1094
+ ---
1095
+
1096
+ ## Common Patterns
1097
+
1098
+ ### Form with Label
1099
+
1100
+ ```tsx
1101
+ <View style={{ gap: 8 }}>
1102
+ <Label nativeID="email">Email</Label>
1103
+ <TextField.Input
1104
+ placeholder="you@example.com"
1105
+ aria-labelledby="email"
1106
+ keyboardType="email-address"
1107
+ />
1108
+ </View>
1109
+ ```
1110
+
1111
+ ### Button with Icon
1112
+
1113
+ ```tsx
1114
+ <Button>
1115
+ <Icon as={Plus} size={16} />
1116
+ <Text>Add Item</Text>
1117
+ </Button>
1118
+ ```
1119
+
1120
+ ### Loading State
1121
+
1122
+ ```tsx
1123
+ <Button disabled={isLoading}>
1124
+ <Spinner loading={isLoading} size="1">
1125
+ <Text>Submit</Text>
1126
+ </Spinner>
1127
+ </Button>
1128
+ ```
1129
+
1130
+ ### List Item with Avatar
1131
+
1132
+ ```tsx
1133
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 12 }}>
1134
+ <Avatar fallback="JD" size="2" />
1135
+ <View style={{ flex: 1 }}>
1136
+ <Text weight="medium">John Doe</Text>
1137
+ <Text size="1" color="gray">
1138
+ john@example.com
1139
+ </Text>
1140
+ </View>
1141
+ <Badge color="success">
1142
+ <Text>Active</Text>
1143
+ </Badge>
1144
+ </View>
1145
+ ```
1146
+
1147
+ ---
1148
+
1149
+ ## Do's and Don'ts
1150
+
1151
+ ### ✅ Do
1152
+
1153
+ ```tsx
1154
+ // Use Text inside Button (auto-styled)
1155
+ <Button>
1156
+ <Text>Click me</Text>
1157
+ </Button>
1158
+
1159
+ // Use compound component pattern correctly
1160
+ <TextField.Root>
1161
+ <TextField.Input placeholder="..." />
1162
+ </TextField.Root>
1163
+
1164
+ // Use semantic colors
1165
+ <Button color="danger">
1166
+ <Text>Delete</Text>
1167
+ </Button>
1168
+ ```
1169
+
1170
+ ### ❌ Don't
1171
+
1172
+ ```tsx
1173
+ // Don't use raw strings in Button
1174
+ <Button>Click me</Button>;
1175
+
1176
+ // Don't import TextInput from react-native
1177
+ import { TextInput } from 'react-native';
1178
+
1179
+ // Don't manually style Text inside components
1180
+ <Button>
1181
+ <Text style={{ color: 'white' }}>Click</Text>
1182
+ </Button>;
1183
+ ```