@retray-dev/ui-kit 12.2.0 → 13.2.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/CONSUMER.md +26 -11
- package/DESIGN.md +2 -2
- package/README.md +15 -11
- package/{COMPONENTS.md → SKILL.md} +374 -996
- package/dist/Accordion.d.mts +2 -0
- package/dist/Accordion.d.ts +2 -0
- package/dist/Accordion.js +49 -210
- package/dist/Accordion.mjs +6 -6
- package/dist/AlertBanner.js +29 -153
- package/dist/AlertBanner.mjs +3 -4
- package/dist/AppHeader.d.mts +5 -2
- package/dist/AppHeader.d.ts +5 -2
- package/dist/AppHeader.js +45 -239
- package/dist/AppHeader.mjs +6 -8
- 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 -3
- package/dist/Badge.js +24 -149
- package/dist/Badge.mjs +3 -4
- package/dist/Button.js +79 -267
- package/dist/Button.mjs +6 -7
- package/dist/ButtonGroup.mjs +0 -1
- package/dist/Card.js +15 -200
- package/dist/Card.mjs +4 -6
- 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 -7
- package/dist/Checkbox.d.mts +2 -1
- package/dist/Checkbox.d.ts +2 -1
- package/dist/Checkbox.js +18 -201
- package/dist/Checkbox.mjs +5 -6
- package/dist/Chip.js +44 -236
- package/dist/Chip.mjs +7 -7
- package/dist/ConfirmDialog.d.mts +2 -1
- package/dist/ConfirmDialog.d.ts +2 -1
- package/dist/ConfirmDialog.js +110 -300
- package/dist/ConfirmDialog.mjs +7 -8
- package/dist/CurrencyDisplay.js +1 -114
- package/dist/CurrencyDisplay.mjs +2 -3
- package/dist/CurrencyInput.js +35 -162
- package/dist/CurrencyInput.mjs +5 -6
- package/dist/DetailRow.js +25 -150
- package/dist/DetailRow.mjs +3 -4
- package/dist/EmptyState.js +80 -268
- package/dist/EmptyState.mjs +7 -8
- package/dist/ErrorBoundary.js +32 -199
- package/dist/ErrorBoundary.mjs +4 -5
- package/dist/Form.js +1 -114
- package/dist/Form.mjs +2 -3
- 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 -33
- package/dist/IconButton.js +36 -234
- package/dist/IconButton.mjs +5 -7
- package/dist/IconPicker.js +222 -929
- package/dist/IconPicker.mjs +5 -6
- package/dist/ImageUpload.d.mts +3 -3
- package/dist/ImageUpload.d.ts +3 -3
- package/dist/ImageUpload.js +49 -238
- package/dist/ImageUpload.mjs +5 -7
- package/dist/ImageViewer.js +75 -266
- package/dist/ImageViewer.mjs +8 -9
- 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 -5
- package/dist/LabelValue.js +24 -149
- package/dist/LabelValue.mjs +3 -4
- package/dist/ListGroup.js +1 -114
- package/dist/ListGroup.mjs +2 -3
- package/dist/ListItem.d.mts +2 -1
- package/dist/ListItem.d.ts +2 -1
- package/dist/ListItem.js +41 -236
- package/dist/ListItem.mjs +5 -7
- 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 -7
- package/dist/MenuGroup.js +1 -114
- package/dist/MenuGroup.mjs +2 -3
- package/dist/MenuItem.d.mts +2 -1
- package/dist/MenuItem.d.ts +2 -1
- package/dist/MenuItem.js +39 -235
- package/dist/MenuItem.mjs +5 -7
- package/dist/MonthPicker.js +8 -163
- package/dist/MonthPicker.mjs +3 -4
- package/dist/NumberStepper.d.mts +2 -1
- package/dist/NumberStepper.d.ts +2 -1
- package/dist/NumberStepper.js +44 -239
- package/dist/NumberStepper.mjs +5 -7
- 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 -6
- package/dist/Pressable.js +14 -85
- package/dist/Pressable.mjs +4 -5
- package/dist/PricingCard.js +87 -272
- package/dist/PricingCard.mjs +8 -9
- package/dist/Progress.js +3 -123
- package/dist/Progress.mjs +3 -4
- package/dist/RadioGroup.js +52 -265
- package/dist/RadioGroup.mjs +5 -6
- package/dist/RetrayProvider.js +3 -6
- package/dist/RetrayProvider.mjs +3 -4
- package/dist/Select.d.mts +3 -1
- package/dist/Select.d.ts +3 -1
- package/dist/Select.js +27 -233
- package/dist/Select.mjs +4 -6
- package/dist/SelectableCard.js +33 -209
- package/dist/SelectableCard.mjs +5 -6
- package/dist/SelectableGrid.d.mts +0 -21
- package/dist/SelectableGrid.d.ts +0 -21
- package/dist/SelectableGrid.js +49 -272
- package/dist/SelectableGrid.mjs +5 -7
- package/dist/Separator.js +1 -114
- package/dist/Separator.mjs +2 -3
- package/dist/Sheet.d.mts +1 -1
- package/dist/Sheet.d.ts +1 -1
- package/dist/Sheet.js +33 -175
- package/dist/Sheet.mjs +3 -4
- package/dist/SheetSelect.js +39 -236
- package/dist/SheetSelect.mjs +6 -7
- package/dist/Skeleton.js +4 -124
- package/dist/Skeleton.mjs +3 -4
- package/dist/Slider.d.mts +2 -1
- package/dist/Slider.d.ts +2 -1
- package/dist/Slider.js +8 -161
- package/dist/Slider.mjs +3 -4
- package/dist/Spinner.js +3 -116
- package/dist/Spinner.mjs +2 -3
- package/dist/Stats.js +36 -234
- package/dist/Stats.mjs +5 -7
- package/dist/Switch.d.mts +2 -1
- package/dist/Switch.d.ts +2 -1
- package/dist/Switch.js +26 -176
- package/dist/Switch.mjs +5 -5
- package/dist/TabBar.js +43 -200
- package/dist/TabBar.mjs +5 -5
- package/dist/Tabs.js +15 -199
- package/dist/Tabs.mjs +5 -6
- package/dist/Text.js +9 -130
- package/dist/Text.mjs +2 -3
- 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 -5
- package/dist/Toast.d.mts +12 -10
- package/dist/Toast.d.ts +12 -10
- package/dist/Toast.js +1 -114
- package/dist/Toast.mjs +2 -3
- package/dist/Toggle.js +39 -236
- package/dist/Toggle.mjs +6 -7
- package/dist/{chunk-ELGEOM7I.mjs → chunk-2QXJDRVU.mjs} +13 -10
- package/dist/{chunk-LIS6I5UP.mjs → chunk-2VIDP72N.mjs} +3 -3
- package/dist/{chunk-NHDI3VQB.mjs → chunk-422IVD3H.mjs} +16 -12
- package/dist/{chunk-DF7JA72E.mjs → chunk-4NQFTHN3.mjs} +13 -7
- package/dist/{chunk-3XCFYSX4.mjs → chunk-5MYNAAFE.mjs} +13 -17
- package/dist/{chunk-E7NEHHXV.mjs → chunk-62BBSSUF.mjs} +3 -3
- package/dist/{chunk-UBUXUMER.mjs → chunk-77UOVFIS.mjs} +7 -5
- package/dist/{chunk-M3C7XM2M.mjs → chunk-7BZJRB77.mjs} +28 -18
- package/dist/chunk-ARONDO7M.mjs +40 -0
- package/dist/{chunk-GH67YXG6.mjs → chunk-AZV7KNJI.mjs} +3 -3
- package/dist/{chunk-2P2CB235.mjs → chunk-BULKGOIZ.mjs} +7 -8
- package/dist/{chunk-RJNLAH76.mjs → chunk-C5ZRMR2E.mjs} +4 -2
- package/dist/chunk-CM2DG4MR.mjs +142 -0
- package/dist/{chunk-UQ4742ET.mjs → chunk-COA2YZOX.mjs} +8 -6
- package/dist/{chunk-EDLCGYIO.mjs → chunk-CZN6L2QU.mjs} +11 -8
- package/dist/{chunk-TS7DGUIR.mjs → chunk-DBHSUUKU.mjs} +2 -2
- package/dist/{chunk-57V2LXCK.mjs → chunk-DE25XTVQ.mjs} +3 -3
- package/dist/{chunk-RMRS44MQ.mjs → chunk-E2PONRJG.mjs} +13 -9
- package/dist/{chunk-GUTDFUNF.mjs → chunk-EHGBHFMH.mjs} +9 -17
- 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-MVMGPZN6.mjs → chunk-H6MQL7PS.mjs} +12 -7
- package/dist/{chunk-CF27NBXO.mjs → chunk-HHOOFDBA.mjs} +38 -41
- package/dist/{chunk-2HFD4IHU.mjs → chunk-HUSSF6TF.mjs} +1 -1
- package/dist/{chunk-HEDQPK4I.mjs → chunk-IDVUZIVY.mjs} +16 -22
- 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-MZ6WRTD2.mjs +40 -0
- package/dist/chunk-NGEN2EES.mjs +581 -0
- package/dist/{chunk-ZR6HSEAB.mjs → chunk-NPCBNGNE.mjs} +17 -26
- 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-BXF4AMHY.mjs → chunk-TMH263OK.mjs} +5 -4
- package/dist/{chunk-NJG7DHVF.mjs → chunk-U6DEBYU5.mjs} +10 -9
- package/dist/{chunk-QXDGGOLC.mjs → chunk-UMZTPUB3.mjs} +33 -21
- 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/fonts.mjs +0 -2
- package/dist/index.d.mts +13 -73
- package/dist/index.d.ts +13 -73
- package/dist/index.js +1149 -1892
- package/dist/index.mjs +81 -86
- package/package.json +20 -20
- package/src/components/Accordion/Accordion.tsx +15 -9
- package/src/components/AlertBanner/AlertBanner.tsx +7 -6
- package/src/components/AppHeader/AppHeader.tsx +25 -10
- 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/Checkbox/Checkbox.tsx +3 -0
- package/src/components/Chip/Chip.tsx +5 -4
- package/src/components/ConfirmDialog/ConfirmDialog.tsx +33 -17
- 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 +43 -46
- 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 +7 -4
- package/src/components/MediaCard/MediaCard.tsx +21 -59
- package/src/components/MenuItem/MenuItem.tsx +5 -2
- package/src/components/MonthPicker/MonthPicker.tsx +2 -2
- package/src/components/NumberStepper/NumberStepper.tsx +10 -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 +35 -39
- package/src/components/SelectableCard/SelectableCard.tsx +4 -6
- package/src/components/SelectableGrid/SelectableGrid.tsx +37 -72
- package/src/components/Sheet/Sheet.tsx +28 -15
- package/src/components/Sheet/index.ts +2 -2
- package/src/components/SheetSelect/SheetSelect.tsx +3 -3
- package/src/components/Skeleton/Skeleton.tsx +1 -1
- package/src/components/Slider/Slider.tsx +3 -0
- package/src/components/Spinner/Spinner.tsx +2 -2
- package/src/components/Stats/Stats.tsx +2 -2
- package/src/components/Switch/Switch.tsx +12 -7
- package/src/components/TabBar/TabBar.tsx +9 -8
- package/src/components/Text/Text.tsx +13 -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-Y6FXYEAI.mjs +0 -8
- 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
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
+
import { Image } from 'expo-image'
|
|
2
3
|
import {
|
|
3
4
|
View,
|
|
4
5
|
Text,
|
|
5
6
|
StyleSheet,
|
|
6
7
|
ViewStyle,
|
|
7
8
|
TextStyle,
|
|
8
|
-
Image,
|
|
9
9
|
ImageSourcePropType,
|
|
10
10
|
} from 'react-native'
|
|
11
11
|
import { Entypo } from '@expo/vector-icons'
|
|
12
12
|
import { selectionAsync as hapticSelection } from '../../utils/haptics'
|
|
13
13
|
import { useTheme } from '../../theme'
|
|
14
14
|
import { s, vs, ms, mvs } from '../../utils/scaling'
|
|
15
|
-
import {
|
|
15
|
+
import { Icon } from '../../utils/icons'
|
|
16
16
|
import { RADIUS } from '../../tokens'
|
|
17
17
|
import { PressableRow } from '../../utils/pressable'
|
|
18
18
|
|
|
@@ -85,6 +85,7 @@ export interface ListItemProps {
|
|
|
85
85
|
captionStyle?: TextStyle
|
|
86
86
|
/** Accessibility label override. Defaults to the title. */
|
|
87
87
|
accessibilityLabel?: string
|
|
88
|
+
accessibilityHint?: string
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
function ListItemBase({
|
|
@@ -110,6 +111,7 @@ function ListItemBase({
|
|
|
110
111
|
subtitleNumberOfLines = 2,
|
|
111
112
|
captionStyle,
|
|
112
113
|
accessibilityLabel,
|
|
114
|
+
accessibilityHint,
|
|
113
115
|
}: ListItemProps) {
|
|
114
116
|
const { colors } = useTheme()
|
|
115
117
|
|
|
@@ -122,7 +124,7 @@ function ListItemBase({
|
|
|
122
124
|
const effectiveLeft: React.ReactNode = imageSource
|
|
123
125
|
? <Image source={imageSource} style={styles.image} />
|
|
124
126
|
: leftIcon
|
|
125
|
-
?
|
|
127
|
+
? <Icon name={leftIcon} size={24} color={leftIconColor ?? colors.foreground} />
|
|
126
128
|
: leftRender
|
|
127
129
|
|
|
128
130
|
const hasRightContent = !!(rightIcon || (rightActions && rightActions.length > 0) || rightRender !== undefined || showChevron)
|
|
@@ -181,7 +183,7 @@ function ListItemBase({
|
|
|
181
183
|
{hasRightContent ? (
|
|
182
184
|
rightIcon ? (
|
|
183
185
|
<View style={styles.rightContainer}>
|
|
184
|
-
{
|
|
186
|
+
<Icon name={rightIcon} size={24} color={rightIconColor ?? colors.foregroundMuted} />
|
|
185
187
|
</View>
|
|
186
188
|
) : rightActions && rightActions.length > 0 ? (
|
|
187
189
|
<View style={styles.rightActionsContainer}>
|
|
@@ -221,6 +223,7 @@ function ListItemBase({
|
|
|
221
223
|
activateOnHover
|
|
222
224
|
accessibilityRole="button"
|
|
223
225
|
accessibilityLabel={a11yLabel}
|
|
226
|
+
accessibilityHint={accessibilityHint}
|
|
224
227
|
accessibilityState={{ disabled: !!disabled }}
|
|
225
228
|
>
|
|
226
229
|
{content}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
+
import { Image } from 'expo-image'
|
|
2
3
|
import {
|
|
3
4
|
View,
|
|
4
|
-
Image,
|
|
5
5
|
Text,
|
|
6
6
|
TouchableOpacity,
|
|
7
7
|
StyleSheet,
|
|
@@ -9,15 +9,12 @@ import {
|
|
|
9
9
|
ImageSourcePropType,
|
|
10
10
|
Platform,
|
|
11
11
|
} from 'react-native'
|
|
12
|
-
import Animated from 'react-native-reanimated'
|
|
13
12
|
import { impactLight } from '../../utils/haptics'
|
|
14
13
|
import { useTheme } from '../../theme'
|
|
15
14
|
import { s, vs, ms, mvs } from '../../utils/scaling'
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import { SPRINGS, PRESS_SCALE } from '../../utils/animations'
|
|
20
|
-
import { RADIUS, SHADOWS } from '../../tokens'
|
|
15
|
+
import { Icon } from '../../utils/icons'
|
|
16
|
+
import { PressableCard } from '../../utils/pressable'
|
|
17
|
+
import { RADIUS } from '../../tokens'
|
|
21
18
|
|
|
22
19
|
export type MediaCardAspectRatio = '1:1' | '4:3' | '16:9' | '4:5' | '3:2'
|
|
23
20
|
|
|
@@ -30,34 +27,20 @@ const aspectRatioMap: Record<MediaCardAspectRatio, number> = {
|
|
|
30
27
|
}
|
|
31
28
|
|
|
32
29
|
export interface MediaCardProps {
|
|
33
|
-
/** Image source — URI string or require(). */
|
|
34
30
|
imageSource?: ImageSourcePropType
|
|
35
|
-
/** Image aspect ratio. Defaults to `'4:3'`. */
|
|
36
31
|
aspectRatio?: MediaCardAspectRatio
|
|
37
|
-
/** Badge content rendered top-left over the image (e.g. a Badge component or Text). */
|
|
38
32
|
badge?: React.ReactNode
|
|
39
|
-
/** Icon rendered in a circle button top-right over the image. Defaults to `'heart'`. */
|
|
40
33
|
actionIcon?: React.ReactNode
|
|
41
|
-
/** Icon name for the action button. Overrides `actionIcon`. */
|
|
42
34
|
actionIconName?: string
|
|
43
|
-
/** Whether the action icon is in active/filled state. */
|
|
44
35
|
actionActive?: boolean
|
|
45
|
-
/** Called when the top-right action icon is pressed. */
|
|
46
36
|
onActionPress?: () => void
|
|
47
|
-
/** Primary text below the image. */
|
|
48
37
|
title?: string
|
|
49
|
-
/** Secondary text below the title. */
|
|
50
38
|
subtitle?: string
|
|
51
|
-
/** Tertiary / caption text below subtitle. */
|
|
52
39
|
caption?: string
|
|
53
|
-
/** Called when the card body is pressed. */
|
|
54
40
|
onPress?: () => void
|
|
55
41
|
style?: ViewStyle
|
|
56
|
-
/** Style for the image container. */
|
|
57
42
|
imageStyle?: ViewStyle
|
|
58
|
-
/** Additional content rendered below caption. */
|
|
59
43
|
footer?: React.ReactNode
|
|
60
|
-
/** Accessibility label override. Defaults to title (and subtitle if present). */
|
|
61
44
|
accessibilityLabel?: string
|
|
62
45
|
}
|
|
63
46
|
|
|
@@ -79,13 +62,6 @@ function MediaCardBase({
|
|
|
79
62
|
accessibilityLabel,
|
|
80
63
|
}: MediaCardProps) {
|
|
81
64
|
const { colors } = useTheme()
|
|
82
|
-
const { hovered, hoverHandlers } = useHover()
|
|
83
|
-
const { animatedStyle, onPressIn, onPressOut } = usePressScale({
|
|
84
|
-
pressScale: PRESS_SCALE.card,
|
|
85
|
-
pressInSpring: SPRINGS.surfacePressIn,
|
|
86
|
-
pressOutSpring: SPRINGS.surfacePressOut,
|
|
87
|
-
disabled: !onPress,
|
|
88
|
-
})
|
|
89
65
|
|
|
90
66
|
const handlePress = () => {
|
|
91
67
|
if (!onPress) return
|
|
@@ -95,22 +71,14 @@ function MediaCardBase({
|
|
|
95
71
|
|
|
96
72
|
const ratio = aspectRatioMap[aspectRatio]
|
|
97
73
|
|
|
98
|
-
// Action icon: active = primary fill, inactive = foreground outline
|
|
99
74
|
const resolvedActionIcon = actionIconName
|
|
100
|
-
?
|
|
101
|
-
: actionIcon ??
|
|
75
|
+
? <Icon name={actionIconName} size={18} color={actionActive ? colors.primary : colors.background} />
|
|
76
|
+
: actionIcon ?? <Icon name="heart" size={18} color={actionActive ? colors.primary : colors.background} />
|
|
102
77
|
|
|
103
78
|
const a11yLabel = accessibilityLabel ?? [title, subtitle].filter(Boolean).join('. ')
|
|
104
79
|
|
|
105
80
|
const cardContent = (
|
|
106
|
-
<View
|
|
107
|
-
style={[
|
|
108
|
-
styles.card,
|
|
109
|
-
hovered && styles.cardHovered,
|
|
110
|
-
style,
|
|
111
|
-
]}
|
|
112
|
-
{...(Platform.OS === 'web' ? hoverHandlers : {})}
|
|
113
|
-
>
|
|
81
|
+
<View style={[styles.card, style]}>
|
|
114
82
|
<View style={[styles.imageContainer, imageStyle]}>
|
|
115
83
|
<View style={{ paddingTop: `${ratio * 100}%` as `${number}%` }}>
|
|
116
84
|
<View style={StyleSheet.absoluteFill}>
|
|
@@ -118,7 +86,7 @@ function MediaCardBase({
|
|
|
118
86
|
<Image
|
|
119
87
|
source={imageSource}
|
|
120
88
|
style={styles.image}
|
|
121
|
-
|
|
89
|
+
contentFit="cover"
|
|
122
90
|
/>
|
|
123
91
|
) : (
|
|
124
92
|
<View style={[styles.imagePlaceholder, { backgroundColor: colors.surface }]} />
|
|
@@ -136,16 +104,14 @@ function MediaCardBase({
|
|
|
136
104
|
<TouchableOpacity
|
|
137
105
|
style={[styles.actionButton, { backgroundColor: 'rgba(0,0,0,0.24)' }]}
|
|
138
106
|
onPress={(e) => {
|
|
139
|
-
// Stop propagation to prevent triggering parent onPress
|
|
140
107
|
e?.stopPropagation?.()
|
|
141
108
|
impactLight()
|
|
142
109
|
onActionPress?.()
|
|
143
110
|
}}
|
|
144
111
|
activeOpacity={0.8}
|
|
145
112
|
touchSoundDisabled={true}
|
|
146
|
-
// On web, avoid nested <button> by using a non-button role when parent is pressable
|
|
147
113
|
accessibilityRole={Platform.OS === 'web' && onPress ? undefined : 'button'}
|
|
148
|
-
accessibilityLabel={actionIconName ?? '
|
|
114
|
+
accessibilityLabel={actionIconName ?? 'acción'}
|
|
149
115
|
accessibilityState={{ selected: actionActive }}
|
|
150
116
|
>
|
|
151
117
|
{resolvedActionIcon}
|
|
@@ -178,19 +144,18 @@ function MediaCardBase({
|
|
|
178
144
|
|
|
179
145
|
if (onPress) {
|
|
180
146
|
return (
|
|
181
|
-
<
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
</Animated.View>
|
|
147
|
+
<PressableCard
|
|
148
|
+
onPress={handlePress}
|
|
149
|
+
enabled
|
|
150
|
+
rippleColor="transparent"
|
|
151
|
+
touchSoundDisabled
|
|
152
|
+
activateOnHover
|
|
153
|
+
accessibilityRole="button"
|
|
154
|
+
accessibilityLabel={a11yLabel}
|
|
155
|
+
accessibilityState={{ disabled: false }}
|
|
156
|
+
>
|
|
157
|
+
{cardContent}
|
|
158
|
+
</PressableCard>
|
|
194
159
|
)
|
|
195
160
|
}
|
|
196
161
|
|
|
@@ -205,9 +170,6 @@ const styles = StyleSheet.create({
|
|
|
205
170
|
overflow: 'hidden',
|
|
206
171
|
backgroundColor: 'transparent',
|
|
207
172
|
},
|
|
208
|
-
cardHovered: {
|
|
209
|
-
...SHADOWS.md,
|
|
210
|
-
},
|
|
211
173
|
imageContainer: {
|
|
212
174
|
borderRadius: RADIUS.md,
|
|
213
175
|
overflow: 'hidden',
|
|
@@ -10,7 +10,7 @@ import { Entypo } from '@expo/vector-icons'
|
|
|
10
10
|
import { selectionAsync as hapticSelection } from '../../utils/haptics'
|
|
11
11
|
import { useTheme } from '../../theme'
|
|
12
12
|
import { s, vs, ms } from '../../utils/scaling'
|
|
13
|
-
import {
|
|
13
|
+
import { Icon } from '../../utils/icons'
|
|
14
14
|
import { RADIUS } from '../../tokens'
|
|
15
15
|
import { PressableRow } from '../../utils/pressable'
|
|
16
16
|
|
|
@@ -55,6 +55,7 @@ export interface MenuItemProps {
|
|
|
55
55
|
labelStyle?: TextStyle
|
|
56
56
|
/** Accessibility label override. Defaults to label. */
|
|
57
57
|
accessibilityLabel?: string
|
|
58
|
+
accessibilityHint?: string
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
function MenuItemBase({
|
|
@@ -72,6 +73,7 @@ function MenuItemBase({
|
|
|
72
73
|
style,
|
|
73
74
|
labelStyle,
|
|
74
75
|
accessibilityLabel,
|
|
76
|
+
accessibilityHint,
|
|
75
77
|
}: MenuItemProps) {
|
|
76
78
|
const { colors } = useTheme()
|
|
77
79
|
|
|
@@ -81,7 +83,7 @@ function MenuItemBase({
|
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
const resolvedIcon: React.ReactNode = iconName
|
|
84
|
-
?
|
|
86
|
+
? <Icon name={iconName} size={22} color={iconColor ?? colors.foreground} />
|
|
85
87
|
: icon
|
|
86
88
|
|
|
87
89
|
const cardStyle: ViewStyle =
|
|
@@ -112,6 +114,7 @@ function MenuItemBase({
|
|
|
112
114
|
activateOnHover
|
|
113
115
|
accessibilityRole="button"
|
|
114
116
|
accessibilityLabel={a11yLabel}
|
|
117
|
+
accessibilityHint={accessibilityHint}
|
|
115
118
|
accessibilityState={{ disabled }}
|
|
116
119
|
>
|
|
117
120
|
{resolvedIcon ? (
|
|
@@ -83,7 +83,7 @@ export function MonthPicker({ value, onChange, minValue, maxValue, locale = 'en'
|
|
|
83
83
|
activeOpacity={0.6}
|
|
84
84
|
touchSoundDisabled={true}
|
|
85
85
|
accessibilityRole="button"
|
|
86
|
-
accessibilityLabel="
|
|
86
|
+
accessibilityLabel="Mes anterior"
|
|
87
87
|
accessibilityState={{ disabled: prevDisabled }}
|
|
88
88
|
hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
|
|
89
89
|
>
|
|
@@ -103,7 +103,7 @@ export function MonthPicker({ value, onChange, minValue, maxValue, locale = 'en'
|
|
|
103
103
|
activeOpacity={0.6}
|
|
104
104
|
touchSoundDisabled={true}
|
|
105
105
|
accessibilityRole="button"
|
|
106
|
-
accessibilityLabel="
|
|
106
|
+
accessibilityLabel="Mes siguiente"
|
|
107
107
|
accessibilityState={{ disabled: nextDisabled }}
|
|
108
108
|
hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
|
|
109
109
|
>
|
|
@@ -3,7 +3,7 @@ import { View, Text, StyleSheet, ViewStyle } from 'react-native'
|
|
|
3
3
|
import { impactLight } from '../../utils/haptics'
|
|
4
4
|
import { useTheme } from '../../theme'
|
|
5
5
|
import { s, ms, mvs } from '../../utils/scaling'
|
|
6
|
-
import {
|
|
6
|
+
import { Icon } from '../../utils/icons'
|
|
7
7
|
import { RADIUS } from '../../tokens'
|
|
8
8
|
import { PressableButton } from '../../utils/pressable'
|
|
9
9
|
|
|
@@ -19,6 +19,7 @@ export interface NumberStepperProps {
|
|
|
19
19
|
disabled?: boolean
|
|
20
20
|
style?: ViewStyle
|
|
21
21
|
accessibilityLabel?: string
|
|
22
|
+
accessibilityHint?: string
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
const sizeConfig: Record<NumberStepperSize, { button: number; icon: number; valueFontSize: number; valueLineHeight: number; valueMinWidth: number }> = {
|
|
@@ -37,6 +38,7 @@ function NumberStepperBase({
|
|
|
37
38
|
disabled = false,
|
|
38
39
|
style,
|
|
39
40
|
accessibilityLabel,
|
|
41
|
+
accessibilityHint,
|
|
40
42
|
}: NumberStepperProps) {
|
|
41
43
|
const { colors } = useTheme()
|
|
42
44
|
|
|
@@ -77,10 +79,11 @@ function NumberStepperBase({
|
|
|
77
79
|
rippleColor="transparent"
|
|
78
80
|
touchSoundDisabled
|
|
79
81
|
accessibilityRole="button"
|
|
80
|
-
accessibilityLabel={`
|
|
82
|
+
accessibilityLabel={`Disminuir, valor actual ${displayValue}`}
|
|
83
|
+
accessibilityHint={accessibilityHint}
|
|
81
84
|
accessibilityState={{ disabled: !canDecrement }}
|
|
82
85
|
>
|
|
83
|
-
|
|
86
|
+
<Icon name="minus" size={iconSize} color={canDecrement ? colors.foreground : colors.foregroundMuted} />
|
|
84
87
|
</PressableButton>
|
|
85
88
|
<Text
|
|
86
89
|
style={[
|
|
@@ -93,7 +96,7 @@ function NumberStepperBase({
|
|
|
93
96
|
},
|
|
94
97
|
]}
|
|
95
98
|
allowFontScaling={true}
|
|
96
|
-
accessibilityLabel={accessibilityLabel ?? `
|
|
99
|
+
accessibilityLabel={accessibilityLabel ?? `Cantidad: ${displayValue}`}
|
|
97
100
|
accessibilityRole="text"
|
|
98
101
|
>
|
|
99
102
|
{displayValue}
|
|
@@ -114,10 +117,11 @@ function NumberStepperBase({
|
|
|
114
117
|
rippleColor="transparent"
|
|
115
118
|
touchSoundDisabled
|
|
116
119
|
accessibilityRole="button"
|
|
117
|
-
accessibilityLabel={`
|
|
120
|
+
accessibilityLabel={`Aumentar, valor actual ${displayValue}`}
|
|
121
|
+
accessibilityHint={accessibilityHint}
|
|
118
122
|
accessibilityState={{ disabled: !canIncrement }}
|
|
119
123
|
>
|
|
120
|
-
|
|
124
|
+
<Icon name="plus" size={iconSize} color={canIncrement ? colors.foreground : colors.foregroundMuted} />
|
|
121
125
|
</PressableButton>
|
|
122
126
|
</View>
|
|
123
127
|
)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useEffect } from 'react'
|
|
2
|
-
import { View,
|
|
2
|
+
import { View, StyleSheet, ViewStyle } from 'react-native'
|
|
3
3
|
import Animated, {
|
|
4
4
|
useSharedValue,
|
|
5
5
|
useAnimatedStyle,
|
|
@@ -10,7 +10,8 @@ import { useTheme } from '../../theme'
|
|
|
10
10
|
import { s } from '../../utils/scaling'
|
|
11
11
|
import { SPRINGS } from '../../utils/animations'
|
|
12
12
|
import { selectionAsync as hapticSelection } from '../../utils/haptics'
|
|
13
|
-
import {
|
|
13
|
+
import { Icon } from '../../utils/icons'
|
|
14
|
+
import { PressableButton } from '../../utils/pressable'
|
|
14
15
|
|
|
15
16
|
export interface PagerDotsProps {
|
|
16
17
|
/** Total number of pages. */
|
|
@@ -23,7 +24,7 @@ export interface PagerDotsProps {
|
|
|
23
24
|
showControls?: boolean | { onPrevious?: () => void; onNext?: () => void }
|
|
24
25
|
/** Diameter of an inactive dot (dp). Defaults to 8. */
|
|
25
26
|
dotSize?: number
|
|
26
|
-
/** Gap between dots (dp). Defaults to
|
|
27
|
+
/** Gap between dots (dp). Defaults to 4. */
|
|
27
28
|
spacing?: number
|
|
28
29
|
/** Active dot color. Defaults to theme `primary`. */
|
|
29
30
|
activeColor?: string
|
|
@@ -53,7 +54,7 @@ function Dot({ active, size, activeColor, inactiveColor, onPress, index, total }
|
|
|
53
54
|
|
|
54
55
|
// Active dot stretches into a pill (width = 2.5×). Color crossfades on the UI thread.
|
|
55
56
|
const animatedStyle = useAnimatedStyle(() => ({
|
|
56
|
-
width: size + progress.value * size
|
|
57
|
+
width: size + progress.value * size,
|
|
57
58
|
backgroundColor: interpolateColor(progress.value, [0, 1], [inactiveColor, activeColor]),
|
|
58
59
|
}))
|
|
59
60
|
|
|
@@ -69,16 +70,17 @@ function Dot({ active, size, activeColor, inactiveColor, onPress, index, total }
|
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
return (
|
|
72
|
-
<
|
|
73
|
+
<PressableButton
|
|
73
74
|
onPress={handlePress}
|
|
74
|
-
|
|
75
|
-
touchSoundDisabled
|
|
75
|
+
rippleColor="transparent"
|
|
76
|
+
touchSoundDisabled
|
|
76
77
|
accessibilityRole="button"
|
|
77
|
-
accessibilityLabel={`
|
|
78
|
-
hitSlop={{ top:
|
|
78
|
+
accessibilityLabel={`Página ${index + 1} de ${total}${active ? ', página actual' : ''}`}
|
|
79
|
+
hitSlop={{ top: 10, bottom: 10, left: 18, right: 18 }}
|
|
80
|
+
style={styles.dotTouchable}
|
|
79
81
|
>
|
|
80
82
|
{dot}
|
|
81
|
-
</
|
|
83
|
+
</PressableButton>
|
|
82
84
|
)
|
|
83
85
|
}
|
|
84
86
|
|
|
@@ -95,7 +97,7 @@ export function PagerDots({
|
|
|
95
97
|
onDotPress,
|
|
96
98
|
showControls = false,
|
|
97
99
|
dotSize = 8,
|
|
98
|
-
spacing =
|
|
100
|
+
spacing = 4,
|
|
99
101
|
activeColor,
|
|
100
102
|
inactiveColor,
|
|
101
103
|
style,
|
|
@@ -133,21 +135,21 @@ export function PagerDots({
|
|
|
133
135
|
<View
|
|
134
136
|
style={[styles.container, { gap: s(spacing) }, style]}
|
|
135
137
|
accessibilityRole="adjustable"
|
|
136
|
-
accessibilityLabel={`
|
|
138
|
+
accessibilityLabel={`Página ${activeIndex + 1} de ${count}`}
|
|
137
139
|
>
|
|
138
140
|
{hasControls && (
|
|
139
|
-
<
|
|
141
|
+
<PressableButton
|
|
140
142
|
onPress={handlePrevious}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
touchSoundDisabled
|
|
143
|
+
enabled={canGoPrev}
|
|
144
|
+
rippleColor="transparent"
|
|
145
|
+
touchSoundDisabled
|
|
144
146
|
accessibilityRole="button"
|
|
145
|
-
accessibilityLabel="
|
|
146
|
-
hitSlop={{ top:
|
|
147
|
+
accessibilityLabel="Página anterior"
|
|
148
|
+
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
|
|
147
149
|
style={[styles.controlBtn, !canGoPrev && styles.controlBtnDisabled]}
|
|
148
150
|
>
|
|
149
|
-
|
|
150
|
-
</
|
|
151
|
+
<Icon name="chevron-left" size={s(18)} color={canGoPrev ? colors.foreground : colors.foregroundMuted} />
|
|
152
|
+
</PressableButton>
|
|
151
153
|
)}
|
|
152
154
|
<View style={[styles.dotsRow, { gap: s(spacing) }]}>
|
|
153
155
|
{Array.from({ length: count }).map((_, i) => (
|
|
@@ -164,18 +166,18 @@ export function PagerDots({
|
|
|
164
166
|
))}
|
|
165
167
|
</View>
|
|
166
168
|
{hasControls && (
|
|
167
|
-
<
|
|
169
|
+
<PressableButton
|
|
168
170
|
onPress={handleNext}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
touchSoundDisabled
|
|
171
|
+
enabled={canGoNext}
|
|
172
|
+
rippleColor="transparent"
|
|
173
|
+
touchSoundDisabled
|
|
172
174
|
accessibilityRole="button"
|
|
173
|
-
accessibilityLabel="
|
|
174
|
-
hitSlop={{ top:
|
|
175
|
+
accessibilityLabel="Página siguiente"
|
|
176
|
+
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
|
|
175
177
|
style={[styles.controlBtn, !canGoNext && styles.controlBtnDisabled]}
|
|
176
178
|
>
|
|
177
|
-
|
|
178
|
-
</
|
|
179
|
+
<Icon name="chevron-right" size={s(18)} color={canGoNext ? colors.foreground : colors.foregroundMuted} />
|
|
180
|
+
</PressableButton>
|
|
179
181
|
)}
|
|
180
182
|
</View>
|
|
181
183
|
)
|
|
@@ -193,6 +195,14 @@ const styles = StyleSheet.create({
|
|
|
193
195
|
},
|
|
194
196
|
controlBtn: {
|
|
195
197
|
padding: s(4),
|
|
198
|
+
minHeight: 44,
|
|
199
|
+
justifyContent: 'center',
|
|
200
|
+
},
|
|
201
|
+
dotTouchable: {
|
|
202
|
+
minHeight: 44,
|
|
203
|
+
paddingHorizontal: s(14),
|
|
204
|
+
justifyContent: 'center',
|
|
205
|
+
alignItems: 'center',
|
|
196
206
|
},
|
|
197
207
|
controlBtnDisabled: {
|
|
198
208
|
opacity: 0.3,
|
|
@@ -3,7 +3,7 @@ import { View, Text, StyleSheet, ViewStyle } from 'react-native'
|
|
|
3
3
|
import { useTheme } from '../../theme'
|
|
4
4
|
import { Button } from '../Button'
|
|
5
5
|
import { Badge } from '../Badge'
|
|
6
|
-
import {
|
|
6
|
+
import { Icon } from '../../utils/icons'
|
|
7
7
|
import { s, vs, ms, mvs } from '../../utils/scaling'
|
|
8
8
|
import { RADIUS, SHADOWS } from '../../tokens'
|
|
9
9
|
|
|
@@ -113,11 +113,11 @@ export function PricingCard({
|
|
|
113
113
|
<View style={styles.features}>
|
|
114
114
|
{features.map(normalize).map((f, i) => (
|
|
115
115
|
<View key={i} style={styles.featureRow}>
|
|
116
|
-
|
|
117
|
-
f.included ? 'check' : 'minus'
|
|
118
|
-
ms(16)
|
|
119
|
-
f.included ? colors.success : colors.foregroundMuted
|
|
120
|
-
|
|
116
|
+
<Icon
|
|
117
|
+
name={f.included ? 'check' : 'minus'}
|
|
118
|
+
size={ms(16)}
|
|
119
|
+
color={f.included ? colors.success : colors.foregroundMuted}
|
|
120
|
+
/>
|
|
121
121
|
<Text
|
|
122
122
|
style={[
|
|
123
123
|
styles.featureLabel,
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import {
|
|
3
|
-
import Animated from 'react-native-reanimated'
|
|
2
|
+
import { View, Text, StyleSheet, ViewStyle } from 'react-native'
|
|
4
3
|
import { EaseView } from 'react-native-ease'
|
|
5
4
|
import { selectionAsync as hapticSelection } from '../../utils/haptics'
|
|
6
5
|
import { useTheme } from '../../theme'
|
|
7
6
|
import { s, vs, ms, mvs } from '../../utils/scaling'
|
|
8
|
-
import {
|
|
9
|
-
import { COLOR_TRANSITION, SPRING_ELASTIC
|
|
7
|
+
import { PressableButton } from '../../utils/pressable'
|
|
8
|
+
import { COLOR_TRANSITION, SPRING_ELASTIC } from '../../utils/animations'
|
|
10
9
|
|
|
11
10
|
export interface RadioOption {
|
|
12
11
|
label: string
|
|
@@ -33,16 +32,9 @@ function RadioItem({
|
|
|
33
32
|
onSelect: () => void
|
|
34
33
|
}) {
|
|
35
34
|
const { colors } = useTheme()
|
|
36
|
-
const { animatedStyle: scaleStyle, onPressIn, onPressOut } = usePressScale({
|
|
37
|
-
pressScale: PRESS_SCALE.button,
|
|
38
|
-
disabled: option.disabled,
|
|
39
|
-
})
|
|
40
35
|
|
|
41
36
|
return (
|
|
42
|
-
|
|
43
|
-
// at full opacity when disabled. The whole row now dims uniformly so users
|
|
44
|
-
// get a single, consistent disabled signal across the entire item.
|
|
45
|
-
<TouchableOpacity
|
|
37
|
+
<PressableButton
|
|
46
38
|
style={[styles.row, option.disabled && styles.rowDisabled]}
|
|
47
39
|
onPress={() => {
|
|
48
40
|
if (!option.disabled) {
|
|
@@ -50,35 +42,31 @@ function RadioItem({
|
|
|
50
42
|
onSelect()
|
|
51
43
|
}
|
|
52
44
|
}}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
touchSoundDisabled={true}
|
|
57
|
-
disabled={option.disabled}
|
|
45
|
+
enabled={!option.disabled}
|
|
46
|
+
rippleColor="transparent"
|
|
47
|
+
touchSoundDisabled
|
|
58
48
|
accessibilityRole="radio"
|
|
59
49
|
accessibilityLabel={option.label}
|
|
60
50
|
accessibilityState={{ checked: selected, disabled: !!option.disabled }}
|
|
61
51
|
>
|
|
62
|
-
<
|
|
52
|
+
<EaseView
|
|
53
|
+
style={styles.radio}
|
|
54
|
+
animate={{ borderColor: selected ? colors.primary : colors.border }}
|
|
55
|
+
transition={COLOR_TRANSITION}
|
|
56
|
+
>
|
|
63
57
|
<EaseView
|
|
64
|
-
style={styles.
|
|
65
|
-
animate={{
|
|
66
|
-
transition={
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
style={[styles.dot, { backgroundColor: colors.primary }]}
|
|
70
|
-
animate={{ scale: selected ? 1 : 0, opacity: selected ? 1 : 0 }}
|
|
71
|
-
transition={SPRING_ELASTIC}
|
|
72
|
-
/>
|
|
73
|
-
</EaseView>
|
|
74
|
-
</Animated.View>
|
|
58
|
+
style={[styles.dot, { backgroundColor: colors.primary }]}
|
|
59
|
+
animate={{ scale: selected ? 1 : 0, opacity: selected ? 1 : 0 }}
|
|
60
|
+
transition={SPRING_ELASTIC}
|
|
61
|
+
/>
|
|
62
|
+
</EaseView>
|
|
75
63
|
<Text
|
|
76
64
|
style={[styles.label, { color: colors.foreground }]}
|
|
77
65
|
allowFontScaling={true}
|
|
78
66
|
>
|
|
79
67
|
{option.label}
|
|
80
68
|
</Text>
|
|
81
|
-
</
|
|
69
|
+
</PressableButton>
|
|
82
70
|
)
|
|
83
71
|
}
|
|
84
72
|
|
|
@@ -121,7 +109,6 @@ const styles = StyleSheet.create({
|
|
|
121
109
|
alignItems: 'center',
|
|
122
110
|
gap: s(12),
|
|
123
111
|
},
|
|
124
|
-
// AUDIT FIX: was opacity on the inner circle only
|
|
125
112
|
rowDisabled: {
|
|
126
113
|
opacity: 0.45,
|
|
127
114
|
},
|