@retray-dev/ui-kit 1.7.0 → 2.3.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/COMPONENTS.md +258 -54
- package/README.md +6 -5
- package/dist/index.d.mts +113 -44
- package/dist/index.d.ts +113 -44
- package/dist/index.js +802 -324
- package/dist/index.mjs +794 -323
- package/package.json +6 -2
- package/src/components/Alert/Alert.tsx +24 -12
- package/src/components/AlertBanner/AlertBanner.tsx +83 -0
- package/src/components/AlertBanner/index.ts +2 -0
- package/src/components/Avatar/Avatar.tsx +1 -0
- package/src/components/Badge/Badge.tsx +44 -8
- package/src/components/Button/Button.tsx +12 -5
- package/src/components/Card/Card.tsx +86 -9
- package/src/components/Chip/Chip.tsx +173 -0
- package/src/components/Chip/index.ts +2 -0
- package/src/components/ConfirmDialog/ConfirmDialog.tsx +87 -0
- package/src/components/ConfirmDialog/index.ts +2 -0
- package/src/components/CurrencyDisplay/CurrencyDisplay.tsx +4 -2
- package/src/components/CurrencyInput/CurrencyInput.tsx +9 -1
- package/src/components/EmptyState/EmptyState.tsx +42 -7
- package/src/components/Input/Input.tsx +102 -21
- package/src/components/LabelValue/LabelValue.tsx +47 -0
- package/src/components/LabelValue/index.ts +2 -0
- package/src/components/ListItem/ListItem.tsx +121 -0
- package/src/components/ListItem/index.ts +2 -0
- package/src/components/MonthPicker/MonthPicker.tsx +92 -0
- package/src/components/MonthPicker/index.ts +2 -0
- package/src/components/Select/Select.tsx +189 -125
- package/src/components/Slider/Slider.tsx +64 -100
- package/src/components/Switch/Switch.tsx +25 -21
- package/src/components/Textarea/Textarea.tsx +12 -2
- package/src/components/Toggle/Toggle.tsx +13 -6
- package/src/index.ts +8 -2
- package/src/theme/ThemeProvider.tsx +11 -8
- package/src/theme/colors.ts +19 -18
- package/src/theme/types.ts +2 -0
- package/src/components/Alert/index.ts +0 -2
- package/src/components/CurrencyInputLarge/CurrencyInputLarge.tsx +0 -66
- package/src/components/CurrencyInputLarge/index.ts +0 -1
package/COMPONENTS.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @retray-dev/ui-kit — Component Reference (
|
|
1
|
+
# @retray-dev/ui-kit — Component Reference (v2.1.0)
|
|
2
2
|
|
|
3
3
|
This file is the AI reference for this package. It is shipped inside the npm package so consuming projects can import it into their `CLAUDE.md` with:
|
|
4
4
|
|
|
@@ -74,29 +74,34 @@ function MyComponent() {
|
|
|
74
74
|
|
|
75
75
|
## Theme Tokens
|
|
76
76
|
|
|
77
|
-
All 20 tokens are available via `useTheme().colors
|
|
77
|
+
All 20 tokens are available via `useTheme().colors` and are applied exactly as provided — there is no automatic color derivation or forced contrast applied by the library. Consumers may pass partial overrides for `light` and/or `dark` and the values are used as-is.
|
|
78
|
+
|
|
79
|
+
The `ThemeColors` type (and `Theme`, `ColorScheme`) are exported directly from the package:
|
|
80
|
+
```ts
|
|
81
|
+
import type { ThemeColors } from '@retray-dev/ui-kit'
|
|
82
|
+
```
|
|
78
83
|
|
|
79
84
|
| Token | Light | Dark | Semantic Role |
|
|
80
85
|
|-------|-------|------|---------------|
|
|
81
86
|
| `background` | `#ffffff` | `#171717` | Screen / page background |
|
|
82
87
|
| `foreground` | `#171717` | `#fafafa` | Primary text color |
|
|
83
|
-
| `card` | `#ffffff` | `#
|
|
88
|
+
| `card` | `#ffffff` | `#222222` | Card / surface background |
|
|
84
89
|
| `cardForeground` | `#171717` | `#fafafa` | Text on cards |
|
|
85
90
|
| `primary` | `#1a1a1a` | `#fafafa` | Primary action (buttons, selected states) |
|
|
86
|
-
| `primaryForeground` | `#
|
|
87
|
-
| `secondary` | `#
|
|
88
|
-
| `secondaryForeground` | `#
|
|
89
|
-
| `muted` | `#
|
|
90
|
-
| `mutedForeground` | `#
|
|
91
|
-
| `accent` | `#
|
|
92
|
-
| `accentForeground` | `#
|
|
91
|
+
| `primaryForeground` | `#ffffff` | `#1a1a1a` | Text/icon on primary background |
|
|
92
|
+
| `secondary` | `#f1f1f1` | `#323232` | Secondary surfaces |
|
|
93
|
+
| `secondaryForeground` | `#171717` | `#fafafa` | Text on secondary |
|
|
94
|
+
| `muted` | `#f1f1f1` | `#323232` | Muted backgrounds, skeleton fills, track fills |
|
|
95
|
+
| `mutedForeground` | `#a2a2a2` | `#888888` | Placeholder text, helper text, captions |
|
|
96
|
+
| `accent` | `#e4e4e4` | `#323232` | Hover / pressed state fills |
|
|
97
|
+
| `accentForeground` | `#171717` | `#fafafa` | Text on accent |
|
|
93
98
|
| `destructive` | `#ef4444` | `#dc2626` | Error / danger / delete actions |
|
|
94
|
-
| `destructiveForeground` | `#
|
|
99
|
+
| `destructiveForeground` | `#1a1a1a` | `#1a1a1a` | Text on destructive |
|
|
95
100
|
| `border` | `#e5e5e5` | `#2a2a2a` | Borders and dividers |
|
|
96
101
|
| `input` | `#e5e5e5` | `#2a2a2a` | Input field border color |
|
|
97
|
-
| `ring` | `#
|
|
102
|
+
| `ring` | `#1a1a1a` | `#fafafa` | Optional focus ring token (components may use `primary` by default) |
|
|
98
103
|
| `success` | `#16a34a` | `#22c55e` | Success state (Toast success variant) |
|
|
99
|
-
| `successForeground` | `#
|
|
104
|
+
| `successForeground` | `#1a1a1a` | `#1a1a1a` | Text on success background |
|
|
100
105
|
|
|
101
106
|
---
|
|
102
107
|
|
|
@@ -142,11 +147,11 @@ All 20 tokens are available via `useTheme().colors`.
|
|
|
142
147
|
| Prop | Type | Default | Notes |
|
|
143
148
|
|------|------|---------|-------|
|
|
144
149
|
| label | `string` | required | Button text |
|
|
145
|
-
| variant | `'primary' \| 'secondary' \| 'outline' \| 'ghost'` | `'primary'` | Visual style |
|
|
150
|
+
| variant | `'primary' \| 'secondary' \| 'outline' \| 'ghost' \| 'destructive'` | `'primary'` | Visual style |
|
|
146
151
|
| size | `'sm' \| 'md' \| 'lg'` | `'md'` | — |
|
|
147
152
|
| loading | `boolean` | `false` | Replaces label with a spinner and forces disabled state |
|
|
148
153
|
| fullWidth | `boolean` | `false` | Stretches to container width (`alignSelf: 'stretch'`) |
|
|
149
|
-
| disabled | `boolean` | — | Reduces opacity to 0.
|
|
154
|
+
| disabled | `boolean` | — | Reduces opacity to 0.5 |
|
|
150
155
|
| icon | `React.ReactNode` | — | Icon rendered alongside the label |
|
|
151
156
|
| iconPosition | `'left' \| 'right'` | `'left'` | Side the icon appears on |
|
|
152
157
|
|
|
@@ -155,6 +160,7 @@ All 20 tokens are available via `useTheme().colors`.
|
|
|
155
160
|
- `secondary`: filled with `secondary` token — less prominent actions
|
|
156
161
|
- `outline`: transparent with `border` — alternative without fill
|
|
157
162
|
- `ghost`: fully transparent — in-context or low-emphasis actions
|
|
163
|
+
- `destructive`: filled with `destructive` token — irreversible or dangerous actions
|
|
158
164
|
|
|
159
165
|
**Animations:** Scale springs to 0.97 on `onPressIn`, back to 1.0 on `onPressOut`.
|
|
160
166
|
|
|
@@ -180,14 +186,19 @@ All 20 tokens are available via `useTheme().colors`.
|
|
|
180
186
|
| label | `string` | — | Label above the input |
|
|
181
187
|
| error | `string` | — | Shows error text below; turns border red (`destructive` token) |
|
|
182
188
|
| hint | `string` | — | Helper text below (hidden when `error` is set) |
|
|
189
|
+
| prefix | `string \| ReactNode` | — | Content rendered before the input field (e.g., `"$"` or an icon) |
|
|
190
|
+
| suffix | `string \| ReactNode` | — | Content rendered after the input field (e.g., `"kg"` or a button) |
|
|
191
|
+
| type | `'text' \| 'password'` | `'text'` | When `'password'`, shows a visibility toggle button in the suffix slot |
|
|
183
192
|
|
|
184
193
|
**Border colors:** `destructive` when `error` is set, `ring` when focused, `border` otherwise.
|
|
185
194
|
|
|
186
195
|
**Example:**
|
|
187
196
|
```tsx
|
|
188
197
|
<Input label="Email" placeholder="you@example.com" keyboardType="email-address" />
|
|
189
|
-
<Input label="Password"
|
|
198
|
+
<Input label="Password" type="password" error="Incorrect password" />
|
|
190
199
|
<Input label="Username" hint="Must be at least 4 characters" />
|
|
200
|
+
<Input label="Amount" prefix="$" placeholder="0.00" keyboardType="numeric" />
|
|
201
|
+
<Input label="Weight" suffix="kg" placeholder="0" />
|
|
191
202
|
```
|
|
192
203
|
|
|
193
204
|
---
|
|
@@ -204,6 +215,7 @@ All 20 tokens are available via `useTheme().colors`.
|
|
|
204
215
|
| onChangeValue | `(raw: number) => void` | — | Called with the parsed number (no separators, no prefix) |
|
|
205
216
|
| prefix | `string` | `'$'` | Symbol prepended to the formatted value |
|
|
206
217
|
| thousandsSeparator | `'.' \| ','` | `'.'` | Character used to separate groups of three digits |
|
|
218
|
+
| size | `'default' \| 'large'` | `'default'` | `'large'` uses 36px font size (previously `CurrencyInputLarge`) |
|
|
207
219
|
| label | `string` | — | Label above the input |
|
|
208
220
|
| error | `string` | — | Error text below; turns border red |
|
|
209
221
|
| hint | `string` | — | Helper text below (hidden when `error` is set) |
|
|
@@ -264,16 +276,20 @@ const [amount, setAmount] = useState(0)
|
|
|
264
276
|
|
|
265
277
|
| Prop | Type | Default | Notes |
|
|
266
278
|
|------|------|---------|-------|
|
|
267
|
-
| label | `string` |
|
|
279
|
+
| label | `string` | — | Badge text — can be omitted if using `children` |
|
|
280
|
+
| children | `ReactNode` | — | Alternative to `label` for custom content |
|
|
268
281
|
| variant | `'default' \| 'secondary' \| 'destructive' \| 'outline'` | `'default'` | — |
|
|
282
|
+
| size | `'sm' \| 'md' \| 'lg'` | `'md'` | Controls padding and font size |
|
|
283
|
+
| icon | `ReactNode` | — | Icon rendered before the label/children |
|
|
269
284
|
| style | `ViewStyle` | — | — |
|
|
270
285
|
|
|
271
286
|
**Example:**
|
|
272
287
|
```tsx
|
|
273
288
|
<Badge label="New" />
|
|
274
289
|
<Badge label="Error" variant="destructive" />
|
|
275
|
-
<Badge label="Draft" variant="secondary" />
|
|
290
|
+
<Badge label="Draft" variant="secondary" size="sm" />
|
|
276
291
|
<Badge label="Beta" variant="outline" />
|
|
292
|
+
<Badge icon={<CheckIcon size={12} />} size="sm">Verified</Badge>
|
|
277
293
|
```
|
|
278
294
|
|
|
279
295
|
---
|
|
@@ -380,29 +396,6 @@ const [amount, setAmount] = useState(0)
|
|
|
380
396
|
|
|
381
397
|
---
|
|
382
398
|
|
|
383
|
-
### Card
|
|
384
|
-
|
|
385
|
-
**Import:** `import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@retray-dev/ui-kit'`
|
|
386
|
-
**When to use:** Grouped content with a surface background, border, and shadow.
|
|
387
|
-
|
|
388
|
-
All sub-components accept a `style` prop for overrides.
|
|
389
|
-
|
|
390
|
-
**Example:**
|
|
391
|
-
```tsx
|
|
392
|
-
<Card>
|
|
393
|
-
<CardHeader>
|
|
394
|
-
<CardTitle>Account</CardTitle>
|
|
395
|
-
<CardDescription>Manage your profile settings</CardDescription>
|
|
396
|
-
</CardHeader>
|
|
397
|
-
<CardContent>
|
|
398
|
-
<Input label="Name" />
|
|
399
|
-
</CardContent>
|
|
400
|
-
<CardFooter>
|
|
401
|
-
<Button label="Save" fullWidth />
|
|
402
|
-
</CardFooter>
|
|
403
|
-
|
|
404
|
-
---
|
|
405
|
-
|
|
406
399
|
### CurrencyDisplay
|
|
407
400
|
|
|
408
401
|
**Import:** `import { CurrencyDisplay } from '@retray-dev/ui-kit'`
|
|
@@ -413,6 +406,7 @@ All sub-components accept a `style` prop for overrides.
|
|
|
413
406
|
| value | `number \| string` | required | Numeric value to display |
|
|
414
407
|
| prefix | `string` | `'$'` | Symbol prepended to the formatted value |
|
|
415
408
|
| showDecimals | `boolean` | `false` | When `true`, shows two decimal places separated by a comma (e.g. `$25.000,00`) |
|
|
409
|
+
| textColor | `string` | — | Override the color of the formatted text. Defaults to the `foreground` token |
|
|
416
410
|
| style | `ViewStyle` | — | Style override for outer container |
|
|
417
411
|
|
|
418
412
|
**Example:**
|
|
@@ -474,11 +468,20 @@ const [amount, setAmount] = useState(0)
|
|
|
474
468
|
**Import:** `import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@retray-dev/ui-kit'`
|
|
475
469
|
**When to use:** Grouped content with a surface background, border, and shadow.
|
|
476
470
|
|
|
477
|
-
|
|
471
|
+
**`Card` Props:**
|
|
472
|
+
|
|
473
|
+
| Prop | Type | Default | Notes |
|
|
474
|
+
|------|------|---------|-------|
|
|
475
|
+
| variant | `'elevated' \| 'outlined' \| 'filled'` | `'elevated'` | `elevated`: shadow + border; `outlined`: border only; `filled`: background fill, no border |
|
|
476
|
+
| onPress | `() => void` | — | Makes the card pressable with scale animation + haptics |
|
|
477
|
+
| children | `ReactNode` | — | — |
|
|
478
|
+
| style | `ViewStyle` | — | — |
|
|
479
|
+
|
|
480
|
+
All sub-components (`CardHeader`, `CardTitle`, `CardDescription`, `CardContent`, `CardFooter`) accept a `style` prop for overrides.
|
|
478
481
|
|
|
479
482
|
**Example:**
|
|
480
483
|
```tsx
|
|
481
|
-
<Card>
|
|
484
|
+
<Card variant="elevated">
|
|
482
485
|
<CardHeader>
|
|
483
486
|
<CardTitle>Account</CardTitle>
|
|
484
487
|
<CardDescription>Manage your profile settings</CardDescription>
|
|
@@ -490,33 +493,44 @@ All sub-components accept a `style` prop for overrides.
|
|
|
490
493
|
<Button label="Save" fullWidth />
|
|
491
494
|
</CardFooter>
|
|
492
495
|
</Card>
|
|
496
|
+
|
|
497
|
+
// Pressable card
|
|
498
|
+
<Card variant="outlined" onPress={() => navigate('detail')}>
|
|
499
|
+
<CardContent>
|
|
500
|
+
<Text>Tap me</Text>
|
|
501
|
+
</CardContent>
|
|
502
|
+
</Card>
|
|
493
503
|
```
|
|
494
504
|
|
|
495
505
|
**Notes:**
|
|
496
|
-
- `CardHeader` and `CardContent` have `padding: 24`
|
|
506
|
+
- `CardHeader` and `CardContent` have `padding: 24`. Override via the `style` prop: `<CardContent style={{ padding: 16 }}>`
|
|
497
507
|
- `CardFooter` has `paddingTop: 0` so it connects naturally to `CardContent`
|
|
498
508
|
- `CardTitle`: 18px / 600 weight, `cardForeground` color
|
|
499
509
|
- `CardDescription`: 14px, `mutedForeground` color
|
|
510
|
+
- Press animation scales to 0.98 via `Animated.spring` when `onPress` is provided
|
|
500
511
|
|
|
501
512
|
---
|
|
502
513
|
|
|
503
|
-
###
|
|
514
|
+
### AlertBanner
|
|
504
515
|
|
|
505
|
-
**Import:** `import {
|
|
506
|
-
**When to use:** Inline feedback messages (info, success,
|
|
516
|
+
**Import:** `import { AlertBanner } from '@retray-dev/ui-kit'`
|
|
517
|
+
**When to use:** Inline feedback messages (info, success, error). Not for transient toasts — use `Toast` for ephemeral feedback.
|
|
518
|
+
|
|
519
|
+
> **Note:** Named `AlertBanner` (not `Alert`) to avoid collision with React Native's built-in `Alert` module.
|
|
507
520
|
|
|
508
521
|
| Prop | Type | Default | Notes |
|
|
509
522
|
|------|------|---------|-------|
|
|
510
523
|
| title | `string` | — | Bold heading |
|
|
511
524
|
| description | `string` | — | Detail text |
|
|
512
|
-
| variant | `'default' \| 'destructive'` | `'default'` |
|
|
513
|
-
| icon | `ReactNode` | — | Icon placed to the left of the text content |
|
|
525
|
+
| variant | `'default' \| 'destructive' \| 'success'` | `'default'` | Controls border/text color |
|
|
526
|
+
| icon | `ReactNode` | — | Icon placed to the left of the text content. Defaults to a variant-appropriate symbol (`ℹ`, `⚠`, `✓`) |
|
|
514
527
|
| style | `ViewStyle` | — | — |
|
|
515
528
|
|
|
516
529
|
**Example:**
|
|
517
530
|
```tsx
|
|
518
|
-
<
|
|
519
|
-
<
|
|
531
|
+
<AlertBanner title="Info" description="Your session will expire in 5 minutes." />
|
|
532
|
+
<AlertBanner variant="destructive" title="Error" description="Failed to save. Try again." />
|
|
533
|
+
<AlertBanner variant="success" title="Done" description="Your changes have been saved." />
|
|
520
534
|
```
|
|
521
535
|
|
|
522
536
|
---
|
|
@@ -532,6 +546,7 @@ All sub-components accept a `style` prop for overrides.
|
|
|
532
546
|
| description | `string` | — | — |
|
|
533
547
|
| icon | `ReactNode` | — | Shown in a 48×48 muted square above the text |
|
|
534
548
|
| action | `ReactNode` | — | Usually a `Button`, placed below the text |
|
|
549
|
+
| size | `'default' \| 'compact'` | `'default'` | `compact` hides description/action, uses a 36×36 icon, smaller title (15px), and tighter spacing |
|
|
535
550
|
| style | `ViewStyle` | — | — |
|
|
536
551
|
|
|
537
552
|
**Example:**
|
|
@@ -577,7 +592,7 @@ const [accepted, setAccepted] = useState(false)
|
|
|
577
592
|
| disabled | `boolean` | — | Reduces opacity to 0.45 |
|
|
578
593
|
| style | `ViewStyle` | — | — |
|
|
579
594
|
|
|
580
|
-
**Dimensions:** Track
|
|
595
|
+
**Dimensions:** Track 60×36pt, Thumb 28×28pt with 4pt offset from edges (`top: 4, left: 4`). Thumb uses `position: 'absolute'` inside the track.
|
|
581
596
|
|
|
582
597
|
**Animation:** Thumb translates via spring (bounciness: 4); track color transitions via opacity timing (150ms).
|
|
583
598
|
|
|
@@ -650,7 +665,7 @@ const [accepted, setAccepted] = useState(false)
|
|
|
650
665
|
### Select
|
|
651
666
|
|
|
652
667
|
**Import:** `import { Select } from '@retray-dev/ui-kit'`
|
|
653
|
-
**When to use:** Dropdown picker.
|
|
668
|
+
**When to use:** Dropdown picker. Uses the native system picker UI on each platform — wheel modal on iOS (confirm with "Done"), spinner dialog on Android, native `<select>` on web (full keyboard support). Requires `@react-native-picker/picker` installed in the consuming app.
|
|
654
669
|
|
|
655
670
|
| Prop | Type | Default | Notes |
|
|
656
671
|
|------|------|---------|-------|
|
|
@@ -690,13 +705,27 @@ const [accepted, setAccepted] = useState(false)
|
|
|
690
705
|
| onValueChange | `(value: number) => void` | — | Fires while dragging |
|
|
691
706
|
| onSlidingComplete | `(value: number) => void` | — | Fires on finger release |
|
|
692
707
|
| disabled | `boolean` | — | — |
|
|
708
|
+
| label | `string` | — | Label text displayed above the slider |
|
|
709
|
+
| showValue | `boolean` | `false` | When `true`, displays the current value at the top right |
|
|
710
|
+
| formatValue | `(value: number) => string` | — | Custom formatter for the displayed value |
|
|
711
|
+
| accessibilityLabel | `string` | — | Accessibility label for screen readers |
|
|
693
712
|
| style | `ViewStyle` | — | — |
|
|
694
713
|
|
|
695
|
-
**
|
|
714
|
+
**Notes:** Uses `@react-native-community/slider` natively — theming applied via `minimumTrackTintColor` (primary), `maximumTrackTintColor` (muted), `thumbTintColor` (primary). Requires `@react-native-community/slider` installed in the consuming app.
|
|
696
715
|
|
|
697
716
|
**Example:**
|
|
698
717
|
```tsx
|
|
699
718
|
<Slider value={volume} minimumValue={0} maximumValue={100} step={1} onValueChange={setVolume} />
|
|
719
|
+
<Slider
|
|
720
|
+
label="Volume"
|
|
721
|
+
showValue
|
|
722
|
+
value={volume}
|
|
723
|
+
minimumValue={0}
|
|
724
|
+
maximumValue={100}
|
|
725
|
+
step={5}
|
|
726
|
+
formatValue={(v) => `${v}%`}
|
|
727
|
+
onValueChange={setVolume}
|
|
728
|
+
/>
|
|
700
729
|
```
|
|
701
730
|
|
|
702
731
|
---
|
|
@@ -795,6 +824,11 @@ pnpm add @gorhom/bottom-sheet react-native-reanimated react-native-gesture-handl
|
|
|
795
824
|
```
|
|
796
825
|
Add `react-native-worklets/plugin` (not `react-native-reanimated/plugin`) to your `babel.config.js` plugins.
|
|
797
826
|
|
|
827
|
+
> **Important — Expo managed workflow:** Expo's install tool may downgrade `@gorhom/bottom-sheet` to an incompatible version (v4). Pin it in `app.json` to prevent this:
|
|
828
|
+
> ```json
|
|
829
|
+
> { "expo": { "install": { "exclude": ["@gorhom/bottom-sheet"] } } }
|
|
830
|
+
> ```
|
|
831
|
+
|
|
798
832
|
| Prop | Type | Default | Notes |
|
|
799
833
|
|------|------|---------|-------|
|
|
800
834
|
| open | `boolean` | required | `true` presents the sheet, `false` dismisses it |
|
|
@@ -859,3 +893,173 @@ function MyComponent() {
|
|
|
859
893
|
- Entrance: `withTiming(120ms, Easing.out(Easing.exp))` slide-down + opacity fade — fast, sharp feel
|
|
860
894
|
- Exit: `withTiming(200ms)` slide-up + opacity fade
|
|
861
895
|
- Swipe left or right to dismiss early (threshold: 80px or 800 pt/s velocity)
|
|
896
|
+
|
|
897
|
+
---
|
|
898
|
+
|
|
899
|
+
### ListItem
|
|
900
|
+
|
|
901
|
+
**Import:** `import { ListItem } from '@retray-dev/ui-kit'`
|
|
902
|
+
**When to use:** Rows in a list or menu. Composes icon, title, subtitle, and trailing content in a standard horizontal layout.
|
|
903
|
+
|
|
904
|
+
| Prop | Type | Default | Notes |
|
|
905
|
+
|------|------|---------|-------|
|
|
906
|
+
| title | `string` | required | Primary label |
|
|
907
|
+
| subtitle | `string` | — | Secondary label below the title |
|
|
908
|
+
| icon | `ReactNode` | — | Node rendered to the left of the text content |
|
|
909
|
+
| trailing | `string \| ReactNode` | — | Content on the right edge. Strings are styled as muted caption |
|
|
910
|
+
| onPress | `() => void` | — | Makes the row pressable. Scale animation + haptics are only active when provided |
|
|
911
|
+
| disabled | `boolean` | — | Reduces opacity to 0.45 |
|
|
912
|
+
| style | `ViewStyle` | — | — |
|
|
913
|
+
|
|
914
|
+
**Example:**
|
|
915
|
+
```tsx
|
|
916
|
+
<ListItem
|
|
917
|
+
icon={<Ionicons name="receipt-outline" size={18} />}
|
|
918
|
+
title="Mercado"
|
|
919
|
+
subtitle="12 mar 2025"
|
|
920
|
+
trailing="$45.000"
|
|
921
|
+
onPress={() => navigate('detail')}
|
|
922
|
+
/>
|
|
923
|
+
|
|
924
|
+
// Non-interactive row
|
|
925
|
+
<ListItem title="Account number" trailing="**** 4321" />
|
|
926
|
+
```
|
|
927
|
+
|
|
928
|
+
---
|
|
929
|
+
|
|
930
|
+
### Chip / ChipGroup
|
|
931
|
+
|
|
932
|
+
**Import:** `import { Chip, ChipGroup } from '@retray-dev/ui-kit'`
|
|
933
|
+
**When to use:** Filter pills, single-select options displayed inline. Use `ChipGroup` for managed single-selection; use `Chip` standalone for custom logic.
|
|
934
|
+
|
|
935
|
+
**`Chip` Props:**
|
|
936
|
+
|
|
937
|
+
| Prop | Type | Default | Notes |
|
|
938
|
+
|------|------|---------|-------|
|
|
939
|
+
| label | `string` | required | — |
|
|
940
|
+
| selected | `boolean` | `false` | Controls fill color |
|
|
941
|
+
| onPress | `() => void` | — | — |
|
|
942
|
+
| style | `ViewStyle` | — | — |
|
|
943
|
+
|
|
944
|
+
**`ChipGroup` Props:**
|
|
945
|
+
|
|
946
|
+
| Prop | Type | Default | Notes |
|
|
947
|
+
|------|------|---------|-------|
|
|
948
|
+
| options | `ChipOption[]` | required | Each: `{ label: string, value: string \| number }` |
|
|
949
|
+
| value | `string \| number \| (string \| number)[]` | — | Currently selected value (single mode) or array of selected values (multi mode) |
|
|
950
|
+
| onValueChange | `(value: string \| number \| (string \| number)[]) => void` | — | — |
|
|
951
|
+
| multiSelect | `boolean` | `false` | When `true`, allows multiple chips to be selected simultaneously |
|
|
952
|
+
| style | `ViewStyle` | — | Applied to the wrapping row |
|
|
953
|
+
|
|
954
|
+
**Animation:** Background, text, and border colors animate via `Animated.timing` (150ms) between unselected (`secondary`/`border`/`foreground`) and selected (`primary`/`primary`/`primaryForeground`) states.
|
|
955
|
+
|
|
956
|
+
**Example:**
|
|
957
|
+
```tsx
|
|
958
|
+
// Single select
|
|
959
|
+
const [pct, setPct] = useState(50)
|
|
960
|
+
|
|
961
|
+
<ChipGroup
|
|
962
|
+
options={[
|
|
963
|
+
{ label: '40%', value: 40 },
|
|
964
|
+
{ label: '50%', value: 50 },
|
|
965
|
+
{ label: '100%', value: 100 },
|
|
966
|
+
]}
|
|
967
|
+
value={pct}
|
|
968
|
+
onValueChange={setPct}
|
|
969
|
+
/>
|
|
970
|
+
|
|
971
|
+
// Multi select
|
|
972
|
+
const [categories, setCategories] = useState<number[]>([1, 3])
|
|
973
|
+
|
|
974
|
+
<ChipGroup
|
|
975
|
+
multiSelect
|
|
976
|
+
options={[
|
|
977
|
+
{ label: 'Food', value: 1 },
|
|
978
|
+
{ label: 'Transport', value: 2 },
|
|
979
|
+
{ label: 'Entertainment', value: 3 },
|
|
980
|
+
]}
|
|
981
|
+
value={categories}
|
|
982
|
+
onValueChange={setCategories}
|
|
983
|
+
/>
|
|
984
|
+
```
|
|
985
|
+
|
|
986
|
+
---
|
|
987
|
+
|
|
988
|
+
### ConfirmDialog
|
|
989
|
+
|
|
990
|
+
**Import:** `import { ConfirmDialog } from '@retray-dev/ui-kit'`
|
|
991
|
+
**When to use:** Confirmation prompts before irreversible or destructive actions (delete, send, discard).
|
|
992
|
+
|
|
993
|
+
| Prop | Type | Default | Notes |
|
|
994
|
+
|------|------|---------|-------|
|
|
995
|
+
| visible | `boolean` | required | Controls modal visibility |
|
|
996
|
+
| title | `string` | required | Dialog heading |
|
|
997
|
+
| description | `string` | — | Supporting text below the title |
|
|
998
|
+
| confirmLabel | `string` | `'Confirm'` | Label for the confirm button |
|
|
999
|
+
| cancelLabel | `string` | `'Cancel'` | Label for the cancel button |
|
|
1000
|
+
| confirmVariant | `'primary' \| 'destructive'` | `'primary'` | Button variant for the confirm action |
|
|
1001
|
+
| onConfirm | `() => void` | required | Called when confirm is tapped |
|
|
1002
|
+
| onCancel | `() => void` | required | Called when cancel is tapped or backdrop is pressed |
|
|
1003
|
+
|
|
1004
|
+
**Notes:**
|
|
1005
|
+
- Uses React Native `Modal` with `animationType="fade"` — no bottom-sheet dependency.
|
|
1006
|
+
- Tapping outside the dialog card calls `onCancel`.
|
|
1007
|
+
- The cancel and confirm buttons are full-width stacked vertically.
|
|
1008
|
+
|
|
1009
|
+
**Example:**
|
|
1010
|
+
```tsx
|
|
1011
|
+
<ConfirmDialog
|
|
1012
|
+
visible={showDelete}
|
|
1013
|
+
title="¿Eliminar gasto?"
|
|
1014
|
+
description="$45.000 · Mercado · 12 mar"
|
|
1015
|
+
confirmLabel="Eliminar"
|
|
1016
|
+
confirmVariant="destructive"
|
|
1017
|
+
onConfirm={handleDelete}
|
|
1018
|
+
onCancel={() => setShowDelete(false)}
|
|
1019
|
+
/>
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
---
|
|
1023
|
+
|
|
1024
|
+
### LabelValue
|
|
1025
|
+
|
|
1026
|
+
**Import:** `import { LabelValue } from '@retray-dev/ui-kit'`
|
|
1027
|
+
**When to use:** Key-value display rows in receipts, summaries, and detail screens. Label on the left (muted caption), value on the right (medium weight).
|
|
1028
|
+
|
|
1029
|
+
| Prop | Type | Default | Notes |
|
|
1030
|
+
|------|------|---------|-------|
|
|
1031
|
+
| label | `string` | required | Caption text on the left |
|
|
1032
|
+
| value | `string \| ReactNode` | required | Value on the right. Strings are auto-styled; pass `ReactNode` for custom rendering |
|
|
1033
|
+
| style | `ViewStyle` | — | — |
|
|
1034
|
+
|
|
1035
|
+
**Example:**
|
|
1036
|
+
```tsx
|
|
1037
|
+
<LabelValue label="Fecha" value="12 mar 2025" />
|
|
1038
|
+
<LabelValue label="Categoría" value="Mercado" />
|
|
1039
|
+
<LabelValue label="Estado" value={<Badge label="Pendiente" variant="secondary" />} />
|
|
1040
|
+
```
|
|
1041
|
+
|
|
1042
|
+
---
|
|
1043
|
+
|
|
1044
|
+
### MonthPicker
|
|
1045
|
+
|
|
1046
|
+
**Import:** `import { MonthPicker } from '@retray-dev/ui-kit'`
|
|
1047
|
+
**When to use:** Compact month/year selector with previous/next navigation. Common in finance apps for filtering by period.
|
|
1048
|
+
|
|
1049
|
+
| Prop | Type | Default | Notes |
|
|
1050
|
+
|------|------|---------|-------|
|
|
1051
|
+
| value | `MonthPickerValue` | required | `{ month: number, year: number }` — `month` is 1–12 |
|
|
1052
|
+
| onChange | `(value: MonthPickerValue) => void` | required | Called on each navigation step |
|
|
1053
|
+
| style | `ViewStyle` | — | — |
|
|
1054
|
+
|
|
1055
|
+
**`MonthPickerValue`:** `{ month: number, year: number }` — month is 1-indexed (January = 1).
|
|
1056
|
+
|
|
1057
|
+
**Navigation:** Arrows wrap correctly at year boundaries (December → January increments the year; January → December decrements it). The component is fully controlled — no internal state.
|
|
1058
|
+
|
|
1059
|
+
**Example:**
|
|
1060
|
+
```tsx
|
|
1061
|
+
const [period, setPeriod] = useState({ month: new Date().getMonth() + 1, year: new Date().getFullYear() })
|
|
1062
|
+
|
|
1063
|
+
<MonthPicker value={period} onChange={setPeriod} />
|
|
1064
|
+
// Displays: "April 2026"
|
|
1065
|
+
```
|
package/README.md
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
A personal React Native / Expo UI component library with a built-in design system, dark mode support, haptic feedback, and smooth animations.
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
- Light/dark theme with
|
|
5
|
+
- 32 components across 6 categories
|
|
6
|
+
- Light/dark theme with 20 color tokens and full customization
|
|
7
7
|
- Apple HIG–compliant touch targets and haptic feedback
|
|
8
8
|
- Animated interactions: spring press, sliding tabs, accordion easing, animated progress
|
|
9
9
|
- Built with TypeScript — full type declarations included
|
|
@@ -93,18 +93,19 @@ import { useTheme } from '@retray-dev/ui-kit'
|
|
|
93
93
|
const { colors, colorScheme } = useTheme()
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
-
**Available tokens:** `background`, `foreground`, `card`, `cardForeground`, `primary`, `primaryForeground`, `secondary`, `secondaryForeground`, `muted`, `mutedForeground`, `accent`, `accentForeground`, `destructive`, `destructiveForeground`, `border`, `input`, `ring`
|
|
96
|
+
**Available tokens:** `background`, `foreground`, `card`, `cardForeground`, `primary`, `primaryForeground`, `secondary`, `secondaryForeground`, `muted`, `mutedForeground`, `accent`, `accentForeground`, `destructive`, `destructiveForeground`, `border`, `input`, `ring`, `success`, `successForeground`
|
|
97
97
|
|
|
98
98
|
## Components
|
|
99
99
|
|
|
100
100
|
| Category | Components |
|
|
101
101
|
| ----------- | ----------------------------------------------------------------------------------------------- |
|
|
102
|
-
| Display | `Text`, `Badge`, `Avatar`, `Separator`, `Spinner`, `Skeleton`, `Progress`, `CurrencyDisplay`
|
|
102
|
+
| Display | `Text`, `Badge`, `Avatar`, `Separator`, `Spinner`, `Skeleton`, `Progress`, `CurrencyDisplay` |
|
|
103
103
|
| Surfaces | `Card`, `Alert`, `EmptyState` |
|
|
104
104
|
| Form | `Button`, `Input`, `CurrencyInput`, `CurrencyInputLarge`, `Textarea`, `Checkbox`, `Switch`, `Toggle`, `RadioGroup`, `Select`, `Slider` |
|
|
105
105
|
| Composition | `Tabs`, `Accordion` |
|
|
106
|
-
| Overlays | `Sheet`
|
|
106
|
+
| Overlays | `Sheet`, `ConfirmDialog` |
|
|
107
107
|
| Feedback | `Toast` / `ToastProvider` / `useToast` |
|
|
108
|
+
| Data | `ListItem`, `Chip` / `ChipGroup`, `LabelValue`, `MonthPicker` |
|
|
108
109
|
|
|
109
110
|
### Quick examples
|
|
110
111
|
|