@retray-dev/ui-kit 6.0.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMPONENTS.md +8 -7
- package/dist/index.d.mts +47 -23
- package/dist/index.d.ts +47 -23
- package/dist/index.js +702 -634
- package/dist/index.mjs +695 -627
- package/package.json +1 -1
- package/src/components/Accordion/Accordion.tsx +10 -12
- package/src/components/Button/Button.tsx +20 -18
- package/src/components/Card/Card.tsx +21 -33
- package/src/components/CategoryStrip/CategoryStrip.tsx +45 -38
- package/src/components/Checkbox/Checkbox.tsx +31 -50
- package/src/components/Chip/Chip.tsx +34 -71
- package/src/components/DetailRow/DetailRow.tsx +13 -8
- package/src/components/IconButton/IconButton.tsx +20 -18
- package/src/components/Input/Input.tsx +39 -22
- package/src/components/ListItem/ListItem.tsx +22 -34
- package/src/components/MediaCard/MediaCard.tsx +24 -24
- package/src/components/MenuItem/MenuItem.tsx +52 -39
- package/src/components/MonthPicker/MonthPicker.tsx +12 -2
- package/src/components/Pressable/Pressable.tsx +27 -46
- package/src/components/Progress/Progress.tsx +21 -12
- package/src/components/RadioGroup/RadioGroup.tsx +52 -26
- package/src/components/Select/Select.tsx +17 -15
- package/src/components/Sheet/Sheet.tsx +4 -1
- package/src/components/Skeleton/Skeleton.tsx +24 -13
- package/src/components/Slider/Slider.tsx +11 -1
- package/src/components/Switch/Switch.tsx +44 -49
- package/src/components/Tabs/Tabs.tsx +39 -31
- package/src/components/Textarea/Textarea.tsx +29 -12
- package/src/components/Toggle/Toggle.tsx +39 -45
- package/src/utils/animations.ts +58 -0
- package/src/utils/useColorTransition.ts +40 -0
- package/src/utils/usePressScale.ts +73 -0
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import React26, { createContext, useMemo, useContext,
|
|
2
|
-
import { Platform, StyleSheet, Dimensions, useColorScheme,
|
|
1
|
+
import React26, { createContext, useMemo, useContext, useState, useEffect, useRef, useCallback } from 'react';
|
|
2
|
+
import { Platform, StyleSheet, Dimensions, useColorScheme, TouchableOpacity, ActivityIndicator, Text, View, TextInput, Image, Modal, ScrollView, Pressable } from 'react-native';
|
|
3
|
+
import Animated9, { Easing, useAnimatedStyle, interpolateColor, useSharedValue, withRepeat, withTiming, withSpring, useDerivedValue } from 'react-native-reanimated';
|
|
3
4
|
import { verticalScale, scale, moderateVerticalScale, moderateScale } from 'react-native-size-matters';
|
|
4
5
|
import AntDesign from '@expo/vector-icons/AntDesign';
|
|
5
6
|
import Entypo from '@expo/vector-icons/Entypo';
|
|
@@ -9,7 +10,6 @@ import MaterialIcons from '@expo/vector-icons/MaterialIcons';
|
|
|
9
10
|
import Ionicons from '@expo/vector-icons/Ionicons';
|
|
10
11
|
import { AntDesign as AntDesign$1, FontAwesome5 as FontAwesome5$1, MaterialIcons as MaterialIcons$1, Entypo as Entypo$1, Feather as Feather$1 } from '@expo/vector-icons';
|
|
11
12
|
import { LinearGradient } from 'expo-linear-gradient';
|
|
12
|
-
import Animated12, { Easing, useSharedValue, useDerivedValue, withTiming, useAnimatedStyle } from 'react-native-reanimated';
|
|
13
13
|
import RNSlider from '@react-native-community/slider';
|
|
14
14
|
import { BottomSheetBackdrop, BottomSheetFooter, BottomSheetModal, BottomSheetScrollView, BottomSheetView } from '@gorhom/bottom-sheet';
|
|
15
15
|
export { BottomSheetModalProvider, BottomSheetTextInput as SheetTextInput } from '@gorhom/bottom-sheet';
|
|
@@ -407,9 +407,87 @@ var TYPOGRAPHY = {
|
|
|
407
407
|
letterSpacing: 0
|
|
408
408
|
}
|
|
409
409
|
};
|
|
410
|
+
var SPRINGS = {
|
|
411
|
+
/** Tight, premium press feel — Buttons, Toggle, Tabs triggers. */
|
|
412
|
+
pressIn: { stiffness: 600, damping: 35, mass: 0.8 },
|
|
413
|
+
pressOut: { stiffness: 280, damping: 22, mass: 0.8 },
|
|
414
|
+
/** Slightly softer for larger surfaces — Card, ListItem, MenuItem. */
|
|
415
|
+
surfacePressIn: { stiffness: 380, damping: 30, mass: 0.95 },
|
|
416
|
+
surfacePressOut: { stiffness: 220, damping: 20, mass: 0.95 },
|
|
417
|
+
/** Settled transitions for moving indicators — Tabs pill, Switch thumb. */
|
|
418
|
+
glide: { stiffness: 380, damping: 38, mass: 1 },
|
|
419
|
+
/** Elastic indicator — Switch thumb, RadioGroup dot. */
|
|
420
|
+
elastic: { stiffness: 320, damping: 22, mass: 0.7 }
|
|
421
|
+
};
|
|
422
|
+
var TIMINGS = {
|
|
423
|
+
/** Color/opacity transitions on toggles, checkboxes, switches. */
|
|
424
|
+
state: { duration: 160 },
|
|
425
|
+
/** Focus ring on inputs. */
|
|
426
|
+
focusIn: { duration: 140 },
|
|
427
|
+
focusOut: { duration: 100 },
|
|
428
|
+
/** Accordion / collapsible content. */
|
|
429
|
+
expand: { duration: 240 },
|
|
430
|
+
collapse: { duration: 200 },
|
|
431
|
+
/** Skeleton shimmer cycle (full pass). */
|
|
432
|
+
shimmer: { duration: 1400 }
|
|
433
|
+
};
|
|
434
|
+
var EASINGS = {
|
|
435
|
+
/** Material-style ease-out — natural deceleration for state changes. */
|
|
436
|
+
standard: Easing.bezier(0.2, 0, 0, 1),
|
|
437
|
+
/** Strong ease-out for expanding surfaces (Accordion open). */
|
|
438
|
+
expand: Easing.bezier(0.23, 1, 0.32, 1),
|
|
439
|
+
/** Quick ease-in for collapsing. */
|
|
440
|
+
collapse: Easing.in(Easing.ease)
|
|
441
|
+
};
|
|
442
|
+
var PRESS_SCALE = {
|
|
443
|
+
button: 0.95,
|
|
444
|
+
card: 0.98,
|
|
445
|
+
row: 0.97,
|
|
446
|
+
chip: 0.94
|
|
447
|
+
};
|
|
448
|
+
function useHover() {
|
|
449
|
+
const [hovered, setHovered] = useState(false);
|
|
450
|
+
const onMouseEnter = useCallback(() => setHovered(true), []);
|
|
451
|
+
const onMouseLeave = useCallback(() => setHovered(false), []);
|
|
452
|
+
if (Platform.OS !== "web") {
|
|
453
|
+
return { hovered: false, hoverHandlers: {} };
|
|
454
|
+
}
|
|
455
|
+
return { hovered, hoverHandlers: { onMouseEnter, onMouseLeave } };
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// src/utils/usePressScale.ts
|
|
459
|
+
function usePressScale({
|
|
460
|
+
pressScale = PRESS_SCALE.button,
|
|
461
|
+
hoverScale = 1.02,
|
|
462
|
+
pressInSpring = SPRINGS.pressIn,
|
|
463
|
+
pressOutSpring = SPRINGS.pressOut,
|
|
464
|
+
disabled = false
|
|
465
|
+
} = {}) {
|
|
466
|
+
const scale2 = useSharedValue(1);
|
|
467
|
+
const { hovered, hoverHandlers } = useHover();
|
|
468
|
+
const onPressIn = useCallback(() => {
|
|
469
|
+
if (disabled) return;
|
|
470
|
+
scale2.value = withSpring(pressScale, pressInSpring);
|
|
471
|
+
}, [disabled, pressScale, pressInSpring, scale2]);
|
|
472
|
+
const onPressOut = useCallback(() => {
|
|
473
|
+
if (disabled) return;
|
|
474
|
+
scale2.value = withSpring(1, pressOutSpring);
|
|
475
|
+
}, [disabled, pressOutSpring, scale2]);
|
|
476
|
+
const hoverActive = Platform.OS === "web" && hovered && hoverScale !== 1 && !disabled;
|
|
477
|
+
const animatedStyle = useAnimatedStyle(() => ({
|
|
478
|
+
transform: [
|
|
479
|
+
{ scale: scale2.value * (hoverActive ? hoverScale : 1) }
|
|
480
|
+
]
|
|
481
|
+
}));
|
|
482
|
+
return {
|
|
483
|
+
animatedStyle,
|
|
484
|
+
onPressIn,
|
|
485
|
+
onPressOut,
|
|
486
|
+
hoverHandlers
|
|
487
|
+
};
|
|
488
|
+
}
|
|
410
489
|
|
|
411
490
|
// src/components/Button/Button.tsx
|
|
412
|
-
var nativeDriver = Platform.OS !== "web";
|
|
413
491
|
var containerSizeStyles = {
|
|
414
492
|
sm: { paddingHorizontal: s(16), paddingVertical: vs(10), minHeight: 40 },
|
|
415
493
|
md: { paddingHorizontal: s(24), paddingVertical: vs(14), minHeight: 48 },
|
|
@@ -434,18 +512,16 @@ function Button({
|
|
|
434
512
|
disabled,
|
|
435
513
|
style,
|
|
436
514
|
onPress,
|
|
515
|
+
accessibilityLabel,
|
|
516
|
+
accessibilityHint,
|
|
437
517
|
...props
|
|
438
518
|
}) {
|
|
439
519
|
const { colors } = useTheme();
|
|
440
520
|
const isDisabled = disabled || loading;
|
|
441
|
-
const
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
};
|
|
446
|
-
const handlePressOut = () => {
|
|
447
|
-
Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver, stiffness: 280, damping: 22, mass: 0.8 }).start();
|
|
448
|
-
};
|
|
521
|
+
const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
522
|
+
pressScale: PRESS_SCALE.button,
|
|
523
|
+
disabled: isDisabled
|
|
524
|
+
});
|
|
449
525
|
const handlePress = (e) => {
|
|
450
526
|
impactMedium();
|
|
451
527
|
onPress?.(e);
|
|
@@ -468,43 +544,54 @@ function Button({
|
|
|
468
544
|
const styleArray = Array.isArray(style) ? style : style ? [style] : [];
|
|
469
545
|
const flatStyle = StyleSheet.flatten(styleArray);
|
|
470
546
|
const { flex, ...restStyle } = flatStyle || {};
|
|
471
|
-
return /* @__PURE__ */ React26.createElement(
|
|
472
|
-
|
|
547
|
+
return /* @__PURE__ */ React26.createElement(
|
|
548
|
+
Animated9.View,
|
|
473
549
|
{
|
|
474
|
-
style: [
|
|
475
|
-
|
|
476
|
-
containerVariantStyle,
|
|
477
|
-
containerSizeStyles[size],
|
|
478
|
-
fullWidth && styles.fullWidth,
|
|
479
|
-
isDisabled && styles.disabled,
|
|
480
|
-
restStyle
|
|
481
|
-
],
|
|
482
|
-
disabled: isDisabled,
|
|
483
|
-
activeOpacity: 1,
|
|
484
|
-
touchSoundDisabled: true,
|
|
485
|
-
onPress: handlePress,
|
|
486
|
-
onPressIn: handlePressIn,
|
|
487
|
-
onPressOut: handlePressOut,
|
|
488
|
-
...props
|
|
550
|
+
style: [fullWidth && styles.fullWidth, flex !== void 0 && { flex }, animatedStyle],
|
|
551
|
+
...hoverHandlers
|
|
489
552
|
},
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
{
|
|
493
|
-
style: [styles.label, labelVariantStyle, labelSizeStyles[size], styles.labelLoading],
|
|
494
|
-
allowFontScaling: true,
|
|
495
|
-
numberOfLines: 1
|
|
496
|
-
},
|
|
497
|
-
label
|
|
498
|
-
)) : /* @__PURE__ */ React26.createElement(React26.Fragment, null, effectiveIcon && iconPosition === "left" && /* @__PURE__ */ React26.createElement(React26.Fragment, null, effectiveIcon), /* @__PURE__ */ React26.createElement(
|
|
499
|
-
Text,
|
|
553
|
+
/* @__PURE__ */ React26.createElement(
|
|
554
|
+
TouchableOpacity,
|
|
500
555
|
{
|
|
501
|
-
style: [
|
|
502
|
-
|
|
503
|
-
|
|
556
|
+
style: [
|
|
557
|
+
styles.base,
|
|
558
|
+
containerVariantStyle,
|
|
559
|
+
containerSizeStyles[size],
|
|
560
|
+
fullWidth && styles.fullWidth,
|
|
561
|
+
isDisabled && styles.disabled,
|
|
562
|
+
restStyle
|
|
563
|
+
],
|
|
564
|
+
disabled: isDisabled,
|
|
565
|
+
activeOpacity: 1,
|
|
566
|
+
touchSoundDisabled: true,
|
|
567
|
+
onPress: handlePress,
|
|
568
|
+
onPressIn,
|
|
569
|
+
onPressOut,
|
|
570
|
+
accessibilityRole: "button",
|
|
571
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
572
|
+
accessibilityHint,
|
|
573
|
+
accessibilityState: { disabled: isDisabled, busy: loading },
|
|
574
|
+
...props
|
|
504
575
|
},
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
576
|
+
loading ? /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(ActivityIndicator, { size: "small", color: spinnerColor, style: { marginRight: s(6) } }), /* @__PURE__ */ React26.createElement(
|
|
577
|
+
Text,
|
|
578
|
+
{
|
|
579
|
+
style: [styles.label, labelVariantStyle, labelSizeStyles[size], styles.labelLoading],
|
|
580
|
+
allowFontScaling: true,
|
|
581
|
+
numberOfLines: 1
|
|
582
|
+
},
|
|
583
|
+
label
|
|
584
|
+
)) : /* @__PURE__ */ React26.createElement(React26.Fragment, null, effectiveIcon && iconPosition === "left" && /* @__PURE__ */ React26.createElement(React26.Fragment, null, effectiveIcon), /* @__PURE__ */ React26.createElement(
|
|
585
|
+
Text,
|
|
586
|
+
{
|
|
587
|
+
style: [styles.label, labelVariantStyle, labelSizeStyles[size], effectiveIcon ? styles.labelWithIcon : void 0],
|
|
588
|
+
allowFontScaling: true,
|
|
589
|
+
numberOfLines: 1
|
|
590
|
+
},
|
|
591
|
+
label
|
|
592
|
+
), effectiveIcon && iconPosition === "right" && /* @__PURE__ */ React26.createElement(React26.Fragment, null, effectiveIcon))
|
|
593
|
+
)
|
|
594
|
+
);
|
|
508
595
|
}
|
|
509
596
|
var styles = StyleSheet.create({
|
|
510
597
|
base: {
|
|
@@ -564,7 +651,6 @@ var styles2 = StyleSheet.create({
|
|
|
564
651
|
flexDirection: "column"
|
|
565
652
|
}
|
|
566
653
|
});
|
|
567
|
-
var nativeDriver2 = Platform.OS !== "web";
|
|
568
654
|
var sizeMap = {
|
|
569
655
|
sm: { container: s(32), icon: 16 },
|
|
570
656
|
md: { container: s(44), icon: 20 },
|
|
@@ -581,18 +667,16 @@ function IconButton({
|
|
|
581
667
|
disabled,
|
|
582
668
|
style,
|
|
583
669
|
onPress,
|
|
670
|
+
accessibilityLabel,
|
|
671
|
+
accessibilityHint,
|
|
584
672
|
...props
|
|
585
673
|
}) {
|
|
586
674
|
const { colors } = useTheme();
|
|
587
675
|
const isDisabled = disabled || loading;
|
|
588
|
-
const
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
};
|
|
593
|
-
const handlePressOut = () => {
|
|
594
|
-
Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver2, speed: 40, bounciness: 4 }).start();
|
|
595
|
-
};
|
|
676
|
+
const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
677
|
+
pressScale: PRESS_SCALE.button,
|
|
678
|
+
disabled: isDisabled
|
|
679
|
+
});
|
|
596
680
|
const handlePress = (e) => {
|
|
597
681
|
impactLight();
|
|
598
682
|
onPress?.(e);
|
|
@@ -617,30 +701,42 @@ function IconButton({
|
|
|
617
701
|
const showBadge = badge !== void 0 && badge !== false && badge !== 0;
|
|
618
702
|
const badgeCount = typeof badge === "number" ? Math.min(badge, 99) : null;
|
|
619
703
|
const showCount = typeof badge === "number" && badge > 0;
|
|
620
|
-
return /* @__PURE__ */ React26.createElement(
|
|
621
|
-
|
|
704
|
+
return /* @__PURE__ */ React26.createElement(
|
|
705
|
+
Animated9.View,
|
|
622
706
|
{
|
|
623
|
-
style: [
|
|
624
|
-
|
|
625
|
-
containerVariantStyle,
|
|
626
|
-
{ width: containerSize, height: containerSize },
|
|
627
|
-
isDisabled && styles3.disabled,
|
|
628
|
-
style
|
|
629
|
-
],
|
|
630
|
-
disabled: isDisabled,
|
|
631
|
-
activeOpacity: 1,
|
|
632
|
-
touchSoundDisabled: true,
|
|
633
|
-
onPress: handlePress,
|
|
634
|
-
onPressIn: handlePressIn,
|
|
635
|
-
onPressOut: handlePressOut,
|
|
636
|
-
...props
|
|
707
|
+
style: [styles3.wrapper, animatedStyle],
|
|
708
|
+
...hoverHandlers
|
|
637
709
|
},
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
710
|
+
/* @__PURE__ */ React26.createElement(
|
|
711
|
+
TouchableOpacity,
|
|
712
|
+
{
|
|
713
|
+
style: [
|
|
714
|
+
styles3.base,
|
|
715
|
+
containerVariantStyle,
|
|
716
|
+
{ width: containerSize, height: containerSize },
|
|
717
|
+
isDisabled && styles3.disabled,
|
|
718
|
+
style
|
|
719
|
+
],
|
|
720
|
+
disabled: isDisabled,
|
|
721
|
+
activeOpacity: 1,
|
|
722
|
+
touchSoundDisabled: true,
|
|
723
|
+
onPress: handlePress,
|
|
724
|
+
onPressIn,
|
|
725
|
+
onPressOut,
|
|
726
|
+
accessibilityRole: "button",
|
|
727
|
+
accessibilityLabel: accessibilityLabel ?? iconName ?? "icon button",
|
|
728
|
+
accessibilityHint,
|
|
729
|
+
accessibilityState: { disabled: isDisabled, busy: loading },
|
|
730
|
+
...props
|
|
731
|
+
},
|
|
732
|
+
loading ? /* @__PURE__ */ React26.createElement(ActivityIndicator, { size: "small", color: spinnerColor }) : resolvedIcon
|
|
733
|
+
),
|
|
734
|
+
showBadge && /* @__PURE__ */ React26.createElement(View, { style: [
|
|
735
|
+
styles3.badge,
|
|
736
|
+
{ backgroundColor: colors.primary },
|
|
737
|
+
showCount ? styles3.badgeCount : styles3.badgeDot
|
|
738
|
+
] }, showCount && /* @__PURE__ */ React26.createElement(Text, { style: [styles3.badgeText, { color: colors.primaryForeground }] }, badgeCount))
|
|
739
|
+
);
|
|
644
740
|
}
|
|
645
741
|
var styles3 = StyleSheet.create({
|
|
646
742
|
wrapper: {
|
|
@@ -729,29 +825,49 @@ function Text3({ variant = "body-md", color, style, children, ...props }) {
|
|
|
729
825
|
children
|
|
730
826
|
);
|
|
731
827
|
}
|
|
828
|
+
function useColorTransition(active, options = {}) {
|
|
829
|
+
const { duration = TIMINGS.state.duration } = options;
|
|
830
|
+
const progress = useSharedValue(active ? 1 : 0);
|
|
831
|
+
useEffect(() => {
|
|
832
|
+
progress.value = withTiming(active ? 1 : 0, { duration, easing: EASINGS.standard });
|
|
833
|
+
}, [active, duration, progress]);
|
|
834
|
+
return progress;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
// src/components/Input/Input.tsx
|
|
732
838
|
var webInputResetStyle = Platform.OS === "web" ? { outlineStyle: "none", outlineWidth: 0, outlineColor: "transparent", boxShadow: "none" } : {};
|
|
733
|
-
function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suffixStyle, prefixIcon, suffixIcon, prefixIconColor, suffixIconColor, type = "text", containerStyle, inputWrapperStyle, style, onFocus, onBlur, secureTextEntry, editable, ...props }) {
|
|
839
|
+
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 }) {
|
|
734
840
|
const { colors } = useTheme();
|
|
735
841
|
const [focused, setFocused] = useState(false);
|
|
736
842
|
const [showPassword, setShowPassword] = useState(false);
|
|
737
|
-
const
|
|
843
|
+
const focusProgress = useColorTransition(focused, {
|
|
844
|
+
duration: focused ? TIMINGS.focusIn.duration : TIMINGS.focusOut.duration
|
|
845
|
+
});
|
|
738
846
|
const isDisabled = disabled || editable === false;
|
|
739
847
|
const isPassword = type === "password";
|
|
740
848
|
const effectiveSecure = isPassword ? !showPassword : secureTextEntry;
|
|
741
849
|
const effectivePrefix = prefixIcon ? renderIcon(prefixIcon, 20, prefixIconColor ?? colors.foregroundMuted) : prefix;
|
|
742
|
-
const effectiveSuffix = isPassword && !suffix && !suffixIcon ? /* @__PURE__ */ React26.createElement(
|
|
850
|
+
const effectiveSuffix = isPassword && !suffix && !suffixIcon ? /* @__PURE__ */ React26.createElement(
|
|
851
|
+
TouchableOpacity,
|
|
852
|
+
{
|
|
853
|
+
onPress: () => setShowPassword(!showPassword),
|
|
854
|
+
style: styles4.passwordToggle,
|
|
855
|
+
activeOpacity: 0.6,
|
|
856
|
+
accessibilityRole: "button",
|
|
857
|
+
accessibilityLabel: showPassword ? "Hide password" : "Show password"
|
|
858
|
+
},
|
|
859
|
+
/* @__PURE__ */ React26.createElement(AntDesign$1, { name: showPassword ? "eye" : "eye-invisible", size: 20, color: colors.foregroundMuted })
|
|
860
|
+
) : suffixIcon ? renderIcon(suffixIcon, 20, suffixIconColor ?? colors.foregroundMuted) : suffix;
|
|
861
|
+
const borderColorStyle = useAnimatedStyle(() => ({
|
|
862
|
+
borderColor: error ? colors.destructive : interpolateColor(focusProgress.value, [0, 1], [colors.border, colors.primary])
|
|
863
|
+
}));
|
|
743
864
|
return /* @__PURE__ */ React26.createElement(View, { style: [styles4.container, isDisabled && styles4.containerDisabled, containerStyle] }, label ? /* @__PURE__ */ React26.createElement(Text, { style: [styles4.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React26.createElement(
|
|
744
|
-
|
|
865
|
+
Animated9.View,
|
|
745
866
|
{
|
|
746
867
|
style: [
|
|
747
868
|
styles4.inputWrapper,
|
|
748
|
-
{
|
|
749
|
-
|
|
750
|
-
inputRange: [0, 1],
|
|
751
|
-
outputRange: [colors.border, colors.primary]
|
|
752
|
-
}),
|
|
753
|
-
backgroundColor: isDisabled ? colors.surface : colors.background
|
|
754
|
-
},
|
|
869
|
+
{ backgroundColor: isDisabled ? colors.surface : colors.background },
|
|
870
|
+
borderColorStyle,
|
|
755
871
|
inputWrapperStyle
|
|
756
872
|
]
|
|
757
873
|
},
|
|
@@ -761,31 +877,36 @@ function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suff
|
|
|
761
877
|
{
|
|
762
878
|
style: [
|
|
763
879
|
styles4.input,
|
|
764
|
-
{
|
|
765
|
-
color: colors.foreground
|
|
766
|
-
},
|
|
880
|
+
{ color: colors.foreground },
|
|
767
881
|
webInputResetStyle,
|
|
768
882
|
style
|
|
769
883
|
],
|
|
770
884
|
onFocus: (e) => {
|
|
771
885
|
setFocused(true);
|
|
772
|
-
Animated.timing(focusAnim, { toValue: 1, duration: 120, easing: Easing$1.out(Easing$1.ease), useNativeDriver: false }).start();
|
|
773
886
|
onFocus?.(e);
|
|
774
887
|
},
|
|
775
888
|
onBlur: (e) => {
|
|
776
889
|
setFocused(false);
|
|
777
|
-
Animated.timing(focusAnim, { toValue: 0, duration: 80, easing: Easing$1.out(Easing$1.ease), useNativeDriver: false }).start();
|
|
778
890
|
onBlur?.(e);
|
|
779
891
|
},
|
|
780
892
|
placeholderTextColor: colors.foregroundMuted,
|
|
781
893
|
allowFontScaling: true,
|
|
782
894
|
secureTextEntry: effectiveSecure,
|
|
783
895
|
editable: isDisabled ? false : editable,
|
|
896
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
784
897
|
...props
|
|
785
898
|
}
|
|
786
899
|
),
|
|
787
900
|
effectiveSuffix ? typeof effectiveSuffix === "string" ? /* @__PURE__ */ React26.createElement(Text, { style: [styles4.suffixText, { color: colors.foregroundMuted }, suffixStyle], allowFontScaling: true }, effectiveSuffix) : /* @__PURE__ */ React26.createElement(View, { style: styles4.suffixContainer }, effectiveSuffix) : null
|
|
788
|
-
), error ? /* @__PURE__ */ React26.createElement(
|
|
901
|
+
), error ? /* @__PURE__ */ React26.createElement(
|
|
902
|
+
Text,
|
|
903
|
+
{
|
|
904
|
+
style: [styles4.helperText, { color: colors.destructive }],
|
|
905
|
+
allowFontScaling: true,
|
|
906
|
+
accessibilityLiveRegion: "polite"
|
|
907
|
+
},
|
|
908
|
+
error
|
|
909
|
+
) : null, !error && hint ? /* @__PURE__ */ React26.createElement(Text, { style: [styles4.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
|
|
789
910
|
}
|
|
790
911
|
var styles4 = StyleSheet.create({
|
|
791
912
|
container: {
|
|
@@ -797,7 +918,6 @@ var styles4 = StyleSheet.create({
|
|
|
797
918
|
label: {
|
|
798
919
|
fontFamily: "Poppins-Medium",
|
|
799
920
|
fontSize: ms(14)
|
|
800
|
-
// caption size for input labels
|
|
801
921
|
},
|
|
802
922
|
inputWrapper: {
|
|
803
923
|
flexDirection: "row",
|
|
@@ -894,30 +1014,14 @@ var styles5 = StyleSheet.create({
|
|
|
894
1014
|
fontFamily: "Poppins-Medium"
|
|
895
1015
|
}
|
|
896
1016
|
});
|
|
897
|
-
|
|
898
|
-
function Card({ children, variant = "elevated", onPress, style }) {
|
|
1017
|
+
function Card({ children, variant = "elevated", onPress, style, accessibilityLabel }) {
|
|
899
1018
|
const { colors } = useTheme();
|
|
900
|
-
const
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
stiffness: 400,
|
|
907
|
-
damping: 30,
|
|
908
|
-
mass: 1
|
|
909
|
-
}).start();
|
|
910
|
-
};
|
|
911
|
-
const handlePressOut = () => {
|
|
912
|
-
if (!onPress) return;
|
|
913
|
-
Animated.spring(scale2, {
|
|
914
|
-
toValue: 1,
|
|
915
|
-
useNativeDriver: nativeDriver3,
|
|
916
|
-
stiffness: 250,
|
|
917
|
-
damping: 24,
|
|
918
|
-
mass: 1
|
|
919
|
-
}).start();
|
|
920
|
-
};
|
|
1019
|
+
const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
1020
|
+
pressScale: PRESS_SCALE.card,
|
|
1021
|
+
pressInSpring: SPRINGS.surfacePressIn,
|
|
1022
|
+
pressOutSpring: SPRINGS.surfacePressOut,
|
|
1023
|
+
disabled: !onPress
|
|
1024
|
+
});
|
|
921
1025
|
const handlePress = () => {
|
|
922
1026
|
if (!onPress) return;
|
|
923
1027
|
impactLight();
|
|
@@ -948,14 +1052,16 @@ function Card({ children, variant = "elevated", onPress, style }) {
|
|
|
948
1052
|
}[variant];
|
|
949
1053
|
const cardContent = /* @__PURE__ */ React26.createElement(View, { style: [styles6.card, variantStyle, style] }, children);
|
|
950
1054
|
if (onPress) {
|
|
951
|
-
return /* @__PURE__ */ React26.createElement(
|
|
1055
|
+
return /* @__PURE__ */ React26.createElement(Animated9.View, { style: animatedStyle, ...hoverHandlers }, /* @__PURE__ */ React26.createElement(
|
|
952
1056
|
TouchableOpacity,
|
|
953
1057
|
{
|
|
954
1058
|
onPress: handlePress,
|
|
955
|
-
onPressIn
|
|
956
|
-
onPressOut
|
|
1059
|
+
onPressIn,
|
|
1060
|
+
onPressOut,
|
|
957
1061
|
activeOpacity: 1,
|
|
958
|
-
touchSoundDisabled: true
|
|
1062
|
+
touchSoundDisabled: true,
|
|
1063
|
+
accessibilityRole: "button",
|
|
1064
|
+
accessibilityLabel
|
|
959
1065
|
},
|
|
960
1066
|
cardContent
|
|
961
1067
|
));
|
|
@@ -982,7 +1088,6 @@ function CardFooter({ children, style }) {
|
|
|
982
1088
|
var styles6 = StyleSheet.create({
|
|
983
1089
|
card: {
|
|
984
1090
|
borderRadius: RADIUS.md,
|
|
985
|
-
// 14px — Airbnb property card spec
|
|
986
1091
|
borderWidth: 1
|
|
987
1092
|
},
|
|
988
1093
|
header: {
|
|
@@ -1080,20 +1185,19 @@ function Skeleton({
|
|
|
1080
1185
|
style
|
|
1081
1186
|
}) {
|
|
1082
1187
|
const { colors, colorScheme } = useTheme();
|
|
1083
|
-
const
|
|
1188
|
+
const shimmer = useSharedValue(0);
|
|
1084
1189
|
const [containerWidth, setContainerWidth] = useState(300);
|
|
1085
1190
|
const shimmerHighlight = colorScheme === "dark" ? "rgba(255,255,255,0.08)" : "rgba(255,255,255,0.7)";
|
|
1086
1191
|
useEffect(() => {
|
|
1087
|
-
|
|
1088
|
-
|
|
1192
|
+
shimmer.value = withRepeat(
|
|
1193
|
+
withTiming(1, { duration: TIMINGS.shimmer.duration, easing: Easing.linear }),
|
|
1194
|
+
-1,
|
|
1195
|
+
false
|
|
1089
1196
|
);
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
inputRange: [0, 1],
|
|
1095
|
-
outputRange: [-containerWidth, containerWidth]
|
|
1096
|
-
});
|
|
1197
|
+
}, [shimmer]);
|
|
1198
|
+
const shimmerStyle = useAnimatedStyle(() => ({
|
|
1199
|
+
transform: [{ translateX: -containerWidth + shimmer.value * (containerWidth * 2) }]
|
|
1200
|
+
}));
|
|
1097
1201
|
const resolvedWidth = preset === "circle" ? s(diameter) : preset === "text" ? "60%" : width;
|
|
1098
1202
|
const resolvedHeight = preset === "circle" ? s(diameter) : preset === "text" ? 14 : height;
|
|
1099
1203
|
const resolvedRadius = preset === "circle" ? 9999 : preset === "text" ? 4 : borderRadius;
|
|
@@ -1105,9 +1209,12 @@ function Skeleton({
|
|
|
1105
1209
|
{ width: resolvedWidth, height: resolvedHeight, borderRadius: resolvedRadius, backgroundColor: colors.surface },
|
|
1106
1210
|
style
|
|
1107
1211
|
],
|
|
1108
|
-
onLayout: (e) => setContainerWidth(e.nativeEvent.layout.width)
|
|
1212
|
+
onLayout: (e) => setContainerWidth(e.nativeEvent.layout.width),
|
|
1213
|
+
accessibilityRole: "progressbar",
|
|
1214
|
+
accessibilityLabel: "Loading",
|
|
1215
|
+
accessibilityState: { busy: true }
|
|
1109
1216
|
},
|
|
1110
|
-
/* @__PURE__ */ React26.createElement(
|
|
1217
|
+
/* @__PURE__ */ React26.createElement(Animated9.View, { style: [StyleSheet.absoluteFill, shimmerStyle] }, /* @__PURE__ */ React26.createElement(
|
|
1111
1218
|
LinearGradient,
|
|
1112
1219
|
{
|
|
1113
1220
|
colors: ["transparent", shimmerHighlight, "transparent"],
|
|
@@ -1253,31 +1360,32 @@ var styles11 = StyleSheet.create({
|
|
|
1253
1360
|
lineHeight: ms(17)
|
|
1254
1361
|
}
|
|
1255
1362
|
});
|
|
1256
|
-
function Progress({ value = 0, max = 100, variant = "default", style }) {
|
|
1363
|
+
function Progress({ value = 0, max = 100, variant = "default", style, accessibilityLabel }) {
|
|
1257
1364
|
const { colors } = useTheme();
|
|
1258
1365
|
const percent = Math.min(Math.max(value / max * 100, 0), 100);
|
|
1259
1366
|
const [trackWidth, setTrackWidth] = useState(0);
|
|
1260
|
-
const animatedWidth =
|
|
1367
|
+
const animatedWidth = useSharedValue(0);
|
|
1261
1368
|
useEffect(() => {
|
|
1262
1369
|
if (trackWidth === 0) return;
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
}).start();
|
|
1269
|
-
}, [percent, trackWidth]);
|
|
1370
|
+
animatedWidth.value = withSpring(percent / 100 * trackWidth, SPRINGS.glide);
|
|
1371
|
+
}, [percent, trackWidth, animatedWidth]);
|
|
1372
|
+
const indicatorAnimatedStyle = useAnimatedStyle(() => ({
|
|
1373
|
+
width: animatedWidth.value
|
|
1374
|
+
}));
|
|
1270
1375
|
const indicatorColor = variant === "success" ? colors.success : variant === "warning" ? colors.warning : variant === "destructive" ? colors.destructive : colors.primary;
|
|
1271
1376
|
return /* @__PURE__ */ React26.createElement(
|
|
1272
1377
|
View,
|
|
1273
1378
|
{
|
|
1274
1379
|
style: [styles12.track, { backgroundColor: colors.surface }, style],
|
|
1275
|
-
onLayout: (e) => setTrackWidth(e.nativeEvent.layout.width)
|
|
1380
|
+
onLayout: (e) => setTrackWidth(e.nativeEvent.layout.width),
|
|
1381
|
+
accessibilityRole: "progressbar",
|
|
1382
|
+
accessibilityLabel,
|
|
1383
|
+
accessibilityValue: { min: 0, max: 100, now: Math.round(percent) }
|
|
1276
1384
|
},
|
|
1277
1385
|
/* @__PURE__ */ React26.createElement(
|
|
1278
|
-
|
|
1386
|
+
Animated9.View,
|
|
1279
1387
|
{
|
|
1280
|
-
style: [styles12.indicator, {
|
|
1388
|
+
style: [styles12.indicator, { backgroundColor: indicatorColor }, indicatorAnimatedStyle]
|
|
1281
1389
|
}
|
|
1282
1390
|
)
|
|
1283
1391
|
);
|
|
@@ -1394,20 +1502,25 @@ function Textarea({
|
|
|
1394
1502
|
style,
|
|
1395
1503
|
onFocus,
|
|
1396
1504
|
onBlur,
|
|
1505
|
+
accessibilityLabel,
|
|
1397
1506
|
...props
|
|
1398
1507
|
}) {
|
|
1399
1508
|
const { colors } = useTheme();
|
|
1400
1509
|
const [focused, setFocused] = useState(false);
|
|
1510
|
+
const focusProgress = useColorTransition(focused, {
|
|
1511
|
+
duration: focused ? TIMINGS.focusIn.duration : TIMINGS.focusOut.duration
|
|
1512
|
+
});
|
|
1401
1513
|
const resolvedPrefixIcon = prefixIcon ? renderIcon(prefixIcon, ms(16), prefixIconColor ?? colors.foregroundMuted) : prefixIconNode;
|
|
1514
|
+
const borderColorStyle = useAnimatedStyle(() => ({
|
|
1515
|
+
borderColor: error ? colors.destructive : interpolateColor(focusProgress.value, [0, 1], [colors.border, colors.primary])
|
|
1516
|
+
}));
|
|
1402
1517
|
return /* @__PURE__ */ React26.createElement(View, { style: [styles14.container, containerStyle] }, label ? /* @__PURE__ */ React26.createElement(Text, { style: [styles14.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React26.createElement(
|
|
1403
|
-
View,
|
|
1518
|
+
Animated9.View,
|
|
1404
1519
|
{
|
|
1405
1520
|
style: [
|
|
1406
1521
|
styles14.inputWrapper,
|
|
1407
|
-
{
|
|
1408
|
-
|
|
1409
|
-
backgroundColor: colors.background
|
|
1410
|
-
}
|
|
1522
|
+
{ backgroundColor: colors.background },
|
|
1523
|
+
borderColorStyle
|
|
1411
1524
|
]
|
|
1412
1525
|
},
|
|
1413
1526
|
resolvedPrefixIcon ? /* @__PURE__ */ React26.createElement(View, { style: styles14.prefixIcon }, resolvedPrefixIcon) : null,
|
|
@@ -1436,10 +1549,19 @@ function Textarea({
|
|
|
1436
1549
|
},
|
|
1437
1550
|
placeholderTextColor: colors.foregroundMuted,
|
|
1438
1551
|
allowFontScaling: true,
|
|
1552
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
1439
1553
|
...props
|
|
1440
1554
|
}
|
|
1441
1555
|
)
|
|
1442
|
-
), error ? /* @__PURE__ */ React26.createElement(
|
|
1556
|
+
), error ? /* @__PURE__ */ React26.createElement(
|
|
1557
|
+
Text,
|
|
1558
|
+
{
|
|
1559
|
+
style: [styles14.helperText, { color: colors.destructive }],
|
|
1560
|
+
allowFontScaling: true,
|
|
1561
|
+
accessibilityLiveRegion: "polite"
|
|
1562
|
+
},
|
|
1563
|
+
error
|
|
1564
|
+
) : null, !error && hint ? /* @__PURE__ */ React26.createElement(Text, { style: [styles14.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
|
|
1443
1565
|
}
|
|
1444
1566
|
var styles14 = StyleSheet.create({
|
|
1445
1567
|
container: {
|
|
@@ -1452,7 +1574,7 @@ var styles14 = StyleSheet.create({
|
|
|
1452
1574
|
marginBottom: vs(2)
|
|
1453
1575
|
},
|
|
1454
1576
|
inputWrapper: {
|
|
1455
|
-
borderWidth:
|
|
1577
|
+
borderWidth: 2,
|
|
1456
1578
|
borderRadius: 8,
|
|
1457
1579
|
paddingHorizontal: s(14),
|
|
1458
1580
|
paddingVertical: vs(11),
|
|
@@ -1477,47 +1599,27 @@ var styles14 = StyleSheet.create({
|
|
|
1477
1599
|
marginTop: vs(4)
|
|
1478
1600
|
}
|
|
1479
1601
|
});
|
|
1480
|
-
var nativeDriver4 = Platform.OS !== "web";
|
|
1481
1602
|
function Checkbox({
|
|
1482
1603
|
checked = false,
|
|
1483
1604
|
onCheckedChange,
|
|
1484
1605
|
label,
|
|
1485
1606
|
disabled,
|
|
1486
|
-
style
|
|
1607
|
+
style,
|
|
1608
|
+
accessibilityLabel
|
|
1487
1609
|
}) {
|
|
1488
1610
|
const { colors } = useTheme();
|
|
1489
|
-
const
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
useEffect(() => {
|
|
1493
|
-
Animated.parallel([
|
|
1494
|
-
Animated.timing(bgOpacity, {
|
|
1495
|
-
toValue: checked ? 1 : 0,
|
|
1496
|
-
duration: 150,
|
|
1497
|
-
useNativeDriver: false
|
|
1498
|
-
}),
|
|
1499
|
-
Animated.timing(checkOpacity, {
|
|
1500
|
-
toValue: checked ? 1 : 0,
|
|
1501
|
-
duration: 120,
|
|
1502
|
-
useNativeDriver: false
|
|
1503
|
-
})
|
|
1504
|
-
]).start();
|
|
1505
|
-
}, [checked, bgOpacity, checkOpacity]);
|
|
1506
|
-
const borderColor = bgOpacity.interpolate({
|
|
1507
|
-
inputRange: [0, 1],
|
|
1508
|
-
outputRange: [colors.border, colors.primary]
|
|
1509
|
-
});
|
|
1510
|
-
const backgroundColor = bgOpacity.interpolate({
|
|
1511
|
-
inputRange: [0, 1],
|
|
1512
|
-
outputRange: ["transparent", colors.primary]
|
|
1611
|
+
const { animatedStyle: scaleStyle, onPressIn, onPressOut } = usePressScale({
|
|
1612
|
+
pressScale: PRESS_SCALE.button,
|
|
1613
|
+
disabled
|
|
1513
1614
|
});
|
|
1514
|
-
const
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1615
|
+
const progress = useColorTransition(checked);
|
|
1616
|
+
const boxStyle = useAnimatedStyle(() => ({
|
|
1617
|
+
borderColor: interpolateColor(progress.value, [0, 1], [colors.border, colors.primary]),
|
|
1618
|
+
backgroundColor: interpolateColor(progress.value, [0, 1], ["transparent", colors.primary])
|
|
1619
|
+
}));
|
|
1620
|
+
const checkStyle = useAnimatedStyle(() => ({
|
|
1621
|
+
opacity: withTiming(checked ? 1 : 0, { duration: TIMINGS.state.duration, easing: EASINGS.standard })
|
|
1622
|
+
}));
|
|
1521
1623
|
return /* @__PURE__ */ React26.createElement(
|
|
1522
1624
|
TouchableOpacity,
|
|
1523
1625
|
{
|
|
@@ -1526,25 +1628,21 @@ function Checkbox({
|
|
|
1526
1628
|
selectionAsync();
|
|
1527
1629
|
onCheckedChange?.(!checked);
|
|
1528
1630
|
},
|
|
1529
|
-
onPressIn
|
|
1530
|
-
onPressOut
|
|
1631
|
+
onPressIn,
|
|
1632
|
+
onPressOut,
|
|
1531
1633
|
disabled,
|
|
1532
1634
|
activeOpacity: 1,
|
|
1533
|
-
touchSoundDisabled: true
|
|
1635
|
+
touchSoundDisabled: true,
|
|
1636
|
+
accessibilityRole: "checkbox",
|
|
1637
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
1638
|
+
accessibilityState: { checked, disabled: !!disabled }
|
|
1534
1639
|
},
|
|
1535
|
-
/* @__PURE__ */ React26.createElement(
|
|
1536
|
-
|
|
1640
|
+
/* @__PURE__ */ React26.createElement(Animated9.View, { style: scaleStyle }, /* @__PURE__ */ React26.createElement(
|
|
1641
|
+
Animated9.View,
|
|
1537
1642
|
{
|
|
1538
|
-
style: [
|
|
1539
|
-
styles15.box,
|
|
1540
|
-
{
|
|
1541
|
-
borderColor,
|
|
1542
|
-
backgroundColor,
|
|
1543
|
-
opacity: disabled ? 0.45 : 1
|
|
1544
|
-
}
|
|
1545
|
-
]
|
|
1643
|
+
style: [styles15.box, { opacity: disabled ? 0.45 : 1 }, boxStyle]
|
|
1546
1644
|
},
|
|
1547
|
-
/* @__PURE__ */ React26.createElement(
|
|
1645
|
+
/* @__PURE__ */ React26.createElement(Animated9.View, { style: checkStyle }, /* @__PURE__ */ React26.createElement(View, { style: [styles15.checkmark, { borderColor: colors.primaryForeground }] }))
|
|
1548
1646
|
)),
|
|
1549
1647
|
label ? /* @__PURE__ */ React26.createElement(
|
|
1550
1648
|
Text,
|
|
@@ -1583,47 +1681,34 @@ var styles15 = StyleSheet.create({
|
|
|
1583
1681
|
lineHeight: mvs(20)
|
|
1584
1682
|
}
|
|
1585
1683
|
});
|
|
1586
|
-
var nativeDriver5 = Platform.OS !== "web";
|
|
1587
1684
|
var TRACK_WIDTH = s(52);
|
|
1588
1685
|
var TRACK_HEIGHT = s(30);
|
|
1589
1686
|
var THUMB_SIZE = s(24);
|
|
1590
1687
|
var THUMB_OFFSET = s(3);
|
|
1591
1688
|
var THUMB_TRAVEL = TRACK_WIDTH - THUMB_SIZE - THUMB_OFFSET * 2;
|
|
1592
1689
|
var ICON_SIZE = s(13);
|
|
1593
|
-
function Switch({ checked = false, onCheckedChange, disabled, style }) {
|
|
1690
|
+
function Switch({ checked = false, onCheckedChange, disabled, style, accessibilityLabel }) {
|
|
1594
1691
|
const { colors } = useTheme();
|
|
1595
|
-
const
|
|
1596
|
-
const trackOpacity = useRef(new Animated.Value(checked ? 1 : 0)).current;
|
|
1597
|
-
const checkOpacity = useRef(new Animated.Value(checked ? 1 : 0)).current;
|
|
1598
|
-
const crossOpacity = useRef(new Animated.Value(checked ? 0 : 1)).current;
|
|
1692
|
+
const progress = useSharedValue(checked ? 1 : 0);
|
|
1599
1693
|
useEffect(() => {
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
duration: 120,
|
|
1619
|
-
useNativeDriver: true
|
|
1620
|
-
})
|
|
1621
|
-
]).start();
|
|
1622
|
-
}, [checked, translateX, trackOpacity, checkOpacity, crossOpacity]);
|
|
1623
|
-
const trackColor = trackOpacity.interpolate({
|
|
1624
|
-
inputRange: [0, 1],
|
|
1625
|
-
outputRange: [colors.surface, colors.primary]
|
|
1626
|
-
});
|
|
1694
|
+
progress.value = withSpring(checked ? 1 : 0, SPRINGS.elastic);
|
|
1695
|
+
}, [checked, progress]);
|
|
1696
|
+
const thumbStyle = useAnimatedStyle(() => ({
|
|
1697
|
+
transform: [{ translateX: progress.value * THUMB_TRAVEL }]
|
|
1698
|
+
}));
|
|
1699
|
+
const trackStyle = useAnimatedStyle(() => ({
|
|
1700
|
+
backgroundColor: interpolateColor(
|
|
1701
|
+
progress.value,
|
|
1702
|
+
[0, 1],
|
|
1703
|
+
[colors.surfaceStrong, colors.primary]
|
|
1704
|
+
)
|
|
1705
|
+
}));
|
|
1706
|
+
const checkIconStyle = useAnimatedStyle(() => ({
|
|
1707
|
+
opacity: withTiming(checked ? 1 : 0, { duration: TIMINGS.state.duration, easing: EASINGS.standard })
|
|
1708
|
+
}));
|
|
1709
|
+
const crossIconStyle = useAnimatedStyle(() => ({
|
|
1710
|
+
opacity: withTiming(checked ? 0 : 1, { duration: TIMINGS.state.duration, easing: EASINGS.standard })
|
|
1711
|
+
}));
|
|
1627
1712
|
return /* @__PURE__ */ React26.createElement(View, { style: [{ opacity: disabled ? 0.45 : 1 }, style] }, /* @__PURE__ */ React26.createElement(
|
|
1628
1713
|
TouchableOpacity,
|
|
1629
1714
|
{
|
|
@@ -1634,29 +1719,25 @@ function Switch({ checked = false, onCheckedChange, disabled, style }) {
|
|
|
1634
1719
|
disabled,
|
|
1635
1720
|
activeOpacity: 0.8,
|
|
1636
1721
|
touchSoundDisabled: true,
|
|
1637
|
-
|
|
1722
|
+
accessibilityRole: "switch",
|
|
1723
|
+
accessibilityLabel,
|
|
1724
|
+
accessibilityState: { checked, disabled: !!disabled }
|
|
1638
1725
|
},
|
|
1639
|
-
/* @__PURE__ */ React26.createElement(
|
|
1640
|
-
|
|
1726
|
+
/* @__PURE__ */ React26.createElement(Animated9.View, { style: [styles16.track, trackStyle] }, /* @__PURE__ */ React26.createElement(
|
|
1727
|
+
Animated9.View,
|
|
1641
1728
|
{
|
|
1642
|
-
style: [
|
|
1643
|
-
styles16.thumb,
|
|
1644
|
-
{ backgroundColor: colors.primaryForeground, transform: [{ translateX }] }
|
|
1645
|
-
]
|
|
1729
|
+
style: [styles16.thumb, { backgroundColor: colors.primaryForeground }, thumbStyle]
|
|
1646
1730
|
},
|
|
1647
|
-
/* @__PURE__ */ React26.createElement(
|
|
1648
|
-
/* @__PURE__ */ React26.createElement(
|
|
1731
|
+
/* @__PURE__ */ React26.createElement(Animated9.View, { style: [styles16.iconWrapper, checkIconStyle] }, /* @__PURE__ */ React26.createElement(Feather$1, { name: "check", size: ICON_SIZE, color: colors.primary })),
|
|
1732
|
+
/* @__PURE__ */ React26.createElement(Animated9.View, { style: [styles16.iconWrapper, crossIconStyle] }, /* @__PURE__ */ React26.createElement(Feather$1, { name: "x", size: ICON_SIZE, color: colors.foregroundMuted }))
|
|
1649
1733
|
))
|
|
1650
1734
|
));
|
|
1651
1735
|
}
|
|
1652
1736
|
var styles16 = StyleSheet.create({
|
|
1653
|
-
wrapper: {},
|
|
1654
1737
|
track: {
|
|
1655
1738
|
width: TRACK_WIDTH,
|
|
1656
1739
|
height: TRACK_HEIGHT,
|
|
1657
1740
|
borderRadius: TRACK_HEIGHT / 2
|
|
1658
|
-
// No justifyContent/alignItems — thumb uses absolute positioning
|
|
1659
|
-
// so the track's flex layout doesn't interfere with translateX animation
|
|
1660
1741
|
},
|
|
1661
1742
|
thumb: {
|
|
1662
1743
|
position: "absolute",
|
|
@@ -1677,7 +1758,6 @@ var styles16 = StyleSheet.create({
|
|
|
1677
1758
|
position: "absolute"
|
|
1678
1759
|
}
|
|
1679
1760
|
});
|
|
1680
|
-
var nativeDriver6 = Platform.OS !== "web";
|
|
1681
1761
|
var sizeStyles = {
|
|
1682
1762
|
sm: { paddingHorizontal: s(12), paddingVertical: vs(8), minWidth: s(40), minHeight: vs(40) },
|
|
1683
1763
|
md: { paddingHorizontal: s(16), paddingVertical: vs(12), minWidth: s(44), minHeight: vs(44) },
|
|
@@ -1698,38 +1778,23 @@ function Toggle({
|
|
|
1698
1778
|
activeIconColor,
|
|
1699
1779
|
disabled,
|
|
1700
1780
|
style,
|
|
1781
|
+
accessibilityLabel,
|
|
1701
1782
|
...props
|
|
1702
1783
|
}) {
|
|
1703
1784
|
const { colors } = useTheme();
|
|
1704
|
-
const
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
Animated.timing(pressAnim, {
|
|
1708
|
-
toValue: pressed ? 1 : 0,
|
|
1709
|
-
duration: 150,
|
|
1710
|
-
easing: Easing$1.out(Easing$1.ease),
|
|
1711
|
-
useNativeDriver: false
|
|
1712
|
-
}).start();
|
|
1713
|
-
}, [pressed, pressAnim]);
|
|
1714
|
-
const handlePressIn = () => {
|
|
1715
|
-
if (disabled) return;
|
|
1716
|
-
Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver6, stiffness: 600, damping: 35, mass: 0.8 }).start();
|
|
1717
|
-
};
|
|
1718
|
-
const handlePressOut = () => {
|
|
1719
|
-
Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver6, stiffness: 280, damping: 22, mass: 0.8 }).start();
|
|
1720
|
-
};
|
|
1721
|
-
const borderColor = pressAnim.interpolate({
|
|
1722
|
-
inputRange: [0, 1],
|
|
1723
|
-
outputRange: [variant === "outline" ? colors.border : "transparent", colors.primary]
|
|
1724
|
-
});
|
|
1725
|
-
const backgroundColor = pressAnim.interpolate({
|
|
1726
|
-
inputRange: [0, 1],
|
|
1727
|
-
outputRange: ["transparent", colors.surfaceStrong]
|
|
1728
|
-
});
|
|
1729
|
-
const textColor = pressAnim.interpolate({
|
|
1730
|
-
inputRange: [0, 1],
|
|
1731
|
-
outputRange: [colors.foreground, colors.primary]
|
|
1785
|
+
const { animatedStyle: scaleStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
1786
|
+
pressScale: PRESS_SCALE.button,
|
|
1787
|
+
disabled
|
|
1732
1788
|
});
|
|
1789
|
+
const progress = useColorTransition(pressed);
|
|
1790
|
+
const inactiveBorder = variant === "outline" ? colors.border : "transparent";
|
|
1791
|
+
const surfaceStyle = useAnimatedStyle(() => ({
|
|
1792
|
+
borderColor: interpolateColor(progress.value, [0, 1], [inactiveBorder, colors.primary]),
|
|
1793
|
+
backgroundColor: interpolateColor(progress.value, [0, 1], ["transparent", colors.surfaceStrong])
|
|
1794
|
+
}));
|
|
1795
|
+
const textStyle = useAnimatedStyle(() => ({
|
|
1796
|
+
color: interpolateColor(progress.value, [0, 1], [colors.foreground, colors.primary])
|
|
1797
|
+
}));
|
|
1733
1798
|
const iconSize = iconSizeMap2[size];
|
|
1734
1799
|
const LeftIcon = () => {
|
|
1735
1800
|
const renderProp = (prop) => {
|
|
@@ -1748,32 +1813,43 @@ function Toggle({
|
|
|
1748
1813
|
if (custom) return /* @__PURE__ */ React26.createElement(React26.Fragment, null, custom);
|
|
1749
1814
|
return /* @__PURE__ */ React26.createElement(FontAwesome5$1, { name: "circle", size: iconSize, color: colors.foregroundMuted });
|
|
1750
1815
|
};
|
|
1751
|
-
return /* @__PURE__ */ React26.createElement(
|
|
1752
|
-
|
|
1816
|
+
return /* @__PURE__ */ React26.createElement(
|
|
1817
|
+
Animated9.View,
|
|
1753
1818
|
{
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
onPressedChange?.(!pressed);
|
|
1757
|
-
},
|
|
1758
|
-
onPressIn: handlePressIn,
|
|
1759
|
-
onPressOut: handlePressOut,
|
|
1760
|
-
disabled,
|
|
1761
|
-
activeOpacity: 1,
|
|
1762
|
-
touchSoundDisabled: true,
|
|
1763
|
-
...props
|
|
1819
|
+
style: [scaleStyle, disabled && styles17.disabled, style],
|
|
1820
|
+
...hoverHandlers
|
|
1764
1821
|
},
|
|
1765
1822
|
/* @__PURE__ */ React26.createElement(
|
|
1766
|
-
|
|
1823
|
+
TouchableOpacity,
|
|
1767
1824
|
{
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1825
|
+
onPress: () => {
|
|
1826
|
+
selectionAsync();
|
|
1827
|
+
onPressedChange?.(!pressed);
|
|
1828
|
+
},
|
|
1829
|
+
onPressIn,
|
|
1830
|
+
onPressOut,
|
|
1831
|
+
disabled,
|
|
1832
|
+
activeOpacity: 1,
|
|
1833
|
+
touchSoundDisabled: true,
|
|
1834
|
+
accessibilityRole: "button",
|
|
1835
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
1836
|
+
accessibilityState: { selected: pressed, disabled: !!disabled },
|
|
1837
|
+
...props
|
|
1773
1838
|
},
|
|
1774
|
-
/* @__PURE__ */ React26.createElement(
|
|
1839
|
+
/* @__PURE__ */ React26.createElement(
|
|
1840
|
+
Animated9.View,
|
|
1841
|
+
{
|
|
1842
|
+
style: [
|
|
1843
|
+
styles17.base,
|
|
1844
|
+
sizeStyles[size],
|
|
1845
|
+
{ borderWidth: 2 },
|
|
1846
|
+
surfaceStyle
|
|
1847
|
+
]
|
|
1848
|
+
},
|
|
1849
|
+
/* @__PURE__ */ React26.createElement(View, { style: styles17.inner }, /* @__PURE__ */ React26.createElement(LeftIcon, null), label ? /* @__PURE__ */ React26.createElement(Animated9.Text, { style: [styles17.label, textStyle], allowFontScaling: true }, label) : null)
|
|
1850
|
+
)
|
|
1775
1851
|
)
|
|
1776
|
-
)
|
|
1852
|
+
);
|
|
1777
1853
|
}
|
|
1778
1854
|
var styles17 = StyleSheet.create({
|
|
1779
1855
|
base: {
|
|
@@ -1793,21 +1869,28 @@ var styles17 = StyleSheet.create({
|
|
|
1793
1869
|
fontSize: ms(14)
|
|
1794
1870
|
}
|
|
1795
1871
|
});
|
|
1796
|
-
var nativeDriver7 = Platform.OS !== "web";
|
|
1797
1872
|
function RadioItem({
|
|
1798
1873
|
option,
|
|
1799
1874
|
selected,
|
|
1800
1875
|
onSelect
|
|
1801
1876
|
}) {
|
|
1802
1877
|
const { colors } = useTheme();
|
|
1803
|
-
const
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
const
|
|
1809
|
-
|
|
1810
|
-
|
|
1878
|
+
const { animatedStyle: scaleStyle, onPressIn, onPressOut } = usePressScale({
|
|
1879
|
+
pressScale: PRESS_SCALE.button,
|
|
1880
|
+
disabled: option.disabled
|
|
1881
|
+
});
|
|
1882
|
+
const colorProgress = useColorTransition(selected);
|
|
1883
|
+
const dotScale = useSharedValue(selected ? 1 : 0);
|
|
1884
|
+
useEffect(() => {
|
|
1885
|
+
dotScale.value = withSpring(selected ? 1 : 0, SPRINGS.elastic);
|
|
1886
|
+
}, [selected, dotScale]);
|
|
1887
|
+
const radioStyle = useAnimatedStyle(() => ({
|
|
1888
|
+
borderColor: interpolateColor(colorProgress.value, [0, 1], [colors.border, colors.primary])
|
|
1889
|
+
}));
|
|
1890
|
+
const dotStyle = useAnimatedStyle(() => ({
|
|
1891
|
+
transform: [{ scale: dotScale.value }],
|
|
1892
|
+
opacity: dotScale.value
|
|
1893
|
+
}));
|
|
1811
1894
|
return /* @__PURE__ */ React26.createElement(
|
|
1812
1895
|
TouchableOpacity,
|
|
1813
1896
|
{
|
|
@@ -1818,26 +1901,26 @@ function RadioItem({
|
|
|
1818
1901
|
onSelect();
|
|
1819
1902
|
}
|
|
1820
1903
|
},
|
|
1821
|
-
onPressIn
|
|
1822
|
-
onPressOut
|
|
1904
|
+
onPressIn,
|
|
1905
|
+
onPressOut,
|
|
1823
1906
|
activeOpacity: 1,
|
|
1824
1907
|
touchSoundDisabled: true,
|
|
1825
|
-
disabled: option.disabled
|
|
1908
|
+
disabled: option.disabled,
|
|
1909
|
+
accessibilityRole: "radio",
|
|
1910
|
+
accessibilityLabel: option.label,
|
|
1911
|
+
accessibilityState: { checked: selected, disabled: !!option.disabled }
|
|
1826
1912
|
},
|
|
1827
|
-
/* @__PURE__ */ React26.createElement(
|
|
1828
|
-
|
|
1913
|
+
/* @__PURE__ */ React26.createElement(Animated9.View, { style: scaleStyle }, /* @__PURE__ */ React26.createElement(
|
|
1914
|
+
Animated9.View,
|
|
1829
1915
|
{
|
|
1830
1916
|
style: [
|
|
1831
1917
|
styles18.radio,
|
|
1832
|
-
{
|
|
1833
|
-
|
|
1834
|
-
opacity: option.disabled ? 0.45 : 1,
|
|
1835
|
-
transform: [{ scale: scale2 }]
|
|
1836
|
-
}
|
|
1918
|
+
{ opacity: option.disabled ? 0.45 : 1 },
|
|
1919
|
+
radioStyle
|
|
1837
1920
|
]
|
|
1838
1921
|
},
|
|
1839
|
-
|
|
1840
|
-
),
|
|
1922
|
+
/* @__PURE__ */ React26.createElement(Animated9.View, { style: [styles18.dot, { backgroundColor: colors.primary }, dotStyle] })
|
|
1923
|
+
)),
|
|
1841
1924
|
/* @__PURE__ */ React26.createElement(
|
|
1842
1925
|
Text,
|
|
1843
1926
|
{
|
|
@@ -1856,17 +1939,26 @@ function RadioGroup({
|
|
|
1856
1939
|
value,
|
|
1857
1940
|
onValueChange,
|
|
1858
1941
|
orientation = "vertical",
|
|
1859
|
-
style
|
|
1942
|
+
style,
|
|
1943
|
+
accessibilityLabel
|
|
1860
1944
|
}) {
|
|
1861
|
-
return /* @__PURE__ */ React26.createElement(
|
|
1862
|
-
|
|
1945
|
+
return /* @__PURE__ */ React26.createElement(
|
|
1946
|
+
View,
|
|
1863
1947
|
{
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1948
|
+
style: [styles18.container, orientation === "horizontal" && styles18.horizontal, style],
|
|
1949
|
+
accessibilityRole: "radiogroup",
|
|
1950
|
+
accessibilityLabel
|
|
1951
|
+
},
|
|
1952
|
+
options.map((option) => /* @__PURE__ */ React26.createElement(
|
|
1953
|
+
RadioItem,
|
|
1954
|
+
{
|
|
1955
|
+
key: option.value,
|
|
1956
|
+
option,
|
|
1957
|
+
selected: option.value === value,
|
|
1958
|
+
onSelect: () => onValueChange?.(option.value)
|
|
1959
|
+
}
|
|
1960
|
+
))
|
|
1961
|
+
);
|
|
1870
1962
|
}
|
|
1871
1963
|
var styles18 = StyleSheet.create({
|
|
1872
1964
|
container: {
|
|
@@ -1900,7 +1992,6 @@ var styles18 = StyleSheet.create({
|
|
|
1900
1992
|
lineHeight: mvs(20)
|
|
1901
1993
|
}
|
|
1902
1994
|
});
|
|
1903
|
-
var nativeDriver8 = Platform.OS !== "web";
|
|
1904
1995
|
function TabTrigger({
|
|
1905
1996
|
tab,
|
|
1906
1997
|
isActive,
|
|
@@ -1909,13 +2000,9 @@ function TabTrigger({
|
|
|
1909
2000
|
variant
|
|
1910
2001
|
}) {
|
|
1911
2002
|
const { colors } = useTheme();
|
|
1912
|
-
const
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
};
|
|
1916
|
-
const handlePressOut = () => {
|
|
1917
|
-
Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver8, stiffness: 280, damping: 22, mass: 0.8 }).start();
|
|
1918
|
-
};
|
|
2003
|
+
const { animatedStyle, onPressIn, onPressOut } = usePressScale({
|
|
2004
|
+
pressScale: PRESS_SCALE.button
|
|
2005
|
+
});
|
|
1919
2006
|
const isUnderline = variant === "underline";
|
|
1920
2007
|
return /* @__PURE__ */ React26.createElement(
|
|
1921
2008
|
TouchableOpacity,
|
|
@@ -1926,13 +2013,16 @@ function TabTrigger({
|
|
|
1926
2013
|
isUnderline && isActive && { borderBottomColor: colors.primary }
|
|
1927
2014
|
],
|
|
1928
2015
|
onPress,
|
|
1929
|
-
onPressIn
|
|
1930
|
-
onPressOut
|
|
2016
|
+
onPressIn,
|
|
2017
|
+
onPressOut,
|
|
1931
2018
|
onLayout,
|
|
1932
2019
|
activeOpacity: 1,
|
|
1933
|
-
touchSoundDisabled: true
|
|
2020
|
+
touchSoundDisabled: true,
|
|
2021
|
+
accessibilityRole: "tab",
|
|
2022
|
+
accessibilityState: { selected: isActive },
|
|
2023
|
+
accessibilityLabel: tab.label
|
|
1934
2024
|
},
|
|
1935
|
-
/* @__PURE__ */ React26.createElement(
|
|
2025
|
+
/* @__PURE__ */ React26.createElement(Animated9.View, { style: animatedStyle }, /* @__PURE__ */ React26.createElement(View, { style: styles19.triggerInner }, tab.icon ? typeof tab.icon === "function" ? tab.icon(isActive) : tab.icon : null, /* @__PURE__ */ React26.createElement(
|
|
1936
2026
|
Text,
|
|
1937
2027
|
{
|
|
1938
2028
|
style: [
|
|
@@ -1951,20 +2041,18 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
|
|
|
1951
2041
|
const { colors } = useTheme();
|
|
1952
2042
|
const active = value ?? internal;
|
|
1953
2043
|
const tabLayouts = useRef({});
|
|
1954
|
-
const pillX =
|
|
1955
|
-
const pillWidth =
|
|
2044
|
+
const pillX = useSharedValue(0);
|
|
2045
|
+
const pillWidth = useSharedValue(0);
|
|
1956
2046
|
const initialised = useRef(false);
|
|
1957
2047
|
const animatePill = (tabValue, animate) => {
|
|
1958
2048
|
const layout = tabLayouts.current[tabValue];
|
|
1959
2049
|
if (!layout) return;
|
|
1960
2050
|
if (animate) {
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
Animated.spring(pillWidth, { toValue: layout.width, useNativeDriver: false, stiffness: 380, damping: 38, mass: 1 })
|
|
1964
|
-
]).start();
|
|
2051
|
+
pillX.value = withSpring(layout.x, SPRINGS.glide);
|
|
2052
|
+
pillWidth.value = withSpring(layout.width, SPRINGS.glide);
|
|
1965
2053
|
} else {
|
|
1966
|
-
pillX.
|
|
1967
|
-
pillWidth.
|
|
2054
|
+
pillX.value = layout.x;
|
|
2055
|
+
pillWidth.value = layout.width;
|
|
1968
2056
|
}
|
|
1969
2057
|
};
|
|
1970
2058
|
useEffect(() => {
|
|
@@ -1975,51 +2063,63 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
|
|
|
1975
2063
|
if (!value) setInternal(v);
|
|
1976
2064
|
onValueChange?.(v);
|
|
1977
2065
|
};
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
2066
|
+
const pillAnimatedStyle = useAnimatedStyle(() => ({
|
|
2067
|
+
transform: [{ translateX: pillX.value }],
|
|
2068
|
+
width: pillWidth.value
|
|
2069
|
+
}));
|
|
2070
|
+
return /* @__PURE__ */ React26.createElement(View, { style }, /* @__PURE__ */ React26.createElement(
|
|
2071
|
+
View,
|
|
1982
2072
|
{
|
|
1983
2073
|
style: [
|
|
1984
|
-
styles19.
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2074
|
+
variant === "pill" ? [styles19.list, { backgroundColor: colors.surface }] : styles19.listUnderline
|
|
2075
|
+
],
|
|
2076
|
+
accessibilityRole: "tablist"
|
|
2077
|
+
},
|
|
2078
|
+
variant === "pill" && /* @__PURE__ */ React26.createElement(
|
|
2079
|
+
Animated9.View,
|
|
2080
|
+
{
|
|
2081
|
+
style: [
|
|
2082
|
+
styles19.pill,
|
|
2083
|
+
{
|
|
2084
|
+
backgroundColor: colors.background,
|
|
2085
|
+
position: "absolute",
|
|
2086
|
+
top: 4,
|
|
2087
|
+
bottom: 4,
|
|
2088
|
+
left: 0,
|
|
2089
|
+
borderRadius: 8,
|
|
2090
|
+
shadowColor: "#000",
|
|
2091
|
+
shadowOffset: { width: 0, height: 1 },
|
|
2092
|
+
shadowOpacity: 0.08,
|
|
2093
|
+
shadowRadius: 2,
|
|
2094
|
+
elevation: 2
|
|
2095
|
+
},
|
|
2096
|
+
pillAnimatedStyle
|
|
2097
|
+
]
|
|
2098
|
+
}
|
|
2099
|
+
),
|
|
2100
|
+
tabs.map((tab) => /* @__PURE__ */ React26.createElement(
|
|
2101
|
+
TabTrigger,
|
|
2102
|
+
{
|
|
2103
|
+
key: tab.value,
|
|
2104
|
+
tab,
|
|
2105
|
+
isActive: tab.value === active,
|
|
2106
|
+
onPress: () => handlePress(tab.value),
|
|
2107
|
+
variant,
|
|
2108
|
+
onLayout: (e) => {
|
|
2109
|
+
const { x, width } = e.nativeEvent.layout;
|
|
2110
|
+
tabLayouts.current[tab.value] = { x, width };
|
|
2111
|
+
if (tab.value === active) {
|
|
2112
|
+
animatePill(tab.value, false);
|
|
2113
|
+
initialised.current = true;
|
|
2114
|
+
}
|
|
2015
2115
|
}
|
|
2016
2116
|
}
|
|
2017
|
-
|
|
2018
|
-
)
|
|
2117
|
+
))
|
|
2118
|
+
), children);
|
|
2019
2119
|
}
|
|
2020
2120
|
function TabsContent({ value, activeValue, children, style }) {
|
|
2021
2121
|
if (value !== activeValue) return null;
|
|
2022
|
-
return /* @__PURE__ */ React26.createElement(View, { style }, children);
|
|
2122
|
+
return /* @__PURE__ */ React26.createElement(View, { style, accessibilityRole: "none" }, children);
|
|
2023
2123
|
}
|
|
2024
2124
|
var styles19 = StyleSheet.create({
|
|
2025
2125
|
list: {
|
|
@@ -2068,8 +2168,6 @@ var styles19 = StyleSheet.create({
|
|
|
2068
2168
|
fontSize: ms(14)
|
|
2069
2169
|
}
|
|
2070
2170
|
});
|
|
2071
|
-
var easingExpand = Easing.bezier(0.23, 1, 0.32, 1);
|
|
2072
|
-
var easingCollapse = Easing.in(Easing.ease);
|
|
2073
2171
|
function AccordionItemComponent({
|
|
2074
2172
|
item,
|
|
2075
2173
|
isOpen,
|
|
@@ -2084,14 +2182,14 @@ function AccordionItemComponent({
|
|
|
2084
2182
|
}, [isOpen]);
|
|
2085
2183
|
const derivedHeight = useDerivedValue(
|
|
2086
2184
|
() => withTiming(height.value * Number(isExpanded.value), {
|
|
2087
|
-
duration:
|
|
2088
|
-
easing: isExpanded.value ?
|
|
2185
|
+
duration: isExpanded.value ? TIMINGS.expand.duration : TIMINGS.collapse.duration,
|
|
2186
|
+
easing: isExpanded.value ? EASINGS.expand : EASINGS.collapse
|
|
2089
2187
|
})
|
|
2090
2188
|
);
|
|
2091
2189
|
const derivedRotation = useDerivedValue(
|
|
2092
2190
|
() => withTiming(isExpanded.value ? 1 : 0, {
|
|
2093
|
-
duration:
|
|
2094
|
-
easing: isExpanded.value ?
|
|
2191
|
+
duration: isExpanded.value ? TIMINGS.expand.duration : TIMINGS.collapse.duration,
|
|
2192
|
+
easing: isExpanded.value ? EASINGS.expand : EASINGS.collapse
|
|
2095
2193
|
})
|
|
2096
2194
|
);
|
|
2097
2195
|
const bodyStyle = useAnimatedStyle(() => ({
|
|
@@ -2108,11 +2206,14 @@ function AccordionItemComponent({
|
|
|
2108
2206
|
onPress: () => {
|
|
2109
2207
|
selectionAsync();
|
|
2110
2208
|
onToggle();
|
|
2111
|
-
}
|
|
2209
|
+
},
|
|
2210
|
+
accessibilityRole: "button",
|
|
2211
|
+
accessibilityState: { expanded: isOpen },
|
|
2212
|
+
accessibilityLabel: item.trigger
|
|
2112
2213
|
},
|
|
2113
2214
|
/* @__PURE__ */ React26.createElement(View, { style: styles20.triggerContent }, resolvedIcon ? /* @__PURE__ */ React26.createElement(View, { style: styles20.icon }, resolvedIcon) : null, /* @__PURE__ */ React26.createElement(Text, { style: [styles20.triggerText, { color: colors.foreground }], allowFontScaling: true }, item.trigger)),
|
|
2114
|
-
/* @__PURE__ */ React26.createElement(
|
|
2115
|
-
), /* @__PURE__ */ React26.createElement(
|
|
2215
|
+
/* @__PURE__ */ React26.createElement(Animated9.View, { style: [styles20.chevron, rotationStyle] }, /* @__PURE__ */ React26.createElement(Entypo$1, { name: "chevron-down", size: 18, color: colors.foregroundMuted }))
|
|
2216
|
+
), /* @__PURE__ */ React26.createElement(Animated9.View, { style: bodyStyle }, /* @__PURE__ */ React26.createElement(
|
|
2116
2217
|
View,
|
|
2117
2218
|
{
|
|
2118
2219
|
style: styles20.content,
|
|
@@ -2212,23 +2313,38 @@ function Slider({
|
|
|
2212
2313
|
}
|
|
2213
2314
|
onValueChange?.(v);
|
|
2214
2315
|
};
|
|
2215
|
-
return /* @__PURE__ */ React26.createElement(
|
|
2216
|
-
|
|
2316
|
+
return /* @__PURE__ */ React26.createElement(
|
|
2317
|
+
View,
|
|
2217
2318
|
{
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2319
|
+
style: [styles21.wrapper, style],
|
|
2320
|
+
accessibilityRole: "adjustable",
|
|
2321
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
2322
|
+
accessibilityValue: {
|
|
2323
|
+
min: minimumValue,
|
|
2324
|
+
max: maximumValue,
|
|
2325
|
+
now: value,
|
|
2326
|
+
text: formatValue2(value)
|
|
2327
|
+
}
|
|
2328
|
+
},
|
|
2329
|
+
label || showValue ? /* @__PURE__ */ React26.createElement(View, { style: styles21.header }, label ? /* @__PURE__ */ React26.createElement(Text, { style: [styles21.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, showValue ? /* @__PURE__ */ React26.createElement(Text, { style: [styles21.valueText, { color: colors.foregroundMuted }], allowFontScaling: true }, formatValue2(value)) : null) : null,
|
|
2330
|
+
/* @__PURE__ */ React26.createElement(View, { style: disabled ? styles21.disabled : void 0 }, /* @__PURE__ */ React26.createElement(
|
|
2331
|
+
RNSlider,
|
|
2332
|
+
{
|
|
2333
|
+
value,
|
|
2334
|
+
minimumValue,
|
|
2335
|
+
maximumValue,
|
|
2336
|
+
step: step || 0,
|
|
2337
|
+
disabled,
|
|
2338
|
+
onValueChange: handleValueChange,
|
|
2339
|
+
onSlidingComplete,
|
|
2340
|
+
minimumTrackTintColor: colors.primary,
|
|
2341
|
+
maximumTrackTintColor: colors.surface,
|
|
2342
|
+
thumbTintColor: colors.primary,
|
|
2343
|
+
style: styles21.slider,
|
|
2344
|
+
accessibilityLabel
|
|
2345
|
+
}
|
|
2346
|
+
))
|
|
2347
|
+
);
|
|
2232
2348
|
}
|
|
2233
2349
|
var styles21 = StyleSheet.create({
|
|
2234
2350
|
wrapper: {
|
|
@@ -2304,13 +2420,16 @@ function Sheet({
|
|
|
2304
2420
|
}, [footer]);
|
|
2305
2421
|
const effectiveSubtitle = subtitle ?? description;
|
|
2306
2422
|
const showHeader = !!(title || effectiveSubtitle || showCloseButton);
|
|
2307
|
-
const headerNode = showHeader ? /* @__PURE__ */ React26.createElement(View, { style: styles22.header }, /* @__PURE__ */ React26.createElement(View, { style: styles22.headerRow }, title ? /* @__PURE__ */ React26.createElement(Text, { style: [styles22.title, { color: colors.foreground }], allowFontScaling: true }, title) : /* @__PURE__ */ React26.createElement(View, { style: { flex: 1 } }), showCloseButton ? /* @__PURE__ */ React26.createElement(
|
|
2423
|
+
const headerNode = showHeader ? /* @__PURE__ */ React26.createElement(View, { style: styles22.header, accessibilityRole: "header" }, /* @__PURE__ */ React26.createElement(View, { style: styles22.headerRow }, title ? /* @__PURE__ */ React26.createElement(Text, { style: [styles22.title, { color: colors.foreground }], allowFontScaling: true }, title) : /* @__PURE__ */ React26.createElement(View, { style: { flex: 1 } }), showCloseButton ? /* @__PURE__ */ React26.createElement(
|
|
2308
2424
|
TouchableOpacity,
|
|
2309
2425
|
{
|
|
2310
2426
|
onPress: onClose,
|
|
2311
2427
|
style: styles22.closeButton,
|
|
2312
2428
|
activeOpacity: 0.6,
|
|
2313
|
-
touchSoundDisabled: true
|
|
2429
|
+
touchSoundDisabled: true,
|
|
2430
|
+
accessibilityRole: "button",
|
|
2431
|
+
accessibilityLabel: "Close",
|
|
2432
|
+
hitSlop: { top: 12, bottom: 12, left: 12, right: 12 }
|
|
2314
2433
|
},
|
|
2315
2434
|
/* @__PURE__ */ React26.createElement(AntDesign$1, { name: "close", size: ms(18), color: colors.foregroundMuted })
|
|
2316
2435
|
) : null), effectiveSubtitle ? /* @__PURE__ */ React26.createElement(Text, { style: [styles22.subtitle, { color: colors.foregroundMuted }], allowFontScaling: true }, effectiveSubtitle) : null) : null;
|
|
@@ -2401,7 +2520,6 @@ var styles22 = StyleSheet.create({
|
|
|
2401
2520
|
var isIOS = Platform.OS === "ios";
|
|
2402
2521
|
var isAndroid2 = Platform.OS === "android";
|
|
2403
2522
|
var isWeb2 = Platform.OS === "web";
|
|
2404
|
-
var nativeDriver9 = Platform.OS !== "web";
|
|
2405
2523
|
function Select({
|
|
2406
2524
|
options,
|
|
2407
2525
|
value,
|
|
@@ -2410,21 +2528,18 @@ function Select({
|
|
|
2410
2528
|
label,
|
|
2411
2529
|
error,
|
|
2412
2530
|
disabled,
|
|
2413
|
-
style
|
|
2531
|
+
style,
|
|
2532
|
+
accessibilityLabel
|
|
2414
2533
|
}) {
|
|
2415
2534
|
const { colors } = useTheme();
|
|
2416
|
-
const
|
|
2535
|
+
const { animatedStyle, onPressIn, onPressOut } = usePressScale({
|
|
2536
|
+
pressScale: PRESS_SCALE.button,
|
|
2537
|
+
disabled
|
|
2538
|
+
});
|
|
2417
2539
|
const [pickerVisible, setPickerVisible] = useState(false);
|
|
2418
2540
|
const [pendingValue, setPendingValue] = useState(value);
|
|
2419
2541
|
const pickerRef = useRef(null);
|
|
2420
2542
|
const selected = options.find((o) => o.value === value);
|
|
2421
|
-
const handlePressIn = () => {
|
|
2422
|
-
if (disabled) return;
|
|
2423
|
-
Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver9, speed: 40, bounciness: 0 }).start();
|
|
2424
|
-
};
|
|
2425
|
-
const handlePressOut = () => {
|
|
2426
|
-
Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver9, speed: 40, bounciness: 4 }).start();
|
|
2427
|
-
};
|
|
2428
2543
|
const handleOpen = () => {
|
|
2429
2544
|
if (disabled) return;
|
|
2430
2545
|
selectionAsync();
|
|
@@ -2445,7 +2560,7 @@ function Select({
|
|
|
2445
2560
|
}
|
|
2446
2561
|
setPickerVisible(false);
|
|
2447
2562
|
};
|
|
2448
|
-
return /* @__PURE__ */ React26.createElement(View, { style: [styles23.container, style] }, label ? /* @__PURE__ */ React26.createElement(Text, { style: [styles23.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, !isWeb2 ? /* @__PURE__ */ React26.createElement(
|
|
2563
|
+
return /* @__PURE__ */ React26.createElement(View, { style: [styles23.container, style] }, label ? /* @__PURE__ */ React26.createElement(Text, { style: [styles23.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, !isWeb2 ? /* @__PURE__ */ React26.createElement(Animated9.View, { style: [animatedStyle, { opacity: disabled ? 0.45 : 1 }] }, /* @__PURE__ */ React26.createElement(
|
|
2449
2564
|
TouchableOpacity,
|
|
2450
2565
|
{
|
|
2451
2566
|
style: [
|
|
@@ -2456,10 +2571,14 @@ function Select({
|
|
|
2456
2571
|
}
|
|
2457
2572
|
],
|
|
2458
2573
|
onPress: handleOpen,
|
|
2459
|
-
onPressIn
|
|
2460
|
-
onPressOut
|
|
2574
|
+
onPressIn,
|
|
2575
|
+
onPressOut,
|
|
2461
2576
|
activeOpacity: 1,
|
|
2462
|
-
touchSoundDisabled: true
|
|
2577
|
+
touchSoundDisabled: true,
|
|
2578
|
+
accessibilityRole: "combobox",
|
|
2579
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
2580
|
+
accessibilityValue: { text: selected?.label ?? placeholder },
|
|
2581
|
+
accessibilityState: { disabled: !!disabled, expanded: pickerVisible }
|
|
2463
2582
|
},
|
|
2464
2583
|
/* @__PURE__ */ React26.createElement(
|
|
2465
2584
|
Text,
|
|
@@ -2773,7 +2892,6 @@ var styles24 = StyleSheet.create({
|
|
|
2773
2892
|
textAlignVertical: "top"
|
|
2774
2893
|
}
|
|
2775
2894
|
});
|
|
2776
|
-
var nativeDriver10 = Platform.OS !== "web";
|
|
2777
2895
|
function ListItem({
|
|
2778
2896
|
leftRender,
|
|
2779
2897
|
rightRender,
|
|
@@ -2794,29 +2912,16 @@ function ListItem({
|
|
|
2794
2912
|
style,
|
|
2795
2913
|
titleStyle,
|
|
2796
2914
|
subtitleStyle,
|
|
2797
|
-
captionStyle
|
|
2915
|
+
captionStyle,
|
|
2916
|
+
accessibilityLabel
|
|
2798
2917
|
}) {
|
|
2799
2918
|
const { colors } = useTheme();
|
|
2800
|
-
const
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
stiffness: 350,
|
|
2807
|
-
damping: 28,
|
|
2808
|
-
mass: 0.9
|
|
2809
|
-
}).start();
|
|
2810
|
-
};
|
|
2811
|
-
const handlePressOut = () => {
|
|
2812
|
-
Animated.spring(scale2, {
|
|
2813
|
-
toValue: 1,
|
|
2814
|
-
useNativeDriver: nativeDriver10,
|
|
2815
|
-
stiffness: 220,
|
|
2816
|
-
damping: 20,
|
|
2817
|
-
mass: 0.9
|
|
2818
|
-
}).start();
|
|
2819
|
-
};
|
|
2919
|
+
const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
2920
|
+
pressScale: PRESS_SCALE.row,
|
|
2921
|
+
pressInSpring: SPRINGS.surfacePressIn,
|
|
2922
|
+
pressOutSpring: SPRINGS.surfacePressOut,
|
|
2923
|
+
disabled: !onPress || disabled
|
|
2924
|
+
});
|
|
2820
2925
|
const handlePress = () => {
|
|
2821
2926
|
selectionAsync();
|
|
2822
2927
|
onPress?.();
|
|
@@ -2834,16 +2939,20 @@ function ListItem({
|
|
|
2834
2939
|
shadowRadius: 6,
|
|
2835
2940
|
elevation: 2
|
|
2836
2941
|
} : {};
|
|
2837
|
-
|
|
2942
|
+
const a11yLabel = accessibilityLabel ?? [title, subtitle, caption].filter(Boolean).join(". ");
|
|
2943
|
+
return /* @__PURE__ */ React26.createElement(Animated9.View, { style: [animatedStyle, disabled && styles25.disabled], ...hoverHandlers }, /* @__PURE__ */ React26.createElement(
|
|
2838
2944
|
TouchableOpacity,
|
|
2839
2945
|
{
|
|
2840
2946
|
style: [styles25.container, cardStyle, style],
|
|
2841
2947
|
onPress: onPress ? handlePress : void 0,
|
|
2842
|
-
onPressIn
|
|
2843
|
-
onPressOut
|
|
2948
|
+
onPressIn,
|
|
2949
|
+
onPressOut,
|
|
2844
2950
|
disabled,
|
|
2845
2951
|
activeOpacity: 1,
|
|
2846
|
-
touchSoundDisabled: true
|
|
2952
|
+
touchSoundDisabled: true,
|
|
2953
|
+
accessibilityRole: onPress ? "button" : void 0,
|
|
2954
|
+
accessibilityLabel: onPress ? a11yLabel : void 0,
|
|
2955
|
+
accessibilityState: onPress ? { disabled: !!disabled } : void 0
|
|
2847
2956
|
},
|
|
2848
2957
|
effectiveLeft ? /* @__PURE__ */ React26.createElement(View, { style: styles25.leftContainer }, effectiveLeft) : null,
|
|
2849
2958
|
/* @__PURE__ */ React26.createElement(View, { style: styles25.content }, /* @__PURE__ */ React26.createElement(
|
|
@@ -2937,9 +3046,6 @@ var styles25 = StyleSheet.create({
|
|
|
2937
3046
|
fontFamily: "Poppins-Regular",
|
|
2938
3047
|
fontSize: ms(14)
|
|
2939
3048
|
},
|
|
2940
|
-
chevron: {
|
|
2941
|
-
marginLeft: s(4)
|
|
2942
|
-
},
|
|
2943
3049
|
separator: {
|
|
2944
3050
|
height: StyleSheet.hairlineWidth,
|
|
2945
3051
|
marginRight: 0
|
|
@@ -2948,9 +3054,9 @@ var styles25 = StyleSheet.create({
|
|
|
2948
3054
|
opacity: 0.45
|
|
2949
3055
|
}
|
|
2950
3056
|
});
|
|
2951
|
-
var nativeDriver11 = Platform.OS !== "web";
|
|
2952
3057
|
function MenuItem({
|
|
2953
3058
|
label,
|
|
3059
|
+
subtitle,
|
|
2954
3060
|
iconName,
|
|
2955
3061
|
icon,
|
|
2956
3062
|
iconColor,
|
|
@@ -2961,29 +3067,16 @@ function MenuItem({
|
|
|
2961
3067
|
variant = "plain",
|
|
2962
3068
|
showSeparator = false,
|
|
2963
3069
|
style,
|
|
2964
|
-
labelStyle
|
|
3070
|
+
labelStyle,
|
|
3071
|
+
accessibilityLabel
|
|
2965
3072
|
}) {
|
|
2966
3073
|
const { colors } = useTheme();
|
|
2967
|
-
const
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
stiffness: 350,
|
|
2974
|
-
damping: 28,
|
|
2975
|
-
mass: 0.9
|
|
2976
|
-
}).start();
|
|
2977
|
-
};
|
|
2978
|
-
const handlePressOut = () => {
|
|
2979
|
-
Animated.spring(scale2, {
|
|
2980
|
-
toValue: 1,
|
|
2981
|
-
useNativeDriver: nativeDriver11,
|
|
2982
|
-
stiffness: 220,
|
|
2983
|
-
damping: 20,
|
|
2984
|
-
mass: 0.9
|
|
2985
|
-
}).start();
|
|
2986
|
-
};
|
|
3074
|
+
const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
3075
|
+
pressScale: PRESS_SCALE.row,
|
|
3076
|
+
pressInSpring: SPRINGS.surfacePressIn,
|
|
3077
|
+
pressOutSpring: SPRINGS.surfacePressOut,
|
|
3078
|
+
disabled
|
|
3079
|
+
});
|
|
2987
3080
|
const handlePress = () => {
|
|
2988
3081
|
selectionAsync();
|
|
2989
3082
|
onPress();
|
|
@@ -3000,19 +3093,23 @@ function MenuItem({
|
|
|
3000
3093
|
shadowRadius: 6,
|
|
3001
3094
|
elevation: 2
|
|
3002
3095
|
} : {};
|
|
3003
|
-
|
|
3096
|
+
const a11yLabel = accessibilityLabel ?? (subtitle ? `${label}. ${subtitle}` : label);
|
|
3097
|
+
return /* @__PURE__ */ React26.createElement(Animated9.View, { style: [animatedStyle, disabled && styles26.disabled], ...hoverHandlers }, /* @__PURE__ */ React26.createElement(
|
|
3004
3098
|
TouchableOpacity,
|
|
3005
3099
|
{
|
|
3006
3100
|
style: [styles26.container, cardStyle, style],
|
|
3007
3101
|
onPress: handlePress,
|
|
3008
|
-
onPressIn
|
|
3009
|
-
onPressOut
|
|
3102
|
+
onPressIn,
|
|
3103
|
+
onPressOut,
|
|
3010
3104
|
disabled,
|
|
3011
3105
|
activeOpacity: 1,
|
|
3012
|
-
touchSoundDisabled: true
|
|
3106
|
+
touchSoundDisabled: true,
|
|
3107
|
+
accessibilityRole: "button",
|
|
3108
|
+
accessibilityLabel: a11yLabel,
|
|
3109
|
+
accessibilityState: { disabled }
|
|
3013
3110
|
},
|
|
3014
3111
|
resolvedIcon ? /* @__PURE__ */ React26.createElement(View, { style: styles26.iconContainer }, resolvedIcon) : null,
|
|
3015
|
-
/* @__PURE__ */ React26.createElement(
|
|
3112
|
+
/* @__PURE__ */ React26.createElement(View, { style: styles26.labelContainer }, /* @__PURE__ */ React26.createElement(
|
|
3016
3113
|
Text,
|
|
3017
3114
|
{
|
|
3018
3115
|
style: [styles26.label, { color: colors.foreground }, labelStyle],
|
|
@@ -3020,7 +3117,15 @@ function MenuItem({
|
|
|
3020
3117
|
allowFontScaling: true
|
|
3021
3118
|
},
|
|
3022
3119
|
label
|
|
3023
|
-
),
|
|
3120
|
+
), subtitle ? /* @__PURE__ */ React26.createElement(
|
|
3121
|
+
Text,
|
|
3122
|
+
{
|
|
3123
|
+
style: [styles26.subtitle, { color: colors.foregroundMuted }],
|
|
3124
|
+
numberOfLines: 1,
|
|
3125
|
+
allowFontScaling: true
|
|
3126
|
+
},
|
|
3127
|
+
subtitle
|
|
3128
|
+
) : null),
|
|
3024
3129
|
rightRender !== void 0 ? /* @__PURE__ */ React26.createElement(
|
|
3025
3130
|
View,
|
|
3026
3131
|
{
|
|
@@ -3060,10 +3165,18 @@ var styles26 = StyleSheet.create({
|
|
|
3060
3165
|
justifyContent: "center",
|
|
3061
3166
|
flexShrink: 0
|
|
3062
3167
|
},
|
|
3168
|
+
labelContainer: {
|
|
3169
|
+
flex: 1,
|
|
3170
|
+
justifyContent: "center"
|
|
3171
|
+
},
|
|
3063
3172
|
label: {
|
|
3064
3173
|
fontFamily: "Poppins-Medium",
|
|
3065
|
-
fontSize: ms(15)
|
|
3066
|
-
|
|
3174
|
+
fontSize: ms(15)
|
|
3175
|
+
},
|
|
3176
|
+
subtitle: {
|
|
3177
|
+
fontFamily: "Poppins-Regular",
|
|
3178
|
+
fontSize: ms(12),
|
|
3179
|
+
marginTop: vs(1)
|
|
3067
3180
|
},
|
|
3068
3181
|
rightContainer: {
|
|
3069
3182
|
alignItems: "flex-end",
|
|
@@ -3078,62 +3191,37 @@ var styles26 = StyleSheet.create({
|
|
|
3078
3191
|
opacity: 0.45
|
|
3079
3192
|
}
|
|
3080
3193
|
});
|
|
3081
|
-
|
|
3082
|
-
function Chip({ label, selected = false, onPress, icon, iconName, style }) {
|
|
3194
|
+
function Chip({ label, selected = false, onPress, icon, iconName, style, accessibilityLabel }) {
|
|
3083
3195
|
const { colors } = useTheme();
|
|
3084
|
-
const
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
Animated.spring(scale2, {
|
|
3096
|
-
toValue: 0.95,
|
|
3097
|
-
useNativeDriver: nativeDriver12,
|
|
3098
|
-
speed: 40,
|
|
3099
|
-
bounciness: 0
|
|
3100
|
-
}).start();
|
|
3101
|
-
};
|
|
3102
|
-
const handlePressOut = () => {
|
|
3103
|
-
Animated.spring(scale2, {
|
|
3104
|
-
toValue: 1,
|
|
3105
|
-
useNativeDriver: nativeDriver12,
|
|
3106
|
-
speed: 40,
|
|
3107
|
-
bounciness: 4
|
|
3108
|
-
}).start();
|
|
3109
|
-
};
|
|
3196
|
+
const { animatedStyle: scaleStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
3197
|
+
pressScale: PRESS_SCALE.chip
|
|
3198
|
+
});
|
|
3199
|
+
const colorProgress = useColorTransition(selected);
|
|
3200
|
+
const surfaceStyle = useAnimatedStyle(() => ({
|
|
3201
|
+
backgroundColor: interpolateColor(colorProgress.value, [0, 1], [colors.surface, colors.primary]),
|
|
3202
|
+
borderColor: interpolateColor(colorProgress.value, [0, 1], [colors.border, colors.primary])
|
|
3203
|
+
}));
|
|
3204
|
+
const textStyle = useAnimatedStyle(() => ({
|
|
3205
|
+
color: interpolateColor(colorProgress.value, [0, 1], [colors.foreground, colors.primaryForeground])
|
|
3206
|
+
}));
|
|
3110
3207
|
const handlePress = () => {
|
|
3111
3208
|
selectionAsync();
|
|
3112
3209
|
onPress?.();
|
|
3113
3210
|
};
|
|
3114
|
-
const backgroundColor = pressAnim.interpolate({
|
|
3115
|
-
inputRange: [0, 1],
|
|
3116
|
-
outputRange: [colors.surface, colors.primary]
|
|
3117
|
-
});
|
|
3118
|
-
const textColor = pressAnim.interpolate({
|
|
3119
|
-
inputRange: [0, 1],
|
|
3120
|
-
outputRange: [colors.foreground, colors.primaryForeground]
|
|
3121
|
-
});
|
|
3122
|
-
const borderColor = pressAnim.interpolate({
|
|
3123
|
-
inputRange: [0, 1],
|
|
3124
|
-
outputRange: [colors.border, colors.primary]
|
|
3125
|
-
});
|
|
3126
3211
|
const resolvedIcon = iconName ? renderIcon(iconName, ms(13), selected ? colors.primaryForeground : colors.foreground) : icon;
|
|
3127
|
-
return /* @__PURE__ */ React26.createElement(
|
|
3212
|
+
return /* @__PURE__ */ React26.createElement(Animated9.View, { style: [styles27.wrapper, scaleStyle, style], ...hoverHandlers }, /* @__PURE__ */ React26.createElement(
|
|
3128
3213
|
TouchableOpacity,
|
|
3129
3214
|
{
|
|
3130
3215
|
onPress: handlePress,
|
|
3131
|
-
onPressIn
|
|
3132
|
-
onPressOut
|
|
3216
|
+
onPressIn,
|
|
3217
|
+
onPressOut,
|
|
3133
3218
|
activeOpacity: 1,
|
|
3134
|
-
touchSoundDisabled: true
|
|
3219
|
+
touchSoundDisabled: true,
|
|
3220
|
+
accessibilityRole: "button",
|
|
3221
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
3222
|
+
accessibilityState: { selected }
|
|
3135
3223
|
},
|
|
3136
|
-
/* @__PURE__ */ React26.createElement(
|
|
3224
|
+
/* @__PURE__ */ React26.createElement(Animated9.View, { style: [styles27.chip, surfaceStyle] }, resolvedIcon ? /* @__PURE__ */ React26.createElement(View, { style: styles27.chipIcon }, resolvedIcon) : null, /* @__PURE__ */ React26.createElement(Animated9.Text, { style: [styles27.label, textStyle], allowFontScaling: true }, label))
|
|
3137
3225
|
));
|
|
3138
3226
|
}
|
|
3139
3227
|
function ChipGroup({ options, value, onValueChange, multiSelect = false, style }) {
|
|
@@ -3144,12 +3232,7 @@ function ChipGroup({ options, value, onValueChange, multiSelect = false, style }
|
|
|
3144
3232
|
}
|
|
3145
3233
|
const currentArray = Array.isArray(value) ? value : value ? [value] : [];
|
|
3146
3234
|
const isSelected2 = currentArray.includes(optionValue);
|
|
3147
|
-
|
|
3148
|
-
if (isSelected2) {
|
|
3149
|
-
newArray = currentArray.filter((v) => v !== optionValue);
|
|
3150
|
-
} else {
|
|
3151
|
-
newArray = [...currentArray, optionValue];
|
|
3152
|
-
}
|
|
3235
|
+
const newArray = isSelected2 ? currentArray.filter((v) => v !== optionValue) : [...currentArray, optionValue];
|
|
3153
3236
|
onValueChange?.(newArray);
|
|
3154
3237
|
};
|
|
3155
3238
|
const isSelected = (optionValue) => {
|
|
@@ -3363,22 +3446,36 @@ function MonthPicker({ value, onChange, locale = "en", formatLabel, style }) {
|
|
|
3363
3446
|
onChange({ month: value.month + 1, year: value.year });
|
|
3364
3447
|
}
|
|
3365
3448
|
};
|
|
3366
|
-
return /* @__PURE__ */ React26.createElement(View, { style: [styles30.container, style] }, /* @__PURE__ */ React26.createElement(
|
|
3449
|
+
return /* @__PURE__ */ React26.createElement(View, { style: [styles30.container, style], accessibilityRole: "adjustable", accessibilityLabel: getLabel() }, /* @__PURE__ */ React26.createElement(
|
|
3367
3450
|
TouchableOpacity,
|
|
3368
3451
|
{
|
|
3369
3452
|
style: styles30.arrow,
|
|
3370
3453
|
onPress: handlePrev,
|
|
3371
3454
|
activeOpacity: 0.6,
|
|
3372
|
-
touchSoundDisabled: true
|
|
3455
|
+
touchSoundDisabled: true,
|
|
3456
|
+
accessibilityRole: "button",
|
|
3457
|
+
accessibilityLabel: "Previous month",
|
|
3458
|
+
hitSlop: { top: 8, bottom: 8, left: 8, right: 8 }
|
|
3373
3459
|
},
|
|
3374
3460
|
/* @__PURE__ */ React26.createElement(Entypo$1, { name: "chevron-left", size: 22, color: colors.foreground })
|
|
3375
|
-
), /* @__PURE__ */ React26.createElement(
|
|
3461
|
+
), /* @__PURE__ */ React26.createElement(
|
|
3462
|
+
Text,
|
|
3463
|
+
{
|
|
3464
|
+
style: [styles30.label, { color: colors.foreground }],
|
|
3465
|
+
allowFontScaling: true,
|
|
3466
|
+
accessibilityLiveRegion: "polite"
|
|
3467
|
+
},
|
|
3468
|
+
getLabel()
|
|
3469
|
+
), /* @__PURE__ */ React26.createElement(
|
|
3376
3470
|
TouchableOpacity,
|
|
3377
3471
|
{
|
|
3378
3472
|
style: styles30.arrow,
|
|
3379
3473
|
onPress: handleNext,
|
|
3380
3474
|
activeOpacity: 0.6,
|
|
3381
|
-
touchSoundDisabled: true
|
|
3475
|
+
touchSoundDisabled: true,
|
|
3476
|
+
accessibilityRole: "button",
|
|
3477
|
+
accessibilityLabel: "Next month",
|
|
3478
|
+
hitSlop: { top: 8, bottom: 8, left: 8, right: 8 }
|
|
3382
3479
|
},
|
|
3383
3480
|
/* @__PURE__ */ React26.createElement(Entypo$1, { name: "chevron-right", size: 22, color: colors.foreground })
|
|
3384
3481
|
));
|
|
@@ -3403,18 +3500,6 @@ var styles30 = StyleSheet.create({
|
|
|
3403
3500
|
minWidth: s(160)
|
|
3404
3501
|
}
|
|
3405
3502
|
});
|
|
3406
|
-
function useHover() {
|
|
3407
|
-
const [hovered, setHovered] = useState(false);
|
|
3408
|
-
const onMouseEnter = useCallback(() => setHovered(true), []);
|
|
3409
|
-
const onMouseLeave = useCallback(() => setHovered(false), []);
|
|
3410
|
-
if (Platform.OS !== "web") {
|
|
3411
|
-
return { hovered: false, hoverHandlers: {} };
|
|
3412
|
-
}
|
|
3413
|
-
return { hovered, hoverHandlers: { onMouseEnter, onMouseLeave } };
|
|
3414
|
-
}
|
|
3415
|
-
|
|
3416
|
-
// src/components/MediaCard/MediaCard.tsx
|
|
3417
|
-
var nativeDriver13 = Platform.OS !== "web";
|
|
3418
3503
|
var aspectRatioMap = {
|
|
3419
3504
|
"1:1": 1,
|
|
3420
3505
|
"4:3": 3 / 4,
|
|
@@ -3436,19 +3521,17 @@ function MediaCard({
|
|
|
3436
3521
|
onPress,
|
|
3437
3522
|
style,
|
|
3438
3523
|
imageStyle,
|
|
3439
|
-
footer
|
|
3524
|
+
footer,
|
|
3525
|
+
accessibilityLabel
|
|
3440
3526
|
}) {
|
|
3441
3527
|
const { colors } = useTheme();
|
|
3442
|
-
const scale2 = useRef(new Animated.Value(1)).current;
|
|
3443
3528
|
const { hovered, hoverHandlers } = useHover();
|
|
3444
|
-
const
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver13, speed: 40, bounciness: 4 }).start();
|
|
3451
|
-
};
|
|
3529
|
+
const { animatedStyle, onPressIn, onPressOut } = usePressScale({
|
|
3530
|
+
pressScale: PRESS_SCALE.card,
|
|
3531
|
+
pressInSpring: SPRINGS.surfacePressIn,
|
|
3532
|
+
pressOutSpring: SPRINGS.surfacePressOut,
|
|
3533
|
+
disabled: !onPress
|
|
3534
|
+
});
|
|
3452
3535
|
const handlePress = () => {
|
|
3453
3536
|
if (!onPress) return;
|
|
3454
3537
|
impactLight();
|
|
@@ -3456,6 +3539,7 @@ function MediaCard({
|
|
|
3456
3539
|
};
|
|
3457
3540
|
const ratio = aspectRatioMap[aspectRatio];
|
|
3458
3541
|
const resolvedActionIcon = actionIconName ? renderIcon(actionIconName, 18, actionActive ? colors.primary : colors.background) : actionIcon ?? renderIcon("heart", 18, actionActive ? colors.primary : colors.background);
|
|
3542
|
+
const a11yLabel = accessibilityLabel ?? [title, subtitle].filter(Boolean).join(". ");
|
|
3459
3543
|
const cardContent = /* @__PURE__ */ React26.createElement(
|
|
3460
3544
|
View,
|
|
3461
3545
|
{
|
|
@@ -3482,21 +3566,26 @@ function MediaCard({
|
|
|
3482
3566
|
onActionPress?.();
|
|
3483
3567
|
},
|
|
3484
3568
|
activeOpacity: 0.8,
|
|
3485
|
-
touchSoundDisabled: true
|
|
3569
|
+
touchSoundDisabled: true,
|
|
3570
|
+
accessibilityRole: "button",
|
|
3571
|
+
accessibilityLabel: actionIconName ?? "action",
|
|
3572
|
+
accessibilityState: { selected: actionActive }
|
|
3486
3573
|
},
|
|
3487
3574
|
resolvedActionIcon
|
|
3488
3575
|
)),
|
|
3489
3576
|
(title || subtitle || caption || footer) && /* @__PURE__ */ React26.createElement(View, { style: styles31.meta }, title ? /* @__PURE__ */ React26.createElement(Text, { style: [styles31.title, { color: colors.foreground }], numberOfLines: 2, allowFontScaling: true }, title) : null, subtitle ? /* @__PURE__ */ React26.createElement(Text, { style: [styles31.subtitle, { color: colors.foregroundSubtle }], numberOfLines: 1, allowFontScaling: true }, subtitle) : null, caption ? /* @__PURE__ */ React26.createElement(Text, { style: [styles31.caption, { color: colors.foregroundMuted }], numberOfLines: 1, allowFontScaling: true }, caption) : null, footer)
|
|
3490
3577
|
);
|
|
3491
3578
|
if (onPress) {
|
|
3492
|
-
return /* @__PURE__ */ React26.createElement(
|
|
3579
|
+
return /* @__PURE__ */ React26.createElement(Animated9.View, { style: animatedStyle }, /* @__PURE__ */ React26.createElement(
|
|
3493
3580
|
TouchableOpacity,
|
|
3494
3581
|
{
|
|
3495
3582
|
onPress: handlePress,
|
|
3496
|
-
onPressIn
|
|
3497
|
-
onPressOut
|
|
3583
|
+
onPressIn,
|
|
3584
|
+
onPressOut,
|
|
3498
3585
|
activeOpacity: 1,
|
|
3499
|
-
touchSoundDisabled: true
|
|
3586
|
+
touchSoundDisabled: true,
|
|
3587
|
+
accessibilityRole: "button",
|
|
3588
|
+
accessibilityLabel: a11yLabel
|
|
3500
3589
|
},
|
|
3501
3590
|
cardContent
|
|
3502
3591
|
));
|
|
@@ -3506,12 +3595,10 @@ function MediaCard({
|
|
|
3506
3595
|
var styles31 = StyleSheet.create({
|
|
3507
3596
|
card: {
|
|
3508
3597
|
borderRadius: RADIUS.md,
|
|
3509
|
-
// 14px — Airbnb property card spec
|
|
3510
3598
|
overflow: "hidden",
|
|
3511
3599
|
backgroundColor: "transparent"
|
|
3512
3600
|
},
|
|
3513
3601
|
cardHovered: {
|
|
3514
|
-
// Web hover: lift shadow
|
|
3515
3602
|
...SHADOWS.md
|
|
3516
3603
|
},
|
|
3517
3604
|
imageContainer: {
|
|
@@ -3562,43 +3649,38 @@ var styles31 = StyleSheet.create({
|
|
|
3562
3649
|
lineHeight: mvs(16)
|
|
3563
3650
|
}
|
|
3564
3651
|
});
|
|
3565
|
-
var nativeDriver14 = Platform.OS !== "web";
|
|
3566
3652
|
function CategoryChip({
|
|
3567
3653
|
item,
|
|
3568
3654
|
selected,
|
|
3569
3655
|
onPress
|
|
3570
3656
|
}) {
|
|
3571
3657
|
const { colors } = useTheme();
|
|
3572
|
-
const
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
const
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
const
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3658
|
+
const { animatedStyle: scaleStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
3659
|
+
pressScale: PRESS_SCALE.chip
|
|
3660
|
+
});
|
|
3661
|
+
const progress = useColorTransition(selected);
|
|
3662
|
+
const surfaceStyle = useAnimatedStyle(() => ({
|
|
3663
|
+
backgroundColor: interpolateColor(progress.value, [0, 1], [colors.surface, colors.primary]),
|
|
3664
|
+
borderColor: interpolateColor(progress.value, [0, 1], [colors.border, colors.primary])
|
|
3665
|
+
}));
|
|
3666
|
+
const textColorStyle = useAnimatedStyle(() => ({
|
|
3667
|
+
color: interpolateColor(progress.value, [0, 1], [colors.foregroundSubtle, colors.primaryForeground])
|
|
3668
|
+
}));
|
|
3669
|
+
const iconColor = selected ? colors.primaryForeground : colors.foregroundSubtle;
|
|
3670
|
+
const resolvedIcon = typeof item.icon === "string" ? renderIcon(item.icon, 16, iconColor) : item.icon ?? null;
|
|
3671
|
+
return /* @__PURE__ */ React26.createElement(Animated9.View, { style: scaleStyle, ...hoverHandlers }, /* @__PURE__ */ React26.createElement(
|
|
3584
3672
|
TouchableOpacity,
|
|
3585
3673
|
{
|
|
3586
|
-
style: [
|
|
3587
|
-
styles32.chip,
|
|
3588
|
-
{
|
|
3589
|
-
backgroundColor: bgColor,
|
|
3590
|
-
borderColor
|
|
3591
|
-
}
|
|
3592
|
-
],
|
|
3593
3674
|
onPress,
|
|
3594
|
-
onPressIn
|
|
3595
|
-
onPressOut
|
|
3675
|
+
onPressIn,
|
|
3676
|
+
onPressOut,
|
|
3596
3677
|
activeOpacity: 1,
|
|
3597
|
-
touchSoundDisabled: true
|
|
3678
|
+
touchSoundDisabled: true,
|
|
3679
|
+
accessibilityRole: "button",
|
|
3680
|
+
accessibilityLabel: item.label,
|
|
3681
|
+
accessibilityState: { selected }
|
|
3598
3682
|
},
|
|
3599
|
-
resolvedIcon && /* @__PURE__ */ React26.createElement(View, { style: styles32.chipIcon }, resolvedIcon),
|
|
3600
|
-
/* @__PURE__ */ React26.createElement(Text, { style: [styles32.chipLabel, { color: textColor }], allowFontScaling: true }, item.label),
|
|
3601
|
-
item.badge !== void 0 && item.badge > 0 && /* @__PURE__ */ React26.createElement(View, { style: [styles32.chipBadge, { backgroundColor: colors.primary }] }, /* @__PURE__ */ React26.createElement(Text, { style: [styles32.chipBadgeText, { color: colors.primaryForeground }] }, Math.min(item.badge, 99)))
|
|
3683
|
+
/* @__PURE__ */ React26.createElement(Animated9.View, { style: [styles32.chip, surfaceStyle] }, resolvedIcon && /* @__PURE__ */ React26.createElement(View, { style: styles32.chipIcon }, resolvedIcon), /* @__PURE__ */ React26.createElement(Animated9.Text, { style: [styles32.chipLabel, textColorStyle], allowFontScaling: true }, item.label), item.badge !== void 0 && item.badge > 0 && /* @__PURE__ */ React26.createElement(View, { style: [styles32.chipBadge, { backgroundColor: colors.primary }] }, /* @__PURE__ */ React26.createElement(Text, { style: [styles32.chipBadgeText, { color: colors.primaryForeground }] }, Math.min(item.badge, 99))))
|
|
3602
3684
|
));
|
|
3603
3685
|
}
|
|
3604
3686
|
function CategoryStrip({
|
|
@@ -3607,7 +3689,8 @@ function CategoryStrip({
|
|
|
3607
3689
|
onValueChange,
|
|
3608
3690
|
multiSelect = false,
|
|
3609
3691
|
style,
|
|
3610
|
-
itemStyle
|
|
3692
|
+
itemStyle,
|
|
3693
|
+
accessibilityLabel
|
|
3611
3694
|
}) {
|
|
3612
3695
|
const selected = Array.isArray(value) ? value : value ? [value] : [];
|
|
3613
3696
|
const handlePress = (v) => {
|
|
@@ -3626,7 +3709,9 @@ function CategoryStrip({
|
|
|
3626
3709
|
horizontal: true,
|
|
3627
3710
|
showsHorizontalScrollIndicator: false,
|
|
3628
3711
|
contentContainerStyle: [styles32.container, style],
|
|
3629
|
-
style: styles32.scroll
|
|
3712
|
+
style: styles32.scroll,
|
|
3713
|
+
accessibilityRole: multiSelect ? void 0 : "radiogroup",
|
|
3714
|
+
accessibilityLabel
|
|
3630
3715
|
},
|
|
3631
3716
|
categories.map((cat) => /* @__PURE__ */ React26.createElement(View, { key: cat.value, style: itemStyle }, /* @__PURE__ */ React26.createElement(
|
|
3632
3717
|
CategoryChip,
|
|
@@ -3679,62 +3764,45 @@ var styles32 = StyleSheet.create({
|
|
|
3679
3764
|
lineHeight: 14
|
|
3680
3765
|
}
|
|
3681
3766
|
});
|
|
3682
|
-
var nativeDriver15 = Platform.OS !== "web";
|
|
3683
3767
|
function Pressable2({
|
|
3684
3768
|
children,
|
|
3685
3769
|
onPress,
|
|
3686
|
-
pressScale =
|
|
3687
|
-
bounciness = 4,
|
|
3770
|
+
pressScale = PRESS_SCALE.card,
|
|
3688
3771
|
haptics = true,
|
|
3689
3772
|
style,
|
|
3690
3773
|
disabled,
|
|
3691
3774
|
hoverScale = 1.02,
|
|
3692
3775
|
...touchableProps
|
|
3693
3776
|
}) {
|
|
3694
|
-
const
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
speed: 40,
|
|
3702
|
-
bounciness: 0
|
|
3703
|
-
}).start();
|
|
3704
|
-
};
|
|
3705
|
-
const handlePressOut = () => {
|
|
3706
|
-
if (disabled) return;
|
|
3707
|
-
Animated.spring(scale2, {
|
|
3708
|
-
toValue: 1,
|
|
3709
|
-
useNativeDriver: nativeDriver15,
|
|
3710
|
-
speed: 40,
|
|
3711
|
-
bounciness
|
|
3712
|
-
}).start();
|
|
3713
|
-
};
|
|
3777
|
+
const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
3778
|
+
pressScale,
|
|
3779
|
+
hoverScale,
|
|
3780
|
+
pressInSpring: SPRINGS.surfacePressIn,
|
|
3781
|
+
pressOutSpring: SPRINGS.surfacePressOut,
|
|
3782
|
+
disabled
|
|
3783
|
+
});
|
|
3714
3784
|
const handlePress = () => {
|
|
3715
3785
|
if (disabled || !onPress) return;
|
|
3716
3786
|
if (haptics) impactLight();
|
|
3717
3787
|
onPress();
|
|
3718
3788
|
};
|
|
3719
|
-
const hoverScaleValue = hovered && hoverScale !== 1 ? hoverScale : 1;
|
|
3720
3789
|
return /* @__PURE__ */ React26.createElement(
|
|
3721
|
-
|
|
3790
|
+
Animated9.View,
|
|
3722
3791
|
{
|
|
3723
|
-
style: [
|
|
3724
|
-
{ transform: [{ scale: Animated.multiply(scale2, hoverScaleValue) }] },
|
|
3725
|
-
style
|
|
3726
|
-
],
|
|
3792
|
+
style: [animatedStyle, style],
|
|
3727
3793
|
...Platform.OS === "web" ? hoverHandlers : {}
|
|
3728
3794
|
},
|
|
3729
3795
|
/* @__PURE__ */ React26.createElement(
|
|
3730
3796
|
TouchableOpacity,
|
|
3731
3797
|
{
|
|
3732
3798
|
onPress: handlePress,
|
|
3733
|
-
onPressIn
|
|
3734
|
-
onPressOut
|
|
3799
|
+
onPressIn,
|
|
3800
|
+
onPressOut,
|
|
3735
3801
|
activeOpacity: 1,
|
|
3736
3802
|
disabled,
|
|
3737
3803
|
touchSoundDisabled: true,
|
|
3804
|
+
accessibilityRole: "button",
|
|
3805
|
+
accessibilityState: { disabled: !!disabled },
|
|
3738
3806
|
...touchableProps
|
|
3739
3807
|
},
|
|
3740
3808
|
children
|
|
@@ -3780,14 +3848,14 @@ function DetailRow({
|
|
|
3780
3848
|
allowFontScaling: true
|
|
3781
3849
|
},
|
|
3782
3850
|
label
|
|
3783
|
-
) : label), separatorStyle ? /* @__PURE__ */ React26.createElement(View, { style: separatorStyle }) : /* @__PURE__ */ React26.createElement(View, { style: styles33.spacer }), /* @__PURE__ */ React26.createElement(View, { style: styles33.valueSide }, /* @__PURE__ */ React26.createElement(
|
|
3851
|
+
) : label), separatorStyle ? /* @__PURE__ */ React26.createElement(View, { style: separatorStyle }) : /* @__PURE__ */ React26.createElement(View, { style: styles33.spacer }), /* @__PURE__ */ React26.createElement(View, { style: styles33.valueSide }, typeof value === "string" ? /* @__PURE__ */ React26.createElement(
|
|
3784
3852
|
Text,
|
|
3785
3853
|
{
|
|
3786
3854
|
style: [styles33.valueText, { color: valueColor ?? colors.foreground }, valueStyle],
|
|
3787
3855
|
allowFontScaling: true
|
|
3788
3856
|
},
|
|
3789
3857
|
value
|
|
3790
|
-
), resolvedRightIcon ? /* @__PURE__ */ React26.createElement(View, { style: styles33.icon }, resolvedRightIcon) : null));
|
|
3858
|
+
) : value, resolvedRightIcon ? /* @__PURE__ */ React26.createElement(View, { style: styles33.icon }, resolvedRightIcon) : null));
|
|
3791
3859
|
}
|
|
3792
3860
|
var styles33 = StyleSheet.create({
|
|
3793
3861
|
row: {
|