@retray-dev/ui-kit 10.2.0 → 12.1.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 +287 -37
- package/README.md +11 -2
- package/dist/Accordion.mjs +2 -2
- package/dist/AlertBanner.mjs +2 -2
- package/dist/AppHeader.mjs +3 -3
- package/dist/Avatar.mjs +2 -2
- package/dist/Badge.mjs +2 -2
- package/dist/Button.mjs +2 -2
- package/dist/Card.mjs +2 -2
- package/dist/CategoryStrip.mjs +2 -2
- package/dist/Checkbox.mjs +2 -2
- package/dist/Chip.mjs +2 -2
- package/dist/ConfirmDialog.d.mts +1 -6
- package/dist/ConfirmDialog.d.ts +1 -6
- package/dist/ConfirmDialog.js +29 -23
- package/dist/ConfirmDialog.mjs +3 -3
- package/dist/CurrencyDisplay.mjs +2 -2
- package/dist/CurrencyInput.d.mts +3 -8
- package/dist/CurrencyInput.d.ts +3 -8
- package/dist/CurrencyInput.js +3 -1
- package/dist/CurrencyInput.mjs +3 -3
- package/dist/DetailRow.mjs +2 -2
- package/dist/EmptyState.mjs +3 -3
- package/dist/ErrorBoundary.mjs +2 -2
- package/dist/Form.mjs +2 -2
- package/dist/IconButton.mjs +2 -2
- package/dist/IconPicker.js +675 -248
- package/dist/IconPicker.mjs +3 -2
- package/dist/ImageUpload.mjs +3 -3
- package/dist/ImageViewer.mjs +4 -4
- package/dist/Input.mjs +2 -2
- package/dist/LabelValue.mjs +2 -2
- package/dist/ListGroup.mjs +2 -2
- package/dist/ListItem.d.mts +7 -7
- package/dist/ListItem.d.ts +7 -7
- package/dist/ListItem.js +12 -7
- package/dist/ListItem.mjs +2 -2
- package/dist/MediaCard.mjs +2 -2
- package/dist/MenuGroup.mjs +2 -2
- package/dist/MenuItem.mjs +2 -2
- package/dist/MonthPicker.mjs +2 -2
- package/dist/NumberStepper.mjs +2 -2
- package/dist/PagerDots.mjs +2 -2
- package/dist/Pressable.d.mts +15 -7
- package/dist/Pressable.d.ts +15 -7
- package/dist/Pressable.js +7 -3
- package/dist/Pressable.mjs +1 -1
- package/dist/PricingCard.mjs +4 -4
- package/dist/Progress.mjs +2 -2
- package/dist/RadioGroup.mjs +2 -2
- package/dist/RetrayProvider.mjs +3 -3
- package/dist/Select.mjs +2 -2
- package/dist/SelectableGrid.mjs +2 -2
- package/dist/Separator.mjs +2 -2
- package/dist/Sheet.d.mts +4 -46
- package/dist/Sheet.d.ts +4 -46
- package/dist/Sheet.js +46 -114
- package/dist/Sheet.mjs +2 -3
- package/dist/SheetSelect.mjs +2 -2
- package/dist/Skeleton.mjs +2 -2
- package/dist/Slider.mjs +2 -2
- package/dist/Spinner.mjs +2 -2
- package/dist/Stats.d.mts +30 -0
- package/dist/Stats.d.ts +30 -0
- package/dist/Stats.js +429 -0
- package/dist/Stats.mjs +9 -0
- package/dist/Switch.mjs +2 -2
- package/dist/TabBar.mjs +2 -2
- package/dist/Tabs.mjs +2 -2
- package/dist/Text.d.mts +3 -1
- package/dist/Text.d.ts +3 -1
- package/dist/Text.js +3 -3
- package/dist/Text.mjs +2 -2
- package/dist/Textarea.mjs +2 -2
- package/dist/Toast.mjs +2 -2
- package/dist/Toggle.mjs +2 -2
- package/dist/{chunk-YJ7I257J.mjs → chunk-265G6A46.mjs} +1 -1
- package/dist/{chunk-ELXBDILQ.mjs → chunk-2A2LEFZG.mjs} +2 -2
- package/dist/{chunk-ID72TK46.mjs → chunk-2CBQKU7H.mjs} +1 -1
- package/dist/{chunk-OB4JUQ3O.mjs → chunk-2I2AYECM.mjs} +1 -1
- package/dist/{chunk-WJLKJMKR.mjs → chunk-357YO24D.mjs} +4 -4
- package/dist/{chunk-GQYFLP3D.mjs → chunk-3GEYJ7I5.mjs} +1 -1
- package/dist/{chunk-AV4EMIRH.mjs → chunk-3N2M3WZL.mjs} +1 -1
- package/dist/{chunk-VF2ATYN3.mjs → chunk-3UYAZ7I4.mjs} +1 -1
- package/dist/{chunk-JMOZEC77.mjs → chunk-4WFMPFZB.mjs} +1 -1
- package/dist/chunk-5OLNXP3S.mjs +144 -0
- package/dist/{chunk-6SECQ2ZF.mjs → chunk-7HSILTC4.mjs} +2 -2
- package/dist/{chunk-IRRY3CRZ.mjs → chunk-AKM4EPOT.mjs} +1 -1
- package/dist/{chunk-IX3NYLYQ.mjs → chunk-AQEVCEXV.mjs} +1 -1
- package/dist/{chunk-WBOOUHSS.mjs → chunk-BCWEHE34.mjs} +1 -1
- package/dist/{chunk-AJ7ZDNBT.mjs → chunk-BOVUP27T.mjs} +1 -1
- package/dist/{chunk-BRKYVJVV.mjs → chunk-BQZE3HAW.mjs} +1 -1
- package/dist/{chunk-Z6SFHN6T.mjs → chunk-D3Y2T42P.mjs} +1 -1
- package/dist/{chunk-T2KCAHOS.mjs → chunk-DF6DU42P.mjs} +1 -1
- package/dist/{chunk-TB6SD2FT.mjs → chunk-DI7CBDL6.mjs} +1 -1
- package/dist/{chunk-HTHGSXFG.mjs → chunk-DOGIPOF5.mjs} +1 -1
- package/dist/{chunk-MBMXYJJV.mjs → chunk-E7NEHHXV.mjs} +7 -3
- package/dist/{chunk-MX6HRKMI.mjs → chunk-EFLFRAHD.mjs} +1 -1
- package/dist/{chunk-SOYNZDVY.mjs → chunk-EMUWGDWC.mjs} +6 -1
- package/dist/{chunk-AJRVDP2H.mjs → chunk-F4V6XLP4.mjs} +3 -3
- package/dist/{chunk-DYT7BG5I.mjs → chunk-FA2KMTH5.mjs} +1 -1
- package/dist/{chunk-Y2NS74WS.mjs → chunk-FFTYLPSB.mjs} +46 -98
- package/dist/{chunk-VKID2D2I.mjs → chunk-FUVYSVGR.mjs} +13 -8
- package/dist/{chunk-7LWRKMF5.mjs → chunk-FVTVCJAH.mjs} +1 -1
- package/dist/{chunk-TZDGAP5N.mjs → chunk-GK4VRMNE.mjs} +2 -2
- package/dist/{chunk-6Q64UFIA.mjs → chunk-HJ46DTJE.mjs} +1 -1
- package/dist/{chunk-WF2XDFRK.mjs → chunk-HLMPMUK2.mjs} +1 -1
- package/dist/{chunk-GD6KXMG5.mjs → chunk-I4V5XZPS.mjs} +1 -1
- package/dist/{chunk-TBNZHU6C.mjs → chunk-ISY26JQJ.mjs} +2 -2
- package/dist/{chunk-X4G6APW6.mjs → chunk-J6Q2YJEV.mjs} +1 -1
- package/dist/{chunk-WYEUNUTP.mjs → chunk-JCZQOY4O.mjs} +31 -24
- package/dist/{chunk-U2XJFYED.mjs → chunk-JNVAIDLK.mjs} +1 -1
- package/dist/{chunk-SOA2Z4RB.mjs → chunk-JULSIZDM.mjs} +1 -1
- package/dist/chunk-KHYX4IOM.mjs +1114 -0
- package/dist/{chunk-RYZC432S.mjs → chunk-LRM4AVYY.mjs} +1 -1
- package/dist/{chunk-6L4G6PBT.mjs → chunk-MYZ2EDYU.mjs} +1 -1
- package/dist/{chunk-BUMAMSTZ.mjs → chunk-N4ZPVCJH.mjs} +1 -1
- package/dist/{chunk-Z4VHZ7B5.mjs → chunk-NXI4YDZ2.mjs} +1 -1
- package/dist/{chunk-ZZ2R6KZ3.mjs → chunk-OULVKTWL.mjs} +1 -1
- package/dist/{chunk-FCSSQK3L.mjs → chunk-P64WHW4A.mjs} +1 -1
- package/dist/{chunk-KOO4WITD.mjs → chunk-P73V2EKS.mjs} +1 -1
- package/dist/{chunk-SXLKNTA4.mjs → chunk-PGERH3P7.mjs} +1 -1
- package/dist/{chunk-2UYENBLV.mjs → chunk-QSFV2P7O.mjs} +1 -1
- package/dist/{chunk-JT7HKXRB.mjs → chunk-S3KJCPEJ.mjs} +1 -1
- package/dist/{chunk-BEMIQXXU.mjs → chunk-V6NFJXKO.mjs} +1 -1
- package/dist/{chunk-A3A6KNQN.mjs → chunk-WOEWGSTU.mjs} +1 -1
- package/dist/{chunk-NMU5FMQJ.mjs → chunk-X26S5EVZ.mjs} +4 -2
- package/dist/{chunk-YFZ3ELX5.mjs → chunk-XBAGGKLW.mjs} +2 -2
- package/dist/{chunk-S2R7UVOE.mjs → chunk-ZHMSAYLT.mjs} +1 -1
- package/dist/fonts.d.mts +1 -7
- package/dist/fonts.d.ts +1 -7
- package/dist/fonts.js +0 -2
- package/dist/fonts.mjs +1 -2
- package/dist/index.d.mts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +1184 -708
- package/dist/index.mjs +53 -52
- package/package.json +3 -3
- package/src/components/ConfirmDialog/ConfirmDialog.tsx +39 -30
- package/src/components/CurrencyInput/CurrencyInput.tsx +4 -7
- package/src/components/IconPicker/IconPicker.tsx +124 -112
- package/src/components/ListItem/ListItem.tsx +43 -28
- package/src/components/Pressable/Pressable.tsx +20 -8
- package/src/components/Sheet/Sheet.tsx +64 -172
- package/src/components/Stats/Stats.tsx +226 -0
- package/src/components/Stats/index.ts +2 -0
- package/src/components/Text/Text.tsx +4 -2
- package/src/fonts.ts +0 -7
- package/src/index.ts +4 -0
- package/src/theme/colorUtils.ts +9 -0
- package/src/utils/curatedIcons.ts +698 -135
- package/src/utils/fontGuard.ts +2 -1
- package/dist/chunk-53Z3NYGE.mjs +0 -742
package/dist/index.mjs
CHANGED
|
@@ -1,63 +1,64 @@
|
|
|
1
|
-
export { Switch } from './chunk-WF2XDFRK.mjs';
|
|
2
|
-
export { TabBar } from './chunk-Z6SFHN6T.mjs';
|
|
3
|
-
export { Tabs, TabsContent } from './chunk-GQYFLP3D.mjs';
|
|
4
|
-
export { Text } from './chunk-WJLKJMKR.mjs';
|
|
5
|
-
export { Textarea } from './chunk-U2XJFYED.mjs';
|
|
6
|
-
export { Toggle } from './chunk-7LWRKMF5.mjs';
|
|
7
1
|
export { VirtualList } from './chunk-NC5ZTR2Y.mjs';
|
|
8
|
-
export {
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
11
|
-
export {
|
|
12
|
-
export {
|
|
13
|
-
export {
|
|
14
|
-
export {
|
|
15
|
-
export {
|
|
16
|
-
export {
|
|
17
|
-
export {
|
|
18
|
-
export {
|
|
19
|
-
export {
|
|
20
|
-
export {
|
|
21
|
-
export {
|
|
22
|
-
export {
|
|
23
|
-
export {
|
|
24
|
-
export {
|
|
25
|
-
export {
|
|
26
|
-
export {
|
|
27
|
-
export {
|
|
28
|
-
export {
|
|
29
|
-
export {
|
|
30
|
-
export {
|
|
31
|
-
export {
|
|
32
|
-
export {
|
|
33
|
-
export {
|
|
34
|
-
export {
|
|
35
|
-
export {
|
|
36
|
-
export {
|
|
37
|
-
export {
|
|
2
|
+
export { Stats } from './chunk-5OLNXP3S.mjs';
|
|
3
|
+
export { Switch } from './chunk-HLMPMUK2.mjs';
|
|
4
|
+
export { TabBar } from './chunk-D3Y2T42P.mjs';
|
|
5
|
+
export { Tabs, TabsContent } from './chunk-3GEYJ7I5.mjs';
|
|
6
|
+
export { Text } from './chunk-357YO24D.mjs';
|
|
7
|
+
export { Textarea } from './chunk-JNVAIDLK.mjs';
|
|
8
|
+
export { Toggle } from './chunk-FVTVCJAH.mjs';
|
|
9
|
+
export { Select } from './chunk-WOEWGSTU.mjs';
|
|
10
|
+
export { SelectableGrid } from './chunk-NXI4YDZ2.mjs';
|
|
11
|
+
export { Separator } from './chunk-EFLFRAHD.mjs';
|
|
12
|
+
export { BottomSheetModalProvider, Sheet, BottomSheetTextInput as SheetTextInput } from './chunk-FFTYLPSB.mjs';
|
|
13
|
+
export { SheetSelect } from './chunk-P73V2EKS.mjs';
|
|
14
|
+
export { Skeleton } from './chunk-BOVUP27T.mjs';
|
|
15
|
+
export { Slider } from './chunk-4WFMPFZB.mjs';
|
|
16
|
+
export { MonthPicker, dateToMonthPickerValue, monthPickerValueToDate } from './chunk-I4V5XZPS.mjs';
|
|
17
|
+
export { NumberStepper } from './chunk-N4ZPVCJH.mjs';
|
|
18
|
+
export { Pressable } from './chunk-E7NEHHXV.mjs';
|
|
19
|
+
export { PricingCard } from './chunk-F4V6XLP4.mjs';
|
|
20
|
+
export { Progress } from './chunk-2I2AYECM.mjs';
|
|
21
|
+
export { RadioGroup } from './chunk-J6Q2YJEV.mjs';
|
|
22
|
+
export { RetrayProvider } from './chunk-XBAGGKLW.mjs';
|
|
23
|
+
export { ToastProvider, sonnerToast as toast, useToast } from './chunk-QSFV2P7O.mjs';
|
|
24
|
+
export { ImageViewer } from './chunk-2A2LEFZG.mjs';
|
|
25
|
+
export { PagerDots } from './chunk-OULVKTWL.mjs';
|
|
26
|
+
export { LabelValue } from './chunk-P64WHW4A.mjs';
|
|
27
|
+
export { ListGroup, ListGroupFooter, ListGroupHeader } from './chunk-JULSIZDM.mjs';
|
|
28
|
+
export { ListItem } from './chunk-FUVYSVGR.mjs';
|
|
29
|
+
export { MediaCard } from './chunk-AQEVCEXV.mjs';
|
|
30
|
+
export { MenuGroup, MenuGroupFooter, MenuGroupHeader } from './chunk-AKM4EPOT.mjs';
|
|
31
|
+
export { MenuItem } from './chunk-DI7CBDL6.mjs';
|
|
32
|
+
export { DetailRow } from './chunk-ZHMSAYLT.mjs';
|
|
33
|
+
export { EmptyState } from './chunk-7HSILTC4.mjs';
|
|
34
|
+
export { ErrorBoundary } from './chunk-LRM4AVYY.mjs';
|
|
35
|
+
export { Form, FormField, FormFooter, FormSection } from './chunk-HJ46DTJE.mjs';
|
|
36
|
+
export { IconPicker } from './chunk-KHYX4IOM.mjs';
|
|
37
|
+
export { ImageUpload } from './chunk-GK4VRMNE.mjs';
|
|
38
|
+
export { Spinner } from './chunk-BCWEHE34.mjs';
|
|
38
39
|
export { ButtonGroup } from './chunk-3BBOZ3OQ.mjs';
|
|
39
|
-
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './chunk-
|
|
40
|
-
export { CategoryStrip } from './chunk-
|
|
40
|
+
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './chunk-2CBQKU7H.mjs';
|
|
41
|
+
export { CategoryStrip } from './chunk-MYZ2EDYU.mjs';
|
|
41
42
|
import './chunk-YNROWHQJ.mjs';
|
|
42
|
-
export { Checkbox } from './chunk-
|
|
43
|
-
export { Chip, ChipGroup } from './chunk-
|
|
44
|
-
export { ConfirmDialog } from './chunk-
|
|
45
|
-
export { CurrencyDisplay } from './chunk-
|
|
46
|
-
export { CurrencyInput } from './chunk-
|
|
47
|
-
export { Input } from './chunk-
|
|
48
|
-
export { Accordion } from './chunk-
|
|
49
|
-
export { AlertBanner } from './chunk-
|
|
50
|
-
export { AppHeader } from './chunk-
|
|
51
|
-
export { IconButton } from './chunk-
|
|
52
|
-
export { Avatar } from './chunk-
|
|
53
|
-
export { Badge } from './chunk-
|
|
54
|
-
export { Button } from './chunk-
|
|
43
|
+
export { Checkbox } from './chunk-3N2M3WZL.mjs';
|
|
44
|
+
export { Chip, ChipGroup } from './chunk-FA2KMTH5.mjs';
|
|
45
|
+
export { ConfirmDialog } from './chunk-JCZQOY4O.mjs';
|
|
46
|
+
export { CurrencyDisplay } from './chunk-BQZE3HAW.mjs';
|
|
47
|
+
export { CurrencyInput } from './chunk-X26S5EVZ.mjs';
|
|
48
|
+
export { Input } from './chunk-PGERH3P7.mjs';
|
|
49
|
+
export { Accordion } from './chunk-265G6A46.mjs';
|
|
50
|
+
export { AlertBanner } from './chunk-V6NFJXKO.mjs';
|
|
51
|
+
export { AppHeader } from './chunk-ISY26JQJ.mjs';
|
|
52
|
+
export { IconButton } from './chunk-DF6DU42P.mjs';
|
|
53
|
+
export { Avatar } from './chunk-S3KJCPEJ.mjs';
|
|
54
|
+
export { Badge } from './chunk-3UYAZ7I4.mjs';
|
|
55
|
+
export { Button } from './chunk-DOGIPOF5.mjs';
|
|
55
56
|
import './chunk-3DKJ2GIC.mjs';
|
|
56
57
|
export { impactHeavy, impactLight, impactMedium, notificationError, notificationSuccess, notificationWarning, richHaptics, selectionAsync } from './chunk-EJ7ZPXOH.mjs';
|
|
57
58
|
import './chunk-DVK4G2GT.mjs';
|
|
58
59
|
export { BREAKPOINTS, ICON_SIZES, RADIUS, SHADOWS, SPACING, TYPOGRAPHY } from './chunk-QY3X2UYR.mjs';
|
|
59
60
|
export { Icon, configureIconFamilies, getValidIconNames, renderIcon } from './chunk-KA7LTET3.mjs';
|
|
60
|
-
export { ThemeProvider, defaultDark, defaultLight, deriveColors, useTheme } from './chunk-
|
|
61
|
+
export { ThemeProvider, defaultDark, defaultLight, deriveColors, useTheme, withAlpha } from './chunk-EMUWGDWC.mjs';
|
|
61
62
|
import './chunk-2CE3TQVY.mjs';
|
|
62
63
|
import './chunk-Y6FXYEAI.mjs';
|
|
63
64
|
import { useState, useCallback } from 'react';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@retray-dev/ui-kit",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "12.1.0",
|
|
4
4
|
"description": "Personal UI Kit for React Native / Expo",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
"react-native-worklets": "0.5.1",
|
|
111
111
|
"@types/react": "19.1.17",
|
|
112
112
|
"react-native-safe-area-context": "5.6.2",
|
|
113
|
-
"@gorhom/bottom-sheet": "5.2.
|
|
113
|
+
"@gorhom/bottom-sheet": "5.2.14"
|
|
114
114
|
},
|
|
115
115
|
"onlyBuiltDependencies": [
|
|
116
116
|
"esbuild"
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"devDependencies": {
|
|
120
120
|
"@eslint/js": "^9.0.0",
|
|
121
121
|
"@expo/vector-icons": "^15.1.1",
|
|
122
|
-
"@gorhom/bottom-sheet": "5.2.
|
|
122
|
+
"@gorhom/bottom-sheet": "5.2.14",
|
|
123
123
|
"@react-native-community/slider": "5.0.1",
|
|
124
124
|
"@react-native-picker/picker": "2.11.1",
|
|
125
125
|
"@shopify/react-native-skia": "2.2.12",
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import React, { useEffect, useRef } from 'react'
|
|
1
|
+
import React, { useCallback, useEffect, useRef, useId } from 'react'
|
|
2
2
|
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'
|
|
3
|
-
import
|
|
3
|
+
import {
|
|
4
|
+
BottomSheetModal,
|
|
4
5
|
BottomSheetView,
|
|
5
6
|
BottomSheetBackdrop,
|
|
6
7
|
type BottomSheetBackdropProps,
|
|
7
8
|
} from '@gorhom/bottom-sheet'
|
|
9
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
8
10
|
import { Feather } from '@expo/vector-icons'
|
|
9
11
|
import { impactMedium, notificationSuccess, selectionAsync as hapticSelection } from '../../utils/haptics'
|
|
10
12
|
import { useTheme } from '../../theme'
|
|
@@ -14,16 +16,11 @@ import { s, vs, ms, mvs } from '../../utils/scaling'
|
|
|
14
16
|
export interface ConfirmDialogProps {
|
|
15
17
|
visible: boolean
|
|
16
18
|
title: string
|
|
17
|
-
/** Secondary text below title. */
|
|
18
19
|
subtitle?: string
|
|
19
|
-
/** @deprecated Use `subtitle` instead. */
|
|
20
|
-
description?: string
|
|
21
20
|
confirmLabel?: string
|
|
22
21
|
cancelLabel?: string
|
|
23
22
|
confirmVariant?: 'primary' | 'destructive'
|
|
24
|
-
/** Show a loading spinner in the confirm button (e.g. while async action completes). */
|
|
25
23
|
loading?: boolean
|
|
26
|
-
/** Show an X close button in the top-right corner. */
|
|
27
24
|
showCloseButton?: boolean
|
|
28
25
|
onConfirm: () => void
|
|
29
26
|
onCancel: () => void
|
|
@@ -33,7 +30,6 @@ export function ConfirmDialog({
|
|
|
33
30
|
visible,
|
|
34
31
|
title,
|
|
35
32
|
subtitle,
|
|
36
|
-
description,
|
|
37
33
|
confirmLabel = 'Confirm',
|
|
38
34
|
cancelLabel = 'Cancel',
|
|
39
35
|
confirmVariant = 'primary',
|
|
@@ -43,37 +39,44 @@ export function ConfirmDialog({
|
|
|
43
39
|
onCancel,
|
|
44
40
|
}: ConfirmDialogProps) {
|
|
45
41
|
const { colors } = useTheme()
|
|
46
|
-
const
|
|
47
|
-
const
|
|
42
|
+
const insets = useSafeAreaInsets()
|
|
43
|
+
const ref = useRef<BottomSheetModal>(null)
|
|
44
|
+
const wasOpened = useRef(false)
|
|
45
|
+
const name = useId()
|
|
48
46
|
|
|
49
47
|
useEffect(() => {
|
|
50
48
|
if (visible) {
|
|
51
49
|
impactMedium()
|
|
52
|
-
ref.current?.
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
ref.current?.present()
|
|
51
|
+
wasOpened.current = true
|
|
52
|
+
} else if (wasOpened.current) {
|
|
53
|
+
ref.current?.dismiss()
|
|
55
54
|
}
|
|
56
55
|
}, [visible])
|
|
57
56
|
|
|
58
|
-
const renderBackdrop = (
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
57
|
+
const renderBackdrop = useCallback(
|
|
58
|
+
(props: BottomSheetBackdropProps) => (
|
|
59
|
+
<BottomSheetBackdrop
|
|
60
|
+
{...props}
|
|
61
|
+
disappearsOnIndex={-1}
|
|
62
|
+
appearsOnIndex={0}
|
|
63
|
+
pressBehavior="close"
|
|
64
|
+
/>
|
|
65
|
+
),
|
|
66
|
+
[]
|
|
65
67
|
)
|
|
66
68
|
|
|
67
69
|
return (
|
|
68
|
-
|
|
70
|
+
<BottomSheetModal
|
|
69
71
|
ref={ref}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
+
name={name}
|
|
73
|
+
onDismiss={onCancel}
|
|
72
74
|
enableDynamicSizing
|
|
73
75
|
backdropComponent={renderBackdrop}
|
|
74
|
-
backgroundStyle={
|
|
75
|
-
handleIndicatorStyle={
|
|
76
|
+
backgroundStyle={{ ...styles.background, backgroundColor: colors.card }}
|
|
77
|
+
handleIndicatorStyle={{ ...styles.handle, backgroundColor: colors.border }}
|
|
76
78
|
enablePanDownToClose
|
|
79
|
+
topInset={insets.top}
|
|
77
80
|
>
|
|
78
81
|
<BottomSheetView style={styles.content}>
|
|
79
82
|
<View style={styles.header} accessibilityRole="header">
|
|
@@ -95,9 +98,9 @@ export function ConfirmDialog({
|
|
|
95
98
|
</TouchableOpacity>
|
|
96
99
|
) : null}
|
|
97
100
|
</View>
|
|
98
|
-
{
|
|
101
|
+
{subtitle ? (
|
|
99
102
|
<Text style={[styles.subtitle, { color: colors.foregroundMuted }]} allowFontScaling={true}>
|
|
100
|
-
{
|
|
103
|
+
{subtitle}
|
|
101
104
|
</Text>
|
|
102
105
|
) : null}
|
|
103
106
|
</View>
|
|
@@ -108,7 +111,10 @@ export function ConfirmDialog({
|
|
|
108
111
|
fullWidth
|
|
109
112
|
loading={loading}
|
|
110
113
|
disabled={loading}
|
|
111
|
-
onPress={() => {
|
|
114
|
+
onPress={() => {
|
|
115
|
+
notificationSuccess()
|
|
116
|
+
onConfirm()
|
|
117
|
+
}}
|
|
112
118
|
icon={
|
|
113
119
|
<Feather
|
|
114
120
|
name={confirmVariant === 'destructive' ? 'trash-2' : 'check'}
|
|
@@ -125,12 +131,15 @@ export function ConfirmDialog({
|
|
|
125
131
|
label={cancelLabel}
|
|
126
132
|
variant="secondary"
|
|
127
133
|
fullWidth
|
|
128
|
-
onPress={() => {
|
|
134
|
+
onPress={() => {
|
|
135
|
+
hapticSelection()
|
|
136
|
+
onCancel()
|
|
137
|
+
}}
|
|
129
138
|
icon={<Feather name="x" size={15} color={colors.foreground} />}
|
|
130
139
|
/>
|
|
131
140
|
</View>
|
|
132
141
|
</BottomSheetView>
|
|
133
|
-
</
|
|
142
|
+
</BottomSheetModal>
|
|
134
143
|
)
|
|
135
144
|
}
|
|
136
145
|
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { ViewStyle, TextStyle } from 'react-native'
|
|
2
|
+
import { ViewStyle, TextStyle, TextInputProps } from 'react-native'
|
|
3
3
|
import { Input } from '../Input'
|
|
4
4
|
import { ms, vs } from '../../utils/scaling'
|
|
5
5
|
|
|
6
|
-
export interface CurrencyInputProps {
|
|
7
|
-
value?: string
|
|
8
|
-
onChangeText?: (formatted: string) => void
|
|
6
|
+
export interface CurrencyInputProps extends TextInputProps {
|
|
9
7
|
/** Called with the parsed numeric value (no separators, no prefix). */
|
|
10
8
|
onChangeValue?: (raw: number) => void
|
|
11
9
|
/** Currency symbol shown left of the value. Any string (`'$'`, `'€'`, `'£'`, `'COP '`). Defaults to `'$'`. */
|
|
@@ -18,10 +16,7 @@ export interface CurrencyInputProps {
|
|
|
18
16
|
/** Red helper text; also changes input border to destructive color. */
|
|
19
17
|
error?: string
|
|
20
18
|
hint?: string
|
|
21
|
-
placeholder?: string
|
|
22
|
-
editable?: boolean
|
|
23
19
|
containerStyle?: ViewStyle
|
|
24
|
-
style?: TextStyle
|
|
25
20
|
/** Use inside a Sheet/BottomSheet — passes sheetMode to the underlying Input. */
|
|
26
21
|
sheetMode?: boolean
|
|
27
22
|
}
|
|
@@ -47,6 +42,7 @@ export function CurrencyInput({
|
|
|
47
42
|
containerStyle,
|
|
48
43
|
style,
|
|
49
44
|
sheetMode,
|
|
45
|
+
...props
|
|
50
46
|
}: CurrencyInputProps) {
|
|
51
47
|
const handleChange = (text: string) => {
|
|
52
48
|
const withoutPrefix = prefix && text.startsWith(prefix) ? text.slice(prefix.length) : text
|
|
@@ -73,6 +69,7 @@ export function CurrencyInput({
|
|
|
73
69
|
|
|
74
70
|
return (
|
|
75
71
|
<Input
|
|
72
|
+
{...props}
|
|
76
73
|
value={displayValue}
|
|
77
74
|
onChangeText={handleChange}
|
|
78
75
|
keyboardType="numeric"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useRef, useState, useCallback,
|
|
1
|
+
import React, { useRef, useState, useCallback, useMemo, useId } from 'react'
|
|
2
2
|
import { View, Text, TouchableOpacity, StyleSheet, ViewStyle, Dimensions } from 'react-native'
|
|
3
3
|
import { ScrollView } from 'react-native-gesture-handler'
|
|
4
4
|
import {
|
|
@@ -13,6 +13,7 @@ import { CURATED_ICONS, ALL_CURATED_ICONS } from '../../utils/curatedIcons'
|
|
|
13
13
|
import { selectionAsync as hapticSelection, impactMedium } from '../../utils/haptics'
|
|
14
14
|
import { s, vs, ms } from '../../utils/scaling'
|
|
15
15
|
import { RADIUS } from '../../tokens'
|
|
16
|
+
import { Spinner } from '../Spinner'
|
|
16
17
|
import type { BottomSheetBackdropProps, BottomSheetModal as BottomSheetModalType } from '@gorhom/bottom-sheet'
|
|
17
18
|
|
|
18
19
|
const NUM_COLUMNS = 6
|
|
@@ -74,10 +75,10 @@ export function IconPicker({
|
|
|
74
75
|
const { colors } = useTheme()
|
|
75
76
|
const insets = useSafeAreaInsets()
|
|
76
77
|
const sheetRef = useRef<BottomSheetModalType>(null)
|
|
77
|
-
const catScrollRef = useRef<
|
|
78
|
-
const [open, setOpen] = useState(false)
|
|
78
|
+
const catScrollRef = useRef<ScrollView>(null)
|
|
79
79
|
const [activeCategory, setActiveCategory] = useState<string | null>(null)
|
|
80
80
|
const [containerWidth, setContainerWidth] = useState(() => Dimensions.get('window').width - s(16) * 2)
|
|
81
|
+
const [ready, setReady] = useState(false)
|
|
81
82
|
|
|
82
83
|
const sheetName = useId()
|
|
83
84
|
|
|
@@ -101,35 +102,26 @@ export function IconPicker({
|
|
|
101
102
|
return result
|
|
102
103
|
}, [activeIcons, numColumns])
|
|
103
104
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
} else {
|
|
109
|
-
sheetRef.current?.dismiss()
|
|
110
|
-
}
|
|
111
|
-
}, [open])
|
|
105
|
+
const handleDismiss = useCallback(() => {
|
|
106
|
+
setActiveCategory(null)
|
|
107
|
+
setReady(false)
|
|
108
|
+
}, [])
|
|
112
109
|
|
|
113
110
|
const handleSelect = useCallback(
|
|
114
111
|
(iconName: string) => {
|
|
115
112
|
onChange(iconName)
|
|
116
|
-
setOpen(false)
|
|
117
|
-
setActiveCategory(null)
|
|
118
113
|
},
|
|
119
114
|
[onChange],
|
|
120
115
|
)
|
|
121
116
|
|
|
122
117
|
const handleOpen = useCallback(() => {
|
|
123
118
|
if (disabled) return
|
|
119
|
+
impactMedium()
|
|
124
120
|
setActiveCategory(null)
|
|
125
|
-
|
|
121
|
+
setReady(false)
|
|
122
|
+
sheetRef.current?.present()
|
|
126
123
|
}, [disabled])
|
|
127
124
|
|
|
128
|
-
const handleClose = useCallback(() => {
|
|
129
|
-
setOpen(false)
|
|
130
|
-
setActiveCategory(null)
|
|
131
|
-
}, [])
|
|
132
|
-
|
|
133
125
|
const renderBackdrop = useCallback(
|
|
134
126
|
(props: BottomSheetBackdropProps) => (
|
|
135
127
|
<BottomSheetBackdrop {...props} disappearsOnIndex={-1} appearsOnIndex={0} pressBehavior="close" />
|
|
@@ -185,12 +177,12 @@ export function IconPicker({
|
|
|
185
177
|
<BottomSheetModal
|
|
186
178
|
ref={sheetRef}
|
|
187
179
|
name={sheetName}
|
|
188
|
-
onDismiss={
|
|
180
|
+
onDismiss={handleDismiss}
|
|
189
181
|
enableDynamicSizing={true}
|
|
190
182
|
maxDynamicContentSize={SCREEN_HEIGHT * 0.7}
|
|
191
183
|
backdropComponent={renderBackdrop}
|
|
192
|
-
backgroundStyle={
|
|
193
|
-
handleIndicatorStyle={
|
|
184
|
+
backgroundStyle={{ ...styles.sheetBackground, backgroundColor: colors.card }}
|
|
185
|
+
handleIndicatorStyle={{ ...styles.handle, backgroundColor: colors.border }}
|
|
194
186
|
enablePanDownToClose
|
|
195
187
|
topInset={insets.top}
|
|
196
188
|
android_keyboardInputMode="adjustPan"
|
|
@@ -199,103 +191,118 @@ export function IconPicker({
|
|
|
199
191
|
contentContainerStyle={styles.sheetContent}
|
|
200
192
|
showsVerticalScrollIndicator={true}
|
|
201
193
|
>
|
|
202
|
-
{/*
|
|
203
|
-
<
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
ref={catScrollRef}
|
|
210
|
-
horizontal
|
|
211
|
-
showsHorizontalScrollIndicator={false}
|
|
212
|
-
contentContainerStyle={styles.categoryStrip}
|
|
213
|
-
style={styles.categoryScroll}
|
|
194
|
+
{/* Measuring container — always rendered so onLayout fires */}
|
|
195
|
+
<View
|
|
196
|
+
style={styles.gridContainer}
|
|
197
|
+
onLayout={(e) => {
|
|
198
|
+
setContainerWidth(e.nativeEvent.layout.width)
|
|
199
|
+
setReady(true)
|
|
200
|
+
}}
|
|
214
201
|
>
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
touchSoundDisabled={true}
|
|
219
|
-
accessibilityRole="button"
|
|
220
|
-
accessibilityLabel="Todos"
|
|
221
|
-
accessibilityState={{ selected: activeCategory === null }}
|
|
222
|
-
style={[
|
|
223
|
-
styles.categoryChip,
|
|
224
|
-
{
|
|
225
|
-
backgroundColor: activeCategory === null ? colors.primary : colors.surface,
|
|
226
|
-
borderColor: activeCategory === null ? colors.primary : colors.border,
|
|
227
|
-
},
|
|
228
|
-
]}
|
|
229
|
-
>
|
|
230
|
-
<View style={styles.categoryChipInner}>
|
|
231
|
-
{renderIcon('grid', ms(14), activeCategory === null ? colors.primaryForeground : colors.foregroundSubtle)}
|
|
232
|
-
<Text
|
|
233
|
-
style={[
|
|
234
|
-
styles.categoryChipText,
|
|
235
|
-
{ color: activeCategory === null ? colors.primaryForeground : colors.foreground },
|
|
236
|
-
]}
|
|
237
|
-
allowFontScaling={true}
|
|
238
|
-
numberOfLines={1}
|
|
239
|
-
>
|
|
240
|
-
Todos
|
|
241
|
-
</Text>
|
|
202
|
+
{!ready ? (
|
|
203
|
+
<View style={styles.loader}>
|
|
204
|
+
<Spinner size="md" color={colors.primary} label="Cargando iconos..." />
|
|
242
205
|
</View>
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
{
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
206
|
+
) : (
|
|
207
|
+
<>
|
|
208
|
+
{/* Category section label */}
|
|
209
|
+
<Text style={[styles.sectionLabel, { color: colors.foregroundSubtle }]} allowFontScaling={true}>
|
|
210
|
+
Categorías
|
|
211
|
+
</Text>
|
|
212
|
+
|
|
213
|
+
{/* Horizontal scrollable category chips */}
|
|
214
|
+
<ScrollView
|
|
215
|
+
ref={catScrollRef}
|
|
216
|
+
horizontal
|
|
217
|
+
showsHorizontalScrollIndicator={false}
|
|
218
|
+
contentContainerStyle={styles.categoryStrip}
|
|
219
|
+
style={styles.categoryScroll}
|
|
220
|
+
>
|
|
221
|
+
<TouchableOpacity
|
|
222
|
+
onPress={() => setActiveCategory(null)}
|
|
223
|
+
activeOpacity={0.7}
|
|
224
|
+
touchSoundDisabled={true}
|
|
225
|
+
accessibilityRole="button"
|
|
226
|
+
accessibilityLabel="Todos"
|
|
227
|
+
accessibilityState={{ selected: activeCategory === null }}
|
|
264
228
|
style={[
|
|
265
|
-
styles.
|
|
266
|
-
{
|
|
229
|
+
styles.categoryChip,
|
|
230
|
+
{
|
|
231
|
+
backgroundColor: activeCategory === null ? colors.primary : colors.surface,
|
|
232
|
+
borderColor: activeCategory === null ? colors.primary : colors.border,
|
|
233
|
+
},
|
|
267
234
|
]}
|
|
268
|
-
allowFontScaling={true}
|
|
269
|
-
numberOfLines={1}
|
|
270
235
|
>
|
|
271
|
-
{
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
236
|
+
<View style={styles.categoryChipInner}>
|
|
237
|
+
{renderIcon('grid', ms(14), activeCategory === null ? colors.primaryForeground : colors.foregroundSubtle)}
|
|
238
|
+
<Text
|
|
239
|
+
style={[
|
|
240
|
+
styles.categoryChipText,
|
|
241
|
+
{ color: activeCategory === null ? colors.primaryForeground : colors.foreground },
|
|
242
|
+
]}
|
|
243
|
+
allowFontScaling={true}
|
|
244
|
+
numberOfLines={1}
|
|
245
|
+
>
|
|
246
|
+
Todos
|
|
247
|
+
</Text>
|
|
248
|
+
</View>
|
|
249
|
+
</TouchableOpacity>
|
|
250
|
+
{CURATED_ICONS.map((cat) => (
|
|
251
|
+
<TouchableOpacity
|
|
252
|
+
key={cat.name}
|
|
253
|
+
onPress={() => setActiveCategory(cat.name)}
|
|
254
|
+
activeOpacity={0.7}
|
|
255
|
+
touchSoundDisabled={true}
|
|
256
|
+
accessibilityRole="button"
|
|
257
|
+
accessibilityLabel={cat.labelEs}
|
|
258
|
+
accessibilityState={{ selected: activeCategory === cat.name }}
|
|
259
|
+
style={[
|
|
260
|
+
styles.categoryChip,
|
|
261
|
+
{
|
|
262
|
+
backgroundColor: activeCategory === cat.name ? colors.primary : colors.surface,
|
|
263
|
+
borderColor: activeCategory === cat.name ? colors.primary : colors.border,
|
|
264
|
+
},
|
|
265
|
+
]}
|
|
266
|
+
>
|
|
267
|
+
<View style={styles.categoryChipInner}>
|
|
268
|
+
{renderIcon(cat.categoryIcon, ms(14), activeCategory === cat.name ? colors.primaryForeground : colors.foregroundSubtle)}
|
|
269
|
+
<Text
|
|
270
|
+
style={[
|
|
271
|
+
styles.categoryChipText,
|
|
272
|
+
{ color: activeCategory === cat.name ? colors.primaryForeground : colors.foreground },
|
|
273
|
+
]}
|
|
274
|
+
allowFontScaling={true}
|
|
275
|
+
numberOfLines={1}
|
|
276
|
+
>
|
|
277
|
+
{cat.labelEs}
|
|
278
|
+
</Text>
|
|
279
|
+
</View>
|
|
280
|
+
</TouchableOpacity>
|
|
281
|
+
))}
|
|
282
|
+
</ScrollView>
|
|
277
283
|
|
|
278
|
-
|
|
279
|
-
|
|
284
|
+
{/* Separator */}
|
|
285
|
+
<View style={[styles.separator, { backgroundColor: colors.border }]} />
|
|
280
286
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
287
|
+
{/* Icon grid */}
|
|
288
|
+
{cellSize > 0 ? rows.map((row, i) => (
|
|
289
|
+
<View key={row[0] ?? `row-${i}`} style={[styles.row, { marginBottom: gapPx }]}>
|
|
290
|
+
{row.map((name) => (
|
|
291
|
+
<IconCellMemo
|
|
292
|
+
key={name}
|
|
293
|
+
name={name}
|
|
294
|
+
selected={value === name}
|
|
295
|
+
size={cellSize}
|
|
296
|
+
onPress={() => { handleSelect(name); sheetRef.current?.dismiss() }}
|
|
297
|
+
/>
|
|
298
|
+
))}
|
|
299
|
+
{Array.from({ length: numColumns - row.length }).map((_, j) => (
|
|
300
|
+
<View key={`spacer-${j}`} style={{ width: cellSize, height: cellSize }} />
|
|
301
|
+
))}
|
|
302
|
+
</View>
|
|
303
|
+
)) : null}
|
|
304
|
+
</>
|
|
305
|
+
)}
|
|
299
306
|
</View>
|
|
300
307
|
</BottomSheetScrollView>
|
|
301
308
|
</BottomSheetModal>
|
|
@@ -380,4 +387,9 @@ const styles = StyleSheet.create({
|
|
|
380
387
|
alignItems: 'center',
|
|
381
388
|
justifyContent: 'center',
|
|
382
389
|
},
|
|
390
|
+
loader: {
|
|
391
|
+
minHeight: vs(200),
|
|
392
|
+
alignItems: 'center',
|
|
393
|
+
justifyContent: 'center',
|
|
394
|
+
},
|
|
383
395
|
})
|