@onekeyfe/react-native-segment-slider 3.0.45 → 3.0.47

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 +50 -2
  2. package/ios/HybridSegmentSlider.swift +52 -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()
@@ -116,6 +147,7 @@ class HybridSegmentSlider(val context: ThemedReactContext) : HybridSegmentSlider
116
147
  // While dragging, the finger owns the value (mirrors web).
117
148
  if (!isDragging && !isDisposed) {
118
149
  currentValue = v
150
+ lastEmitted = v
119
151
  view.invalidate()
120
152
  }
121
153
  }
@@ -152,6 +184,11 @@ class HybridSegmentSlider(val context: ThemedReactContext) : HybridSegmentSlider
152
184
  get() = field
153
185
  set(v) { field = v; invalidateIfAlive() }
154
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
+
155
192
  override var epoch: Double = 0.0
156
193
  get() = field
157
194
  set(v) { field = v }
@@ -208,6 +245,9 @@ class HybridSegmentSlider(val context: ThemedReactContext) : HybridSegmentSlider
208
245
  private val rangeSafe: Double get() = (max - min).let { if (it == 0.0) 1.0 else it }
209
246
  private val markCount: Int get() = if (segments >= 1) segments.toInt() + 1 else 0
210
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
+
211
251
  private fun valueToFrac(v: Double): Float {
212
252
  val clamped = v.coerceIn(min, max)
213
253
  return ((clamped - min) / rangeSafe).toFloat()
@@ -221,6 +261,14 @@ class HybridSegmentSlider(val context: ThemedReactContext) : HybridSegmentSlider
221
261
  return min + frac * (max - min)
222
262
  }
223
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
+
224
272
  private fun commitDragValue(raw: Double) {
225
273
  val rounded = raw.coerceIn(min, max).let { Math.round(it).toDouble() }
226
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
@@ -56,6 +67,7 @@ final class HybridSegmentSlider: HybridSegmentSliderSpec {
56
67
  // (web skips its useLayoutEffect when draggingRef.current is true).
57
68
  if !isDragging {
58
69
  currentValue = value
70
+ lastEmitted = value
59
71
  applyVisual(value)
60
72
  }
61
73
  }
@@ -72,6 +84,8 @@ final class HybridSegmentSlider: HybridSegmentSliderSpec {
72
84
  }
73
85
  var showBubble: Bool = true { didSet { scheduleLayout() } }
74
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
75
89
  var epoch: Double = 0 { didSet { scheduleLayout() } }
76
90
 
77
91
  var fillColor: String = "" {
@@ -359,24 +373,52 @@ final class HybridSegmentSlider: HybridSegmentSliderSpec {
359
373
  }
360
374
 
361
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
+
362
380
  private func handleTouchBegan(_ x: CGFloat) {
363
381
  guard !disabled else { return }
364
382
  isDragging = true
383
+ hasDragged = false
384
+ touchStartX = x
385
+ lastTouchX = x
386
+ touchStartTime = CACurrentMediaTime()
365
387
  haptic.prepare()
366
388
  onSlideStart?()
367
389
  animateThumbScale(1.15)
368
390
  setBubbleVisible(true)
369
- 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
+ }
370
396
  }
371
397
 
372
398
  private func handleTouchMoved(_ x: CGFloat) {
373
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 }
374
406
  setValue(valueFromX(x))
375
407
  }
376
408
 
377
409
  private func handleTouchEnded() {
378
410
  guard isDragging else { return }
379
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
+ }
380
422
  hoverMarkIndex = -1
381
423
  setHalo(visible: false, index: 0)
382
424
  animateThumbScale(1.0)
@@ -384,6 +426,15 @@ final class HybridSegmentSlider: HybridSegmentSliderSpec {
384
426
  onSlideComplete?()
385
427
  }
386
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
+
387
438
  private func setValue(_ raw: Double) {
388
439
  let clamped = Swift.max(min, Swift.min(max, raw))
389
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.45",
3
+ "version": "3.0.47",
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