@retray-dev/ui-kit 9.1.0 → 9.3.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 +166 -4
- package/CONSUMER.md +247 -0
- package/DESIGN.md +668 -0
- package/FONTS.md +107 -0
- package/README.md +3 -3
- package/dist/AlertBanner.d.mts +3 -1
- package/dist/AlertBanner.d.ts +3 -1
- package/dist/AlertBanner.js +18 -2
- package/dist/AlertBanner.mjs +1 -1
- package/dist/ConfirmDialog.d.mts +3 -1
- package/dist/ConfirmDialog.d.ts +3 -1
- package/dist/ConfirmDialog.js +3 -0
- package/dist/ConfirmDialog.mjs +1 -1
- package/dist/CurrencyInput.d.mts +3 -1
- package/dist/CurrencyInput.d.ts +3 -1
- package/dist/CurrencyInput.js +52 -39
- package/dist/CurrencyInput.mjs +2 -3
- package/dist/ImageUpload.d.mts +27 -0
- package/dist/ImageUpload.d.ts +27 -0
- package/dist/ImageUpload.js +399 -0
- package/dist/ImageUpload.mjs +9 -0
- package/dist/Input.d.mts +3 -1
- package/dist/Input.d.ts +3 -1
- package/dist/Input.js +48 -37
- package/dist/Input.mjs +1 -2
- package/dist/ListItem.d.mts +9 -2
- package/dist/ListItem.d.ts +9 -2
- package/dist/ListItem.js +9 -2
- package/dist/ListItem.mjs +1 -1
- package/dist/SheetSelect.d.mts +25 -0
- package/dist/SheetSelect.d.ts +25 -0
- package/dist/SheetSelect.js +440 -0
- package/dist/SheetSelect.mjs +9 -0
- package/dist/Textarea.mjs +1 -2
- package/dist/{chunk-M6ZXVBTK.mjs → chunk-6MKGPAR2.mjs} +21 -5
- package/dist/{chunk-EH745HE5.mjs → chunk-CZCQZHG6.mjs} +13 -4
- package/dist/{chunk-7QHVVCB3.mjs → chunk-FZZLPJ6B.mjs} +3 -0
- package/dist/{chunk-MAC465BB.mjs → chunk-JUXSWN54.mjs} +5 -3
- package/dist/{chunk-BNP626TY.mjs → chunk-OHBNABL5.mjs} +10 -3
- package/dist/chunk-URI2WBIV.mjs +147 -0
- package/dist/chunk-Y4GL2MHX.mjs +112 -0
- package/dist/{chunk-756RAKE4.mjs → chunk-ZUR7AU5R.mjs} +38 -20
- package/dist/fonts.d.mts +32 -0
- package/dist/fonts.d.ts +32 -0
- package/dist/fonts.js +44 -0
- package/dist/fonts.mjs +37 -0
- package/dist/index.d.mts +26 -1
- package/dist/index.d.ts +26 -1
- package/dist/index.js +425 -106
- package/dist/index.mjs +55 -17
- package/package.json +23 -6
- package/src/components/AlertBanner/AlertBanner.tsx +21 -3
- package/src/components/ConfirmDialog/ConfirmDialog.tsx +5 -0
- package/src/components/CurrencyInput/CurrencyInput.tsx +4 -0
- package/src/components/ImageUpload/ImageUpload.tsx +158 -0
- package/src/components/ImageUpload/index.ts +1 -0
- package/src/components/Input/Input.tsx +64 -53
- package/src/components/ListItem/ListItem.tsx +23 -4
- package/src/components/SheetSelect/SheetSelect.tsx +192 -0
- package/src/components/SheetSelect/index.ts +1 -0
- package/src/fonts.ts +30 -29
- package/src/hooks/useConfirmDialog.ts +67 -0
- package/src/index.ts +6 -0
- package/dist/chunk-26BCI223.mjs +0 -14
package/dist/index.js
CHANGED
|
@@ -10,13 +10,13 @@ var FontAwesome5 = require('@expo/vector-icons/FontAwesome5');
|
|
|
10
10
|
var MaterialIcons = require('@expo/vector-icons/MaterialIcons');
|
|
11
11
|
var Ionicons = require('@expo/vector-icons/Ionicons');
|
|
12
12
|
var pressto = require('pressto');
|
|
13
|
-
var
|
|
13
|
+
var Animated12 = require('react-native-reanimated');
|
|
14
14
|
var expoFont = require('expo-font');
|
|
15
|
+
var bottomSheet = require('@gorhom/bottom-sheet');
|
|
16
|
+
var reactNativeEase = require('react-native-ease');
|
|
15
17
|
var vectorIcons = require('@expo/vector-icons');
|
|
16
18
|
var expoLinearGradient = require('expo-linear-gradient');
|
|
17
|
-
var reactNativeEase = require('react-native-ease');
|
|
18
19
|
var RNSlider = require('@react-native-community/slider');
|
|
19
|
-
var bottomSheet = require('@gorhom/bottom-sheet');
|
|
20
20
|
var reactNativeSafeAreaContext = require('react-native-safe-area-context');
|
|
21
21
|
var picker = require('@react-native-picker/picker');
|
|
22
22
|
var sonnerNative = require('sonner-native');
|
|
@@ -31,7 +31,7 @@ var Feather__default = /*#__PURE__*/_interopDefault(Feather);
|
|
|
31
31
|
var FontAwesome5__default = /*#__PURE__*/_interopDefault(FontAwesome5);
|
|
32
32
|
var MaterialIcons__default = /*#__PURE__*/_interopDefault(MaterialIcons);
|
|
33
33
|
var Ionicons__default = /*#__PURE__*/_interopDefault(Ionicons);
|
|
34
|
-
var
|
|
34
|
+
var Animated12__default = /*#__PURE__*/_interopDefault(Animated12);
|
|
35
35
|
var RNSlider__default = /*#__PURE__*/_interopDefault(RNSlider);
|
|
36
36
|
|
|
37
37
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
@@ -611,11 +611,11 @@ var TIMINGS = {
|
|
|
611
611
|
};
|
|
612
612
|
var EASINGS = {
|
|
613
613
|
/** Material-style ease-out — natural deceleration for state changes. */
|
|
614
|
-
standard:
|
|
614
|
+
standard: Animated12.Easing.bezier(0.2, 0, 0, 1),
|
|
615
615
|
/** Strong ease-out for expanding surfaces (Accordion open). */
|
|
616
|
-
expand:
|
|
616
|
+
expand: Animated12.Easing.bezier(0.23, 1, 0.32, 1),
|
|
617
617
|
/** Quick ease-in for collapsing. */
|
|
618
|
-
collapse:
|
|
618
|
+
collapse: Animated12.Easing.in(Animated12.Easing.ease)
|
|
619
619
|
};
|
|
620
620
|
var COLOR_TRANSITION = {
|
|
621
621
|
type: "timing",
|
|
@@ -1000,24 +1000,11 @@ function TextBase({ variant = "body-md", color, style, children, ...props }) {
|
|
|
1000
1000
|
);
|
|
1001
1001
|
}
|
|
1002
1002
|
var Text3 = React25__default.default.memo(TextBase);
|
|
1003
|
-
function useColorTransition(active, options = {}) {
|
|
1004
|
-
const { duration = TIMINGS.state.duration } = options;
|
|
1005
|
-
const progress = Animated13.useSharedValue(active ? 1 : 0);
|
|
1006
|
-
React25.useEffect(() => {
|
|
1007
|
-
progress.value = Animated13.withTiming(active ? 1 : 0, { duration, easing: EASINGS.standard });
|
|
1008
|
-
}, [active, duration, progress]);
|
|
1009
|
-
return progress;
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
|
-
// src/components/Input/Input.tsx
|
|
1013
1003
|
var webInputResetStyle = reactNative.Platform.OS === "web" ? { outlineStyle: "none", outlineWidth: 0, outlineColor: "transparent", boxShadow: "none" } : {};
|
|
1014
|
-
function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suffixStyle, prefixIcon, suffixIcon, prefixIconColor, suffixIconColor, type = "text", containerStyle, inputWrapperStyle, style, onFocus, onBlur, secureTextEntry, editable, accessibilityLabel, ...props }) {
|
|
1004
|
+
function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suffixStyle, prefixIcon, suffixIcon, prefixIconColor, suffixIconColor, type = "text", containerStyle, inputWrapperStyle, sheetMode = false, style, onFocus, onBlur, secureTextEntry, editable, accessibilityLabel, ...props }) {
|
|
1015
1005
|
const { colors } = useTheme();
|
|
1016
1006
|
const [focused, setFocused] = React25.useState(false);
|
|
1017
1007
|
const [showPassword, setShowPassword] = React25.useState(false);
|
|
1018
|
-
const focusProgress = useColorTransition(focused, {
|
|
1019
|
-
duration: focused ? TIMINGS.focusIn.duration : TIMINGS.focusOut.duration
|
|
1020
|
-
});
|
|
1021
1008
|
const isDisabled = disabled || editable === false;
|
|
1022
1009
|
const isPassword = type === "password";
|
|
1023
1010
|
const effectiveSecure = isPassword ? !showPassword : secureTextEntry;
|
|
@@ -1033,22 +1020,45 @@ function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suff
|
|
|
1033
1020
|
},
|
|
1034
1021
|
/* @__PURE__ */ React25__default.default.createElement(vectorIcons.AntDesign, { name: showPassword ? "eye" : "eye-invisible", size: 20, color: colors.foregroundMuted })
|
|
1035
1022
|
) : suffixIcon ? renderIcon(suffixIcon, 20, suffixIconColor ?? colors.foregroundMuted) : suffix;
|
|
1036
|
-
const
|
|
1037
|
-
borderColor: error ? colors.destructive : Animated13.interpolateColor(focusProgress.value, [0, 1], [colors.border, colors.primary]),
|
|
1038
|
-
borderWidth: error ? 2 : Animated13.interpolate(focusProgress.value, [0, 1], [1, 2])
|
|
1039
|
-
}));
|
|
1023
|
+
const borderColor = error ? colors.destructive : focused ? colors.primary : colors.border;
|
|
1040
1024
|
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles4.container, isDisabled && styles4.containerDisabled, containerStyle] }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles4.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React25__default.default.createElement(
|
|
1041
|
-
|
|
1025
|
+
reactNativeEase.EaseView,
|
|
1042
1026
|
{
|
|
1043
1027
|
style: [
|
|
1044
1028
|
styles4.inputWrapper,
|
|
1045
1029
|
{ backgroundColor: isDisabled ? colors.surface : colors.background },
|
|
1030
|
+
error && styles4.inputWrapperError,
|
|
1046
1031
|
inputWrapperStyle
|
|
1047
|
-
]
|
|
1032
|
+
],
|
|
1033
|
+
animate: { borderColor },
|
|
1034
|
+
transition: COLOR_TRANSITION
|
|
1048
1035
|
},
|
|
1049
|
-
/* @__PURE__ */ React25__default.default.createElement(Animated13__default.default.View, { style: [styles4.borderOverlay, borderAnimStyle], pointerEvents: "none" }),
|
|
1050
1036
|
effectivePrefix ? typeof effectivePrefix === "string" ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles4.prefixText, { color: colors.foregroundMuted }, prefixStyle], allowFontScaling: true }, effectivePrefix) : /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles4.prefixContainer }, effectivePrefix) : null,
|
|
1051
|
-
/* @__PURE__ */ React25__default.default.createElement(
|
|
1037
|
+
sheetMode ? /* @__PURE__ */ React25__default.default.createElement(
|
|
1038
|
+
bottomSheet.BottomSheetTextInput,
|
|
1039
|
+
{
|
|
1040
|
+
style: [
|
|
1041
|
+
styles4.input,
|
|
1042
|
+
{ color: colors.foreground },
|
|
1043
|
+
webInputResetStyle,
|
|
1044
|
+
style
|
|
1045
|
+
],
|
|
1046
|
+
onFocus: (e) => {
|
|
1047
|
+
setFocused(true);
|
|
1048
|
+
onFocus?.(e);
|
|
1049
|
+
},
|
|
1050
|
+
onBlur: (e) => {
|
|
1051
|
+
setFocused(false);
|
|
1052
|
+
onBlur?.(e);
|
|
1053
|
+
},
|
|
1054
|
+
placeholderTextColor: colors.foregroundMuted,
|
|
1055
|
+
allowFontScaling: true,
|
|
1056
|
+
secureTextEntry: effectiveSecure,
|
|
1057
|
+
editable: isDisabled ? false : editable,
|
|
1058
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
1059
|
+
...props
|
|
1060
|
+
}
|
|
1061
|
+
) : /* @__PURE__ */ React25__default.default.createElement(
|
|
1052
1062
|
reactNative.TextInput,
|
|
1053
1063
|
{
|
|
1054
1064
|
style: [
|
|
@@ -1098,16 +1108,14 @@ var styles4 = reactNative.StyleSheet.create({
|
|
|
1098
1108
|
inputWrapper: {
|
|
1099
1109
|
flexDirection: "row",
|
|
1100
1110
|
alignItems: "center",
|
|
1101
|
-
// Border lives on borderOverlay (absolute) so its 1px→2px focus change
|
|
1102
|
-
// never resizes this box. Wrapper itself carries no border.
|
|
1103
1111
|
borderRadius: 8,
|
|
1112
|
+
borderWidth: 1,
|
|
1104
1113
|
paddingHorizontal: s(14),
|
|
1105
1114
|
paddingVertical: vs(11),
|
|
1106
1115
|
minHeight: 48
|
|
1107
1116
|
},
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
borderRadius: 8
|
|
1117
|
+
inputWrapperError: {
|
|
1118
|
+
borderWidth: 2
|
|
1111
1119
|
},
|
|
1112
1120
|
input: {
|
|
1113
1121
|
fontFamily: "Sohne-Regular",
|
|
@@ -1397,17 +1405,17 @@ function Skeleton({
|
|
|
1397
1405
|
style
|
|
1398
1406
|
}) {
|
|
1399
1407
|
const { colors, colorScheme } = useTheme();
|
|
1400
|
-
const shimmer =
|
|
1408
|
+
const shimmer = Animated12.useSharedValue(0);
|
|
1401
1409
|
const [containerWidth, setContainerWidth] = React25.useState(300);
|
|
1402
1410
|
const shimmerHighlight = colorScheme === "dark" ? "rgba(255,255,255,0.08)" : "rgba(255,255,255,0.7)";
|
|
1403
1411
|
React25.useEffect(() => {
|
|
1404
|
-
shimmer.value =
|
|
1405
|
-
|
|
1412
|
+
shimmer.value = Animated12.withRepeat(
|
|
1413
|
+
Animated12.withTiming(1, { duration: TIMINGS.shimmer.duration, easing: Animated12.Easing.linear }),
|
|
1406
1414
|
-1,
|
|
1407
1415
|
false
|
|
1408
1416
|
);
|
|
1409
1417
|
}, [shimmer]);
|
|
1410
|
-
const shimmerStyle =
|
|
1418
|
+
const shimmerStyle = Animated12.useAnimatedStyle(() => ({
|
|
1411
1419
|
transform: [{ translateX: -containerWidth + shimmer.value * (containerWidth * 2) }]
|
|
1412
1420
|
}));
|
|
1413
1421
|
const resolvedWidth = preset === "circle" ? s(diameter) : preset === "text" ? "60%" : width;
|
|
@@ -1426,7 +1434,7 @@ function Skeleton({
|
|
|
1426
1434
|
accessibilityLabel: "Loading",
|
|
1427
1435
|
accessibilityState: { busy: true }
|
|
1428
1436
|
},
|
|
1429
|
-
/* @__PURE__ */ React25__default.default.createElement(
|
|
1437
|
+
/* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [reactNative.StyleSheet.absoluteFill, shimmerStyle] }, /* @__PURE__ */ React25__default.default.createElement(
|
|
1430
1438
|
expoLinearGradient.LinearGradient,
|
|
1431
1439
|
{
|
|
1432
1440
|
colors: ["transparent", shimmerHighlight, "transparent"],
|
|
@@ -1604,7 +1612,7 @@ var styles10 = reactNative.StyleSheet.create({
|
|
|
1604
1612
|
right: 0
|
|
1605
1613
|
}
|
|
1606
1614
|
});
|
|
1607
|
-
function AlertBanner({ title, description, variant = "default", icon, iconName, iconColor, style }) {
|
|
1615
|
+
function AlertBanner({ title, description, variant = "default", icon, iconName, iconColor, onDismiss, style }) {
|
|
1608
1616
|
const { colors, colorScheme } = useTheme();
|
|
1609
1617
|
const isDark = colorScheme === "dark";
|
|
1610
1618
|
const accentColor = variant === "destructive" ? colors.destructive : variant === "success" ? colors.success : variant === "warning" ? colors.warning : colors.foreground;
|
|
@@ -1630,7 +1638,18 @@ function AlertBanner({ title, description, variant = "default", icon, iconName,
|
|
|
1630
1638
|
accessibilityLabel: a11yLabel
|
|
1631
1639
|
},
|
|
1632
1640
|
/* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles11.iconSlot }, effectiveIcon),
|
|
1633
|
-
/* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles11.content }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles11.title, { color: colors.foreground }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles11.description, { color: colors.foreground, opacity: 0.85 }], allowFontScaling: true }, description) : null)
|
|
1641
|
+
/* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles11.content }, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles11.title, { color: colors.foreground }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles11.description, { color: colors.foreground, opacity: 0.85 }], allowFontScaling: true }, description) : null),
|
|
1642
|
+
onDismiss ? /* @__PURE__ */ React25__default.default.createElement(
|
|
1643
|
+
reactNative.TouchableOpacity,
|
|
1644
|
+
{
|
|
1645
|
+
onPress: onDismiss,
|
|
1646
|
+
style: styles11.dismissButton,
|
|
1647
|
+
activeOpacity: 0.6,
|
|
1648
|
+
accessibilityRole: "button",
|
|
1649
|
+
accessibilityLabel: "Dismiss"
|
|
1650
|
+
},
|
|
1651
|
+
/* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "x", size: ms(16), color: colors.foregroundMuted })
|
|
1652
|
+
) : null
|
|
1634
1653
|
);
|
|
1635
1654
|
}
|
|
1636
1655
|
var styles11 = reactNative.StyleSheet.create({
|
|
@@ -1656,18 +1675,23 @@ var styles11 = reactNative.StyleSheet.create({
|
|
|
1656
1675
|
description: {
|
|
1657
1676
|
fontFamily: "Sohne-Regular",
|
|
1658
1677
|
fontSize: ms(12)
|
|
1678
|
+
},
|
|
1679
|
+
dismissButton: {
|
|
1680
|
+
padding: s(4),
|
|
1681
|
+
marginTop: vs(-2),
|
|
1682
|
+
marginRight: -s(4)
|
|
1659
1683
|
}
|
|
1660
1684
|
});
|
|
1661
1685
|
function Progress({ value = 0, max = 100, variant = "default", style, accessibilityLabel }) {
|
|
1662
1686
|
const { colors } = useTheme();
|
|
1663
1687
|
const percent = Math.min(Math.max(value / max * 100, 0), 100);
|
|
1664
1688
|
const [trackWidth, setTrackWidth] = React25.useState(0);
|
|
1665
|
-
const animatedWidth =
|
|
1689
|
+
const animatedWidth = Animated12.useSharedValue(0);
|
|
1666
1690
|
React25.useEffect(() => {
|
|
1667
1691
|
if (trackWidth === 0) return;
|
|
1668
|
-
animatedWidth.value =
|
|
1692
|
+
animatedWidth.value = Animated12.withSpring(percent / 100 * trackWidth, SPRINGS.glide);
|
|
1669
1693
|
}, [percent, trackWidth, animatedWidth]);
|
|
1670
|
-
const indicatorAnimatedStyle =
|
|
1694
|
+
const indicatorAnimatedStyle = Animated12.useAnimatedStyle(() => ({
|
|
1671
1695
|
width: animatedWidth.value
|
|
1672
1696
|
}));
|
|
1673
1697
|
const indicatorColor = variant === "success" ? colors.success : variant === "warning" ? colors.warning : variant === "destructive" ? colors.destructive : colors.primary;
|
|
@@ -1681,7 +1705,7 @@ function Progress({ value = 0, max = 100, variant = "default", style, accessibil
|
|
|
1681
1705
|
accessibilityValue: { min: 0, max: 100, now: Math.round(percent) }
|
|
1682
1706
|
},
|
|
1683
1707
|
/* @__PURE__ */ React25__default.default.createElement(
|
|
1684
|
-
|
|
1708
|
+
Animated12__default.default.View,
|
|
1685
1709
|
{
|
|
1686
1710
|
style: [styles12.indicator, { backgroundColor: indicatorColor }, indicatorAnimatedStyle]
|
|
1687
1711
|
}
|
|
@@ -1789,6 +1813,16 @@ var styles13 = reactNative.StyleSheet.create({
|
|
|
1789
1813
|
paddingHorizontal: s(32)
|
|
1790
1814
|
}
|
|
1791
1815
|
});
|
|
1816
|
+
function useColorTransition(active, options = {}) {
|
|
1817
|
+
const { duration = TIMINGS.state.duration } = options;
|
|
1818
|
+
const progress = Animated12.useSharedValue(active ? 1 : 0);
|
|
1819
|
+
React25.useEffect(() => {
|
|
1820
|
+
progress.value = Animated12.withTiming(active ? 1 : 0, { duration, easing: EASINGS.standard });
|
|
1821
|
+
}, [active, duration, progress]);
|
|
1822
|
+
return progress;
|
|
1823
|
+
}
|
|
1824
|
+
|
|
1825
|
+
// src/components/Textarea/Textarea.tsx
|
|
1792
1826
|
var webInputResetStyle2 = reactNative.Platform.OS === "web" ? { outlineStyle: "none", outlineWidth: 0, outlineColor: "transparent", boxShadow: "none" } : {};
|
|
1793
1827
|
function Textarea({
|
|
1794
1828
|
label,
|
|
@@ -1811,19 +1845,19 @@ function Textarea({
|
|
|
1811
1845
|
duration: focused ? TIMINGS.focusIn.duration : TIMINGS.focusOut.duration
|
|
1812
1846
|
});
|
|
1813
1847
|
const resolvedPrefixIcon = prefixIcon ? renderIcon(prefixIcon, ms(16), prefixIconColor ?? colors.foregroundMuted) : prefixIconNode;
|
|
1814
|
-
const borderAnimStyle =
|
|
1815
|
-
borderColor: error ? colors.destructive :
|
|
1816
|
-
borderWidth: error ? 2 :
|
|
1848
|
+
const borderAnimStyle = Animated12.useAnimatedStyle(() => ({
|
|
1849
|
+
borderColor: error ? colors.destructive : Animated12.interpolateColor(focusProgress.value, [0, 1], [colors.border, colors.primary]),
|
|
1850
|
+
borderWidth: error ? 2 : Animated12.interpolate(focusProgress.value, [0, 1], [1, 2])
|
|
1817
1851
|
}));
|
|
1818
1852
|
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles14.container, containerStyle] }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles14.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React25__default.default.createElement(
|
|
1819
|
-
|
|
1853
|
+
Animated12__default.default.View,
|
|
1820
1854
|
{
|
|
1821
1855
|
style: [
|
|
1822
1856
|
styles14.inputWrapper,
|
|
1823
1857
|
{ backgroundColor: colors.background }
|
|
1824
1858
|
]
|
|
1825
1859
|
},
|
|
1826
|
-
/* @__PURE__ */ React25__default.default.createElement(
|
|
1860
|
+
/* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [styles14.borderOverlay, borderAnimStyle], pointerEvents: "none" }),
|
|
1827
1861
|
resolvedPrefixIcon ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles14.prefixIcon }, resolvedPrefixIcon) : null,
|
|
1828
1862
|
/* @__PURE__ */ React25__default.default.createElement(
|
|
1829
1863
|
reactNative.TextInput,
|
|
@@ -2203,18 +2237,18 @@ function usePressScale({
|
|
|
2203
2237
|
pressOutSpring = SPRINGS.pressOut,
|
|
2204
2238
|
disabled = false
|
|
2205
2239
|
} = {}) {
|
|
2206
|
-
const scale2 =
|
|
2240
|
+
const scale2 = Animated12.useSharedValue(1);
|
|
2207
2241
|
const { hovered, hoverHandlers } = useHover();
|
|
2208
2242
|
const onPressIn = React25.useCallback(() => {
|
|
2209
2243
|
if (disabled) return;
|
|
2210
|
-
scale2.value =
|
|
2244
|
+
scale2.value = Animated12.withSpring(pressScale, pressInSpring);
|
|
2211
2245
|
}, [disabled, pressScale, pressInSpring, scale2]);
|
|
2212
2246
|
const onPressOut = React25.useCallback(() => {
|
|
2213
2247
|
if (disabled) return;
|
|
2214
|
-
scale2.value =
|
|
2248
|
+
scale2.value = Animated12.withSpring(1, pressOutSpring);
|
|
2215
2249
|
}, [disabled, pressOutSpring, scale2]);
|
|
2216
2250
|
const hoverActive = reactNative.Platform.OS === "web" && hovered && hoverScale !== 1 && !disabled;
|
|
2217
|
-
const animatedStyle =
|
|
2251
|
+
const animatedStyle = Animated12.useAnimatedStyle(() => ({
|
|
2218
2252
|
transform: [
|
|
2219
2253
|
{ scale: scale2.value * (hoverActive ? hoverScale : 1) }
|
|
2220
2254
|
]
|
|
@@ -2261,7 +2295,7 @@ function RadioItem({
|
|
|
2261
2295
|
accessibilityLabel: option.label,
|
|
2262
2296
|
accessibilityState: { checked: selected, disabled: !!option.disabled }
|
|
2263
2297
|
},
|
|
2264
|
-
/* @__PURE__ */ React25__default.default.createElement(
|
|
2298
|
+
/* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: scaleStyle }, /* @__PURE__ */ React25__default.default.createElement(
|
|
2265
2299
|
reactNativeEase.EaseView,
|
|
2266
2300
|
{
|
|
2267
2301
|
style: styles18.radio,
|
|
@@ -2396,15 +2430,15 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
|
|
|
2396
2430
|
const { colors } = useTheme();
|
|
2397
2431
|
const active = value ?? internal;
|
|
2398
2432
|
const tabLayouts = React25.useRef({});
|
|
2399
|
-
const pillX =
|
|
2400
|
-
const pillWidth =
|
|
2433
|
+
const pillX = Animated12.useSharedValue(0);
|
|
2434
|
+
const pillWidth = Animated12.useSharedValue(0);
|
|
2401
2435
|
const initialised = React25.useRef(false);
|
|
2402
2436
|
const animatePill = React25.useCallback((tabValue, animate) => {
|
|
2403
2437
|
const layout = tabLayouts.current[tabValue];
|
|
2404
2438
|
if (!layout) return;
|
|
2405
2439
|
if (animate) {
|
|
2406
|
-
pillX.value =
|
|
2407
|
-
pillWidth.value =
|
|
2440
|
+
pillX.value = Animated12.withSpring(layout.x, SPRINGS.glide);
|
|
2441
|
+
pillWidth.value = Animated12.withSpring(layout.width, SPRINGS.glide);
|
|
2408
2442
|
} else {
|
|
2409
2443
|
pillX.value = layout.x;
|
|
2410
2444
|
pillWidth.value = layout.width;
|
|
@@ -2418,7 +2452,7 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
|
|
|
2418
2452
|
if (!value) setInternal(v);
|
|
2419
2453
|
onValueChange?.(v);
|
|
2420
2454
|
};
|
|
2421
|
-
const pillAnimatedStyle =
|
|
2455
|
+
const pillAnimatedStyle = Animated12.useAnimatedStyle(() => ({
|
|
2422
2456
|
transform: [{ translateX: pillX.value }],
|
|
2423
2457
|
width: pillWidth.value
|
|
2424
2458
|
}));
|
|
@@ -2431,7 +2465,7 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
|
|
|
2431
2465
|
accessibilityRole: "tablist"
|
|
2432
2466
|
},
|
|
2433
2467
|
variant === "pill" && /* @__PURE__ */ React25__default.default.createElement(
|
|
2434
|
-
|
|
2468
|
+
Animated12__default.default.View,
|
|
2435
2469
|
{
|
|
2436
2470
|
style: [
|
|
2437
2471
|
styles19.pill,
|
|
@@ -2533,28 +2567,28 @@ function AccordionItemComponent({
|
|
|
2533
2567
|
}) {
|
|
2534
2568
|
const { colors } = useTheme();
|
|
2535
2569
|
const resolvedIcon = item.iconName ? renderIcon(item.iconName, ms(16), item.iconColor ?? colors.foregroundMuted) : item.icon;
|
|
2536
|
-
const isExpanded =
|
|
2537
|
-
const height =
|
|
2570
|
+
const isExpanded = Animated12.useSharedValue(isOpen);
|
|
2571
|
+
const height = Animated12.useSharedValue(0);
|
|
2538
2572
|
React25__default.default.useEffect(() => {
|
|
2539
2573
|
isExpanded.value = isOpen;
|
|
2540
2574
|
}, [isOpen, isExpanded]);
|
|
2541
|
-
const derivedHeight =
|
|
2542
|
-
() =>
|
|
2575
|
+
const derivedHeight = Animated12.useDerivedValue(
|
|
2576
|
+
() => Animated12.withTiming(height.value * Number(isExpanded.value), {
|
|
2543
2577
|
duration: isExpanded.value ? TIMINGS.expand.duration : TIMINGS.collapse.duration,
|
|
2544
2578
|
easing: isExpanded.value ? EASINGS.expand : EASINGS.collapse
|
|
2545
2579
|
})
|
|
2546
2580
|
);
|
|
2547
|
-
const derivedRotation =
|
|
2548
|
-
() =>
|
|
2581
|
+
const derivedRotation = Animated12.useDerivedValue(
|
|
2582
|
+
() => Animated12.withTiming(isExpanded.value ? 1 : 0, {
|
|
2549
2583
|
duration: isExpanded.value ? TIMINGS.expand.duration : TIMINGS.collapse.duration,
|
|
2550
2584
|
easing: isExpanded.value ? EASINGS.expand : EASINGS.collapse
|
|
2551
2585
|
})
|
|
2552
2586
|
);
|
|
2553
|
-
const bodyStyle =
|
|
2587
|
+
const bodyStyle = Animated12.useAnimatedStyle(() => ({
|
|
2554
2588
|
height: derivedHeight.value,
|
|
2555
2589
|
overflow: "hidden"
|
|
2556
2590
|
}));
|
|
2557
|
-
const rotationStyle =
|
|
2591
|
+
const rotationStyle = Animated12.useAnimatedStyle(() => ({
|
|
2558
2592
|
transform: [{ rotate: `${derivedRotation.value * 180}deg` }]
|
|
2559
2593
|
}));
|
|
2560
2594
|
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles20.item, { backgroundColor: colors.card, borderColor: colors.border }] }, /* @__PURE__ */ React25__default.default.createElement(
|
|
@@ -2570,8 +2604,8 @@ function AccordionItemComponent({
|
|
|
2570
2604
|
accessibilityLabel: item.trigger
|
|
2571
2605
|
},
|
|
2572
2606
|
/* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles20.triggerContent }, resolvedIcon ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles20.icon }, resolvedIcon) : null, /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles20.triggerText, { color: colors.foreground }], allowFontScaling: true }, item.trigger)),
|
|
2573
|
-
/* @__PURE__ */ React25__default.default.createElement(
|
|
2574
|
-
), /* @__PURE__ */ React25__default.default.createElement(
|
|
2607
|
+
/* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [styles20.chevron, rotationStyle] }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Entypo, { name: "chevron-down", size: 18, color: colors.foregroundMuted }))
|
|
2608
|
+
), /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: bodyStyle }, /* @__PURE__ */ React25__default.default.createElement(
|
|
2575
2609
|
reactNative.View,
|
|
2576
2610
|
{
|
|
2577
2611
|
style: styles20.content,
|
|
@@ -3002,7 +3036,7 @@ function Select({
|
|
|
3002
3036
|
}
|
|
3003
3037
|
setPickerVisible(false);
|
|
3004
3038
|
};
|
|
3005
|
-
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles23.container, style] }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles23.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, !isWeb2 ? /* @__PURE__ */ React25__default.default.createElement(
|
|
3039
|
+
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles23.container, style] }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles23.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, !isWeb2 ? /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [animatedStyle, { opacity: disabled ? 0.45 : 1 }] }, /* @__PURE__ */ React25__default.default.createElement(
|
|
3006
3040
|
reactNative.TouchableOpacity,
|
|
3007
3041
|
{
|
|
3008
3042
|
style: [
|
|
@@ -3249,7 +3283,8 @@ function CurrencyInput({
|
|
|
3249
3283
|
placeholder,
|
|
3250
3284
|
editable,
|
|
3251
3285
|
containerStyle,
|
|
3252
|
-
style
|
|
3286
|
+
style,
|
|
3287
|
+
sheetMode
|
|
3253
3288
|
}) {
|
|
3254
3289
|
const handleChange = (text) => {
|
|
3255
3290
|
const withoutPrefix = prefix && text.startsWith(prefix) ? text.slice(prefix.length) : text;
|
|
@@ -3282,7 +3317,8 @@ function CurrencyInput({
|
|
|
3282
3317
|
prefixStyle,
|
|
3283
3318
|
containerStyle,
|
|
3284
3319
|
inputWrapperStyle: isLarge ? { paddingVertical: vs(16), minHeight: 72 } : void 0,
|
|
3285
|
-
style: [inputStyle, style]
|
|
3320
|
+
style: [inputStyle, style],
|
|
3321
|
+
sheetMode
|
|
3286
3322
|
}
|
|
3287
3323
|
);
|
|
3288
3324
|
}
|
|
@@ -3340,6 +3376,7 @@ var styles24 = reactNative.StyleSheet.create({
|
|
|
3340
3376
|
}
|
|
3341
3377
|
});
|
|
3342
3378
|
function ListItemBase({
|
|
3379
|
+
imageSource,
|
|
3343
3380
|
leftRender,
|
|
3344
3381
|
rightRender,
|
|
3345
3382
|
trailing,
|
|
@@ -3359,6 +3396,7 @@ function ListItemBase({
|
|
|
3359
3396
|
style,
|
|
3360
3397
|
titleStyle,
|
|
3361
3398
|
subtitleStyle,
|
|
3399
|
+
subtitleNumberOfLines = 2,
|
|
3362
3400
|
captionStyle,
|
|
3363
3401
|
accessibilityLabel
|
|
3364
3402
|
}) {
|
|
@@ -3367,7 +3405,7 @@ function ListItemBase({
|
|
|
3367
3405
|
selectionAsync();
|
|
3368
3406
|
onPress?.();
|
|
3369
3407
|
};
|
|
3370
|
-
const effectiveLeft = leftIcon ? renderIcon(leftIcon, 24, leftIconColor ?? colors.foreground) : leftRender ?? icon;
|
|
3408
|
+
const effectiveLeft = imageSource ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Image, { source: imageSource, style: styles25.image }) : leftIcon ? renderIcon(leftIcon, 24, leftIconColor ?? colors.foreground) : leftRender ?? icon;
|
|
3371
3409
|
const effectiveRight = rightIcon ? renderIcon(rightIcon, 24, rightIconColor ?? colors.foregroundMuted) : rightRender ?? trailing;
|
|
3372
3410
|
const cardStyle = variant === "card" ? {
|
|
3373
3411
|
backgroundColor: colors.card,
|
|
@@ -3393,7 +3431,7 @@ function ListItemBase({
|
|
|
3393
3431
|
reactNative.Text,
|
|
3394
3432
|
{
|
|
3395
3433
|
style: [styles25.subtitle, { color: colors.foregroundMuted }, subtitleStyle],
|
|
3396
|
-
numberOfLines:
|
|
3434
|
+
numberOfLines: subtitleNumberOfLines,
|
|
3397
3435
|
allowFontScaling: true
|
|
3398
3436
|
},
|
|
3399
3437
|
subtitle
|
|
@@ -3448,6 +3486,11 @@ var styles25 = reactNative.StyleSheet.create({
|
|
|
3448
3486
|
justifyContent: "center",
|
|
3449
3487
|
flexShrink: 0
|
|
3450
3488
|
},
|
|
3489
|
+
image: {
|
|
3490
|
+
width: s(40),
|
|
3491
|
+
height: s(40),
|
|
3492
|
+
borderRadius: 8
|
|
3493
|
+
},
|
|
3451
3494
|
content: {
|
|
3452
3495
|
flex: 1,
|
|
3453
3496
|
gap: vs(4)
|
|
@@ -3861,6 +3904,7 @@ function ConfirmDialog({
|
|
|
3861
3904
|
confirmLabel = "Confirm",
|
|
3862
3905
|
cancelLabel = "Cancel",
|
|
3863
3906
|
confirmVariant = "primary",
|
|
3907
|
+
loading = false,
|
|
3864
3908
|
onConfirm,
|
|
3865
3909
|
onCancel
|
|
3866
3910
|
}) {
|
|
@@ -3900,6 +3944,8 @@ function ConfirmDialog({
|
|
|
3900
3944
|
label: confirmLabel,
|
|
3901
3945
|
variant: confirmVariant,
|
|
3902
3946
|
fullWidth: true,
|
|
3947
|
+
loading,
|
|
3948
|
+
disabled: loading,
|
|
3903
3949
|
onPress: () => {
|
|
3904
3950
|
notificationSuccess();
|
|
3905
3951
|
onConfirm();
|
|
@@ -4166,7 +4212,7 @@ function MediaCardBase({
|
|
|
4166
4212
|
(title || subtitle || caption || footer) && /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles33.meta }, title ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles33.title, { color: colors.foreground }], numberOfLines: 2, allowFontScaling: true }, title) : null, subtitle ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles33.subtitle, { color: colors.foregroundSubtle }], numberOfLines: 1, allowFontScaling: true }, subtitle) : null, caption ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles33.caption, { color: colors.foregroundMuted }], numberOfLines: 1, allowFontScaling: true }, caption) : null, footer)
|
|
4167
4213
|
);
|
|
4168
4214
|
if (onPress) {
|
|
4169
|
-
return /* @__PURE__ */ React25__default.default.createElement(
|
|
4215
|
+
return /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: animatedStyle }, /* @__PURE__ */ React25__default.default.createElement(
|
|
4170
4216
|
reactNative.TouchableOpacity,
|
|
4171
4217
|
{
|
|
4172
4218
|
onPress: handlePress,
|
|
@@ -4251,7 +4297,7 @@ var CategoryChip = React25__default.default.memo(function CategoryChip2({
|
|
|
4251
4297
|
});
|
|
4252
4298
|
const iconColor = selected ? colors.primaryForeground : colors.foregroundSubtle;
|
|
4253
4299
|
const resolvedIcon = typeof item.icon === "string" ? renderIcon(item.icon, 16, iconColor) : item.icon ?? null;
|
|
4254
|
-
return /* @__PURE__ */ React25__default.default.createElement(
|
|
4300
|
+
return /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: scaleStyle, ...hoverHandlers }, /* @__PURE__ */ React25__default.default.createElement(
|
|
4255
4301
|
reactNative.TouchableOpacity,
|
|
4256
4302
|
{
|
|
4257
4303
|
onPress: () => onSelect(item.value),
|
|
@@ -4674,15 +4720,15 @@ var styles38 = reactNative.StyleSheet.create({
|
|
|
4674
4720
|
}
|
|
4675
4721
|
});
|
|
4676
4722
|
function Dot({ active, size, activeColor, inactiveColor, onPress, index, total }) {
|
|
4677
|
-
const progress =
|
|
4723
|
+
const progress = Animated12.useSharedValue(active ? 1 : 0);
|
|
4678
4724
|
React25.useEffect(() => {
|
|
4679
|
-
progress.value =
|
|
4725
|
+
progress.value = Animated12.withSpring(active ? 1 : 0, SPRINGS.glide);
|
|
4680
4726
|
}, [active, progress]);
|
|
4681
|
-
const animatedStyle =
|
|
4727
|
+
const animatedStyle = Animated12.useAnimatedStyle(() => ({
|
|
4682
4728
|
width: size + progress.value * size * 1.5,
|
|
4683
|
-
backgroundColor:
|
|
4729
|
+
backgroundColor: Animated12.interpolateColor(progress.value, [0, 1], [inactiveColor, activeColor])
|
|
4684
4730
|
}));
|
|
4685
|
-
const dot = /* @__PURE__ */ React25__default.default.createElement(
|
|
4731
|
+
const dot = /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [{ height: size, borderRadius: size / 2 }, animatedStyle] });
|
|
4686
4732
|
if (!onPress) return dot;
|
|
4687
4733
|
const handlePress = () => {
|
|
4688
4734
|
selectionAsync();
|
|
@@ -4921,7 +4967,7 @@ function Cell({ item, selected, width, onPress }) {
|
|
|
4921
4967
|
});
|
|
4922
4968
|
const iconColor = selected ? colors.primary : colors.foregroundSubtle;
|
|
4923
4969
|
const iconNode = item.icon ?? (item.iconName ? renderIcon(item.iconName, ms(24), iconColor) : null);
|
|
4924
|
-
return /* @__PURE__ */ React25__default.default.createElement(
|
|
4970
|
+
return /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [{ width }, animatedStyle] }, /* @__PURE__ */ React25__default.default.createElement(
|
|
4925
4971
|
reactNative.TouchableOpacity,
|
|
4926
4972
|
{
|
|
4927
4973
|
onPress,
|
|
@@ -5283,22 +5329,22 @@ var styles43 = reactNative.StyleSheet.create({
|
|
|
5283
5329
|
var MAX_SCALE = 3;
|
|
5284
5330
|
var DOUBLE_TAP_SCALE = 2.5;
|
|
5285
5331
|
function ZoomableImage({ source, width, height, onZoomChange }) {
|
|
5286
|
-
const scale2 =
|
|
5287
|
-
const savedScale =
|
|
5288
|
-
const translateX =
|
|
5289
|
-
const translateY =
|
|
5290
|
-
const savedX =
|
|
5291
|
-
const savedY =
|
|
5332
|
+
const scale2 = Animated12.useSharedValue(1);
|
|
5333
|
+
const savedScale = Animated12.useSharedValue(1);
|
|
5334
|
+
const translateX = Animated12.useSharedValue(0);
|
|
5335
|
+
const translateY = Animated12.useSharedValue(0);
|
|
5336
|
+
const savedX = Animated12.useSharedValue(0);
|
|
5337
|
+
const savedY = Animated12.useSharedValue(0);
|
|
5292
5338
|
const reportZoom = React25.useCallback((zoomed) => onZoomChange(zoomed), [onZoomChange]);
|
|
5293
5339
|
const reset = () => {
|
|
5294
5340
|
"worklet";
|
|
5295
|
-
scale2.value =
|
|
5341
|
+
scale2.value = Animated12.withTiming(1);
|
|
5296
5342
|
savedScale.value = 1;
|
|
5297
|
-
translateX.value =
|
|
5298
|
-
translateY.value =
|
|
5343
|
+
translateX.value = Animated12.withTiming(0);
|
|
5344
|
+
translateY.value = Animated12.withTiming(0);
|
|
5299
5345
|
savedX.value = 0;
|
|
5300
5346
|
savedY.value = 0;
|
|
5301
|
-
|
|
5347
|
+
Animated12.runOnJS(reportZoom)(false);
|
|
5302
5348
|
};
|
|
5303
5349
|
const pinch = reactNativeGestureHandler.Gesture.Pinch().onUpdate((e) => {
|
|
5304
5350
|
scale2.value = Math.max(1, Math.min(savedScale.value * e.scale, MAX_SCALE));
|
|
@@ -5307,7 +5353,7 @@ function ZoomableImage({ source, width, height, onZoomChange }) {
|
|
|
5307
5353
|
if (scale2.value <= 1) {
|
|
5308
5354
|
reset();
|
|
5309
5355
|
} else {
|
|
5310
|
-
|
|
5356
|
+
Animated12.runOnJS(reportZoom)(true);
|
|
5311
5357
|
}
|
|
5312
5358
|
});
|
|
5313
5359
|
const pan = reactNativeGestureHandler.Gesture.Pan().onUpdate((e) => {
|
|
@@ -5322,21 +5368,21 @@ function ZoomableImage({ source, width, height, onZoomChange }) {
|
|
|
5322
5368
|
if (scale2.value > 1) {
|
|
5323
5369
|
reset();
|
|
5324
5370
|
} else {
|
|
5325
|
-
scale2.value =
|
|
5371
|
+
scale2.value = Animated12.withTiming(DOUBLE_TAP_SCALE);
|
|
5326
5372
|
savedScale.value = DOUBLE_TAP_SCALE;
|
|
5327
|
-
|
|
5373
|
+
Animated12.runOnJS(reportZoom)(true);
|
|
5328
5374
|
}
|
|
5329
5375
|
});
|
|
5330
5376
|
const composed = reactNativeGestureHandler.Gesture.Exclusive(doubleTap, reactNativeGestureHandler.Gesture.Simultaneous(pinch, pan));
|
|
5331
|
-
const animatedStyle =
|
|
5377
|
+
const animatedStyle = Animated12.useAnimatedStyle(() => ({
|
|
5332
5378
|
transform: [
|
|
5333
5379
|
{ translateX: translateX.value },
|
|
5334
5380
|
{ translateY: translateY.value },
|
|
5335
5381
|
{ scale: scale2.value }
|
|
5336
5382
|
]
|
|
5337
5383
|
}));
|
|
5338
|
-
return /* @__PURE__ */ React25__default.default.createElement(reactNativeGestureHandler.GestureDetector, { gesture: composed }, /* @__PURE__ */ React25__default.default.createElement(
|
|
5339
|
-
|
|
5384
|
+
return /* @__PURE__ */ React25__default.default.createElement(reactNativeGestureHandler.GestureDetector, { gesture: composed }, /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [{ width, height }, styles44.imageWrap] }, /* @__PURE__ */ React25__default.default.createElement(
|
|
5385
|
+
Animated12__default.default.Image,
|
|
5340
5386
|
{
|
|
5341
5387
|
source,
|
|
5342
5388
|
style: [{ width, height }, animatedStyle],
|
|
@@ -5359,25 +5405,25 @@ function ImageViewer({ images, visible, onClose, initialIndex = 0 }) {
|
|
|
5359
5405
|
});
|
|
5360
5406
|
return () => cancelAnimationFrame(handle);
|
|
5361
5407
|
}, [visible, initialIndex, width]);
|
|
5362
|
-
const dragY =
|
|
5408
|
+
const dragY = Animated12.useSharedValue(0);
|
|
5363
5409
|
const DISMISS_THRESHOLD = height * 0.18;
|
|
5364
5410
|
const closeViewer = React25.useCallback(() => onClose(), [onClose]);
|
|
5365
5411
|
const swipeDown = reactNativeGestureHandler.Gesture.Pan().enabled(pagingEnabled).activeOffsetY(12).failOffsetX([-16, 16]).onUpdate((e) => {
|
|
5366
5412
|
dragY.value = Math.max(0, e.translationY);
|
|
5367
5413
|
}).onEnd((e) => {
|
|
5368
5414
|
if (e.translationY > DISMISS_THRESHOLD || e.velocityY > 800) {
|
|
5369
|
-
|
|
5415
|
+
Animated12.runOnJS(closeViewer)();
|
|
5370
5416
|
} else {
|
|
5371
|
-
dragY.value =
|
|
5417
|
+
dragY.value = Animated12.withTiming(0);
|
|
5372
5418
|
}
|
|
5373
5419
|
});
|
|
5374
5420
|
React25__default.default.useEffect(() => {
|
|
5375
5421
|
if (visible) dragY.value = 0;
|
|
5376
5422
|
}, [visible, dragY]);
|
|
5377
|
-
const dismissStyle =
|
|
5423
|
+
const dismissStyle = Animated12.useAnimatedStyle(() => ({
|
|
5378
5424
|
transform: [{ translateY: dragY.value }]
|
|
5379
5425
|
}));
|
|
5380
|
-
const backdropStyle =
|
|
5426
|
+
const backdropStyle = Animated12.useAnimatedStyle(() => ({
|
|
5381
5427
|
opacity: 1 - Math.min(dragY.value / (height * 0.5), 0.85)
|
|
5382
5428
|
}));
|
|
5383
5429
|
const onMomentumEnd = (e) => {
|
|
@@ -5388,7 +5434,7 @@ function ImageViewer({ images, visible, onClose, initialIndex = 0 }) {
|
|
|
5388
5434
|
scrollRef.current?.scrollTo({ x: page * width, animated: true });
|
|
5389
5435
|
setIndex(page);
|
|
5390
5436
|
};
|
|
5391
|
-
return /* @__PURE__ */ React25__default.default.createElement(reactNative.Modal, { visible, transparent: false, animationType: "fade", onRequestClose: onClose, statusBarTranslucent: true }, /* @__PURE__ */ React25__default.default.createElement(reactNativeGestureHandler.GestureHandlerRootView, { style: styles44.root }, /* @__PURE__ */ React25__default.default.createElement(
|
|
5437
|
+
return /* @__PURE__ */ React25__default.default.createElement(reactNative.Modal, { visible, transparent: false, animationType: "fade", onRequestClose: onClose, statusBarTranslucent: true }, /* @__PURE__ */ React25__default.default.createElement(reactNativeGestureHandler.GestureHandlerRootView, { style: styles44.root }, /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [styles44.backdrop, backdropStyle], pointerEvents: "none" }), /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: [styles44.container, dismissStyle] }, /* @__PURE__ */ React25__default.default.createElement(reactNativeGestureHandler.GestureDetector, { gesture: swipeDown }, /* @__PURE__ */ React25__default.default.createElement(Animated12__default.default.View, { style: styles44.root }, /* @__PURE__ */ React25__default.default.createElement(
|
|
5392
5438
|
reactNative.ScrollView,
|
|
5393
5439
|
{
|
|
5394
5440
|
ref: scrollRef,
|
|
@@ -5465,6 +5511,240 @@ var styles44 = reactNative.StyleSheet.create({
|
|
|
5465
5511
|
alignItems: "center"
|
|
5466
5512
|
}
|
|
5467
5513
|
});
|
|
5514
|
+
function SheetSelectChip({
|
|
5515
|
+
option,
|
|
5516
|
+
selected,
|
|
5517
|
+
onPress
|
|
5518
|
+
}) {
|
|
5519
|
+
const { colors } = useTheme();
|
|
5520
|
+
const handlePress = () => {
|
|
5521
|
+
selectionAsync();
|
|
5522
|
+
onPress();
|
|
5523
|
+
};
|
|
5524
|
+
const iconColor = selected ? colors.primaryForeground : colors.foreground;
|
|
5525
|
+
const resolvedIcon = option.iconName ? renderIcon(option.iconName, ms(13), iconColor) : null;
|
|
5526
|
+
return /* @__PURE__ */ React25__default.default.createElement(
|
|
5527
|
+
PressableChip,
|
|
5528
|
+
{
|
|
5529
|
+
onPress: option.disabled ? void 0 : handlePress,
|
|
5530
|
+
rippleColor: "transparent",
|
|
5531
|
+
touchSoundDisabled: true,
|
|
5532
|
+
accessibilityRole: "button",
|
|
5533
|
+
accessibilityLabel: option.disabled ? `${option.label}, unavailable` : option.label,
|
|
5534
|
+
accessibilityState: { selected, disabled: option.disabled }
|
|
5535
|
+
},
|
|
5536
|
+
/* @__PURE__ */ React25__default.default.createElement(
|
|
5537
|
+
reactNativeEase.EaseView,
|
|
5538
|
+
{
|
|
5539
|
+
style: [styles45.chip, option.disabled && styles45.chipDisabled],
|
|
5540
|
+
animate: {
|
|
5541
|
+
backgroundColor: selected ? colors.primary : colors.surface,
|
|
5542
|
+
borderColor: selected ? colors.primary : colors.border
|
|
5543
|
+
},
|
|
5544
|
+
transition: COLOR_TRANSITION
|
|
5545
|
+
},
|
|
5546
|
+
resolvedIcon ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles45.chipIcon }, resolvedIcon) : null,
|
|
5547
|
+
/* @__PURE__ */ React25__default.default.createElement(
|
|
5548
|
+
reactNative.Text,
|
|
5549
|
+
{
|
|
5550
|
+
style: [styles45.chipLabel, { color: selected ? colors.primaryForeground : colors.foreground }],
|
|
5551
|
+
allowFontScaling: true
|
|
5552
|
+
},
|
|
5553
|
+
option.label
|
|
5554
|
+
)
|
|
5555
|
+
)
|
|
5556
|
+
);
|
|
5557
|
+
}
|
|
5558
|
+
function SheetSelect({
|
|
5559
|
+
options,
|
|
5560
|
+
value,
|
|
5561
|
+
onValueChange,
|
|
5562
|
+
multiSelect = false,
|
|
5563
|
+
label,
|
|
5564
|
+
error,
|
|
5565
|
+
wrap = false,
|
|
5566
|
+
style,
|
|
5567
|
+
accessibilityLabel
|
|
5568
|
+
}) {
|
|
5569
|
+
const { colors } = useTheme();
|
|
5570
|
+
const isSelected2 = (optionValue) => {
|
|
5571
|
+
if (Array.isArray(value)) return value.includes(optionValue);
|
|
5572
|
+
return optionValue === value;
|
|
5573
|
+
};
|
|
5574
|
+
const handlePress = (optionValue) => {
|
|
5575
|
+
if (!multiSelect) {
|
|
5576
|
+
onValueChange?.(optionValue);
|
|
5577
|
+
return;
|
|
5578
|
+
}
|
|
5579
|
+
const currentArray = Array.isArray(value) ? value : value != null ? [value] : [];
|
|
5580
|
+
const alreadySelected = currentArray.includes(optionValue);
|
|
5581
|
+
const newArray = alreadySelected ? currentArray.filter((v) => v !== optionValue) : [...currentArray, optionValue];
|
|
5582
|
+
onValueChange?.(newArray);
|
|
5583
|
+
};
|
|
5584
|
+
const chips = options.map((opt) => /* @__PURE__ */ React25__default.default.createElement(
|
|
5585
|
+
SheetSelectChip,
|
|
5586
|
+
{
|
|
5587
|
+
key: opt.value,
|
|
5588
|
+
option: opt,
|
|
5589
|
+
selected: isSelected2(opt.value),
|
|
5590
|
+
onPress: () => handlePress(opt.value)
|
|
5591
|
+
}
|
|
5592
|
+
));
|
|
5593
|
+
return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles45.container, style], accessibilityLabel }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles45.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, wrap ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles45.wrapContainer }, chips) : /* @__PURE__ */ React25__default.default.createElement(
|
|
5594
|
+
reactNative.ScrollView,
|
|
5595
|
+
{
|
|
5596
|
+
horizontal: true,
|
|
5597
|
+
showsHorizontalScrollIndicator: false,
|
|
5598
|
+
contentContainerStyle: styles45.scrollContent
|
|
5599
|
+
},
|
|
5600
|
+
chips
|
|
5601
|
+
), error ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles45.error, { color: colors.destructive }], allowFontScaling: true, accessibilityLiveRegion: "polite" }, error) : null);
|
|
5602
|
+
}
|
|
5603
|
+
var styles45 = reactNative.StyleSheet.create({
|
|
5604
|
+
container: {
|
|
5605
|
+
gap: vs(8)
|
|
5606
|
+
},
|
|
5607
|
+
label: {
|
|
5608
|
+
fontFamily: "Sohne-Medium",
|
|
5609
|
+
fontSize: ms(14)
|
|
5610
|
+
},
|
|
5611
|
+
scrollContent: {
|
|
5612
|
+
flexDirection: "row",
|
|
5613
|
+
gap: s(8)
|
|
5614
|
+
},
|
|
5615
|
+
wrapContainer: {
|
|
5616
|
+
flexDirection: "row",
|
|
5617
|
+
flexWrap: "wrap",
|
|
5618
|
+
gap: s(8)
|
|
5619
|
+
},
|
|
5620
|
+
chip: {
|
|
5621
|
+
borderRadius: RADIUS.full,
|
|
5622
|
+
paddingHorizontal: s(14),
|
|
5623
|
+
paddingVertical: vs(10),
|
|
5624
|
+
minHeight: 44,
|
|
5625
|
+
borderWidth: 1,
|
|
5626
|
+
alignItems: "center",
|
|
5627
|
+
justifyContent: "center",
|
|
5628
|
+
flexDirection: "row",
|
|
5629
|
+
gap: s(5)
|
|
5630
|
+
},
|
|
5631
|
+
chipDisabled: {
|
|
5632
|
+
opacity: 0.4
|
|
5633
|
+
},
|
|
5634
|
+
chipIcon: {
|
|
5635
|
+
alignItems: "center",
|
|
5636
|
+
justifyContent: "center"
|
|
5637
|
+
},
|
|
5638
|
+
chipLabel: {
|
|
5639
|
+
fontFamily: "Sohne-Medium",
|
|
5640
|
+
fontSize: ms(13),
|
|
5641
|
+
lineHeight: mvs(18)
|
|
5642
|
+
},
|
|
5643
|
+
error: {
|
|
5644
|
+
fontFamily: "Sohne-Regular",
|
|
5645
|
+
fontSize: ms(13)
|
|
5646
|
+
}
|
|
5647
|
+
});
|
|
5648
|
+
function ImageUpload({
|
|
5649
|
+
value,
|
|
5650
|
+
onChange,
|
|
5651
|
+
loading = false,
|
|
5652
|
+
placeholder = "Tap to add image",
|
|
5653
|
+
width,
|
|
5654
|
+
height = 200,
|
|
5655
|
+
borderRadius = RADIUS.lg,
|
|
5656
|
+
resizeMode = "cover",
|
|
5657
|
+
disabled = false,
|
|
5658
|
+
style,
|
|
5659
|
+
accessibilityLabel
|
|
5660
|
+
}) {
|
|
5661
|
+
const { colors } = useTheme();
|
|
5662
|
+
const handlePress = async () => {
|
|
5663
|
+
if (disabled || loading) return;
|
|
5664
|
+
impactLight();
|
|
5665
|
+
let ImagePicker;
|
|
5666
|
+
try {
|
|
5667
|
+
ImagePicker = await import('expo-image-picker');
|
|
5668
|
+
} catch {
|
|
5669
|
+
if (__DEV__) console.warn("[ImageUpload] expo-image-picker not installed. Add it as a dependency.");
|
|
5670
|
+
return;
|
|
5671
|
+
}
|
|
5672
|
+
if (reactNative.Platform.OS !== "web") {
|
|
5673
|
+
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
|
|
5674
|
+
if (status !== "granted") return;
|
|
5675
|
+
}
|
|
5676
|
+
const result = await ImagePicker.launchImageLibraryAsync({
|
|
5677
|
+
mediaTypes: ["images"],
|
|
5678
|
+
allowsEditing: true,
|
|
5679
|
+
quality: 0.8
|
|
5680
|
+
});
|
|
5681
|
+
if (!result.canceled && result.assets[0]) {
|
|
5682
|
+
onChange?.(result.assets[0].uri);
|
|
5683
|
+
}
|
|
5684
|
+
};
|
|
5685
|
+
const containerStyle = {
|
|
5686
|
+
width,
|
|
5687
|
+
height,
|
|
5688
|
+
borderRadius,
|
|
5689
|
+
borderWidth: value ? 0 : 1,
|
|
5690
|
+
borderStyle: "dashed",
|
|
5691
|
+
borderColor: colors.border,
|
|
5692
|
+
backgroundColor: value ? "transparent" : colors.surface,
|
|
5693
|
+
overflow: "hidden"
|
|
5694
|
+
};
|
|
5695
|
+
return /* @__PURE__ */ React25__default.default.createElement(
|
|
5696
|
+
PressableCard,
|
|
5697
|
+
{
|
|
5698
|
+
onPress: handlePress,
|
|
5699
|
+
enabled: !disabled && !loading,
|
|
5700
|
+
rippleColor: "transparent",
|
|
5701
|
+
touchSoundDisabled: true,
|
|
5702
|
+
accessibilityRole: "button",
|
|
5703
|
+
accessibilityLabel: accessibilityLabel ?? (value ? "Change image" : placeholder),
|
|
5704
|
+
accessibilityState: { disabled: disabled || loading },
|
|
5705
|
+
style: [containerStyle, style]
|
|
5706
|
+
},
|
|
5707
|
+
value ? /* @__PURE__ */ React25__default.default.createElement(
|
|
5708
|
+
reactNative.Image,
|
|
5709
|
+
{
|
|
5710
|
+
source: { uri: value },
|
|
5711
|
+
style: [reactNative.StyleSheet.absoluteFillObject, { borderRadius }],
|
|
5712
|
+
resizeMode
|
|
5713
|
+
}
|
|
5714
|
+
) : /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles46.placeholder }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "image", size: ms(28), color: colors.foregroundMuted }), /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles46.placeholderText, { color: colors.foregroundMuted }], allowFontScaling: true }, placeholder)),
|
|
5715
|
+
loading ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles46.loadingOverlay, { backgroundColor: colors.overlay }] }, /* @__PURE__ */ React25__default.default.createElement(Spinner, { size: "md" })) : null,
|
|
5716
|
+
value && !loading ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles46.editBadge, pointerEvents: "none" }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles46.editBadgeInner, { backgroundColor: colors.overlay }] }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "edit-2", size: ms(12), color: "#fff" }))) : null
|
|
5717
|
+
);
|
|
5718
|
+
}
|
|
5719
|
+
var styles46 = reactNative.StyleSheet.create({
|
|
5720
|
+
placeholder: {
|
|
5721
|
+
flex: 1,
|
|
5722
|
+
alignItems: "center",
|
|
5723
|
+
justifyContent: "center",
|
|
5724
|
+
gap: vs(8)
|
|
5725
|
+
},
|
|
5726
|
+
placeholderText: {
|
|
5727
|
+
fontFamily: "Sohne-Regular",
|
|
5728
|
+
fontSize: ms(13)
|
|
5729
|
+
},
|
|
5730
|
+
loadingOverlay: {
|
|
5731
|
+
...reactNative.StyleSheet.absoluteFillObject,
|
|
5732
|
+
alignItems: "center",
|
|
5733
|
+
justifyContent: "center"
|
|
5734
|
+
},
|
|
5735
|
+
editBadge: {
|
|
5736
|
+
position: "absolute",
|
|
5737
|
+
bottom: vs(8),
|
|
5738
|
+
right: s(8)
|
|
5739
|
+
},
|
|
5740
|
+
editBadgeInner: {
|
|
5741
|
+
width: s(28),
|
|
5742
|
+
height: s(28),
|
|
5743
|
+
borderRadius: 999,
|
|
5744
|
+
alignItems: "center",
|
|
5745
|
+
justifyContent: "center"
|
|
5746
|
+
}
|
|
5747
|
+
});
|
|
5468
5748
|
|
|
5469
5749
|
// src/utils/typography.ts
|
|
5470
5750
|
function getResponsiveFontSize(text, maxSize, steps = [
|
|
@@ -5479,6 +5759,42 @@ function getResponsiveFontSize(text, maxSize, steps = [
|
|
|
5479
5759
|
}
|
|
5480
5760
|
return maxSize - 8;
|
|
5481
5761
|
}
|
|
5762
|
+
function useConfirmDialog(options) {
|
|
5763
|
+
const [visible, setVisible] = React25.useState(false);
|
|
5764
|
+
const [target, setTarget] = React25.useState(null);
|
|
5765
|
+
const [loading, setLoading] = React25.useState(false);
|
|
5766
|
+
const open = React25.useCallback((t) => {
|
|
5767
|
+
setTarget(t ?? null);
|
|
5768
|
+
setVisible(true);
|
|
5769
|
+
}, []);
|
|
5770
|
+
const handleConfirm = React25.useCallback(async () => {
|
|
5771
|
+
setLoading(true);
|
|
5772
|
+
try {
|
|
5773
|
+
await options.onConfirm();
|
|
5774
|
+
} finally {
|
|
5775
|
+
setLoading(false);
|
|
5776
|
+
setVisible(false);
|
|
5777
|
+
setTarget(null);
|
|
5778
|
+
}
|
|
5779
|
+
}, [options]);
|
|
5780
|
+
const handleCancel = React25.useCallback(() => {
|
|
5781
|
+
setVisible(false);
|
|
5782
|
+
setTarget(null);
|
|
5783
|
+
options.onCancel?.();
|
|
5784
|
+
}, [options]);
|
|
5785
|
+
return {
|
|
5786
|
+
visible,
|
|
5787
|
+
target,
|
|
5788
|
+
loading,
|
|
5789
|
+
open,
|
|
5790
|
+
dialogProps: {
|
|
5791
|
+
visible,
|
|
5792
|
+
loading,
|
|
5793
|
+
onConfirm: handleConfirm,
|
|
5794
|
+
onCancel: handleCancel
|
|
5795
|
+
}
|
|
5796
|
+
};
|
|
5797
|
+
}
|
|
5482
5798
|
|
|
5483
5799
|
Object.defineProperty(exports, "BottomSheetModalProvider", {
|
|
5484
5800
|
enumerable: true,
|
|
@@ -5523,6 +5839,7 @@ exports.FormSection = FormSection;
|
|
|
5523
5839
|
exports.ICON_SIZES = ICON_SIZES;
|
|
5524
5840
|
exports.Icon = Icon;
|
|
5525
5841
|
exports.IconButton = IconButton;
|
|
5842
|
+
exports.ImageUpload = ImageUpload;
|
|
5526
5843
|
exports.ImageViewer = ImageViewer;
|
|
5527
5844
|
exports.Input = Input;
|
|
5528
5845
|
exports.LabelValue = LabelValue;
|
|
@@ -5549,6 +5866,7 @@ exports.Select = Select;
|
|
|
5549
5866
|
exports.SelectableGrid = SelectableGrid;
|
|
5550
5867
|
exports.Separator = Separator;
|
|
5551
5868
|
exports.Sheet = Sheet;
|
|
5869
|
+
exports.SheetSelect = SheetSelect;
|
|
5552
5870
|
exports.Skeleton = Skeleton;
|
|
5553
5871
|
exports.Slider = Slider;
|
|
5554
5872
|
exports.Spinner = Spinner;
|
|
@@ -5579,5 +5897,6 @@ exports.notificationWarning = notificationWarning;
|
|
|
5579
5897
|
exports.renderIcon = renderIcon;
|
|
5580
5898
|
exports.richHaptics = richHaptics;
|
|
5581
5899
|
exports.selectionAsync = selectionAsync;
|
|
5900
|
+
exports.useConfirmDialog = useConfirmDialog;
|
|
5582
5901
|
exports.useTheme = useTheme;
|
|
5583
5902
|
exports.useToast = useToast;
|