@retray-dev/ui-kit 1.0.0 → 1.5.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 +120 -64
- package/README.md +18 -19
- package/dist/index.d.mts +39 -4
- package/dist/index.d.ts +39 -4
- package/dist/index.js +431 -265
- package/dist/index.mjs +430 -265
- package/package.json +20 -3
- package/src/components/Accordion/Accordion.tsx +50 -38
- package/src/components/Alert/Alert.tsx +3 -1
- package/src/components/Avatar/Avatar.tsx +5 -1
- package/src/components/Badge/Badge.tsx +1 -1
- package/src/components/Button/Button.tsx +24 -8
- package/src/components/Card/Card.tsx +2 -8
- package/src/components/Checkbox/Checkbox.tsx +35 -7
- package/src/components/EmptyState/EmptyState.tsx +1 -3
- package/src/components/Input/Input.tsx +18 -10
- package/src/components/Progress/Progress.tsx +3 -4
- package/src/components/RadioGroup/RadioGroup.tsx +72 -45
- package/src/components/Select/Select.tsx +117 -70
- package/src/components/Sheet/Sheet.tsx +9 -2
- package/src/components/Skeleton/Skeleton.tsx +36 -13
- package/src/components/Slider/Slider.tsx +5 -4
- package/src/components/Spinner/Spinner.tsx +1 -7
- package/src/components/Switch/Switch.tsx +5 -1
- package/src/components/Tabs/Tabs.tsx +82 -31
- package/src/components/Textarea/Textarea.tsx +29 -10
- package/src/components/Toast/Toast.tsx +69 -33
- package/src/components/Toggle/Toggle.tsx +32 -20
- package/src/theme/colors.ts +4 -0
- package/src/theme/types.ts +2 -0
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import React23, { createContext, useMemo, useContext, useRef, useState, useEffect, useCallback } from 'react';
|
|
2
|
-
import { StyleSheet, useColorScheme, Animated, TouchableOpacity, ActivityIndicator, Text, View, TextInput, Image, PanResponder
|
|
3
|
-
import * as
|
|
2
|
+
import { StyleSheet, useColorScheme, Animated, TouchableOpacity, ActivityIndicator, Text, View, TextInput, Image, PanResponder } from 'react-native';
|
|
3
|
+
import * as Haptics11 from 'expo-haptics';
|
|
4
|
+
import { LinearGradient } from 'expo-linear-gradient';
|
|
5
|
+
import ReanimatedAnimated, { useSharedValue, useAnimatedStyle, withTiming, Easing, runOnJS, withSpring } from 'react-native-reanimated';
|
|
4
6
|
import { BottomSheetModal, BottomSheetView, BottomSheetBackdrop } from '@gorhom/bottom-sheet';
|
|
5
7
|
export { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
|
|
8
|
+
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
6
9
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
7
10
|
|
|
8
11
|
// src/theme/ThemeProvider.tsx
|
|
@@ -25,7 +28,9 @@ var defaultLight = {
|
|
|
25
28
|
destructiveForeground: "#fafafa",
|
|
26
29
|
border: "#e5e5e5",
|
|
27
30
|
input: "#e5e5e5",
|
|
28
|
-
ring: "#a3a3a3"
|
|
31
|
+
ring: "#a3a3a3",
|
|
32
|
+
success: "#16a34a",
|
|
33
|
+
successForeground: "#ffffff"
|
|
29
34
|
};
|
|
30
35
|
var defaultDark = {
|
|
31
36
|
background: "#171717",
|
|
@@ -44,7 +49,9 @@ var defaultDark = {
|
|
|
44
49
|
destructiveForeground: "#fafafa",
|
|
45
50
|
border: "#2a2a2a",
|
|
46
51
|
input: "#2a2a2a",
|
|
47
|
-
ring: "#d4d4d4"
|
|
52
|
+
ring: "#d4d4d4",
|
|
53
|
+
success: "#22c55e",
|
|
54
|
+
successForeground: "#ffffff"
|
|
48
55
|
};
|
|
49
56
|
|
|
50
57
|
// src/theme/ThemeProvider.tsx
|
|
@@ -81,6 +88,8 @@ function Button({
|
|
|
81
88
|
size = "md",
|
|
82
89
|
loading = false,
|
|
83
90
|
fullWidth = false,
|
|
91
|
+
icon,
|
|
92
|
+
iconPosition = "left",
|
|
84
93
|
disabled,
|
|
85
94
|
style,
|
|
86
95
|
onPress,
|
|
@@ -91,13 +100,18 @@ function Button({
|
|
|
91
100
|
const scale = useRef(new Animated.Value(1)).current;
|
|
92
101
|
const handlePressIn = () => {
|
|
93
102
|
if (isDisabled) return;
|
|
94
|
-
Animated.spring(scale, {
|
|
103
|
+
Animated.spring(scale, {
|
|
104
|
+
toValue: 0.95,
|
|
105
|
+
useNativeDriver: true,
|
|
106
|
+
speed: 40,
|
|
107
|
+
bounciness: 0
|
|
108
|
+
}).start();
|
|
95
109
|
};
|
|
96
110
|
const handlePressOut = () => {
|
|
97
|
-
Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness:
|
|
111
|
+
Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
|
|
98
112
|
};
|
|
99
113
|
const handlePress = (e) => {
|
|
100
|
-
|
|
114
|
+
Haptics11.impactAsync(Haptics11.ImpactFeedbackStyle.Light);
|
|
101
115
|
onPress?.(e);
|
|
102
116
|
};
|
|
103
117
|
const containerVariantStyle = {
|
|
@@ -126,12 +140,13 @@ function Button({
|
|
|
126
140
|
],
|
|
127
141
|
disabled: isDisabled,
|
|
128
142
|
activeOpacity: 1,
|
|
143
|
+
touchSoundDisabled: true,
|
|
129
144
|
onPress: handlePress,
|
|
130
145
|
onPressIn: handlePressIn,
|
|
131
146
|
onPressOut: handlePressOut,
|
|
132
147
|
...props
|
|
133
148
|
},
|
|
134
|
-
loading ? /* @__PURE__ */ React23.createElement(ActivityIndicator, { size: "small", color: spinnerColor }) : /* @__PURE__ */ React23.createElement(Text, { style: [styles.label, labelVariantStyle, labelSizeStyles[size]] }, label)
|
|
149
|
+
loading ? /* @__PURE__ */ React23.createElement(ActivityIndicator, { size: "small", color: spinnerColor }) : /* @__PURE__ */ React23.createElement(React23.Fragment, null, icon && iconPosition === "left" && /* @__PURE__ */ React23.createElement(React23.Fragment, null, icon), /* @__PURE__ */ React23.createElement(Text, { style: [styles.label, labelVariantStyle, labelSizeStyles[size], icon ? styles.labelWithIcon : void 0] }, label), icon && iconPosition === "right" && /* @__PURE__ */ React23.createElement(React23.Fragment, null, icon))
|
|
135
150
|
));
|
|
136
151
|
}
|
|
137
152
|
var styles = StyleSheet.create({
|
|
@@ -149,6 +164,9 @@ var styles = StyleSheet.create({
|
|
|
149
164
|
},
|
|
150
165
|
label: {
|
|
151
166
|
fontWeight: "600"
|
|
167
|
+
},
|
|
168
|
+
labelWithIcon: {
|
|
169
|
+
marginHorizontal: 6
|
|
152
170
|
}
|
|
153
171
|
});
|
|
154
172
|
var variantStyles = {
|
|
@@ -172,10 +190,10 @@ function Text2({ variant = "body", color, style, children, ...props }) {
|
|
|
172
190
|
children
|
|
173
191
|
);
|
|
174
192
|
}
|
|
175
|
-
function Input({ label, error, hint, style, onFocus, onBlur, ...props }) {
|
|
193
|
+
function Input({ label, error, hint, containerStyle, style, onFocus, onBlur, ...props }) {
|
|
176
194
|
const { colors } = useTheme();
|
|
177
195
|
const [focused, setFocused] = useState(false);
|
|
178
|
-
return /* @__PURE__ */ React23.createElement(View, { style: styles2.container }, label ? /* @__PURE__ */ React23.createElement(Text, { style: [styles2.label, { color: colors.foreground }] }, label) : null, /* @__PURE__ */ React23.createElement(
|
|
196
|
+
return /* @__PURE__ */ React23.createElement(View, { style: [styles2.container, containerStyle] }, label ? /* @__PURE__ */ React23.createElement(Text, { style: [styles2.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React23.createElement(
|
|
179
197
|
TextInput,
|
|
180
198
|
{
|
|
181
199
|
style: [
|
|
@@ -199,7 +217,7 @@ function Input({ label, error, hint, style, onFocus, onBlur, ...props }) {
|
|
|
199
217
|
allowFontScaling: true,
|
|
200
218
|
...props
|
|
201
219
|
}
|
|
202
|
-
), error ? /* @__PURE__ */ React23.createElement(Text, { style: [styles2.helperText, { color: colors.destructive }] }, error) : null, !error && hint ? /* @__PURE__ */ React23.createElement(Text, { style: [styles2.helperText, { color: colors.mutedForeground }] }, hint) : null);
|
|
220
|
+
), error ? /* @__PURE__ */ React23.createElement(Text, { style: [styles2.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React23.createElement(Text, { style: [styles2.helperText, { color: colors.mutedForeground }], allowFontScaling: true }, hint) : null);
|
|
203
221
|
}
|
|
204
222
|
var styles2 = StyleSheet.create({
|
|
205
223
|
container: {
|
|
@@ -235,7 +253,7 @@ function Badge({ label, variant = "default", style }) {
|
|
|
235
253
|
destructive: colors.destructiveForeground,
|
|
236
254
|
outline: colors.foreground
|
|
237
255
|
}[variant];
|
|
238
|
-
return /* @__PURE__ */ React23.createElement(View, { style: [styles3.container, containerStyle, style] }, /* @__PURE__ */ React23.createElement(Text, { style: [styles3.label, { color: textColor }] }, label));
|
|
256
|
+
return /* @__PURE__ */ React23.createElement(View, { style: [styles3.container, containerStyle, style] }, /* @__PURE__ */ React23.createElement(Text, { style: [styles3.label, { color: textColor }], allowFontScaling: true }, label));
|
|
239
257
|
}
|
|
240
258
|
var styles3 = StyleSheet.create({
|
|
241
259
|
container: {
|
|
@@ -254,11 +272,7 @@ function Card({ children, style }) {
|
|
|
254
272
|
return /* @__PURE__ */ React23.createElement(
|
|
255
273
|
View,
|
|
256
274
|
{
|
|
257
|
-
style: [
|
|
258
|
-
styles4.card,
|
|
259
|
-
{ backgroundColor: colors.card, borderColor: colors.border },
|
|
260
|
-
style
|
|
261
|
-
]
|
|
275
|
+
style: [styles4.card, { backgroundColor: colors.card, borderColor: colors.border }, style]
|
|
262
276
|
},
|
|
263
277
|
children
|
|
264
278
|
);
|
|
@@ -344,41 +358,53 @@ var sizeMap = {
|
|
|
344
358
|
};
|
|
345
359
|
function Spinner({ size = "md", color, ...props }) {
|
|
346
360
|
const { colors } = useTheme();
|
|
347
|
-
return /* @__PURE__ */ React23.createElement(
|
|
348
|
-
ActivityIndicator,
|
|
349
|
-
{
|
|
350
|
-
size: sizeMap[size],
|
|
351
|
-
color: color ?? colors.primary,
|
|
352
|
-
...props
|
|
353
|
-
}
|
|
354
|
-
);
|
|
361
|
+
return /* @__PURE__ */ React23.createElement(ActivityIndicator, { size: sizeMap[size], color: color ?? colors.primary, ...props });
|
|
355
362
|
}
|
|
356
363
|
function Skeleton({ width = "100%", height = 16, borderRadius = 6, style }) {
|
|
357
|
-
const { colors } = useTheme();
|
|
358
|
-
const
|
|
364
|
+
const { colors, colorScheme } = useTheme();
|
|
365
|
+
const shimmerAnim = useRef(new Animated.Value(0)).current;
|
|
366
|
+
const [containerWidth, setContainerWidth] = useState(300);
|
|
367
|
+
const shimmerHighlight = colorScheme === "dark" ? "rgba(255,255,255,0.08)" : "rgba(255,255,255,0.7)";
|
|
359
368
|
useEffect(() => {
|
|
360
369
|
const animation = Animated.loop(
|
|
361
|
-
Animated.
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
370
|
+
Animated.timing(shimmerAnim, {
|
|
371
|
+
toValue: 1,
|
|
372
|
+
duration: 1200,
|
|
373
|
+
useNativeDriver: true
|
|
374
|
+
})
|
|
365
375
|
);
|
|
366
376
|
animation.start();
|
|
367
377
|
return () => animation.stop();
|
|
368
|
-
}, [
|
|
378
|
+
}, [shimmerAnim]);
|
|
379
|
+
const translateX = shimmerAnim.interpolate({
|
|
380
|
+
inputRange: [0, 1],
|
|
381
|
+
outputRange: [-containerWidth, containerWidth]
|
|
382
|
+
});
|
|
369
383
|
return /* @__PURE__ */ React23.createElement(
|
|
370
|
-
|
|
384
|
+
View,
|
|
371
385
|
{
|
|
372
386
|
style: [
|
|
373
387
|
styles6.base,
|
|
374
|
-
{ width, height, borderRadius, backgroundColor: colors.muted
|
|
388
|
+
{ width, height, borderRadius, backgroundColor: colors.muted },
|
|
375
389
|
style
|
|
376
|
-
]
|
|
377
|
-
|
|
390
|
+
],
|
|
391
|
+
onLayout: (e) => setContainerWidth(e.nativeEvent.layout.width)
|
|
392
|
+
},
|
|
393
|
+
/* @__PURE__ */ React23.createElement(Animated.View, { style: [StyleSheet.absoluteFill, { transform: [{ translateX }] }] }, /* @__PURE__ */ React23.createElement(
|
|
394
|
+
LinearGradient,
|
|
395
|
+
{
|
|
396
|
+
colors: ["transparent", shimmerHighlight, "transparent"],
|
|
397
|
+
start: { x: 0, y: 0 },
|
|
398
|
+
end: { x: 1, y: 0 },
|
|
399
|
+
style: StyleSheet.absoluteFill
|
|
400
|
+
}
|
|
401
|
+
))
|
|
378
402
|
);
|
|
379
403
|
}
|
|
380
404
|
var styles6 = StyleSheet.create({
|
|
381
|
-
base: {
|
|
405
|
+
base: {
|
|
406
|
+
overflow: "hidden"
|
|
407
|
+
}
|
|
382
408
|
});
|
|
383
409
|
var sizeMap2 = {
|
|
384
410
|
sm: 24,
|
|
@@ -411,7 +437,13 @@ function Avatar({ src, fallback, size = "md", style }) {
|
|
|
411
437
|
style: { width: dimension, height: dimension },
|
|
412
438
|
onError: () => setImageError(true)
|
|
413
439
|
}
|
|
414
|
-
) : /* @__PURE__ */ React23.createElement(
|
|
440
|
+
) : /* @__PURE__ */ React23.createElement(
|
|
441
|
+
Text,
|
|
442
|
+
{
|
|
443
|
+
style: [styles7.fallback, { color: colors.mutedForeground, fontSize: fontSizeMap[size] }]
|
|
444
|
+
},
|
|
445
|
+
fallback?.slice(0, 2).toUpperCase() ?? "?"
|
|
446
|
+
));
|
|
415
447
|
}
|
|
416
448
|
var styles7 = StyleSheet.create({
|
|
417
449
|
base: {
|
|
@@ -477,10 +509,7 @@ function Progress({ value = 0, max = 100, style }) {
|
|
|
477
509
|
/* @__PURE__ */ React23.createElement(
|
|
478
510
|
Animated.View,
|
|
479
511
|
{
|
|
480
|
-
style: [
|
|
481
|
-
styles9.indicator,
|
|
482
|
-
{ width: animatedWidth, backgroundColor: colors.primary }
|
|
483
|
-
]
|
|
512
|
+
style: [styles9.indicator, { width: animatedWidth, backgroundColor: colors.primary }]
|
|
484
513
|
}
|
|
485
514
|
)
|
|
486
515
|
);
|
|
@@ -537,10 +566,20 @@ var styles10 = StyleSheet.create({
|
|
|
537
566
|
marginTop: 8
|
|
538
567
|
}
|
|
539
568
|
});
|
|
540
|
-
function Textarea({
|
|
569
|
+
function Textarea({
|
|
570
|
+
label,
|
|
571
|
+
error,
|
|
572
|
+
hint,
|
|
573
|
+
rows = 4,
|
|
574
|
+
containerStyle,
|
|
575
|
+
style,
|
|
576
|
+
onFocus,
|
|
577
|
+
onBlur,
|
|
578
|
+
...props
|
|
579
|
+
}) {
|
|
541
580
|
const { colors } = useTheme();
|
|
542
581
|
const [focused, setFocused] = useState(false);
|
|
543
|
-
return /* @__PURE__ */ React23.createElement(View, { style: styles11.container }, label ? /* @__PURE__ */ React23.createElement(Text, { style: [styles11.label, { color: colors.foreground }] }, label) : null, /* @__PURE__ */ React23.createElement(
|
|
582
|
+
return /* @__PURE__ */ React23.createElement(View, { style: [styles11.container, containerStyle] }, label ? /* @__PURE__ */ React23.createElement(Text, { style: [styles11.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React23.createElement(
|
|
544
583
|
TextInput,
|
|
545
584
|
{
|
|
546
585
|
multiline: true,
|
|
@@ -568,7 +607,7 @@ function Textarea({ label, error, hint, rows = 4, style, onFocus, onBlur, ...pro
|
|
|
568
607
|
allowFontScaling: true,
|
|
569
608
|
...props
|
|
570
609
|
}
|
|
571
|
-
), error ? /* @__PURE__ */ React23.createElement(Text, { style: [styles11.helperText, { color: colors.destructive }] }, error) : null, !error && hint ? /* @__PURE__ */ React23.createElement(Text, { style: [styles11.helperText, { color: colors.mutedForeground }] }, hint) : null);
|
|
610
|
+
), error ? /* @__PURE__ */ React23.createElement(Text, { style: [styles11.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React23.createElement(Text, { style: [styles11.helperText, { color: colors.mutedForeground }], allowFontScaling: true }, hint) : null);
|
|
572
611
|
}
|
|
573
612
|
var styles11 = StyleSheet.create({
|
|
574
613
|
container: {
|
|
@@ -590,18 +629,35 @@ var styles11 = StyleSheet.create({
|
|
|
590
629
|
fontSize: 12
|
|
591
630
|
}
|
|
592
631
|
});
|
|
593
|
-
function Checkbox({
|
|
632
|
+
function Checkbox({
|
|
633
|
+
checked = false,
|
|
634
|
+
onCheckedChange,
|
|
635
|
+
label,
|
|
636
|
+
disabled,
|
|
637
|
+
style
|
|
638
|
+
}) {
|
|
594
639
|
const { colors } = useTheme();
|
|
595
|
-
|
|
640
|
+
const scale = useRef(new Animated.Value(1)).current;
|
|
641
|
+
const handlePressIn = () => {
|
|
642
|
+
if (disabled) return;
|
|
643
|
+
Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
|
|
644
|
+
};
|
|
645
|
+
const handlePressOut = () => {
|
|
646
|
+
Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
|
|
647
|
+
};
|
|
648
|
+
return /* @__PURE__ */ React23.createElement(Animated.View, { style: { transform: [{ scale }] } }, /* @__PURE__ */ React23.createElement(
|
|
596
649
|
TouchableOpacity,
|
|
597
650
|
{
|
|
598
651
|
style: [styles12.row, style],
|
|
599
652
|
onPress: () => {
|
|
600
|
-
|
|
653
|
+
Haptics11.selectionAsync();
|
|
601
654
|
onCheckedChange?.(!checked);
|
|
602
655
|
},
|
|
656
|
+
onPressIn: handlePressIn,
|
|
657
|
+
onPressOut: handlePressOut,
|
|
603
658
|
disabled,
|
|
604
|
-
activeOpacity:
|
|
659
|
+
activeOpacity: 1,
|
|
660
|
+
touchSoundDisabled: true
|
|
605
661
|
},
|
|
606
662
|
/* @__PURE__ */ React23.createElement(
|
|
607
663
|
View,
|
|
@@ -617,8 +673,14 @@ function Checkbox({ checked = false, onCheckedChange, label, disabled, style })
|
|
|
617
673
|
},
|
|
618
674
|
checked ? /* @__PURE__ */ React23.createElement(View, { style: [styles12.checkmark, { borderColor: colors.primaryForeground }] }) : null
|
|
619
675
|
),
|
|
620
|
-
label ? /* @__PURE__ */ React23.createElement(
|
|
621
|
-
|
|
676
|
+
label ? /* @__PURE__ */ React23.createElement(
|
|
677
|
+
Text,
|
|
678
|
+
{
|
|
679
|
+
style: [styles12.label, { color: disabled ? colors.mutedForeground : colors.foreground }]
|
|
680
|
+
},
|
|
681
|
+
label
|
|
682
|
+
) : null
|
|
683
|
+
));
|
|
622
684
|
}
|
|
623
685
|
var styles12 = StyleSheet.create({
|
|
624
686
|
row: {
|
|
@@ -677,11 +739,12 @@ function Switch({ checked = false, onCheckedChange, disabled, style }) {
|
|
|
677
739
|
TouchableOpacity,
|
|
678
740
|
{
|
|
679
741
|
onPress: () => {
|
|
680
|
-
|
|
742
|
+
Haptics11.selectionAsync();
|
|
681
743
|
onCheckedChange?.(!checked);
|
|
682
744
|
},
|
|
683
745
|
disabled,
|
|
684
746
|
activeOpacity: 0.8,
|
|
747
|
+
touchSoundDisabled: true,
|
|
685
748
|
style: [styles13.wrapper, { opacity: disabled ? 0.45 : 1 }, style]
|
|
686
749
|
},
|
|
687
750
|
/* @__PURE__ */ React23.createElement(Animated.View, { style: [styles13.track, { backgroundColor: trackColor }] }, /* @__PURE__ */ React23.createElement(
|
|
@@ -732,29 +795,34 @@ function Toggle({
|
|
|
732
795
|
...props
|
|
733
796
|
}) {
|
|
734
797
|
const { colors } = useTheme();
|
|
798
|
+
const scale = useRef(new Animated.Value(1)).current;
|
|
799
|
+
const handlePressIn = () => {
|
|
800
|
+
if (disabled) return;
|
|
801
|
+
Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
|
|
802
|
+
};
|
|
803
|
+
const handlePressOut = () => {
|
|
804
|
+
Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
|
|
805
|
+
};
|
|
735
806
|
const containerStyle = pressed ? { backgroundColor: colors.accent } : variant === "outline" ? { backgroundColor: "transparent", borderWidth: 1, borderColor: colors.border } : { backgroundColor: "transparent" };
|
|
736
807
|
const textColor = pressed ? colors.accentForeground : colors.foreground;
|
|
737
|
-
return /* @__PURE__ */ React23.createElement(
|
|
808
|
+
return /* @__PURE__ */ React23.createElement(Animated.View, { style: { transform: [{ scale }] } }, /* @__PURE__ */ React23.createElement(
|
|
738
809
|
TouchableOpacity,
|
|
739
810
|
{
|
|
740
|
-
style: [
|
|
741
|
-
styles14.base,
|
|
742
|
-
containerStyle,
|
|
743
|
-
sizeStyles[size],
|
|
744
|
-
disabled && styles14.disabled,
|
|
745
|
-
style
|
|
746
|
-
],
|
|
811
|
+
style: [styles14.base, containerStyle, sizeStyles[size], disabled && styles14.disabled, style],
|
|
747
812
|
onPress: () => {
|
|
748
|
-
|
|
813
|
+
Haptics11.selectionAsync();
|
|
749
814
|
onPressedChange?.(!pressed);
|
|
750
815
|
},
|
|
816
|
+
onPressIn: handlePressIn,
|
|
817
|
+
onPressOut: handlePressOut,
|
|
751
818
|
disabled,
|
|
752
|
-
activeOpacity:
|
|
819
|
+
activeOpacity: 1,
|
|
820
|
+
touchSoundDisabled: true,
|
|
753
821
|
...props
|
|
754
822
|
},
|
|
755
823
|
icon,
|
|
756
824
|
label ? /* @__PURE__ */ React23.createElement(Text, { style: [styles14.label, { color: textColor }] }, label) : null
|
|
757
|
-
);
|
|
825
|
+
));
|
|
758
826
|
}
|
|
759
827
|
var styles14 = StyleSheet.create({
|
|
760
828
|
base: {
|
|
@@ -772,6 +840,61 @@ var styles14 = StyleSheet.create({
|
|
|
772
840
|
fontWeight: "500"
|
|
773
841
|
}
|
|
774
842
|
});
|
|
843
|
+
function RadioItem({
|
|
844
|
+
option,
|
|
845
|
+
selected,
|
|
846
|
+
onSelect
|
|
847
|
+
}) {
|
|
848
|
+
const { colors } = useTheme();
|
|
849
|
+
const scale = useRef(new Animated.Value(1)).current;
|
|
850
|
+
const handlePressIn = () => {
|
|
851
|
+
if (option.disabled) return;
|
|
852
|
+
Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
|
|
853
|
+
};
|
|
854
|
+
const handlePressOut = () => {
|
|
855
|
+
Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
|
|
856
|
+
};
|
|
857
|
+
return /* @__PURE__ */ React23.createElement(Animated.View, { style: { transform: [{ scale }] } }, /* @__PURE__ */ React23.createElement(
|
|
858
|
+
TouchableOpacity,
|
|
859
|
+
{
|
|
860
|
+
style: styles15.row,
|
|
861
|
+
onPress: () => {
|
|
862
|
+
if (!option.disabled) {
|
|
863
|
+
Haptics11.selectionAsync();
|
|
864
|
+
onSelect();
|
|
865
|
+
}
|
|
866
|
+
},
|
|
867
|
+
onPressIn: handlePressIn,
|
|
868
|
+
onPressOut: handlePressOut,
|
|
869
|
+
activeOpacity: 1,
|
|
870
|
+
touchSoundDisabled: true,
|
|
871
|
+
disabled: option.disabled
|
|
872
|
+
},
|
|
873
|
+
/* @__PURE__ */ React23.createElement(
|
|
874
|
+
View,
|
|
875
|
+
{
|
|
876
|
+
style: [
|
|
877
|
+
styles15.radio,
|
|
878
|
+
{
|
|
879
|
+
borderColor: selected ? colors.primary : colors.border,
|
|
880
|
+
opacity: option.disabled ? 0.45 : 1
|
|
881
|
+
}
|
|
882
|
+
]
|
|
883
|
+
},
|
|
884
|
+
selected ? /* @__PURE__ */ React23.createElement(View, { style: [styles15.dot, { backgroundColor: colors.primary }] }) : null
|
|
885
|
+
),
|
|
886
|
+
/* @__PURE__ */ React23.createElement(
|
|
887
|
+
Text,
|
|
888
|
+
{
|
|
889
|
+
style: [
|
|
890
|
+
styles15.label,
|
|
891
|
+
{ color: option.disabled ? colors.mutedForeground : colors.foreground }
|
|
892
|
+
]
|
|
893
|
+
},
|
|
894
|
+
option.label
|
|
895
|
+
)
|
|
896
|
+
));
|
|
897
|
+
}
|
|
775
898
|
function RadioGroup({
|
|
776
899
|
options,
|
|
777
900
|
value,
|
|
@@ -779,58 +902,15 @@ function RadioGroup({
|
|
|
779
902
|
orientation = "vertical",
|
|
780
903
|
style
|
|
781
904
|
}) {
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
View,
|
|
905
|
+
return /* @__PURE__ */ React23.createElement(View, { style: [styles15.container, orientation === "horizontal" && styles15.horizontal, style] }, options.map((option) => /* @__PURE__ */ React23.createElement(
|
|
906
|
+
RadioItem,
|
|
785
907
|
{
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
options.map((option) => {
|
|
793
|
-
const selected = option.value === value;
|
|
794
|
-
return /* @__PURE__ */ React23.createElement(
|
|
795
|
-
TouchableOpacity,
|
|
796
|
-
{
|
|
797
|
-
key: option.value,
|
|
798
|
-
style: styles15.row,
|
|
799
|
-
onPress: () => {
|
|
800
|
-
if (!option.disabled) {
|
|
801
|
-
Haptics10.selectionAsync();
|
|
802
|
-
onValueChange?.(option.value);
|
|
803
|
-
}
|
|
804
|
-
},
|
|
805
|
-
activeOpacity: 0.7,
|
|
806
|
-
disabled: option.disabled
|
|
807
|
-
},
|
|
808
|
-
/* @__PURE__ */ React23.createElement(
|
|
809
|
-
View,
|
|
810
|
-
{
|
|
811
|
-
style: [
|
|
812
|
-
styles15.radio,
|
|
813
|
-
{
|
|
814
|
-
borderColor: selected ? colors.primary : colors.border,
|
|
815
|
-
opacity: option.disabled ? 0.45 : 1
|
|
816
|
-
}
|
|
817
|
-
]
|
|
818
|
-
},
|
|
819
|
-
selected ? /* @__PURE__ */ React23.createElement(View, { style: [styles15.dot, { backgroundColor: colors.primary }] }) : null
|
|
820
|
-
),
|
|
821
|
-
/* @__PURE__ */ React23.createElement(
|
|
822
|
-
Text,
|
|
823
|
-
{
|
|
824
|
-
style: [
|
|
825
|
-
styles15.label,
|
|
826
|
-
{ color: option.disabled ? colors.mutedForeground : colors.foreground }
|
|
827
|
-
]
|
|
828
|
-
},
|
|
829
|
-
option.label
|
|
830
|
-
)
|
|
831
|
-
);
|
|
832
|
-
})
|
|
833
|
-
);
|
|
908
|
+
key: option.value,
|
|
909
|
+
option,
|
|
910
|
+
selected: option.value === value,
|
|
911
|
+
onSelect: () => onValueChange?.(option.value)
|
|
912
|
+
}
|
|
913
|
+
)));
|
|
834
914
|
}
|
|
835
915
|
var styles15 = StyleSheet.create({
|
|
836
916
|
container: {
|
|
@@ -863,6 +943,44 @@ var styles15 = StyleSheet.create({
|
|
|
863
943
|
lineHeight: 20
|
|
864
944
|
}
|
|
865
945
|
});
|
|
946
|
+
function TabTrigger({
|
|
947
|
+
tab,
|
|
948
|
+
isActive,
|
|
949
|
+
onPress,
|
|
950
|
+
onLayout
|
|
951
|
+
}) {
|
|
952
|
+
const { colors } = useTheme();
|
|
953
|
+
const scale = useRef(new Animated.Value(1)).current;
|
|
954
|
+
const handlePressIn = () => {
|
|
955
|
+
Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
|
|
956
|
+
};
|
|
957
|
+
const handlePressOut = () => {
|
|
958
|
+
Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
|
|
959
|
+
};
|
|
960
|
+
return /* @__PURE__ */ React23.createElement(
|
|
961
|
+
TouchableOpacity,
|
|
962
|
+
{
|
|
963
|
+
style: styles16.trigger,
|
|
964
|
+
onPress,
|
|
965
|
+
onPressIn: handlePressIn,
|
|
966
|
+
onPressOut: handlePressOut,
|
|
967
|
+
onLayout,
|
|
968
|
+
activeOpacity: 1,
|
|
969
|
+
touchSoundDisabled: true
|
|
970
|
+
},
|
|
971
|
+
/* @__PURE__ */ React23.createElement(Animated.View, { style: { transform: [{ scale }] } }, /* @__PURE__ */ React23.createElement(
|
|
972
|
+
Text,
|
|
973
|
+
{
|
|
974
|
+
style: [
|
|
975
|
+
styles16.triggerLabel,
|
|
976
|
+
{ color: isActive ? colors.foreground : colors.mutedForeground },
|
|
977
|
+
isActive && styles16.activeTriggerLabel
|
|
978
|
+
]
|
|
979
|
+
},
|
|
980
|
+
tab.label
|
|
981
|
+
))
|
|
982
|
+
);
|
|
983
|
+
}
|
|
866
984
|
function Tabs({ tabs, value, onValueChange, children, style }) {
|
|
867
985
|
const [internal, setInternal] = useState(tabs[0]?.value ?? "");
|
|
868
986
|
const { colors } = useTheme();
|
|
@@ -876,8 +994,18 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
|
|
|
876
994
|
if (!layout) return;
|
|
877
995
|
if (animate) {
|
|
878
996
|
Animated.parallel([
|
|
879
|
-
Animated.spring(pillX, {
|
|
880
|
-
|
|
997
|
+
Animated.spring(pillX, {
|
|
998
|
+
toValue: layout.x,
|
|
999
|
+
useNativeDriver: false,
|
|
1000
|
+
speed: 20,
|
|
1001
|
+
bounciness: 0
|
|
1002
|
+
}),
|
|
1003
|
+
Animated.spring(pillWidth, {
|
|
1004
|
+
toValue: layout.width,
|
|
1005
|
+
useNativeDriver: false,
|
|
1006
|
+
speed: 20,
|
|
1007
|
+
bounciness: 0
|
|
1008
|
+
})
|
|
881
1009
|
]).start();
|
|
882
1010
|
} else {
|
|
883
1011
|
pillX.setValue(layout.x);
|
|
@@ -890,6 +1018,7 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
|
|
|
890
1018
|
}
|
|
891
1019
|
}, [active]);
|
|
892
1020
|
const handlePress = (v) => {
|
|
1021
|
+
Haptics11.selectionAsync();
|
|
893
1022
|
if (!value) setInternal(v);
|
|
894
1023
|
onValueChange?.(v);
|
|
895
1024
|
};
|
|
@@ -914,37 +1043,23 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
|
|
|
914
1043
|
}
|
|
915
1044
|
]
|
|
916
1045
|
}
|
|
917
|
-
), tabs.map((tab) =>
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
animatePill(tab.value, false);
|
|
931
|
-
initialised.current = true;
|
|
932
|
-
}
|
|
1046
|
+
), tabs.map((tab) => /* @__PURE__ */ React23.createElement(
|
|
1047
|
+
TabTrigger,
|
|
1048
|
+
{
|
|
1049
|
+
key: tab.value,
|
|
1050
|
+
tab,
|
|
1051
|
+
isActive: tab.value === active,
|
|
1052
|
+
onPress: () => handlePress(tab.value),
|
|
1053
|
+
onLayout: (e) => {
|
|
1054
|
+
const { x, width } = e.nativeEvent.layout;
|
|
1055
|
+
tabLayouts.current[tab.value] = { x, width };
|
|
1056
|
+
if (tab.value === active) {
|
|
1057
|
+
animatePill(tab.value, false);
|
|
1058
|
+
initialised.current = true;
|
|
933
1059
|
}
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
{
|
|
938
|
-
style: [
|
|
939
|
-
styles16.triggerLabel,
|
|
940
|
-
{ color: isActive ? colors.foreground : colors.mutedForeground },
|
|
941
|
-
isActive && styles16.activeTriggerLabel
|
|
942
|
-
]
|
|
943
|
-
},
|
|
944
|
-
tab.label
|
|
945
|
-
)
|
|
946
|
-
);
|
|
947
|
-
})), children);
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
))), children);
|
|
948
1063
|
}
|
|
949
1064
|
function TabsContent({ value, activeValue, children, style }) {
|
|
950
1065
|
if (value !== activeValue) return null;
|
|
@@ -964,6 +1079,7 @@ var styles16 = StyleSheet.create({
|
|
|
964
1079
|
paddingHorizontal: 12,
|
|
965
1080
|
borderRadius: 6,
|
|
966
1081
|
alignItems: "center",
|
|
1082
|
+
justifyContent: "center",
|
|
967
1083
|
zIndex: 1
|
|
968
1084
|
},
|
|
969
1085
|
triggerLabel: {
|
|
@@ -980,24 +1096,14 @@ function AccordionItemComponent({
|
|
|
980
1096
|
onToggle
|
|
981
1097
|
}) {
|
|
982
1098
|
const { colors } = useTheme();
|
|
983
|
-
const animatedHeight =
|
|
984
|
-
const animatedRotation =
|
|
1099
|
+
const animatedHeight = useSharedValue(0);
|
|
1100
|
+
const animatedRotation = useSharedValue(0);
|
|
985
1101
|
const contentHeight = useRef(0);
|
|
1102
|
+
const scale = useRef(new Animated.Value(1)).current;
|
|
986
1103
|
const toggle = (open) => {
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
duration: 220,
|
|
991
|
-
easing: open ? Easing.out(Easing.ease) : Easing.in(Easing.ease),
|
|
992
|
-
useNativeDriver: false
|
|
993
|
-
}),
|
|
994
|
-
Animated.timing(animatedRotation, {
|
|
995
|
-
toValue: open ? 1 : 0,
|
|
996
|
-
duration: 220,
|
|
997
|
-
easing: open ? Easing.out(Easing.ease) : Easing.in(Easing.ease),
|
|
998
|
-
useNativeDriver: true
|
|
999
|
-
})
|
|
1000
|
-
]).start();
|
|
1104
|
+
const easing = open ? Easing.out(Easing.ease) : Easing.in(Easing.ease);
|
|
1105
|
+
animatedHeight.value = withTiming(open ? contentHeight.current : 0, { duration: 220, easing });
|
|
1106
|
+
animatedRotation.value = withTiming(open ? 1 : 0, { duration: 220, easing });
|
|
1001
1107
|
};
|
|
1002
1108
|
React23.useEffect(() => {
|
|
1003
1109
|
toggle(isOpen);
|
|
@@ -1005,32 +1111,44 @@ function AccordionItemComponent({
|
|
|
1005
1111
|
const onLayout = (e) => {
|
|
1006
1112
|
if (contentHeight.current === 0) {
|
|
1007
1113
|
contentHeight.current = e.nativeEvent.layout.height;
|
|
1008
|
-
if (isOpen) animatedHeight.
|
|
1114
|
+
if (isOpen) animatedHeight.value = contentHeight.current;
|
|
1009
1115
|
}
|
|
1010
1116
|
};
|
|
1011
|
-
const
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
});
|
|
1015
|
-
|
|
1117
|
+
const heightStyle = useAnimatedStyle(() => ({
|
|
1118
|
+
height: animatedHeight.value,
|
|
1119
|
+
overflow: "hidden"
|
|
1120
|
+
}));
|
|
1121
|
+
const rotationStyle = useAnimatedStyle(() => ({
|
|
1122
|
+
transform: [{ rotate: `${animatedRotation.value * 180}deg` }]
|
|
1123
|
+
}));
|
|
1124
|
+
const handlePressIn = () => {
|
|
1125
|
+
Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
|
|
1126
|
+
};
|
|
1127
|
+
const handlePressOut = () => {
|
|
1128
|
+
Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
|
|
1129
|
+
};
|
|
1130
|
+
return /* @__PURE__ */ React23.createElement(View, { style: [styles17.item, { borderBottomColor: colors.border }] }, /* @__PURE__ */ React23.createElement(Animated.View, { style: { transform: [{ scale }] } }, /* @__PURE__ */ React23.createElement(
|
|
1016
1131
|
TouchableOpacity,
|
|
1017
1132
|
{
|
|
1018
1133
|
style: styles17.trigger,
|
|
1019
1134
|
onPress: () => {
|
|
1020
|
-
|
|
1135
|
+
Haptics11.selectionAsync();
|
|
1021
1136
|
onToggle();
|
|
1022
1137
|
},
|
|
1023
|
-
|
|
1138
|
+
onPressIn: handlePressIn,
|
|
1139
|
+
onPressOut: handlePressOut,
|
|
1140
|
+
activeOpacity: 1,
|
|
1141
|
+
touchSoundDisabled: true
|
|
1024
1142
|
},
|
|
1025
1143
|
/* @__PURE__ */ React23.createElement(Text, { style: [styles17.triggerText, { color: colors.foreground }] }, item.trigger),
|
|
1026
1144
|
/* @__PURE__ */ React23.createElement(
|
|
1027
|
-
|
|
1145
|
+
ReanimatedAnimated.Text,
|
|
1028
1146
|
{
|
|
1029
|
-
style: [styles17.chevron, { color: colors.foreground
|
|
1147
|
+
style: [styles17.chevron, { color: colors.foreground }, rotationStyle]
|
|
1030
1148
|
},
|
|
1031
1149
|
"\u25BE"
|
|
1032
1150
|
)
|
|
1033
|
-
), /* @__PURE__ */ React23.createElement(
|
|
1151
|
+
)), /* @__PURE__ */ React23.createElement(ReanimatedAnimated.View, { style: heightStyle }, /* @__PURE__ */ React23.createElement(View, { style: styles17.content, onLayout }, item.content)));
|
|
1034
1152
|
}
|
|
1035
1153
|
function Accordion({ items, type = "single", defaultValue, style }) {
|
|
1036
1154
|
const [openValues, setOpenValues] = useState(() => {
|
|
@@ -1075,7 +1193,6 @@ var styles17 = StyleSheet.create({
|
|
|
1075
1193
|
fontSize: 16,
|
|
1076
1194
|
marginLeft: 8
|
|
1077
1195
|
},
|
|
1078
|
-
contentWrapper: {},
|
|
1079
1196
|
content: {
|
|
1080
1197
|
paddingBottom: 16,
|
|
1081
1198
|
position: "absolute",
|
|
@@ -1122,7 +1239,7 @@ function Slider({
|
|
|
1122
1239
|
const newValue = xToValue(x);
|
|
1123
1240
|
if (newValue !== lastSteppedValue.current) {
|
|
1124
1241
|
lastSteppedValue.current = newValue;
|
|
1125
|
-
|
|
1242
|
+
Haptics11.selectionAsync();
|
|
1126
1243
|
}
|
|
1127
1244
|
setInternalValue(newValue);
|
|
1128
1245
|
onValueChange?.(newValue);
|
|
@@ -1149,10 +1266,7 @@ function Slider({
|
|
|
1149
1266
|
/* @__PURE__ */ React23.createElement(View, { style: [styles18.track, { backgroundColor: colors.muted }] }, /* @__PURE__ */ React23.createElement(
|
|
1150
1267
|
View,
|
|
1151
1268
|
{
|
|
1152
|
-
style: [
|
|
1153
|
-
styles18.range,
|
|
1154
|
-
{ width: `${percent}%`, backgroundColor: colors.primary }
|
|
1155
|
-
]
|
|
1269
|
+
style: [styles18.range, { width: `${percent}%`, backgroundColor: colors.primary }]
|
|
1156
1270
|
}
|
|
1157
1271
|
)),
|
|
1158
1272
|
/* @__PURE__ */ React23.createElement(
|
|
@@ -1217,7 +1331,7 @@ function Sheet({
|
|
|
1217
1331
|
const ref = useRef(null);
|
|
1218
1332
|
useEffect(() => {
|
|
1219
1333
|
if (open) {
|
|
1220
|
-
|
|
1334
|
+
Haptics11.impactAsync(Haptics11.ImpactFeedbackStyle.Light);
|
|
1221
1335
|
ref.current?.present();
|
|
1222
1336
|
} else {
|
|
1223
1337
|
ref.current?.dismiss();
|
|
@@ -1284,26 +1398,49 @@ function Select({
|
|
|
1284
1398
|
style
|
|
1285
1399
|
}) {
|
|
1286
1400
|
const { colors } = useTheme();
|
|
1287
|
-
const
|
|
1401
|
+
const bottomSheetRef = useRef(null);
|
|
1402
|
+
const scale = useRef(new Animated.Value(1)).current;
|
|
1288
1403
|
const selected = options.find((o) => o.value === value);
|
|
1289
|
-
|
|
1404
|
+
const handlePressIn = () => {
|
|
1405
|
+
if (disabled) return;
|
|
1406
|
+
Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
|
|
1407
|
+
};
|
|
1408
|
+
const handlePressOut = () => {
|
|
1409
|
+
Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
|
|
1410
|
+
};
|
|
1411
|
+
const handleOpen = () => {
|
|
1412
|
+
if (!disabled) {
|
|
1413
|
+
Haptics11.selectionAsync();
|
|
1414
|
+
bottomSheetRef.current?.present();
|
|
1415
|
+
}
|
|
1416
|
+
};
|
|
1417
|
+
const renderBackdrop = useCallback(
|
|
1418
|
+
(props) => /* @__PURE__ */ React23.createElement(
|
|
1419
|
+
BottomSheetBackdrop,
|
|
1420
|
+
{
|
|
1421
|
+
...props,
|
|
1422
|
+
disappearsOnIndex: -1,
|
|
1423
|
+
appearsOnIndex: 0,
|
|
1424
|
+
pressBehavior: "close"
|
|
1425
|
+
}
|
|
1426
|
+
),
|
|
1427
|
+
[]
|
|
1428
|
+
);
|
|
1429
|
+
return /* @__PURE__ */ React23.createElement(View, { style: [styles20.container, style] }, label ? /* @__PURE__ */ React23.createElement(Text, { style: [styles20.label, { color: colors.foreground }] }, label) : null, /* @__PURE__ */ React23.createElement(Animated.View, { style: { transform: [{ scale }], opacity: disabled ? 0.45 : 1 } }, /* @__PURE__ */ React23.createElement(
|
|
1290
1430
|
TouchableOpacity,
|
|
1291
1431
|
{
|
|
1292
1432
|
style: [
|
|
1293
1433
|
styles20.trigger,
|
|
1294
1434
|
{
|
|
1295
1435
|
borderColor: error ? colors.destructive : colors.border,
|
|
1296
|
-
backgroundColor: colors.background
|
|
1297
|
-
opacity: disabled ? 0.45 : 1
|
|
1436
|
+
backgroundColor: colors.background
|
|
1298
1437
|
}
|
|
1299
1438
|
],
|
|
1300
|
-
onPress:
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
},
|
|
1306
|
-
activeOpacity: 0.7
|
|
1439
|
+
onPress: handleOpen,
|
|
1440
|
+
onPressIn: handlePressIn,
|
|
1441
|
+
onPressOut: handlePressOut,
|
|
1442
|
+
activeOpacity: 1,
|
|
1443
|
+
touchSoundDisabled: true
|
|
1307
1444
|
},
|
|
1308
1445
|
/* @__PURE__ */ React23.createElement(
|
|
1309
1446
|
Text,
|
|
@@ -1317,46 +1454,52 @@ function Select({
|
|
|
1317
1454
|
selected?.label ?? placeholder
|
|
1318
1455
|
),
|
|
1319
1456
|
/* @__PURE__ */ React23.createElement(Text, { style: [styles20.chevron, { color: colors.mutedForeground }] }, "\u25BE")
|
|
1320
|
-
), error ? /* @__PURE__ */ React23.createElement(Text, { style: [styles20.helperText, { color: colors.destructive }] }, error) : null, /* @__PURE__ */ React23.createElement(
|
|
1321
|
-
|
|
1457
|
+
)), error ? /* @__PURE__ */ React23.createElement(Text, { style: [styles20.helperText, { color: colors.destructive }] }, error) : null, /* @__PURE__ */ React23.createElement(
|
|
1458
|
+
BottomSheetModal,
|
|
1322
1459
|
{
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1460
|
+
ref: bottomSheetRef,
|
|
1461
|
+
enableDynamicSizing: true,
|
|
1462
|
+
enablePanDownToClose: true,
|
|
1463
|
+
backdropComponent: renderBackdrop,
|
|
1464
|
+
backgroundStyle: [styles20.sheetBackground, { backgroundColor: colors.card }],
|
|
1465
|
+
handleIndicatorStyle: [styles20.sheetHandle, { backgroundColor: colors.border }]
|
|
1466
|
+
},
|
|
1467
|
+
/* @__PURE__ */ React23.createElement(BottomSheetView, { style: styles20.sheetContent }, label ? /* @__PURE__ */ React23.createElement(Text, { style: [styles20.sheetTitle, { color: colors.foreground }] }, label) : null, options.map((item) => {
|
|
1468
|
+
const isSelected = item.value === value;
|
|
1469
|
+
return /* @__PURE__ */ React23.createElement(
|
|
1470
|
+
TouchableOpacity,
|
|
1471
|
+
{
|
|
1472
|
+
key: item.value,
|
|
1473
|
+
style: [
|
|
1474
|
+
styles20.option,
|
|
1475
|
+
isSelected && { backgroundColor: colors.accent },
|
|
1476
|
+
item.disabled && styles20.disabledOption
|
|
1477
|
+
],
|
|
1478
|
+
onPress: () => {
|
|
1479
|
+
if (!item.disabled) {
|
|
1480
|
+
Haptics11.selectionAsync();
|
|
1481
|
+
onValueChange?.(item.value);
|
|
1482
|
+
bottomSheetRef.current?.dismiss();
|
|
1483
|
+
}
|
|
1484
|
+
},
|
|
1485
|
+
activeOpacity: 0.7,
|
|
1486
|
+
touchSoundDisabled: true
|
|
1487
|
+
},
|
|
1488
|
+
/* @__PURE__ */ React23.createElement(
|
|
1489
|
+
Text,
|
|
1329
1490
|
{
|
|
1330
1491
|
style: [
|
|
1331
|
-
styles20.
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
]
|
|
1335
|
-
onPress: () => {
|
|
1336
|
-
if (!item.disabled) {
|
|
1337
|
-
Haptics10.selectionAsync();
|
|
1338
|
-
onValueChange?.(item.value);
|
|
1339
|
-
setOpen(false);
|
|
1340
|
-
}
|
|
1341
|
-
},
|
|
1342
|
-
activeOpacity: 0.7
|
|
1492
|
+
styles20.optionText,
|
|
1493
|
+
{ color: item.disabled ? colors.mutedForeground : colors.foreground },
|
|
1494
|
+
isSelected && { fontWeight: "500" }
|
|
1495
|
+
]
|
|
1343
1496
|
},
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
isSelected && { fontWeight: "500" }
|
|
1351
|
-
]
|
|
1352
|
-
},
|
|
1353
|
-
item.label
|
|
1354
|
-
),
|
|
1355
|
-
isSelected ? /* @__PURE__ */ React23.createElement(Text, { style: [styles20.checkmark, { color: colors.primary }] }, "\u2713") : null
|
|
1356
|
-
);
|
|
1357
|
-
}
|
|
1358
|
-
}
|
|
1359
|
-
)))));
|
|
1497
|
+
item.label
|
|
1498
|
+
),
|
|
1499
|
+
isSelected ? /* @__PURE__ */ React23.createElement(Text, { style: [styles20.checkmark, { color: colors.primary }] }, "\u2713") : null
|
|
1500
|
+
);
|
|
1501
|
+
}))
|
|
1502
|
+
));
|
|
1360
1503
|
}
|
|
1361
1504
|
var styles20 = StyleSheet.create({
|
|
1362
1505
|
container: {
|
|
@@ -1387,34 +1530,44 @@ var styles20 = StyleSheet.create({
|
|
|
1387
1530
|
helperText: {
|
|
1388
1531
|
fontSize: 12
|
|
1389
1532
|
},
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
justifyContent: "center",
|
|
1394
|
-
padding: 24
|
|
1533
|
+
sheetBackground: {
|
|
1534
|
+
borderTopLeftRadius: 16,
|
|
1535
|
+
borderTopRightRadius: 16
|
|
1395
1536
|
},
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1537
|
+
sheetHandle: {
|
|
1538
|
+
width: 36,
|
|
1539
|
+
height: 4,
|
|
1540
|
+
borderRadius: 2
|
|
1541
|
+
},
|
|
1542
|
+
sheetContent: {
|
|
1543
|
+
paddingHorizontal: 16,
|
|
1544
|
+
paddingBottom: 32
|
|
1545
|
+
},
|
|
1546
|
+
sheetTitle: {
|
|
1547
|
+
fontSize: 16,
|
|
1548
|
+
fontWeight: "600",
|
|
1549
|
+
paddingVertical: 12,
|
|
1550
|
+
paddingHorizontal: 4
|
|
1401
1551
|
},
|
|
1402
1552
|
option: {
|
|
1403
1553
|
flexDirection: "row",
|
|
1404
1554
|
alignItems: "center",
|
|
1405
1555
|
justifyContent: "space-between",
|
|
1406
1556
|
paddingHorizontal: 12,
|
|
1407
|
-
paddingVertical:
|
|
1557
|
+
paddingVertical: 14,
|
|
1558
|
+
borderRadius: 8
|
|
1408
1559
|
},
|
|
1409
1560
|
optionText: {
|
|
1410
|
-
fontSize: 15
|
|
1561
|
+
fontSize: 15,
|
|
1562
|
+
flex: 1
|
|
1411
1563
|
},
|
|
1412
1564
|
disabledOption: {
|
|
1413
1565
|
opacity: 0.45
|
|
1414
1566
|
},
|
|
1415
1567
|
checkmark: {
|
|
1416
1568
|
fontSize: 14,
|
|
1417
|
-
fontWeight: "600"
|
|
1569
|
+
fontWeight: "600",
|
|
1570
|
+
marginLeft: 8
|
|
1418
1571
|
}
|
|
1419
1572
|
});
|
|
1420
1573
|
var ToastContext = createContext({
|
|
@@ -1426,41 +1579,53 @@ var ToastContext = createContext({
|
|
|
1426
1579
|
function useToast() {
|
|
1427
1580
|
return useContext(ToastContext);
|
|
1428
1581
|
}
|
|
1582
|
+
var SWIPE_THRESHOLD = 80;
|
|
1583
|
+
var VELOCITY_THRESHOLD = 800;
|
|
1429
1584
|
function ToastNotification({ item, onDismiss }) {
|
|
1430
1585
|
const { colors } = useTheme();
|
|
1431
|
-
const translateY =
|
|
1432
|
-
const
|
|
1586
|
+
const translateY = useSharedValue(-80);
|
|
1587
|
+
const translateX = useSharedValue(0);
|
|
1588
|
+
const opacity = useSharedValue(0);
|
|
1433
1589
|
useEffect(() => {
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
Animated.timing(opacity, { toValue: 1, duration: 200, useNativeDriver: true })
|
|
1437
|
-
]).start();
|
|
1590
|
+
translateY.value = withTiming(0, { duration: 120, easing: Easing.out(Easing.exp) });
|
|
1591
|
+
opacity.value = withTiming(1, { duration: 100 });
|
|
1438
1592
|
const timer = setTimeout(() => {
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1593
|
+
translateY.value = withTiming(-80, { duration: 200 });
|
|
1594
|
+
opacity.value = withTiming(0, { duration: 200 }, (done) => {
|
|
1595
|
+
if (done) runOnJS(onDismiss)();
|
|
1596
|
+
});
|
|
1443
1597
|
}, item.duration ?? 3e3);
|
|
1444
1598
|
return () => clearTimeout(timer);
|
|
1445
1599
|
}, []);
|
|
1600
|
+
const panGesture = Gesture.Pan().onUpdate((e) => {
|
|
1601
|
+
translateX.value = e.translationX;
|
|
1602
|
+
}).onEnd((e) => {
|
|
1603
|
+
const shouldDismiss = Math.abs(translateX.value) > SWIPE_THRESHOLD || Math.abs(e.velocityX) > VELOCITY_THRESHOLD;
|
|
1604
|
+
if (shouldDismiss) {
|
|
1605
|
+
const direction = translateX.value > 0 ? 1 : -1;
|
|
1606
|
+
translateX.value = withTiming(direction * 500, { duration: 200 }, (done) => {
|
|
1607
|
+
if (done) runOnJS(onDismiss)();
|
|
1608
|
+
});
|
|
1609
|
+
opacity.value = withTiming(0, { duration: 150 });
|
|
1610
|
+
} else {
|
|
1611
|
+
translateX.value = withSpring(0, { damping: 20, stiffness: 300 });
|
|
1612
|
+
}
|
|
1613
|
+
});
|
|
1614
|
+
const animatedStyle = useAnimatedStyle(() => ({
|
|
1615
|
+
opacity: opacity.value,
|
|
1616
|
+
transform: [{ translateY: translateY.value }, { translateX: translateX.value }]
|
|
1617
|
+
}));
|
|
1446
1618
|
const bgColor = {
|
|
1447
1619
|
default: colors.foreground,
|
|
1448
1620
|
destructive: colors.destructive,
|
|
1449
|
-
success:
|
|
1621
|
+
success: colors.success
|
|
1450
1622
|
}[item.variant ?? "default"];
|
|
1451
1623
|
const textColor = {
|
|
1452
1624
|
default: colors.background,
|
|
1453
1625
|
destructive: colors.destructiveForeground,
|
|
1454
|
-
success:
|
|
1626
|
+
success: colors.successForeground
|
|
1455
1627
|
}[item.variant ?? "default"];
|
|
1456
|
-
return /* @__PURE__ */ React23.createElement(
|
|
1457
|
-
Animated.View,
|
|
1458
|
-
{
|
|
1459
|
-
style: [styles21.toast, { backgroundColor: bgColor, opacity, transform: [{ translateY }] }]
|
|
1460
|
-
},
|
|
1461
|
-
/* @__PURE__ */ React23.createElement(View, { style: styles21.toastContent }, item.title ? /* @__PURE__ */ React23.createElement(Text, { style: [styles21.toastTitle, { color: textColor }] }, item.title) : null, item.description ? /* @__PURE__ */ React23.createElement(Text, { style: [styles21.toastDescription, { color: textColor, opacity: 0.85 }] }, item.description) : null),
|
|
1462
|
-
/* @__PURE__ */ React23.createElement(TouchableOpacity, { onPress: onDismiss, style: styles21.dismissButton }, /* @__PURE__ */ React23.createElement(Text, { style: [styles21.dismissIcon, { color: textColor }] }, "\u2715"))
|
|
1463
|
-
);
|
|
1628
|
+
return /* @__PURE__ */ React23.createElement(GestureDetector, { gesture: panGesture }, /* @__PURE__ */ React23.createElement(ReanimatedAnimated.View, { style: [styles21.toast, { backgroundColor: bgColor }, animatedStyle] }, /* @__PURE__ */ React23.createElement(View, { style: styles21.toastContent }, item.title ? /* @__PURE__ */ React23.createElement(Text, { style: [styles21.toastTitle, { color: textColor }] }, item.title) : null, item.description ? /* @__PURE__ */ React23.createElement(Text, { style: [styles21.toastDescription, { color: textColor, opacity: 0.85 }] }, item.description) : null), /* @__PURE__ */ React23.createElement(TouchableOpacity, { onPress: onDismiss, style: styles21.dismissButton, touchSoundDisabled: true }, /* @__PURE__ */ React23.createElement(Text, { style: [styles21.dismissIcon, { color: textColor }] }, "\u2715"))));
|
|
1464
1629
|
}
|
|
1465
1630
|
function ToastProvider({ children }) {
|
|
1466
1631
|
const [toasts, setToasts] = useState([]);
|
|
@@ -1468,11 +1633,11 @@ function ToastProvider({ children }) {
|
|
|
1468
1633
|
const toast = useCallback((item) => {
|
|
1469
1634
|
const id = Math.random().toString(36).slice(2);
|
|
1470
1635
|
if (item.variant === "success") {
|
|
1471
|
-
|
|
1636
|
+
Haptics11.notificationAsync(Haptics11.NotificationFeedbackType.Success);
|
|
1472
1637
|
} else if (item.variant === "destructive") {
|
|
1473
|
-
|
|
1638
|
+
Haptics11.notificationAsync(Haptics11.NotificationFeedbackType.Error);
|
|
1474
1639
|
} else {
|
|
1475
|
-
|
|
1640
|
+
Haptics11.impactAsync(Haptics11.ImpactFeedbackStyle.Light);
|
|
1476
1641
|
}
|
|
1477
1642
|
setToasts((prev) => [{ ...item, id }, ...prev].slice(0, 3));
|
|
1478
1643
|
}, []);
|
|
@@ -1513,8 +1678,8 @@ var styles21 = StyleSheet.create({
|
|
|
1513
1678
|
fontSize: 13
|
|
1514
1679
|
},
|
|
1515
1680
|
dismissButton: {
|
|
1516
|
-
padding:
|
|
1517
|
-
marginLeft:
|
|
1681
|
+
padding: 12,
|
|
1682
|
+
marginLeft: 4
|
|
1518
1683
|
},
|
|
1519
1684
|
dismissIcon: {
|
|
1520
1685
|
fontSize: 12
|