@onekeyfe/react-native-segment-slider 3.0.46 → 3.0.48

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 (66) hide show
  1. package/android/src/main/java/com/margelo/nitro/segmentslider/HybridSegmentSlider.kt +49 -2
  2. package/ios/HybridSegmentSlider.swift +51 -1
  3. package/lib/nitrogen/generated/android/c++/JHybridSegmentSliderSpec.cpp +9 -0
  4. package/lib/nitrogen/generated/android/c++/JHybridSegmentSliderSpec.hpp +2 -0
  5. package/lib/nitrogen/generated/android/c++/views/JHybridSegmentSliderStateUpdater.cpp +4 -0
  6. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/segmentslider/HybridSegmentSliderSpec.kt +6 -0
  7. package/lib/nitrogen/generated/ios/c++/HybridSegmentSliderSpecSwift.hpp +6 -0
  8. package/lib/nitrogen/generated/ios/c++/views/HybridSegmentSliderComponent.mm +5 -0
  9. package/lib/nitrogen/generated/ios/swift/HybridSegmentSliderSpec.swift +1 -0
  10. package/lib/nitrogen/generated/ios/swift/HybridSegmentSliderSpec_cxx.swift +11 -0
  11. package/lib/nitrogen/generated/shared/c++/HybridSegmentSliderSpec.cpp +2 -0
  12. package/lib/nitrogen/generated/shared/c++/HybridSegmentSliderSpec.hpp +2 -0
  13. package/lib/nitrogen/generated/shared/c++/views/HybridSegmentSliderComponent.cpp +12 -0
  14. package/lib/nitrogen/generated/shared/c++/views/HybridSegmentSliderComponent.hpp +1 -0
  15. package/lib/nitrogen/generated/shared/json/SegmentSliderConfig.json +1 -0
  16. package/lib/typescript/src/SegmentSlider.nitro.d.ts +7 -0
  17. package/lib/typescript/src/SegmentSlider.nitro.d.ts.map +1 -1
  18. package/nitrogen/generated/android/c++/JHybridSegmentSliderSpec.cpp +9 -0
  19. package/nitrogen/generated/android/c++/JHybridSegmentSliderSpec.hpp +2 -0
  20. package/nitrogen/generated/android/c++/views/JHybridSegmentSliderStateUpdater.cpp +4 -0
  21. package/nitrogen/generated/android/kotlin/com/margelo/nitro/segmentslider/HybridSegmentSliderSpec.kt +6 -0
  22. package/nitrogen/generated/ios/c++/HybridSegmentSliderSpecSwift.hpp +6 -0
  23. package/nitrogen/generated/ios/c++/views/HybridSegmentSliderComponent.mm +5 -0
  24. package/nitrogen/generated/ios/swift/HybridSegmentSliderSpec.swift +1 -0
  25. package/nitrogen/generated/ios/swift/HybridSegmentSliderSpec_cxx.swift +11 -0
  26. package/nitrogen/generated/shared/c++/HybridSegmentSliderSpec.cpp +2 -0
  27. package/nitrogen/generated/shared/c++/HybridSegmentSliderSpec.hpp +2 -0
  28. package/nitrogen/generated/shared/c++/views/HybridSegmentSliderComponent.cpp +12 -0
  29. package/nitrogen/generated/shared/c++/views/HybridSegmentSliderComponent.hpp +1 -0
  30. package/nitrogen/generated/shared/json/SegmentSliderConfig.json +1 -0
  31. package/package.json +2 -2
  32. package/src/SegmentSlider.nitro.ts +7 -0
  33. package/lib/nitrogen/nitrogen/generated/android/c++/JFunc_void.hpp +0 -75
  34. package/lib/nitrogen/nitrogen/generated/android/c++/JFunc_void_double.hpp +0 -75
  35. package/lib/nitrogen/nitrogen/generated/android/c++/JHybridSegmentSliderSpec.cpp +0 -265
  36. package/lib/nitrogen/nitrogen/generated/android/c++/JHybridSegmentSliderSpec.hpp +0 -106
  37. package/lib/nitrogen/nitrogen/generated/android/c++/views/JHybridSegmentSliderStateUpdater.cpp +0 -136
  38. package/lib/nitrogen/nitrogen/generated/android/c++/views/JHybridSegmentSliderStateUpdater.hpp +0 -49
  39. package/lib/nitrogen/nitrogen/generated/android/kotlin/com/margelo/nitro/segmentslider/Func_void.kt +0 -80
  40. package/lib/nitrogen/nitrogen/generated/android/kotlin/com/margelo/nitro/segmentslider/Func_void_double.kt +0 -80
  41. package/lib/nitrogen/nitrogen/generated/android/kotlin/com/margelo/nitro/segmentslider/HybridSegmentSliderSpec.kt +0 -203
  42. package/lib/nitrogen/nitrogen/generated/android/kotlin/com/margelo/nitro/segmentslider/segmentsliderOnLoad.kt +0 -35
  43. package/lib/nitrogen/nitrogen/generated/android/kotlin/com/margelo/nitro/segmentslider/views/HybridSegmentSliderManager.kt +0 -50
  44. package/lib/nitrogen/nitrogen/generated/android/kotlin/com/margelo/nitro/segmentslider/views/HybridSegmentSliderStateUpdater.kt +0 -23
  45. package/lib/nitrogen/nitrogen/generated/android/segmentslider+autolinking.cmake +0 -83
  46. package/lib/nitrogen/nitrogen/generated/android/segmentslider+autolinking.gradle +0 -27
  47. package/lib/nitrogen/nitrogen/generated/android/segmentsliderOnLoad.cpp +0 -50
  48. package/lib/nitrogen/nitrogen/generated/android/segmentsliderOnLoad.hpp +0 -25
  49. package/lib/nitrogen/nitrogen/generated/ios/SegmentSlider+autolinking.rb +0 -60
  50. package/lib/nitrogen/nitrogen/generated/ios/SegmentSlider-Swift-Cxx-Bridge.cpp +0 -49
  51. package/lib/nitrogen/nitrogen/generated/ios/SegmentSlider-Swift-Cxx-Bridge.hpp +0 -116
  52. package/lib/nitrogen/nitrogen/generated/ios/SegmentSlider-Swift-Cxx-Umbrella.hpp +0 -44
  53. package/lib/nitrogen/nitrogen/generated/ios/SegmentSliderAutolinking.mm +0 -33
  54. package/lib/nitrogen/nitrogen/generated/ios/SegmentSliderAutolinking.swift +0 -25
  55. package/lib/nitrogen/nitrogen/generated/ios/c++/HybridSegmentSliderSpecSwift.cpp +0 -11
  56. package/lib/nitrogen/nitrogen/generated/ios/c++/HybridSegmentSliderSpecSwift.hpp +0 -208
  57. package/lib/nitrogen/nitrogen/generated/ios/c++/views/HybridSegmentSliderComponent.mm +0 -196
  58. package/lib/nitrogen/nitrogen/generated/ios/swift/Func_void.swift +0 -47
  59. package/lib/nitrogen/nitrogen/generated/ios/swift/Func_void_double.swift +0 -47
  60. package/lib/nitrogen/nitrogen/generated/ios/swift/HybridSegmentSliderSpec.swift +0 -76
  61. package/lib/nitrogen/nitrogen/generated/ios/swift/HybridSegmentSliderSpec_cxx.swift +0 -423
  62. package/lib/nitrogen/nitrogen/generated/shared/c++/HybridSegmentSliderSpec.cpp +0 -62
  63. package/lib/nitrogen/nitrogen/generated/shared/c++/HybridSegmentSliderSpec.hpp +0 -105
  64. package/lib/nitrogen/nitrogen/generated/shared/c++/views/HybridSegmentSliderComponent.cpp +0 -327
  65. package/lib/nitrogen/nitrogen/generated/shared/c++/views/HybridSegmentSliderComponent.hpp +0 -128
  66. package/lib/nitrogen/nitrogen/generated/shared/json/SegmentSliderConfig.json +0 -30
@@ -67,6 +67,16 @@ class HybridSegmentSlider(val context: ThemedReactContext) : HybridSegmentSlider
67
67
  // Segment node the thumb currently sits on (-1 = none). Drives the halo +
68
68
  // a light haptic tick fired once each time the thumb enters a new node.
69
69
  private var hoverMarkIndex = -1
70
+ // Tap-vs-drag tracking for `snapTapToSegment`. A gesture starts as a tap
71
+ // candidate; once the finger travels past `tapMoveThresholdPx` it becomes a
72
+ // drag and the release no longer snaps.
73
+ private var touchStartX = 0f
74
+ private var lastTouchX = 0f
75
+ private var hasDragged = false
76
+ private val tapMoveThresholdPx = 8f * density
77
+ // A tap only snaps when it's quick. Holding longer (without dragging) is a
78
+ // long-press and does nothing — matching the competitor's tap window.
79
+ private val tapMaxDurationMs = 300L
70
80
 
71
81
  override val view: View = object : View(context) {
72
82
  override fun onDraw(canvas: Canvas) {
@@ -78,19 +88,40 @@ class HybridSegmentSlider(val context: ThemedReactContext) : HybridSegmentSlider
78
88
  when (event.action) {
79
89
  MotionEvent.ACTION_DOWN -> {
80
90
  isDragging = true
91
+ hasDragged = false
92
+ touchStartX = event.x
93
+ lastTouchX = event.x
81
94
  onSlideStart?.invoke()
82
95
  animateThumbScale(1.15f)
83
- commitDragValue(valueFromX(event.x))
96
+ // Tap-snap mode: defer the value commit until we know this is a tap or
97
+ // a drag, so a tap never jumps to the raw touch point first.
98
+ if (!snapTapsActive) commitDragValue(valueFromX(event.x))
84
99
  parent?.requestDisallowInterceptTouchEvent(true)
85
100
  return true
86
101
  }
87
102
  MotionEvent.ACTION_MOVE -> {
88
- if (isDragging) commitDragValue(valueFromX(event.x))
103
+ if (isDragging) {
104
+ lastTouchX = event.x
105
+ if (!hasDragged && Math.abs(event.x - touchStartX) > tapMoveThresholdPx) {
106
+ hasDragged = true
107
+ }
108
+ // Still a tap candidate in snap mode → keep the thumb put.
109
+ if (!(snapTapsActive && !hasDragged)) commitDragValue(valueFromX(event.x))
110
+ }
89
111
  return true
90
112
  }
91
113
  MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
92
114
  if (isDragging) {
93
115
  isDragging = false
116
+ // A quick tap (no drag) lands directly on the nearest segment node
117
+ // in a single move — no detour through the raw touch point. A long
118
+ // press (held past tapMaxDurationMs without dragging) does nothing.
119
+ // A drag keeps its free value.
120
+ if (snapTapsActive && !hasDragged &&
121
+ (event.eventTime - event.downTime) <= tapMaxDurationMs
122
+ ) {
123
+ commitDragValue(snapValueToNearestMark(valueFromX(lastTouchX)))
124
+ }
94
125
  hoverMarkIndex = -1
95
126
  animateThumbScale(1f)
96
127
  view.invalidate()
@@ -153,6 +184,11 @@ class HybridSegmentSlider(val context: ThemedReactContext) : HybridSegmentSlider
153
184
  get() = field
154
185
  set(v) { field = v; invalidateIfAlive() }
155
186
 
187
+ // Gates tap snapping only; no visual change on its own.
188
+ override var snapTapToSegment: Boolean = false
189
+ get() = field
190
+ set(v) { field = v }
191
+
156
192
  override var epoch: Double = 0.0
157
193
  get() = field
158
194
  set(v) { field = v }
@@ -209,6 +245,9 @@ class HybridSegmentSlider(val context: ThemedReactContext) : HybridSegmentSlider
209
245
  private val rangeSafe: Double get() = (max - min).let { if (it == 0.0) 1.0 else it }
210
246
  private val markCount: Int get() = if (segments >= 1) segments.toInt() + 1 else 0
211
247
 
248
+ /** True when tap-snapping should defer the value commit: enabled with marks to snap to. */
249
+ private val snapTapsActive: Boolean get() = snapTapToSegment && markCount > 1
250
+
212
251
  private fun valueToFrac(v: Double): Float {
213
252
  val clamped = v.coerceIn(min, max)
214
253
  return ((clamped - min) / rangeSafe).toFloat()
@@ -222,6 +261,14 @@ class HybridSegmentSlider(val context: ThemedReactContext) : HybridSegmentSlider
222
261
  return min + frac * (max - min)
223
262
  }
224
263
 
264
+ /** Snaps a value to the value of the nearest segment mark. Caller guarantees `markCount > 1`. */
265
+ private fun snapValueToNearestMark(v: Double): Double {
266
+ val frac = valueToFrac(v).toDouble()
267
+ val idx = Math.round(frac * (markCount - 1)).toDouble()
268
+ val snappedFrac = idx / (markCount - 1)
269
+ return min + snappedFrac * (max - min)
270
+ }
271
+
225
272
  private fun commitDragValue(raw: Double) {
226
273
  val rounded = raw.coerceIn(min, max).let { Math.round(it).toDouble() }
227
274
  currentValue = rounded
@@ -44,6 +44,17 @@ final class HybridSegmentSlider: HybridSegmentSliderSpec {
44
44
  private var lastEmitted: Double = .nan
45
45
  private var isDragging = false
46
46
  private var hasLaidOut = false
47
+ // Tap-vs-drag tracking for `snapTapToSegment`. A gesture starts as a tap
48
+ // candidate; once the finger travels past `tapMoveThreshold` it becomes a
49
+ // drag and the release no longer snaps.
50
+ private var touchStartX: CGFloat = 0
51
+ private var lastTouchX: CGFloat = 0
52
+ private var touchStartTime: CFTimeInterval = 0
53
+ private var hasDragged = false
54
+ private let tapMoveThreshold: CGFloat = 8
55
+ // A tap only snaps when it's quick. Holding longer (without dragging) is a
56
+ // long-press and does nothing — matching the competitor's tap window.
57
+ private let tapMaxDuration: CFTimeInterval = 0.3
47
58
  // Segment node the thumb currently sits on (-1 = none). Drives the halo +
48
59
  // a light haptic tick fired once each time the thumb enters a new node.
49
60
  private var hoverMarkIndex = -1
@@ -73,6 +84,8 @@ final class HybridSegmentSlider: HybridSegmentSliderSpec {
73
84
  }
74
85
  var showBubble: Bool = true { didSet { scheduleLayout() } }
75
86
  var centerOrigin: Bool = false { didSet { scheduleLayout() } }
87
+ // Gates tap snapping only; no visual change on its own, so no didSet.
88
+ var snapTapToSegment: Bool = false
76
89
  var epoch: Double = 0 { didSet { scheduleLayout() } }
77
90
 
78
91
  var fillColor: String = "" {
@@ -360,24 +373,52 @@ final class HybridSegmentSlider: HybridSegmentSliderSpec {
360
373
  }
361
374
 
362
375
  // MARK: - Touch handling
376
+ /// True when tap-snapping should defer the value commit: enabled and there
377
+ /// are marks to snap to.
378
+ private var snapTapsActive: Bool { snapTapToSegment && markCount > 1 }
379
+
363
380
  private func handleTouchBegan(_ x: CGFloat) {
364
381
  guard !disabled else { return }
365
382
  isDragging = true
383
+ hasDragged = false
384
+ touchStartX = x
385
+ lastTouchX = x
386
+ touchStartTime = CACurrentMediaTime()
366
387
  haptic.prepare()
367
388
  onSlideStart?()
368
389
  animateThumbScale(1.15)
369
390
  setBubbleVisible(true)
370
- setValue(valueFromX(x))
391
+ // Tap-snap mode: defer any value change until we know this is a tap or a
392
+ // drag, so a tap never jumps to the raw touch point first.
393
+ if !snapTapsActive {
394
+ setValue(valueFromX(x))
395
+ }
371
396
  }
372
397
 
373
398
  private func handleTouchMoved(_ x: CGFloat) {
374
399
  guard isDragging else { return }
400
+ lastTouchX = x
401
+ if !hasDragged, abs(x - touchStartX) > tapMoveThreshold {
402
+ hasDragged = true
403
+ }
404
+ // Still a tap candidate in snap mode → keep the thumb put.
405
+ if snapTapsActive, !hasDragged { return }
375
406
  setValue(valueFromX(x))
376
407
  }
377
408
 
378
409
  private func handleTouchEnded() {
379
410
  guard isDragging else { return }
380
411
  isDragging = false
412
+ // A quick tap (no drag) lands directly on the nearest segment node in a
413
+ // single move — no detour through the raw touch point. A long press (held
414
+ // past tapMaxDuration without dragging) does nothing. A drag keeps its
415
+ // free value.
416
+ if snapTapsActive, !hasDragged {
417
+ let pressDuration = CACurrentMediaTime() - touchStartTime
418
+ if pressDuration <= tapMaxDuration {
419
+ setValue(snapValueToNearestMark(valueFromX(lastTouchX)))
420
+ }
421
+ }
381
422
  hoverMarkIndex = -1
382
423
  setHalo(visible: false, index: 0)
383
424
  animateThumbScale(1.0)
@@ -385,6 +426,15 @@ final class HybridSegmentSlider: HybridSegmentSliderSpec {
385
426
  onSlideComplete?()
386
427
  }
387
428
 
429
+ /// Snaps a value to the value of the nearest segment mark. Caller guarantees
430
+ /// `markCount > 1`.
431
+ private func snapValueToNearestMark(_ v: Double) -> Double {
432
+ let frac = Double(valueToFrac(v))
433
+ let idx = (frac * Double(markCount - 1)).rounded()
434
+ let snappedFrac = idx / Double(markCount - 1)
435
+ return min + snappedFrac * (max - min)
436
+ }
437
+
388
438
  private func setValue(_ raw: Double) {
389
439
  let clamped = Swift.max(min, Swift.min(max, raw))
390
440
  let rounded = clamped.rounded()
@@ -117,6 +117,15 @@ namespace margelo::nitro::segmentslider {
117
117
  static const auto method = javaClassStatic()->getMethod<void(jboolean /* centerOrigin */)>("setCenterOrigin");
118
118
  method(_javaPart, centerOrigin);
119
119
  }
120
+ bool JHybridSegmentSliderSpec::getSnapTapToSegment() {
121
+ static const auto method = javaClassStatic()->getMethod<jboolean()>("getSnapTapToSegment");
122
+ auto __result = method(_javaPart);
123
+ return static_cast<bool>(__result);
124
+ }
125
+ void JHybridSegmentSliderSpec::setSnapTapToSegment(bool snapTapToSegment) {
126
+ static const auto method = javaClassStatic()->getMethod<void(jboolean /* snapTapToSegment */)>("setSnapTapToSegment");
127
+ method(_javaPart, snapTapToSegment);
128
+ }
120
129
  double JHybridSegmentSliderSpec::getEpoch() {
121
130
  static const auto method = javaClassStatic()->getMethod<double()>("getEpoch");
122
131
  auto __result = method(_javaPart);
@@ -66,6 +66,8 @@ namespace margelo::nitro::segmentslider {
66
66
  void setShowBubble(bool showBubble) override;
67
67
  bool getCenterOrigin() override;
68
68
  void setCenterOrigin(bool centerOrigin) override;
69
+ bool getSnapTapToSegment() override;
70
+ void setSnapTapToSegment(bool snapTapToSegment) override;
69
71
  double getEpoch() override;
70
72
  void setEpoch(double epoch) override;
71
73
  std::string getFillColor() override;
@@ -68,6 +68,10 @@ void JHybridSegmentSliderStateUpdater::updateViewProps(jni::alias_ref<jni::JClas
68
68
  view->setCenterOrigin(props.centerOrigin.value);
69
69
  // TODO: Set isDirty = false
70
70
  }
71
+ if (props.snapTapToSegment.isDirty) {
72
+ view->setSnapTapToSegment(props.snapTapToSegment.value);
73
+ // TODO: Set isDirty = false
74
+ }
71
75
  if (props.epoch.isDirty) {
72
76
  view->setEpoch(props.epoch.value);
73
77
  // TODO: Set isDirty = false
@@ -90,6 +90,12 @@ abstract class HybridSegmentSliderSpec: HybridView() {
90
90
  @set:Keep
91
91
  abstract var centerOrigin: Boolean
92
92
 
93
+ @get:DoNotStrip
94
+ @get:Keep
95
+ @set:DoNotStrip
96
+ @set:Keep
97
+ abstract var snapTapToSegment: Boolean
98
+
93
99
  @get:DoNotStrip
94
100
  @get:Keep
95
101
  @set:DoNotStrip
@@ -106,6 +106,12 @@ namespace margelo::nitro::segmentslider {
106
106
  inline void setCenterOrigin(bool centerOrigin) noexcept override {
107
107
  _swiftPart.setCenterOrigin(std::forward<decltype(centerOrigin)>(centerOrigin));
108
108
  }
109
+ inline bool getSnapTapToSegment() noexcept override {
110
+ return _swiftPart.getSnapTapToSegment();
111
+ }
112
+ inline void setSnapTapToSegment(bool snapTapToSegment) noexcept override {
113
+ _swiftPart.setSnapTapToSegment(std::forward<decltype(snapTapToSegment)>(snapTapToSegment));
114
+ }
109
115
  inline double getEpoch() noexcept override {
110
116
  return _swiftPart.getEpoch();
111
117
  }
@@ -111,6 +111,11 @@ using namespace margelo::nitro::segmentslider::views;
111
111
  swiftPart.setCenterOrigin(newViewProps.centerOrigin.value);
112
112
  newViewProps.centerOrigin.isDirty = false;
113
113
  }
114
+ // snapTapToSegment: boolean
115
+ if (newViewProps.snapTapToSegment.isDirty) {
116
+ swiftPart.setSnapTapToSegment(newViewProps.snapTapToSegment.value);
117
+ newViewProps.snapTapToSegment.isDirty = false;
118
+ }
114
119
  // epoch: number
115
120
  if (newViewProps.epoch.isDirty) {
116
121
  swiftPart.setEpoch(newViewProps.epoch.value);
@@ -19,6 +19,7 @@ public protocol HybridSegmentSliderSpec_protocol: HybridObject, HybridView {
19
19
  var disabled: Bool { get set }
20
20
  var showBubble: Bool { get set }
21
21
  var centerOrigin: Bool { get set }
22
+ var snapTapToSegment: Bool { get set }
22
23
  var epoch: Double { get set }
23
24
  var fillColor: String { get set }
24
25
  var trackColor: String { get set }
@@ -202,6 +202,17 @@ open class HybridSegmentSliderSpec_cxx {
202
202
  }
203
203
  }
204
204
 
205
+ public final var snapTapToSegment: Bool {
206
+ @inline(__always)
207
+ get {
208
+ return self.__implementation.snapTapToSegment
209
+ }
210
+ @inline(__always)
211
+ set {
212
+ self.__implementation.snapTapToSegment = newValue
213
+ }
214
+ }
215
+
205
216
  public final var epoch: Double {
206
217
  @inline(__always)
207
218
  get {
@@ -30,6 +30,8 @@ namespace margelo::nitro::segmentslider {
30
30
  prototype.registerHybridSetter("showBubble", &HybridSegmentSliderSpec::setShowBubble);
31
31
  prototype.registerHybridGetter("centerOrigin", &HybridSegmentSliderSpec::getCenterOrigin);
32
32
  prototype.registerHybridSetter("centerOrigin", &HybridSegmentSliderSpec::setCenterOrigin);
33
+ prototype.registerHybridGetter("snapTapToSegment", &HybridSegmentSliderSpec::getSnapTapToSegment);
34
+ prototype.registerHybridSetter("snapTapToSegment", &HybridSegmentSliderSpec::setSnapTapToSegment);
33
35
  prototype.registerHybridGetter("epoch", &HybridSegmentSliderSpec::getEpoch);
34
36
  prototype.registerHybridSetter("epoch", &HybridSegmentSliderSpec::setEpoch);
35
37
  prototype.registerHybridGetter("fillColor", &HybridSegmentSliderSpec::getFillColor);
@@ -62,6 +62,8 @@ namespace margelo::nitro::segmentslider {
62
62
  virtual void setShowBubble(bool showBubble) = 0;
63
63
  virtual bool getCenterOrigin() = 0;
64
64
  virtual void setCenterOrigin(bool centerOrigin) = 0;
65
+ virtual bool getSnapTapToSegment() = 0;
66
+ virtual void setSnapTapToSegment(bool snapTapToSegment) = 0;
65
67
  virtual double getEpoch() = 0;
66
68
  virtual void setEpoch(double epoch) = 0;
67
69
  virtual std::string getFillColor() = 0;
@@ -105,6 +105,16 @@ namespace margelo::nitro::segmentslider::views {
105
105
  throw std::runtime_error(std::string("SegmentSlider.centerOrigin: ") + exc.what());
106
106
  }
107
107
  }()),
108
+ snapTapToSegment([&]() -> CachedProp<bool> {
109
+ try {
110
+ const react::RawValue* rawValue = rawProps.at("snapTapToSegment", nullptr, nullptr);
111
+ if (rawValue == nullptr) return sourceProps.snapTapToSegment;
112
+ const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
113
+ return CachedProp<bool>::fromRawValue(*runtime, value, sourceProps.snapTapToSegment);
114
+ } catch (const std::exception& exc) {
115
+ throw std::runtime_error(std::string("SegmentSlider.snapTapToSegment: ") + exc.what());
116
+ }
117
+ }()),
108
118
  epoch([&]() -> CachedProp<double> {
109
119
  try {
110
120
  const react::RawValue* rawValue = rawProps.at("epoch", nullptr, nullptr);
@@ -256,6 +266,7 @@ namespace margelo::nitro::segmentslider::views {
256
266
  disabled(other.disabled),
257
267
  showBubble(other.showBubble),
258
268
  centerOrigin(other.centerOrigin),
269
+ snapTapToSegment(other.snapTapToSegment),
259
270
  epoch(other.epoch),
260
271
  fillColor(other.fillColor),
261
272
  trackColor(other.trackColor),
@@ -281,6 +292,7 @@ namespace margelo::nitro::segmentslider::views {
281
292
  case hashString("disabled"): return true;
282
293
  case hashString("showBubble"): return true;
283
294
  case hashString("centerOrigin"): return true;
295
+ case hashString("snapTapToSegment"): return true;
284
296
  case hashString("epoch"): return true;
285
297
  case hashString("fillColor"): return true;
286
298
  case hashString("trackColor"): return true;
@@ -51,6 +51,7 @@ namespace margelo::nitro::segmentslider::views {
51
51
  CachedProp<bool> disabled;
52
52
  CachedProp<bool> showBubble;
53
53
  CachedProp<bool> centerOrigin;
54
+ CachedProp<bool> snapTapToSegment;
54
55
  CachedProp<double> epoch;
55
56
  CachedProp<std::string> fillColor;
56
57
  CachedProp<std::string> trackColor;
@@ -12,6 +12,7 @@
12
12
  "disabled": true,
13
13
  "showBubble": true,
14
14
  "centerOrigin": true,
15
+ "snapTapToSegment": true,
15
16
  "epoch": true,
16
17
  "fillColor": true,
17
18
  "trackColor": true,
@@ -35,6 +35,13 @@ export interface SegmentSliderProps extends HybridViewProps {
35
35
  showBubble: boolean;
36
36
  /** When true the fill grows from the value-0 origin instead of the left. */
37
37
  centerOrigin: boolean;
38
+ /**
39
+ * When true, a tap (a press that does not turn into a drag) snaps the value to
40
+ * the nearest segment mark on release; a drag still moves freely to any value.
41
+ * No-op when `segments` is 0 (no marks to snap to). Default false, so existing
42
+ * callers keep the free-tap behavior.
43
+ */
44
+ snapTapToSegment: boolean;
38
45
  /**
39
46
  * Monotonic token. Bump from JS on coin / leverage reset so the native view
40
47
  * snaps to the new value WITHOUT animating the thumb scale. Mirrors the
@@ -1 +1 @@
1
- {"version":3,"file":"SegmentSlider.nitro.d.ts","sourceRoot":"","sources":["../../../src/SegmentSlider.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EACjB,eAAe,EAChB,MAAM,4BAA4B,CAAC;AAEpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACzD,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,qBAAqB;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,QAAQ,EAAE,OAAO,CAAC;IAClB,6EAA6E;IAC7E,UAAU,EAAE,OAAO,CAAC;IACpB,4EAA4E;IAC5E,YAAY,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IAGd,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,gBAAgB,EAAE,MAAM,CAAC;IACzB,6DAA6D;IAC7D,eAAe,EAAE,MAAM,CAAC;IACxB,+CAA+C;IAC/C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,uDAAuD;IACvD,eAAe,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,eAAe,EAAE,MAAM,CAAC;IAExB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,yCAAyC;IACzC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,uCAAuC;IACvC,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;CAAG;AAElE,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,kBAAkB,EAAE,oBAAoB,CAAC,CAAC"}
1
+ {"version":3,"file":"SegmentSlider.nitro.d.ts","sourceRoot":"","sources":["../../../src/SegmentSlider.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EACjB,eAAe,EAChB,MAAM,4BAA4B,CAAC;AAEpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACzD,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,qBAAqB;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,QAAQ,EAAE,OAAO,CAAC;IAClB,6EAA6E;IAC7E,UAAU,EAAE,OAAO,CAAC;IACpB,4EAA4E;IAC5E,YAAY,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,gBAAgB,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IAGd,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,gBAAgB,EAAE,MAAM,CAAC;IACzB,6DAA6D;IAC7D,eAAe,EAAE,MAAM,CAAC;IACxB,+CAA+C;IAC/C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,uDAAuD;IACvD,eAAe,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,eAAe,EAAE,MAAM,CAAC;IAExB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,yCAAyC;IACzC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,uCAAuC;IACvC,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;CAAG;AAElE,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,kBAAkB,EAAE,oBAAoB,CAAC,CAAC"}
@@ -117,6 +117,15 @@ namespace margelo::nitro::segmentslider {
117
117
  static const auto method = javaClassStatic()->getMethod<void(jboolean /* centerOrigin */)>("setCenterOrigin");
118
118
  method(_javaPart, centerOrigin);
119
119
  }
120
+ bool JHybridSegmentSliderSpec::getSnapTapToSegment() {
121
+ static const auto method = javaClassStatic()->getMethod<jboolean()>("getSnapTapToSegment");
122
+ auto __result = method(_javaPart);
123
+ return static_cast<bool>(__result);
124
+ }
125
+ void JHybridSegmentSliderSpec::setSnapTapToSegment(bool snapTapToSegment) {
126
+ static const auto method = javaClassStatic()->getMethod<void(jboolean /* snapTapToSegment */)>("setSnapTapToSegment");
127
+ method(_javaPart, snapTapToSegment);
128
+ }
120
129
  double JHybridSegmentSliderSpec::getEpoch() {
121
130
  static const auto method = javaClassStatic()->getMethod<double()>("getEpoch");
122
131
  auto __result = method(_javaPart);
@@ -66,6 +66,8 @@ namespace margelo::nitro::segmentslider {
66
66
  void setShowBubble(bool showBubble) override;
67
67
  bool getCenterOrigin() override;
68
68
  void setCenterOrigin(bool centerOrigin) override;
69
+ bool getSnapTapToSegment() override;
70
+ void setSnapTapToSegment(bool snapTapToSegment) override;
69
71
  double getEpoch() override;
70
72
  void setEpoch(double epoch) override;
71
73
  std::string getFillColor() override;
@@ -68,6 +68,10 @@ void JHybridSegmentSliderStateUpdater::updateViewProps(jni::alias_ref<jni::JClas
68
68
  view->setCenterOrigin(props.centerOrigin.value);
69
69
  // TODO: Set isDirty = false
70
70
  }
71
+ if (props.snapTapToSegment.isDirty) {
72
+ view->setSnapTapToSegment(props.snapTapToSegment.value);
73
+ // TODO: Set isDirty = false
74
+ }
71
75
  if (props.epoch.isDirty) {
72
76
  view->setEpoch(props.epoch.value);
73
77
  // TODO: Set isDirty = false
@@ -90,6 +90,12 @@ abstract class HybridSegmentSliderSpec: HybridView() {
90
90
  @set:Keep
91
91
  abstract var centerOrigin: Boolean
92
92
 
93
+ @get:DoNotStrip
94
+ @get:Keep
95
+ @set:DoNotStrip
96
+ @set:Keep
97
+ abstract var snapTapToSegment: Boolean
98
+
93
99
  @get:DoNotStrip
94
100
  @get:Keep
95
101
  @set:DoNotStrip
@@ -106,6 +106,12 @@ namespace margelo::nitro::segmentslider {
106
106
  inline void setCenterOrigin(bool centerOrigin) noexcept override {
107
107
  _swiftPart.setCenterOrigin(std::forward<decltype(centerOrigin)>(centerOrigin));
108
108
  }
109
+ inline bool getSnapTapToSegment() noexcept override {
110
+ return _swiftPart.getSnapTapToSegment();
111
+ }
112
+ inline void setSnapTapToSegment(bool snapTapToSegment) noexcept override {
113
+ _swiftPart.setSnapTapToSegment(std::forward<decltype(snapTapToSegment)>(snapTapToSegment));
114
+ }
109
115
  inline double getEpoch() noexcept override {
110
116
  return _swiftPart.getEpoch();
111
117
  }
@@ -111,6 +111,11 @@ using namespace margelo::nitro::segmentslider::views;
111
111
  swiftPart.setCenterOrigin(newViewProps.centerOrigin.value);
112
112
  newViewProps.centerOrigin.isDirty = false;
113
113
  }
114
+ // snapTapToSegment: boolean
115
+ if (newViewProps.snapTapToSegment.isDirty) {
116
+ swiftPart.setSnapTapToSegment(newViewProps.snapTapToSegment.value);
117
+ newViewProps.snapTapToSegment.isDirty = false;
118
+ }
114
119
  // epoch: number
115
120
  if (newViewProps.epoch.isDirty) {
116
121
  swiftPart.setEpoch(newViewProps.epoch.value);
@@ -19,6 +19,7 @@ public protocol HybridSegmentSliderSpec_protocol: HybridObject, HybridView {
19
19
  var disabled: Bool { get set }
20
20
  var showBubble: Bool { get set }
21
21
  var centerOrigin: Bool { get set }
22
+ var snapTapToSegment: Bool { get set }
22
23
  var epoch: Double { get set }
23
24
  var fillColor: String { get set }
24
25
  var trackColor: String { get set }
@@ -202,6 +202,17 @@ open class HybridSegmentSliderSpec_cxx {
202
202
  }
203
203
  }
204
204
 
205
+ public final var snapTapToSegment: Bool {
206
+ @inline(__always)
207
+ get {
208
+ return self.__implementation.snapTapToSegment
209
+ }
210
+ @inline(__always)
211
+ set {
212
+ self.__implementation.snapTapToSegment = newValue
213
+ }
214
+ }
215
+
205
216
  public final var epoch: Double {
206
217
  @inline(__always)
207
218
  get {
@@ -30,6 +30,8 @@ namespace margelo::nitro::segmentslider {
30
30
  prototype.registerHybridSetter("showBubble", &HybridSegmentSliderSpec::setShowBubble);
31
31
  prototype.registerHybridGetter("centerOrigin", &HybridSegmentSliderSpec::getCenterOrigin);
32
32
  prototype.registerHybridSetter("centerOrigin", &HybridSegmentSliderSpec::setCenterOrigin);
33
+ prototype.registerHybridGetter("snapTapToSegment", &HybridSegmentSliderSpec::getSnapTapToSegment);
34
+ prototype.registerHybridSetter("snapTapToSegment", &HybridSegmentSliderSpec::setSnapTapToSegment);
33
35
  prototype.registerHybridGetter("epoch", &HybridSegmentSliderSpec::getEpoch);
34
36
  prototype.registerHybridSetter("epoch", &HybridSegmentSliderSpec::setEpoch);
35
37
  prototype.registerHybridGetter("fillColor", &HybridSegmentSliderSpec::getFillColor);
@@ -62,6 +62,8 @@ namespace margelo::nitro::segmentslider {
62
62
  virtual void setShowBubble(bool showBubble) = 0;
63
63
  virtual bool getCenterOrigin() = 0;
64
64
  virtual void setCenterOrigin(bool centerOrigin) = 0;
65
+ virtual bool getSnapTapToSegment() = 0;
66
+ virtual void setSnapTapToSegment(bool snapTapToSegment) = 0;
65
67
  virtual double getEpoch() = 0;
66
68
  virtual void setEpoch(double epoch) = 0;
67
69
  virtual std::string getFillColor() = 0;
@@ -105,6 +105,16 @@ namespace margelo::nitro::segmentslider::views {
105
105
  throw std::runtime_error(std::string("SegmentSlider.centerOrigin: ") + exc.what());
106
106
  }
107
107
  }()),
108
+ snapTapToSegment([&]() -> CachedProp<bool> {
109
+ try {
110
+ const react::RawValue* rawValue = rawProps.at("snapTapToSegment", nullptr, nullptr);
111
+ if (rawValue == nullptr) return sourceProps.snapTapToSegment;
112
+ const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
113
+ return CachedProp<bool>::fromRawValue(*runtime, value, sourceProps.snapTapToSegment);
114
+ } catch (const std::exception& exc) {
115
+ throw std::runtime_error(std::string("SegmentSlider.snapTapToSegment: ") + exc.what());
116
+ }
117
+ }()),
108
118
  epoch([&]() -> CachedProp<double> {
109
119
  try {
110
120
  const react::RawValue* rawValue = rawProps.at("epoch", nullptr, nullptr);
@@ -256,6 +266,7 @@ namespace margelo::nitro::segmentslider::views {
256
266
  disabled(other.disabled),
257
267
  showBubble(other.showBubble),
258
268
  centerOrigin(other.centerOrigin),
269
+ snapTapToSegment(other.snapTapToSegment),
259
270
  epoch(other.epoch),
260
271
  fillColor(other.fillColor),
261
272
  trackColor(other.trackColor),
@@ -281,6 +292,7 @@ namespace margelo::nitro::segmentslider::views {
281
292
  case hashString("disabled"): return true;
282
293
  case hashString("showBubble"): return true;
283
294
  case hashString("centerOrigin"): return true;
295
+ case hashString("snapTapToSegment"): return true;
284
296
  case hashString("epoch"): return true;
285
297
  case hashString("fillColor"): return true;
286
298
  case hashString("trackColor"): return true;
@@ -51,6 +51,7 @@ namespace margelo::nitro::segmentslider::views {
51
51
  CachedProp<bool> disabled;
52
52
  CachedProp<bool> showBubble;
53
53
  CachedProp<bool> centerOrigin;
54
+ CachedProp<bool> snapTapToSegment;
54
55
  CachedProp<double> epoch;
55
56
  CachedProp<std::string> fillColor;
56
57
  CachedProp<std::string> trackColor;
@@ -12,6 +12,7 @@
12
12
  "disabled": true,
13
13
  "showBubble": true,
14
14
  "centerOrigin": true,
15
+ "snapTapToSegment": true,
15
16
  "epoch": true,
16
17
  "fillColor": true,
17
18
  "trackColor": true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/react-native-segment-slider",
3
- "version": "3.0.46",
3
+ "version": "3.0.48",
4
4
  "description": "react-native-segment-slider",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -35,7 +35,7 @@
35
35
  ],
36
36
  "scripts": {
37
37
  "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
38
- "prepare": "bob build && cp -r nitrogen lib/nitrogen",
38
+ "prepare": "bob build && rm -rf lib/nitrogen && cp -r nitrogen lib/nitrogen",
39
39
  "nitrogen": "nitrogen",
40
40
  "typecheck": "tsc",
41
41
  "lint": "eslint \"**/*.{js,ts,tsx}\"",
@@ -40,6 +40,13 @@ export interface SegmentSliderProps extends HybridViewProps {
40
40
  showBubble: boolean;
41
41
  /** When true the fill grows from the value-0 origin instead of the left. */
42
42
  centerOrigin: boolean;
43
+ /**
44
+ * When true, a tap (a press that does not turn into a drag) snaps the value to
45
+ * the nearest segment mark on release; a drag still moves freely to any value.
46
+ * No-op when `segments` is 0 (no marks to snap to). Default false, so existing
47
+ * callers keep the free-tap behavior.
48
+ */
49
+ snapTapToSegment: boolean;
43
50
  /**
44
51
  * Monotonic token. Bump from JS on coin / leverage reset so the native view
45
52
  * snaps to the new value WITHOUT animating the thumb scale. Mirrors the