@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.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var React26 = require('react');
|
|
4
4
|
var reactNative = require('react-native');
|
|
5
|
+
var Animated9 = require('react-native-reanimated');
|
|
5
6
|
var reactNativeSizeMatters = require('react-native-size-matters');
|
|
6
7
|
var AntDesign = require('@expo/vector-icons/AntDesign');
|
|
7
8
|
var Entypo = require('@expo/vector-icons/Entypo');
|
|
@@ -11,7 +12,6 @@ var MaterialIcons = require('@expo/vector-icons/MaterialIcons');
|
|
|
11
12
|
var Ionicons = require('@expo/vector-icons/Ionicons');
|
|
12
13
|
var vectorIcons = require('@expo/vector-icons');
|
|
13
14
|
var expoLinearGradient = require('expo-linear-gradient');
|
|
14
|
-
var Animated12 = require('react-native-reanimated');
|
|
15
15
|
var RNSlider = require('@react-native-community/slider');
|
|
16
16
|
var bottomSheet = require('@gorhom/bottom-sheet');
|
|
17
17
|
var reactNativeSafeAreaContext = require('react-native-safe-area-context');
|
|
@@ -21,13 +21,13 @@ var sonnerNative = require('sonner-native');
|
|
|
21
21
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
22
22
|
|
|
23
23
|
var React26__default = /*#__PURE__*/_interopDefault(React26);
|
|
24
|
+
var Animated9__default = /*#__PURE__*/_interopDefault(Animated9);
|
|
24
25
|
var AntDesign__default = /*#__PURE__*/_interopDefault(AntDesign);
|
|
25
26
|
var Entypo__default = /*#__PURE__*/_interopDefault(Entypo);
|
|
26
27
|
var Feather__default = /*#__PURE__*/_interopDefault(Feather);
|
|
27
28
|
var FontAwesome5__default = /*#__PURE__*/_interopDefault(FontAwesome5);
|
|
28
29
|
var MaterialIcons__default = /*#__PURE__*/_interopDefault(MaterialIcons);
|
|
29
30
|
var Ionicons__default = /*#__PURE__*/_interopDefault(Ionicons);
|
|
30
|
-
var Animated12__default = /*#__PURE__*/_interopDefault(Animated12);
|
|
31
31
|
var RNSlider__default = /*#__PURE__*/_interopDefault(RNSlider);
|
|
32
32
|
|
|
33
33
|
// src/theme/ThemeProvider.tsx
|
|
@@ -419,9 +419,87 @@ var TYPOGRAPHY = {
|
|
|
419
419
|
letterSpacing: 0
|
|
420
420
|
}
|
|
421
421
|
};
|
|
422
|
+
var SPRINGS = {
|
|
423
|
+
/** Tight, premium press feel — Buttons, Toggle, Tabs triggers. */
|
|
424
|
+
pressIn: { stiffness: 600, damping: 35, mass: 0.8 },
|
|
425
|
+
pressOut: { stiffness: 280, damping: 22, mass: 0.8 },
|
|
426
|
+
/** Slightly softer for larger surfaces — Card, ListItem, MenuItem. */
|
|
427
|
+
surfacePressIn: { stiffness: 380, damping: 30, mass: 0.95 },
|
|
428
|
+
surfacePressOut: { stiffness: 220, damping: 20, mass: 0.95 },
|
|
429
|
+
/** Settled transitions for moving indicators — Tabs pill, Switch thumb. */
|
|
430
|
+
glide: { stiffness: 380, damping: 38, mass: 1 },
|
|
431
|
+
/** Elastic indicator — Switch thumb, RadioGroup dot. */
|
|
432
|
+
elastic: { stiffness: 320, damping: 22, mass: 0.7 }
|
|
433
|
+
};
|
|
434
|
+
var TIMINGS = {
|
|
435
|
+
/** Color/opacity transitions on toggles, checkboxes, switches. */
|
|
436
|
+
state: { duration: 160 },
|
|
437
|
+
/** Focus ring on inputs. */
|
|
438
|
+
focusIn: { duration: 140 },
|
|
439
|
+
focusOut: { duration: 100 },
|
|
440
|
+
/** Accordion / collapsible content. */
|
|
441
|
+
expand: { duration: 240 },
|
|
442
|
+
collapse: { duration: 200 },
|
|
443
|
+
/** Skeleton shimmer cycle (full pass). */
|
|
444
|
+
shimmer: { duration: 1400 }
|
|
445
|
+
};
|
|
446
|
+
var EASINGS = {
|
|
447
|
+
/** Material-style ease-out — natural deceleration for state changes. */
|
|
448
|
+
standard: Animated9.Easing.bezier(0.2, 0, 0, 1),
|
|
449
|
+
/** Strong ease-out for expanding surfaces (Accordion open). */
|
|
450
|
+
expand: Animated9.Easing.bezier(0.23, 1, 0.32, 1),
|
|
451
|
+
/** Quick ease-in for collapsing. */
|
|
452
|
+
collapse: Animated9.Easing.in(Animated9.Easing.ease)
|
|
453
|
+
};
|
|
454
|
+
var PRESS_SCALE = {
|
|
455
|
+
button: 0.95,
|
|
456
|
+
card: 0.98,
|
|
457
|
+
row: 0.97,
|
|
458
|
+
chip: 0.94
|
|
459
|
+
};
|
|
460
|
+
function useHover() {
|
|
461
|
+
const [hovered, setHovered] = React26.useState(false);
|
|
462
|
+
const onMouseEnter = React26.useCallback(() => setHovered(true), []);
|
|
463
|
+
const onMouseLeave = React26.useCallback(() => setHovered(false), []);
|
|
464
|
+
if (reactNative.Platform.OS !== "web") {
|
|
465
|
+
return { hovered: false, hoverHandlers: {} };
|
|
466
|
+
}
|
|
467
|
+
return { hovered, hoverHandlers: { onMouseEnter, onMouseLeave } };
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// src/utils/usePressScale.ts
|
|
471
|
+
function usePressScale({
|
|
472
|
+
pressScale = PRESS_SCALE.button,
|
|
473
|
+
hoverScale = 1.02,
|
|
474
|
+
pressInSpring = SPRINGS.pressIn,
|
|
475
|
+
pressOutSpring = SPRINGS.pressOut,
|
|
476
|
+
disabled = false
|
|
477
|
+
} = {}) {
|
|
478
|
+
const scale2 = Animated9.useSharedValue(1);
|
|
479
|
+
const { hovered, hoverHandlers } = useHover();
|
|
480
|
+
const onPressIn = React26.useCallback(() => {
|
|
481
|
+
if (disabled) return;
|
|
482
|
+
scale2.value = Animated9.withSpring(pressScale, pressInSpring);
|
|
483
|
+
}, [disabled, pressScale, pressInSpring, scale2]);
|
|
484
|
+
const onPressOut = React26.useCallback(() => {
|
|
485
|
+
if (disabled) return;
|
|
486
|
+
scale2.value = Animated9.withSpring(1, pressOutSpring);
|
|
487
|
+
}, [disabled, pressOutSpring, scale2]);
|
|
488
|
+
const hoverActive = reactNative.Platform.OS === "web" && hovered && hoverScale !== 1 && !disabled;
|
|
489
|
+
const animatedStyle = Animated9.useAnimatedStyle(() => ({
|
|
490
|
+
transform: [
|
|
491
|
+
{ scale: scale2.value * (hoverActive ? hoverScale : 1) }
|
|
492
|
+
]
|
|
493
|
+
}));
|
|
494
|
+
return {
|
|
495
|
+
animatedStyle,
|
|
496
|
+
onPressIn,
|
|
497
|
+
onPressOut,
|
|
498
|
+
hoverHandlers
|
|
499
|
+
};
|
|
500
|
+
}
|
|
422
501
|
|
|
423
502
|
// src/components/Button/Button.tsx
|
|
424
|
-
var nativeDriver = reactNative.Platform.OS !== "web";
|
|
425
503
|
var containerSizeStyles = {
|
|
426
504
|
sm: { paddingHorizontal: s(16), paddingVertical: vs(10), minHeight: 40 },
|
|
427
505
|
md: { paddingHorizontal: s(24), paddingVertical: vs(14), minHeight: 48 },
|
|
@@ -446,18 +524,16 @@ function Button({
|
|
|
446
524
|
disabled,
|
|
447
525
|
style,
|
|
448
526
|
onPress,
|
|
527
|
+
accessibilityLabel,
|
|
528
|
+
accessibilityHint,
|
|
449
529
|
...props
|
|
450
530
|
}) {
|
|
451
531
|
const { colors } = useTheme();
|
|
452
532
|
const isDisabled = disabled || loading;
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
};
|
|
458
|
-
const handlePressOut = () => {
|
|
459
|
-
reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver, stiffness: 280, damping: 22, mass: 0.8 }).start();
|
|
460
|
-
};
|
|
533
|
+
const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
534
|
+
pressScale: PRESS_SCALE.button,
|
|
535
|
+
disabled: isDisabled
|
|
536
|
+
});
|
|
461
537
|
const handlePress = (e) => {
|
|
462
538
|
impactMedium();
|
|
463
539
|
onPress?.(e);
|
|
@@ -480,43 +556,54 @@ function Button({
|
|
|
480
556
|
const styleArray = Array.isArray(style) ? style : style ? [style] : [];
|
|
481
557
|
const flatStyle = reactNative.StyleSheet.flatten(styleArray);
|
|
482
558
|
const { flex, ...restStyle } = flatStyle || {};
|
|
483
|
-
return /* @__PURE__ */ React26__default.default.createElement(
|
|
484
|
-
|
|
559
|
+
return /* @__PURE__ */ React26__default.default.createElement(
|
|
560
|
+
Animated9__default.default.View,
|
|
485
561
|
{
|
|
486
|
-
style: [
|
|
487
|
-
|
|
488
|
-
containerVariantStyle,
|
|
489
|
-
containerSizeStyles[size],
|
|
490
|
-
fullWidth && styles.fullWidth,
|
|
491
|
-
isDisabled && styles.disabled,
|
|
492
|
-
restStyle
|
|
493
|
-
],
|
|
494
|
-
disabled: isDisabled,
|
|
495
|
-
activeOpacity: 1,
|
|
496
|
-
touchSoundDisabled: true,
|
|
497
|
-
onPress: handlePress,
|
|
498
|
-
onPressIn: handlePressIn,
|
|
499
|
-
onPressOut: handlePressOut,
|
|
500
|
-
...props
|
|
562
|
+
style: [fullWidth && styles.fullWidth, flex !== void 0 && { flex }, animatedStyle],
|
|
563
|
+
...hoverHandlers
|
|
501
564
|
},
|
|
502
|
-
|
|
503
|
-
reactNative.
|
|
504
|
-
{
|
|
505
|
-
style: [styles.label, labelVariantStyle, labelSizeStyles[size], styles.labelLoading],
|
|
506
|
-
allowFontScaling: true,
|
|
507
|
-
numberOfLines: 1
|
|
508
|
-
},
|
|
509
|
-
label
|
|
510
|
-
)) : /* @__PURE__ */ React26__default.default.createElement(React26__default.default.Fragment, null, effectiveIcon && iconPosition === "left" && /* @__PURE__ */ React26__default.default.createElement(React26__default.default.Fragment, null, effectiveIcon), /* @__PURE__ */ React26__default.default.createElement(
|
|
511
|
-
reactNative.Text,
|
|
565
|
+
/* @__PURE__ */ React26__default.default.createElement(
|
|
566
|
+
reactNative.TouchableOpacity,
|
|
512
567
|
{
|
|
513
|
-
style: [
|
|
514
|
-
|
|
515
|
-
|
|
568
|
+
style: [
|
|
569
|
+
styles.base,
|
|
570
|
+
containerVariantStyle,
|
|
571
|
+
containerSizeStyles[size],
|
|
572
|
+
fullWidth && styles.fullWidth,
|
|
573
|
+
isDisabled && styles.disabled,
|
|
574
|
+
restStyle
|
|
575
|
+
],
|
|
576
|
+
disabled: isDisabled,
|
|
577
|
+
activeOpacity: 1,
|
|
578
|
+
touchSoundDisabled: true,
|
|
579
|
+
onPress: handlePress,
|
|
580
|
+
onPressIn,
|
|
581
|
+
onPressOut,
|
|
582
|
+
accessibilityRole: "button",
|
|
583
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
584
|
+
accessibilityHint,
|
|
585
|
+
accessibilityState: { disabled: isDisabled, busy: loading },
|
|
586
|
+
...props
|
|
516
587
|
},
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
588
|
+
loading ? /* @__PURE__ */ React26__default.default.createElement(React26__default.default.Fragment, null, /* @__PURE__ */ React26__default.default.createElement(reactNative.ActivityIndicator, { size: "small", color: spinnerColor, style: { marginRight: s(6) } }), /* @__PURE__ */ React26__default.default.createElement(
|
|
589
|
+
reactNative.Text,
|
|
590
|
+
{
|
|
591
|
+
style: [styles.label, labelVariantStyle, labelSizeStyles[size], styles.labelLoading],
|
|
592
|
+
allowFontScaling: true,
|
|
593
|
+
numberOfLines: 1
|
|
594
|
+
},
|
|
595
|
+
label
|
|
596
|
+
)) : /* @__PURE__ */ React26__default.default.createElement(React26__default.default.Fragment, null, effectiveIcon && iconPosition === "left" && /* @__PURE__ */ React26__default.default.createElement(React26__default.default.Fragment, null, effectiveIcon), /* @__PURE__ */ React26__default.default.createElement(
|
|
597
|
+
reactNative.Text,
|
|
598
|
+
{
|
|
599
|
+
style: [styles.label, labelVariantStyle, labelSizeStyles[size], effectiveIcon ? styles.labelWithIcon : void 0],
|
|
600
|
+
allowFontScaling: true,
|
|
601
|
+
numberOfLines: 1
|
|
602
|
+
},
|
|
603
|
+
label
|
|
604
|
+
), effectiveIcon && iconPosition === "right" && /* @__PURE__ */ React26__default.default.createElement(React26__default.default.Fragment, null, effectiveIcon))
|
|
605
|
+
)
|
|
606
|
+
);
|
|
520
607
|
}
|
|
521
608
|
var styles = reactNative.StyleSheet.create({
|
|
522
609
|
base: {
|
|
@@ -576,7 +663,6 @@ var styles2 = reactNative.StyleSheet.create({
|
|
|
576
663
|
flexDirection: "column"
|
|
577
664
|
}
|
|
578
665
|
});
|
|
579
|
-
var nativeDriver2 = reactNative.Platform.OS !== "web";
|
|
580
666
|
var sizeMap = {
|
|
581
667
|
sm: { container: s(32), icon: 16 },
|
|
582
668
|
md: { container: s(44), icon: 20 },
|
|
@@ -593,18 +679,16 @@ function IconButton({
|
|
|
593
679
|
disabled,
|
|
594
680
|
style,
|
|
595
681
|
onPress,
|
|
682
|
+
accessibilityLabel,
|
|
683
|
+
accessibilityHint,
|
|
596
684
|
...props
|
|
597
685
|
}) {
|
|
598
686
|
const { colors } = useTheme();
|
|
599
687
|
const isDisabled = disabled || loading;
|
|
600
|
-
const
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
};
|
|
605
|
-
const handlePressOut = () => {
|
|
606
|
-
reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver2, speed: 40, bounciness: 4 }).start();
|
|
607
|
-
};
|
|
688
|
+
const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
689
|
+
pressScale: PRESS_SCALE.button,
|
|
690
|
+
disabled: isDisabled
|
|
691
|
+
});
|
|
608
692
|
const handlePress = (e) => {
|
|
609
693
|
impactLight();
|
|
610
694
|
onPress?.(e);
|
|
@@ -629,30 +713,42 @@ function IconButton({
|
|
|
629
713
|
const showBadge = badge !== void 0 && badge !== false && badge !== 0;
|
|
630
714
|
const badgeCount = typeof badge === "number" ? Math.min(badge, 99) : null;
|
|
631
715
|
const showCount = typeof badge === "number" && badge > 0;
|
|
632
|
-
return /* @__PURE__ */ React26__default.default.createElement(
|
|
633
|
-
|
|
716
|
+
return /* @__PURE__ */ React26__default.default.createElement(
|
|
717
|
+
Animated9__default.default.View,
|
|
634
718
|
{
|
|
635
|
-
style: [
|
|
636
|
-
|
|
637
|
-
containerVariantStyle,
|
|
638
|
-
{ width: containerSize, height: containerSize },
|
|
639
|
-
isDisabled && styles3.disabled,
|
|
640
|
-
style
|
|
641
|
-
],
|
|
642
|
-
disabled: isDisabled,
|
|
643
|
-
activeOpacity: 1,
|
|
644
|
-
touchSoundDisabled: true,
|
|
645
|
-
onPress: handlePress,
|
|
646
|
-
onPressIn: handlePressIn,
|
|
647
|
-
onPressOut: handlePressOut,
|
|
648
|
-
...props
|
|
719
|
+
style: [styles3.wrapper, animatedStyle],
|
|
720
|
+
...hoverHandlers
|
|
649
721
|
},
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
722
|
+
/* @__PURE__ */ React26__default.default.createElement(
|
|
723
|
+
reactNative.TouchableOpacity,
|
|
724
|
+
{
|
|
725
|
+
style: [
|
|
726
|
+
styles3.base,
|
|
727
|
+
containerVariantStyle,
|
|
728
|
+
{ width: containerSize, height: containerSize },
|
|
729
|
+
isDisabled && styles3.disabled,
|
|
730
|
+
style
|
|
731
|
+
],
|
|
732
|
+
disabled: isDisabled,
|
|
733
|
+
activeOpacity: 1,
|
|
734
|
+
touchSoundDisabled: true,
|
|
735
|
+
onPress: handlePress,
|
|
736
|
+
onPressIn,
|
|
737
|
+
onPressOut,
|
|
738
|
+
accessibilityRole: "button",
|
|
739
|
+
accessibilityLabel: accessibilityLabel ?? iconName ?? "icon button",
|
|
740
|
+
accessibilityHint,
|
|
741
|
+
accessibilityState: { disabled: isDisabled, busy: loading },
|
|
742
|
+
...props
|
|
743
|
+
},
|
|
744
|
+
loading ? /* @__PURE__ */ React26__default.default.createElement(reactNative.ActivityIndicator, { size: "small", color: spinnerColor }) : resolvedIcon
|
|
745
|
+
),
|
|
746
|
+
showBadge && /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [
|
|
747
|
+
styles3.badge,
|
|
748
|
+
{ backgroundColor: colors.primary },
|
|
749
|
+
showCount ? styles3.badgeCount : styles3.badgeDot
|
|
750
|
+
] }, showCount && /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles3.badgeText, { color: colors.primaryForeground }] }, badgeCount))
|
|
751
|
+
);
|
|
656
752
|
}
|
|
657
753
|
var styles3 = reactNative.StyleSheet.create({
|
|
658
754
|
wrapper: {
|
|
@@ -741,29 +837,49 @@ function Text3({ variant = "body-md", color, style, children, ...props }) {
|
|
|
741
837
|
children
|
|
742
838
|
);
|
|
743
839
|
}
|
|
840
|
+
function useColorTransition(active, options = {}) {
|
|
841
|
+
const { duration = TIMINGS.state.duration } = options;
|
|
842
|
+
const progress = Animated9.useSharedValue(active ? 1 : 0);
|
|
843
|
+
React26.useEffect(() => {
|
|
844
|
+
progress.value = Animated9.withTiming(active ? 1 : 0, { duration, easing: EASINGS.standard });
|
|
845
|
+
}, [active, duration, progress]);
|
|
846
|
+
return progress;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
// src/components/Input/Input.tsx
|
|
744
850
|
var webInputResetStyle = reactNative.Platform.OS === "web" ? { outlineStyle: "none", outlineWidth: 0, outlineColor: "transparent", boxShadow: "none" } : {};
|
|
745
|
-
function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suffixStyle, prefixIcon, suffixIcon, prefixIconColor, suffixIconColor, type = "text", containerStyle, inputWrapperStyle, style, onFocus, onBlur, secureTextEntry, editable, ...props }) {
|
|
851
|
+
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 }) {
|
|
746
852
|
const { colors } = useTheme();
|
|
747
853
|
const [focused, setFocused] = React26.useState(false);
|
|
748
854
|
const [showPassword, setShowPassword] = React26.useState(false);
|
|
749
|
-
const
|
|
855
|
+
const focusProgress = useColorTransition(focused, {
|
|
856
|
+
duration: focused ? TIMINGS.focusIn.duration : TIMINGS.focusOut.duration
|
|
857
|
+
});
|
|
750
858
|
const isDisabled = disabled || editable === false;
|
|
751
859
|
const isPassword = type === "password";
|
|
752
860
|
const effectiveSecure = isPassword ? !showPassword : secureTextEntry;
|
|
753
861
|
const effectivePrefix = prefixIcon ? renderIcon(prefixIcon, 20, prefixIconColor ?? colors.foregroundMuted) : prefix;
|
|
754
|
-
const effectiveSuffix = isPassword && !suffix && !suffixIcon ? /* @__PURE__ */ React26__default.default.createElement(
|
|
862
|
+
const effectiveSuffix = isPassword && !suffix && !suffixIcon ? /* @__PURE__ */ React26__default.default.createElement(
|
|
863
|
+
reactNative.TouchableOpacity,
|
|
864
|
+
{
|
|
865
|
+
onPress: () => setShowPassword(!showPassword),
|
|
866
|
+
style: styles4.passwordToggle,
|
|
867
|
+
activeOpacity: 0.6,
|
|
868
|
+
accessibilityRole: "button",
|
|
869
|
+
accessibilityLabel: showPassword ? "Hide password" : "Show password"
|
|
870
|
+
},
|
|
871
|
+
/* @__PURE__ */ React26__default.default.createElement(vectorIcons.AntDesign, { name: showPassword ? "eye" : "eye-invisible", size: 20, color: colors.foregroundMuted })
|
|
872
|
+
) : suffixIcon ? renderIcon(suffixIcon, 20, suffixIconColor ?? colors.foregroundMuted) : suffix;
|
|
873
|
+
const borderColorStyle = Animated9.useAnimatedStyle(() => ({
|
|
874
|
+
borderColor: error ? colors.destructive : Animated9.interpolateColor(focusProgress.value, [0, 1], [colors.border, colors.primary])
|
|
875
|
+
}));
|
|
755
876
|
return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles4.container, isDisabled && styles4.containerDisabled, containerStyle] }, label ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles4.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React26__default.default.createElement(
|
|
756
|
-
|
|
877
|
+
Animated9__default.default.View,
|
|
757
878
|
{
|
|
758
879
|
style: [
|
|
759
880
|
styles4.inputWrapper,
|
|
760
|
-
{
|
|
761
|
-
|
|
762
|
-
inputRange: [0, 1],
|
|
763
|
-
outputRange: [colors.border, colors.primary]
|
|
764
|
-
}),
|
|
765
|
-
backgroundColor: isDisabled ? colors.surface : colors.background
|
|
766
|
-
},
|
|
881
|
+
{ backgroundColor: isDisabled ? colors.surface : colors.background },
|
|
882
|
+
borderColorStyle,
|
|
767
883
|
inputWrapperStyle
|
|
768
884
|
]
|
|
769
885
|
},
|
|
@@ -773,31 +889,36 @@ function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suff
|
|
|
773
889
|
{
|
|
774
890
|
style: [
|
|
775
891
|
styles4.input,
|
|
776
|
-
{
|
|
777
|
-
color: colors.foreground
|
|
778
|
-
},
|
|
892
|
+
{ color: colors.foreground },
|
|
779
893
|
webInputResetStyle,
|
|
780
894
|
style
|
|
781
895
|
],
|
|
782
896
|
onFocus: (e) => {
|
|
783
897
|
setFocused(true);
|
|
784
|
-
reactNative.Animated.timing(focusAnim, { toValue: 1, duration: 120, easing: reactNative.Easing.out(reactNative.Easing.ease), useNativeDriver: false }).start();
|
|
785
898
|
onFocus?.(e);
|
|
786
899
|
},
|
|
787
900
|
onBlur: (e) => {
|
|
788
901
|
setFocused(false);
|
|
789
|
-
reactNative.Animated.timing(focusAnim, { toValue: 0, duration: 80, easing: reactNative.Easing.out(reactNative.Easing.ease), useNativeDriver: false }).start();
|
|
790
902
|
onBlur?.(e);
|
|
791
903
|
},
|
|
792
904
|
placeholderTextColor: colors.foregroundMuted,
|
|
793
905
|
allowFontScaling: true,
|
|
794
906
|
secureTextEntry: effectiveSecure,
|
|
795
907
|
editable: isDisabled ? false : editable,
|
|
908
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
796
909
|
...props
|
|
797
910
|
}
|
|
798
911
|
),
|
|
799
912
|
effectiveSuffix ? typeof effectiveSuffix === "string" ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles4.suffixText, { color: colors.foregroundMuted }, suffixStyle], allowFontScaling: true }, effectiveSuffix) : /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles4.suffixContainer }, effectiveSuffix) : null
|
|
800
|
-
), error ? /* @__PURE__ */ React26__default.default.createElement(
|
|
913
|
+
), error ? /* @__PURE__ */ React26__default.default.createElement(
|
|
914
|
+
reactNative.Text,
|
|
915
|
+
{
|
|
916
|
+
style: [styles4.helperText, { color: colors.destructive }],
|
|
917
|
+
allowFontScaling: true,
|
|
918
|
+
accessibilityLiveRegion: "polite"
|
|
919
|
+
},
|
|
920
|
+
error
|
|
921
|
+
) : null, !error && hint ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles4.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
|
|
801
922
|
}
|
|
802
923
|
var styles4 = reactNative.StyleSheet.create({
|
|
803
924
|
container: {
|
|
@@ -809,7 +930,6 @@ var styles4 = reactNative.StyleSheet.create({
|
|
|
809
930
|
label: {
|
|
810
931
|
fontFamily: "Poppins-Medium",
|
|
811
932
|
fontSize: ms(14)
|
|
812
|
-
// caption size for input labels
|
|
813
933
|
},
|
|
814
934
|
inputWrapper: {
|
|
815
935
|
flexDirection: "row",
|
|
@@ -906,30 +1026,14 @@ var styles5 = reactNative.StyleSheet.create({
|
|
|
906
1026
|
fontFamily: "Poppins-Medium"
|
|
907
1027
|
}
|
|
908
1028
|
});
|
|
909
|
-
|
|
910
|
-
function Card({ children, variant = "elevated", onPress, style }) {
|
|
1029
|
+
function Card({ children, variant = "elevated", onPress, style, accessibilityLabel }) {
|
|
911
1030
|
const { colors } = useTheme();
|
|
912
|
-
const
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
stiffness: 400,
|
|
919
|
-
damping: 30,
|
|
920
|
-
mass: 1
|
|
921
|
-
}).start();
|
|
922
|
-
};
|
|
923
|
-
const handlePressOut = () => {
|
|
924
|
-
if (!onPress) return;
|
|
925
|
-
reactNative.Animated.spring(scale2, {
|
|
926
|
-
toValue: 1,
|
|
927
|
-
useNativeDriver: nativeDriver3,
|
|
928
|
-
stiffness: 250,
|
|
929
|
-
damping: 24,
|
|
930
|
-
mass: 1
|
|
931
|
-
}).start();
|
|
932
|
-
};
|
|
1031
|
+
const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
1032
|
+
pressScale: PRESS_SCALE.card,
|
|
1033
|
+
pressInSpring: SPRINGS.surfacePressIn,
|
|
1034
|
+
pressOutSpring: SPRINGS.surfacePressOut,
|
|
1035
|
+
disabled: !onPress
|
|
1036
|
+
});
|
|
933
1037
|
const handlePress = () => {
|
|
934
1038
|
if (!onPress) return;
|
|
935
1039
|
impactLight();
|
|
@@ -960,14 +1064,16 @@ function Card({ children, variant = "elevated", onPress, style }) {
|
|
|
960
1064
|
}[variant];
|
|
961
1065
|
const cardContent = /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles6.card, variantStyle, style] }, children);
|
|
962
1066
|
if (onPress) {
|
|
963
|
-
return /* @__PURE__ */ React26__default.default.createElement(
|
|
1067
|
+
return /* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: animatedStyle, ...hoverHandlers }, /* @__PURE__ */ React26__default.default.createElement(
|
|
964
1068
|
reactNative.TouchableOpacity,
|
|
965
1069
|
{
|
|
966
1070
|
onPress: handlePress,
|
|
967
|
-
onPressIn
|
|
968
|
-
onPressOut
|
|
1071
|
+
onPressIn,
|
|
1072
|
+
onPressOut,
|
|
969
1073
|
activeOpacity: 1,
|
|
970
|
-
touchSoundDisabled: true
|
|
1074
|
+
touchSoundDisabled: true,
|
|
1075
|
+
accessibilityRole: "button",
|
|
1076
|
+
accessibilityLabel
|
|
971
1077
|
},
|
|
972
1078
|
cardContent
|
|
973
1079
|
));
|
|
@@ -994,7 +1100,6 @@ function CardFooter({ children, style }) {
|
|
|
994
1100
|
var styles6 = reactNative.StyleSheet.create({
|
|
995
1101
|
card: {
|
|
996
1102
|
borderRadius: RADIUS.md,
|
|
997
|
-
// 14px — Airbnb property card spec
|
|
998
1103
|
borderWidth: 1
|
|
999
1104
|
},
|
|
1000
1105
|
header: {
|
|
@@ -1092,20 +1197,19 @@ function Skeleton({
|
|
|
1092
1197
|
style
|
|
1093
1198
|
}) {
|
|
1094
1199
|
const { colors, colorScheme } = useTheme();
|
|
1095
|
-
const
|
|
1200
|
+
const shimmer = Animated9.useSharedValue(0);
|
|
1096
1201
|
const [containerWidth, setContainerWidth] = React26.useState(300);
|
|
1097
1202
|
const shimmerHighlight = colorScheme === "dark" ? "rgba(255,255,255,0.08)" : "rgba(255,255,255,0.7)";
|
|
1098
1203
|
React26.useEffect(() => {
|
|
1099
|
-
|
|
1100
|
-
|
|
1204
|
+
shimmer.value = Animated9.withRepeat(
|
|
1205
|
+
Animated9.withTiming(1, { duration: TIMINGS.shimmer.duration, easing: Animated9.Easing.linear }),
|
|
1206
|
+
-1,
|
|
1207
|
+
false
|
|
1101
1208
|
);
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
inputRange: [0, 1],
|
|
1107
|
-
outputRange: [-containerWidth, containerWidth]
|
|
1108
|
-
});
|
|
1209
|
+
}, [shimmer]);
|
|
1210
|
+
const shimmerStyle = Animated9.useAnimatedStyle(() => ({
|
|
1211
|
+
transform: [{ translateX: -containerWidth + shimmer.value * (containerWidth * 2) }]
|
|
1212
|
+
}));
|
|
1109
1213
|
const resolvedWidth = preset === "circle" ? s(diameter) : preset === "text" ? "60%" : width;
|
|
1110
1214
|
const resolvedHeight = preset === "circle" ? s(diameter) : preset === "text" ? 14 : height;
|
|
1111
1215
|
const resolvedRadius = preset === "circle" ? 9999 : preset === "text" ? 4 : borderRadius;
|
|
@@ -1117,9 +1221,12 @@ function Skeleton({
|
|
|
1117
1221
|
{ width: resolvedWidth, height: resolvedHeight, borderRadius: resolvedRadius, backgroundColor: colors.surface },
|
|
1118
1222
|
style
|
|
1119
1223
|
],
|
|
1120
|
-
onLayout: (e) => setContainerWidth(e.nativeEvent.layout.width)
|
|
1224
|
+
onLayout: (e) => setContainerWidth(e.nativeEvent.layout.width),
|
|
1225
|
+
accessibilityRole: "progressbar",
|
|
1226
|
+
accessibilityLabel: "Loading",
|
|
1227
|
+
accessibilityState: { busy: true }
|
|
1121
1228
|
},
|
|
1122
|
-
/* @__PURE__ */ React26__default.default.createElement(
|
|
1229
|
+
/* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: [reactNative.StyleSheet.absoluteFill, shimmerStyle] }, /* @__PURE__ */ React26__default.default.createElement(
|
|
1123
1230
|
expoLinearGradient.LinearGradient,
|
|
1124
1231
|
{
|
|
1125
1232
|
colors: ["transparent", shimmerHighlight, "transparent"],
|
|
@@ -1265,31 +1372,32 @@ var styles11 = reactNative.StyleSheet.create({
|
|
|
1265
1372
|
lineHeight: ms(17)
|
|
1266
1373
|
}
|
|
1267
1374
|
});
|
|
1268
|
-
function Progress({ value = 0, max = 100, variant = "default", style }) {
|
|
1375
|
+
function Progress({ value = 0, max = 100, variant = "default", style, accessibilityLabel }) {
|
|
1269
1376
|
const { colors } = useTheme();
|
|
1270
1377
|
const percent = Math.min(Math.max(value / max * 100, 0), 100);
|
|
1271
1378
|
const [trackWidth, setTrackWidth] = React26.useState(0);
|
|
1272
|
-
const animatedWidth =
|
|
1379
|
+
const animatedWidth = Animated9.useSharedValue(0);
|
|
1273
1380
|
React26.useEffect(() => {
|
|
1274
1381
|
if (trackWidth === 0) return;
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
}).start();
|
|
1281
|
-
}, [percent, trackWidth]);
|
|
1382
|
+
animatedWidth.value = Animated9.withSpring(percent / 100 * trackWidth, SPRINGS.glide);
|
|
1383
|
+
}, [percent, trackWidth, animatedWidth]);
|
|
1384
|
+
const indicatorAnimatedStyle = Animated9.useAnimatedStyle(() => ({
|
|
1385
|
+
width: animatedWidth.value
|
|
1386
|
+
}));
|
|
1282
1387
|
const indicatorColor = variant === "success" ? colors.success : variant === "warning" ? colors.warning : variant === "destructive" ? colors.destructive : colors.primary;
|
|
1283
1388
|
return /* @__PURE__ */ React26__default.default.createElement(
|
|
1284
1389
|
reactNative.View,
|
|
1285
1390
|
{
|
|
1286
1391
|
style: [styles12.track, { backgroundColor: colors.surface }, style],
|
|
1287
|
-
onLayout: (e) => setTrackWidth(e.nativeEvent.layout.width)
|
|
1392
|
+
onLayout: (e) => setTrackWidth(e.nativeEvent.layout.width),
|
|
1393
|
+
accessibilityRole: "progressbar",
|
|
1394
|
+
accessibilityLabel,
|
|
1395
|
+
accessibilityValue: { min: 0, max: 100, now: Math.round(percent) }
|
|
1288
1396
|
},
|
|
1289
1397
|
/* @__PURE__ */ React26__default.default.createElement(
|
|
1290
|
-
|
|
1398
|
+
Animated9__default.default.View,
|
|
1291
1399
|
{
|
|
1292
|
-
style: [styles12.indicator, {
|
|
1400
|
+
style: [styles12.indicator, { backgroundColor: indicatorColor }, indicatorAnimatedStyle]
|
|
1293
1401
|
}
|
|
1294
1402
|
)
|
|
1295
1403
|
);
|
|
@@ -1406,20 +1514,25 @@ function Textarea({
|
|
|
1406
1514
|
style,
|
|
1407
1515
|
onFocus,
|
|
1408
1516
|
onBlur,
|
|
1517
|
+
accessibilityLabel,
|
|
1409
1518
|
...props
|
|
1410
1519
|
}) {
|
|
1411
1520
|
const { colors } = useTheme();
|
|
1412
1521
|
const [focused, setFocused] = React26.useState(false);
|
|
1522
|
+
const focusProgress = useColorTransition(focused, {
|
|
1523
|
+
duration: focused ? TIMINGS.focusIn.duration : TIMINGS.focusOut.duration
|
|
1524
|
+
});
|
|
1413
1525
|
const resolvedPrefixIcon = prefixIcon ? renderIcon(prefixIcon, ms(16), prefixIconColor ?? colors.foregroundMuted) : prefixIconNode;
|
|
1526
|
+
const borderColorStyle = Animated9.useAnimatedStyle(() => ({
|
|
1527
|
+
borderColor: error ? colors.destructive : Animated9.interpolateColor(focusProgress.value, [0, 1], [colors.border, colors.primary])
|
|
1528
|
+
}));
|
|
1414
1529
|
return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles14.container, containerStyle] }, label ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles14.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React26__default.default.createElement(
|
|
1415
|
-
|
|
1530
|
+
Animated9__default.default.View,
|
|
1416
1531
|
{
|
|
1417
1532
|
style: [
|
|
1418
1533
|
styles14.inputWrapper,
|
|
1419
|
-
{
|
|
1420
|
-
|
|
1421
|
-
backgroundColor: colors.background
|
|
1422
|
-
}
|
|
1534
|
+
{ backgroundColor: colors.background },
|
|
1535
|
+
borderColorStyle
|
|
1423
1536
|
]
|
|
1424
1537
|
},
|
|
1425
1538
|
resolvedPrefixIcon ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles14.prefixIcon }, resolvedPrefixIcon) : null,
|
|
@@ -1448,10 +1561,19 @@ function Textarea({
|
|
|
1448
1561
|
},
|
|
1449
1562
|
placeholderTextColor: colors.foregroundMuted,
|
|
1450
1563
|
allowFontScaling: true,
|
|
1564
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
1451
1565
|
...props
|
|
1452
1566
|
}
|
|
1453
1567
|
)
|
|
1454
|
-
), error ? /* @__PURE__ */ React26__default.default.createElement(
|
|
1568
|
+
), error ? /* @__PURE__ */ React26__default.default.createElement(
|
|
1569
|
+
reactNative.Text,
|
|
1570
|
+
{
|
|
1571
|
+
style: [styles14.helperText, { color: colors.destructive }],
|
|
1572
|
+
allowFontScaling: true,
|
|
1573
|
+
accessibilityLiveRegion: "polite"
|
|
1574
|
+
},
|
|
1575
|
+
error
|
|
1576
|
+
) : null, !error && hint ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles14.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
|
|
1455
1577
|
}
|
|
1456
1578
|
var styles14 = reactNative.StyleSheet.create({
|
|
1457
1579
|
container: {
|
|
@@ -1464,7 +1586,7 @@ var styles14 = reactNative.StyleSheet.create({
|
|
|
1464
1586
|
marginBottom: vs(2)
|
|
1465
1587
|
},
|
|
1466
1588
|
inputWrapper: {
|
|
1467
|
-
borderWidth:
|
|
1589
|
+
borderWidth: 2,
|
|
1468
1590
|
borderRadius: 8,
|
|
1469
1591
|
paddingHorizontal: s(14),
|
|
1470
1592
|
paddingVertical: vs(11),
|
|
@@ -1489,47 +1611,27 @@ var styles14 = reactNative.StyleSheet.create({
|
|
|
1489
1611
|
marginTop: vs(4)
|
|
1490
1612
|
}
|
|
1491
1613
|
});
|
|
1492
|
-
var nativeDriver4 = reactNative.Platform.OS !== "web";
|
|
1493
1614
|
function Checkbox({
|
|
1494
1615
|
checked = false,
|
|
1495
1616
|
onCheckedChange,
|
|
1496
1617
|
label,
|
|
1497
1618
|
disabled,
|
|
1498
|
-
style
|
|
1619
|
+
style,
|
|
1620
|
+
accessibilityLabel
|
|
1499
1621
|
}) {
|
|
1500
1622
|
const { colors } = useTheme();
|
|
1501
|
-
const
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
React26.useEffect(() => {
|
|
1505
|
-
reactNative.Animated.parallel([
|
|
1506
|
-
reactNative.Animated.timing(bgOpacity, {
|
|
1507
|
-
toValue: checked ? 1 : 0,
|
|
1508
|
-
duration: 150,
|
|
1509
|
-
useNativeDriver: false
|
|
1510
|
-
}),
|
|
1511
|
-
reactNative.Animated.timing(checkOpacity, {
|
|
1512
|
-
toValue: checked ? 1 : 0,
|
|
1513
|
-
duration: 120,
|
|
1514
|
-
useNativeDriver: false
|
|
1515
|
-
})
|
|
1516
|
-
]).start();
|
|
1517
|
-
}, [checked, bgOpacity, checkOpacity]);
|
|
1518
|
-
const borderColor = bgOpacity.interpolate({
|
|
1519
|
-
inputRange: [0, 1],
|
|
1520
|
-
outputRange: [colors.border, colors.primary]
|
|
1521
|
-
});
|
|
1522
|
-
const backgroundColor = bgOpacity.interpolate({
|
|
1523
|
-
inputRange: [0, 1],
|
|
1524
|
-
outputRange: ["transparent", colors.primary]
|
|
1623
|
+
const { animatedStyle: scaleStyle, onPressIn, onPressOut } = usePressScale({
|
|
1624
|
+
pressScale: PRESS_SCALE.button,
|
|
1625
|
+
disabled
|
|
1525
1626
|
});
|
|
1526
|
-
const
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1627
|
+
const progress = useColorTransition(checked);
|
|
1628
|
+
const boxStyle = Animated9.useAnimatedStyle(() => ({
|
|
1629
|
+
borderColor: Animated9.interpolateColor(progress.value, [0, 1], [colors.border, colors.primary]),
|
|
1630
|
+
backgroundColor: Animated9.interpolateColor(progress.value, [0, 1], ["transparent", colors.primary])
|
|
1631
|
+
}));
|
|
1632
|
+
const checkStyle = Animated9.useAnimatedStyle(() => ({
|
|
1633
|
+
opacity: Animated9.withTiming(checked ? 1 : 0, { duration: TIMINGS.state.duration, easing: EASINGS.standard })
|
|
1634
|
+
}));
|
|
1533
1635
|
return /* @__PURE__ */ React26__default.default.createElement(
|
|
1534
1636
|
reactNative.TouchableOpacity,
|
|
1535
1637
|
{
|
|
@@ -1538,25 +1640,21 @@ function Checkbox({
|
|
|
1538
1640
|
selectionAsync();
|
|
1539
1641
|
onCheckedChange?.(!checked);
|
|
1540
1642
|
},
|
|
1541
|
-
onPressIn
|
|
1542
|
-
onPressOut
|
|
1643
|
+
onPressIn,
|
|
1644
|
+
onPressOut,
|
|
1543
1645
|
disabled,
|
|
1544
1646
|
activeOpacity: 1,
|
|
1545
|
-
touchSoundDisabled: true
|
|
1647
|
+
touchSoundDisabled: true,
|
|
1648
|
+
accessibilityRole: "checkbox",
|
|
1649
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
1650
|
+
accessibilityState: { checked, disabled: !!disabled }
|
|
1546
1651
|
},
|
|
1547
|
-
/* @__PURE__ */ React26__default.default.createElement(
|
|
1548
|
-
|
|
1652
|
+
/* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: scaleStyle }, /* @__PURE__ */ React26__default.default.createElement(
|
|
1653
|
+
Animated9__default.default.View,
|
|
1549
1654
|
{
|
|
1550
|
-
style: [
|
|
1551
|
-
styles15.box,
|
|
1552
|
-
{
|
|
1553
|
-
borderColor,
|
|
1554
|
-
backgroundColor,
|
|
1555
|
-
opacity: disabled ? 0.45 : 1
|
|
1556
|
-
}
|
|
1557
|
-
]
|
|
1655
|
+
style: [styles15.box, { opacity: disabled ? 0.45 : 1 }, boxStyle]
|
|
1558
1656
|
},
|
|
1559
|
-
/* @__PURE__ */ React26__default.default.createElement(
|
|
1657
|
+
/* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: checkStyle }, /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles15.checkmark, { borderColor: colors.primaryForeground }] }))
|
|
1560
1658
|
)),
|
|
1561
1659
|
label ? /* @__PURE__ */ React26__default.default.createElement(
|
|
1562
1660
|
reactNative.Text,
|
|
@@ -1595,47 +1693,34 @@ var styles15 = reactNative.StyleSheet.create({
|
|
|
1595
1693
|
lineHeight: mvs(20)
|
|
1596
1694
|
}
|
|
1597
1695
|
});
|
|
1598
|
-
var nativeDriver5 = reactNative.Platform.OS !== "web";
|
|
1599
1696
|
var TRACK_WIDTH = s(52);
|
|
1600
1697
|
var TRACK_HEIGHT = s(30);
|
|
1601
1698
|
var THUMB_SIZE = s(24);
|
|
1602
1699
|
var THUMB_OFFSET = s(3);
|
|
1603
1700
|
var THUMB_TRAVEL = TRACK_WIDTH - THUMB_SIZE - THUMB_OFFSET * 2;
|
|
1604
1701
|
var ICON_SIZE = s(13);
|
|
1605
|
-
function Switch({ checked = false, onCheckedChange, disabled, style }) {
|
|
1702
|
+
function Switch({ checked = false, onCheckedChange, disabled, style, accessibilityLabel }) {
|
|
1606
1703
|
const { colors } = useTheme();
|
|
1607
|
-
const
|
|
1608
|
-
const trackOpacity = React26.useRef(new reactNative.Animated.Value(checked ? 1 : 0)).current;
|
|
1609
|
-
const checkOpacity = React26.useRef(new reactNative.Animated.Value(checked ? 1 : 0)).current;
|
|
1610
|
-
const crossOpacity = React26.useRef(new reactNative.Animated.Value(checked ? 0 : 1)).current;
|
|
1704
|
+
const progress = Animated9.useSharedValue(checked ? 1 : 0);
|
|
1611
1705
|
React26.useEffect(() => {
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
duration: 120,
|
|
1631
|
-
useNativeDriver: true
|
|
1632
|
-
})
|
|
1633
|
-
]).start();
|
|
1634
|
-
}, [checked, translateX, trackOpacity, checkOpacity, crossOpacity]);
|
|
1635
|
-
const trackColor = trackOpacity.interpolate({
|
|
1636
|
-
inputRange: [0, 1],
|
|
1637
|
-
outputRange: [colors.surface, colors.primary]
|
|
1638
|
-
});
|
|
1706
|
+
progress.value = Animated9.withSpring(checked ? 1 : 0, SPRINGS.elastic);
|
|
1707
|
+
}, [checked, progress]);
|
|
1708
|
+
const thumbStyle = Animated9.useAnimatedStyle(() => ({
|
|
1709
|
+
transform: [{ translateX: progress.value * THUMB_TRAVEL }]
|
|
1710
|
+
}));
|
|
1711
|
+
const trackStyle = Animated9.useAnimatedStyle(() => ({
|
|
1712
|
+
backgroundColor: Animated9.interpolateColor(
|
|
1713
|
+
progress.value,
|
|
1714
|
+
[0, 1],
|
|
1715
|
+
[colors.surfaceStrong, colors.primary]
|
|
1716
|
+
)
|
|
1717
|
+
}));
|
|
1718
|
+
const checkIconStyle = Animated9.useAnimatedStyle(() => ({
|
|
1719
|
+
opacity: Animated9.withTiming(checked ? 1 : 0, { duration: TIMINGS.state.duration, easing: EASINGS.standard })
|
|
1720
|
+
}));
|
|
1721
|
+
const crossIconStyle = Animated9.useAnimatedStyle(() => ({
|
|
1722
|
+
opacity: Animated9.withTiming(checked ? 0 : 1, { duration: TIMINGS.state.duration, easing: EASINGS.standard })
|
|
1723
|
+
}));
|
|
1639
1724
|
return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [{ opacity: disabled ? 0.45 : 1 }, style] }, /* @__PURE__ */ React26__default.default.createElement(
|
|
1640
1725
|
reactNative.TouchableOpacity,
|
|
1641
1726
|
{
|
|
@@ -1646,29 +1731,25 @@ function Switch({ checked = false, onCheckedChange, disabled, style }) {
|
|
|
1646
1731
|
disabled,
|
|
1647
1732
|
activeOpacity: 0.8,
|
|
1648
1733
|
touchSoundDisabled: true,
|
|
1649
|
-
|
|
1734
|
+
accessibilityRole: "switch",
|
|
1735
|
+
accessibilityLabel,
|
|
1736
|
+
accessibilityState: { checked, disabled: !!disabled }
|
|
1650
1737
|
},
|
|
1651
|
-
/* @__PURE__ */ React26__default.default.createElement(
|
|
1652
|
-
|
|
1738
|
+
/* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: [styles16.track, trackStyle] }, /* @__PURE__ */ React26__default.default.createElement(
|
|
1739
|
+
Animated9__default.default.View,
|
|
1653
1740
|
{
|
|
1654
|
-
style: [
|
|
1655
|
-
styles16.thumb,
|
|
1656
|
-
{ backgroundColor: colors.primaryForeground, transform: [{ translateX }] }
|
|
1657
|
-
]
|
|
1741
|
+
style: [styles16.thumb, { backgroundColor: colors.primaryForeground }, thumbStyle]
|
|
1658
1742
|
},
|
|
1659
|
-
/* @__PURE__ */ React26__default.default.createElement(
|
|
1660
|
-
/* @__PURE__ */ React26__default.default.createElement(
|
|
1743
|
+
/* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: [styles16.iconWrapper, checkIconStyle] }, /* @__PURE__ */ React26__default.default.createElement(vectorIcons.Feather, { name: "check", size: ICON_SIZE, color: colors.primary })),
|
|
1744
|
+
/* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: [styles16.iconWrapper, crossIconStyle] }, /* @__PURE__ */ React26__default.default.createElement(vectorIcons.Feather, { name: "x", size: ICON_SIZE, color: colors.foregroundMuted }))
|
|
1661
1745
|
))
|
|
1662
1746
|
));
|
|
1663
1747
|
}
|
|
1664
1748
|
var styles16 = reactNative.StyleSheet.create({
|
|
1665
|
-
wrapper: {},
|
|
1666
1749
|
track: {
|
|
1667
1750
|
width: TRACK_WIDTH,
|
|
1668
1751
|
height: TRACK_HEIGHT,
|
|
1669
1752
|
borderRadius: TRACK_HEIGHT / 2
|
|
1670
|
-
// No justifyContent/alignItems — thumb uses absolute positioning
|
|
1671
|
-
// so the track's flex layout doesn't interfere with translateX animation
|
|
1672
1753
|
},
|
|
1673
1754
|
thumb: {
|
|
1674
1755
|
position: "absolute",
|
|
@@ -1689,7 +1770,6 @@ var styles16 = reactNative.StyleSheet.create({
|
|
|
1689
1770
|
position: "absolute"
|
|
1690
1771
|
}
|
|
1691
1772
|
});
|
|
1692
|
-
var nativeDriver6 = reactNative.Platform.OS !== "web";
|
|
1693
1773
|
var sizeStyles = {
|
|
1694
1774
|
sm: { paddingHorizontal: s(12), paddingVertical: vs(8), minWidth: s(40), minHeight: vs(40) },
|
|
1695
1775
|
md: { paddingHorizontal: s(16), paddingVertical: vs(12), minWidth: s(44), minHeight: vs(44) },
|
|
@@ -1710,38 +1790,23 @@ function Toggle({
|
|
|
1710
1790
|
activeIconColor,
|
|
1711
1791
|
disabled,
|
|
1712
1792
|
style,
|
|
1793
|
+
accessibilityLabel,
|
|
1713
1794
|
...props
|
|
1714
1795
|
}) {
|
|
1715
1796
|
const { colors } = useTheme();
|
|
1716
|
-
const
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
reactNative.Animated.timing(pressAnim, {
|
|
1720
|
-
toValue: pressed ? 1 : 0,
|
|
1721
|
-
duration: 150,
|
|
1722
|
-
easing: reactNative.Easing.out(reactNative.Easing.ease),
|
|
1723
|
-
useNativeDriver: false
|
|
1724
|
-
}).start();
|
|
1725
|
-
}, [pressed, pressAnim]);
|
|
1726
|
-
const handlePressIn = () => {
|
|
1727
|
-
if (disabled) return;
|
|
1728
|
-
reactNative.Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver6, stiffness: 600, damping: 35, mass: 0.8 }).start();
|
|
1729
|
-
};
|
|
1730
|
-
const handlePressOut = () => {
|
|
1731
|
-
reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver6, stiffness: 280, damping: 22, mass: 0.8 }).start();
|
|
1732
|
-
};
|
|
1733
|
-
const borderColor = pressAnim.interpolate({
|
|
1734
|
-
inputRange: [0, 1],
|
|
1735
|
-
outputRange: [variant === "outline" ? colors.border : "transparent", colors.primary]
|
|
1736
|
-
});
|
|
1737
|
-
const backgroundColor = pressAnim.interpolate({
|
|
1738
|
-
inputRange: [0, 1],
|
|
1739
|
-
outputRange: ["transparent", colors.surfaceStrong]
|
|
1740
|
-
});
|
|
1741
|
-
const textColor = pressAnim.interpolate({
|
|
1742
|
-
inputRange: [0, 1],
|
|
1743
|
-
outputRange: [colors.foreground, colors.primary]
|
|
1797
|
+
const { animatedStyle: scaleStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
1798
|
+
pressScale: PRESS_SCALE.button,
|
|
1799
|
+
disabled
|
|
1744
1800
|
});
|
|
1801
|
+
const progress = useColorTransition(pressed);
|
|
1802
|
+
const inactiveBorder = variant === "outline" ? colors.border : "transparent";
|
|
1803
|
+
const surfaceStyle = Animated9.useAnimatedStyle(() => ({
|
|
1804
|
+
borderColor: Animated9.interpolateColor(progress.value, [0, 1], [inactiveBorder, colors.primary]),
|
|
1805
|
+
backgroundColor: Animated9.interpolateColor(progress.value, [0, 1], ["transparent", colors.surfaceStrong])
|
|
1806
|
+
}));
|
|
1807
|
+
const textStyle = Animated9.useAnimatedStyle(() => ({
|
|
1808
|
+
color: Animated9.interpolateColor(progress.value, [0, 1], [colors.foreground, colors.primary])
|
|
1809
|
+
}));
|
|
1745
1810
|
const iconSize = iconSizeMap2[size];
|
|
1746
1811
|
const LeftIcon = () => {
|
|
1747
1812
|
const renderProp = (prop) => {
|
|
@@ -1760,32 +1825,43 @@ function Toggle({
|
|
|
1760
1825
|
if (custom) return /* @__PURE__ */ React26__default.default.createElement(React26__default.default.Fragment, null, custom);
|
|
1761
1826
|
return /* @__PURE__ */ React26__default.default.createElement(vectorIcons.FontAwesome5, { name: "circle", size: iconSize, color: colors.foregroundMuted });
|
|
1762
1827
|
};
|
|
1763
|
-
return /* @__PURE__ */ React26__default.default.createElement(
|
|
1764
|
-
|
|
1828
|
+
return /* @__PURE__ */ React26__default.default.createElement(
|
|
1829
|
+
Animated9__default.default.View,
|
|
1765
1830
|
{
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
onPressedChange?.(!pressed);
|
|
1769
|
-
},
|
|
1770
|
-
onPressIn: handlePressIn,
|
|
1771
|
-
onPressOut: handlePressOut,
|
|
1772
|
-
disabled,
|
|
1773
|
-
activeOpacity: 1,
|
|
1774
|
-
touchSoundDisabled: true,
|
|
1775
|
-
...props
|
|
1831
|
+
style: [scaleStyle, disabled && styles17.disabled, style],
|
|
1832
|
+
...hoverHandlers
|
|
1776
1833
|
},
|
|
1777
1834
|
/* @__PURE__ */ React26__default.default.createElement(
|
|
1778
|
-
reactNative.
|
|
1835
|
+
reactNative.TouchableOpacity,
|
|
1779
1836
|
{
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1837
|
+
onPress: () => {
|
|
1838
|
+
selectionAsync();
|
|
1839
|
+
onPressedChange?.(!pressed);
|
|
1840
|
+
},
|
|
1841
|
+
onPressIn,
|
|
1842
|
+
onPressOut,
|
|
1843
|
+
disabled,
|
|
1844
|
+
activeOpacity: 1,
|
|
1845
|
+
touchSoundDisabled: true,
|
|
1846
|
+
accessibilityRole: "button",
|
|
1847
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
1848
|
+
accessibilityState: { selected: pressed, disabled: !!disabled },
|
|
1849
|
+
...props
|
|
1785
1850
|
},
|
|
1786
|
-
/* @__PURE__ */ React26__default.default.createElement(
|
|
1851
|
+
/* @__PURE__ */ React26__default.default.createElement(
|
|
1852
|
+
Animated9__default.default.View,
|
|
1853
|
+
{
|
|
1854
|
+
style: [
|
|
1855
|
+
styles17.base,
|
|
1856
|
+
sizeStyles[size],
|
|
1857
|
+
{ borderWidth: 2 },
|
|
1858
|
+
surfaceStyle
|
|
1859
|
+
]
|
|
1860
|
+
},
|
|
1861
|
+
/* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles17.inner }, /* @__PURE__ */ React26__default.default.createElement(LeftIcon, null), label ? /* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.Text, { style: [styles17.label, textStyle], allowFontScaling: true }, label) : null)
|
|
1862
|
+
)
|
|
1787
1863
|
)
|
|
1788
|
-
)
|
|
1864
|
+
);
|
|
1789
1865
|
}
|
|
1790
1866
|
var styles17 = reactNative.StyleSheet.create({
|
|
1791
1867
|
base: {
|
|
@@ -1805,21 +1881,28 @@ var styles17 = reactNative.StyleSheet.create({
|
|
|
1805
1881
|
fontSize: ms(14)
|
|
1806
1882
|
}
|
|
1807
1883
|
});
|
|
1808
|
-
var nativeDriver7 = reactNative.Platform.OS !== "web";
|
|
1809
1884
|
function RadioItem({
|
|
1810
1885
|
option,
|
|
1811
1886
|
selected,
|
|
1812
1887
|
onSelect
|
|
1813
1888
|
}) {
|
|
1814
1889
|
const { colors } = useTheme();
|
|
1815
|
-
const
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
const
|
|
1821
|
-
|
|
1822
|
-
|
|
1890
|
+
const { animatedStyle: scaleStyle, onPressIn, onPressOut } = usePressScale({
|
|
1891
|
+
pressScale: PRESS_SCALE.button,
|
|
1892
|
+
disabled: option.disabled
|
|
1893
|
+
});
|
|
1894
|
+
const colorProgress = useColorTransition(selected);
|
|
1895
|
+
const dotScale = Animated9.useSharedValue(selected ? 1 : 0);
|
|
1896
|
+
React26.useEffect(() => {
|
|
1897
|
+
dotScale.value = Animated9.withSpring(selected ? 1 : 0, SPRINGS.elastic);
|
|
1898
|
+
}, [selected, dotScale]);
|
|
1899
|
+
const radioStyle = Animated9.useAnimatedStyle(() => ({
|
|
1900
|
+
borderColor: Animated9.interpolateColor(colorProgress.value, [0, 1], [colors.border, colors.primary])
|
|
1901
|
+
}));
|
|
1902
|
+
const dotStyle = Animated9.useAnimatedStyle(() => ({
|
|
1903
|
+
transform: [{ scale: dotScale.value }],
|
|
1904
|
+
opacity: dotScale.value
|
|
1905
|
+
}));
|
|
1823
1906
|
return /* @__PURE__ */ React26__default.default.createElement(
|
|
1824
1907
|
reactNative.TouchableOpacity,
|
|
1825
1908
|
{
|
|
@@ -1830,26 +1913,26 @@ function RadioItem({
|
|
|
1830
1913
|
onSelect();
|
|
1831
1914
|
}
|
|
1832
1915
|
},
|
|
1833
|
-
onPressIn
|
|
1834
|
-
onPressOut
|
|
1916
|
+
onPressIn,
|
|
1917
|
+
onPressOut,
|
|
1835
1918
|
activeOpacity: 1,
|
|
1836
1919
|
touchSoundDisabled: true,
|
|
1837
|
-
disabled: option.disabled
|
|
1920
|
+
disabled: option.disabled,
|
|
1921
|
+
accessibilityRole: "radio",
|
|
1922
|
+
accessibilityLabel: option.label,
|
|
1923
|
+
accessibilityState: { checked: selected, disabled: !!option.disabled }
|
|
1838
1924
|
},
|
|
1839
|
-
/* @__PURE__ */ React26__default.default.createElement(
|
|
1840
|
-
|
|
1925
|
+
/* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: scaleStyle }, /* @__PURE__ */ React26__default.default.createElement(
|
|
1926
|
+
Animated9__default.default.View,
|
|
1841
1927
|
{
|
|
1842
1928
|
style: [
|
|
1843
1929
|
styles18.radio,
|
|
1844
|
-
{
|
|
1845
|
-
|
|
1846
|
-
opacity: option.disabled ? 0.45 : 1,
|
|
1847
|
-
transform: [{ scale: scale2 }]
|
|
1848
|
-
}
|
|
1930
|
+
{ opacity: option.disabled ? 0.45 : 1 },
|
|
1931
|
+
radioStyle
|
|
1849
1932
|
]
|
|
1850
1933
|
},
|
|
1851
|
-
|
|
1852
|
-
),
|
|
1934
|
+
/* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: [styles18.dot, { backgroundColor: colors.primary }, dotStyle] })
|
|
1935
|
+
)),
|
|
1853
1936
|
/* @__PURE__ */ React26__default.default.createElement(
|
|
1854
1937
|
reactNative.Text,
|
|
1855
1938
|
{
|
|
@@ -1868,17 +1951,26 @@ function RadioGroup({
|
|
|
1868
1951
|
value,
|
|
1869
1952
|
onValueChange,
|
|
1870
1953
|
orientation = "vertical",
|
|
1871
|
-
style
|
|
1954
|
+
style,
|
|
1955
|
+
accessibilityLabel
|
|
1872
1956
|
}) {
|
|
1873
|
-
return /* @__PURE__ */ React26__default.default.createElement(
|
|
1874
|
-
|
|
1957
|
+
return /* @__PURE__ */ React26__default.default.createElement(
|
|
1958
|
+
reactNative.View,
|
|
1875
1959
|
{
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1960
|
+
style: [styles18.container, orientation === "horizontal" && styles18.horizontal, style],
|
|
1961
|
+
accessibilityRole: "radiogroup",
|
|
1962
|
+
accessibilityLabel
|
|
1963
|
+
},
|
|
1964
|
+
options.map((option) => /* @__PURE__ */ React26__default.default.createElement(
|
|
1965
|
+
RadioItem,
|
|
1966
|
+
{
|
|
1967
|
+
key: option.value,
|
|
1968
|
+
option,
|
|
1969
|
+
selected: option.value === value,
|
|
1970
|
+
onSelect: () => onValueChange?.(option.value)
|
|
1971
|
+
}
|
|
1972
|
+
))
|
|
1973
|
+
);
|
|
1882
1974
|
}
|
|
1883
1975
|
var styles18 = reactNative.StyleSheet.create({
|
|
1884
1976
|
container: {
|
|
@@ -1912,7 +2004,6 @@ var styles18 = reactNative.StyleSheet.create({
|
|
|
1912
2004
|
lineHeight: mvs(20)
|
|
1913
2005
|
}
|
|
1914
2006
|
});
|
|
1915
|
-
var nativeDriver8 = reactNative.Platform.OS !== "web";
|
|
1916
2007
|
function TabTrigger({
|
|
1917
2008
|
tab,
|
|
1918
2009
|
isActive,
|
|
@@ -1921,13 +2012,9 @@ function TabTrigger({
|
|
|
1921
2012
|
variant
|
|
1922
2013
|
}) {
|
|
1923
2014
|
const { colors } = useTheme();
|
|
1924
|
-
const
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
};
|
|
1928
|
-
const handlePressOut = () => {
|
|
1929
|
-
reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver8, stiffness: 280, damping: 22, mass: 0.8 }).start();
|
|
1930
|
-
};
|
|
2015
|
+
const { animatedStyle, onPressIn, onPressOut } = usePressScale({
|
|
2016
|
+
pressScale: PRESS_SCALE.button
|
|
2017
|
+
});
|
|
1931
2018
|
const isUnderline = variant === "underline";
|
|
1932
2019
|
return /* @__PURE__ */ React26__default.default.createElement(
|
|
1933
2020
|
reactNative.TouchableOpacity,
|
|
@@ -1938,13 +2025,16 @@ function TabTrigger({
|
|
|
1938
2025
|
isUnderline && isActive && { borderBottomColor: colors.primary }
|
|
1939
2026
|
],
|
|
1940
2027
|
onPress,
|
|
1941
|
-
onPressIn
|
|
1942
|
-
onPressOut
|
|
2028
|
+
onPressIn,
|
|
2029
|
+
onPressOut,
|
|
1943
2030
|
onLayout,
|
|
1944
2031
|
activeOpacity: 1,
|
|
1945
|
-
touchSoundDisabled: true
|
|
2032
|
+
touchSoundDisabled: true,
|
|
2033
|
+
accessibilityRole: "tab",
|
|
2034
|
+
accessibilityState: { selected: isActive },
|
|
2035
|
+
accessibilityLabel: tab.label
|
|
1946
2036
|
},
|
|
1947
|
-
/* @__PURE__ */ React26__default.default.createElement(
|
|
2037
|
+
/* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: animatedStyle }, /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles19.triggerInner }, tab.icon ? typeof tab.icon === "function" ? tab.icon(isActive) : tab.icon : null, /* @__PURE__ */ React26__default.default.createElement(
|
|
1948
2038
|
reactNative.Text,
|
|
1949
2039
|
{
|
|
1950
2040
|
style: [
|
|
@@ -1963,20 +2053,18 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
|
|
|
1963
2053
|
const { colors } = useTheme();
|
|
1964
2054
|
const active = value ?? internal;
|
|
1965
2055
|
const tabLayouts = React26.useRef({});
|
|
1966
|
-
const pillX =
|
|
1967
|
-
const pillWidth =
|
|
2056
|
+
const pillX = Animated9.useSharedValue(0);
|
|
2057
|
+
const pillWidth = Animated9.useSharedValue(0);
|
|
1968
2058
|
const initialised = React26.useRef(false);
|
|
1969
2059
|
const animatePill = (tabValue, animate) => {
|
|
1970
2060
|
const layout = tabLayouts.current[tabValue];
|
|
1971
2061
|
if (!layout) return;
|
|
1972
2062
|
if (animate) {
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
reactNative.Animated.spring(pillWidth, { toValue: layout.width, useNativeDriver: false, stiffness: 380, damping: 38, mass: 1 })
|
|
1976
|
-
]).start();
|
|
2063
|
+
pillX.value = Animated9.withSpring(layout.x, SPRINGS.glide);
|
|
2064
|
+
pillWidth.value = Animated9.withSpring(layout.width, SPRINGS.glide);
|
|
1977
2065
|
} else {
|
|
1978
|
-
pillX.
|
|
1979
|
-
pillWidth.
|
|
2066
|
+
pillX.value = layout.x;
|
|
2067
|
+
pillWidth.value = layout.width;
|
|
1980
2068
|
}
|
|
1981
2069
|
};
|
|
1982
2070
|
React26.useEffect(() => {
|
|
@@ -1987,51 +2075,63 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
|
|
|
1987
2075
|
if (!value) setInternal(v);
|
|
1988
2076
|
onValueChange?.(v);
|
|
1989
2077
|
};
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
2078
|
+
const pillAnimatedStyle = Animated9.useAnimatedStyle(() => ({
|
|
2079
|
+
transform: [{ translateX: pillX.value }],
|
|
2080
|
+
width: pillWidth.value
|
|
2081
|
+
}));
|
|
2082
|
+
return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style }, /* @__PURE__ */ React26__default.default.createElement(
|
|
2083
|
+
reactNative.View,
|
|
1994
2084
|
{
|
|
1995
2085
|
style: [
|
|
1996
|
-
styles19.
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2086
|
+
variant === "pill" ? [styles19.list, { backgroundColor: colors.surface }] : styles19.listUnderline
|
|
2087
|
+
],
|
|
2088
|
+
accessibilityRole: "tablist"
|
|
2089
|
+
},
|
|
2090
|
+
variant === "pill" && /* @__PURE__ */ React26__default.default.createElement(
|
|
2091
|
+
Animated9__default.default.View,
|
|
2092
|
+
{
|
|
2093
|
+
style: [
|
|
2094
|
+
styles19.pill,
|
|
2095
|
+
{
|
|
2096
|
+
backgroundColor: colors.background,
|
|
2097
|
+
position: "absolute",
|
|
2098
|
+
top: 4,
|
|
2099
|
+
bottom: 4,
|
|
2100
|
+
left: 0,
|
|
2101
|
+
borderRadius: 8,
|
|
2102
|
+
shadowColor: "#000",
|
|
2103
|
+
shadowOffset: { width: 0, height: 1 },
|
|
2104
|
+
shadowOpacity: 0.08,
|
|
2105
|
+
shadowRadius: 2,
|
|
2106
|
+
elevation: 2
|
|
2107
|
+
},
|
|
2108
|
+
pillAnimatedStyle
|
|
2109
|
+
]
|
|
2110
|
+
}
|
|
2111
|
+
),
|
|
2112
|
+
tabs.map((tab) => /* @__PURE__ */ React26__default.default.createElement(
|
|
2113
|
+
TabTrigger,
|
|
2114
|
+
{
|
|
2115
|
+
key: tab.value,
|
|
2116
|
+
tab,
|
|
2117
|
+
isActive: tab.value === active,
|
|
2118
|
+
onPress: () => handlePress(tab.value),
|
|
2119
|
+
variant,
|
|
2120
|
+
onLayout: (e) => {
|
|
2121
|
+
const { x, width } = e.nativeEvent.layout;
|
|
2122
|
+
tabLayouts.current[tab.value] = { x, width };
|
|
2123
|
+
if (tab.value === active) {
|
|
2124
|
+
animatePill(tab.value, false);
|
|
2125
|
+
initialised.current = true;
|
|
2126
|
+
}
|
|
2027
2127
|
}
|
|
2028
2128
|
}
|
|
2029
|
-
|
|
2030
|
-
)
|
|
2129
|
+
))
|
|
2130
|
+
), children);
|
|
2031
2131
|
}
|
|
2032
2132
|
function TabsContent({ value, activeValue, children, style }) {
|
|
2033
2133
|
if (value !== activeValue) return null;
|
|
2034
|
-
return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style }, children);
|
|
2134
|
+
return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style, accessibilityRole: "none" }, children);
|
|
2035
2135
|
}
|
|
2036
2136
|
var styles19 = reactNative.StyleSheet.create({
|
|
2037
2137
|
list: {
|
|
@@ -2080,8 +2180,6 @@ var styles19 = reactNative.StyleSheet.create({
|
|
|
2080
2180
|
fontSize: ms(14)
|
|
2081
2181
|
}
|
|
2082
2182
|
});
|
|
2083
|
-
var easingExpand = Animated12.Easing.bezier(0.23, 1, 0.32, 1);
|
|
2084
|
-
var easingCollapse = Animated12.Easing.in(Animated12.Easing.ease);
|
|
2085
2183
|
function AccordionItemComponent({
|
|
2086
2184
|
item,
|
|
2087
2185
|
isOpen,
|
|
@@ -2089,28 +2187,28 @@ function AccordionItemComponent({
|
|
|
2089
2187
|
}) {
|
|
2090
2188
|
const { colors } = useTheme();
|
|
2091
2189
|
const resolvedIcon = item.iconName ? renderIcon(item.iconName, ms(16), item.iconColor ?? colors.foregroundMuted) : item.icon;
|
|
2092
|
-
const isExpanded =
|
|
2093
|
-
const height =
|
|
2190
|
+
const isExpanded = Animated9.useSharedValue(isOpen);
|
|
2191
|
+
const height = Animated9.useSharedValue(0);
|
|
2094
2192
|
React26__default.default.useEffect(() => {
|
|
2095
2193
|
isExpanded.value = isOpen;
|
|
2096
2194
|
}, [isOpen]);
|
|
2097
|
-
const derivedHeight =
|
|
2098
|
-
() =>
|
|
2099
|
-
duration:
|
|
2100
|
-
easing: isExpanded.value ?
|
|
2195
|
+
const derivedHeight = Animated9.useDerivedValue(
|
|
2196
|
+
() => Animated9.withTiming(height.value * Number(isExpanded.value), {
|
|
2197
|
+
duration: isExpanded.value ? TIMINGS.expand.duration : TIMINGS.collapse.duration,
|
|
2198
|
+
easing: isExpanded.value ? EASINGS.expand : EASINGS.collapse
|
|
2101
2199
|
})
|
|
2102
2200
|
);
|
|
2103
|
-
const derivedRotation =
|
|
2104
|
-
() =>
|
|
2105
|
-
duration:
|
|
2106
|
-
easing: isExpanded.value ?
|
|
2201
|
+
const derivedRotation = Animated9.useDerivedValue(
|
|
2202
|
+
() => Animated9.withTiming(isExpanded.value ? 1 : 0, {
|
|
2203
|
+
duration: isExpanded.value ? TIMINGS.expand.duration : TIMINGS.collapse.duration,
|
|
2204
|
+
easing: isExpanded.value ? EASINGS.expand : EASINGS.collapse
|
|
2107
2205
|
})
|
|
2108
2206
|
);
|
|
2109
|
-
const bodyStyle =
|
|
2207
|
+
const bodyStyle = Animated9.useAnimatedStyle(() => ({
|
|
2110
2208
|
height: derivedHeight.value,
|
|
2111
2209
|
overflow: "hidden"
|
|
2112
2210
|
}));
|
|
2113
|
-
const rotationStyle =
|
|
2211
|
+
const rotationStyle = Animated9.useAnimatedStyle(() => ({
|
|
2114
2212
|
transform: [{ rotate: `${derivedRotation.value * 180}deg` }]
|
|
2115
2213
|
}));
|
|
2116
2214
|
return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles20.item, { backgroundColor: colors.card, borderColor: colors.border }] }, /* @__PURE__ */ React26__default.default.createElement(
|
|
@@ -2120,11 +2218,14 @@ function AccordionItemComponent({
|
|
|
2120
2218
|
onPress: () => {
|
|
2121
2219
|
selectionAsync();
|
|
2122
2220
|
onToggle();
|
|
2123
|
-
}
|
|
2221
|
+
},
|
|
2222
|
+
accessibilityRole: "button",
|
|
2223
|
+
accessibilityState: { expanded: isOpen },
|
|
2224
|
+
accessibilityLabel: item.trigger
|
|
2124
2225
|
},
|
|
2125
2226
|
/* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles20.triggerContent }, resolvedIcon ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles20.icon }, resolvedIcon) : null, /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles20.triggerText, { color: colors.foreground }], allowFontScaling: true }, item.trigger)),
|
|
2126
|
-
/* @__PURE__ */ React26__default.default.createElement(
|
|
2127
|
-
), /* @__PURE__ */ React26__default.default.createElement(
|
|
2227
|
+
/* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: [styles20.chevron, rotationStyle] }, /* @__PURE__ */ React26__default.default.createElement(vectorIcons.Entypo, { name: "chevron-down", size: 18, color: colors.foregroundMuted }))
|
|
2228
|
+
), /* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: bodyStyle }, /* @__PURE__ */ React26__default.default.createElement(
|
|
2128
2229
|
reactNative.View,
|
|
2129
2230
|
{
|
|
2130
2231
|
style: styles20.content,
|
|
@@ -2224,23 +2325,38 @@ function Slider({
|
|
|
2224
2325
|
}
|
|
2225
2326
|
onValueChange?.(v);
|
|
2226
2327
|
};
|
|
2227
|
-
return /* @__PURE__ */ React26__default.default.createElement(
|
|
2228
|
-
|
|
2328
|
+
return /* @__PURE__ */ React26__default.default.createElement(
|
|
2329
|
+
reactNative.View,
|
|
2229
2330
|
{
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2331
|
+
style: [styles21.wrapper, style],
|
|
2332
|
+
accessibilityRole: "adjustable",
|
|
2333
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
2334
|
+
accessibilityValue: {
|
|
2335
|
+
min: minimumValue,
|
|
2336
|
+
max: maximumValue,
|
|
2337
|
+
now: value,
|
|
2338
|
+
text: formatValue2(value)
|
|
2339
|
+
}
|
|
2340
|
+
},
|
|
2341
|
+
label || showValue ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles21.header }, label ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles21.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, showValue ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles21.valueText, { color: colors.foregroundMuted }], allowFontScaling: true }, formatValue2(value)) : null) : null,
|
|
2342
|
+
/* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: disabled ? styles21.disabled : void 0 }, /* @__PURE__ */ React26__default.default.createElement(
|
|
2343
|
+
RNSlider__default.default,
|
|
2344
|
+
{
|
|
2345
|
+
value,
|
|
2346
|
+
minimumValue,
|
|
2347
|
+
maximumValue,
|
|
2348
|
+
step: step || 0,
|
|
2349
|
+
disabled,
|
|
2350
|
+
onValueChange: handleValueChange,
|
|
2351
|
+
onSlidingComplete,
|
|
2352
|
+
minimumTrackTintColor: colors.primary,
|
|
2353
|
+
maximumTrackTintColor: colors.surface,
|
|
2354
|
+
thumbTintColor: colors.primary,
|
|
2355
|
+
style: styles21.slider,
|
|
2356
|
+
accessibilityLabel
|
|
2357
|
+
}
|
|
2358
|
+
))
|
|
2359
|
+
);
|
|
2244
2360
|
}
|
|
2245
2361
|
var styles21 = reactNative.StyleSheet.create({
|
|
2246
2362
|
wrapper: {
|
|
@@ -2316,13 +2432,16 @@ function Sheet({
|
|
|
2316
2432
|
}, [footer]);
|
|
2317
2433
|
const effectiveSubtitle = subtitle ?? description;
|
|
2318
2434
|
const showHeader = !!(title || effectiveSubtitle || showCloseButton);
|
|
2319
|
-
const headerNode = showHeader ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles22.header }, /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles22.headerRow }, title ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles22.title, { color: colors.foreground }], allowFontScaling: true }, title) : /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: { flex: 1 } }), showCloseButton ? /* @__PURE__ */ React26__default.default.createElement(
|
|
2435
|
+
const headerNode = showHeader ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles22.header, accessibilityRole: "header" }, /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles22.headerRow }, title ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles22.title, { color: colors.foreground }], allowFontScaling: true }, title) : /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: { flex: 1 } }), showCloseButton ? /* @__PURE__ */ React26__default.default.createElement(
|
|
2320
2436
|
reactNative.TouchableOpacity,
|
|
2321
2437
|
{
|
|
2322
2438
|
onPress: onClose,
|
|
2323
2439
|
style: styles22.closeButton,
|
|
2324
2440
|
activeOpacity: 0.6,
|
|
2325
|
-
touchSoundDisabled: true
|
|
2441
|
+
touchSoundDisabled: true,
|
|
2442
|
+
accessibilityRole: "button",
|
|
2443
|
+
accessibilityLabel: "Close",
|
|
2444
|
+
hitSlop: { top: 12, bottom: 12, left: 12, right: 12 }
|
|
2326
2445
|
},
|
|
2327
2446
|
/* @__PURE__ */ React26__default.default.createElement(vectorIcons.AntDesign, { name: "close", size: ms(18), color: colors.foregroundMuted })
|
|
2328
2447
|
) : null), effectiveSubtitle ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles22.subtitle, { color: colors.foregroundMuted }], allowFontScaling: true }, effectiveSubtitle) : null) : null;
|
|
@@ -2413,7 +2532,6 @@ var styles22 = reactNative.StyleSheet.create({
|
|
|
2413
2532
|
var isIOS = reactNative.Platform.OS === "ios";
|
|
2414
2533
|
var isAndroid2 = reactNative.Platform.OS === "android";
|
|
2415
2534
|
var isWeb2 = reactNative.Platform.OS === "web";
|
|
2416
|
-
var nativeDriver9 = reactNative.Platform.OS !== "web";
|
|
2417
2535
|
function Select({
|
|
2418
2536
|
options,
|
|
2419
2537
|
value,
|
|
@@ -2422,21 +2540,18 @@ function Select({
|
|
|
2422
2540
|
label,
|
|
2423
2541
|
error,
|
|
2424
2542
|
disabled,
|
|
2425
|
-
style
|
|
2543
|
+
style,
|
|
2544
|
+
accessibilityLabel
|
|
2426
2545
|
}) {
|
|
2427
2546
|
const { colors } = useTheme();
|
|
2428
|
-
const
|
|
2547
|
+
const { animatedStyle, onPressIn, onPressOut } = usePressScale({
|
|
2548
|
+
pressScale: PRESS_SCALE.button,
|
|
2549
|
+
disabled
|
|
2550
|
+
});
|
|
2429
2551
|
const [pickerVisible, setPickerVisible] = React26.useState(false);
|
|
2430
2552
|
const [pendingValue, setPendingValue] = React26.useState(value);
|
|
2431
2553
|
const pickerRef = React26.useRef(null);
|
|
2432
2554
|
const selected = options.find((o) => o.value === value);
|
|
2433
|
-
const handlePressIn = () => {
|
|
2434
|
-
if (disabled) return;
|
|
2435
|
-
reactNative.Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver9, speed: 40, bounciness: 0 }).start();
|
|
2436
|
-
};
|
|
2437
|
-
const handlePressOut = () => {
|
|
2438
|
-
reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver9, speed: 40, bounciness: 4 }).start();
|
|
2439
|
-
};
|
|
2440
2555
|
const handleOpen = () => {
|
|
2441
2556
|
if (disabled) return;
|
|
2442
2557
|
selectionAsync();
|
|
@@ -2457,7 +2572,7 @@ function Select({
|
|
|
2457
2572
|
}
|
|
2458
2573
|
setPickerVisible(false);
|
|
2459
2574
|
};
|
|
2460
|
-
return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles23.container, style] }, label ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles23.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, !isWeb2 ? /* @__PURE__ */ React26__default.default.createElement(
|
|
2575
|
+
return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles23.container, style] }, label ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles23.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, !isWeb2 ? /* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: [animatedStyle, { opacity: disabled ? 0.45 : 1 }] }, /* @__PURE__ */ React26__default.default.createElement(
|
|
2461
2576
|
reactNative.TouchableOpacity,
|
|
2462
2577
|
{
|
|
2463
2578
|
style: [
|
|
@@ -2468,10 +2583,14 @@ function Select({
|
|
|
2468
2583
|
}
|
|
2469
2584
|
],
|
|
2470
2585
|
onPress: handleOpen,
|
|
2471
|
-
onPressIn
|
|
2472
|
-
onPressOut
|
|
2586
|
+
onPressIn,
|
|
2587
|
+
onPressOut,
|
|
2473
2588
|
activeOpacity: 1,
|
|
2474
|
-
touchSoundDisabled: true
|
|
2589
|
+
touchSoundDisabled: true,
|
|
2590
|
+
accessibilityRole: "combobox",
|
|
2591
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
2592
|
+
accessibilityValue: { text: selected?.label ?? placeholder },
|
|
2593
|
+
accessibilityState: { disabled: !!disabled, expanded: pickerVisible }
|
|
2475
2594
|
},
|
|
2476
2595
|
/* @__PURE__ */ React26__default.default.createElement(
|
|
2477
2596
|
reactNative.Text,
|
|
@@ -2785,7 +2904,6 @@ var styles24 = reactNative.StyleSheet.create({
|
|
|
2785
2904
|
textAlignVertical: "top"
|
|
2786
2905
|
}
|
|
2787
2906
|
});
|
|
2788
|
-
var nativeDriver10 = reactNative.Platform.OS !== "web";
|
|
2789
2907
|
function ListItem({
|
|
2790
2908
|
leftRender,
|
|
2791
2909
|
rightRender,
|
|
@@ -2806,29 +2924,16 @@ function ListItem({
|
|
|
2806
2924
|
style,
|
|
2807
2925
|
titleStyle,
|
|
2808
2926
|
subtitleStyle,
|
|
2809
|
-
captionStyle
|
|
2927
|
+
captionStyle,
|
|
2928
|
+
accessibilityLabel
|
|
2810
2929
|
}) {
|
|
2811
2930
|
const { colors } = useTheme();
|
|
2812
|
-
const
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
stiffness: 350,
|
|
2819
|
-
damping: 28,
|
|
2820
|
-
mass: 0.9
|
|
2821
|
-
}).start();
|
|
2822
|
-
};
|
|
2823
|
-
const handlePressOut = () => {
|
|
2824
|
-
reactNative.Animated.spring(scale2, {
|
|
2825
|
-
toValue: 1,
|
|
2826
|
-
useNativeDriver: nativeDriver10,
|
|
2827
|
-
stiffness: 220,
|
|
2828
|
-
damping: 20,
|
|
2829
|
-
mass: 0.9
|
|
2830
|
-
}).start();
|
|
2831
|
-
};
|
|
2931
|
+
const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
2932
|
+
pressScale: PRESS_SCALE.row,
|
|
2933
|
+
pressInSpring: SPRINGS.surfacePressIn,
|
|
2934
|
+
pressOutSpring: SPRINGS.surfacePressOut,
|
|
2935
|
+
disabled: !onPress || disabled
|
|
2936
|
+
});
|
|
2832
2937
|
const handlePress = () => {
|
|
2833
2938
|
selectionAsync();
|
|
2834
2939
|
onPress?.();
|
|
@@ -2846,16 +2951,20 @@ function ListItem({
|
|
|
2846
2951
|
shadowRadius: 6,
|
|
2847
2952
|
elevation: 2
|
|
2848
2953
|
} : {};
|
|
2849
|
-
|
|
2954
|
+
const a11yLabel = accessibilityLabel ?? [title, subtitle, caption].filter(Boolean).join(". ");
|
|
2955
|
+
return /* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: [animatedStyle, disabled && styles25.disabled], ...hoverHandlers }, /* @__PURE__ */ React26__default.default.createElement(
|
|
2850
2956
|
reactNative.TouchableOpacity,
|
|
2851
2957
|
{
|
|
2852
2958
|
style: [styles25.container, cardStyle, style],
|
|
2853
2959
|
onPress: onPress ? handlePress : void 0,
|
|
2854
|
-
onPressIn
|
|
2855
|
-
onPressOut
|
|
2960
|
+
onPressIn,
|
|
2961
|
+
onPressOut,
|
|
2856
2962
|
disabled,
|
|
2857
2963
|
activeOpacity: 1,
|
|
2858
|
-
touchSoundDisabled: true
|
|
2964
|
+
touchSoundDisabled: true,
|
|
2965
|
+
accessibilityRole: onPress ? "button" : void 0,
|
|
2966
|
+
accessibilityLabel: onPress ? a11yLabel : void 0,
|
|
2967
|
+
accessibilityState: onPress ? { disabled: !!disabled } : void 0
|
|
2859
2968
|
},
|
|
2860
2969
|
effectiveLeft ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles25.leftContainer }, effectiveLeft) : null,
|
|
2861
2970
|
/* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles25.content }, /* @__PURE__ */ React26__default.default.createElement(
|
|
@@ -2949,9 +3058,6 @@ var styles25 = reactNative.StyleSheet.create({
|
|
|
2949
3058
|
fontFamily: "Poppins-Regular",
|
|
2950
3059
|
fontSize: ms(14)
|
|
2951
3060
|
},
|
|
2952
|
-
chevron: {
|
|
2953
|
-
marginLeft: s(4)
|
|
2954
|
-
},
|
|
2955
3061
|
separator: {
|
|
2956
3062
|
height: reactNative.StyleSheet.hairlineWidth,
|
|
2957
3063
|
marginRight: 0
|
|
@@ -2960,9 +3066,9 @@ var styles25 = reactNative.StyleSheet.create({
|
|
|
2960
3066
|
opacity: 0.45
|
|
2961
3067
|
}
|
|
2962
3068
|
});
|
|
2963
|
-
var nativeDriver11 = reactNative.Platform.OS !== "web";
|
|
2964
3069
|
function MenuItem({
|
|
2965
3070
|
label,
|
|
3071
|
+
subtitle,
|
|
2966
3072
|
iconName,
|
|
2967
3073
|
icon,
|
|
2968
3074
|
iconColor,
|
|
@@ -2973,29 +3079,16 @@ function MenuItem({
|
|
|
2973
3079
|
variant = "plain",
|
|
2974
3080
|
showSeparator = false,
|
|
2975
3081
|
style,
|
|
2976
|
-
labelStyle
|
|
3082
|
+
labelStyle,
|
|
3083
|
+
accessibilityLabel
|
|
2977
3084
|
}) {
|
|
2978
3085
|
const { colors } = useTheme();
|
|
2979
|
-
const
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
stiffness: 350,
|
|
2986
|
-
damping: 28,
|
|
2987
|
-
mass: 0.9
|
|
2988
|
-
}).start();
|
|
2989
|
-
};
|
|
2990
|
-
const handlePressOut = () => {
|
|
2991
|
-
reactNative.Animated.spring(scale2, {
|
|
2992
|
-
toValue: 1,
|
|
2993
|
-
useNativeDriver: nativeDriver11,
|
|
2994
|
-
stiffness: 220,
|
|
2995
|
-
damping: 20,
|
|
2996
|
-
mass: 0.9
|
|
2997
|
-
}).start();
|
|
2998
|
-
};
|
|
3086
|
+
const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
3087
|
+
pressScale: PRESS_SCALE.row,
|
|
3088
|
+
pressInSpring: SPRINGS.surfacePressIn,
|
|
3089
|
+
pressOutSpring: SPRINGS.surfacePressOut,
|
|
3090
|
+
disabled
|
|
3091
|
+
});
|
|
2999
3092
|
const handlePress = () => {
|
|
3000
3093
|
selectionAsync();
|
|
3001
3094
|
onPress();
|
|
@@ -3012,19 +3105,23 @@ function MenuItem({
|
|
|
3012
3105
|
shadowRadius: 6,
|
|
3013
3106
|
elevation: 2
|
|
3014
3107
|
} : {};
|
|
3015
|
-
|
|
3108
|
+
const a11yLabel = accessibilityLabel ?? (subtitle ? `${label}. ${subtitle}` : label);
|
|
3109
|
+
return /* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: [animatedStyle, disabled && styles26.disabled], ...hoverHandlers }, /* @__PURE__ */ React26__default.default.createElement(
|
|
3016
3110
|
reactNative.TouchableOpacity,
|
|
3017
3111
|
{
|
|
3018
3112
|
style: [styles26.container, cardStyle, style],
|
|
3019
3113
|
onPress: handlePress,
|
|
3020
|
-
onPressIn
|
|
3021
|
-
onPressOut
|
|
3114
|
+
onPressIn,
|
|
3115
|
+
onPressOut,
|
|
3022
3116
|
disabled,
|
|
3023
3117
|
activeOpacity: 1,
|
|
3024
|
-
touchSoundDisabled: true
|
|
3118
|
+
touchSoundDisabled: true,
|
|
3119
|
+
accessibilityRole: "button",
|
|
3120
|
+
accessibilityLabel: a11yLabel,
|
|
3121
|
+
accessibilityState: { disabled }
|
|
3025
3122
|
},
|
|
3026
3123
|
resolvedIcon ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles26.iconContainer }, resolvedIcon) : null,
|
|
3027
|
-
/* @__PURE__ */ React26__default.default.createElement(
|
|
3124
|
+
/* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles26.labelContainer }, /* @__PURE__ */ React26__default.default.createElement(
|
|
3028
3125
|
reactNative.Text,
|
|
3029
3126
|
{
|
|
3030
3127
|
style: [styles26.label, { color: colors.foreground }, labelStyle],
|
|
@@ -3032,7 +3129,15 @@ function MenuItem({
|
|
|
3032
3129
|
allowFontScaling: true
|
|
3033
3130
|
},
|
|
3034
3131
|
label
|
|
3035
|
-
),
|
|
3132
|
+
), subtitle ? /* @__PURE__ */ React26__default.default.createElement(
|
|
3133
|
+
reactNative.Text,
|
|
3134
|
+
{
|
|
3135
|
+
style: [styles26.subtitle, { color: colors.foregroundMuted }],
|
|
3136
|
+
numberOfLines: 1,
|
|
3137
|
+
allowFontScaling: true
|
|
3138
|
+
},
|
|
3139
|
+
subtitle
|
|
3140
|
+
) : null),
|
|
3036
3141
|
rightRender !== void 0 ? /* @__PURE__ */ React26__default.default.createElement(
|
|
3037
3142
|
reactNative.View,
|
|
3038
3143
|
{
|
|
@@ -3072,10 +3177,18 @@ var styles26 = reactNative.StyleSheet.create({
|
|
|
3072
3177
|
justifyContent: "center",
|
|
3073
3178
|
flexShrink: 0
|
|
3074
3179
|
},
|
|
3180
|
+
labelContainer: {
|
|
3181
|
+
flex: 1,
|
|
3182
|
+
justifyContent: "center"
|
|
3183
|
+
},
|
|
3075
3184
|
label: {
|
|
3076
3185
|
fontFamily: "Poppins-Medium",
|
|
3077
|
-
fontSize: ms(15)
|
|
3078
|
-
|
|
3186
|
+
fontSize: ms(15)
|
|
3187
|
+
},
|
|
3188
|
+
subtitle: {
|
|
3189
|
+
fontFamily: "Poppins-Regular",
|
|
3190
|
+
fontSize: ms(12),
|
|
3191
|
+
marginTop: vs(1)
|
|
3079
3192
|
},
|
|
3080
3193
|
rightContainer: {
|
|
3081
3194
|
alignItems: "flex-end",
|
|
@@ -3090,62 +3203,37 @@ var styles26 = reactNative.StyleSheet.create({
|
|
|
3090
3203
|
opacity: 0.45
|
|
3091
3204
|
}
|
|
3092
3205
|
});
|
|
3093
|
-
|
|
3094
|
-
function Chip({ label, selected = false, onPress, icon, iconName, style }) {
|
|
3206
|
+
function Chip({ label, selected = false, onPress, icon, iconName, style, accessibilityLabel }) {
|
|
3095
3207
|
const { colors } = useTheme();
|
|
3096
|
-
const
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
reactNative.Animated.spring(scale2, {
|
|
3108
|
-
toValue: 0.95,
|
|
3109
|
-
useNativeDriver: nativeDriver12,
|
|
3110
|
-
speed: 40,
|
|
3111
|
-
bounciness: 0
|
|
3112
|
-
}).start();
|
|
3113
|
-
};
|
|
3114
|
-
const handlePressOut = () => {
|
|
3115
|
-
reactNative.Animated.spring(scale2, {
|
|
3116
|
-
toValue: 1,
|
|
3117
|
-
useNativeDriver: nativeDriver12,
|
|
3118
|
-
speed: 40,
|
|
3119
|
-
bounciness: 4
|
|
3120
|
-
}).start();
|
|
3121
|
-
};
|
|
3208
|
+
const { animatedStyle: scaleStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
3209
|
+
pressScale: PRESS_SCALE.chip
|
|
3210
|
+
});
|
|
3211
|
+
const colorProgress = useColorTransition(selected);
|
|
3212
|
+
const surfaceStyle = Animated9.useAnimatedStyle(() => ({
|
|
3213
|
+
backgroundColor: Animated9.interpolateColor(colorProgress.value, [0, 1], [colors.surface, colors.primary]),
|
|
3214
|
+
borderColor: Animated9.interpolateColor(colorProgress.value, [0, 1], [colors.border, colors.primary])
|
|
3215
|
+
}));
|
|
3216
|
+
const textStyle = Animated9.useAnimatedStyle(() => ({
|
|
3217
|
+
color: Animated9.interpolateColor(colorProgress.value, [0, 1], [colors.foreground, colors.primaryForeground])
|
|
3218
|
+
}));
|
|
3122
3219
|
const handlePress = () => {
|
|
3123
3220
|
selectionAsync();
|
|
3124
3221
|
onPress?.();
|
|
3125
3222
|
};
|
|
3126
|
-
const backgroundColor = pressAnim.interpolate({
|
|
3127
|
-
inputRange: [0, 1],
|
|
3128
|
-
outputRange: [colors.surface, colors.primary]
|
|
3129
|
-
});
|
|
3130
|
-
const textColor = pressAnim.interpolate({
|
|
3131
|
-
inputRange: [0, 1],
|
|
3132
|
-
outputRange: [colors.foreground, colors.primaryForeground]
|
|
3133
|
-
});
|
|
3134
|
-
const borderColor = pressAnim.interpolate({
|
|
3135
|
-
inputRange: [0, 1],
|
|
3136
|
-
outputRange: [colors.border, colors.primary]
|
|
3137
|
-
});
|
|
3138
3223
|
const resolvedIcon = iconName ? renderIcon(iconName, ms(13), selected ? colors.primaryForeground : colors.foreground) : icon;
|
|
3139
|
-
return /* @__PURE__ */ React26__default.default.createElement(
|
|
3224
|
+
return /* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: [styles27.wrapper, scaleStyle, style], ...hoverHandlers }, /* @__PURE__ */ React26__default.default.createElement(
|
|
3140
3225
|
reactNative.TouchableOpacity,
|
|
3141
3226
|
{
|
|
3142
3227
|
onPress: handlePress,
|
|
3143
|
-
onPressIn
|
|
3144
|
-
onPressOut
|
|
3228
|
+
onPressIn,
|
|
3229
|
+
onPressOut,
|
|
3145
3230
|
activeOpacity: 1,
|
|
3146
|
-
touchSoundDisabled: true
|
|
3231
|
+
touchSoundDisabled: true,
|
|
3232
|
+
accessibilityRole: "button",
|
|
3233
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
3234
|
+
accessibilityState: { selected }
|
|
3147
3235
|
},
|
|
3148
|
-
/* @__PURE__ */ React26__default.default.createElement(
|
|
3236
|
+
/* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: [styles27.chip, surfaceStyle] }, resolvedIcon ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles27.chipIcon }, resolvedIcon) : null, /* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.Text, { style: [styles27.label, textStyle], allowFontScaling: true }, label))
|
|
3149
3237
|
));
|
|
3150
3238
|
}
|
|
3151
3239
|
function ChipGroup({ options, value, onValueChange, multiSelect = false, style }) {
|
|
@@ -3156,12 +3244,7 @@ function ChipGroup({ options, value, onValueChange, multiSelect = false, style }
|
|
|
3156
3244
|
}
|
|
3157
3245
|
const currentArray = Array.isArray(value) ? value : value ? [value] : [];
|
|
3158
3246
|
const isSelected2 = currentArray.includes(optionValue);
|
|
3159
|
-
|
|
3160
|
-
if (isSelected2) {
|
|
3161
|
-
newArray = currentArray.filter((v) => v !== optionValue);
|
|
3162
|
-
} else {
|
|
3163
|
-
newArray = [...currentArray, optionValue];
|
|
3164
|
-
}
|
|
3247
|
+
const newArray = isSelected2 ? currentArray.filter((v) => v !== optionValue) : [...currentArray, optionValue];
|
|
3165
3248
|
onValueChange?.(newArray);
|
|
3166
3249
|
};
|
|
3167
3250
|
const isSelected = (optionValue) => {
|
|
@@ -3375,22 +3458,36 @@ function MonthPicker({ value, onChange, locale = "en", formatLabel, style }) {
|
|
|
3375
3458
|
onChange({ month: value.month + 1, year: value.year });
|
|
3376
3459
|
}
|
|
3377
3460
|
};
|
|
3378
|
-
return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles30.container, style] }, /* @__PURE__ */ React26__default.default.createElement(
|
|
3461
|
+
return /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles30.container, style], accessibilityRole: "adjustable", accessibilityLabel: getLabel() }, /* @__PURE__ */ React26__default.default.createElement(
|
|
3379
3462
|
reactNative.TouchableOpacity,
|
|
3380
3463
|
{
|
|
3381
3464
|
style: styles30.arrow,
|
|
3382
3465
|
onPress: handlePrev,
|
|
3383
3466
|
activeOpacity: 0.6,
|
|
3384
|
-
touchSoundDisabled: true
|
|
3467
|
+
touchSoundDisabled: true,
|
|
3468
|
+
accessibilityRole: "button",
|
|
3469
|
+
accessibilityLabel: "Previous month",
|
|
3470
|
+
hitSlop: { top: 8, bottom: 8, left: 8, right: 8 }
|
|
3385
3471
|
},
|
|
3386
3472
|
/* @__PURE__ */ React26__default.default.createElement(vectorIcons.Entypo, { name: "chevron-left", size: 22, color: colors.foreground })
|
|
3387
|
-
), /* @__PURE__ */ React26__default.default.createElement(
|
|
3473
|
+
), /* @__PURE__ */ React26__default.default.createElement(
|
|
3474
|
+
reactNative.Text,
|
|
3475
|
+
{
|
|
3476
|
+
style: [styles30.label, { color: colors.foreground }],
|
|
3477
|
+
allowFontScaling: true,
|
|
3478
|
+
accessibilityLiveRegion: "polite"
|
|
3479
|
+
},
|
|
3480
|
+
getLabel()
|
|
3481
|
+
), /* @__PURE__ */ React26__default.default.createElement(
|
|
3388
3482
|
reactNative.TouchableOpacity,
|
|
3389
3483
|
{
|
|
3390
3484
|
style: styles30.arrow,
|
|
3391
3485
|
onPress: handleNext,
|
|
3392
3486
|
activeOpacity: 0.6,
|
|
3393
|
-
touchSoundDisabled: true
|
|
3487
|
+
touchSoundDisabled: true,
|
|
3488
|
+
accessibilityRole: "button",
|
|
3489
|
+
accessibilityLabel: "Next month",
|
|
3490
|
+
hitSlop: { top: 8, bottom: 8, left: 8, right: 8 }
|
|
3394
3491
|
},
|
|
3395
3492
|
/* @__PURE__ */ React26__default.default.createElement(vectorIcons.Entypo, { name: "chevron-right", size: 22, color: colors.foreground })
|
|
3396
3493
|
));
|
|
@@ -3415,18 +3512,6 @@ var styles30 = reactNative.StyleSheet.create({
|
|
|
3415
3512
|
minWidth: s(160)
|
|
3416
3513
|
}
|
|
3417
3514
|
});
|
|
3418
|
-
function useHover() {
|
|
3419
|
-
const [hovered, setHovered] = React26.useState(false);
|
|
3420
|
-
const onMouseEnter = React26.useCallback(() => setHovered(true), []);
|
|
3421
|
-
const onMouseLeave = React26.useCallback(() => setHovered(false), []);
|
|
3422
|
-
if (reactNative.Platform.OS !== "web") {
|
|
3423
|
-
return { hovered: false, hoverHandlers: {} };
|
|
3424
|
-
}
|
|
3425
|
-
return { hovered, hoverHandlers: { onMouseEnter, onMouseLeave } };
|
|
3426
|
-
}
|
|
3427
|
-
|
|
3428
|
-
// src/components/MediaCard/MediaCard.tsx
|
|
3429
|
-
var nativeDriver13 = reactNative.Platform.OS !== "web";
|
|
3430
3515
|
var aspectRatioMap = {
|
|
3431
3516
|
"1:1": 1,
|
|
3432
3517
|
"4:3": 3 / 4,
|
|
@@ -3448,19 +3533,17 @@ function MediaCard({
|
|
|
3448
3533
|
onPress,
|
|
3449
3534
|
style,
|
|
3450
3535
|
imageStyle,
|
|
3451
|
-
footer
|
|
3536
|
+
footer,
|
|
3537
|
+
accessibilityLabel
|
|
3452
3538
|
}) {
|
|
3453
3539
|
const { colors } = useTheme();
|
|
3454
|
-
const scale2 = React26.useRef(new reactNative.Animated.Value(1)).current;
|
|
3455
3540
|
const { hovered, hoverHandlers } = useHover();
|
|
3456
|
-
const
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver13, speed: 40, bounciness: 4 }).start();
|
|
3463
|
-
};
|
|
3541
|
+
const { animatedStyle, onPressIn, onPressOut } = usePressScale({
|
|
3542
|
+
pressScale: PRESS_SCALE.card,
|
|
3543
|
+
pressInSpring: SPRINGS.surfacePressIn,
|
|
3544
|
+
pressOutSpring: SPRINGS.surfacePressOut,
|
|
3545
|
+
disabled: !onPress
|
|
3546
|
+
});
|
|
3464
3547
|
const handlePress = () => {
|
|
3465
3548
|
if (!onPress) return;
|
|
3466
3549
|
impactLight();
|
|
@@ -3468,6 +3551,7 @@ function MediaCard({
|
|
|
3468
3551
|
};
|
|
3469
3552
|
const ratio = aspectRatioMap[aspectRatio];
|
|
3470
3553
|
const resolvedActionIcon = actionIconName ? renderIcon(actionIconName, 18, actionActive ? colors.primary : colors.background) : actionIcon ?? renderIcon("heart", 18, actionActive ? colors.primary : colors.background);
|
|
3554
|
+
const a11yLabel = accessibilityLabel ?? [title, subtitle].filter(Boolean).join(". ");
|
|
3471
3555
|
const cardContent = /* @__PURE__ */ React26__default.default.createElement(
|
|
3472
3556
|
reactNative.View,
|
|
3473
3557
|
{
|
|
@@ -3494,21 +3578,26 @@ function MediaCard({
|
|
|
3494
3578
|
onActionPress?.();
|
|
3495
3579
|
},
|
|
3496
3580
|
activeOpacity: 0.8,
|
|
3497
|
-
touchSoundDisabled: true
|
|
3581
|
+
touchSoundDisabled: true,
|
|
3582
|
+
accessibilityRole: "button",
|
|
3583
|
+
accessibilityLabel: actionIconName ?? "action",
|
|
3584
|
+
accessibilityState: { selected: actionActive }
|
|
3498
3585
|
},
|
|
3499
3586
|
resolvedActionIcon
|
|
3500
3587
|
)),
|
|
3501
3588
|
(title || subtitle || caption || footer) && /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles31.meta }, title ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles31.title, { color: colors.foreground }], numberOfLines: 2, allowFontScaling: true }, title) : null, subtitle ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles31.subtitle, { color: colors.foregroundSubtle }], numberOfLines: 1, allowFontScaling: true }, subtitle) : null, caption ? /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles31.caption, { color: colors.foregroundMuted }], numberOfLines: 1, allowFontScaling: true }, caption) : null, footer)
|
|
3502
3589
|
);
|
|
3503
3590
|
if (onPress) {
|
|
3504
|
-
return /* @__PURE__ */ React26__default.default.createElement(
|
|
3591
|
+
return /* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: animatedStyle }, /* @__PURE__ */ React26__default.default.createElement(
|
|
3505
3592
|
reactNative.TouchableOpacity,
|
|
3506
3593
|
{
|
|
3507
3594
|
onPress: handlePress,
|
|
3508
|
-
onPressIn
|
|
3509
|
-
onPressOut
|
|
3595
|
+
onPressIn,
|
|
3596
|
+
onPressOut,
|
|
3510
3597
|
activeOpacity: 1,
|
|
3511
|
-
touchSoundDisabled: true
|
|
3598
|
+
touchSoundDisabled: true,
|
|
3599
|
+
accessibilityRole: "button",
|
|
3600
|
+
accessibilityLabel: a11yLabel
|
|
3512
3601
|
},
|
|
3513
3602
|
cardContent
|
|
3514
3603
|
));
|
|
@@ -3518,12 +3607,10 @@ function MediaCard({
|
|
|
3518
3607
|
var styles31 = reactNative.StyleSheet.create({
|
|
3519
3608
|
card: {
|
|
3520
3609
|
borderRadius: RADIUS.md,
|
|
3521
|
-
// 14px — Airbnb property card spec
|
|
3522
3610
|
overflow: "hidden",
|
|
3523
3611
|
backgroundColor: "transparent"
|
|
3524
3612
|
},
|
|
3525
3613
|
cardHovered: {
|
|
3526
|
-
// Web hover: lift shadow
|
|
3527
3614
|
...SHADOWS.md
|
|
3528
3615
|
},
|
|
3529
3616
|
imageContainer: {
|
|
@@ -3574,43 +3661,38 @@ var styles31 = reactNative.StyleSheet.create({
|
|
|
3574
3661
|
lineHeight: mvs(16)
|
|
3575
3662
|
}
|
|
3576
3663
|
});
|
|
3577
|
-
var nativeDriver14 = reactNative.Platform.OS !== "web";
|
|
3578
3664
|
function CategoryChip({
|
|
3579
3665
|
item,
|
|
3580
3666
|
selected,
|
|
3581
3667
|
onPress
|
|
3582
3668
|
}) {
|
|
3583
3669
|
const { colors } = useTheme();
|
|
3584
|
-
const
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
const
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
const
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3670
|
+
const { animatedStyle: scaleStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
3671
|
+
pressScale: PRESS_SCALE.chip
|
|
3672
|
+
});
|
|
3673
|
+
const progress = useColorTransition(selected);
|
|
3674
|
+
const surfaceStyle = Animated9.useAnimatedStyle(() => ({
|
|
3675
|
+
backgroundColor: Animated9.interpolateColor(progress.value, [0, 1], [colors.surface, colors.primary]),
|
|
3676
|
+
borderColor: Animated9.interpolateColor(progress.value, [0, 1], [colors.border, colors.primary])
|
|
3677
|
+
}));
|
|
3678
|
+
const textColorStyle = Animated9.useAnimatedStyle(() => ({
|
|
3679
|
+
color: Animated9.interpolateColor(progress.value, [0, 1], [colors.foregroundSubtle, colors.primaryForeground])
|
|
3680
|
+
}));
|
|
3681
|
+
const iconColor = selected ? colors.primaryForeground : colors.foregroundSubtle;
|
|
3682
|
+
const resolvedIcon = typeof item.icon === "string" ? renderIcon(item.icon, 16, iconColor) : item.icon ?? null;
|
|
3683
|
+
return /* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: scaleStyle, ...hoverHandlers }, /* @__PURE__ */ React26__default.default.createElement(
|
|
3596
3684
|
reactNative.TouchableOpacity,
|
|
3597
3685
|
{
|
|
3598
|
-
style: [
|
|
3599
|
-
styles32.chip,
|
|
3600
|
-
{
|
|
3601
|
-
backgroundColor: bgColor,
|
|
3602
|
-
borderColor
|
|
3603
|
-
}
|
|
3604
|
-
],
|
|
3605
3686
|
onPress,
|
|
3606
|
-
onPressIn
|
|
3607
|
-
onPressOut
|
|
3687
|
+
onPressIn,
|
|
3688
|
+
onPressOut,
|
|
3608
3689
|
activeOpacity: 1,
|
|
3609
|
-
touchSoundDisabled: true
|
|
3690
|
+
touchSoundDisabled: true,
|
|
3691
|
+
accessibilityRole: "button",
|
|
3692
|
+
accessibilityLabel: item.label,
|
|
3693
|
+
accessibilityState: { selected }
|
|
3610
3694
|
},
|
|
3611
|
-
resolvedIcon && /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles32.chipIcon }, resolvedIcon),
|
|
3612
|
-
/* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles32.chipLabel, { color: textColor }], allowFontScaling: true }, item.label),
|
|
3613
|
-
item.badge !== void 0 && item.badge > 0 && /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles32.chipBadge, { backgroundColor: colors.primary }] }, /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles32.chipBadgeText, { color: colors.primaryForeground }] }, Math.min(item.badge, 99)))
|
|
3695
|
+
/* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: [styles32.chip, surfaceStyle] }, resolvedIcon && /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles32.chipIcon }, resolvedIcon), /* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.Text, { style: [styles32.chipLabel, textColorStyle], allowFontScaling: true }, item.label), item.badge !== void 0 && item.badge > 0 && /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: [styles32.chipBadge, { backgroundColor: colors.primary }] }, /* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles32.chipBadgeText, { color: colors.primaryForeground }] }, Math.min(item.badge, 99))))
|
|
3614
3696
|
));
|
|
3615
3697
|
}
|
|
3616
3698
|
function CategoryStrip({
|
|
@@ -3619,7 +3701,8 @@ function CategoryStrip({
|
|
|
3619
3701
|
onValueChange,
|
|
3620
3702
|
multiSelect = false,
|
|
3621
3703
|
style,
|
|
3622
|
-
itemStyle
|
|
3704
|
+
itemStyle,
|
|
3705
|
+
accessibilityLabel
|
|
3623
3706
|
}) {
|
|
3624
3707
|
const selected = Array.isArray(value) ? value : value ? [value] : [];
|
|
3625
3708
|
const handlePress = (v) => {
|
|
@@ -3638,7 +3721,9 @@ function CategoryStrip({
|
|
|
3638
3721
|
horizontal: true,
|
|
3639
3722
|
showsHorizontalScrollIndicator: false,
|
|
3640
3723
|
contentContainerStyle: [styles32.container, style],
|
|
3641
|
-
style: styles32.scroll
|
|
3724
|
+
style: styles32.scroll,
|
|
3725
|
+
accessibilityRole: multiSelect ? void 0 : "radiogroup",
|
|
3726
|
+
accessibilityLabel
|
|
3642
3727
|
},
|
|
3643
3728
|
categories.map((cat) => /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { key: cat.value, style: itemStyle }, /* @__PURE__ */ React26__default.default.createElement(
|
|
3644
3729
|
CategoryChip,
|
|
@@ -3691,62 +3776,45 @@ var styles32 = reactNative.StyleSheet.create({
|
|
|
3691
3776
|
lineHeight: 14
|
|
3692
3777
|
}
|
|
3693
3778
|
});
|
|
3694
|
-
var nativeDriver15 = reactNative.Platform.OS !== "web";
|
|
3695
3779
|
function Pressable2({
|
|
3696
3780
|
children,
|
|
3697
3781
|
onPress,
|
|
3698
|
-
pressScale =
|
|
3699
|
-
bounciness = 4,
|
|
3782
|
+
pressScale = PRESS_SCALE.card,
|
|
3700
3783
|
haptics = true,
|
|
3701
3784
|
style,
|
|
3702
3785
|
disabled,
|
|
3703
3786
|
hoverScale = 1.02,
|
|
3704
3787
|
...touchableProps
|
|
3705
3788
|
}) {
|
|
3706
|
-
const
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
speed: 40,
|
|
3714
|
-
bounciness: 0
|
|
3715
|
-
}).start();
|
|
3716
|
-
};
|
|
3717
|
-
const handlePressOut = () => {
|
|
3718
|
-
if (disabled) return;
|
|
3719
|
-
reactNative.Animated.spring(scale2, {
|
|
3720
|
-
toValue: 1,
|
|
3721
|
-
useNativeDriver: nativeDriver15,
|
|
3722
|
-
speed: 40,
|
|
3723
|
-
bounciness
|
|
3724
|
-
}).start();
|
|
3725
|
-
};
|
|
3789
|
+
const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
3790
|
+
pressScale,
|
|
3791
|
+
hoverScale,
|
|
3792
|
+
pressInSpring: SPRINGS.surfacePressIn,
|
|
3793
|
+
pressOutSpring: SPRINGS.surfacePressOut,
|
|
3794
|
+
disabled
|
|
3795
|
+
});
|
|
3726
3796
|
const handlePress = () => {
|
|
3727
3797
|
if (disabled || !onPress) return;
|
|
3728
3798
|
if (haptics) impactLight();
|
|
3729
3799
|
onPress();
|
|
3730
3800
|
};
|
|
3731
|
-
const hoverScaleValue = hovered && hoverScale !== 1 ? hoverScale : 1;
|
|
3732
3801
|
return /* @__PURE__ */ React26__default.default.createElement(
|
|
3733
|
-
|
|
3802
|
+
Animated9__default.default.View,
|
|
3734
3803
|
{
|
|
3735
|
-
style: [
|
|
3736
|
-
{ transform: [{ scale: reactNative.Animated.multiply(scale2, hoverScaleValue) }] },
|
|
3737
|
-
style
|
|
3738
|
-
],
|
|
3804
|
+
style: [animatedStyle, style],
|
|
3739
3805
|
...reactNative.Platform.OS === "web" ? hoverHandlers : {}
|
|
3740
3806
|
},
|
|
3741
3807
|
/* @__PURE__ */ React26__default.default.createElement(
|
|
3742
3808
|
reactNative.TouchableOpacity,
|
|
3743
3809
|
{
|
|
3744
3810
|
onPress: handlePress,
|
|
3745
|
-
onPressIn
|
|
3746
|
-
onPressOut
|
|
3811
|
+
onPressIn,
|
|
3812
|
+
onPressOut,
|
|
3747
3813
|
activeOpacity: 1,
|
|
3748
3814
|
disabled,
|
|
3749
3815
|
touchSoundDisabled: true,
|
|
3816
|
+
accessibilityRole: "button",
|
|
3817
|
+
accessibilityState: { disabled: !!disabled },
|
|
3750
3818
|
...touchableProps
|
|
3751
3819
|
},
|
|
3752
3820
|
children
|
|
@@ -3792,14 +3860,14 @@ function DetailRow({
|
|
|
3792
3860
|
allowFontScaling: true
|
|
3793
3861
|
},
|
|
3794
3862
|
label
|
|
3795
|
-
) : label), separatorStyle ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: separatorStyle }) : /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles33.spacer }), /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles33.valueSide }, /* @__PURE__ */ React26__default.default.createElement(
|
|
3863
|
+
) : label), separatorStyle ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: separatorStyle }) : /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles33.spacer }), /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles33.valueSide }, typeof value === "string" ? /* @__PURE__ */ React26__default.default.createElement(
|
|
3796
3864
|
reactNative.Text,
|
|
3797
3865
|
{
|
|
3798
3866
|
style: [styles33.valueText, { color: valueColor ?? colors.foreground }, valueStyle],
|
|
3799
3867
|
allowFontScaling: true
|
|
3800
3868
|
},
|
|
3801
3869
|
value
|
|
3802
|
-
), resolvedRightIcon ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles33.icon }, resolvedRightIcon) : null));
|
|
3870
|
+
) : value, resolvedRightIcon ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles33.icon }, resolvedRightIcon) : null));
|
|
3803
3871
|
}
|
|
3804
3872
|
var styles33 = reactNative.StyleSheet.create({
|
|
3805
3873
|
row: {
|