@compsych/mobile-ui 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1015 -0
- package/package.json +26 -0
- package/src/Alert.tsx +372 -0
- package/src/Avatar.tsx +255 -0
- package/src/Badge.tsx +189 -0
- package/src/BodyText.tsx +62 -0
- package/src/Breadcrumb.tsx +192 -0
- package/src/Button.tsx +228 -0
- package/src/Card.tsx +152 -0
- package/src/Checkbox.tsx +182 -0
- package/src/Chip.tsx +291 -0
- package/src/Divider.tsx +60 -0
- package/src/EmptyState.tsx +364 -0
- package/src/HeaderText.tsx +69 -0
- package/src/Input.tsx +228 -0
- package/src/Pagination.tsx +353 -0
- package/src/ProgressTracker.tsx +160 -0
- package/src/RadioButton.tsx +177 -0
- package/src/Slider.tsx +347 -0
- package/src/Switch.tsx +183 -0
- package/src/Tooltip.tsx +214 -0
- package/src/index.ts +62 -0
- package/src/tokens.ts +121 -0
package/README.md
ADDED
|
@@ -0,0 +1,1015 @@
|
|
|
1
|
+
# ComPsych Design System — React Native
|
|
2
|
+
|
|
3
|
+
A React Native component library built directly from the ComPsych Figma Design System, using the four-tier token architecture. All 17 components are pixel-accurate implementations synchronized with Figma.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Getting Started
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install
|
|
11
|
+
npx expo start
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Token System
|
|
17
|
+
|
|
18
|
+
All components consume `sys.*` tokens exclusively — never raw values.
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { sys } from '@/components/ds/tokens';
|
|
22
|
+
const { colorRoles: cr, dimensions: dim, typeScale: ts } = sys;
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Components
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
### Alert
|
|
32
|
+
|
|
33
|
+
`Version: 1.0.0`
|
|
34
|
+
|
|
35
|
+
Inline feedback banner for status, warnings, errors, and success messages. Supports a title, icon, action button, and dismiss control.
|
|
36
|
+
|
|
37
|
+

|
|
38
|
+
|
|
39
|
+
**Import**
|
|
40
|
+
```tsx
|
|
41
|
+
import { Alert } from '@/components/ds/Alert';
|
|
42
|
+
```
|
|
43
|
+
**Component File:** `components/ds/Alert.tsx`
|
|
44
|
+
|
|
45
|
+
#### Variants
|
|
46
|
+
|
|
47
|
+
There are six alert variants covering the full range of feedback contexts.
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
<Alert variant="informative" description="Tips, help, or guidance." />
|
|
51
|
+
<Alert variant="warning" description="Your session will expire in 5 minutes." />
|
|
52
|
+
<Alert variant="danger" description="Failed to save changes." />
|
|
53
|
+
<Alert variant="positive" description="Changes saved successfully." />
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
#### With Action
|
|
57
|
+
|
|
58
|
+
An optional action button prompts the user to take a next step.
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
<Alert
|
|
62
|
+
variant="informative"
|
|
63
|
+
title="New feature available"
|
|
64
|
+
description="Update the app to access the latest tools."
|
|
65
|
+
actionLabel="Update now"
|
|
66
|
+
onAction={handleUpdate}
|
|
67
|
+
/>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
#### Dismissible
|
|
71
|
+
|
|
72
|
+
Add a dismiss button by setting `dismissible` to `true`.
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
<Alert variant="danger" description="Failed to save." dismissible onDismiss={() => setVisible(false)} />
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Props**
|
|
79
|
+
|
|
80
|
+
| Name | Type | Default | Description |
|
|
81
|
+
|------|------|---------|-------------|
|
|
82
|
+
| `variant` | `'default' \| 'elevated' \| 'informative' \| 'warning' \| 'positive' \| 'danger'` | `'default'` | Color scheme and icon |
|
|
83
|
+
| `size` | `'sm' \| 'lg'` | `'lg'` | `lg` shows a bold title; `sm` is compact |
|
|
84
|
+
| `description` | `string` | — | **Required.** Body text |
|
|
85
|
+
| `title` | `string` | — | Bold heading (`lg` size only) |
|
|
86
|
+
| `hideIcon` | `boolean` | `false` | Removes the leading icon |
|
|
87
|
+
| `actionLabel` | `string` | — | Label for the optional action button |
|
|
88
|
+
| `onAction` | `() => void` | — | Action button handler |
|
|
89
|
+
| `dismissible` | `boolean` | `false` | Shows a × dismiss button |
|
|
90
|
+
| `onDismiss` | `() => void` | — | Dismiss button handler |
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
### Avatar
|
|
95
|
+
|
|
96
|
+
`Version: 1.0.0`
|
|
97
|
+
|
|
98
|
+
Circular user representation — text initials, photo, or icon. Supports a presence badge and activity ring.
|
|
99
|
+
|
|
100
|
+

|
|
101
|
+
|
|
102
|
+
**Import**
|
|
103
|
+
```tsx
|
|
104
|
+
import { Avatar } from '@/components/ds/Avatar';
|
|
105
|
+
```
|
|
106
|
+
**Component File:** `components/ds/Avatar.tsx`
|
|
107
|
+
|
|
108
|
+
#### Sizes
|
|
109
|
+
|
|
110
|
+
Avatar can be rendered in seven sizes from extra-small to triple-extra-large.
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
<Avatar variant="text" initials="CP" size="xs" />
|
|
114
|
+
<Avatar variant="text" initials="CP" size="md" />
|
|
115
|
+
<Avatar variant="text" initials="CP" size="xl" />
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### Image Avatar
|
|
119
|
+
|
|
120
|
+
Display a user's photo by providing an image source.
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
<Avatar variant="image" source={{ uri: 'https://example.com/photo.jpg' }} size="lg" activityRing />
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
#### Letter Avatar
|
|
127
|
+
|
|
128
|
+
Render up to two initials when no photo is available.
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
<Avatar variant="text" initials="JD" size="md" />
|
|
132
|
+
<Avatar variant="text" initials="AB" size="lg" />
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Props**
|
|
136
|
+
|
|
137
|
+
| Name | Type | Default | Description |
|
|
138
|
+
|------|------|---------|-------------|
|
|
139
|
+
| `variant` | `'text' \| 'image' \| 'icon'` | `'text'` | Content type |
|
|
140
|
+
| `size` | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| '3xl'` | `'md'` | Circle diameter |
|
|
141
|
+
| `initials` | `string` | — | Up to 2 characters (text variant) |
|
|
142
|
+
| `source` | `ImageSourcePropType` | — | Photo source (image variant) |
|
|
143
|
+
| `activityRing` | `boolean` | `false` | Renders a coloured ring around the circle |
|
|
144
|
+
| `presenceBadge` | `boolean` | `false` | Renders a shield-check badge at bottom-right |
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
### Badge
|
|
149
|
+
|
|
150
|
+
`Version: 1.0.0`
|
|
151
|
+
|
|
152
|
+
Small status indicator as a pill, dot, or count. Used on icons and list items to show notification states.
|
|
153
|
+
|
|
154
|
+

|
|
155
|
+
|
|
156
|
+
**Import**
|
|
157
|
+
```tsx
|
|
158
|
+
import { Badge } from '@/components/ds/Badge';
|
|
159
|
+
```
|
|
160
|
+
**Component File:** `components/ds/Badge.tsx`
|
|
161
|
+
|
|
162
|
+
#### Styles
|
|
163
|
+
|
|
164
|
+
Badge supports six visual styles covering neutral, semantic, and dot presentations.
|
|
165
|
+
|
|
166
|
+
```tsx
|
|
167
|
+
<Badge label={5} badgeStyle="filled" />
|
|
168
|
+
<Badge label="New" badgeStyle="positive" />
|
|
169
|
+
<Badge label="99+" badgeStyle="danger" />
|
|
170
|
+
<Badge label={3} badgeStyle="tonal" />
|
|
171
|
+
<Badge badgeStyle="dot" />
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
#### Sizes
|
|
175
|
+
|
|
176
|
+
Badge can be rendered in three sizes.
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
<Badge label={5} size="sm" />
|
|
180
|
+
<Badge label={5} size="md" />
|
|
181
|
+
<Badge label={5} size="lg" />
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Props**
|
|
185
|
+
|
|
186
|
+
| Name | Type | Default | Description |
|
|
187
|
+
|------|------|---------|-------------|
|
|
188
|
+
| `label` | `number \| string` | — | Text or count inside the badge |
|
|
189
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Controls diameter and font size |
|
|
190
|
+
| `badgeStyle` | `'filled' \| 'positive' \| 'danger' \| 'elevated' \| 'tonal' \| 'dot'` | `'filled'` | Color scheme and shape |
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
### Breadcrumb
|
|
195
|
+
|
|
196
|
+
`Version: 1.0.0`
|
|
197
|
+
|
|
198
|
+
Horizontal scrollable navigation trail with `/` dividers. The last item always renders as the current page.
|
|
199
|
+
|
|
200
|
+

|
|
201
|
+
|
|
202
|
+
**Import**
|
|
203
|
+
```tsx
|
|
204
|
+
import { Breadcrumb } from '@/components/ds/Breadcrumb';
|
|
205
|
+
```
|
|
206
|
+
**Component File:** `components/ds/Breadcrumb.tsx`
|
|
207
|
+
|
|
208
|
+
#### Basic
|
|
209
|
+
|
|
210
|
+
Provide an ordered array of items. The last item is always treated as the current page.
|
|
211
|
+
|
|
212
|
+
```tsx
|
|
213
|
+
<Breadcrumb
|
|
214
|
+
items={[
|
|
215
|
+
{ isHome: true, onPress: goHome },
|
|
216
|
+
{ label: 'Settings', onPress: goSettings },
|
|
217
|
+
{ label: 'Profile' },
|
|
218
|
+
]}
|
|
219
|
+
/>
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
#### With Overflow
|
|
223
|
+
|
|
224
|
+
Use `isOverflow: true` to collapse middle crumbs into an ellipsis.
|
|
225
|
+
|
|
226
|
+
```tsx
|
|
227
|
+
<Breadcrumb
|
|
228
|
+
items={[
|
|
229
|
+
{ isHome: true, onPress: goHome },
|
|
230
|
+
{ isOverflow: true, onPress: expandCrumbs },
|
|
231
|
+
{ label: 'Current Page' },
|
|
232
|
+
]}
|
|
233
|
+
/>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
**Props**
|
|
237
|
+
|
|
238
|
+
| Name | Type | Default | Description |
|
|
239
|
+
|------|------|---------|-------------|
|
|
240
|
+
| `items` | `BreadcrumbItem[]` | — | **Required.** Ordered crumb items |
|
|
241
|
+
| `size` | `'sm' \| 'lg'` | `'lg'` | Font size and vertical padding |
|
|
242
|
+
|
|
243
|
+
**BreadcrumbItem**
|
|
244
|
+
|
|
245
|
+
| Field | Type | Description |
|
|
246
|
+
|-------|------|-------------|
|
|
247
|
+
| `label` | `string` | Display text |
|
|
248
|
+
| `isHome` | `boolean` | Renders the home icon instead of text |
|
|
249
|
+
| `isOverflow` | `boolean` | Renders `…` for collapsed middle crumbs |
|
|
250
|
+
| `disabled` | `boolean` | Reduces opacity; non-interactive |
|
|
251
|
+
| `onPress` | `() => void` | Omit for the current/last crumb |
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
### Button
|
|
256
|
+
|
|
257
|
+
`Version: 1.0.0`
|
|
258
|
+
|
|
259
|
+
Buttons are touchable elements used to trigger actions. They support seven visual variants, four sizes, leading and trailing icons, a loading state, and full-width layout.
|
|
260
|
+
|
|
261
|
+

|
|
262
|
+
|
|
263
|
+
**Import**
|
|
264
|
+
```tsx
|
|
265
|
+
import { Button } from '@/components/ds/Button';
|
|
266
|
+
```
|
|
267
|
+
**Component File:** `components/ds/Button.tsx`
|
|
268
|
+
|
|
269
|
+
#### Variants
|
|
270
|
+
|
|
271
|
+
There are solid, outline, text, tonal, elevated, danger, and danger-outlined button types.
|
|
272
|
+
|
|
273
|
+
```tsx
|
|
274
|
+
<Button label="Filled" variant="filled" onPress={handlePress} />
|
|
275
|
+
<Button label="Tonal" variant="tonal" onPress={handlePress} />
|
|
276
|
+
<Button label="Outlined" variant="outlined" onPress={handlePress} />
|
|
277
|
+
<Button label="Text" variant="text" onPress={handlePress} />
|
|
278
|
+
<Button label="Danger" variant="danger" onPress={handlePress} />
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
#### Size
|
|
282
|
+
|
|
283
|
+
Button can be small, medium, large, or extra-large.
|
|
284
|
+
|
|
285
|
+
```tsx
|
|
286
|
+
<Button label="Small" size="sm" onPress={handlePress} />
|
|
287
|
+
<Button label="Medium" size="md" onPress={handlePress} />
|
|
288
|
+
<Button label="Large" size="lg" onPress={handlePress} />
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
#### Disabled
|
|
292
|
+
|
|
293
|
+
Disabled buttons reduce opacity and ignore press interactions.
|
|
294
|
+
|
|
295
|
+
```tsx
|
|
296
|
+
<Button label="Filled" variant="filled" disabled />
|
|
297
|
+
<Button label="Outlined" variant="outlined" disabled />
|
|
298
|
+
<Button label="Text" variant="text" disabled />
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
#### Icon Button
|
|
302
|
+
|
|
303
|
+
Can contain a leading or trailing icon, or be rendered as a square icon-only button.
|
|
304
|
+
|
|
305
|
+
```tsx
|
|
306
|
+
<Button label="Delete" variant="danger" leadingIcon={<Ionicons name="trash-outline" size={16} />} onPress={handleDelete} />
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
#### Loading Spinner
|
|
310
|
+
|
|
311
|
+
Use the `loading` prop to replace the label with an activity indicator.
|
|
312
|
+
|
|
313
|
+
```tsx
|
|
314
|
+
<Button label="Saving…" loading />
|
|
315
|
+
<Button label="Saving…" loading variant="outlined" />
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**Props**
|
|
319
|
+
|
|
320
|
+
| Name | Type | Default | Description |
|
|
321
|
+
|------|------|---------|-------------|
|
|
322
|
+
| `label` | `string` | — | **Required.** Button text |
|
|
323
|
+
| `variant` | `'filled' \| 'tonal' \| 'outlined' \| 'elevated' \| 'text' \| 'danger' \| 'danger-outlined'` | `'filled'` | Visual style |
|
|
324
|
+
| `size` | `'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` | Height and padding |
|
|
325
|
+
| `disabled` | `boolean` | `false` | Disables interaction and reduces opacity |
|
|
326
|
+
| `loading` | `boolean` | `false` | Shows `ActivityIndicator` in place of label |
|
|
327
|
+
| `fullWidth` | `boolean` | `false` | Stretches to fill the parent |
|
|
328
|
+
| `iconOnly` | `boolean` | `false` | Square layout for single icons |
|
|
329
|
+
| `leadingIcon` | `React.ReactNode` | — | Icon before the label |
|
|
330
|
+
| `trailingIcon` | `React.ReactNode` | — | Icon after the label |
|
|
331
|
+
| `onPress` | `() => void` | — | Press handler |
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
### Card
|
|
336
|
+
|
|
337
|
+
`Version: 1.0.0`
|
|
338
|
+
|
|
339
|
+
Surface container for grouping related content. Supports three visual variants, four padding sizes, interactive press states, and a current/selected highlight.
|
|
340
|
+
|
|
341
|
+
**Import**
|
|
342
|
+
```tsx
|
|
343
|
+
import { Card } from '@/components/ds/Card';
|
|
344
|
+
```
|
|
345
|
+
**Component File:** `components/ds/Card.tsx`
|
|
346
|
+
|
|
347
|
+
#### Variants
|
|
348
|
+
|
|
349
|
+
There are outlined, filled, and gradient card types.
|
|
350
|
+
|
|
351
|
+
```tsx
|
|
352
|
+
<Card variant="outlined"><Text>Outlined card</Text></Card>
|
|
353
|
+
<Card variant="filled"><Text>Filled card</Text></Card>
|
|
354
|
+
<Card variant="gradient"><Text>Gradient card</Text></Card>
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
#### Interactive
|
|
358
|
+
|
|
359
|
+
Set `interactive` to enable press feedback and wrap the card in a `Pressable`.
|
|
360
|
+
|
|
361
|
+
```tsx
|
|
362
|
+
<Card interactive onPress={handleCardPress}><Text>Tap me</Text></Card>
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
#### Current State
|
|
366
|
+
|
|
367
|
+
The `current` prop applies a primary-colored border to indicate the selected card.
|
|
368
|
+
|
|
369
|
+
```tsx
|
|
370
|
+
<Card interactive current onPress={handlePress}><Text>Selected card</Text></Card>
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
**Props**
|
|
374
|
+
|
|
375
|
+
| Name | Type | Default | Description |
|
|
376
|
+
|------|------|---------|-------------|
|
|
377
|
+
| `variant` | `'outlined' \| 'filled' \| 'gradient'` | `'outlined'` | Visual treatment |
|
|
378
|
+
| `size` | `'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` | Inner padding |
|
|
379
|
+
| `interactive` | `boolean` | `false` | Enables press feedback |
|
|
380
|
+
| `disabled` | `boolean` | `false` | Reduces opacity |
|
|
381
|
+
| `current` | `boolean` | `false` | Primary border (selected state) |
|
|
382
|
+
| `fullWidth` | `boolean` | `false` | Fills parent width |
|
|
383
|
+
| `onPress` | `() => void` | — | Press handler (requires `interactive`) |
|
|
384
|
+
| `children` | `React.ReactNode` | — | Card content |
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
### Checkbox
|
|
389
|
+
|
|
390
|
+
`Version: 1.0.0`
|
|
391
|
+
|
|
392
|
+
Binary or indeterminate selection control. Supports controlled and uncontrolled usage.
|
|
393
|
+
|
|
394
|
+

|
|
395
|
+
|
|
396
|
+
**Import**
|
|
397
|
+
```tsx
|
|
398
|
+
import { Checkbox } from '@/components/ds/Checkbox';
|
|
399
|
+
```
|
|
400
|
+
**Component File:** `components/ds/Checkbox.tsx`
|
|
401
|
+
|
|
402
|
+
#### States
|
|
403
|
+
|
|
404
|
+
Checkbox can be unchecked, checked, indeterminate, or disabled.
|
|
405
|
+
|
|
406
|
+
```tsx
|
|
407
|
+
<Checkbox defaultChecked={false} onValueChange={console.log} />
|
|
408
|
+
<Checkbox defaultChecked={true} onValueChange={console.log} />
|
|
409
|
+
<Checkbox checked="indeterminate" onValueChange={handleChange} />
|
|
410
|
+
<Checkbox disabled />
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
#### Controlled
|
|
414
|
+
|
|
415
|
+
Use the `checked` prop with `onValueChange` for controlled usage.
|
|
416
|
+
|
|
417
|
+
```tsx
|
|
418
|
+
const [checked, setChecked] = useState(false);
|
|
419
|
+
<Checkbox checked={checked} onValueChange={setChecked} />
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
#### Sizes
|
|
423
|
+
|
|
424
|
+
Checkbox supports medium (default) and small sizes.
|
|
425
|
+
|
|
426
|
+
```tsx
|
|
427
|
+
<Checkbox size="md" defaultChecked />
|
|
428
|
+
<Checkbox size="sm" defaultChecked />
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
**Props**
|
|
432
|
+
|
|
433
|
+
| Name | Type | Default | Description |
|
|
434
|
+
|------|------|---------|-------------|
|
|
435
|
+
| `checked` | `boolean \| 'indeterminate'` | — | Controlled state |
|
|
436
|
+
| `defaultChecked` | `boolean` | `false` | Initial uncontrolled state |
|
|
437
|
+
| `onValueChange` | `(value: boolean \| 'indeterminate') => void` | — | Change handler |
|
|
438
|
+
| `size` | `'sm' \| 'md'` | `'md'` | Hit area and box size |
|
|
439
|
+
| `disabled` | `boolean` | `false` | Disables interaction |
|
|
440
|
+
| `accessibilityLabel` | `string` | — | Screen-reader label |
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
### Chip
|
|
445
|
+
|
|
446
|
+
`Version: 1.0.0`
|
|
447
|
+
|
|
448
|
+
Compact label pill for status, category, or filter display. Supports a leading icon, dismiss button, and badge count.
|
|
449
|
+
|
|
450
|
+

|
|
451
|
+
|
|
452
|
+
**Import**
|
|
453
|
+
```tsx
|
|
454
|
+
import { Chip } from '@/components/ds/Chip';
|
|
455
|
+
```
|
|
456
|
+
**Component File:** `components/ds/Chip.tsx`
|
|
457
|
+
|
|
458
|
+
#### Colors
|
|
459
|
+
|
|
460
|
+
Chip supports neutral, informative, positive, danger, and warning semantic colors.
|
|
461
|
+
|
|
462
|
+
```tsx
|
|
463
|
+
<Chip label="Neutral" usage="neutral" />
|
|
464
|
+
<Chip label="Info" usage="informative" />
|
|
465
|
+
<Chip label="Completed" usage="positive" />
|
|
466
|
+
<Chip label="Overdue" usage="danger" />
|
|
467
|
+
<Chip label="Pending" usage="warning" />
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
#### Sizes
|
|
471
|
+
|
|
472
|
+
Chip can be rendered in four sizes.
|
|
473
|
+
|
|
474
|
+
```tsx
|
|
475
|
+
<Chip label="Small" size="sm" />
|
|
476
|
+
<Chip label="Medium" size="md" />
|
|
477
|
+
<Chip label="Large" size="lg" />
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
#### Dismissible
|
|
481
|
+
|
|
482
|
+
Add a dismiss button at the trailing end using the `dismissible` prop.
|
|
483
|
+
|
|
484
|
+
```tsx
|
|
485
|
+
<Chip label="Filter" dismissible onDismiss={handleDismiss} />
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
**Props**
|
|
489
|
+
|
|
490
|
+
| Name | Type | Default | Description |
|
|
491
|
+
|------|------|---------|-------------|
|
|
492
|
+
| `label` | `string` | — | **Required.** Chip text |
|
|
493
|
+
| `size` | `'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` | Height and font |
|
|
494
|
+
| `usage` | `'neutral' \| 'informative' \| 'positive' \| 'danger' \| 'warning'` | `'neutral'` | Semantic color |
|
|
495
|
+
| `leadingIcon` | `React.ReactNode` | — | Icon before the label |
|
|
496
|
+
| `dismissible` | `boolean` | `false` | Shows a × button |
|
|
497
|
+
| `onDismiss` | `() => void` | — | Called when dismissed |
|
|
498
|
+
| `badge` | `number \| string` | — | Trailing count or label |
|
|
499
|
+
|
|
500
|
+
---
|
|
501
|
+
|
|
502
|
+
### Divider
|
|
503
|
+
|
|
504
|
+
`Version: 1.0.0`
|
|
505
|
+
|
|
506
|
+
Decorative separator — horizontal or vertical, thin or thick, solid or dashed.
|
|
507
|
+
|
|
508
|
+

|
|
509
|
+
|
|
510
|
+
**Import**
|
|
511
|
+
```tsx
|
|
512
|
+
import { Divider } from '@/components/ds/Divider';
|
|
513
|
+
```
|
|
514
|
+
**Component File:** `components/ds/Divider.tsx`
|
|
515
|
+
|
|
516
|
+
#### Horizontal
|
|
517
|
+
|
|
518
|
+
A horizontal divider stretches to fill its parent width and is the default orientation.
|
|
519
|
+
|
|
520
|
+
```tsx
|
|
521
|
+
<Divider />
|
|
522
|
+
<Divider weight="thick" />
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
#### Vertical
|
|
526
|
+
|
|
527
|
+
A vertical divider fills its parent height and is used as a separator inside a row layout.
|
|
528
|
+
|
|
529
|
+
```tsx
|
|
530
|
+
<View style={{ flexDirection: 'row', height: 40 }}>
|
|
531
|
+
<Text>Left</Text>
|
|
532
|
+
<Divider variant="vertical" />
|
|
533
|
+
<Text>Right</Text>
|
|
534
|
+
</View>
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
#### Dashed
|
|
538
|
+
|
|
539
|
+
The dashed style is used for section breaks or to indicate optional content areas.
|
|
540
|
+
|
|
541
|
+
```tsx
|
|
542
|
+
<Divider dashed />
|
|
543
|
+
<Divider weight="thick" dashed />
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
**Props**
|
|
547
|
+
|
|
548
|
+
| Name | Type | Default | Description |
|
|
549
|
+
|------|------|---------|-------------|
|
|
550
|
+
| `variant` | `'horizontal' \| 'vertical'` | `'horizontal'` | Orientation |
|
|
551
|
+
| `weight` | `'thin' \| 'thick'` | `'thin'` | 1px or 2px line |
|
|
552
|
+
| `dashed` | `boolean` | `false` | Dashed line pattern |
|
|
553
|
+
|
|
554
|
+
---
|
|
555
|
+
|
|
556
|
+
### EmptyState
|
|
557
|
+
|
|
558
|
+
`Version: 1.0.0`
|
|
559
|
+
|
|
560
|
+
Full-panel placeholder for empty screens. Supports an icon circle or illustrated card-collage graphic with an optional action button.
|
|
561
|
+
|
|
562
|
+

|
|
563
|
+
|
|
564
|
+
**Import**
|
|
565
|
+
```tsx
|
|
566
|
+
import { EmptyState } from '@/components/ds/EmptyState';
|
|
567
|
+
```
|
|
568
|
+
**Component File:** `components/ds/EmptyState.tsx`
|
|
569
|
+
|
|
570
|
+
#### Icon Style
|
|
571
|
+
|
|
572
|
+
The default style renders an icon inside a circular container above the title and description.
|
|
573
|
+
|
|
574
|
+
```tsx
|
|
575
|
+
<EmptyState
|
|
576
|
+
title="No messages"
|
|
577
|
+
description="When you receive messages they will appear here."
|
|
578
|
+
/>
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
#### Illustration Style
|
|
582
|
+
|
|
583
|
+
The `illustration` style renders a pure-View card collage — no image assets required.
|
|
584
|
+
|
|
585
|
+
```tsx
|
|
586
|
+
<EmptyState style="illustration" title="Nothing here yet" description="Get started by creating your first item." />
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
#### With Action
|
|
590
|
+
|
|
591
|
+
An optional action button prompts the user to take a next step.
|
|
592
|
+
|
|
593
|
+
```tsx
|
|
594
|
+
<EmptyState title="No results" description="Try adjusting your filters." actionLabel="Clear filters" onAction={clearFilters} />
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
**Props**
|
|
598
|
+
|
|
599
|
+
| Name | Type | Default | Description |
|
|
600
|
+
|------|------|---------|-------------|
|
|
601
|
+
| `style` | `'icon' \| 'illustration'` | `'icon'` | Graphic treatment |
|
|
602
|
+
| `viewport` | `'desktop' \| 'mobile'` | `'mobile'` | Token set for type scale and sizing |
|
|
603
|
+
| `title` | `string` | `'No results'` | Heading text |
|
|
604
|
+
| `description` | `string` | `'Description if needed'` | Body copy |
|
|
605
|
+
| `showDescription` | `boolean` | `true` | Hides description when `false` |
|
|
606
|
+
| `icon` | `React.ReactNode` | — | Custom icon in the circle |
|
|
607
|
+
| `actionLabel` | `string` | — | Action button label |
|
|
608
|
+
| `onAction` | `() => void` | — | Action press handler |
|
|
609
|
+
|
|
610
|
+
---
|
|
611
|
+
|
|
612
|
+
### Input
|
|
613
|
+
|
|
614
|
+
`Version: 1.0.0`
|
|
615
|
+
|
|
616
|
+
Single-line text field with floating label, helper/error text, and leading/trailing icon slots.
|
|
617
|
+
|
|
618
|
+

|
|
619
|
+
|
|
620
|
+
**Import**
|
|
621
|
+
```tsx
|
|
622
|
+
import { Input } from '@/components/ds/Input';
|
|
623
|
+
```
|
|
624
|
+
**Component File:** `components/ds/Input.tsx`
|
|
625
|
+
|
|
626
|
+
#### Basic
|
|
627
|
+
|
|
628
|
+
A simple text field with a floating label and placeholder.
|
|
629
|
+
|
|
630
|
+
```tsx
|
|
631
|
+
<Input label="Email" placeholder="you@example.com" />
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
#### Sizes
|
|
635
|
+
|
|
636
|
+
Input supports three sizes that control height, padding, and font scale.
|
|
637
|
+
|
|
638
|
+
```tsx
|
|
639
|
+
<Input size="sm" label="Small" placeholder="Small field" />
|
|
640
|
+
<Input size="md" label="Medium" placeholder="Medium field" />
|
|
641
|
+
<Input size="lg" label="Large" placeholder="Large field" />
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
#### Error State
|
|
645
|
+
|
|
646
|
+
Use `invalid` and `errorText` to communicate a validation error.
|
|
647
|
+
|
|
648
|
+
```tsx
|
|
649
|
+
<Input label="Username" invalid={!!errors.username} errorText={errors.username} />
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
#### With Icons
|
|
653
|
+
|
|
654
|
+
Leading and trailing icons can be placed inside the field.
|
|
655
|
+
|
|
656
|
+
```tsx
|
|
657
|
+
<Input label="Search" leadingIcon={<Ionicons name="search" size={20} />} />
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
**Props**
|
|
661
|
+
|
|
662
|
+
| Name | Type | Default | Description |
|
|
663
|
+
|------|------|---------|-------------|
|
|
664
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Height, padding, and font |
|
|
665
|
+
| `label` | `string` | — | Floating label |
|
|
666
|
+
| `helperText` | `string` | — | Hint text below the field |
|
|
667
|
+
| `errorText` | `string` | — | Error message; replaces `helperText` |
|
|
668
|
+
| `invalid` | `boolean` | `false` | Red border and error color |
|
|
669
|
+
| `leadingIcon` | `React.ReactNode` | — | Icon at the leading edge |
|
|
670
|
+
| `trailingIcon` | `React.ReactNode` | — | Icon at the trailing edge |
|
|
671
|
+
|
|
672
|
+
---
|
|
673
|
+
|
|
674
|
+
### Pagination
|
|
675
|
+
|
|
676
|
+
`Version: 1.0.0`
|
|
677
|
+
|
|
678
|
+
Page navigation with smart truncation. Supports numbered layout or compact prev/next-only mode.
|
|
679
|
+
|
|
680
|
+

|
|
681
|
+
|
|
682
|
+
**Import**
|
|
683
|
+
```tsx
|
|
684
|
+
import { Pagination } from '@/components/ds/Pagination';
|
|
685
|
+
```
|
|
686
|
+
**Component File:** `components/ds/Pagination.tsx`
|
|
687
|
+
|
|
688
|
+
#### Standard
|
|
689
|
+
|
|
690
|
+
The default layout renders numbered page buttons with prev and next arrows inside a pill container.
|
|
691
|
+
|
|
692
|
+
```tsx
|
|
693
|
+
const [page, setPage] = useState(1);
|
|
694
|
+
<Pagination totalPages={12} currentPage={page} onPageChange={setPage} />
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
#### Compact
|
|
698
|
+
|
|
699
|
+
Compact mode renders only prev/next arrows — ideal for narrow mobile screens.
|
|
700
|
+
|
|
701
|
+
```tsx
|
|
702
|
+
<Pagination compact totalPages={20} currentPage={page} onPageChange={setPage} />
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
**Props**
|
|
706
|
+
|
|
707
|
+
| Name | Type | Default | Description |
|
|
708
|
+
|------|------|---------|-------------|
|
|
709
|
+
| `totalPages` | `number` | — | **Required.** Total pages |
|
|
710
|
+
| `currentPage` | `number` | — | **Required.** Active page (1-based) |
|
|
711
|
+
| `onPageChange` | `(page: number) => void` | — | **Required.** Page change handler |
|
|
712
|
+
| `size` | `'sm' \| 'lg'` | `'lg'` | `lg` inside a pill; `sm` bare |
|
|
713
|
+
| `siblingCount` | `number` | `1` | Pages shown on each side before `…` |
|
|
714
|
+
| `compact` | `boolean` | `false` | Prev/next only — no page numbers |
|
|
715
|
+
|
|
716
|
+
---
|
|
717
|
+
|
|
718
|
+
### ProgressTracker
|
|
719
|
+
|
|
720
|
+
`Version: 1.0.0`
|
|
721
|
+
|
|
722
|
+
Multi-step progress indicator with labelled steps and per-step progress bars.
|
|
723
|
+
|
|
724
|
+

|
|
725
|
+
|
|
726
|
+
**Import**
|
|
727
|
+
```tsx
|
|
728
|
+
import { ProgressTracker } from '@/components/ds/ProgressTracker';
|
|
729
|
+
```
|
|
730
|
+
**Component File:** `components/ds/ProgressTracker.tsx`
|
|
731
|
+
|
|
732
|
+
#### Basic
|
|
733
|
+
|
|
734
|
+
Provide an array of steps with a `label` and `state` for each.
|
|
735
|
+
|
|
736
|
+
```tsx
|
|
737
|
+
<ProgressTracker
|
|
738
|
+
steps={[
|
|
739
|
+
{ label: 'Personal info', state: 'completed' },
|
|
740
|
+
{ label: 'Address', state: 'completed' },
|
|
741
|
+
{ label: 'Review', state: 'active' },
|
|
742
|
+
{ label: 'Submit', state: 'pending' },
|
|
743
|
+
]}
|
|
744
|
+
/>
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
#### Without Labels
|
|
748
|
+
|
|
749
|
+
Set `showLabels` to `false` for a compact bar-only indicator.
|
|
750
|
+
|
|
751
|
+
```tsx
|
|
752
|
+
<ProgressTracker showLabels={false} steps={steps} />
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
**Props**
|
|
756
|
+
|
|
757
|
+
| Name | Type | Default | Description |
|
|
758
|
+
|------|------|---------|-------------|
|
|
759
|
+
| `steps` | `TrackerStep[]` | — | **Required.** Step descriptors |
|
|
760
|
+
| `size` | `'sm' \| 'lg'` | `'lg'` | Label font size |
|
|
761
|
+
| `showLabels` | `boolean` | `true` | Show step labels below bars |
|
|
762
|
+
|
|
763
|
+
**TrackerStep**
|
|
764
|
+
|
|
765
|
+
| Field | Type | Description |
|
|
766
|
+
|-------|------|-------------|
|
|
767
|
+
| `label` | `string` | Step display name |
|
|
768
|
+
| `state` | `'completed' \| 'active' \| 'pending'` | 100% / 25% / 0% fill |
|
|
769
|
+
|
|
770
|
+
---
|
|
771
|
+
|
|
772
|
+
### RadioButton
|
|
773
|
+
|
|
774
|
+
`Version: 1.0.0`
|
|
775
|
+
|
|
776
|
+
Single-selection control. Use within a group where only one option can be selected at a time.
|
|
777
|
+
|
|
778
|
+

|
|
779
|
+
|
|
780
|
+
**Import**
|
|
781
|
+
```tsx
|
|
782
|
+
import { RadioButton } from '@/components/ds/RadioButton';
|
|
783
|
+
```
|
|
784
|
+
**Component File:** `components/ds/RadioButton.tsx`
|
|
785
|
+
|
|
786
|
+
#### States
|
|
787
|
+
|
|
788
|
+
RadioButton can be unselected, selected, or disabled.
|
|
789
|
+
|
|
790
|
+
```tsx
|
|
791
|
+
<RadioButton defaultSelected={false} />
|
|
792
|
+
<RadioButton defaultSelected={true} />
|
|
793
|
+
<RadioButton disabled />
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
#### In a Group
|
|
797
|
+
|
|
798
|
+
Manage selection state externally and pass `selected` and `onValueChange` to each option.
|
|
799
|
+
|
|
800
|
+
```tsx
|
|
801
|
+
const [selected, setSelected] = useState<string>('a');
|
|
802
|
+
|
|
803
|
+
<RadioButton selected={selected === 'a'} onValueChange={() => setSelected('a')} accessibilityLabel="Option A" />
|
|
804
|
+
<RadioButton selected={selected === 'b'} onValueChange={() => setSelected('b')} accessibilityLabel="Option B" />
|
|
805
|
+
<RadioButton selected={selected === 'c'} onValueChange={() => setSelected('c')} disabled />
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
**Props**
|
|
809
|
+
|
|
810
|
+
| Name | Type | Default | Description |
|
|
811
|
+
|------|------|---------|-------------|
|
|
812
|
+
| `selected` | `boolean` | — | Controlled state |
|
|
813
|
+
| `defaultSelected` | `boolean` | `false` | Initial uncontrolled state |
|
|
814
|
+
| `onValueChange` | `(value: boolean) => void` | — | Change handler |
|
|
815
|
+
| `size` | `'sm' \| 'md'` | `'md'` | Hit area and ring size |
|
|
816
|
+
| `disabled` | `boolean` | `false` | Disables interaction |
|
|
817
|
+
| `accessibilityLabel` | `string` | — | Screen-reader label |
|
|
818
|
+
|
|
819
|
+
---
|
|
820
|
+
|
|
821
|
+
### Slider
|
|
822
|
+
|
|
823
|
+
`Version: 1.0.0`
|
|
824
|
+
|
|
825
|
+
Continuous value selector with a draggable thumb. Tap anywhere on the track to jump; drag to adjust. Resists gesture theft from parent `ScrollView`.
|
|
826
|
+
|
|
827
|
+

|
|
828
|
+
|
|
829
|
+
**Import**
|
|
830
|
+
```tsx
|
|
831
|
+
import { Slider } from '@/components/ds/Slider';
|
|
832
|
+
```
|
|
833
|
+
**Component File:** `components/ds/Slider.tsx`
|
|
834
|
+
|
|
835
|
+
#### Basic
|
|
836
|
+
|
|
837
|
+
A simple uncontrolled slider with default `min` (0) and `max` (100).
|
|
838
|
+
|
|
839
|
+
```tsx
|
|
840
|
+
<Slider onSlidingComplete={(v) => console.log(v)} />
|
|
841
|
+
```
|
|
842
|
+
|
|
843
|
+
#### With Label
|
|
844
|
+
|
|
845
|
+
Use the `label` prop to render a descriptor above the track.
|
|
846
|
+
|
|
847
|
+
```tsx
|
|
848
|
+
const [volume, setVolume] = useState(50);
|
|
849
|
+
<Slider label="Volume" value={volume} onValueChange={setVolume} />
|
|
850
|
+
```
|
|
851
|
+
|
|
852
|
+
#### Step
|
|
853
|
+
|
|
854
|
+
Use the `step` prop to snap the thumb to fixed intervals.
|
|
855
|
+
|
|
856
|
+
```tsx
|
|
857
|
+
<Slider defaultValue={0} min={0} max={100} step={10} showMinMax />
|
|
858
|
+
```
|
|
859
|
+
|
|
860
|
+
#### Disabled
|
|
861
|
+
|
|
862
|
+
A disabled slider reduces opacity and ignores interaction.
|
|
863
|
+
|
|
864
|
+
```tsx
|
|
865
|
+
<Slider value={40} disabled label="Locked setting" />
|
|
866
|
+
```
|
|
867
|
+
|
|
868
|
+
**Props**
|
|
869
|
+
|
|
870
|
+
| Name | Type | Default | Description |
|
|
871
|
+
|------|------|---------|-------------|
|
|
872
|
+
| `value` | `number` | — | Controlled value |
|
|
873
|
+
| `defaultValue` | `number` | `min` | Initial uncontrolled value |
|
|
874
|
+
| `min` | `number` | `0` | Minimum |
|
|
875
|
+
| `max` | `number` | `100` | Maximum |
|
|
876
|
+
| `step` | `number` | `1` | Snap interval |
|
|
877
|
+
| `onValueChange` | `(value: number) => void` | — | Called while dragging |
|
|
878
|
+
| `onSlidingComplete` | `(value: number) => void` | — | Called on release |
|
|
879
|
+
| `label` | `string` | — | Label above the track |
|
|
880
|
+
| `showMinMax` | `boolean` | `true` | Min/max labels on each side |
|
|
881
|
+
| `disabled` | `boolean` | `false` | Disables interaction |
|
|
882
|
+
|
|
883
|
+
---
|
|
884
|
+
|
|
885
|
+
### Switch
|
|
886
|
+
|
|
887
|
+
`Version: 1.0.0`
|
|
888
|
+
|
|
889
|
+
Animated binary toggle with 150ms thumb slide and background color transition. Supports controlled and uncontrolled usage.
|
|
890
|
+
|
|
891
|
+

|
|
892
|
+
|
|
893
|
+
**Import**
|
|
894
|
+
```tsx
|
|
895
|
+
import { Switch } from '@/components/ds/Switch';
|
|
896
|
+
```
|
|
897
|
+
**Component File:** `components/ds/Switch.tsx`
|
|
898
|
+
|
|
899
|
+
#### On and Off
|
|
900
|
+
|
|
901
|
+
Switch can be toggled between on and off states.
|
|
902
|
+
|
|
903
|
+
```tsx
|
|
904
|
+
<Switch defaultValue={false} onValueChange={console.log} />
|
|
905
|
+
<Switch defaultValue={true} onValueChange={console.log} />
|
|
906
|
+
```
|
|
907
|
+
|
|
908
|
+
#### Controlled
|
|
909
|
+
|
|
910
|
+
Use the `value` prop with `onValueChange` for controlled usage.
|
|
911
|
+
|
|
912
|
+
```tsx
|
|
913
|
+
const [enabled, setEnabled] = useState(false);
|
|
914
|
+
<Switch value={enabled} onValueChange={setEnabled} accessibilityLabel="Notifications" />
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
#### Disabled
|
|
918
|
+
|
|
919
|
+
Disabled switches reduce opacity and ignore press interactions.
|
|
920
|
+
|
|
921
|
+
```tsx
|
|
922
|
+
<Switch value={false} disabled />
|
|
923
|
+
<Switch value={true} disabled />
|
|
924
|
+
```
|
|
925
|
+
|
|
926
|
+
**Props**
|
|
927
|
+
|
|
928
|
+
| Name | Type | Default | Description |
|
|
929
|
+
|------|------|---------|-------------|
|
|
930
|
+
| `value` | `boolean` | — | Controlled value |
|
|
931
|
+
| `defaultValue` | `boolean` | `false` | Initial uncontrolled value |
|
|
932
|
+
| `onValueChange` | `(value: boolean) => void` | — | Toggle handler |
|
|
933
|
+
| `disabled` | `boolean` | `false` | Disables interaction |
|
|
934
|
+
| `accessibilityLabel` | `string` | — | Screen-reader label |
|
|
935
|
+
|
|
936
|
+
---
|
|
937
|
+
|
|
938
|
+
### Tooltip
|
|
939
|
+
|
|
940
|
+
`Version: 1.0.0`
|
|
941
|
+
|
|
942
|
+
Short contextual label with a directional arrow. Use to clarify icon buttons, abbreviations, or truncated text.
|
|
943
|
+
|
|
944
|
+

|
|
945
|
+
|
|
946
|
+
**Import**
|
|
947
|
+
```tsx
|
|
948
|
+
import { Tooltip } from '@/components/ds/Tooltip';
|
|
949
|
+
```
|
|
950
|
+
**Component File:** `components/ds/Tooltip.tsx`
|
|
951
|
+
|
|
952
|
+
#### Filled
|
|
953
|
+
|
|
954
|
+
The filled variant uses a dark inverse surface — the default and most common style.
|
|
955
|
+
|
|
956
|
+
```tsx
|
|
957
|
+
<Tooltip text="More options" />
|
|
958
|
+
<Tooltip text="Delete item" direction="bottom" />
|
|
959
|
+
```
|
|
960
|
+
|
|
961
|
+
#### Elevated
|
|
962
|
+
|
|
963
|
+
The elevated variant uses a white surface with a border and shadow — for use on dark backgrounds.
|
|
964
|
+
|
|
965
|
+
```tsx
|
|
966
|
+
<Tooltip text="Save your work" variant="elevated" direction="bottom" />
|
|
967
|
+
```
|
|
968
|
+
|
|
969
|
+
#### Directions
|
|
970
|
+
|
|
971
|
+
The `direction` prop describes where the target is relative to the bubble, which determines where the arrow is drawn.
|
|
972
|
+
|
|
973
|
+
```tsx
|
|
974
|
+
<Tooltip text="No arrow" direction="none" />
|
|
975
|
+
<Tooltip text="Arrow up" direction="top" />
|
|
976
|
+
<Tooltip text="Arrow down" direction="bottom" />
|
|
977
|
+
<Tooltip text="Arrow left" direction="left" />
|
|
978
|
+
<Tooltip text="Arrow right" direction="right" />
|
|
979
|
+
```
|
|
980
|
+
|
|
981
|
+
**Props**
|
|
982
|
+
|
|
983
|
+
| Name | Type | Default | Description |
|
|
984
|
+
|------|------|---------|-------------|
|
|
985
|
+
| `text` | `string` | — | **Required.** Tooltip content |
|
|
986
|
+
| `variant` | `'filled' \| 'elevated'` | `'filled'` | Dark inverse or white elevated |
|
|
987
|
+
| `direction` | `'none' \| 'top' \| 'bottom' \| 'left' \| 'right'` | `'none'` | Where the target is relative to the bubble |
|
|
988
|
+
|
|
989
|
+
---
|
|
990
|
+
|
|
991
|
+
## Token System
|
|
992
|
+
|
|
993
|
+
All components reference only `sys.*` tokens via:
|
|
994
|
+
|
|
995
|
+
```ts
|
|
996
|
+
import { sys } from '@/components/ds/tokens';
|
|
997
|
+
const { colorRoles: cr, dimensions: dim, typeScale: ts } = sys;
|
|
998
|
+
```
|
|
999
|
+
|
|
1000
|
+
Never apply `core.*`, `product.*`, or `brand.*` tokens directly in UI — they are internal plumbing and will not respond to theme or brand changes.
|
|
1001
|
+
|
|
1002
|
+
---
|
|
1003
|
+
|
|
1004
|
+
## Project Structure
|
|
1005
|
+
|
|
1006
|
+
```
|
|
1007
|
+
components/ds/ All 17 DS component implementations
|
|
1008
|
+
components/ds/tokens.ts sys.* token bridge from @javierkonpo/design-system
|
|
1009
|
+
app/(tabs)/index.tsx Component gallery / showcase screen
|
|
1010
|
+
docs/
|
|
1011
|
+
components.md Full component API reference (RNEUI-style)
|
|
1012
|
+
Components.docx Word document with Figma screenshots
|
|
1013
|
+
components.pdf PDF reference with Figma screenshots
|
|
1014
|
+
images/ Figma component screenshots
|
|
1015
|
+
```
|