@retray-dev/ui-kit 1.6.0 → 1.8.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 +264 -15
- package/README.md +7 -6
- package/dist/index.d.mts +114 -11
- package/dist/index.d.ts +114 -11
- package/dist/index.js +660 -134
- package/dist/index.mjs +656 -138
- package/package.json +8 -8
- package/src/components/Accordion/Accordion.tsx +4 -4
- package/src/components/Alert/Alert.tsx +32 -8
- package/src/components/Alert/index.ts +2 -2
- package/src/components/Avatar/Avatar.tsx +8 -8
- package/src/components/Badge/Badge.tsx +4 -4
- package/src/components/Button/Button.tsx +21 -14
- package/src/components/Card/Card.tsx +9 -9
- package/src/components/Checkbox/Checkbox.tsx +8 -8
- package/src/components/Chip/Chip.tsx +142 -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 +48 -0
- package/src/components/CurrencyDisplay/index.ts +1 -0
- package/src/components/CurrencyInputLarge/CurrencyInputLarge.tsx +66 -0
- package/src/components/CurrencyInputLarge/index.ts +1 -0
- package/src/components/EmptyState/EmptyState.tsx +40 -6
- package/src/components/Input/Input.tsx +8 -8
- 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 +19 -19
- package/src/components/Switch/Switch.tsx +12 -7
- package/src/components/Tabs/Tabs.tsx +34 -15
- package/src/components/Text/Text.tsx +6 -6
- package/src/components/Textarea/Textarea.tsx +9 -9
- package/src/components/Toast/Toast.tsx +25 -7
- package/src/components/Toggle/Toggle.tsx +93 -24
- package/src/index.ts +7 -0
package/COMPONENTS.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @retray-dev/ui-kit — Component Reference (v1.
|
|
1
|
+
# @retray-dev/ui-kit — Component Reference (v1.8.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
|
|
|
@@ -76,6 +76,11 @@ function MyComponent() {
|
|
|
76
76
|
|
|
77
77
|
All 20 tokens are available via `useTheme().colors`.
|
|
78
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
|
+
```
|
|
83
|
+
|
|
79
84
|
| Token | Light | Dark | Semantic Role |
|
|
80
85
|
|-------|-------|------|---------------|
|
|
81
86
|
| `background` | `#ffffff` | `#171717` | Screen / page background |
|
|
@@ -142,7 +147,7 @@ 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'`) |
|
|
@@ -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
|
|
|
@@ -216,6 +222,7 @@ All 20 tokens are available via `useTheme().colors`.
|
|
|
216
222
|
const [display, setDisplay] = useState('')
|
|
217
223
|
const [amount, setAmount] = useState(0)
|
|
218
224
|
|
|
225
|
+
// Default: dot as thousands separator → "$1.234.567"
|
|
219
226
|
<CurrencyInput
|
|
220
227
|
label="Amount"
|
|
221
228
|
value={display}
|
|
@@ -224,10 +231,10 @@ const [amount, setAmount] = useState(0)
|
|
|
224
231
|
hint={`Parsed: ${amount}`}
|
|
225
232
|
/>
|
|
226
233
|
|
|
227
|
-
//
|
|
234
|
+
// Comma as thousands separator → "$1,234,567"
|
|
228
235
|
<CurrencyInput
|
|
229
|
-
prefix="
|
|
230
|
-
thousandsSeparator="
|
|
236
|
+
prefix="$"
|
|
237
|
+
thousandsSeparator=","
|
|
231
238
|
value={display}
|
|
232
239
|
onChangeText={setDisplay}
|
|
233
240
|
onChangeValue={setAmount}
|
|
@@ -379,6 +386,73 @@ const [amount, setAmount] = useState(0)
|
|
|
379
386
|
|
|
380
387
|
---
|
|
381
388
|
|
|
389
|
+
### CurrencyDisplay
|
|
390
|
+
|
|
391
|
+
**Import:** `import { CurrencyDisplay } from '@retray-dev/ui-kit'`
|
|
392
|
+
**When to use:** Prominent display of monetary values (account balances, totals). Large, attention-grabbing typographic treatment with dot-separated thousands and optional comma-decimal.
|
|
393
|
+
|
|
394
|
+
| Prop | Type | Default | Notes |
|
|
395
|
+
|------|------|---------|-------|
|
|
396
|
+
| value | `number \| string` | required | Numeric value to display |
|
|
397
|
+
| prefix | `string` | `'$'` | Symbol prepended to the formatted value |
|
|
398
|
+
| showDecimals | `boolean` | `false` | When `true`, shows two decimal places separated by a comma (e.g. `$25.000,00`) |
|
|
399
|
+
| textColor | `string` | — | Override the color of the formatted text. Defaults to the `foreground` token |
|
|
400
|
+
| style | `ViewStyle` | — | Style override for outer container |
|
|
401
|
+
|
|
402
|
+
**Example:**
|
|
403
|
+
```tsx
|
|
404
|
+
<CurrencyDisplay value={25000} />
|
|
405
|
+
// → $25.000
|
|
406
|
+
|
|
407
|
+
<CurrencyDisplay value={25000000.5} showDecimals />
|
|
408
|
+
// → $25.000.000,50
|
|
409
|
+
|
|
410
|
+
<CurrencyDisplay value={1500} prefix="€" />
|
|
411
|
+
// → €1.500
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
**Notes:**
|
|
415
|
+
- Uses dot (`.`) as thousands separator and comma (`,`) as decimal separator — Latin American / European format.
|
|
416
|
+
- Intended as a display-only component (not editable).
|
|
417
|
+
- `allowFontScaling={true}` is set on the inner `Text`.
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
### CurrencyInputLarge
|
|
422
|
+
|
|
423
|
+
**Import:** `import { CurrencyInputLarge } from '@retray-dev/ui-kit'`
|
|
424
|
+
**When to use:** Large, form-style monetary input for prominent entry screens (payments, transfers). Same formatting behavior as `CurrencyInput` but with 36px font size.
|
|
425
|
+
|
|
426
|
+
| Prop | Type | Default | Notes |
|
|
427
|
+
|------|------|---------|-------|
|
|
428
|
+
| value | `string` | — | Controlled display value (includes prefix, e.g. `'$1.234'`) |
|
|
429
|
+
| onChangeText | `(formatted: string) => void` | — | Called with the formatted display string |
|
|
430
|
+
| onChangeValue | `(raw: number) => void` | — | Called with the parsed number (no separators, no prefix) |
|
|
431
|
+
| label | `string` | — | Label above the input |
|
|
432
|
+
| prefix | `string` | `'$'` | Currency prefix |
|
|
433
|
+
| thousandsSeparator | `'.' \| ','` | `'.'` | Separator used to format groups of three digits |
|
|
434
|
+
| error | `string` | — | Error text below; turns border red |
|
|
435
|
+
| hint | `string` | — | Helper text below (hidden when `error` is set) |
|
|
436
|
+
| placeholder | `string` | `'$0'` | Defaults to `prefix + '0'` |
|
|
437
|
+
| editable | `boolean` | — | Pass `false` to disable editing |
|
|
438
|
+
| containerStyle | `ViewStyle` | — | Style for the outer container |
|
|
439
|
+
|
|
440
|
+
**Example:**
|
|
441
|
+
```tsx
|
|
442
|
+
const [display, setDisplay] = useState('')
|
|
443
|
+
const [amount, setAmount] = useState(0)
|
|
444
|
+
|
|
445
|
+
<CurrencyInputLarge
|
|
446
|
+
label="Amount"
|
|
447
|
+
value={display}
|
|
448
|
+
onChangeText={setDisplay}
|
|
449
|
+
onChangeValue={setAmount}
|
|
450
|
+
/>
|
|
451
|
+
// Typing "25000" produces "$25.000"
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
382
456
|
### Card
|
|
383
457
|
|
|
384
458
|
**Import:** `import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@retray-dev/ui-kit'`
|
|
@@ -403,30 +477,33 @@ All sub-components accept a `style` prop for overrides.
|
|
|
403
477
|
```
|
|
404
478
|
|
|
405
479
|
**Notes:**
|
|
406
|
-
- `CardHeader` and `CardContent` have `padding: 24`
|
|
480
|
+
- `CardHeader` and `CardContent` have `padding: 24`. Override via the `style` prop: `<CardContent style={{ padding: 16 }}>`
|
|
407
481
|
- `CardFooter` has `paddingTop: 0` so it connects naturally to `CardContent`
|
|
408
482
|
- `CardTitle`: 18px / 600 weight, `cardForeground` color
|
|
409
483
|
- `CardDescription`: 14px, `mutedForeground` color
|
|
410
484
|
|
|
411
485
|
---
|
|
412
486
|
|
|
413
|
-
###
|
|
487
|
+
### AlertBanner
|
|
414
488
|
|
|
415
|
-
**Import:** `import {
|
|
416
|
-
**When to use:** Inline feedback messages (info, success,
|
|
489
|
+
**Import:** `import { AlertBanner } from '@retray-dev/ui-kit'`
|
|
490
|
+
**When to use:** Inline feedback messages (info, success, error). Not for transient toasts — use `Toast` for ephemeral feedback.
|
|
491
|
+
|
|
492
|
+
> **Note:** Named `AlertBanner` (not `Alert`) to avoid collision with React Native's built-in `Alert` module.
|
|
417
493
|
|
|
418
494
|
| Prop | Type | Default | Notes |
|
|
419
495
|
|------|------|---------|-------|
|
|
420
496
|
| title | `string` | — | Bold heading |
|
|
421
497
|
| description | `string` | — | Detail text |
|
|
422
|
-
| variant | `'default' \| 'destructive'` | `'default'` |
|
|
423
|
-
| icon | `ReactNode` | — | Icon placed to the left of the text content |
|
|
498
|
+
| variant | `'default' \| 'destructive' \| 'success'` | `'default'` | Controls border/text color |
|
|
499
|
+
| icon | `ReactNode` | — | Icon placed to the left of the text content. Defaults to a variant-appropriate symbol (`ℹ`, `⚠`, `✓`) |
|
|
424
500
|
| style | `ViewStyle` | — | — |
|
|
425
501
|
|
|
426
502
|
**Example:**
|
|
427
503
|
```tsx
|
|
428
|
-
<
|
|
429
|
-
<
|
|
504
|
+
<AlertBanner title="Info" description="Your session will expire in 5 minutes." />
|
|
505
|
+
<AlertBanner variant="destructive" title="Error" description="Failed to save. Try again." />
|
|
506
|
+
<AlertBanner variant="success" title="Done" description="Your changes have been saved." />
|
|
430
507
|
```
|
|
431
508
|
|
|
432
509
|
---
|
|
@@ -442,6 +519,7 @@ All sub-components accept a `style` prop for overrides.
|
|
|
442
519
|
| description | `string` | — | — |
|
|
443
520
|
| icon | `ReactNode` | — | Shown in a 48×48 muted square above the text |
|
|
444
521
|
| action | `ReactNode` | — | Usually a `Button`, placed below the text |
|
|
522
|
+
| size | `'default' \| 'compact'` | `'default'` | `compact` hides description/action, uses a 36×36 icon, smaller title (15px), and tighter spacing |
|
|
445
523
|
| style | `ViewStyle` | — | — |
|
|
446
524
|
|
|
447
525
|
**Example:**
|
|
@@ -487,7 +565,7 @@ const [accepted, setAccepted] = useState(false)
|
|
|
487
565
|
| disabled | `boolean` | — | Reduces opacity to 0.45 |
|
|
488
566
|
| style | `ViewStyle` | — | — |
|
|
489
567
|
|
|
490
|
-
**Dimensions:** Track
|
|
568
|
+
**Dimensions:** Track 60×36pt, Thumb 28×28pt with 4pt offset from edges (`top: 4, left: 4`). Thumb uses `position: 'absolute'` inside the track.
|
|
491
569
|
|
|
492
570
|
**Animation:** Thumb translates via spring (bounciness: 4); track color transitions via opacity timing (150ms).
|
|
493
571
|
|
|
@@ -510,11 +588,22 @@ const [accepted, setAccepted] = useState(false)
|
|
|
510
588
|
| variant | `'default' \| 'outline'` | `'default'` | `outline` adds a border when unpressed |
|
|
511
589
|
| size | `'sm' \| 'md' \| 'lg'` | `'md'` | sm=minH 40pt, md=minH 44pt, lg=minH 48pt |
|
|
512
590
|
| label | `string` | — | Text label |
|
|
513
|
-
| icon | `ReactNode` | — | Icon — can be combined with `label` |
|
|
591
|
+
| icon | `ReactNode \| ((pressed: boolean) => ReactNode)` | — | Icon shown when not pressed — can be combined with `label` |
|
|
592
|
+
| activeIcon | `ReactNode \| ((pressed: boolean) => ReactNode)` | — | Icon shown when pressed. If omitted, a default `✓` check mark is shown |
|
|
593
|
+
|
|
594
|
+
**Animation:** `borderColor` and `backgroundColor` animate via `Animated.timing` (150ms, `Easing.out`) on press state change. `borderWidth` stays fixed at 2pt to prevent layout jumps.
|
|
514
595
|
|
|
515
596
|
**Example:**
|
|
516
597
|
```tsx
|
|
517
598
|
<Toggle pressed={bold} onPressedChange={setBold} label="Bold" variant="outline" />
|
|
599
|
+
|
|
600
|
+
// With custom active icon
|
|
601
|
+
<Toggle
|
|
602
|
+
pressed={favorited}
|
|
603
|
+
onPressedChange={setFavorited}
|
|
604
|
+
icon={<HeartIcon size={18} />}
|
|
605
|
+
activeIcon={<HeartIcon size={18} color={colors.primary} />}
|
|
606
|
+
/>
|
|
518
607
|
```
|
|
519
608
|
|
|
520
609
|
---
|
|
@@ -694,6 +783,11 @@ pnpm add @gorhom/bottom-sheet react-native-reanimated react-native-gesture-handl
|
|
|
694
783
|
```
|
|
695
784
|
Add `react-native-worklets/plugin` (not `react-native-reanimated/plugin`) to your `babel.config.js` plugins.
|
|
696
785
|
|
|
786
|
+
> **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:
|
|
787
|
+
> ```json
|
|
788
|
+
> { "expo": { "install": { "exclude": ["@gorhom/bottom-sheet"] } } }
|
|
789
|
+
> ```
|
|
790
|
+
|
|
697
791
|
| Prop | Type | Default | Notes |
|
|
698
792
|
|------|------|---------|-------|
|
|
699
793
|
| open | `boolean` | required | `true` presents the sheet, `false` dismisses it |
|
|
@@ -748,6 +842,7 @@ function MyComponent() {
|
|
|
748
842
|
| description | `string` | — | Detail text |
|
|
749
843
|
| variant | `'default' \| 'destructive' \| 'success'` | `'default'` | `default`: dark background. `destructive`: red. `success`: green |
|
|
750
844
|
| duration | `number` (ms) | `3000` | Auto-dismiss after this delay |
|
|
845
|
+
| icon | `ReactNode` | — | Custom icon node. Defaults to a variant-appropriate symbol (`✓`, `✖`, `ℹ`) at 22px |
|
|
751
846
|
|
|
752
847
|
**`dismiss(id)`:** Dismiss a toast programmatically. The `id` is returned by the `toast()` call — store it if you need programmatic dismissal.
|
|
753
848
|
|
|
@@ -757,3 +852,157 @@ function MyComponent() {
|
|
|
757
852
|
- Entrance: `withTiming(120ms, Easing.out(Easing.exp))` slide-down + opacity fade — fast, sharp feel
|
|
758
853
|
- Exit: `withTiming(200ms)` slide-up + opacity fade
|
|
759
854
|
- Swipe left or right to dismiss early (threshold: 80px or 800 pt/s velocity)
|
|
855
|
+
|
|
856
|
+
---
|
|
857
|
+
|
|
858
|
+
### ListItem
|
|
859
|
+
|
|
860
|
+
**Import:** `import { ListItem } from '@retray-dev/ui-kit'`
|
|
861
|
+
**When to use:** Rows in a list or menu. Composes icon, title, subtitle, and trailing content in a standard horizontal layout.
|
|
862
|
+
|
|
863
|
+
| Prop | Type | Default | Notes |
|
|
864
|
+
|------|------|---------|-------|
|
|
865
|
+
| title | `string` | required | Primary label |
|
|
866
|
+
| subtitle | `string` | — | Secondary label below the title |
|
|
867
|
+
| icon | `ReactNode` | — | Node rendered to the left of the text content |
|
|
868
|
+
| trailing | `string \| ReactNode` | — | Content on the right edge. Strings are styled as muted caption |
|
|
869
|
+
| onPress | `() => void` | — | Makes the row pressable. Scale animation + haptics are only active when provided |
|
|
870
|
+
| disabled | `boolean` | — | Reduces opacity to 0.45 |
|
|
871
|
+
| style | `ViewStyle` | — | — |
|
|
872
|
+
|
|
873
|
+
**Example:**
|
|
874
|
+
```tsx
|
|
875
|
+
<ListItem
|
|
876
|
+
icon={<Ionicons name="receipt-outline" size={18} />}
|
|
877
|
+
title="Mercado"
|
|
878
|
+
subtitle="12 mar 2025"
|
|
879
|
+
trailing="$45.000"
|
|
880
|
+
onPress={() => navigate('detail')}
|
|
881
|
+
/>
|
|
882
|
+
|
|
883
|
+
// Non-interactive row
|
|
884
|
+
<ListItem title="Account number" trailing="**** 4321" />
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
---
|
|
888
|
+
|
|
889
|
+
### Chip / ChipGroup
|
|
890
|
+
|
|
891
|
+
**Import:** `import { Chip, ChipGroup } from '@retray-dev/ui-kit'`
|
|
892
|
+
**When to use:** Filter pills, single-select options displayed inline. Use `ChipGroup` for managed single-selection; use `Chip` standalone for custom logic.
|
|
893
|
+
|
|
894
|
+
**`Chip` Props:**
|
|
895
|
+
|
|
896
|
+
| Prop | Type | Default | Notes |
|
|
897
|
+
|------|------|---------|-------|
|
|
898
|
+
| label | `string` | required | — |
|
|
899
|
+
| selected | `boolean` | `false` | Controls fill color |
|
|
900
|
+
| onPress | `() => void` | — | — |
|
|
901
|
+
| style | `ViewStyle` | — | — |
|
|
902
|
+
|
|
903
|
+
**`ChipGroup` Props:**
|
|
904
|
+
|
|
905
|
+
| Prop | Type | Default | Notes |
|
|
906
|
+
|------|------|---------|-------|
|
|
907
|
+
| options | `ChipOption[]` | required | Each: `{ label: string, value: string \| number }` |
|
|
908
|
+
| value | `string \| number` | — | Currently selected value |
|
|
909
|
+
| onValueChange | `(value: string \| number) => void` | — | — |
|
|
910
|
+
| style | `ViewStyle` | — | Applied to the wrapping row |
|
|
911
|
+
|
|
912
|
+
**Animation:** Background, text, and border colors animate via `Animated.timing` (150ms) between unselected (`secondary`/`border`/`foreground`) and selected (`primary`/`primary`/`primaryForeground`) states.
|
|
913
|
+
|
|
914
|
+
**Example:**
|
|
915
|
+
```tsx
|
|
916
|
+
const [pct, setPct] = useState(50)
|
|
917
|
+
|
|
918
|
+
<ChipGroup
|
|
919
|
+
options={[
|
|
920
|
+
{ label: '40%', value: 40 },
|
|
921
|
+
{ label: '50%', value: 50 },
|
|
922
|
+
{ label: '100%', value: 100 },
|
|
923
|
+
]}
|
|
924
|
+
value={pct}
|
|
925
|
+
onValueChange={setPct}
|
|
926
|
+
/>
|
|
927
|
+
```
|
|
928
|
+
|
|
929
|
+
---
|
|
930
|
+
|
|
931
|
+
### ConfirmDialog
|
|
932
|
+
|
|
933
|
+
**Import:** `import { ConfirmDialog } from '@retray-dev/ui-kit'`
|
|
934
|
+
**When to use:** Confirmation prompts before irreversible or destructive actions (delete, send, discard).
|
|
935
|
+
|
|
936
|
+
| Prop | Type | Default | Notes |
|
|
937
|
+
|------|------|---------|-------|
|
|
938
|
+
| visible | `boolean` | required | Controls modal visibility |
|
|
939
|
+
| title | `string` | required | Dialog heading |
|
|
940
|
+
| description | `string` | — | Supporting text below the title |
|
|
941
|
+
| confirmLabel | `string` | `'Confirm'` | Label for the confirm button |
|
|
942
|
+
| cancelLabel | `string` | `'Cancel'` | Label for the cancel button |
|
|
943
|
+
| confirmVariant | `'primary' \| 'destructive'` | `'primary'` | Button variant for the confirm action |
|
|
944
|
+
| onConfirm | `() => void` | required | Called when confirm is tapped |
|
|
945
|
+
| onCancel | `() => void` | required | Called when cancel is tapped or backdrop is pressed |
|
|
946
|
+
|
|
947
|
+
**Notes:**
|
|
948
|
+
- Uses React Native `Modal` with `animationType="fade"` — no bottom-sheet dependency.
|
|
949
|
+
- Tapping outside the dialog card calls `onCancel`.
|
|
950
|
+
- The cancel and confirm buttons are full-width stacked vertically.
|
|
951
|
+
|
|
952
|
+
**Example:**
|
|
953
|
+
```tsx
|
|
954
|
+
<ConfirmDialog
|
|
955
|
+
visible={showDelete}
|
|
956
|
+
title="¿Eliminar gasto?"
|
|
957
|
+
description="$45.000 · Mercado · 12 mar"
|
|
958
|
+
confirmLabel="Eliminar"
|
|
959
|
+
confirmVariant="destructive"
|
|
960
|
+
onConfirm={handleDelete}
|
|
961
|
+
onCancel={() => setShowDelete(false)}
|
|
962
|
+
/>
|
|
963
|
+
```
|
|
964
|
+
|
|
965
|
+
---
|
|
966
|
+
|
|
967
|
+
### LabelValue
|
|
968
|
+
|
|
969
|
+
**Import:** `import { LabelValue } from '@retray-dev/ui-kit'`
|
|
970
|
+
**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).
|
|
971
|
+
|
|
972
|
+
| Prop | Type | Default | Notes |
|
|
973
|
+
|------|------|---------|-------|
|
|
974
|
+
| label | `string` | required | Caption text on the left |
|
|
975
|
+
| value | `string \| ReactNode` | required | Value on the right. Strings are auto-styled; pass `ReactNode` for custom rendering |
|
|
976
|
+
| style | `ViewStyle` | — | — |
|
|
977
|
+
|
|
978
|
+
**Example:**
|
|
979
|
+
```tsx
|
|
980
|
+
<LabelValue label="Fecha" value="12 mar 2025" />
|
|
981
|
+
<LabelValue label="Categoría" value="Mercado" />
|
|
982
|
+
<LabelValue label="Estado" value={<Badge label="Pendiente" variant="secondary" />} />
|
|
983
|
+
```
|
|
984
|
+
|
|
985
|
+
---
|
|
986
|
+
|
|
987
|
+
### MonthPicker
|
|
988
|
+
|
|
989
|
+
**Import:** `import { MonthPicker } from '@retray-dev/ui-kit'`
|
|
990
|
+
**When to use:** Compact month/year selector with previous/next navigation. Common in finance apps for filtering by period.
|
|
991
|
+
|
|
992
|
+
| Prop | Type | Default | Notes |
|
|
993
|
+
|------|------|---------|-------|
|
|
994
|
+
| value | `MonthPickerValue` | required | `{ month: number, year: number }` — `month` is 1–12 |
|
|
995
|
+
| onChange | `(value: MonthPickerValue) => void` | required | Called on each navigation step |
|
|
996
|
+
| style | `ViewStyle` | — | — |
|
|
997
|
+
|
|
998
|
+
**`MonthPickerValue`:** `{ month: number, year: number }` — month is 1-indexed (January = 1).
|
|
999
|
+
|
|
1000
|
+
**Navigation:** Arrows wrap correctly at year boundaries (December → January increments the year; January → December decrements it). The component is fully controlled — no internal state.
|
|
1001
|
+
|
|
1002
|
+
**Example:**
|
|
1003
|
+
```tsx
|
|
1004
|
+
const [period, setPeriod] = useState({ month: new Date().getMonth() + 1, year: new Date().getFullYear() })
|
|
1005
|
+
|
|
1006
|
+
<MonthPicker value={period} onChange={setPeriod} />
|
|
1007
|
+
// Displays: "April 2026"
|
|
1008
|
+
```
|
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`
|
|
102
|
+
| Display | `Text`, `Badge`, `Avatar`, `Separator`, `Spinner`, `Skeleton`, `Progress`, `CurrencyDisplay` |
|
|
103
103
|
| Surfaces | `Card`, `Alert`, `EmptyState` |
|
|
104
|
-
| Form | `Button`, `Input`, `CurrencyInput`, `Textarea`, `Checkbox`, `Switch`, `Toggle`, `RadioGroup`, `Select`, `Slider` |
|
|
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
|
|
package/dist/index.d.mts
CHANGED
|
@@ -55,7 +55,7 @@ declare function useTheme(): ThemeContextValue;
|
|
|
55
55
|
declare const defaultLight: ThemeColors;
|
|
56
56
|
declare const defaultDark: ThemeColors;
|
|
57
57
|
|
|
58
|
-
type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost';
|
|
58
|
+
type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost' | 'destructive';
|
|
59
59
|
type ButtonSize = 'sm' | 'md' | 'lg';
|
|
60
60
|
interface ButtonProps extends TouchableOpacityProps {
|
|
61
61
|
label: string;
|
|
@@ -70,8 +70,12 @@ interface ButtonProps extends TouchableOpacityProps {
|
|
|
70
70
|
/** Replaces the label with a spinner and forces `disabled`. */
|
|
71
71
|
loading?: boolean;
|
|
72
72
|
fullWidth?: boolean;
|
|
73
|
-
/** Icon rendered alongside the label. */
|
|
74
|
-
icon?: React.ReactNode
|
|
73
|
+
/** Icon rendered alongside the label. Can be a ReactNode or a render function `(props) => ReactNode`. */
|
|
74
|
+
icon?: React.ReactNode | ((props: {
|
|
75
|
+
label: string;
|
|
76
|
+
size: ButtonSize;
|
|
77
|
+
variant: ButtonVariant;
|
|
78
|
+
}) => React.ReactNode);
|
|
75
79
|
/** Side the icon appears on. Defaults to `'left'`. */
|
|
76
80
|
iconPosition?: 'left' | 'right';
|
|
77
81
|
}
|
|
@@ -166,15 +170,15 @@ interface AvatarProps {
|
|
|
166
170
|
}
|
|
167
171
|
declare function Avatar({ src, fallback, size, style }: AvatarProps): React.JSX.Element;
|
|
168
172
|
|
|
169
|
-
type
|
|
170
|
-
interface
|
|
173
|
+
type AlertBannerVariant = 'default' | 'destructive' | 'success';
|
|
174
|
+
interface AlertBannerProps {
|
|
171
175
|
title?: string;
|
|
172
176
|
description?: string;
|
|
173
|
-
variant?:
|
|
177
|
+
variant?: AlertBannerVariant;
|
|
174
178
|
icon?: React.ReactNode;
|
|
175
179
|
style?: ViewStyle;
|
|
176
180
|
}
|
|
177
|
-
declare function
|
|
181
|
+
declare function AlertBanner({ title, description, variant, icon, style }: AlertBannerProps): React.JSX.Element;
|
|
178
182
|
|
|
179
183
|
interface ProgressProps {
|
|
180
184
|
/** Current progress value. Clamped to `[0, max]`. Defaults to `0`. */
|
|
@@ -190,9 +194,11 @@ interface EmptyStateProps {
|
|
|
190
194
|
title: string;
|
|
191
195
|
description?: string;
|
|
192
196
|
action?: React.ReactNode;
|
|
197
|
+
/** `compact` hides description/action and uses tighter spacing and a smaller icon. */
|
|
198
|
+
size?: 'default' | 'compact';
|
|
193
199
|
style?: ViewStyle;
|
|
194
200
|
}
|
|
195
|
-
declare function EmptyState({ icon, title, description, action, style }: EmptyStateProps): React.JSX.Element;
|
|
201
|
+
declare function EmptyState({ icon, title, description, action, size, style }: EmptyStateProps): React.JSX.Element;
|
|
196
202
|
|
|
197
203
|
interface TextareaProps extends TextInputProps {
|
|
198
204
|
label?: string;
|
|
@@ -232,9 +238,12 @@ interface ToggleProps extends TouchableOpacityProps {
|
|
|
232
238
|
variant?: ToggleVariant;
|
|
233
239
|
size?: ToggleSize;
|
|
234
240
|
label?: string;
|
|
235
|
-
|
|
241
|
+
/** Icon to show when not pressed */
|
|
242
|
+
icon?: React.ReactNode | ((pressed: boolean) => React.ReactNode);
|
|
243
|
+
/** Icon to show when pressed/active. If omitted, a default check mark is used. */
|
|
244
|
+
activeIcon?: React.ReactNode | ((pressed: boolean) => React.ReactNode);
|
|
236
245
|
}
|
|
237
|
-
declare function Toggle({ pressed, onPressedChange, variant, size, label, icon, disabled, style, ...props }: ToggleProps): React.JSX.Element;
|
|
246
|
+
declare function Toggle({ pressed, onPressedChange, variant, size, label, icon, activeIcon, disabled, style, ...props }: ToggleProps): React.JSX.Element;
|
|
238
247
|
|
|
239
248
|
interface RadioOption {
|
|
240
249
|
label: string;
|
|
@@ -253,6 +262,7 @@ declare function RadioGroup({ options, value, onValueChange, orientation, style,
|
|
|
253
262
|
interface TabItem {
|
|
254
263
|
label: string;
|
|
255
264
|
value: string;
|
|
265
|
+
icon?: React.ReactNode;
|
|
256
266
|
}
|
|
257
267
|
interface TabsProps {
|
|
258
268
|
tabs: TabItem[];
|
|
@@ -349,6 +359,7 @@ interface ToastItem {
|
|
|
349
359
|
title?: string;
|
|
350
360
|
description?: string;
|
|
351
361
|
variant?: ToastVariant;
|
|
362
|
+
icon?: React.ReactNode;
|
|
352
363
|
/** Auto-dismiss delay in milliseconds. Defaults to `3000`. */
|
|
353
364
|
duration?: number;
|
|
354
365
|
}
|
|
@@ -386,4 +397,96 @@ interface CurrencyInputProps {
|
|
|
386
397
|
}
|
|
387
398
|
declare function CurrencyInput({ value, onChangeText, onChangeValue, prefix, thousandsSeparator, label, error, hint, placeholder, editable, containerStyle, }: CurrencyInputProps): React.JSX.Element;
|
|
388
399
|
|
|
389
|
-
|
|
400
|
+
interface CurrencyDisplayProps {
|
|
401
|
+
value: number | string;
|
|
402
|
+
/** Symbol prepended to the formatted value. Defaults to `'$'`. */
|
|
403
|
+
prefix?: string;
|
|
404
|
+
/** When true, shows two decimal places separated by a comma (e.g. `$25.000,00`). Defaults to `false`. */
|
|
405
|
+
showDecimals?: boolean;
|
|
406
|
+
/** Override the color of the formatted text. Defaults to the `foreground` theme token. */
|
|
407
|
+
textColor?: string;
|
|
408
|
+
style?: ViewStyle;
|
|
409
|
+
}
|
|
410
|
+
declare function CurrencyDisplay({ value, prefix, showDecimals, textColor, style }: CurrencyDisplayProps): React.JSX.Element;
|
|
411
|
+
|
|
412
|
+
interface CurrencyInputLargeProps {
|
|
413
|
+
value?: string;
|
|
414
|
+
onChangeText?: (formatted: string) => void;
|
|
415
|
+
/** Called with the parsed numeric value (no separators, no prefix). */
|
|
416
|
+
onChangeValue?: (raw: number) => void;
|
|
417
|
+
/** Symbol prepended to the formatted value. Defaults to `'$'`. */
|
|
418
|
+
prefix?: string;
|
|
419
|
+
/** Character used to separate groups of three digits. Defaults to `'.'`. */
|
|
420
|
+
thousandsSeparator?: '.' | ',';
|
|
421
|
+
label?: string;
|
|
422
|
+
/** Red helper text; also changes input border to destructive color. */
|
|
423
|
+
error?: string;
|
|
424
|
+
hint?: string;
|
|
425
|
+
placeholder?: string;
|
|
426
|
+
editable?: boolean;
|
|
427
|
+
containerStyle?: ViewStyle;
|
|
428
|
+
}
|
|
429
|
+
declare function CurrencyInputLarge({ value, onChangeText, onChangeValue, prefix, thousandsSeparator, label, error, hint, placeholder, editable, containerStyle, }: CurrencyInputLargeProps): React.JSX.Element;
|
|
430
|
+
|
|
431
|
+
interface ListItemProps {
|
|
432
|
+
icon?: React.ReactNode;
|
|
433
|
+
title: string;
|
|
434
|
+
subtitle?: string;
|
|
435
|
+
trailing?: string | React.ReactNode;
|
|
436
|
+
onPress?: () => void;
|
|
437
|
+
disabled?: boolean;
|
|
438
|
+
style?: ViewStyle;
|
|
439
|
+
}
|
|
440
|
+
declare function ListItem({ icon, title, subtitle, trailing, onPress, disabled, style }: ListItemProps): React.JSX.Element;
|
|
441
|
+
|
|
442
|
+
interface ChipProps {
|
|
443
|
+
label: string;
|
|
444
|
+
selected?: boolean;
|
|
445
|
+
onPress?: () => void;
|
|
446
|
+
style?: ViewStyle;
|
|
447
|
+
}
|
|
448
|
+
interface ChipOption {
|
|
449
|
+
label: string;
|
|
450
|
+
value: string | number;
|
|
451
|
+
}
|
|
452
|
+
interface ChipGroupProps {
|
|
453
|
+
options: ChipOption[];
|
|
454
|
+
value?: string | number;
|
|
455
|
+
onValueChange?: (value: string | number) => void;
|
|
456
|
+
style?: ViewStyle;
|
|
457
|
+
}
|
|
458
|
+
declare function Chip({ label, selected, onPress, style }: ChipProps): React.JSX.Element;
|
|
459
|
+
declare function ChipGroup({ options, value, onValueChange, style }: ChipGroupProps): React.JSX.Element;
|
|
460
|
+
|
|
461
|
+
interface ConfirmDialogProps {
|
|
462
|
+
visible: boolean;
|
|
463
|
+
title: string;
|
|
464
|
+
description?: string;
|
|
465
|
+
confirmLabel?: string;
|
|
466
|
+
cancelLabel?: string;
|
|
467
|
+
confirmVariant?: 'primary' | 'destructive';
|
|
468
|
+
onConfirm: () => void;
|
|
469
|
+
onCancel: () => void;
|
|
470
|
+
}
|
|
471
|
+
declare function ConfirmDialog({ visible, title, description, confirmLabel, cancelLabel, confirmVariant, onConfirm, onCancel, }: ConfirmDialogProps): React.JSX.Element;
|
|
472
|
+
|
|
473
|
+
interface LabelValueProps {
|
|
474
|
+
label: string;
|
|
475
|
+
value: string | React.ReactNode;
|
|
476
|
+
style?: ViewStyle;
|
|
477
|
+
}
|
|
478
|
+
declare function LabelValue({ label, value, style }: LabelValueProps): React.JSX.Element;
|
|
479
|
+
|
|
480
|
+
interface MonthPickerValue {
|
|
481
|
+
/** Month number 1–12 */
|
|
482
|
+
month: number;
|
|
483
|
+
year: number;
|
|
484
|
+
}
|
|
485
|
+
interface MonthPickerProps {
|
|
486
|
+
value: MonthPickerValue;
|
|
487
|
+
onChange: (value: MonthPickerValue) => void;
|
|
488
|
+
style?: ViewStyle;
|
|
489
|
+
}
|
|
490
|
+
declare function MonthPicker({ value, onChange, style }: MonthPickerProps): React.JSX.Element;
|
|
491
|
+
|
|
492
|
+
export { Accordion, type AccordionItem, type AccordionProps, AlertBanner, type AlertBannerProps, type AlertBannerVariant, Avatar, type AvatarProps, type AvatarSize, Badge, type BadgeProps, type BadgeVariant, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Card, CardContent, type CardContentProps, CardDescription, type CardDescriptionProps, CardFooter, type CardFooterProps, CardHeader, type CardHeaderProps, type CardProps, CardTitle, type CardTitleProps, Checkbox, type CheckboxProps, Chip, ChipGroup, type ChipGroupProps, type ChipOption, type ChipProps, type ColorScheme, ConfirmDialog, type ConfirmDialogProps, CurrencyDisplay, type CurrencyDisplayProps, CurrencyInput, CurrencyInputLarge, type CurrencyInputLargeProps, type CurrencyInputProps, EmptyState, type EmptyStateProps, Input, type InputProps, LabelValue, type LabelValueProps, ListItem, type ListItemProps, MonthPicker, type MonthPickerProps, type MonthPickerValue, Progress, type ProgressProps, RadioGroup, type RadioGroupProps, type RadioOption, Select, type SelectOption, type SelectProps, Separator, type SeparatorProps, Sheet, type SheetProps, Skeleton, type SkeletonProps, Slider, type SliderProps, Spinner, type SpinnerProps, type SpinnerSize, Switch, type SwitchProps, type TabItem, Tabs, TabsContent, type TabsContentProps, type TabsProps, Text, type TextProps, type TextVariant, Textarea, type TextareaProps, type Theme, type ThemeColors, ThemeProvider, type ThemeProviderProps, type ToastItem, ToastProvider, type ToastProviderProps, type ToastVariant, Toggle, type ToggleProps, type ToggleSize, type ToggleVariant, defaultDark, defaultLight, useTheme, useToast };
|