@xhsreds/reds-rn-next 0.10.1-beta202511051512 → 0.10.1-beta202511062045

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.
Files changed (52) hide show
  1. package/coverage/.tmp/coverage-10.json +1 -1
  2. package/coverage/.tmp/coverage-11.json +1 -1
  3. package/coverage/.tmp/coverage-12.json +1 -1
  4. package/coverage/.tmp/coverage-13.json +1 -1
  5. package/coverage/.tmp/coverage-14.json +1 -1
  6. package/coverage/.tmp/coverage-15.json +1 -1
  7. package/coverage/.tmp/coverage-16.json +1 -1
  8. package/coverage/.tmp/coverage-17.json +1 -1
  9. package/coverage/.tmp/coverage-18.json +1 -1
  10. package/coverage/.tmp/coverage-19.json +1 -1
  11. package/coverage/.tmp/coverage-2.json +1 -1
  12. package/coverage/.tmp/coverage-20.json +1 -1
  13. package/coverage/.tmp/coverage-21.json +1 -1
  14. package/coverage/.tmp/coverage-22.json +1 -1
  15. package/coverage/.tmp/coverage-24.json +1 -1
  16. package/coverage/.tmp/coverage-25.json +1 -1
  17. package/coverage/.tmp/coverage-26.json +1 -1
  18. package/coverage/.tmp/coverage-27.json +1 -1
  19. package/coverage/.tmp/coverage-3.json +1 -1
  20. package/coverage/.tmp/coverage-30.json +1 -1
  21. package/coverage/.tmp/coverage-31.json +1 -1
  22. package/coverage/.tmp/coverage-33.json +1 -1
  23. package/coverage/.tmp/coverage-34.json +1 -1
  24. package/coverage/.tmp/coverage-35.json +1 -1
  25. package/coverage/.tmp/coverage-36.json +1 -1
  26. package/coverage/.tmp/coverage-37.json +1 -1
  27. package/coverage/.tmp/coverage-38.json +1 -1
  28. package/coverage/.tmp/coverage-39.json +1 -1
  29. package/coverage/.tmp/coverage-4.json +1 -1
  30. package/coverage/.tmp/coverage-40.json +1 -1
  31. package/coverage/.tmp/coverage-41.json +1 -1
  32. package/coverage/.tmp/coverage-42.json +1 -1
  33. package/coverage/.tmp/coverage-43.json +1 -1
  34. package/coverage/.tmp/coverage-5.json +1 -1
  35. package/coverage/.tmp/coverage-6.json +1 -1
  36. package/coverage/.tmp/coverage-7.json +1 -1
  37. package/coverage/.tmp/coverage-8.json +1 -1
  38. package/coverage/.tmp/coverage-9.json +1 -1
  39. package/lib/cjs/components/Sheets/AnimatedSheets.js +2 -2
  40. package/lib/cjs/components/Sheets/AnimatedSheets.js.map +1 -1
  41. package/lib/cjs/components/Slider/Slider.js +51 -15
  42. package/lib/cjs/components/Slider/Slider.js.map +1 -1
  43. package/lib/esm/components/Sheets/AnimatedSheets.js +2 -2
  44. package/lib/esm/components/Sheets/AnimatedSheets.js.map +1 -1
  45. package/lib/esm/components/Slider/Slider.js +53 -17
  46. package/lib/esm/components/Slider/Slider.js.map +1 -1
  47. package/lib/src/components/Slider/Slider.d.ts +1 -1
  48. package/lib/types/components/Slider/Slider.d.ts +1 -1
  49. package/package.json +2 -2
  50. package/src/components/Sheets/AnimatedSheets.tsx +116 -112
  51. package/src/components/Slider/Slider.tsx +92 -20
  52. package/src/components/Slider/demo/index.tsx +18 -0
@@ -402,123 +402,127 @@ const AnimatedSheets = forwardRef((props: RedsSheets, ref) => {
402
402
  ) : (
403
403
  <></>
404
404
  )}
405
- <Animated.View
406
- testID="Sheets"
407
- style={[
408
- styles.picker,
409
- { backgroundColor: themeColor.Bg2 },
410
- {
411
- height: sheetsHeight,
412
- transform: [{ translateY }],
413
- },
414
- { zIndex: props.zIndex },
415
- props.sheetsStyle,
416
- ]}
417
- >
418
- {props.header ? <View onLayout={handleLabelLayout}>{props.header}</View> : <></>}
419
- {/** normal */}
420
- {showLabel && !props.header ? (
421
- <View
422
- style={[
423
- props.headlerLayout === "center" ? styles.labelContainer : styles.leftLabelContainer,
424
- { backgroundColor: themeColor.Bg2 },
425
- props.headerStyle,
426
- ]}
427
- onLayout={handleLabelLayout}
428
- >
429
- {!cancel ? (
430
- props.headlerLayout === "center" ? (
431
- <Block />
405
+ {_visible ? (
406
+ <Animated.View
407
+ testID="Sheets"
408
+ style={[
409
+ styles.picker,
410
+ { backgroundColor: themeColor.Bg2 },
411
+ {
412
+ height: sheetsHeight,
413
+ transform: [{ translateY }],
414
+ },
415
+ { zIndex: props.zIndex },
416
+ props.sheetsStyle,
417
+ ]}
418
+ >
419
+ {props.header ? <View onLayout={handleLabelLayout}>{props.header}</View> : <></>}
420
+ {/** normal */}
421
+ {showLabel && !props.header ? (
422
+ <View
423
+ style={[
424
+ props.headlerLayout === "center" ? styles.labelContainer : styles.leftLabelContainer,
425
+ { backgroundColor: themeColor.Bg2 },
426
+ props.headerStyle,
427
+ ]}
428
+ onLayout={handleLabelLayout}
429
+ >
430
+ {!cancel ? (
431
+ props.headlerLayout === "center" ? (
432
+ <Block />
433
+ ) : (
434
+ <></>
435
+ )
436
+ ) : (
437
+ <TouchableOpacity onPress={handleCancel} activeOpacity={1}>
438
+ {cancelType === SheetsActionType.text ? (
439
+ <Text style={[styles.cancel, { color: themeColor.Title }]} testID="cancel">
440
+ {cancelText || cancelKey}
441
+ </Text>
442
+ ) : (
443
+ iconWrapper("cancel")
444
+ )}
445
+ </TouchableOpacity>
446
+ )}
447
+ {label ? (
448
+ <Text style={[styles.label, { color: themeColor.Title }]}>
449
+ {label}
450
+ {showMask}
451
+ </Text>
432
452
  ) : (
433
453
  <></>
434
- )
435
- ) : (
436
- <TouchableOpacity onPress={handleCancel} activeOpacity={1}>
437
- {cancelType === SheetsActionType.text ? (
438
- <Text style={[styles.cancel, { color: themeColor.Title }]} testID="cancel">
439
- {cancelText || cancelKey}
440
- </Text>
454
+ )}
455
+ {!close ? (
456
+ props.headlerLayout === "center" ? (
457
+ <Block />
441
458
  ) : (
442
- iconWrapper("cancel")
443
- )}
444
- </TouchableOpacity>
445
- )}
446
- {label ? (
447
- <Text style={[styles.label, { color: themeColor.Title }]}>
448
- {label}
449
- {showMask}
450
- </Text>
451
- ) : (
452
- <></>
453
- )}
454
- {!close ? (
455
- props.headlerLayout === "center" ? (
456
- <Block />
459
+ <></>
460
+ )
461
+ ) : (
462
+ <TouchableOpacity onPress={handleConfirm} activeOpacity={1}>
463
+ {closeType === SheetsActionType.text ? (
464
+ <View>
465
+ <Text
466
+ style={[
467
+ styles.confirm,
468
+ { color: themeColor.Primary },
469
+ { elevation: 0, shadowColor: "transparent" },
470
+ ]}
471
+ testID="close"
472
+ >
473
+ {closeText || sureKey}
474
+ </Text>
475
+ </View>
476
+ ) : (
477
+ iconWrapper("confirm")
478
+ )}
479
+ </TouchableOpacity>
480
+ )}
481
+ </View>
482
+ ) : (
483
+ <></>
484
+ )}
485
+
486
+ {/** 拖拽按钮 */}
487
+ {sheetsType === SheetsType.dragable && !props.header ? (
488
+ <Animated.View style={[styles.dragableContainer]} {...panResponder.panHandlers} testID={"draggable"}>
489
+ <View style={[styles.dragable, { backgroundColor: themeColor.Fill3 }]} />
490
+ </Animated.View>
491
+ ) : (
492
+ <></>
493
+ )}
494
+
495
+ <View onLayout={handleLayout}>{children}</View>
496
+
497
+ {/** action */}
498
+ {showAction ? (
499
+ <View style={[styles.actionContainer]} onLayout={handleActionLayout}>
500
+ {cancel ? (
501
+ <View style={styles.action}>
502
+ <Button block onClick={handleCancel}>
503
+ {cancelText || cancelKey}
504
+ </Button>
505
+ </View>
457
506
  ) : (
458
507
  <></>
459
- )
460
- ) : (
461
- <TouchableOpacity onPress={handleConfirm} activeOpacity={1}>
462
- {closeType === SheetsActionType.text ? (
463
- <View>
464
- <Text
465
- style={[
466
- styles.confirm,
467
- { color: themeColor.Primary },
468
- { elevation: 0, shadowColor: "transparent" },
469
- ]}
470
- testID="close"
471
- >
472
- {closeText || sureKey}
473
- </Text>
474
- </View>
475
- ) : (
476
- iconWrapper("confirm")
477
- )}
478
- </TouchableOpacity>
479
- )}
480
- </View>
481
- ) : (
482
- <></>
483
- )}
484
-
485
- {/** 拖拽按钮 */}
486
- {sheetsType === SheetsType.dragable && !props.header ? (
487
- <Animated.View style={[styles.dragableContainer]} {...panResponder.panHandlers} testID={"draggable"}>
488
- <View style={[styles.dragable, { backgroundColor: themeColor.Fill3 }]} />
489
- </Animated.View>
490
- ) : (
491
- <></>
492
- )}
493
-
494
- <View onLayout={handleLayout}>{children}</View>
495
-
496
- {/** action */}
497
- {showAction ? (
498
- <View style={[styles.actionContainer]} onLayout={handleActionLayout}>
499
- {cancel ? (
500
- <View style={styles.action}>
501
- <Button block onClick={handleCancel}>
502
- {cancelText || cancelKey}
503
- </Button>
504
- </View>
505
- ) : (
506
- <></>
507
- )}
508
- {close ? (
509
- <View style={styles.action}>
510
- <Button block onClick={handleConfirm} type="primary">
511
- {closeText || sureKey}
512
- </Button>
513
- </View>
514
- ) : (
515
- <></>
516
- )}
517
- </View>
518
- ) : (
519
- <></>
520
- )}
521
- </Animated.View>
508
+ )}
509
+ {close ? (
510
+ <View style={styles.action}>
511
+ <Button block onClick={handleConfirm} type="primary">
512
+ {closeText || sureKey}
513
+ </Button>
514
+ </View>
515
+ ) : (
516
+ <></>
517
+ )}
518
+ </View>
519
+ ) : (
520
+ <></>
521
+ )}
522
+ </Animated.View>
523
+ ) : (
524
+ <></>
525
+ )}
522
526
  </>
523
527
  );
524
528
  });
@@ -15,9 +15,17 @@ import { RedsSlider, SliderDefaultProps } from "./interface/index";
15
15
  import styles from "./styles";
16
16
  import useMounted from "../../pvCount/useUnmountedProcess";
17
17
 
18
- const Slider = ({ defaultValue, min = 0, max = 100, initalValue = 0, onValueChange, dotStyle = {} }: RedsSlider) => {
18
+ const Slider = ({
19
+ defaultValue,
20
+ min = 0,
21
+ max = 100,
22
+ initalValue = 0,
23
+ onValueChange,
24
+ dotStyle = {},
25
+ step = 1,
26
+ }: RedsSlider) => {
19
27
  useMounted("Slider");
20
- const [sliderWidth, setSliderWidth] = useState(Dimensions.get("window").width * 0.8);
28
+ const [sliderWidth, setSliderWidth] = useState(Dimensions.get("window").width);
21
29
  const [value, setValue] = useState(initalValue);
22
30
 
23
31
  if (max < min) {
@@ -27,31 +35,90 @@ const Slider = ({ defaultValue, min = 0, max = 100, initalValue = 0, onValueChan
27
35
  return;
28
36
  }
29
37
 
30
- const thumbPosition = (value / (max - min)) * sliderWidth;
31
- const step = 1;
38
+ // 添加一个函数来计算最接近的step值
39
+ const getSteppedValue = useCallback(
40
+ (rawValue: number) => {
41
+ const steppedValue = Math.round((rawValue - min) / step) * step + min;
42
+ return Math.max(min, Math.min(max, steppedValue));
43
+ },
44
+ [min, max, step],
45
+ );
46
+
32
47
  const animatedValue = useRef(new Animated.Value((initalValue * sliderWidth) / (max - min))).current;
48
+
49
+ const animatedThumbValue = useRef(
50
+ new Animated.Value(
51
+ (initalValue * sliderWidth) / (max - min) > 0
52
+ ? (initalValue * sliderWidth) / (max - min) - 8
53
+ : (initalValue * sliderWidth) / (max - min),
54
+ ),
55
+ ).current;
56
+
33
57
  useEffect(() => {
34
58
  const handleOrientationChange = () => {
35
- setSliderWidth(Dimensions.get("window").width * 0.8);
59
+ setSliderWidth(Dimensions.get("window").width);
36
60
  };
37
61
 
38
62
  const subscription = Dimensions.addEventListener("change", handleOrientationChange);
39
63
  return () => {
40
64
  subscription.remove();
41
- //Dimensions.removeEventListener("change", handleOrientationChange);
42
65
  };
43
66
  }, []);
44
67
 
45
68
  // 可以根据需要调整的滑块高度
46
- const hanleValueUpdate = (gestureState: PanResponderGestureState) => {
47
- const currentValue = Math.max(min, Math.min(max, (gestureState.dx / sliderWidth) * (max - min) + initalValue));
48
-
49
- setValue(currentValue);
50
- animatedValue.setValue((currentValue * sliderWidth) / (max - min));
51
- if (onValueChange) {
52
- onValueChange(currentValue);
53
- }
54
- };
69
+ const hanleValueUpdate = useCallback(
70
+ (gestureState: PanResponderGestureState) => {
71
+ // 计算原始值
72
+ const rawValue = Math.max(min, Math.min(max, (gestureState.dx / sliderWidth) * (max - min) + initalValue));
73
+ // 根据step计算实际值
74
+ const steppedValue = getSteppedValue(rawValue);
75
+
76
+ setValue(steppedValue);
77
+ animatedValue.setValue((steppedValue * sliderWidth) / (max - min));
78
+ animatedThumbValue.setValue(
79
+ (steppedValue * sliderWidth) / (max - min) > 0
80
+ ? (steppedValue * sliderWidth) / (max - min) - 8
81
+ : (steppedValue * sliderWidth) / (max - min),
82
+ );
83
+
84
+ if (onValueChange) {
85
+ onValueChange(steppedValue);
86
+ }
87
+ },
88
+ [min, max, sliderWidth, initalValue, step, getSteppedValue, onValueChange],
89
+ );
90
+
91
+ // 添加点击轨道跳转功能(可选)
92
+ const handleTrackPress = useCallback(
93
+ (event: GestureResponderEvent) => {
94
+ const { locationX } = event.nativeEvent;
95
+ const rawValue = (locationX / sliderWidth) * (max - min) + min;
96
+ const steppedValue = getSteppedValue(rawValue);
97
+
98
+ setValue(steppedValue);
99
+
100
+ // 使用动画过渡到新位置
101
+ Animated.timing(animatedValue, {
102
+ toValue: (steppedValue * sliderWidth) / (max - min),
103
+ duration: 200,
104
+ useNativeDriver: false,
105
+ }).start();
106
+
107
+ Animated.timing(animatedThumbValue, {
108
+ toValue:
109
+ (steppedValue * sliderWidth) / (max - min) > 0
110
+ ? (steppedValue * sliderWidth) / (max - min) - 8
111
+ : (steppedValue * sliderWidth) / (max - min),
112
+ duration: 200,
113
+ useNativeDriver: false,
114
+ }).start();
115
+
116
+ if (onValueChange) {
117
+ onValueChange(steppedValue);
118
+ }
119
+ },
120
+ [sliderWidth, min, max, getSteppedValue, onValueChange, animatedValue, animatedThumbValue],
121
+ );
55
122
 
56
123
  const handleLayout = (event: LayoutChangeEvent) => {
57
124
  setSliderWidth(event.nativeEvent.layout.width);
@@ -69,7 +136,7 @@ const Slider = ({ defaultValue, min = 0, max = 100, initalValue = 0, onValueChan
69
136
  hanleValueUpdate(gestureState);
70
137
  },
71
138
  }),
72
- [],
139
+ [hanleValueUpdate],
73
140
  );
74
141
 
75
142
  const styles = StyleSheet.create({
@@ -79,7 +146,7 @@ const Slider = ({ defaultValue, min = 0, max = 100, initalValue = 0, onValueChan
79
146
  justifyContent: "center",
80
147
  },
81
148
  trackContainer: {
82
- width: "80%",
149
+ width: "100%",
83
150
  height: 4,
84
151
  backgroundColor: "rgba(48, 48, 52, 0.20)",
85
152
  borderRadius: 2,
@@ -106,11 +173,16 @@ const Slider = ({ defaultValue, min = 0, max = 100, initalValue = 0, onValueChan
106
173
  });
107
174
 
108
175
  return (
109
- <View style={styles.sliderContainer} onLayout={handleLayout}>
110
- <View style={styles.trackContainer}>
176
+ <View style={styles.sliderContainer}>
177
+ <View style={styles.trackContainer} onLayout={handleLayout}>
178
+ {/* 添加可点击的轨道 */}
179
+ <TouchableWithoutFeedback onPress={handleTrackPress}>
180
+ <View style={{ position: "absolute", width: "100%", height: 4 }} />
181
+ </TouchableWithoutFeedback>
182
+
111
183
  <Animated.View style={[styles.coloredTrack, { width: animatedValue }]} />
112
184
  <Animated.View
113
- style={[styles.thumbButton, { transform: [{ translateX: animatedValue }] }, dotStyle]}
185
+ style={[styles.thumbButton, { transform: [{ translateX: animatedThumbValue }] }, dotStyle]}
114
186
  {...panResponder.panHandlers}
115
187
  hitSlop={{ top: 20, bottom: 20, left: 20, right: 20 }}
116
188
  />
@@ -8,6 +8,7 @@ const styles = StyleSheet.create({
8
8
  justifyContent: "center",
9
9
  paddingTop: 100,
10
10
  paddingBottom: 100,
11
+ paddingHorizontal: 50,
11
12
  },
12
13
  scrollView: {
13
14
  backgroundColor: "pink",
@@ -44,6 +45,23 @@ export default function App() {
44
45
  <Br />
45
46
  <Slider min={200} max={100}></Slider>
46
47
  <Br />
48
+ <Desc>step使用示例</Desc>
49
+ <Slider
50
+ min={0}
51
+ max={100}
52
+ step={10} // 每次移动10个单位
53
+ initalValue={0}
54
+ onValueChange={(value: any) => console.log("Current value:", value)}
55
+ />
56
+ <Br />
57
+ <Desc>step使用示例(或者更小的步长)</Desc>
58
+ <Slider
59
+ min={0}
60
+ max={1}
61
+ step={0.1} // 每次移动0.1个单位
62
+ initalValue={0.5}
63
+ onValueChange={(value: any) => console.log("Current value:", value)}
64
+ />
47
65
  </View>
48
66
  );
49
67
  }