@retray-dev/ui-kit 6.1.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 +4 -4
- package/dist/index.d.mts +42 -21
- package/dist/index.d.ts +42 -21
- package/dist/index.js +679 -628
- package/dist/index.mjs +672 -621
- 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/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 +22 -31
- 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]
|
|
1623
|
+
const { animatedStyle: scaleStyle, onPressIn, onPressOut } = usePressScale({
|
|
1624
|
+
pressScale: PRESS_SCALE.button,
|
|
1625
|
+
disabled
|
|
1521
1626
|
});
|
|
1522
|
-
const
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
};
|
|
1530
|
-
const handlePressOut = () => {
|
|
1531
|
-
reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver4, speed: 40, bounciness: 0 }).start();
|
|
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,7 +3066,6 @@ 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,
|
|
2966
3071
|
subtitle,
|
|
@@ -2974,29 +3079,16 @@ function MenuItem({
|
|
|
2974
3079
|
variant = "plain",
|
|
2975
3080
|
showSeparator = false,
|
|
2976
3081
|
style,
|
|
2977
|
-
labelStyle
|
|
3082
|
+
labelStyle,
|
|
3083
|
+
accessibilityLabel
|
|
2978
3084
|
}) {
|
|
2979
3085
|
const { colors } = useTheme();
|
|
2980
|
-
const
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
stiffness: 350,
|
|
2987
|
-
damping: 28,
|
|
2988
|
-
mass: 0.9
|
|
2989
|
-
}).start();
|
|
2990
|
-
};
|
|
2991
|
-
const handlePressOut = () => {
|
|
2992
|
-
reactNative.Animated.spring(scale2, {
|
|
2993
|
-
toValue: 1,
|
|
2994
|
-
useNativeDriver: nativeDriver11,
|
|
2995
|
-
stiffness: 220,
|
|
2996
|
-
damping: 20,
|
|
2997
|
-
mass: 0.9
|
|
2998
|
-
}).start();
|
|
2999
|
-
};
|
|
3086
|
+
const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
3087
|
+
pressScale: PRESS_SCALE.row,
|
|
3088
|
+
pressInSpring: SPRINGS.surfacePressIn,
|
|
3089
|
+
pressOutSpring: SPRINGS.surfacePressOut,
|
|
3090
|
+
disabled
|
|
3091
|
+
});
|
|
3000
3092
|
const handlePress = () => {
|
|
3001
3093
|
selectionAsync();
|
|
3002
3094
|
onPress();
|
|
@@ -3013,16 +3105,20 @@ function MenuItem({
|
|
|
3013
3105
|
shadowRadius: 6,
|
|
3014
3106
|
elevation: 2
|
|
3015
3107
|
} : {};
|
|
3016
|
-
|
|
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(
|
|
3017
3110
|
reactNative.TouchableOpacity,
|
|
3018
3111
|
{
|
|
3019
3112
|
style: [styles26.container, cardStyle, style],
|
|
3020
3113
|
onPress: handlePress,
|
|
3021
|
-
onPressIn
|
|
3022
|
-
onPressOut
|
|
3114
|
+
onPressIn,
|
|
3115
|
+
onPressOut,
|
|
3023
3116
|
disabled,
|
|
3024
3117
|
activeOpacity: 1,
|
|
3025
|
-
touchSoundDisabled: true
|
|
3118
|
+
touchSoundDisabled: true,
|
|
3119
|
+
accessibilityRole: "button",
|
|
3120
|
+
accessibilityLabel: a11yLabel,
|
|
3121
|
+
accessibilityState: { disabled }
|
|
3026
3122
|
},
|
|
3027
3123
|
resolvedIcon ? /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles26.iconContainer }, resolvedIcon) : null,
|
|
3028
3124
|
/* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles26.labelContainer }, /* @__PURE__ */ React26__default.default.createElement(
|
|
@@ -3107,62 +3203,37 @@ var styles26 = reactNative.StyleSheet.create({
|
|
|
3107
3203
|
opacity: 0.45
|
|
3108
3204
|
}
|
|
3109
3205
|
});
|
|
3110
|
-
|
|
3111
|
-
function Chip({ label, selected = false, onPress, icon, iconName, style }) {
|
|
3206
|
+
function Chip({ label, selected = false, onPress, icon, iconName, style, accessibilityLabel }) {
|
|
3112
3207
|
const { colors } = useTheme();
|
|
3113
|
-
const
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
reactNative.Animated.spring(scale2, {
|
|
3125
|
-
toValue: 0.95,
|
|
3126
|
-
useNativeDriver: nativeDriver12,
|
|
3127
|
-
speed: 40,
|
|
3128
|
-
bounciness: 0
|
|
3129
|
-
}).start();
|
|
3130
|
-
};
|
|
3131
|
-
const handlePressOut = () => {
|
|
3132
|
-
reactNative.Animated.spring(scale2, {
|
|
3133
|
-
toValue: 1,
|
|
3134
|
-
useNativeDriver: nativeDriver12,
|
|
3135
|
-
speed: 40,
|
|
3136
|
-
bounciness: 4
|
|
3137
|
-
}).start();
|
|
3138
|
-
};
|
|
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
|
+
}));
|
|
3139
3219
|
const handlePress = () => {
|
|
3140
3220
|
selectionAsync();
|
|
3141
3221
|
onPress?.();
|
|
3142
3222
|
};
|
|
3143
|
-
const backgroundColor = pressAnim.interpolate({
|
|
3144
|
-
inputRange: [0, 1],
|
|
3145
|
-
outputRange: [colors.surface, colors.primary]
|
|
3146
|
-
});
|
|
3147
|
-
const textColor = pressAnim.interpolate({
|
|
3148
|
-
inputRange: [0, 1],
|
|
3149
|
-
outputRange: [colors.foreground, colors.primaryForeground]
|
|
3150
|
-
});
|
|
3151
|
-
const borderColor = pressAnim.interpolate({
|
|
3152
|
-
inputRange: [0, 1],
|
|
3153
|
-
outputRange: [colors.border, colors.primary]
|
|
3154
|
-
});
|
|
3155
3223
|
const resolvedIcon = iconName ? renderIcon(iconName, ms(13), selected ? colors.primaryForeground : colors.foreground) : icon;
|
|
3156
|
-
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(
|
|
3157
3225
|
reactNative.TouchableOpacity,
|
|
3158
3226
|
{
|
|
3159
3227
|
onPress: handlePress,
|
|
3160
|
-
onPressIn
|
|
3161
|
-
onPressOut
|
|
3228
|
+
onPressIn,
|
|
3229
|
+
onPressOut,
|
|
3162
3230
|
activeOpacity: 1,
|
|
3163
|
-
touchSoundDisabled: true
|
|
3231
|
+
touchSoundDisabled: true,
|
|
3232
|
+
accessibilityRole: "button",
|
|
3233
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
3234
|
+
accessibilityState: { selected }
|
|
3164
3235
|
},
|
|
3165
|
-
/* @__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))
|
|
3166
3237
|
));
|
|
3167
3238
|
}
|
|
3168
3239
|
function ChipGroup({ options, value, onValueChange, multiSelect = false, style }) {
|
|
@@ -3173,12 +3244,7 @@ function ChipGroup({ options, value, onValueChange, multiSelect = false, style }
|
|
|
3173
3244
|
}
|
|
3174
3245
|
const currentArray = Array.isArray(value) ? value : value ? [value] : [];
|
|
3175
3246
|
const isSelected2 = currentArray.includes(optionValue);
|
|
3176
|
-
|
|
3177
|
-
if (isSelected2) {
|
|
3178
|
-
newArray = currentArray.filter((v) => v !== optionValue);
|
|
3179
|
-
} else {
|
|
3180
|
-
newArray = [...currentArray, optionValue];
|
|
3181
|
-
}
|
|
3247
|
+
const newArray = isSelected2 ? currentArray.filter((v) => v !== optionValue) : [...currentArray, optionValue];
|
|
3182
3248
|
onValueChange?.(newArray);
|
|
3183
3249
|
};
|
|
3184
3250
|
const isSelected = (optionValue) => {
|
|
@@ -3392,22 +3458,36 @@ function MonthPicker({ value, onChange, locale = "en", formatLabel, style }) {
|
|
|
3392
3458
|
onChange({ month: value.month + 1, year: value.year });
|
|
3393
3459
|
}
|
|
3394
3460
|
};
|
|
3395
|
-
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(
|
|
3396
3462
|
reactNative.TouchableOpacity,
|
|
3397
3463
|
{
|
|
3398
3464
|
style: styles30.arrow,
|
|
3399
3465
|
onPress: handlePrev,
|
|
3400
3466
|
activeOpacity: 0.6,
|
|
3401
|
-
touchSoundDisabled: true
|
|
3467
|
+
touchSoundDisabled: true,
|
|
3468
|
+
accessibilityRole: "button",
|
|
3469
|
+
accessibilityLabel: "Previous month",
|
|
3470
|
+
hitSlop: { top: 8, bottom: 8, left: 8, right: 8 }
|
|
3402
3471
|
},
|
|
3403
3472
|
/* @__PURE__ */ React26__default.default.createElement(vectorIcons.Entypo, { name: "chevron-left", size: 22, color: colors.foreground })
|
|
3404
|
-
), /* @__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(
|
|
3405
3482
|
reactNative.TouchableOpacity,
|
|
3406
3483
|
{
|
|
3407
3484
|
style: styles30.arrow,
|
|
3408
3485
|
onPress: handleNext,
|
|
3409
3486
|
activeOpacity: 0.6,
|
|
3410
|
-
touchSoundDisabled: true
|
|
3487
|
+
touchSoundDisabled: true,
|
|
3488
|
+
accessibilityRole: "button",
|
|
3489
|
+
accessibilityLabel: "Next month",
|
|
3490
|
+
hitSlop: { top: 8, bottom: 8, left: 8, right: 8 }
|
|
3411
3491
|
},
|
|
3412
3492
|
/* @__PURE__ */ React26__default.default.createElement(vectorIcons.Entypo, { name: "chevron-right", size: 22, color: colors.foreground })
|
|
3413
3493
|
));
|
|
@@ -3432,18 +3512,6 @@ var styles30 = reactNative.StyleSheet.create({
|
|
|
3432
3512
|
minWidth: s(160)
|
|
3433
3513
|
}
|
|
3434
3514
|
});
|
|
3435
|
-
function useHover() {
|
|
3436
|
-
const [hovered, setHovered] = React26.useState(false);
|
|
3437
|
-
const onMouseEnter = React26.useCallback(() => setHovered(true), []);
|
|
3438
|
-
const onMouseLeave = React26.useCallback(() => setHovered(false), []);
|
|
3439
|
-
if (reactNative.Platform.OS !== "web") {
|
|
3440
|
-
return { hovered: false, hoverHandlers: {} };
|
|
3441
|
-
}
|
|
3442
|
-
return { hovered, hoverHandlers: { onMouseEnter, onMouseLeave } };
|
|
3443
|
-
}
|
|
3444
|
-
|
|
3445
|
-
// src/components/MediaCard/MediaCard.tsx
|
|
3446
|
-
var nativeDriver13 = reactNative.Platform.OS !== "web";
|
|
3447
3515
|
var aspectRatioMap = {
|
|
3448
3516
|
"1:1": 1,
|
|
3449
3517
|
"4:3": 3 / 4,
|
|
@@ -3465,19 +3533,17 @@ function MediaCard({
|
|
|
3465
3533
|
onPress,
|
|
3466
3534
|
style,
|
|
3467
3535
|
imageStyle,
|
|
3468
|
-
footer
|
|
3536
|
+
footer,
|
|
3537
|
+
accessibilityLabel
|
|
3469
3538
|
}) {
|
|
3470
3539
|
const { colors } = useTheme();
|
|
3471
|
-
const scale2 = React26.useRef(new reactNative.Animated.Value(1)).current;
|
|
3472
3540
|
const { hovered, hoverHandlers } = useHover();
|
|
3473
|
-
const
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
reactNative.Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver13, speed: 40, bounciness: 4 }).start();
|
|
3480
|
-
};
|
|
3541
|
+
const { animatedStyle, onPressIn, onPressOut } = usePressScale({
|
|
3542
|
+
pressScale: PRESS_SCALE.card,
|
|
3543
|
+
pressInSpring: SPRINGS.surfacePressIn,
|
|
3544
|
+
pressOutSpring: SPRINGS.surfacePressOut,
|
|
3545
|
+
disabled: !onPress
|
|
3546
|
+
});
|
|
3481
3547
|
const handlePress = () => {
|
|
3482
3548
|
if (!onPress) return;
|
|
3483
3549
|
impactLight();
|
|
@@ -3485,6 +3551,7 @@ function MediaCard({
|
|
|
3485
3551
|
};
|
|
3486
3552
|
const ratio = aspectRatioMap[aspectRatio];
|
|
3487
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(". ");
|
|
3488
3555
|
const cardContent = /* @__PURE__ */ React26__default.default.createElement(
|
|
3489
3556
|
reactNative.View,
|
|
3490
3557
|
{
|
|
@@ -3511,21 +3578,26 @@ function MediaCard({
|
|
|
3511
3578
|
onActionPress?.();
|
|
3512
3579
|
},
|
|
3513
3580
|
activeOpacity: 0.8,
|
|
3514
|
-
touchSoundDisabled: true
|
|
3581
|
+
touchSoundDisabled: true,
|
|
3582
|
+
accessibilityRole: "button",
|
|
3583
|
+
accessibilityLabel: actionIconName ?? "action",
|
|
3584
|
+
accessibilityState: { selected: actionActive }
|
|
3515
3585
|
},
|
|
3516
3586
|
resolvedActionIcon
|
|
3517
3587
|
)),
|
|
3518
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)
|
|
3519
3589
|
);
|
|
3520
3590
|
if (onPress) {
|
|
3521
|
-
return /* @__PURE__ */ React26__default.default.createElement(
|
|
3591
|
+
return /* @__PURE__ */ React26__default.default.createElement(Animated9__default.default.View, { style: animatedStyle }, /* @__PURE__ */ React26__default.default.createElement(
|
|
3522
3592
|
reactNative.TouchableOpacity,
|
|
3523
3593
|
{
|
|
3524
3594
|
onPress: handlePress,
|
|
3525
|
-
onPressIn
|
|
3526
|
-
onPressOut
|
|
3595
|
+
onPressIn,
|
|
3596
|
+
onPressOut,
|
|
3527
3597
|
activeOpacity: 1,
|
|
3528
|
-
touchSoundDisabled: true
|
|
3598
|
+
touchSoundDisabled: true,
|
|
3599
|
+
accessibilityRole: "button",
|
|
3600
|
+
accessibilityLabel: a11yLabel
|
|
3529
3601
|
},
|
|
3530
3602
|
cardContent
|
|
3531
3603
|
));
|
|
@@ -3535,12 +3607,10 @@ function MediaCard({
|
|
|
3535
3607
|
var styles31 = reactNative.StyleSheet.create({
|
|
3536
3608
|
card: {
|
|
3537
3609
|
borderRadius: RADIUS.md,
|
|
3538
|
-
// 14px — Airbnb property card spec
|
|
3539
3610
|
overflow: "hidden",
|
|
3540
3611
|
backgroundColor: "transparent"
|
|
3541
3612
|
},
|
|
3542
3613
|
cardHovered: {
|
|
3543
|
-
// Web hover: lift shadow
|
|
3544
3614
|
...SHADOWS.md
|
|
3545
3615
|
},
|
|
3546
3616
|
imageContainer: {
|
|
@@ -3591,43 +3661,38 @@ var styles31 = reactNative.StyleSheet.create({
|
|
|
3591
3661
|
lineHeight: mvs(16)
|
|
3592
3662
|
}
|
|
3593
3663
|
});
|
|
3594
|
-
var nativeDriver14 = reactNative.Platform.OS !== "web";
|
|
3595
3664
|
function CategoryChip({
|
|
3596
3665
|
item,
|
|
3597
3666
|
selected,
|
|
3598
3667
|
onPress
|
|
3599
3668
|
}) {
|
|
3600
3669
|
const { colors } = useTheme();
|
|
3601
|
-
const
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
const
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
const
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
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(
|
|
3613
3684
|
reactNative.TouchableOpacity,
|
|
3614
3685
|
{
|
|
3615
|
-
style: [
|
|
3616
|
-
styles32.chip,
|
|
3617
|
-
{
|
|
3618
|
-
backgroundColor: bgColor,
|
|
3619
|
-
borderColor
|
|
3620
|
-
}
|
|
3621
|
-
],
|
|
3622
3686
|
onPress,
|
|
3623
|
-
onPressIn
|
|
3624
|
-
onPressOut
|
|
3687
|
+
onPressIn,
|
|
3688
|
+
onPressOut,
|
|
3625
3689
|
activeOpacity: 1,
|
|
3626
|
-
touchSoundDisabled: true
|
|
3690
|
+
touchSoundDisabled: true,
|
|
3691
|
+
accessibilityRole: "button",
|
|
3692
|
+
accessibilityLabel: item.label,
|
|
3693
|
+
accessibilityState: { selected }
|
|
3627
3694
|
},
|
|
3628
|
-
resolvedIcon && /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { style: styles32.chipIcon }, resolvedIcon),
|
|
3629
|
-
/* @__PURE__ */ React26__default.default.createElement(reactNative.Text, { style: [styles32.chipLabel, { color: textColor }], allowFontScaling: true }, item.label),
|
|
3630
|
-
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))))
|
|
3631
3696
|
));
|
|
3632
3697
|
}
|
|
3633
3698
|
function CategoryStrip({
|
|
@@ -3636,7 +3701,8 @@ function CategoryStrip({
|
|
|
3636
3701
|
onValueChange,
|
|
3637
3702
|
multiSelect = false,
|
|
3638
3703
|
style,
|
|
3639
|
-
itemStyle
|
|
3704
|
+
itemStyle,
|
|
3705
|
+
accessibilityLabel
|
|
3640
3706
|
}) {
|
|
3641
3707
|
const selected = Array.isArray(value) ? value : value ? [value] : [];
|
|
3642
3708
|
const handlePress = (v) => {
|
|
@@ -3655,7 +3721,9 @@ function CategoryStrip({
|
|
|
3655
3721
|
horizontal: true,
|
|
3656
3722
|
showsHorizontalScrollIndicator: false,
|
|
3657
3723
|
contentContainerStyle: [styles32.container, style],
|
|
3658
|
-
style: styles32.scroll
|
|
3724
|
+
style: styles32.scroll,
|
|
3725
|
+
accessibilityRole: multiSelect ? void 0 : "radiogroup",
|
|
3726
|
+
accessibilityLabel
|
|
3659
3727
|
},
|
|
3660
3728
|
categories.map((cat) => /* @__PURE__ */ React26__default.default.createElement(reactNative.View, { key: cat.value, style: itemStyle }, /* @__PURE__ */ React26__default.default.createElement(
|
|
3661
3729
|
CategoryChip,
|
|
@@ -3708,62 +3776,45 @@ var styles32 = reactNative.StyleSheet.create({
|
|
|
3708
3776
|
lineHeight: 14
|
|
3709
3777
|
}
|
|
3710
3778
|
});
|
|
3711
|
-
var nativeDriver15 = reactNative.Platform.OS !== "web";
|
|
3712
3779
|
function Pressable2({
|
|
3713
3780
|
children,
|
|
3714
3781
|
onPress,
|
|
3715
|
-
pressScale =
|
|
3716
|
-
bounciness = 4,
|
|
3782
|
+
pressScale = PRESS_SCALE.card,
|
|
3717
3783
|
haptics = true,
|
|
3718
3784
|
style,
|
|
3719
3785
|
disabled,
|
|
3720
3786
|
hoverScale = 1.02,
|
|
3721
3787
|
...touchableProps
|
|
3722
3788
|
}) {
|
|
3723
|
-
const
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
speed: 40,
|
|
3731
|
-
bounciness: 0
|
|
3732
|
-
}).start();
|
|
3733
|
-
};
|
|
3734
|
-
const handlePressOut = () => {
|
|
3735
|
-
if (disabled) return;
|
|
3736
|
-
reactNative.Animated.spring(scale2, {
|
|
3737
|
-
toValue: 1,
|
|
3738
|
-
useNativeDriver: nativeDriver15,
|
|
3739
|
-
speed: 40,
|
|
3740
|
-
bounciness
|
|
3741
|
-
}).start();
|
|
3742
|
-
};
|
|
3789
|
+
const { animatedStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
3790
|
+
pressScale,
|
|
3791
|
+
hoverScale,
|
|
3792
|
+
pressInSpring: SPRINGS.surfacePressIn,
|
|
3793
|
+
pressOutSpring: SPRINGS.surfacePressOut,
|
|
3794
|
+
disabled
|
|
3795
|
+
});
|
|
3743
3796
|
const handlePress = () => {
|
|
3744
3797
|
if (disabled || !onPress) return;
|
|
3745
3798
|
if (haptics) impactLight();
|
|
3746
3799
|
onPress();
|
|
3747
3800
|
};
|
|
3748
|
-
const hoverScaleValue = hovered && hoverScale !== 1 ? hoverScale : 1;
|
|
3749
3801
|
return /* @__PURE__ */ React26__default.default.createElement(
|
|
3750
|
-
|
|
3802
|
+
Animated9__default.default.View,
|
|
3751
3803
|
{
|
|
3752
|
-
style: [
|
|
3753
|
-
{ transform: [{ scale: reactNative.Animated.multiply(scale2, hoverScaleValue) }] },
|
|
3754
|
-
style
|
|
3755
|
-
],
|
|
3804
|
+
style: [animatedStyle, style],
|
|
3756
3805
|
...reactNative.Platform.OS === "web" ? hoverHandlers : {}
|
|
3757
3806
|
},
|
|
3758
3807
|
/* @__PURE__ */ React26__default.default.createElement(
|
|
3759
3808
|
reactNative.TouchableOpacity,
|
|
3760
3809
|
{
|
|
3761
3810
|
onPress: handlePress,
|
|
3762
|
-
onPressIn
|
|
3763
|
-
onPressOut
|
|
3811
|
+
onPressIn,
|
|
3812
|
+
onPressOut,
|
|
3764
3813
|
activeOpacity: 1,
|
|
3765
3814
|
disabled,
|
|
3766
3815
|
touchSoundDisabled: true,
|
|
3816
|
+
accessibilityRole: "button",
|
|
3817
|
+
accessibilityState: { disabled: !!disabled },
|
|
3767
3818
|
...touchableProps
|
|
3768
3819
|
},
|
|
3769
3820
|
children
|