@retray-dev/ui-kit 7.0.1 → 9.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 +567 -14
- package/EXAMPLES.md +21 -14
- package/README.md +14 -8
- package/dist/Accordion.js +57 -5
- package/dist/Accordion.mjs +4 -3
- package/dist/AlertBanner.js +4 -1
- package/dist/AlertBanner.mjs +3 -2
- package/dist/AppHeader.d.mts +40 -0
- package/dist/AppHeader.d.ts +40 -0
- package/dist/AppHeader.js +515 -0
- package/dist/AppHeader.mjs +10 -0
- package/dist/Avatar.js +39 -29
- package/dist/Avatar.mjs +2 -1
- package/dist/Badge.js +11 -1
- package/dist/Badge.mjs +2 -1
- package/dist/Button.d.mts +8 -3
- package/dist/Button.d.ts +8 -3
- package/dist/Button.js +126 -108
- package/dist/Button.mjs +6 -5
- package/dist/ButtonGroup.mjs +1 -0
- package/dist/Card.js +90 -70
- package/dist/Card.mjs +5 -4
- package/dist/CategoryStrip.js +79 -22
- package/dist/CategoryStrip.mjs +6 -6
- package/dist/Checkbox.js +118 -86
- package/dist/Checkbox.mjs +5 -5
- package/dist/Chip.js +113 -80
- package/dist/Chip.mjs +5 -5
- package/dist/ConfirmDialog.js +140 -110
- package/dist/ConfirmDialog.mjs +7 -6
- package/dist/CurrencyDisplay.mjs +1 -0
- package/dist/CurrencyInput.d.mts +1 -1
- package/dist/CurrencyInput.d.ts +1 -1
- package/dist/CurrencyInput.js +9 -5
- package/dist/CurrencyInput.mjs +5 -4
- package/dist/DetailRow.mjs +1 -0
- package/dist/EmptyState.js +131 -111
- package/dist/EmptyState.mjs +7 -6
- package/dist/ErrorBoundary.d.mts +42 -0
- package/dist/ErrorBoundary.d.ts +42 -0
- package/dist/ErrorBoundary.js +351 -0
- package/dist/ErrorBoundary.mjs +7 -0
- package/dist/Form.mjs +1 -0
- package/dist/HolographicCard.d.mts +55 -0
- package/dist/HolographicCard.d.ts +55 -0
- package/dist/HolographicCard.js +316 -0
- package/dist/HolographicCard.mjs +191 -0
- package/dist/IconButton.d.mts +8 -3
- package/dist/IconButton.d.ts +8 -3
- package/dist/IconButton.js +115 -98
- package/dist/IconButton.mjs +5 -4
- package/dist/ImageViewer.d.mts +23 -0
- package/dist/ImageViewer.d.ts +23 -0
- package/dist/ImageViewer.js +582 -0
- package/dist/ImageViewer.mjs +8 -0
- package/dist/Input.mjs +4 -3
- package/dist/LabelValue.mjs +1 -0
- package/dist/ListGroup.mjs +1 -0
- package/dist/ListItem.js +131 -117
- package/dist/ListItem.mjs +6 -5
- package/dist/MediaCard.js +54 -6
- package/dist/MediaCard.mjs +6 -5
- package/dist/MenuGroup.mjs +1 -0
- package/dist/MenuItem.js +91 -79
- package/dist/MenuItem.mjs +6 -5
- package/dist/MonthPicker.d.mts +10 -2
- package/dist/MonthPicker.d.ts +10 -2
- package/dist/MonthPicker.js +80 -17
- package/dist/MonthPicker.mjs +3 -2
- package/dist/PagerDots.d.mts +35 -0
- package/dist/PagerDots.d.ts +35 -0
- package/dist/PagerDots.js +392 -0
- package/dist/PagerDots.mjs +7 -0
- package/dist/Pressable.d.mts +5 -5
- package/dist/Pressable.d.ts +5 -5
- package/dist/Pressable.js +97 -86
- package/dist/Pressable.mjs +5 -4
- package/dist/PricingCard.d.mts +50 -0
- package/dist/PricingCard.d.ts +50 -0
- package/dist/PricingCard.js +636 -0
- package/dist/PricingCard.mjs +11 -0
- package/dist/Progress.mjs +3 -2
- package/dist/RadioGroup.js +81 -30
- package/dist/RadioGroup.mjs +5 -5
- package/dist/RetrayProvider.d.mts +2 -0
- package/dist/RetrayProvider.d.ts +2 -0
- package/dist/RetrayProvider.js +214 -0
- package/dist/RetrayProvider.mjs +5 -0
- package/dist/Select.js +51 -4
- package/dist/Select.mjs +5 -4
- package/dist/SelectableGrid.d.mts +44 -0
- package/dist/SelectableGrid.d.ts +44 -0
- package/dist/SelectableGrid.js +448 -0
- package/dist/SelectableGrid.mjs +9 -0
- package/dist/Separator.mjs +1 -0
- package/dist/Sheet.d.mts +13 -1
- package/dist/Sheet.d.ts +13 -1
- package/dist/Sheet.js +115 -5
- package/dist/Sheet.mjs +4 -2
- package/dist/Skeleton.d.mts +50 -0
- package/dist/Skeleton.d.ts +50 -0
- package/dist/Skeleton.js +61 -0
- package/dist/Skeleton.mjs +4 -2
- package/dist/Slider.js +51 -4
- package/dist/Slider.mjs +3 -2
- package/dist/Spinner.js +28 -7
- package/dist/Spinner.mjs +2 -1
- package/dist/Switch.js +98 -48
- package/dist/Switch.mjs +4 -3
- package/dist/TabBar.d.mts +42 -0
- package/dist/TabBar.d.ts +42 -0
- package/dist/TabBar.js +361 -0
- package/dist/TabBar.mjs +6 -0
- package/dist/Tabs.js +92 -62
- package/dist/Tabs.mjs +5 -4
- package/dist/Text.js +16 -0
- package/dist/Text.mjs +2 -1
- package/dist/Textarea.mjs +4 -3
- package/dist/Toast.d.mts +7 -7
- package/dist/Toast.d.ts +7 -7
- package/dist/Toast.mjs +1 -0
- package/dist/Toggle.d.mts +6 -3
- package/dist/Toggle.d.ts +6 -3
- package/dist/Toggle.js +135 -120
- package/dist/Toggle.mjs +5 -5
- package/dist/VirtualList.mjs +1 -0
- package/dist/{chunk-7H2OR44A.mjs → chunk-26BCI223.mjs} +1 -1
- package/dist/{chunk-CRYBX2CM.mjs → chunk-2TFTAWVJ.mjs} +44 -59
- package/dist/chunk-3DKJ2GIC.mjs +30 -0
- package/dist/{chunk-KWCPOM6W.mjs → chunk-3U4SSNWP.mjs} +32 -48
- package/dist/chunk-4I7D47FH.mjs +139 -0
- package/dist/chunk-4K625MVM.mjs +142 -0
- package/dist/{chunk-MN7OG7IY.mjs → chunk-6OAZJ577.mjs} +6 -4
- package/dist/{chunk-L7E7TVEZ.mjs → chunk-756RAKE4.mjs} +2 -2
- package/dist/{chunk-HSPSMN6U.mjs → chunk-7QHVVCB3.mjs} +2 -2
- package/dist/{chunk-URLL5JBR.mjs → chunk-A3A6KNQN.mjs} +3 -3
- package/dist/chunk-AJ7ZDNBT.mjs +120 -0
- package/dist/{chunk-FTLJOUOQ.mjs → chunk-AV4EMIRH.mjs} +25 -28
- package/dist/chunk-AZJF2BLK.mjs +115 -0
- package/dist/chunk-BNP626TY.mjs +159 -0
- package/dist/{chunk-5IKW3VNC.mjs → chunk-DVK4G2GT.mjs} +17 -1
- package/dist/{chunk-6LQYY7HC.mjs → chunk-EH745HE5.mjs} +2 -2
- package/dist/chunk-EJ7ZPXOH.mjs +163 -0
- package/dist/{chunk-RKLHUDZS.mjs → chunk-GD6KXMG5.mjs} +29 -15
- package/dist/{chunk-RR2VQLKE.mjs → chunk-GQYFLP3D.mjs} +14 -17
- package/dist/{chunk-Y6MXOREN.mjs → chunk-ID72TK46.mjs} +8 -17
- package/dist/{chunk-NQGVLMWG.mjs → chunk-JMOZEC77.mjs} +1 -1
- package/dist/{chunk-GCWOGZYL.mjs → chunk-JT7HKXRB.mjs} +39 -29
- package/dist/{chunk-LWG526VX.mjs → chunk-KIHCWCWL.mjs} +47 -62
- package/dist/chunk-LXJIIOYQ.mjs +104 -0
- package/dist/{chunk-SBZYEV4S.mjs → chunk-M6ZXVBTK.mjs} +5 -2
- package/dist/{chunk-XDMN67KV.mjs → chunk-MAC465BB.mjs} +10 -8
- package/dist/chunk-MBMXYJJV.mjs +36 -0
- package/dist/chunk-MLF3EZFW.mjs +119 -0
- package/dist/chunk-NA7PARID.mjs +147 -0
- package/dist/{chunk-QXGYKWI7.mjs → chunk-O3HA6TYM.mjs} +9 -4
- package/dist/{chunk-63357L2X.mjs → chunk-OB4JUQ3O.mjs} +1 -1
- package/dist/{chunk-AU2VDY4P.mjs → chunk-PFZTM6D5.mjs} +52 -4
- package/dist/chunk-QKH5ZOD5.mjs +97 -0
- package/dist/{chunk-KZJRQOIU.mjs → chunk-TERDKCLE.mjs} +11 -1
- package/dist/{chunk-U4N7WF4Z.mjs → chunk-UREA2GYY.mjs} +28 -23
- package/dist/{chunk-TAJ2PQ2O.mjs → chunk-VGTDN7SW.mjs} +7 -6
- package/dist/{chunk-URDE3EUU.mjs → chunk-VQ57HWPL.mjs} +27 -15
- package/dist/chunk-WBOOUHSS.mjs +62 -0
- package/dist/{chunk-GNGLDL6Z.mjs → chunk-WJLKJMKR.mjs} +18 -0
- package/dist/{chunk-YZJAFS4P.mjs → chunk-X4G6APW6.mjs} +22 -19
- package/dist/chunk-Y6FXYEAI.mjs +8 -0
- package/dist/chunk-YFZ3ELX5.mjs +16 -0
- package/dist/{chunk-QCNARS3X.mjs → chunk-YNROWHQJ.mjs} +1 -1
- package/dist/chunk-Z4BVUWW6.mjs +196 -0
- package/dist/{chunk-GPOUINK5.mjs → chunk-ZJKGQMYH.mjs} +10 -27
- package/dist/index-wt-orHUi.d.mts +85 -0
- package/dist/index-wt-orHUi.d.ts +85 -0
- package/dist/index.d.mts +59 -51
- package/dist/index.d.ts +59 -51
- package/dist/index.js +1940 -744
- package/dist/index.mjs +49 -39
- package/package.json +35 -5
- package/src/components/Accordion/Accordion.tsx +12 -1
- package/src/components/AlertBanner/AlertBanner.tsx +5 -0
- package/src/components/AppHeader/AppHeader.tsx +172 -0
- package/src/components/AppHeader/index.ts +1 -0
- package/src/components/Avatar/Avatar.tsx +10 -2
- package/src/components/Badge/Badge.tsx +8 -1
- package/src/components/Button/Button.tsx +20 -27
- package/src/components/Card/Card.tsx +12 -23
- package/src/components/CategoryStrip/CategoryStrip.tsx +17 -21
- package/src/components/Checkbox/Checkbox.tsx +26 -40
- package/src/components/Chip/Chip.tsx +24 -33
- package/src/components/CurrencyInput/CurrencyInput.tsx +10 -8
- package/src/components/EmptyState/EmptyState.tsx +2 -1
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +153 -0
- package/src/components/ErrorBoundary/index.ts +1 -0
- package/src/components/HolographicCard/HolographicCard.tsx +315 -0
- package/src/components/HolographicCard/index.ts +1 -0
- package/src/components/IconButton/IconButton.tsx +19 -27
- package/src/components/ImageViewer/ImageViewer.tsx +290 -0
- package/src/components/ImageViewer/index.ts +1 -0
- package/src/components/ListItem/ListItem.tsx +70 -67
- package/src/components/MediaCard/MediaCard.tsx +8 -2
- package/src/components/MenuItem/MenuItem.tsx +10 -25
- package/src/components/MonthPicker/MonthPicker.tsx +39 -13
- package/src/components/MonthPicker/index.ts +1 -1
- package/src/components/PagerDots/PagerDots.tsx +200 -0
- package/src/components/PagerDots/index.ts +1 -0
- package/src/components/Pressable/Pressable.tsx +19 -35
- package/src/components/PricingCard/PricingCard.tsx +220 -0
- package/src/components/PricingCard/index.ts +1 -0
- package/src/components/RadioGroup/RadioGroup.tsx +14 -27
- package/src/components/RetrayProvider/RetrayProvider.tsx +59 -0
- package/src/components/RetrayProvider/index.ts +1 -0
- package/src/components/SelectableGrid/SelectableGrid.tsx +205 -0
- package/src/components/SelectableGrid/index.ts +1 -0
- package/src/components/Sheet/Sheet.tsx +65 -1
- package/src/components/Skeleton/Skeleton.tsx +142 -1
- package/src/components/Spinner/Spinner.tsx +17 -2
- package/src/components/Switch/Switch.tsx +30 -58
- package/src/components/TabBar/TabBar.tsx +169 -0
- package/src/components/TabBar/index.ts +1 -0
- package/src/components/Tabs/Tabs.tsx +23 -26
- package/src/components/Text/Text.tsx +2 -0
- package/src/components/Toggle/Toggle.tsx +35 -51
- package/src/fonts.ts +4 -1
- package/src/index.ts +23 -2
- package/src/utils/animations.ts +29 -1
- package/src/utils/fontGuard.ts +34 -0
- package/src/utils/haptics.ts +211 -9
- package/src/utils/pressable.ts +66 -0
- package/dist/chunk-76PFOSM2.mjs +0 -41
- package/dist/chunk-DITNP6PL.mjs +0 -106
- package/dist/chunk-JBLL7U3U.mjs +0 -64
- package/dist/chunk-LG4DO3DK.mjs +0 -174
- package/dist/chunk-RMMK64W5.mjs +0 -54
- package/dist/chunk-RTC3CFXF.mjs +0 -29
package/src/utils/haptics.ts
CHANGED
|
@@ -1,38 +1,240 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Haptic feedback utilities using expo-haptics.
|
|
3
|
+
*
|
|
4
|
+
* Uses expo-haptics which works with both Expo Go and development builds.
|
|
5
|
+
* react-native-pulsar support is optional for dev builds with native modules.
|
|
6
|
+
*
|
|
7
|
+
* All functions are web-safe (no-op on web platform).
|
|
8
|
+
*/
|
|
9
|
+
import { Platform, NativeModules } from 'react-native'
|
|
2
10
|
|
|
11
|
+
// ─── expo-haptics (primary) ───────────────────────────────────────────────────
|
|
3
12
|
type HapticsModule = typeof import('expo-haptics')
|
|
4
|
-
|
|
5
13
|
let _haptics: HapticsModule | null = null
|
|
14
|
+
let _hapticsLoaded = false
|
|
6
15
|
|
|
7
16
|
async function getHaptics(): Promise<HapticsModule | null> {
|
|
8
17
|
if (Platform.OS === 'web') return null
|
|
9
|
-
if (!
|
|
10
|
-
|
|
18
|
+
if (!_hapticsLoaded) {
|
|
19
|
+
_hapticsLoaded = true
|
|
20
|
+
try {
|
|
21
|
+
_haptics = await import('expo-haptics')
|
|
22
|
+
} catch {
|
|
23
|
+
_haptics = null
|
|
24
|
+
}
|
|
11
25
|
}
|
|
12
26
|
return _haptics
|
|
13
27
|
}
|
|
14
28
|
|
|
29
|
+
// ─── Pulsar (optional for dev builds) ─────────────────────────────────────────
|
|
30
|
+
// Only available in development builds with native modules installed.
|
|
31
|
+
// Gracefully falls back to expo-haptics if not available.
|
|
32
|
+
type PulsarModule = typeof import('react-native-pulsar')
|
|
33
|
+
let _pulsar: PulsarModule | null = null
|
|
34
|
+
let _pulsarChecked = false
|
|
35
|
+
let _pulsarAvailable = false
|
|
36
|
+
|
|
37
|
+
function isPulsarNativeRegistered(): boolean {
|
|
38
|
+
// react-native-pulsar's NativeRNPulsar.ts calls
|
|
39
|
+
// TurboModuleRegistry.getEnforcing('RNPulsar') at module-eval time. When the
|
|
40
|
+
// native binary is absent (e.g. Expo Go), requiring the package throws during
|
|
41
|
+
// Metro module eval — and that throw is surfaced by RN's global error handler
|
|
42
|
+
// (red screen) even when wrapped in try/catch, because guardedLoadModule
|
|
43
|
+
// reports it before rethrowing. So we must confirm the native module is
|
|
44
|
+
// actually registered BEFORE requiring the JS wrapper.
|
|
45
|
+
//
|
|
46
|
+
// TurboModuleRegistry.get() returns a truthy proxy even for unregistered
|
|
47
|
+
// modules (false positive), so it can't be trusted. Instead we probe the low
|
|
48
|
+
// level: the new-arch turbo proxy returns null for unregistered names, and
|
|
49
|
+
// the old-arch NativeModules map omits them. A direct lookup throws nothing —
|
|
50
|
+
// unlike a top-level import — so any failure is caught safely here.
|
|
51
|
+
try {
|
|
52
|
+
const g = globalThis as {
|
|
53
|
+
__turboModuleProxy?: (name: string) => unknown
|
|
54
|
+
}
|
|
55
|
+
if (typeof g.__turboModuleProxy === 'function') {
|
|
56
|
+
return g.__turboModuleProxy('RNPulsar') != null
|
|
57
|
+
}
|
|
58
|
+
return NativeModules?.RNPulsar != null
|
|
59
|
+
} catch {
|
|
60
|
+
return false
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function getPulsar(): PulsarModule | null {
|
|
65
|
+
if (Platform.OS === 'web') return null
|
|
66
|
+
if (!_pulsarChecked) {
|
|
67
|
+
_pulsarChecked = true
|
|
68
|
+
try {
|
|
69
|
+
// Only require the package when its native module is registered —
|
|
70
|
+
// otherwise the require would red-screen the app (see above).
|
|
71
|
+
if (isPulsarNativeRegistered()) {
|
|
72
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
73
|
+
_pulsar = require('react-native-pulsar') as PulsarModule
|
|
74
|
+
_pulsarAvailable = true
|
|
75
|
+
}
|
|
76
|
+
} catch {
|
|
77
|
+
_pulsar = null
|
|
78
|
+
_pulsarAvailable = false
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return _pulsarAvailable ? _pulsar : null
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// ─── Public API ───────────────────────────────────────────────────────────────
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Light selection feedback — checkboxes, switches, toggles, pickers.
|
|
88
|
+
*/
|
|
15
89
|
export function selectionAsync(): void {
|
|
16
90
|
if (Platform.OS === 'web') return
|
|
17
|
-
|
|
91
|
+
// Try expo-haptics first (always available in Expo Go)
|
|
92
|
+
getHaptics().then((h) => {
|
|
93
|
+
if (h) {
|
|
94
|
+
h.selectionAsync()
|
|
95
|
+
} else {
|
|
96
|
+
// Fallback to Pulsar if available
|
|
97
|
+
getPulsar()?.Presets.System.selection()
|
|
98
|
+
}
|
|
99
|
+
})
|
|
18
100
|
}
|
|
19
101
|
|
|
102
|
+
/**
|
|
103
|
+
* Light impact — cards, surfaces, light interactions.
|
|
104
|
+
*/
|
|
20
105
|
export function impactLight(): void {
|
|
21
106
|
if (Platform.OS === 'web') return
|
|
22
|
-
getHaptics().then(h =>
|
|
107
|
+
getHaptics().then((h) => {
|
|
108
|
+
if (h) {
|
|
109
|
+
h.impactAsync(h.ImpactFeedbackStyle.Light)
|
|
110
|
+
} else {
|
|
111
|
+
getPulsar()?.Presets.System.impactLight()
|
|
112
|
+
}
|
|
113
|
+
})
|
|
23
114
|
}
|
|
24
115
|
|
|
116
|
+
/**
|
|
117
|
+
* Medium impact — buttons, primary actions.
|
|
118
|
+
*/
|
|
25
119
|
export function impactMedium(): void {
|
|
26
120
|
if (Platform.OS === 'web') return
|
|
27
|
-
getHaptics().then(h =>
|
|
121
|
+
getHaptics().then((h) => {
|
|
122
|
+
if (h) {
|
|
123
|
+
h.impactAsync(h.ImpactFeedbackStyle.Medium)
|
|
124
|
+
} else {
|
|
125
|
+
getPulsar()?.Presets.System.impactMedium()
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Heavy impact — confirmations, important actions.
|
|
132
|
+
*/
|
|
133
|
+
export function impactHeavy(): void {
|
|
134
|
+
if (Platform.OS === 'web') return
|
|
135
|
+
getHaptics().then((h) => {
|
|
136
|
+
if (h) {
|
|
137
|
+
h.impactAsync(h.ImpactFeedbackStyle.Heavy)
|
|
138
|
+
} else {
|
|
139
|
+
getPulsar()?.Presets.System.impactHeavy()
|
|
140
|
+
}
|
|
141
|
+
})
|
|
28
142
|
}
|
|
29
143
|
|
|
144
|
+
/**
|
|
145
|
+
* Success notification — confirmations, completed actions.
|
|
146
|
+
*/
|
|
30
147
|
export function notificationSuccess(): void {
|
|
31
148
|
if (Platform.OS === 'web') return
|
|
32
|
-
getHaptics().then(h =>
|
|
149
|
+
getHaptics().then((h) => {
|
|
150
|
+
if (h) {
|
|
151
|
+
h.notificationAsync(h.NotificationFeedbackType.Success)
|
|
152
|
+
} else {
|
|
153
|
+
getPulsar()?.Presets.System.notificationSuccess()
|
|
154
|
+
}
|
|
155
|
+
})
|
|
33
156
|
}
|
|
34
157
|
|
|
158
|
+
/**
|
|
159
|
+
* Error notification — failed actions, errors.
|
|
160
|
+
*/
|
|
35
161
|
export function notificationError(): void {
|
|
36
162
|
if (Platform.OS === 'web') return
|
|
37
|
-
getHaptics().then(h =>
|
|
163
|
+
getHaptics().then((h) => {
|
|
164
|
+
if (h) {
|
|
165
|
+
h.notificationAsync(h.NotificationFeedbackType.Error)
|
|
166
|
+
} else {
|
|
167
|
+
getPulsar()?.Presets.System.notificationError()
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Warning notification — caution states.
|
|
174
|
+
*/
|
|
175
|
+
export function notificationWarning(): void {
|
|
176
|
+
if (Platform.OS === 'web') return
|
|
177
|
+
getHaptics().then((h) => {
|
|
178
|
+
if (h) {
|
|
179
|
+
h.notificationAsync(h.NotificationFeedbackType.Warning)
|
|
180
|
+
} else {
|
|
181
|
+
getPulsar()?.Presets.System.notificationWarning()
|
|
182
|
+
}
|
|
183
|
+
})
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// ─── Rich Pulsar Presets (enhanced feedback) ──────────────────────────────────
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Rich haptic presets from Pulsar — enhanced feedback for special interactions.
|
|
190
|
+
* Falls back to basic expo-haptics on Expo Go or unsupported devices.
|
|
191
|
+
*/
|
|
192
|
+
export const richHaptics = {
|
|
193
|
+
/** Hammer strike — strong confirmation feedback. */
|
|
194
|
+
hammer: (): void => {
|
|
195
|
+
if (Platform.OS === 'web') return
|
|
196
|
+
const p = getPulsar()
|
|
197
|
+
if (p) p.Presets.hammer()
|
|
198
|
+
else impactHeavy()
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
/** Pulse — rhythmic feedback for toggles or state changes. */
|
|
202
|
+
pulse: (): void => {
|
|
203
|
+
if (Platform.OS === 'web') return
|
|
204
|
+
const p = getPulsar()
|
|
205
|
+
if (p) p.Presets.pulse()
|
|
206
|
+
else selectionAsync()
|
|
207
|
+
},
|
|
208
|
+
|
|
209
|
+
/** Buzz — continuous vibration for attention. */
|
|
210
|
+
buzz: (): void => {
|
|
211
|
+
if (Platform.OS === 'web') return
|
|
212
|
+
const p = getPulsar()
|
|
213
|
+
if (p) p.Presets.buzz()
|
|
214
|
+
else impactMedium()
|
|
215
|
+
},
|
|
216
|
+
|
|
217
|
+
/** Flick — crisp click feedback. */
|
|
218
|
+
flick: (): void => {
|
|
219
|
+
if (Platform.OS === 'web') return
|
|
220
|
+
const p = getPulsar()
|
|
221
|
+
if (p) p.Presets.flick()
|
|
222
|
+
else selectionAsync()
|
|
223
|
+
},
|
|
224
|
+
|
|
225
|
+
/** Soft — gentle, subtle feedback. */
|
|
226
|
+
soft: (): void => {
|
|
227
|
+
if (Platform.OS === 'web') return
|
|
228
|
+
const p = getPulsar()
|
|
229
|
+
if (p) p.Presets.System.impactSoft()
|
|
230
|
+
else impactLight()
|
|
231
|
+
},
|
|
232
|
+
|
|
233
|
+
/** Rigid — firm, solid feedback. */
|
|
234
|
+
rigid: (): void => {
|
|
235
|
+
if (Platform.OS === 'web') return
|
|
236
|
+
const p = getPulsar()
|
|
237
|
+
if (p) p.Presets.System.impactRigid()
|
|
238
|
+
else impactMedium()
|
|
239
|
+
},
|
|
38
240
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pressto-based pressable primitives for the UI Kit.
|
|
3
|
+
*
|
|
4
|
+
* Pressto provides main-thread pressable animations built on react-native-gesture-handler
|
|
5
|
+
* and react-native-reanimated. Animations run at 60fps with zero JS overhead.
|
|
6
|
+
*
|
|
7
|
+
* These custom pressables match the UI Kit's design language:
|
|
8
|
+
* - Button: 0.95 scale (tight, premium press)
|
|
9
|
+
* - Card: 0.98 scale (subtle surface response)
|
|
10
|
+
* - Row: 0.97 scale (list items, menu items)
|
|
11
|
+
* - Chip: 0.94 scale (compact, snappy)
|
|
12
|
+
*/
|
|
13
|
+
import { createAnimatedPressable } from 'pressto'
|
|
14
|
+
import { PRESS_SCALE } from './animations'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Button pressable — tight 0.95 scale for primary actions.
|
|
18
|
+
* Use for: Button, IconButton, Toggle, Checkbox triggers.
|
|
19
|
+
*/
|
|
20
|
+
export const PressableButton = createAnimatedPressable((progress) => {
|
|
21
|
+
'worklet'
|
|
22
|
+
const scale = 1 - (1 - PRESS_SCALE.button) * progress
|
|
23
|
+
return { transform: [{ scale }] }
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Card pressable — subtle 0.98 scale for surfaces.
|
|
28
|
+
* Use for: Card (interactive), MediaCard, Pressable component.
|
|
29
|
+
*/
|
|
30
|
+
export const PressableCard = createAnimatedPressable((progress) => {
|
|
31
|
+
'worklet'
|
|
32
|
+
const scale = 1 - (1 - PRESS_SCALE.card) * progress
|
|
33
|
+
return { transform: [{ scale }] }
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Row pressable — balanced 0.97 scale for list interactions.
|
|
38
|
+
* Use for: ListItem, MenuItem, Accordion triggers.
|
|
39
|
+
*/
|
|
40
|
+
export const PressableRow = createAnimatedPressable((progress) => {
|
|
41
|
+
'worklet'
|
|
42
|
+
const scale = 1 - (1 - PRESS_SCALE.row) * progress
|
|
43
|
+
return { transform: [{ scale }] }
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Chip pressable — snappy 0.94 scale for compact elements.
|
|
48
|
+
* Use for: Chip, small toggleable items.
|
|
49
|
+
*/
|
|
50
|
+
export const PressableChip = createAnimatedPressable((progress) => {
|
|
51
|
+
'worklet'
|
|
52
|
+
const scale = 1 - (1 - PRESS_SCALE.chip) * progress
|
|
53
|
+
return { transform: [{ scale }] }
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Tab pressable — same as button for tab triggers.
|
|
58
|
+
*/
|
|
59
|
+
export const PressableTab = createAnimatedPressable((progress) => {
|
|
60
|
+
'worklet'
|
|
61
|
+
const scale = 1 - (1 - PRESS_SCALE.button) * progress
|
|
62
|
+
return { transform: [{ scale }] }
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
// Re-export pressto components for direct use
|
|
66
|
+
export { PressableScale, PressableOpacity, PressablesConfig } from 'pressto'
|
package/dist/chunk-76PFOSM2.mjs
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { useTheme } from './chunk-SOYNZDVY.mjs';
|
|
2
|
-
import { ms, mvs, vs } from './chunk-2CE3TQVY.mjs';
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import { StyleSheet, View, ActivityIndicator, Text } from 'react-native';
|
|
5
|
-
|
|
6
|
-
var sizeMap = {
|
|
7
|
-
sm: "small",
|
|
8
|
-
md: "small",
|
|
9
|
-
lg: "large"
|
|
10
|
-
};
|
|
11
|
-
var labelFontSize = {
|
|
12
|
-
sm: ms(11),
|
|
13
|
-
md: ms(13),
|
|
14
|
-
lg: ms(14)
|
|
15
|
-
};
|
|
16
|
-
function Spinner({ size = "md", color, label, ...props }) {
|
|
17
|
-
const { colors } = useTheme();
|
|
18
|
-
if (label) {
|
|
19
|
-
return /* @__PURE__ */ React.createElement(View, { style: styles.wrapper }, /* @__PURE__ */ React.createElement(ActivityIndicator, { size: sizeMap[size], color: color ?? colors.primary, ...props }), /* @__PURE__ */ React.createElement(
|
|
20
|
-
Text,
|
|
21
|
-
{
|
|
22
|
-
style: [styles.label, { color: colors.foregroundMuted, fontSize: labelFontSize[size] }],
|
|
23
|
-
allowFontScaling: true
|
|
24
|
-
},
|
|
25
|
-
label
|
|
26
|
-
));
|
|
27
|
-
}
|
|
28
|
-
return /* @__PURE__ */ React.createElement(ActivityIndicator, { size: sizeMap[size], color: color ?? colors.primary, ...props });
|
|
29
|
-
}
|
|
30
|
-
var styles = StyleSheet.create({
|
|
31
|
-
wrapper: {
|
|
32
|
-
alignItems: "center",
|
|
33
|
-
gap: vs(6)
|
|
34
|
-
},
|
|
35
|
-
label: {
|
|
36
|
-
fontFamily: "Sohne-Regular",
|
|
37
|
-
lineHeight: mvs(18)
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
export { Spinner };
|
package/dist/chunk-DITNP6PL.mjs
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { selectionAsync } from './chunk-RTC3CFXF.mjs';
|
|
2
|
-
import { SPRINGS, EASINGS, TIMINGS } from './chunk-5IKW3VNC.mjs';
|
|
3
|
-
import { useTheme } from './chunk-SOYNZDVY.mjs';
|
|
4
|
-
import { s } from './chunk-2CE3TQVY.mjs';
|
|
5
|
-
import React, { useEffect } from 'react';
|
|
6
|
-
import { StyleSheet, View, TouchableOpacity } from 'react-native';
|
|
7
|
-
import Animated, { useSharedValue, withSpring, useAnimatedStyle, interpolateColor, withTiming } from 'react-native-reanimated';
|
|
8
|
-
import { Feather } from '@expo/vector-icons';
|
|
9
|
-
|
|
10
|
-
var TRACK_WIDTH = s(52);
|
|
11
|
-
var TRACK_HEIGHT = s(30);
|
|
12
|
-
var THUMB_SIZE = s(24);
|
|
13
|
-
var THUMB_OFFSET = s(3);
|
|
14
|
-
var THUMB_TRAVEL = TRACK_WIDTH - THUMB_SIZE - THUMB_OFFSET * 2;
|
|
15
|
-
var ICON_SIZE = s(13);
|
|
16
|
-
function Switch({ checked = false, onCheckedChange, disabled, style, accessibilityLabel }) {
|
|
17
|
-
const { colors } = useTheme();
|
|
18
|
-
const progress = useSharedValue(checked ? 1 : 0);
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
progress.value = withSpring(checked ? 1 : 0, SPRINGS.elastic);
|
|
21
|
-
}, [checked, progress]);
|
|
22
|
-
const thumbStyle = useAnimatedStyle(() => ({
|
|
23
|
-
transform: [{ translateX: progress.value * THUMB_TRAVEL }]
|
|
24
|
-
}));
|
|
25
|
-
const trackStyle = useAnimatedStyle(() => ({
|
|
26
|
-
backgroundColor: interpolateColor(
|
|
27
|
-
progress.value,
|
|
28
|
-
[0, 1],
|
|
29
|
-
[colors.surfaceStrong, colors.primary]
|
|
30
|
-
)
|
|
31
|
-
}));
|
|
32
|
-
const trackBorderStyle = useAnimatedStyle(() => ({
|
|
33
|
-
borderWidth: 1.5,
|
|
34
|
-
borderColor: interpolateColor(
|
|
35
|
-
progress.value,
|
|
36
|
-
[0, 1],
|
|
37
|
-
[colors.border, "transparent"]
|
|
38
|
-
)
|
|
39
|
-
}));
|
|
40
|
-
const checkIconStyle = useAnimatedStyle(() => ({
|
|
41
|
-
opacity: withTiming(checked ? 1 : 0, { duration: TIMINGS.state.duration, easing: EASINGS.standard })
|
|
42
|
-
}));
|
|
43
|
-
const crossIconStyle = useAnimatedStyle(() => ({
|
|
44
|
-
opacity: withTiming(checked ? 0 : 1, { duration: TIMINGS.state.duration, easing: EASINGS.standard })
|
|
45
|
-
}));
|
|
46
|
-
return /* @__PURE__ */ React.createElement(View, { style: [{ opacity: disabled ? 0.45 : 1, alignSelf: "flex-start" }, style] }, /* @__PURE__ */ React.createElement(
|
|
47
|
-
TouchableOpacity,
|
|
48
|
-
{
|
|
49
|
-
onPress: () => {
|
|
50
|
-
selectionAsync();
|
|
51
|
-
onCheckedChange?.(!checked);
|
|
52
|
-
},
|
|
53
|
-
disabled,
|
|
54
|
-
activeOpacity: 0.8,
|
|
55
|
-
touchSoundDisabled: true,
|
|
56
|
-
accessibilityRole: "switch",
|
|
57
|
-
accessibilityLabel,
|
|
58
|
-
accessibilityState: { checked, disabled: !!disabled },
|
|
59
|
-
style: styles.touchable
|
|
60
|
-
},
|
|
61
|
-
/* @__PURE__ */ React.createElement(Animated.View, { style: [styles.track, trackStyle] }, /* @__PURE__ */ React.createElement(Animated.View, { style: [styles.trackBorder, trackBorderStyle], pointerEvents: "none" }), /* @__PURE__ */ React.createElement(
|
|
62
|
-
Animated.View,
|
|
63
|
-
{
|
|
64
|
-
style: [styles.thumb, { backgroundColor: colors.primaryForeground }, thumbStyle]
|
|
65
|
-
},
|
|
66
|
-
/* @__PURE__ */ React.createElement(Animated.View, { style: [styles.iconWrapper, checkIconStyle] }, /* @__PURE__ */ React.createElement(Feather, { name: "check", size: ICON_SIZE, color: colors.primary })),
|
|
67
|
-
/* @__PURE__ */ React.createElement(Animated.View, { style: [styles.iconWrapper, crossIconStyle] }, /* @__PURE__ */ React.createElement(Feather, { name: "x", size: ICON_SIZE, color: colors.foregroundMuted }))
|
|
68
|
-
))
|
|
69
|
-
));
|
|
70
|
-
}
|
|
71
|
-
var styles = StyleSheet.create({
|
|
72
|
-
touchable: {
|
|
73
|
-
alignSelf: "flex-start"
|
|
74
|
-
},
|
|
75
|
-
track: {
|
|
76
|
-
width: TRACK_WIDTH,
|
|
77
|
-
height: TRACK_HEIGHT,
|
|
78
|
-
borderRadius: TRACK_HEIGHT / 2
|
|
79
|
-
},
|
|
80
|
-
trackBorder: {
|
|
81
|
-
...StyleSheet.absoluteFillObject,
|
|
82
|
-
borderRadius: TRACK_HEIGHT / 2
|
|
83
|
-
},
|
|
84
|
-
thumb: {
|
|
85
|
-
position: "absolute",
|
|
86
|
-
top: THUMB_OFFSET,
|
|
87
|
-
left: THUMB_OFFSET,
|
|
88
|
-
width: THUMB_SIZE,
|
|
89
|
-
height: THUMB_SIZE,
|
|
90
|
-
borderRadius: THUMB_SIZE / 2,
|
|
91
|
-
shadowColor: "#000",
|
|
92
|
-
shadowOffset: { width: 0, height: 1 },
|
|
93
|
-
shadowOpacity: 0.15,
|
|
94
|
-
shadowRadius: 2,
|
|
95
|
-
elevation: 2,
|
|
96
|
-
alignItems: "center",
|
|
97
|
-
justifyContent: "center"
|
|
98
|
-
},
|
|
99
|
-
iconWrapper: {
|
|
100
|
-
position: "absolute",
|
|
101
|
-
alignItems: "center",
|
|
102
|
-
justifyContent: "center"
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
export { Switch };
|
package/dist/chunk-JBLL7U3U.mjs
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { TIMINGS } from './chunk-5IKW3VNC.mjs';
|
|
2
|
-
import { useTheme } from './chunk-SOYNZDVY.mjs';
|
|
3
|
-
import { s } from './chunk-2CE3TQVY.mjs';
|
|
4
|
-
import React, { useState, useEffect } from 'react';
|
|
5
|
-
import { StyleSheet, View } from 'react-native';
|
|
6
|
-
import Animated, { useSharedValue, withRepeat, withTiming, Easing, useAnimatedStyle } from 'react-native-reanimated';
|
|
7
|
-
import { LinearGradient } from 'expo-linear-gradient';
|
|
8
|
-
|
|
9
|
-
function Skeleton({
|
|
10
|
-
width = "100%",
|
|
11
|
-
height = 16,
|
|
12
|
-
borderRadius = 6,
|
|
13
|
-
preset = "base",
|
|
14
|
-
diameter = 40,
|
|
15
|
-
style
|
|
16
|
-
}) {
|
|
17
|
-
const { colors, colorScheme } = useTheme();
|
|
18
|
-
const shimmer = useSharedValue(0);
|
|
19
|
-
const [containerWidth, setContainerWidth] = useState(300);
|
|
20
|
-
const shimmerHighlight = colorScheme === "dark" ? "rgba(255,255,255,0.08)" : "rgba(255,255,255,0.7)";
|
|
21
|
-
useEffect(() => {
|
|
22
|
-
shimmer.value = withRepeat(
|
|
23
|
-
withTiming(1, { duration: TIMINGS.shimmer.duration, easing: Easing.linear }),
|
|
24
|
-
-1,
|
|
25
|
-
false
|
|
26
|
-
);
|
|
27
|
-
}, [shimmer]);
|
|
28
|
-
const shimmerStyle = useAnimatedStyle(() => ({
|
|
29
|
-
transform: [{ translateX: -containerWidth + shimmer.value * (containerWidth * 2) }]
|
|
30
|
-
}));
|
|
31
|
-
const resolvedWidth = preset === "circle" ? s(diameter) : preset === "text" ? "60%" : width;
|
|
32
|
-
const resolvedHeight = preset === "circle" ? s(diameter) : preset === "text" ? 14 : height;
|
|
33
|
-
const resolvedRadius = preset === "circle" ? 9999 : preset === "text" ? 4 : borderRadius;
|
|
34
|
-
return /* @__PURE__ */ React.createElement(
|
|
35
|
-
View,
|
|
36
|
-
{
|
|
37
|
-
style: [
|
|
38
|
-
styles.base,
|
|
39
|
-
{ width: resolvedWidth, height: resolvedHeight, borderRadius: resolvedRadius, backgroundColor: colors.surface },
|
|
40
|
-
style
|
|
41
|
-
],
|
|
42
|
-
onLayout: (e) => setContainerWidth(e.nativeEvent.layout.width),
|
|
43
|
-
accessibilityRole: "progressbar",
|
|
44
|
-
accessibilityLabel: "Loading",
|
|
45
|
-
accessibilityState: { busy: true }
|
|
46
|
-
},
|
|
47
|
-
/* @__PURE__ */ React.createElement(Animated.View, { style: [StyleSheet.absoluteFill, shimmerStyle] }, /* @__PURE__ */ React.createElement(
|
|
48
|
-
LinearGradient,
|
|
49
|
-
{
|
|
50
|
-
colors: ["transparent", shimmerHighlight, "transparent"],
|
|
51
|
-
start: { x: 0, y: 0 },
|
|
52
|
-
end: { x: 1, y: 0 },
|
|
53
|
-
style: StyleSheet.absoluteFill
|
|
54
|
-
}
|
|
55
|
-
))
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
var styles = StyleSheet.create({
|
|
59
|
-
base: {
|
|
60
|
-
overflow: "hidden"
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
export { Skeleton };
|
package/dist/chunk-LG4DO3DK.mjs
DELETED
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
import { renderIcon } from './chunk-T7XZ7H7Y.mjs';
|
|
2
|
-
import { usePressScale } from './chunk-QCNARS3X.mjs';
|
|
3
|
-
import { selectionAsync } from './chunk-RTC3CFXF.mjs';
|
|
4
|
-
import { SPRINGS, PRESS_SCALE } from './chunk-5IKW3VNC.mjs';
|
|
5
|
-
import { RADIUS } from './chunk-QY3X2UYR.mjs';
|
|
6
|
-
import { useTheme } from './chunk-SOYNZDVY.mjs';
|
|
7
|
-
import { ms, s, mvs, vs } from './chunk-2CE3TQVY.mjs';
|
|
8
|
-
import React from 'react';
|
|
9
|
-
import { StyleSheet, TouchableOpacity, View, Text } from 'react-native';
|
|
10
|
-
import Animated from 'react-native-reanimated';
|
|
11
|
-
import { Entypo } from '@expo/vector-icons';
|
|
12
|
-
|
|
13
|
-
function ListItemBase({
|
|
14
|
-
leftRender,
|
|
15
|
-
rightRender,
|
|
16
|
-
trailing,
|
|
17
|
-
icon,
|
|
18
|
-
leftIcon,
|
|
19
|
-
rightIcon,
|
|
20
|
-
leftIconColor,
|
|
21
|
-
rightIconColor,
|
|
22
|
-
title,
|
|
23
|
-
subtitle,
|
|
24
|
-
caption,
|
|
25
|
-
variant = "plain",
|
|
26
|
-
showChevron = false,
|
|
27
|
-
showSeparator = false,
|
|
28
|
-
onPress,
|
|
29
|
-
disabled,
|
|
30
|
-
style,
|
|
31
|
-
titleStyle,
|
|
32
|
-
subtitleStyle,
|
|
33
|
-
captionStyle,
|
|
34
|
-
accessibilityLabel
|
|
35
|
-
}) {
|
|
36
|
-
const { colors } = useTheme();
|
|
37
|
-
const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
38
|
-
pressScale: PRESS_SCALE.row,
|
|
39
|
-
pressInSpring: SPRINGS.surfacePressIn,
|
|
40
|
-
pressOutSpring: SPRINGS.surfacePressOut,
|
|
41
|
-
disabled: !onPress || disabled
|
|
42
|
-
});
|
|
43
|
-
const handlePress = () => {
|
|
44
|
-
selectionAsync();
|
|
45
|
-
onPress?.();
|
|
46
|
-
};
|
|
47
|
-
const effectiveLeft = leftIcon ? renderIcon(leftIcon, 24, leftIconColor ?? colors.foreground) : leftRender ?? icon;
|
|
48
|
-
const effectiveRight = rightIcon ? renderIcon(rightIcon, 24, rightIconColor ?? colors.foregroundMuted) : rightRender ?? trailing;
|
|
49
|
-
const cardStyle = variant === "card" ? {
|
|
50
|
-
backgroundColor: colors.card,
|
|
51
|
-
borderRadius: RADIUS.md,
|
|
52
|
-
borderWidth: 1,
|
|
53
|
-
borderColor: colors.border,
|
|
54
|
-
shadowColor: "#000",
|
|
55
|
-
shadowOffset: { width: 0, height: 2 },
|
|
56
|
-
shadowOpacity: 0.06,
|
|
57
|
-
shadowRadius: 6,
|
|
58
|
-
elevation: 2
|
|
59
|
-
} : {};
|
|
60
|
-
const a11yLabel = accessibilityLabel ?? [title, subtitle, caption].filter(Boolean).join(". ");
|
|
61
|
-
return /* @__PURE__ */ React.createElement(Animated.View, { style: [animatedStyle, disabled && styles.disabled], ...hoverHandlers }, /* @__PURE__ */ React.createElement(
|
|
62
|
-
TouchableOpacity,
|
|
63
|
-
{
|
|
64
|
-
style: [styles.container, cardStyle, style],
|
|
65
|
-
onPress: onPress ? handlePress : void 0,
|
|
66
|
-
onPressIn,
|
|
67
|
-
onPressOut,
|
|
68
|
-
disabled,
|
|
69
|
-
activeOpacity: 1,
|
|
70
|
-
touchSoundDisabled: true,
|
|
71
|
-
accessibilityRole: onPress ? "button" : void 0,
|
|
72
|
-
accessibilityLabel: onPress ? a11yLabel : void 0,
|
|
73
|
-
accessibilityState: onPress ? { disabled: !!disabled } : void 0
|
|
74
|
-
},
|
|
75
|
-
effectiveLeft ? /* @__PURE__ */ React.createElement(View, { style: styles.leftContainer }, effectiveLeft) : null,
|
|
76
|
-
/* @__PURE__ */ React.createElement(View, { style: styles.content }, /* @__PURE__ */ React.createElement(
|
|
77
|
-
Text,
|
|
78
|
-
{
|
|
79
|
-
style: [styles.title, { color: colors.foreground }, titleStyle],
|
|
80
|
-
numberOfLines: 2,
|
|
81
|
-
allowFontScaling: true
|
|
82
|
-
},
|
|
83
|
-
title
|
|
84
|
-
), subtitle ? /* @__PURE__ */ React.createElement(
|
|
85
|
-
Text,
|
|
86
|
-
{
|
|
87
|
-
style: [styles.subtitle, { color: colors.foregroundMuted }, subtitleStyle],
|
|
88
|
-
numberOfLines: 2,
|
|
89
|
-
allowFontScaling: true
|
|
90
|
-
},
|
|
91
|
-
subtitle
|
|
92
|
-
) : null, caption ? /* @__PURE__ */ React.createElement(
|
|
93
|
-
Text,
|
|
94
|
-
{
|
|
95
|
-
style: [styles.caption, { color: colors.foregroundMuted }, captionStyle],
|
|
96
|
-
numberOfLines: 1,
|
|
97
|
-
allowFontScaling: true
|
|
98
|
-
},
|
|
99
|
-
caption
|
|
100
|
-
) : null),
|
|
101
|
-
effectiveRight !== void 0 ? /* @__PURE__ */ React.createElement(View, { style: styles.rightContainer }, typeof effectiveRight === "string" ? /* @__PURE__ */ React.createElement(
|
|
102
|
-
Text,
|
|
103
|
-
{
|
|
104
|
-
style: [styles.rightText, { color: colors.foregroundMuted }],
|
|
105
|
-
allowFontScaling: true
|
|
106
|
-
},
|
|
107
|
-
effectiveRight
|
|
108
|
-
) : effectiveRight) : showChevron ? /* @__PURE__ */ React.createElement(Entypo, { name: "chevron-with-circle-right", size: 20, color: colors.foregroundMuted }) : null
|
|
109
|
-
), showSeparator ? /* @__PURE__ */ React.createElement(
|
|
110
|
-
View,
|
|
111
|
-
{
|
|
112
|
-
style: [
|
|
113
|
-
styles.separator,
|
|
114
|
-
{ backgroundColor: colors.separator }
|
|
115
|
-
]
|
|
116
|
-
}
|
|
117
|
-
) : null);
|
|
118
|
-
}
|
|
119
|
-
var ListItem = React.memo(ListItemBase);
|
|
120
|
-
var styles = StyleSheet.create({
|
|
121
|
-
container: {
|
|
122
|
-
flexDirection: "row",
|
|
123
|
-
alignItems: "center",
|
|
124
|
-
paddingHorizontal: s(16),
|
|
125
|
-
paddingVertical: vs(10),
|
|
126
|
-
gap: s(12)
|
|
127
|
-
},
|
|
128
|
-
leftContainer: {
|
|
129
|
-
width: s(44),
|
|
130
|
-
height: s(44),
|
|
131
|
-
alignItems: "center",
|
|
132
|
-
justifyContent: "center",
|
|
133
|
-
flexShrink: 0
|
|
134
|
-
},
|
|
135
|
-
content: {
|
|
136
|
-
flex: 1,
|
|
137
|
-
gap: vs(4)
|
|
138
|
-
},
|
|
139
|
-
title: {
|
|
140
|
-
fontFamily: "Sohne-Medium",
|
|
141
|
-
fontSize: ms(15),
|
|
142
|
-
lineHeight: mvs(22)
|
|
143
|
-
},
|
|
144
|
-
subtitle: {
|
|
145
|
-
fontFamily: "Sohne-Regular",
|
|
146
|
-
fontSize: ms(13),
|
|
147
|
-
lineHeight: mvs(18)
|
|
148
|
-
},
|
|
149
|
-
caption: {
|
|
150
|
-
fontFamily: "Sohne-Regular",
|
|
151
|
-
fontSize: ms(12),
|
|
152
|
-
lineHeight: mvs(16),
|
|
153
|
-
opacity: 0.7
|
|
154
|
-
},
|
|
155
|
-
rightContainer: {
|
|
156
|
-
alignItems: "flex-end",
|
|
157
|
-
justifyContent: "center",
|
|
158
|
-
flexShrink: 0,
|
|
159
|
-
maxWidth: s(160)
|
|
160
|
-
},
|
|
161
|
-
rightText: {
|
|
162
|
-
fontFamily: "Sohne-Regular",
|
|
163
|
-
fontSize: ms(14)
|
|
164
|
-
},
|
|
165
|
-
separator: {
|
|
166
|
-
height: StyleSheet.hairlineWidth,
|
|
167
|
-
marginRight: 0
|
|
168
|
-
},
|
|
169
|
-
disabled: {
|
|
170
|
-
opacity: 0.45
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
export { ListItem };
|