@retray-dev/ui-kit 12.2.0 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMPONENTS.md +85 -143
- package/CONSUMER.md +2 -2
- package/DESIGN.md +2 -2
- package/README.md +11 -6
- package/dist/Accordion.js +48 -210
- package/dist/Accordion.mjs +6 -5
- package/dist/AlertBanner.js +29 -153
- package/dist/AlertBanner.mjs +3 -3
- package/dist/AppHeader.js +37 -235
- package/dist/AppHeader.mjs +6 -7
- package/dist/Avatar.d.mts +17 -1
- package/dist/Avatar.d.ts +17 -1
- package/dist/Avatar.js +80 -115
- package/dist/Avatar.mjs +2 -2
- package/dist/Badge.js +24 -149
- package/dist/Badge.mjs +3 -3
- package/dist/Button.js +79 -267
- package/dist/Button.mjs +6 -6
- package/dist/Card.js +15 -200
- package/dist/Card.mjs +4 -5
- package/dist/CategoryStrip.d.mts +0 -5
- package/dist/CategoryStrip.d.ts +0 -5
- package/dist/CategoryStrip.js +47 -265
- package/dist/CategoryStrip.mjs +6 -6
- package/dist/Checkbox.js +15 -200
- package/dist/Checkbox.mjs +5 -5
- package/dist/Chip.js +44 -236
- package/dist/Chip.mjs +7 -6
- package/dist/ConfirmDialog.js +84 -286
- package/dist/ConfirmDialog.mjs +7 -7
- package/dist/CurrencyDisplay.js +1 -114
- package/dist/CurrencyDisplay.mjs +2 -2
- package/dist/CurrencyInput.js +35 -162
- package/dist/CurrencyInput.mjs +5 -5
- package/dist/DetailRow.js +25 -150
- package/dist/DetailRow.mjs +3 -3
- package/dist/EmptyState.js +80 -268
- package/dist/EmptyState.mjs +7 -7
- package/dist/ErrorBoundary.js +32 -199
- package/dist/ErrorBoundary.mjs +4 -4
- package/dist/Form.js +1 -114
- package/dist/Form.mjs +2 -2
- package/dist/HolographicCard.d.mts +0 -28
- package/dist/HolographicCard.d.ts +0 -28
- package/dist/HolographicCard.js +20 -130
- package/dist/HolographicCard.mjs +9 -32
- package/dist/IconButton.js +36 -234
- package/dist/IconButton.mjs +5 -6
- package/dist/IconPicker.js +222 -929
- package/dist/IconPicker.mjs +5 -5
- package/dist/ImageUpload.d.mts +3 -1
- package/dist/ImageUpload.d.ts +3 -1
- package/dist/ImageUpload.js +25 -215
- package/dist/ImageUpload.mjs +5 -6
- package/dist/ImageViewer.js +75 -266
- package/dist/ImageViewer.mjs +8 -8
- package/dist/Input.d.mts +1 -1
- package/dist/Input.d.ts +1 -1
- package/dist/Input.js +35 -162
- package/dist/Input.mjs +4 -4
- package/dist/LabelValue.js +24 -149
- package/dist/LabelValue.mjs +3 -3
- package/dist/ListGroup.js +1 -114
- package/dist/ListGroup.mjs +2 -2
- package/dist/ListItem.js +38 -235
- package/dist/ListItem.mjs +5 -6
- package/dist/MediaCard.d.mts +0 -14
- package/dist/MediaCard.d.ts +0 -14
- package/dist/MediaCard.js +69 -315
- package/dist/MediaCard.mjs +5 -6
- package/dist/MenuGroup.js +1 -114
- package/dist/MenuGroup.mjs +2 -2
- package/dist/MenuItem.js +36 -234
- package/dist/MenuItem.mjs +5 -6
- package/dist/MonthPicker.js +8 -163
- package/dist/MonthPicker.mjs +3 -3
- package/dist/NumberStepper.js +40 -238
- package/dist/NumberStepper.mjs +5 -6
- package/dist/PagerDots.d.mts +1 -1
- package/dist/PagerDots.d.ts +1 -1
- package/dist/PagerDots.js +69 -224
- package/dist/PagerDots.mjs +6 -5
- package/dist/Pressable.js +14 -85
- package/dist/Pressable.mjs +4 -4
- package/dist/PricingCard.js +87 -272
- package/dist/PricingCard.mjs +8 -8
- package/dist/Progress.js +3 -123
- package/dist/Progress.mjs +3 -3
- package/dist/RadioGroup.js +52 -265
- package/dist/RadioGroup.mjs +5 -5
- package/dist/RetrayProvider.js +3 -6
- package/dist/RetrayProvider.mjs +3 -3
- package/dist/Select.d.mts +2 -1
- package/dist/Select.d.ts +2 -1
- package/dist/Select.js +24 -232
- package/dist/Select.mjs +4 -5
- package/dist/SelectableCard.js +33 -209
- package/dist/SelectableCard.mjs +5 -5
- package/dist/SelectableGrid.d.mts +0 -21
- package/dist/SelectableGrid.d.ts +0 -21
- package/dist/SelectableGrid.js +49 -271
- package/dist/SelectableGrid.mjs +5 -6
- package/dist/Separator.js +1 -114
- package/dist/Separator.mjs +2 -2
- package/dist/Sheet.js +7 -162
- package/dist/Sheet.mjs +3 -3
- package/dist/SheetSelect.js +39 -236
- package/dist/SheetSelect.mjs +6 -6
- package/dist/Skeleton.js +4 -124
- package/dist/Skeleton.mjs +3 -3
- package/dist/Slider.js +6 -161
- package/dist/Slider.mjs +3 -3
- package/dist/Spinner.js +3 -116
- package/dist/Spinner.mjs +2 -2
- package/dist/Stats.js +36 -234
- package/dist/Stats.mjs +5 -6
- package/dist/Switch.js +24 -175
- package/dist/Switch.mjs +5 -4
- package/dist/TabBar.js +43 -200
- package/dist/TabBar.mjs +5 -4
- package/dist/Tabs.js +15 -199
- package/dist/Tabs.mjs +5 -5
- package/dist/Text.js +9 -130
- package/dist/Text.mjs +2 -2
- package/dist/Textarea.d.mts +2 -1
- package/dist/Textarea.d.ts +2 -1
- package/dist/Textarea.js +71 -219
- package/dist/Textarea.mjs +4 -4
- package/dist/Toast.js +1 -114
- package/dist/Toast.mjs +2 -2
- package/dist/Toggle.js +39 -236
- package/dist/Toggle.mjs +6 -6
- package/dist/{chunk-M3C7XM2M.mjs → chunk-2QOHHBJC.mjs} +3 -3
- package/dist/{chunk-LIS6I5UP.mjs → chunk-2VIDP72N.mjs} +3 -3
- package/dist/{chunk-DF7JA72E.mjs → chunk-4NQFTHN3.mjs} +13 -7
- package/dist/{chunk-UBUXUMER.mjs → chunk-4ZO5PTKF.mjs} +4 -4
- package/dist/{chunk-3XCFYSX4.mjs → chunk-5MYNAAFE.mjs} +13 -17
- package/dist/{chunk-E7NEHHXV.mjs → chunk-62BBSSUF.mjs} +3 -3
- package/dist/{chunk-MVMGPZN6.mjs → chunk-6CR4S6W2.mjs} +3 -3
- package/dist/{chunk-EDLCGYIO.mjs → chunk-6QLBHUEG.mjs} +8 -7
- package/dist/chunk-ARONDO7M.mjs +40 -0
- package/dist/{chunk-GH67YXG6.mjs → chunk-AZV7KNJI.mjs} +3 -3
- package/dist/{chunk-RMRS44MQ.mjs → chunk-BTUW5LSG.mjs} +11 -8
- package/dist/{chunk-2P2CB235.mjs → chunk-BULKGOIZ.mjs} +7 -8
- package/dist/{chunk-NHDI3VQB.mjs → chunk-CBIZLRYH.mjs} +15 -12
- package/dist/chunk-CM2DG4MR.mjs +142 -0
- package/dist/{chunk-TS7DGUIR.mjs → chunk-DBHSUUKU.mjs} +2 -2
- package/dist/{chunk-57V2LXCK.mjs → chunk-DE25XTVQ.mjs} +3 -3
- package/dist/{chunk-UQ4742ET.mjs → chunk-E4EQSCKR.mjs} +5 -5
- package/dist/{chunk-GUTDFUNF.mjs → chunk-EHGBHFMH.mjs} +9 -17
- package/dist/{chunk-CF27NBXO.mjs → chunk-EROPDCB5.mjs} +16 -24
- package/dist/{chunk-ZIMY2QUM.mjs → chunk-ERWJPVX7.mjs} +2 -2
- package/dist/{chunk-NLZY4TXU.mjs → chunk-ESQDPO5E.mjs} +7 -7
- package/dist/{chunk-VJBUCITV.mjs → chunk-EW2FIDSM.mjs} +1 -1
- package/dist/{chunk-HC4VVCWY.mjs → chunk-FTTI6T5Q.mjs} +4 -4
- package/dist/{chunk-2HFD4IHU.mjs → chunk-HUSSF6TF.mjs} +1 -1
- package/dist/chunk-IFYMBOEN.mjs +14 -0
- package/dist/{chunk-QOLWA2PW.mjs → chunk-IGU223UM.mjs} +80 -4
- package/dist/chunk-IJCMPVW5.mjs +121 -0
- package/dist/{chunk-AENAVIKT.mjs → chunk-ITG4JQM3.mjs} +4 -4
- package/dist/{chunk-E5UKLSJZ.mjs → chunk-K3QX2M26.mjs} +11 -8
- package/dist/{chunk-4OORJ2DY.mjs → chunk-K7TKID3V.mjs} +8 -7
- package/dist/{chunk-2LG326TT.mjs → chunk-KAGADD2O.mjs} +4 -4
- package/dist/{chunk-IVSRW4HS.mjs → chunk-KC5QDYGZ.mjs} +4 -4
- package/dist/{chunk-7AFZWSCI.mjs → chunk-KPTY7UYQ.mjs} +1 -1
- package/dist/{chunk-YTXRIXNZ.mjs → chunk-KSSVIFYR.mjs} +9 -12
- package/dist/chunk-L3YKPTJQ.mjs +119 -0
- package/dist/chunk-M53LC4Q7.mjs +35 -0
- package/dist/{chunk-ZR6HSEAB.mjs → chunk-MP7GLMIR.mjs} +17 -25
- package/dist/chunk-MZ6WRTD2.mjs +40 -0
- package/dist/chunk-NGEN2EES.mjs +581 -0
- package/dist/{chunk-C43HRKXH.mjs → chunk-OBV72JD4.mjs} +1 -1
- package/dist/{chunk-LPV4NJJK.mjs → chunk-PGQ6FMXS.mjs} +6 -5
- package/dist/{chunk-MEPSKGBO.mjs → chunk-PI6RULJX.mjs} +1 -1
- package/dist/{chunk-F3YTWO3T.mjs → chunk-RA6SAAFE.mjs} +9 -8
- package/dist/{chunk-UNNRUJTM.mjs → chunk-RRKM4MKB.mjs} +7 -7
- package/dist/{chunk-ULGNQPNE.mjs → chunk-S2VGME7X.mjs} +1 -1
- package/dist/{chunk-OLVJFKXS.mjs → chunk-S44XWTTC.mjs} +35 -25
- package/dist/{chunk-YMYIEVZP.mjs → chunk-SZEKQAOY.mjs} +1 -1
- package/dist/{chunk-ELGEOM7I.mjs → chunk-TETMEKZE.mjs} +9 -9
- package/dist/{chunk-BXF4AMHY.mjs → chunk-TMH263OK.mjs} +5 -4
- package/dist/{chunk-NJG7DHVF.mjs → chunk-U6DEBYU5.mjs} +10 -9
- package/dist/{chunk-RJNLAH76.mjs → chunk-UOKFSFNJ.mjs} +2 -2
- package/dist/{chunk-HEDQPK4I.mjs → chunk-URIH43IJ.mjs} +13 -21
- package/dist/{chunk-QXDGGOLC.mjs → chunk-V2ZB2XNS.mjs} +6 -6
- package/dist/{chunk-KSUWPU2F.mjs → chunk-WIPEDNSD.mjs} +7 -7
- package/dist/{chunk-QDAZGZUF.mjs → chunk-XCIG6HT2.mjs} +3 -3
- package/dist/{chunk-4J2PXL36.mjs → chunk-Y6YS33GM.mjs} +40 -38
- package/dist/{chunk-4XOB5TTD.mjs → chunk-ZKDKKQCE.mjs} +5 -5
- package/dist/{chunk-LOBLCFMN.mjs → chunk-ZTPYUU5C.mjs} +5 -5
- package/dist/index.d.mts +12 -72
- package/dist/index.d.ts +12 -72
- package/dist/index.js +1051 -1838
- package/dist/index.mjs +81 -85
- package/package.json +8 -10
- package/src/components/Accordion/Accordion.tsx +12 -9
- package/src/components/AlertBanner/AlertBanner.tsx +7 -6
- package/src/components/AppHeader/AppHeader.tsx +1 -1
- package/src/components/Avatar/Avatar.tsx +92 -1
- package/src/components/Avatar/index.ts +2 -2
- package/src/components/Badge/Badge.tsx +2 -2
- package/src/components/Button/Button.tsx +50 -46
- package/src/components/Card/Card.tsx +1 -0
- package/src/components/CategoryStrip/CategoryStrip.tsx +36 -49
- package/src/components/Chip/Chip.tsx +5 -4
- package/src/components/ConfirmDialog/ConfirmDialog.tsx +3 -3
- package/src/components/DetailRow/DetailRow.tsx +3 -3
- package/src/components/EmptyState/EmptyState.tsx +2 -2
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +6 -6
- package/src/components/HolographicCard/HolographicCard.tsx +14 -95
- package/src/components/IconButton/IconButton.tsx +2 -2
- package/src/components/IconPicker/IconPicker.tsx +13 -12
- package/src/components/ImageUpload/ImageUpload.tsx +14 -25
- package/src/components/ImageViewer/ImageViewer.tsx +3 -3
- package/src/components/Input/Input.tsx +11 -5
- package/src/components/LabelValue/LabelValue.tsx +2 -2
- package/src/components/ListItem/ListItem.tsx +4 -4
- package/src/components/MediaCard/MediaCard.tsx +21 -59
- package/src/components/MenuItem/MenuItem.tsx +2 -2
- package/src/components/MonthPicker/MonthPicker.tsx +2 -2
- package/src/components/NumberStepper/NumberStepper.tsx +6 -6
- package/src/components/PagerDots/PagerDots.tsx +38 -28
- package/src/components/PricingCard/PricingCard.tsx +6 -6
- package/src/components/RadioGroup/RadioGroup.tsx +18 -31
- package/src/components/Select/Select.tsx +32 -39
- package/src/components/SelectableCard/SelectableCard.tsx +4 -6
- package/src/components/SelectableGrid/SelectableGrid.tsx +38 -72
- package/src/components/Sheet/Sheet.tsx +1 -1
- package/src/components/SheetSelect/SheetSelect.tsx +3 -3
- package/src/components/Skeleton/Skeleton.tsx +1 -1
- package/src/components/Spinner/Spinner.tsx +2 -2
- package/src/components/Stats/Stats.tsx +2 -2
- package/src/components/Switch/Switch.tsx +9 -6
- package/src/components/TabBar/TabBar.tsx +9 -8
- package/src/components/Text/Text.tsx +12 -1
- package/src/components/Textarea/Textarea.tsx +18 -32
- package/src/components/Toggle/Toggle.tsx +3 -3
- package/src/hooks/useConfirmDialog.ts +31 -42
- package/src/index.ts +3 -4
- package/src/theme/ThemeProvider.tsx +1 -4
- package/src/theme/colorUtils.ts +1 -72
- package/src/theme/colors.ts +40 -1
- package/src/theme/types.ts +2 -2
- package/src/utils/animations.ts +0 -47
- package/src/utils/curatedIcons.ts +93 -801
- package/src/utils/haptics.ts +13 -208
- package/src/utils/icons.ts +27 -91
- package/src/utils/pressable.ts +10 -61
- package/dist/VirtualList.d.mts +0 -19
- package/dist/VirtualList.d.ts +0 -19
- package/dist/VirtualList.js +0 -38
- package/dist/VirtualList.mjs +0 -2
- package/dist/chunk-2BA3JMKK.mjs +0 -136
- package/dist/chunk-3DKJ2GIC.mjs +0 -30
- package/dist/chunk-7ELGZ66G.mjs +0 -164
- package/dist/chunk-DVK4G2GT.mjs +0 -59
- package/dist/chunk-EJ7ZPXOH.mjs +0 -163
- package/dist/chunk-KA7LTET3.mjs +0 -71
- package/dist/chunk-LNPKGWBG.mjs +0 -134
- package/dist/chunk-NC5ZTR2Y.mjs +0 -32
- package/dist/chunk-SAWUXP3A.mjs +0 -1114
- package/dist/chunk-YNROWHQJ.mjs +0 -46
- package/src/components/VirtualList/VirtualList.tsx +0 -60
- package/src/components/VirtualList/index.ts +0 -1
- package/src/utils/fontGuard.ts +0 -35
- package/src/utils/hover.ts +0 -25
- package/src/utils/useColorTransition.ts +0 -40
- package/src/utils/usePressScale.ts +0 -75
|
@@ -7,12 +7,14 @@ import {
|
|
|
7
7
|
ViewStyle,
|
|
8
8
|
TextStyle,
|
|
9
9
|
} from 'react-native'
|
|
10
|
+
import { EaseView } from 'react-native-ease'
|
|
10
11
|
import { impactMedium } from '../../utils/haptics'
|
|
11
12
|
import { useTheme } from '../../theme'
|
|
12
13
|
import { s, vs, ms, mvs } from '../../utils/scaling'
|
|
13
|
-
import {
|
|
14
|
+
import { Icon } from '../../utils/icons'
|
|
14
15
|
import { RADIUS, TYPOGRAPHY } from '../../tokens'
|
|
15
16
|
import { PressableButton } from '../../utils/pressable'
|
|
17
|
+
import { COLOR_TRANSITION } from '../../utils/animations'
|
|
16
18
|
|
|
17
19
|
export type ButtonVariant = 'primary' | 'secondary' | 'text' | 'destructive'
|
|
18
20
|
export type ButtonSize = 'sm' | 'md' | 'lg'
|
|
@@ -73,19 +75,16 @@ function ButtonBase({
|
|
|
73
75
|
onPress?.()
|
|
74
76
|
}
|
|
75
77
|
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
text: { backgroundColor: 'transparent' },
|
|
87
|
-
destructive: { backgroundColor: colors.destructive },
|
|
88
|
-
}[variant]
|
|
78
|
+
const isSecondary = variant === 'secondary'
|
|
79
|
+
const borderWidth = isSecondary ? 1.5 : 0
|
|
80
|
+
|
|
81
|
+
const animateBgColor: string = isDisabled
|
|
82
|
+
? { primary: colors.surface, secondary: 'transparent', text: 'transparent', destructive: colors.surface }[variant]
|
|
83
|
+
: { primary: colors.primary, secondary: 'transparent', text: 'transparent', destructive: colors.destructive }[variant]
|
|
84
|
+
|
|
85
|
+
const animateBorderColor: string = isDisabled
|
|
86
|
+
? (isSecondary ? colors.border : 'transparent')
|
|
87
|
+
: (isSecondary ? colors.primary : 'transparent')
|
|
89
88
|
|
|
90
89
|
const labelColor = isDisabled
|
|
91
90
|
? colors.foregroundMuted
|
|
@@ -99,7 +98,7 @@ function ButtonBase({
|
|
|
99
98
|
const textColor = iconColor ?? labelColor
|
|
100
99
|
|
|
101
100
|
const effectiveIcon: React.ReactNode = iconName
|
|
102
|
-
?
|
|
101
|
+
? <Icon name={iconName} size={iconSizeMap[size]} color={textColor} />
|
|
103
102
|
: typeof icon === 'function' ? icon({ label, size, variant, color: textColor }) : icon
|
|
104
103
|
|
|
105
104
|
const spinnerColor = isDisabled
|
|
@@ -115,13 +114,6 @@ function ButtonBase({
|
|
|
115
114
|
return (
|
|
116
115
|
<View style={[fullWidth && styles.fullWidth, flex !== undefined && { flex }]}>
|
|
117
116
|
<PressableButton
|
|
118
|
-
style={[
|
|
119
|
-
styles.base,
|
|
120
|
-
containerVariantStyle,
|
|
121
|
-
containerSizeStyles[size],
|
|
122
|
-
fullWidth && styles.fullWidth,
|
|
123
|
-
restStyle,
|
|
124
|
-
]}
|
|
125
117
|
enabled={!isDisabled}
|
|
126
118
|
onPress={handlePress}
|
|
127
119
|
rippleColor="transparent"
|
|
@@ -132,30 +124,42 @@ function ButtonBase({
|
|
|
132
124
|
accessibilityHint={accessibilityHint}
|
|
133
125
|
accessibilityState={{ disabled: isDisabled, busy: loading }}
|
|
134
126
|
>
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
127
|
+
<EaseView
|
|
128
|
+
style={[
|
|
129
|
+
styles.base,
|
|
130
|
+
containerSizeStyles[size],
|
|
131
|
+
{ borderWidth },
|
|
132
|
+
fullWidth && styles.fullWidth,
|
|
133
|
+
restStyle,
|
|
134
|
+
]}
|
|
135
|
+
animate={{ backgroundColor: animateBgColor, borderColor: animateBorderColor }}
|
|
136
|
+
transition={COLOR_TRANSITION}
|
|
137
|
+
>
|
|
138
|
+
{loading ? (
|
|
139
|
+
<>
|
|
140
|
+
<ActivityIndicator size="small" color={spinnerColor} style={{ marginRight: s(6) }} />
|
|
141
|
+
<Text
|
|
142
|
+
style={[styles.label, { color: labelColor }, labelSizeStyles[size], styles.labelLoading]}
|
|
143
|
+
allowFontScaling={true}
|
|
144
|
+
numberOfLines={1}
|
|
145
|
+
>
|
|
146
|
+
{label}
|
|
147
|
+
</Text>
|
|
148
|
+
</>
|
|
149
|
+
) : (
|
|
150
|
+
<>
|
|
151
|
+
{effectiveIcon && iconPosition === 'left' && <>{effectiveIcon}</>}
|
|
152
|
+
<Text
|
|
153
|
+
style={[styles.label, { color: labelColor }, labelSizeStyles[size], effectiveIcon ? styles.labelWithIcon : undefined]}
|
|
154
|
+
allowFontScaling={true}
|
|
155
|
+
numberOfLines={1}
|
|
156
|
+
>
|
|
157
|
+
{label}
|
|
158
|
+
</Text>
|
|
159
|
+
{effectiveIcon && iconPosition === 'right' && <>{effectiveIcon}</>}
|
|
160
|
+
</>
|
|
161
|
+
)}
|
|
162
|
+
</EaseView>
|
|
159
163
|
</PressableButton>
|
|
160
164
|
</View>
|
|
161
165
|
)
|
|
@@ -1,40 +1,33 @@
|
|
|
1
1
|
import React, { useCallback } from 'react'
|
|
2
2
|
import {
|
|
3
3
|
ScrollView,
|
|
4
|
-
TouchableOpacity,
|
|
5
4
|
Text,
|
|
6
5
|
View,
|
|
7
6
|
StyleSheet,
|
|
8
7
|
ViewStyle,
|
|
9
8
|
} from 'react-native'
|
|
10
|
-
import Animated from 'react-native-reanimated'
|
|
11
9
|
import { EaseView } from 'react-native-ease'
|
|
12
10
|
import { selectionAsync as hapticSelection } from '../../utils/haptics'
|
|
13
11
|
import { useTheme } from '../../theme'
|
|
14
12
|
import { s, vs, ms } from '../../utils/scaling'
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import { COLOR_TRANSITION
|
|
13
|
+
import { Icon } from '../../utils/icons'
|
|
14
|
+
import { PressableChip } from '../../utils/pressable'
|
|
15
|
+
import { COLOR_TRANSITION } from '../../utils/animations'
|
|
18
16
|
import { RADIUS } from '../../tokens'
|
|
19
17
|
|
|
20
18
|
export interface CategoryItem {
|
|
21
19
|
label: string
|
|
22
20
|
value: string
|
|
23
|
-
/** Icon rendered to the left of the label. ReactNode or icon name string. */
|
|
24
21
|
icon?: React.ReactNode | string
|
|
25
|
-
/** Badge count over the icon/label. */
|
|
26
22
|
badge?: number
|
|
27
23
|
}
|
|
28
24
|
|
|
29
25
|
export interface CategoryStripProps {
|
|
30
26
|
categories: CategoryItem[]
|
|
31
27
|
value?: string | string[]
|
|
32
|
-
/** Called with new value(s) on selection change. */
|
|
33
28
|
onValueChange?: (value: string | string[]) => void
|
|
34
|
-
/** Allow multiple simultaneous selections. Defaults to false. */
|
|
35
29
|
multiSelect?: boolean
|
|
36
30
|
style?: ViewStyle
|
|
37
|
-
/** Style applied to each pill item. */
|
|
38
31
|
itemStyle?: ViewStyle
|
|
39
32
|
accessibilityLabel?: string
|
|
40
33
|
}
|
|
@@ -49,53 +42,47 @@ const CategoryChip = React.memo(function CategoryChip({
|
|
|
49
42
|
onSelect: (value: string) => void
|
|
50
43
|
}) {
|
|
51
44
|
const { colors } = useTheme()
|
|
52
|
-
const { animatedStyle: scaleStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
53
|
-
pressScale: PRESS_SCALE.chip,
|
|
54
|
-
})
|
|
55
|
-
// Static color for icon — icon families take a static color prop, not animated.
|
|
56
45
|
const iconColor = selected ? colors.primaryForeground : colors.foregroundSubtle
|
|
57
46
|
const resolvedIcon =
|
|
58
47
|
typeof item.icon === 'string'
|
|
59
|
-
?
|
|
48
|
+
? <Icon name={item.icon} size={16} color={iconColor} />
|
|
60
49
|
: item.icon ?? null
|
|
61
50
|
|
|
62
51
|
return (
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
52
|
+
<PressableChip
|
|
53
|
+
onPress={() => onSelect(item.value)}
|
|
54
|
+
enabled
|
|
55
|
+
rippleColor="transparent"
|
|
56
|
+
touchSoundDisabled
|
|
57
|
+
activateOnHover
|
|
58
|
+
accessibilityRole="button"
|
|
59
|
+
accessibilityLabel={item.label}
|
|
60
|
+
accessibilityState={{ selected }}
|
|
61
|
+
>
|
|
62
|
+
<EaseView
|
|
63
|
+
style={styles.chip}
|
|
64
|
+
animate={{
|
|
65
|
+
backgroundColor: selected ? colors.primary : colors.surface,
|
|
66
|
+
borderColor: selected ? colors.primary : colors.border,
|
|
67
|
+
}}
|
|
68
|
+
transition={COLOR_TRANSITION}
|
|
73
69
|
>
|
|
74
|
-
<
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
borderColor: selected ? colors.primary : colors.border,
|
|
79
|
-
}}
|
|
80
|
-
transition={COLOR_TRANSITION}
|
|
70
|
+
{resolvedIcon && <View style={styles.chipIcon}>{resolvedIcon}</View>}
|
|
71
|
+
<Text
|
|
72
|
+
style={[styles.chipLabel, { color: selected ? colors.primaryForeground : colors.foregroundSubtle }]}
|
|
73
|
+
allowFontScaling={true}
|
|
81
74
|
>
|
|
82
|
-
{
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
</Text>
|
|
94
|
-
</View>
|
|
95
|
-
)}
|
|
96
|
-
</EaseView>
|
|
97
|
-
</TouchableOpacity>
|
|
98
|
-
</Animated.View>
|
|
75
|
+
{item.label}
|
|
76
|
+
</Text>
|
|
77
|
+
{item.badge !== undefined && item.badge > 0 && (
|
|
78
|
+
<View style={[styles.chipBadge, { backgroundColor: colors.primary }]}>
|
|
79
|
+
<Text style={[styles.chipBadgeText, { color: colors.primaryForeground }]}>
|
|
80
|
+
{Math.min(item.badge, 99)}
|
|
81
|
+
</Text>
|
|
82
|
+
</View>
|
|
83
|
+
)}
|
|
84
|
+
</EaseView>
|
|
85
|
+
</PressableChip>
|
|
99
86
|
)
|
|
100
87
|
})
|
|
101
88
|
|
|
@@ -4,8 +4,9 @@ import { EaseView } from 'react-native-ease'
|
|
|
4
4
|
import { selectionAsync as hapticSelection } from '../../utils/haptics'
|
|
5
5
|
import { useTheme } from '../../theme'
|
|
6
6
|
import { s, vs, ms, mvs } from '../../utils/scaling'
|
|
7
|
-
import {
|
|
7
|
+
import { Icon } from '../../utils/icons'
|
|
8
8
|
import { COLOR_TRANSITION } from '../../utils/animations'
|
|
9
|
+
import { RADIUS } from '../../tokens'
|
|
9
10
|
import { PressableChip as PressableChipComponent } from '../../utils/pressable'
|
|
10
11
|
|
|
11
12
|
export interface ChipProps {
|
|
@@ -43,7 +44,7 @@ function ChipBase({ label, selected = false, onPress, icon, iconName, style, acc
|
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
const resolvedIcon = iconName
|
|
46
|
-
?
|
|
47
|
+
? <Icon name={iconName} size={ms(13)} color={selected ? colors.primaryForeground : colors.foreground} />
|
|
47
48
|
: icon
|
|
48
49
|
|
|
49
50
|
return (
|
|
@@ -111,7 +112,7 @@ export function ChipGroup({ options, value, onValueChange, multiSelect = false,
|
|
|
111
112
|
// Now passes disabled state to the Chip's TouchableOpacity via onPress=undefined
|
|
112
113
|
// and adds explicit accessibility state for screen readers.
|
|
113
114
|
style={opt.disabled ? styles.chipDisabled : undefined}
|
|
114
|
-
accessibilityLabel={opt.disabled ? `${opt.label},
|
|
115
|
+
accessibilityLabel={opt.disabled ? `${opt.label}, no disponible` : opt.label}
|
|
115
116
|
/>
|
|
116
117
|
))}
|
|
117
118
|
</View>
|
|
@@ -121,7 +122,7 @@ export function ChipGroup({ options, value, onValueChange, multiSelect = false,
|
|
|
121
122
|
const styles = StyleSheet.create({
|
|
122
123
|
wrapper: {},
|
|
123
124
|
chip: {
|
|
124
|
-
borderRadius:
|
|
125
|
+
borderRadius: RADIUS.full,
|
|
125
126
|
paddingHorizontal: s(14),
|
|
126
127
|
// AUDIT FIX: was vs(5) → ~28px total height — below WCAG 44px tap target.
|
|
127
128
|
// vs(10) → ~44px total height meets WCAG 2.5.5 (AAA) minimum.
|
|
@@ -30,8 +30,8 @@ export function ConfirmDialog({
|
|
|
30
30
|
visible,
|
|
31
31
|
title,
|
|
32
32
|
subtitle,
|
|
33
|
-
confirmLabel = '
|
|
34
|
-
cancelLabel = '
|
|
33
|
+
confirmLabel = 'Confirmar',
|
|
34
|
+
cancelLabel = 'Cancelar',
|
|
35
35
|
confirmVariant = 'primary',
|
|
36
36
|
loading = false,
|
|
37
37
|
showCloseButton = false,
|
|
@@ -98,7 +98,7 @@ export function ConfirmDialog({
|
|
|
98
98
|
activeOpacity={0.6}
|
|
99
99
|
touchSoundDisabled={true}
|
|
100
100
|
accessibilityRole="button"
|
|
101
|
-
accessibilityLabel="
|
|
101
|
+
accessibilityLabel="Cerrar"
|
|
102
102
|
hitSlop={{ top: 12, bottom: 12, left: 12, right: 12 }}
|
|
103
103
|
>
|
|
104
104
|
<Feather name="x" size={ms(18)} color={colors.foregroundMuted} />
|
|
@@ -2,7 +2,7 @@ import React from 'react'
|
|
|
2
2
|
import { View, Text, StyleSheet, ViewStyle, TextStyle } from 'react-native'
|
|
3
3
|
import { useTheme } from '../../theme'
|
|
4
4
|
import { s, ms, mvs } from '../../utils/scaling'
|
|
5
|
-
import {
|
|
5
|
+
import { Icon } from '../../utils/icons'
|
|
6
6
|
|
|
7
7
|
export type DetailRowSeparator = 'dotted' | 'solid' | 'dashed' | 'none'
|
|
8
8
|
export type DetailRowLabelWeight = 'normal' | 'medium' | 'semibold' | 'bold'
|
|
@@ -56,11 +56,11 @@ function DetailRowBase({
|
|
|
56
56
|
const { colors } = useTheme()
|
|
57
57
|
|
|
58
58
|
const resolvedLeftIcon = leftIconName
|
|
59
|
-
?
|
|
59
|
+
? <Icon name={leftIconName} size={ms(14)} color={leftIconColor ?? colors.foregroundMuted} />
|
|
60
60
|
: leftIcon
|
|
61
61
|
|
|
62
62
|
const resolvedRightIcon = rightIconName
|
|
63
|
-
?
|
|
63
|
+
? <Icon name={rightIconName} size={ms(14)} color={rightIconColor ?? colors.foregroundMuted} />
|
|
64
64
|
: null
|
|
65
65
|
|
|
66
66
|
const separatorStyle: ViewStyle | null =
|
|
@@ -2,7 +2,7 @@ import React from 'react'
|
|
|
2
2
|
import { View, Text, StyleSheet, ViewStyle } from 'react-native'
|
|
3
3
|
import { useTheme } from '../../theme'
|
|
4
4
|
import { s, vs, ms, mvs } from '../../utils/scaling'
|
|
5
|
-
import {
|
|
5
|
+
import { Icon } from '../../utils/icons'
|
|
6
6
|
import { Button } from '../Button'
|
|
7
7
|
|
|
8
8
|
export interface EmptyStateProps {
|
|
@@ -32,7 +32,7 @@ export function EmptyState({ icon, iconName, iconColor, title, description, acti
|
|
|
32
32
|
const isCompact = size === 'compact'
|
|
33
33
|
|
|
34
34
|
const effectiveIcon: React.ReactNode = iconName
|
|
35
|
-
?
|
|
35
|
+
? <Icon name={iconName} size={isCompact ? 32 : 48} color={iconColor ?? colors.foregroundMuted} />
|
|
36
36
|
: icon
|
|
37
37
|
|
|
38
38
|
return (
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'
|
|
3
3
|
import { useTheme } from '../../theme'
|
|
4
|
-
import {
|
|
4
|
+
import { Icon } from '../../utils/icons'
|
|
5
5
|
import { s, vs, ms, mvs } from '../../utils/scaling'
|
|
6
6
|
import { RADIUS } from '../../tokens'
|
|
7
7
|
import { impactLight } from '../../utils/haptics'
|
|
@@ -35,20 +35,20 @@ interface ErrorBoundaryState {
|
|
|
35
35
|
function DefaultErrorFallback({
|
|
36
36
|
error,
|
|
37
37
|
reset,
|
|
38
|
-
title = '
|
|
38
|
+
title = 'Algo salió mal',
|
|
39
39
|
message,
|
|
40
40
|
}: ErrorFallbackProps & { title?: string; message?: string }) {
|
|
41
41
|
const { colors } = useTheme()
|
|
42
42
|
return (
|
|
43
43
|
<View style={[styles.container, { backgroundColor: colors.background }]} accessibilityRole="alert">
|
|
44
44
|
<View style={[styles.iconCircle, { backgroundColor: colors.destructiveTint }]}>
|
|
45
|
-
|
|
45
|
+
<Icon name="alert-triangle" size={ms(28)} color={colors.destructive} />
|
|
46
46
|
</View>
|
|
47
47
|
<Text style={[styles.title, { color: colors.foreground }]} allowFontScaling={true}>
|
|
48
48
|
{title}
|
|
49
49
|
</Text>
|
|
50
50
|
<Text style={[styles.message, { color: colors.foregroundMuted }]} allowFontScaling={true}>
|
|
51
|
-
{message ?? error.message ?? '
|
|
51
|
+
{message ?? error.message ?? 'Ocurrió un error inesperado.'}
|
|
52
52
|
</Text>
|
|
53
53
|
<TouchableOpacity
|
|
54
54
|
style={[styles.button, { backgroundColor: colors.primary }]}
|
|
@@ -59,10 +59,10 @@ function DefaultErrorFallback({
|
|
|
59
59
|
activeOpacity={0.85}
|
|
60
60
|
touchSoundDisabled={true}
|
|
61
61
|
accessibilityRole="button"
|
|
62
|
-
accessibilityLabel="
|
|
62
|
+
accessibilityLabel="Intentar de nuevo"
|
|
63
63
|
>
|
|
64
64
|
<Text style={[styles.buttonLabel, { color: colors.primaryForeground }]} allowFontScaling={true}>
|
|
65
|
-
|
|
65
|
+
Intentar de nuevo
|
|
66
66
|
</Text>
|
|
67
67
|
</TouchableOpacity>
|
|
68
68
|
</View>
|