related-ui-components 3.3.0 → 3.3.1

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.
@@ -4,10 +4,12 @@ import React, { useCallback, useMemo, useState } from "react";
4
4
  import { I18nManager, StyleSheet, View } from "react-native";
5
5
  import { Gesture, GestureDetector } from "react-native-gesture-handler";
6
6
  import Animated, { runOnJS, useAnimatedStyle, useSharedValue } from "react-native-reanimated";
7
- import { SliderLabels } from "./SliderLabel.js";
8
7
  import { useTheme } from "../../theme/index.js";
8
+ import { SliderLabels } from "./SliderLabel.js";
9
+ import { Input } from "../Input/index.js";
9
10
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
11
  const THUMB_SIZE = 28;
12
+ const THUMB_RADIUS = THUMB_SIZE / 2;
11
13
  const RAIL_HEIGHT = 6;
12
14
  const LABEL_HEIGHT = 26;
13
15
  /**
@@ -16,13 +18,9 @@ const LABEL_HEIGHT = 26;
16
18
  */
17
19
  function createPercentileBreakpoints(data) {
18
20
  const sorted = [...new Set(data)].sort((a, b) => a - b);
19
-
20
- // If small dataset, use all unique values
21
21
  if (sorted.length <= 100) {
22
22
  return sorted;
23
23
  }
24
-
25
- // For larger datasets, sample at percentile intervals
26
24
  const breakpoints = [];
27
25
  const numBreakpoints = 100;
28
26
  for (let i = 0; i <= numBreakpoints; i++) {
@@ -63,7 +61,11 @@ const RangeSlider = ({
63
61
  onValueChange,
64
62
  theme,
65
63
  scale = "linear",
66
- dataPoints
64
+ dataPoints,
65
+ showCustomInputs = false,
66
+ inputPlaceholders,
67
+ inputLabels,
68
+ isBottomSheet = false
67
69
  }) => {
68
70
  const {
69
71
  theme: defaultTheme
@@ -74,6 +76,13 @@ const RangeSlider = ({
74
76
  const [leftLabel, setLeftLabel] = useState(initialMinValue.toLocaleString());
75
77
  const [rightLabel, setRightLabel] = useState(initialMaxValue.toLocaleString());
76
78
 
79
+ // State for custom input fields
80
+ const [minInputValue, setMinInputValue] = useState(initialMinValue.toString());
81
+ const [maxInputValue, setMaxInputValue] = useState(initialMaxValue.toString());
82
+
83
+ // The effective track width (where thumb CENTER can travel)
84
+ const effectiveWidth = sliderWidth - THUMB_SIZE;
85
+
77
86
  // Pre-compute breakpoints for percentile scale
78
87
  const breakpoints = useMemo(() => {
79
88
  if (scale === "percentile" && dataPoints?.length) {
@@ -87,14 +96,12 @@ const RangeSlider = ({
87
96
 
88
97
  let percentage;
89
98
  if (scale === "percentile" && breakpoints.length > 1) {
90
- // Find where this value falls in the breakpoints
91
99
  const index = findBreakpointIndex(breakpoints, value);
92
100
  if (index === 0) {
93
101
  percentage = 0;
94
102
  } else if (index >= breakpoints.length - 1) {
95
103
  percentage = 1;
96
104
  } else {
97
- // Interpolate between breakpoints
98
105
  const lowerVal = breakpoints[index - 1];
99
106
  const upperVal = breakpoints[index];
100
107
  const lowerPct = (index - 1) / (breakpoints.length - 1);
@@ -114,16 +121,21 @@ const RangeSlider = ({
114
121
  } else {
115
122
  percentage = (value - min) / (max - min);
116
123
  }
117
- return isRTL ? (1 - percentage) * sliderWidth : percentage * sliderWidth;
118
- }, [min, max, safeMin, sliderWidth, isRTL, scale, breakpoints]);
124
+
125
+ // Map to effective width, offset by thumb radius
126
+ const position = percentage * effectiveWidth + THUMB_RADIUS;
127
+ return isRTL ? sliderWidth - position : position;
128
+ }, [min, max, safeMin, sliderWidth, effectiveWidth, isRTL, scale, breakpoints]);
119
129
  const positionToValue = useCallback(position => {
120
130
  "worklet";
121
131
 
122
- const percentage = isRTL ? 1 - position / sliderWidth : position / sliderWidth;
132
+ // Convert position to percentage using effective width
133
+ const adjustedPosition = isRTL ? sliderWidth - position : position;
134
+ const percentage = (adjustedPosition - THUMB_RADIUS) / effectiveWidth;
135
+ const clampedPercentage = Math.max(0, Math.min(1, percentage));
123
136
  let rawValue;
124
137
  if (scale === "percentile" && breakpoints.length > 1) {
125
- // Map percentage to breakpoint index
126
- const exactIndex = percentage * (breakpoints.length - 1);
138
+ const exactIndex = clampedPercentage * (breakpoints.length - 1);
127
139
  const lowerIndex = Math.floor(exactIndex);
128
140
  const upperIndex = Math.min(lowerIndex + 1, breakpoints.length - 1);
129
141
  const ratio = exactIndex - lowerIndex;
@@ -131,12 +143,12 @@ const RangeSlider = ({
131
143
  } else if (scale === "logarithmic") {
132
144
  const logMin = Math.log(safeMin);
133
145
  const logMax = Math.log(max);
134
- rawValue = Math.exp(logMin + percentage * (logMax - logMin));
146
+ rawValue = Math.exp(logMin + clampedPercentage * (logMax - logMin));
135
147
  } else {
136
- rawValue = percentage * (max - min) + min;
148
+ rawValue = clampedPercentage * (max - min) + min;
137
149
  }
138
150
  return Math.round(rawValue / step) * step;
139
- }, [min, max, safeMin, step, sliderWidth, isRTL, scale, breakpoints]);
151
+ }, [min, max, safeMin, step, sliderWidth, effectiveWidth, isRTL, scale, breakpoints]);
140
152
  const leftPosition = useSharedValue(valueToPosition(initialMinValue));
141
153
  const rightPosition = useSharedValue(valueToPosition(initialMaxValue));
142
154
  const context = useSharedValue({
@@ -161,17 +173,21 @@ const RangeSlider = ({
161
173
  if (activeThumb.value === null) return;
162
174
  const newPos = context.value.x + e.translationX;
163
175
  if (activeThumb.value === "left") {
164
- const lowerBound = isRTL ? rightPosition.value + THUMB_SIZE : 0;
165
- const upperBound = isRTL ? sliderWidth : rightPosition.value - THUMB_SIZE;
176
+ const lowerBound = isRTL ? rightPosition.value + THUMB_SIZE : THUMB_RADIUS;
177
+ const upperBound = isRTL ? sliderWidth - THUMB_RADIUS : rightPosition.value - THUMB_SIZE;
166
178
  const clampedPos = Math.max(Math.min(newPos, upperBound), lowerBound);
167
179
  leftPosition.value = clampedPos;
168
- runOnJS(setLeftLabel)(positionToValue(clampedPos).toLocaleString());
180
+ const newValue = positionToValue(clampedPos);
181
+ runOnJS(setLeftLabel)(newValue.toLocaleString());
182
+ runOnJS(setMinInputValue)(newValue.toString());
169
183
  } else {
170
- const lowerBound = isRTL ? 0 : leftPosition.value + THUMB_SIZE;
171
- const upperBound = isRTL ? leftPosition.value - THUMB_SIZE : sliderWidth;
184
+ const lowerBound = isRTL ? THUMB_RADIUS : leftPosition.value + THUMB_SIZE;
185
+ const upperBound = isRTL ? leftPosition.value - THUMB_SIZE : sliderWidth - THUMB_RADIUS;
172
186
  const clampedPos = Math.max(Math.min(newPos, upperBound), lowerBound);
173
187
  rightPosition.value = clampedPos;
174
- runOnJS(setRightLabel)(positionToValue(clampedPos).toLocaleString());
188
+ const newValue = positionToValue(clampedPos);
189
+ runOnJS(setRightLabel)(newValue.toLocaleString());
190
+ runOnJS(setMaxInputValue)(newValue.toString());
175
191
  }
176
192
  }).onEnd(() => {
177
193
  if (activeThumb.value === null) return;
@@ -183,14 +199,81 @@ const RangeSlider = ({
183
199
  });
184
200
  activeThumb.value = null;
185
201
  });
202
+
203
+ // Handlers for custom input fields
204
+ const handleMinInputChange = useCallback(text => {
205
+ // Allow only numeric input (with optional decimal)
206
+ const sanitized = text.replace(/[^0-9.]/g, "");
207
+ setMinInputValue(sanitized);
208
+ }, []);
209
+ const handleMaxInputChange = useCallback(text => {
210
+ const sanitized = text.replace(/[^0-9.]/g, "");
211
+ setMaxInputValue(sanitized);
212
+ }, []);
213
+ const handleMinInputSubmit = useCallback(() => {
214
+ const parsed = parseFloat(minInputValue);
215
+ if (isNaN(parsed)) {
216
+ // Reset to current slider value
217
+ const currentValue = positionToValue(leftPosition.value);
218
+ setMinInputValue(currentValue.toString());
219
+ return;
220
+ }
221
+
222
+ // Clamp value: must be >= min and <= current max value
223
+ const currentMaxValue = positionToValue(rightPosition.value);
224
+ const clampedValue = Math.max(min, Math.min(parsed, currentMaxValue - step));
225
+ const steppedValue = Math.round(clampedValue / step) * step;
226
+
227
+ // Update input display
228
+ setMinInputValue(steppedValue.toString());
229
+ setLeftLabel(steppedValue.toLocaleString());
230
+
231
+ // Update slider position
232
+ leftPosition.value = valueToPosition(steppedValue);
233
+
234
+ // Trigger callback
235
+ onValueChange({
236
+ min: steppedValue,
237
+ max: currentMaxValue
238
+ });
239
+ }, [minInputValue, min, step, leftPosition, rightPosition, positionToValue, valueToPosition, onValueChange]);
240
+ const handleMaxInputSubmit = useCallback(() => {
241
+ const parsed = parseFloat(maxInputValue);
242
+ if (isNaN(parsed)) {
243
+ // Reset to current slider value
244
+ const currentValue = positionToValue(rightPosition.value);
245
+ setMaxInputValue(currentValue.toString());
246
+ return;
247
+ }
248
+
249
+ // Clamp value: must be <= max and >= current min value
250
+ const currentMinValue = positionToValue(leftPosition.value);
251
+ const clampedValue = Math.min(max, Math.max(parsed, currentMinValue + step));
252
+ const steppedValue = Math.round(clampedValue / step) * step;
253
+
254
+ // Update input display
255
+ setMaxInputValue(steppedValue.toString());
256
+ setRightLabel(steppedValue.toLocaleString());
257
+
258
+ // Update slider position
259
+ rightPosition.value = valueToPosition(steppedValue);
260
+
261
+ // Trigger callback
262
+ onValueChange({
263
+ min: currentMinValue,
264
+ max: steppedValue
265
+ });
266
+ }, [maxInputValue, max, step, leftPosition, rightPosition, positionToValue, valueToPosition, onValueChange]);
267
+
268
+ // Thumb position = center of thumb, so offset by radius to get left edge
186
269
  const animatedLeftThumbStyle = useAnimatedStyle(() => ({
187
270
  transform: [{
188
- translateX: leftPosition.value - (isRTL ? THUMB_SIZE : 0)
271
+ translateX: leftPosition.value - THUMB_RADIUS
189
272
  }]
190
273
  }));
191
274
  const animatedRightThumbStyle = useAnimatedStyle(() => ({
192
275
  transform: [{
193
- translateX: rightPosition.value - (isRTL ? 0 : THUMB_SIZE)
276
+ translateX: rightPosition.value - THUMB_RADIUS
194
277
  }]
195
278
  }));
196
279
  const animatedActiveRailStyle = useAnimatedStyle(() => {
@@ -202,10 +285,41 @@ const RangeSlider = ({
202
285
  };
203
286
  });
204
287
  return /*#__PURE__*/_jsxs(View, {
205
- style: [styles.container, {
288
+ style: [showCustomInputs ? styles.containerWithInputs : styles.container, {
206
289
  width: sliderWidth
207
290
  }],
208
- children: [/*#__PURE__*/_jsx(SliderLabels, {
291
+ children: [showCustomInputs ? /*#__PURE__*/_jsxs(View, {
292
+ style: styles.inputsContainer,
293
+ children: [/*#__PURE__*/_jsx(View, {
294
+ style: styles.inputWrapper,
295
+ children: /*#__PURE__*/_jsx(Input, {
296
+ label: inputLabels?.min ?? "Min",
297
+ value: minInputValue,
298
+ onChangeText: handleMinInputChange,
299
+ onBlur: handleMinInputSubmit,
300
+ onSubmitEditing: handleMinInputSubmit,
301
+ keyboardType: "numeric",
302
+ placeholder: inputPlaceholders?.min,
303
+ placeholderTextColor: currTheme.surfaceVariant,
304
+ returnKeyType: "done",
305
+ isBottomSheet: isBottomSheet
306
+ })
307
+ }), /*#__PURE__*/_jsx(View, {
308
+ style: styles.inputWrapper,
309
+ children: /*#__PURE__*/_jsx(Input, {
310
+ label: inputLabels?.max ?? "Max",
311
+ value: maxInputValue,
312
+ onChangeText: handleMaxInputChange,
313
+ onBlur: handleMaxInputSubmit,
314
+ onSubmitEditing: handleMaxInputSubmit,
315
+ keyboardType: "numeric",
316
+ placeholder: inputPlaceholders?.max,
317
+ placeholderTextColor: currTheme.surfaceVariant,
318
+ returnKeyType: "done",
319
+ isBottomSheet: isBottomSheet
320
+ })
321
+ })]
322
+ }) : /*#__PURE__*/_jsx(SliderLabels, {
209
323
  leftValue: leftLabel,
210
324
  rightValue: rightLabel,
211
325
  leftPosition: leftPosition,
@@ -242,6 +356,9 @@ const getStyles = theme => StyleSheet.create({
242
356
  marginTop: LABEL_HEIGHT,
243
357
  direction: "ltr"
244
358
  },
359
+ containerWithInputs: {
360
+ direction: "ltr"
361
+ },
245
362
  railContainer: {
246
363
  justifyContent: "center",
247
364
  height: THUMB_SIZE
@@ -270,6 +387,34 @@ const getStyles = theme => StyleSheet.create({
270
387
  backgroundColor: theme.background,
271
388
  borderColor: theme.primary,
272
389
  borderWidth: 5
390
+ },
391
+ inputsContainer: {
392
+ flexDirection: "row",
393
+ justifyContent: "space-between",
394
+ gap: 16,
395
+ marginBottom: 12,
396
+ direction: I18nManager.isRTL ? "rtl" : "ltr"
397
+ },
398
+ inputWrapper: {
399
+ flex: 1
400
+ },
401
+ inputLabel: {
402
+ color: theme.onSurface,
403
+ fontSize: 13,
404
+ fontFamily: "DinMedium",
405
+ marginBottom: 6
406
+ },
407
+ input: {
408
+ backgroundColor: theme.background,
409
+ paddingHorizontal: 16,
410
+ paddingVertical: 10,
411
+ borderRadius: 8,
412
+ borderWidth: 1,
413
+ borderColor: theme.surfaceVariant,
414
+ color: theme.onSurface,
415
+ fontSize: 15,
416
+ fontFamily: "DinBold",
417
+ textAlign: "center"
273
418
  }
274
419
  });
275
420
  export default RangeSlider;
@@ -1 +1 @@
1
- {"version":3,"names":["React","useCallback","useMemo","useState","I18nManager","StyleSheet","View","Gesture","GestureDetector","Animated","runOnJS","useAnimatedStyle","useSharedValue","SliderLabels","useTheme","jsx","_jsx","jsxs","_jsxs","THUMB_SIZE","RAIL_HEIGHT","LABEL_HEIGHT","createPercentileBreakpoints","data","sorted","Set","sort","a","b","length","breakpoints","numBreakpoints","i","index","Math","floor","value","push","findBreakpointIndex","left","right","mid","RangeSlider","min","max","step","sliderWidth","initialMinValue","initialMaxValue","onValueChange","theme","scale","dataPoints","defaultTheme","currTheme","styles","getStyles","isRTL","leftLabel","setLeftLabel","toLocaleString","rightLabel","setRightLabel","safeMin","valueToPosition","percentage","lowerVal","upperVal","lowerPct","upperPct","ratio","logMin","log","logMax","logValue","positionToValue","position","rawValue","exactIndex","lowerIndex","upperIndex","exp","round","leftPosition","rightPosition","context","x","activeThumb","panGesture","Pan","onBegin","e","distToLeft","abs","distToRight","onUpdate","newPos","translationX","lowerBound","upperBound","clampedPos","onEnd","finalLeftValue","finalRightValue","animatedLeftThumbStyle","transform","translateX","animatedRightThumbStyle","animatedActiveRailStyle","start","end","style","container","width","children","leftValue","rightValue","thumbSize","gesture","railContainer","rail","activeRail","thumbContainer","thumb","create","height","justifyContent","marginTop","direction","borderRadius","backgroundColor","surface","primary","alignItems","background","borderColor","borderWidth"],"sourceRoot":"..\\..\\..\\..\\src","sources":["components/RangeSlider/RangeSlider.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["React","useCallback","useMemo","useState","I18nManager","StyleSheet","View","Gesture","GestureDetector","Animated","runOnJS","useAnimatedStyle","useSharedValue","useTheme","SliderLabels","Input","jsx","_jsx","jsxs","_jsxs","THUMB_SIZE","THUMB_RADIUS","RAIL_HEIGHT","LABEL_HEIGHT","createPercentileBreakpoints","data","sorted","Set","sort","a","b","length","breakpoints","numBreakpoints","i","index","Math","floor","value","push","findBreakpointIndex","left","right","mid","RangeSlider","min","max","step","sliderWidth","initialMinValue","initialMaxValue","onValueChange","theme","scale","dataPoints","showCustomInputs","inputPlaceholders","inputLabels","isBottomSheet","defaultTheme","currTheme","styles","getStyles","isRTL","leftLabel","setLeftLabel","toLocaleString","rightLabel","setRightLabel","minInputValue","setMinInputValue","toString","maxInputValue","setMaxInputValue","effectiveWidth","safeMin","valueToPosition","percentage","lowerVal","upperVal","lowerPct","upperPct","ratio","logMin","log","logMax","logValue","position","positionToValue","adjustedPosition","clampedPercentage","rawValue","exactIndex","lowerIndex","upperIndex","exp","round","leftPosition","rightPosition","context","x","activeThumb","panGesture","Pan","onBegin","e","distToLeft","abs","distToRight","onUpdate","newPos","translationX","lowerBound","upperBound","clampedPos","newValue","onEnd","finalLeftValue","finalRightValue","handleMinInputChange","text","sanitized","replace","handleMaxInputChange","handleMinInputSubmit","parsed","parseFloat","isNaN","currentValue","currentMaxValue","clampedValue","steppedValue","handleMaxInputSubmit","currentMinValue","animatedLeftThumbStyle","transform","translateX","animatedRightThumbStyle","animatedActiveRailStyle","start","end","style","containerWithInputs","container","width","children","inputsContainer","inputWrapper","label","onChangeText","onBlur","onSubmitEditing","keyboardType","placeholder","placeholderTextColor","surfaceVariant","returnKeyType","leftValue","rightValue","thumbSize","gesture","railContainer","rail","activeRail","thumbContainer","thumb","create","height","justifyContent","marginTop","direction","borderRadius","backgroundColor","surface","primary","alignItems","background","borderColor","borderWidth","flexDirection","gap","marginBottom","flex","inputLabel","color","onSurface","fontSize","fontFamily","input","paddingHorizontal","paddingVertical","textAlign"],"sourceRoot":"..\\..\\..\\..\\src","sources":["components/RangeSlider/RangeSlider.tsx"],"mappings":"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","ignoreList":[]}
@@ -6,35 +6,71 @@ import Animated, { useAnimatedStyle, useDerivedValue, useSharedValue } from "rea
6
6
  import { useTheme } from "../../theme/index.js";
7
7
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
8
  const LABEL_HEIGHT = 26;
9
- const CenteredLabel = ({
9
+ const LABEL_PADDING = 8;
10
+ const MIN_GAP = 4;
11
+ const SingleLabel = ({
10
12
  value,
11
13
  position,
12
14
  sliderWidth,
13
- thumbSize,
15
+ onWidthChange,
16
+ isVisible,
14
17
  theme
15
18
  }) => {
19
+ const styles = getStyles(theme);
20
+ const localWidth = useSharedValue(0);
21
+ const animatedStyle = useAnimatedStyle(() => {
22
+ const halfLabel = localWidth.value / 2;
23
+ const rawCenter = position.value;
24
+ const shifted = rawCenter - halfLabel;
25
+ const left = Math.min(Math.max(shifted, 0), sliderWidth - localWidth.value);
26
+ return {
27
+ left,
28
+ opacity: isVisible.value ? 1 : 0
29
+ };
30
+ });
31
+ return /*#__PURE__*/_jsx(Animated.View, {
32
+ style: [styles.labelContainer, animatedStyle],
33
+ onLayout: e => {
34
+ const width = e.nativeEvent.layout.width;
35
+ localWidth.value = width;
36
+ onWidthChange(width);
37
+ },
38
+ children: /*#__PURE__*/_jsx(Text, {
39
+ style: styles.labelText,
40
+ children: value
41
+ })
42
+ });
43
+ };
44
+ const MergedLabel = ({
45
+ leftValue,
46
+ rightValue,
47
+ leftPosition,
48
+ rightPosition,
49
+ sliderWidth,
50
+ isVisible,
51
+ theme
52
+ }) => {
53
+ const styles = getStyles(theme);
16
54
  const labelWidth = useSharedValue(0);
17
- const {
18
- theme: defaultTheme
19
- } = useTheme();
20
- const currTheme = theme || defaultTheme;
21
- const styles = getStyles(currTheme);
22
- const animatedLabelStyle = useAnimatedStyle(() => {
23
- const rawCenter = position.value + thumbSize / 2;
24
- const shifted = rawCenter - labelWidth.value / 2;
55
+ const animatedStyle = useAnimatedStyle(() => {
56
+ const centerPosition = (leftPosition.value + rightPosition.value) / 2;
57
+ const halfLabel = labelWidth.value / 2;
58
+ const shifted = centerPosition - halfLabel;
25
59
  const left = Math.min(Math.max(shifted, 0), sliderWidth - labelWidth.value);
26
60
  return {
27
- left: left
61
+ left,
62
+ opacity: isVisible.value ? 1 : 0
28
63
  };
29
64
  });
65
+ const displayText = leftValue === rightValue ? leftValue : `${leftValue} - ${rightValue}`;
30
66
  return /*#__PURE__*/_jsx(Animated.View, {
31
- style: [styles.labelContainer, animatedLabelStyle],
67
+ style: [styles.labelContainer, animatedStyle],
32
68
  onLayout: e => {
33
69
  labelWidth.value = e.nativeEvent.layout.width;
34
70
  },
35
71
  children: /*#__PURE__*/_jsx(Text, {
36
72
  style: styles.labelText,
37
- children: value
73
+ children: displayText
38
74
  })
39
75
  });
40
76
  };
@@ -51,27 +87,54 @@ export const SliderLabels = ({
51
87
  theme: defaultTheme
52
88
  } = useTheme();
53
89
  const currTheme = theme || defaultTheme;
54
- const styles = getStyles(currTheme);
55
- const rightThumbLeftPosition = useDerivedValue(() => {
56
- return rightPosition.value - thumbSize;
57
- });
58
- const leftThumbLeftPosition = useDerivedValue(() => {
59
- return leftPosition.value - thumbSize;
60
- });
61
90
  const isRTL = I18nManager.isRTL;
91
+
92
+ // Track label widths in parent for overlap calculation
93
+ const leftLabelWidth = useSharedValue(0);
94
+ const rightLabelWidth = useSharedValue(0);
95
+ const shouldMerge = useDerivedValue(() => {
96
+ const leftCenter = leftPosition.value;
97
+ const rightCenter = rightPosition.value;
98
+ const leftEnd = leftCenter + leftLabelWidth.value / 2;
99
+ const rightStart = rightCenter - rightLabelWidth.value / 2;
100
+ if (isRTL) {
101
+ const rtlLeftEnd = rightCenter + rightLabelWidth.value / 2;
102
+ const rtlRightStart = leftCenter - leftLabelWidth.value / 2;
103
+ return rtlRightStart - rtlLeftEnd < MIN_GAP;
104
+ }
105
+ return rightStart - leftEnd < MIN_GAP;
106
+ });
107
+ const showSeparate = useDerivedValue(() => !shouldMerge.value);
108
+ const showMerged = useDerivedValue(() => shouldMerge.value);
62
109
  return /*#__PURE__*/_jsxs(View, {
63
- style: styles.wrapper,
110
+ style: getStyles(currTheme).wrapper,
64
111
  pointerEvents: "none",
65
- children: [/*#__PURE__*/_jsx(CenteredLabel, {
112
+ children: [/*#__PURE__*/_jsx(SingleLabel, {
66
113
  value: leftValue,
67
- thumbSize: thumbSize,
68
- position: isRTL ? leftThumbLeftPosition : leftPosition,
69
- sliderWidth: sliderWidth
70
- }), /*#__PURE__*/_jsx(CenteredLabel, {
114
+ position: leftPosition,
115
+ sliderWidth: sliderWidth,
116
+ onWidthChange: width => {
117
+ leftLabelWidth.value = width;
118
+ },
119
+ isVisible: showSeparate,
120
+ theme: currTheme
121
+ }), /*#__PURE__*/_jsx(SingleLabel, {
71
122
  value: rightValue,
72
- thumbSize: thumbSize,
73
- position: isRTL ? rightPosition : rightThumbLeftPosition,
74
- sliderWidth: sliderWidth
123
+ position: rightPosition,
124
+ sliderWidth: sliderWidth,
125
+ onWidthChange: width => {
126
+ rightLabelWidth.value = width;
127
+ },
128
+ isVisible: showSeparate,
129
+ theme: currTheme
130
+ }), /*#__PURE__*/_jsx(MergedLabel, {
131
+ leftValue: leftValue,
132
+ rightValue: rightValue,
133
+ leftPosition: leftPosition,
134
+ rightPosition: rightPosition,
135
+ sliderWidth: sliderWidth,
136
+ isVisible: showMerged,
137
+ theme: currTheme
75
138
  })]
76
139
  });
77
140
  };
@@ -88,7 +151,7 @@ const getStyles = theme => StyleSheet.create({
88
151
  },
89
152
  labelText: {
90
153
  backgroundColor: theme.surface,
91
- paddingHorizontal: 8,
154
+ paddingHorizontal: LABEL_PADDING,
92
155
  paddingVertical: 4,
93
156
  borderRadius: 4,
94
157
  color: theme.onSurface,
@@ -1 +1 @@
1
- {"version":3,"names":["React","I18nManager","StyleSheet","Text","View","Animated","useAnimatedStyle","useDerivedValue","useSharedValue","useTheme","jsx","_jsx","jsxs","_jsxs","LABEL_HEIGHT","CenteredLabel","value","position","sliderWidth","thumbSize","theme","labelWidth","defaultTheme","currTheme","styles","getStyles","animatedLabelStyle","rawCenter","shifted","left","Math","min","max","style","labelContainer","onLayout","e","nativeEvent","layout","width","children","labelText","SliderLabels","leftValue","rightValue","leftPosition","rightPosition","rightThumbLeftPosition","leftThumbLeftPosition","isRTL","wrapper","pointerEvents","create","height","top","alignItems","backgroundColor","surface","paddingHorizontal","paddingVertical","borderRadius","color","onSurface","fontSize","fontFamily"],"sourceRoot":"..\\..\\..\\..\\src","sources":["components/RangeSlider/SliderLabel.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["React","I18nManager","StyleSheet","Text","View","Animated","useAnimatedStyle","useDerivedValue","useSharedValue","useTheme","jsx","_jsx","jsxs","_jsxs","LABEL_HEIGHT","LABEL_PADDING","MIN_GAP","SingleLabel","value","position","sliderWidth","onWidthChange","isVisible","theme","styles","getStyles","localWidth","animatedStyle","halfLabel","rawCenter","shifted","left","Math","min","max","opacity","style","labelContainer","onLayout","e","width","nativeEvent","layout","children","labelText","MergedLabel","leftValue","rightValue","leftPosition","rightPosition","labelWidth","centerPosition","displayText","SliderLabels","thumbSize","defaultTheme","currTheme","isRTL","leftLabelWidth","rightLabelWidth","shouldMerge","leftCenter","rightCenter","leftEnd","rightStart","rtlLeftEnd","rtlRightStart","showSeparate","showMerged","wrapper","pointerEvents","create","height","top","alignItems","backgroundColor","surface","paddingHorizontal","paddingVertical","borderRadius","color","onSurface","fontSize","fontFamily"],"sourceRoot":"..\\..\\..\\..\\src","sources":["components/RangeSlider/SliderLabel.tsx"],"mappings":"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","ignoreList":[]}
@@ -14,11 +14,17 @@ interface RangeSliderProps {
14
14
  }) => void;
15
15
  theme?: ThemeType;
16
16
  scale?: ScaleType;
17
- /**
18
- * For percentile scale: array of all values in your dataset
19
- * The slider will distribute positions based on data density
20
- */
21
17
  dataPoints?: number[];
18
+ showCustomInputs?: boolean;
19
+ inputPlaceholders?: {
20
+ min?: string;
21
+ max?: string;
22
+ };
23
+ inputLabels?: {
24
+ min?: string;
25
+ max?: string;
26
+ };
27
+ isBottomSheet?: boolean;
22
28
  }
23
29
  declare const RangeSlider: React.FC<RangeSliderProps>;
24
30
  export default RangeSlider;
@@ -1 +1 @@
1
- {"version":3,"file":"RangeSlider.d.ts","sourceRoot":"","sources":["../../../../../src/components/RangeSlider/RangeSlider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAS9D,OAAO,EAAE,SAAS,EAAY,MAAM,aAAa,CAAC;AAMlD,KAAK,SAAS,GAAG,QAAQ,GAAG,aAAa,GAAG,YAAY,CAAC;AAEzD,UAAU,gBAAgB;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9D,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAiDD,QAAA,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAwM3C,CAAC;AAyCF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"RangeSlider.d.ts","sourceRoot":"","sources":["../../../../../src/components/RangeSlider/RangeSlider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAQ9D,OAAO,EAAE,SAAS,EAAY,MAAM,aAAa,CAAC;AASlD,KAAK,SAAS,GAAG,QAAQ,GAAG,aAAa,GAAG,YAAY,CAAC;AAEzD,UAAU,gBAAgB;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9D,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iBAAiB,CAAC,EAAE;QAClB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,WAAW,CAAC,EAAE;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AA+CD,QAAA,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAqW3C,CAAC;AAwEF,eAAe,WAAW,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SliderLabel.d.ts","sourceRoot":"","sources":["../../../../../src/components/RangeSlider/SliderLabel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAiB,EACf,WAAW,EAIZ,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,SAAS,EAAY,MAAM,aAAa,CAAC;AAIlD,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB;AAgDD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAqCpD,CAAC"}
1
+ {"version":3,"file":"SliderLabel.d.ts","sourceRoot":"","sources":["../../../../../src/components/RangeSlider/SliderLabel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAiB,EACb,WAAW,EAId,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,SAAS,EAAY,MAAM,aAAa,CAAC;AAMlD,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAiGD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAsEpD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "related-ui-components",
3
- "version": "3.3.0",
3
+ "version": "3.3.1",
4
4
  "main": "lib/module/index.js",
5
5
  "scripts": {
6
6
  "start": "expo start",
@@ -6,10 +6,12 @@ import Animated, {
6
6
  useAnimatedStyle,
7
7
  useSharedValue,
8
8
  } from "react-native-reanimated";
9
- import { SliderLabels } from "./SliderLabel";
10
9
  import { ThemeType, useTheme } from "../../theme";
10
+ import { SliderLabels } from "./SliderLabel";
11
+ import { Input } from "../Input";
11
12
 
12
13
  const THUMB_SIZE = 28;
14
+ const THUMB_RADIUS = THUMB_SIZE / 2;
13
15
  const RAIL_HEIGHT = 6;
14
16
  const LABEL_HEIGHT = 26;
15
17
 
@@ -25,11 +27,17 @@ interface RangeSliderProps {
25
27
  onValueChange: (values: { min: number; max: number }) => void;
26
28
  theme?: ThemeType;
27
29
  scale?: ScaleType;
28
- /**
29
- * For percentile scale: array of all values in your dataset
30
- * The slider will distribute positions based on data density
31
- */
32
30
  dataPoints?: number[];
31
+ showCustomInputs?: boolean;
32
+ inputPlaceholders?: {
33
+ min?: string;
34
+ max?: string;
35
+ };
36
+ inputLabels?: {
37
+ min?: string;
38
+ max?: string;
39
+ };
40
+ isBottomSheet?: boolean;
33
41
  }
34
42
 
35
43
  /**
@@ -39,12 +47,10 @@ interface RangeSliderProps {
39
47
  function createPercentileBreakpoints(data: number[]): number[] {
40
48
  const sorted = [...new Set(data)].sort((a, b) => a - b);
41
49
 
42
- // If small dataset, use all unique values
43
50
  if (sorted.length <= 100) {
44
51
  return sorted;
45
52
  }
46
53
 
47
- // For larger datasets, sample at percentile intervals
48
54
  const breakpoints: number[] = [];
49
55
  const numBreakpoints = 100;
50
56
 
@@ -90,6 +96,10 @@ const RangeSlider: React.FC<RangeSliderProps> = ({
90
96
  theme,
91
97
  scale = "linear",
92
98
  dataPoints,
99
+ showCustomInputs = false,
100
+ inputPlaceholders,
101
+ inputLabels,
102
+ isBottomSheet = false,
93
103
  }) => {
94
104
  const { theme: defaultTheme } = useTheme();
95
105
  const currTheme = theme || defaultTheme;
@@ -98,9 +108,20 @@ const RangeSlider: React.FC<RangeSliderProps> = ({
98
108
 
99
109
  const [leftLabel, setLeftLabel] = useState(initialMinValue.toLocaleString());
100
110
  const [rightLabel, setRightLabel] = useState(
101
- initialMaxValue.toLocaleString()
111
+ initialMaxValue.toLocaleString(),
112
+ );
113
+
114
+ // State for custom input fields
115
+ const [minInputValue, setMinInputValue] = useState(
116
+ initialMinValue.toString(),
117
+ );
118
+ const [maxInputValue, setMaxInputValue] = useState(
119
+ initialMaxValue.toString(),
102
120
  );
103
121
 
122
+ // The effective track width (where thumb CENTER can travel)
123
+ const effectiveWidth = sliderWidth - THUMB_SIZE;
124
+
104
125
  // Pre-compute breakpoints for percentile scale
105
126
  const breakpoints = useMemo(() => {
106
127
  if (scale === "percentile" && dataPoints?.length) {
@@ -117,7 +138,6 @@ const RangeSlider: React.FC<RangeSliderProps> = ({
117
138
  let percentage: number;
118
139
 
119
140
  if (scale === "percentile" && breakpoints.length > 1) {
120
- // Find where this value falls in the breakpoints
121
141
  const index = findBreakpointIndex(breakpoints, value);
122
142
 
123
143
  if (index === 0) {
@@ -125,7 +145,6 @@ const RangeSlider: React.FC<RangeSliderProps> = ({
125
145
  } else if (index >= breakpoints.length - 1) {
126
146
  percentage = 1;
127
147
  } else {
128
- // Interpolate between breakpoints
129
148
  const lowerVal = breakpoints[index - 1];
130
149
  const upperVal = breakpoints[index];
131
150
  const lowerPct = (index - 1) / (breakpoints.length - 1);
@@ -147,41 +166,52 @@ const RangeSlider: React.FC<RangeSliderProps> = ({
147
166
  percentage = (value - min) / (max - min);
148
167
  }
149
168
 
150
- return isRTL ? (1 - percentage) * sliderWidth : percentage * sliderWidth;
169
+ // Map to effective width, offset by thumb radius
170
+ const position = percentage * effectiveWidth + THUMB_RADIUS;
171
+ return isRTL ? sliderWidth - position : position;
151
172
  },
152
- [min, max, safeMin, sliderWidth, isRTL, scale, breakpoints]
173
+ [min, max, safeMin, sliderWidth, effectiveWidth, isRTL, scale, breakpoints],
153
174
  );
154
175
 
155
176
  const positionToValue = useCallback(
156
177
  (position: number) => {
157
178
  "worklet";
158
- const percentage = isRTL
159
- ? 1 - position / sliderWidth
160
- : position / sliderWidth;
179
+ // Convert position to percentage using effective width
180
+ const adjustedPosition = isRTL ? sliderWidth - position : position;
181
+ const percentage = (adjustedPosition - THUMB_RADIUS) / effectiveWidth;
182
+ const clampedPercentage = Math.max(0, Math.min(1, percentage));
161
183
 
162
184
  let rawValue: number;
163
185
 
164
186
  if (scale === "percentile" && breakpoints.length > 1) {
165
- // Map percentage to breakpoint index
166
- const exactIndex = percentage * (breakpoints.length - 1);
187
+ const exactIndex = clampedPercentage * (breakpoints.length - 1);
167
188
  const lowerIndex = Math.floor(exactIndex);
168
189
  const upperIndex = Math.min(lowerIndex + 1, breakpoints.length - 1);
169
190
  const ratio = exactIndex - lowerIndex;
170
-
171
191
  rawValue =
172
192
  breakpoints[lowerIndex] +
173
193
  ratio * (breakpoints[upperIndex] - breakpoints[lowerIndex]);
174
194
  } else if (scale === "logarithmic") {
175
195
  const logMin = Math.log(safeMin);
176
196
  const logMax = Math.log(max);
177
- rawValue = Math.exp(logMin + percentage * (logMax - logMin));
197
+ rawValue = Math.exp(logMin + clampedPercentage * (logMax - logMin));
178
198
  } else {
179
- rawValue = percentage * (max - min) + min;
199
+ rawValue = clampedPercentage * (max - min) + min;
180
200
  }
181
201
 
182
202
  return Math.round(rawValue / step) * step;
183
203
  },
184
- [min, max, safeMin, step, sliderWidth, isRTL, scale, breakpoints]
204
+ [
205
+ min,
206
+ max,
207
+ safeMin,
208
+ step,
209
+ sliderWidth,
210
+ effectiveWidth,
211
+ isRTL,
212
+ scale,
213
+ breakpoints,
214
+ ],
185
215
  );
186
216
 
187
217
  const leftPosition = useSharedValue(valueToPosition(initialMinValue));
@@ -206,21 +236,29 @@ const RangeSlider: React.FC<RangeSliderProps> = ({
206
236
  const newPos = context.value.x + e.translationX;
207
237
 
208
238
  if (activeThumb.value === "left") {
209
- const lowerBound = isRTL ? rightPosition.value + THUMB_SIZE : 0;
239
+ const lowerBound = isRTL
240
+ ? rightPosition.value + THUMB_SIZE
241
+ : THUMB_RADIUS;
210
242
  const upperBound = isRTL
211
- ? sliderWidth
243
+ ? sliderWidth - THUMB_RADIUS
212
244
  : rightPosition.value - THUMB_SIZE;
213
245
  const clampedPos = Math.max(Math.min(newPos, upperBound), lowerBound);
214
246
  leftPosition.value = clampedPos;
215
- runOnJS(setLeftLabel)(positionToValue(clampedPos).toLocaleString());
247
+ const newValue = positionToValue(clampedPos);
248
+ runOnJS(setLeftLabel)(newValue.toLocaleString());
249
+ runOnJS(setMinInputValue)(newValue.toString());
216
250
  } else {
217
- const lowerBound = isRTL ? 0 : leftPosition.value + THUMB_SIZE;
251
+ const lowerBound = isRTL
252
+ ? THUMB_RADIUS
253
+ : leftPosition.value + THUMB_SIZE;
218
254
  const upperBound = isRTL
219
255
  ? leftPosition.value - THUMB_SIZE
220
- : sliderWidth;
256
+ : sliderWidth - THUMB_RADIUS;
221
257
  const clampedPos = Math.max(Math.min(newPos, upperBound), lowerBound);
222
258
  rightPosition.value = clampedPos;
223
- runOnJS(setRightLabel)(positionToValue(clampedPos).toLocaleString());
259
+ const newValue = positionToValue(clampedPos);
260
+ runOnJS(setRightLabel)(newValue.toLocaleString());
261
+ runOnJS(setMaxInputValue)(newValue.toString());
224
262
  }
225
263
  })
226
264
  .onEnd(() => {
@@ -231,12 +269,99 @@ const RangeSlider: React.FC<RangeSliderProps> = ({
231
269
  activeThumb.value = null;
232
270
  });
233
271
 
272
+ // Handlers for custom input fields
273
+ const handleMinInputChange = useCallback((text: string) => {
274
+ // Allow only numeric input (with optional decimal)
275
+ const sanitized = text.replace(/[^0-9.]/g, "");
276
+ setMinInputValue(sanitized);
277
+ }, []);
278
+
279
+ const handleMaxInputChange = useCallback((text: string) => {
280
+ const sanitized = text.replace(/[^0-9.]/g, "");
281
+ setMaxInputValue(sanitized);
282
+ }, []);
283
+
284
+ const handleMinInputSubmit = useCallback(() => {
285
+ const parsed = parseFloat(minInputValue);
286
+ if (isNaN(parsed)) {
287
+ // Reset to current slider value
288
+ const currentValue = positionToValue(leftPosition.value);
289
+ setMinInputValue(currentValue.toString());
290
+ return;
291
+ }
292
+
293
+ // Clamp value: must be >= min and <= current max value
294
+ const currentMaxValue = positionToValue(rightPosition.value);
295
+ const clampedValue = Math.max(
296
+ min,
297
+ Math.min(parsed, currentMaxValue - step),
298
+ );
299
+ const steppedValue = Math.round(clampedValue / step) * step;
300
+
301
+ // Update input display
302
+ setMinInputValue(steppedValue.toString());
303
+ setLeftLabel(steppedValue.toLocaleString());
304
+
305
+ // Update slider position
306
+ leftPosition.value = valueToPosition(steppedValue);
307
+
308
+ // Trigger callback
309
+ onValueChange({ min: steppedValue, max: currentMaxValue });
310
+ }, [
311
+ minInputValue,
312
+ min,
313
+ step,
314
+ leftPosition,
315
+ rightPosition,
316
+ positionToValue,
317
+ valueToPosition,
318
+ onValueChange,
319
+ ]);
320
+
321
+ const handleMaxInputSubmit = useCallback(() => {
322
+ const parsed = parseFloat(maxInputValue);
323
+ if (isNaN(parsed)) {
324
+ // Reset to current slider value
325
+ const currentValue = positionToValue(rightPosition.value);
326
+ setMaxInputValue(currentValue.toString());
327
+ return;
328
+ }
329
+
330
+ // Clamp value: must be <= max and >= current min value
331
+ const currentMinValue = positionToValue(leftPosition.value);
332
+ const clampedValue = Math.min(
333
+ max,
334
+ Math.max(parsed, currentMinValue + step),
335
+ );
336
+ const steppedValue = Math.round(clampedValue / step) * step;
337
+
338
+ // Update input display
339
+ setMaxInputValue(steppedValue.toString());
340
+ setRightLabel(steppedValue.toLocaleString());
341
+
342
+ // Update slider position
343
+ rightPosition.value = valueToPosition(steppedValue);
344
+
345
+ // Trigger callback
346
+ onValueChange({ min: currentMinValue, max: steppedValue });
347
+ }, [
348
+ maxInputValue,
349
+ max,
350
+ step,
351
+ leftPosition,
352
+ rightPosition,
353
+ positionToValue,
354
+ valueToPosition,
355
+ onValueChange,
356
+ ]);
357
+
358
+ // Thumb position = center of thumb, so offset by radius to get left edge
234
359
  const animatedLeftThumbStyle = useAnimatedStyle(() => ({
235
- transform: [{ translateX: leftPosition.value - (isRTL ? THUMB_SIZE : 0) }],
360
+ transform: [{ translateX: leftPosition.value - THUMB_RADIUS }],
236
361
  }));
237
362
 
238
363
  const animatedRightThumbStyle = useAnimatedStyle(() => ({
239
- transform: [{ translateX: rightPosition.value - (isRTL ? 0 : THUMB_SIZE) }],
364
+ transform: [{ translateX: rightPosition.value - THUMB_RADIUS }],
240
365
  }));
241
366
 
242
367
  const animatedActiveRailStyle = useAnimatedStyle(() => {
@@ -249,15 +374,53 @@ const RangeSlider: React.FC<RangeSliderProps> = ({
249
374
  });
250
375
 
251
376
  return (
252
- <View style={[styles.container, { width: sliderWidth }]}>
253
- <SliderLabels
254
- leftValue={leftLabel}
255
- rightValue={rightLabel}
256
- leftPosition={leftPosition}
257
- rightPosition={rightPosition}
258
- sliderWidth={sliderWidth}
259
- thumbSize={THUMB_SIZE}
260
- />
377
+ <View
378
+ style={[
379
+ showCustomInputs ? styles.containerWithInputs : styles.container,
380
+ { width: sliderWidth },
381
+ ]}
382
+ >
383
+ {showCustomInputs ? (
384
+ <View style={styles.inputsContainer}>
385
+ <View style={styles.inputWrapper}>
386
+ <Input
387
+ label={inputLabels?.min ?? "Min"}
388
+ value={minInputValue}
389
+ onChangeText={handleMinInputChange}
390
+ onBlur={handleMinInputSubmit}
391
+ onSubmitEditing={handleMinInputSubmit}
392
+ keyboardType="numeric"
393
+ placeholder={inputPlaceholders?.min}
394
+ placeholderTextColor={currTheme.surfaceVariant}
395
+ returnKeyType="done"
396
+ isBottomSheet={isBottomSheet}
397
+ />
398
+ </View>
399
+ <View style={styles.inputWrapper}>
400
+ <Input
401
+ label={inputLabels?.max ?? "Max"}
402
+ value={maxInputValue}
403
+ onChangeText={handleMaxInputChange}
404
+ onBlur={handleMaxInputSubmit}
405
+ onSubmitEditing={handleMaxInputSubmit}
406
+ keyboardType="numeric"
407
+ placeholder={inputPlaceholders?.max}
408
+ placeholderTextColor={currTheme.surfaceVariant}
409
+ returnKeyType="done"
410
+ isBottomSheet={isBottomSheet}
411
+ />
412
+ </View>
413
+ </View>
414
+ ) : (
415
+ <SliderLabels
416
+ leftValue={leftLabel}
417
+ rightValue={rightLabel}
418
+ leftPosition={leftPosition}
419
+ rightPosition={rightPosition}
420
+ sliderWidth={sliderWidth}
421
+ thumbSize={THUMB_SIZE}
422
+ />
423
+ )}
261
424
 
262
425
  <GestureDetector gesture={panGesture}>
263
426
  <View style={styles.railContainer}>
@@ -289,6 +452,9 @@ const getStyles = (theme: ThemeType) =>
289
452
  marginTop: LABEL_HEIGHT,
290
453
  direction: "ltr",
291
454
  },
455
+ containerWithInputs: {
456
+ direction: "ltr",
457
+ },
292
458
  railContainer: {
293
459
  justifyContent: "center",
294
460
  height: THUMB_SIZE,
@@ -318,6 +484,34 @@ const getStyles = (theme: ThemeType) =>
318
484
  borderColor: theme.primary,
319
485
  borderWidth: 5,
320
486
  },
487
+ inputsContainer: {
488
+ flexDirection: "row",
489
+ justifyContent: "space-between",
490
+ gap: 16,
491
+ marginBottom: 12,
492
+ direction: I18nManager.isRTL ? "rtl" : "ltr",
493
+ },
494
+ inputWrapper: {
495
+ flex: 1,
496
+ },
497
+ inputLabel: {
498
+ color: theme.onSurface,
499
+ fontSize: 13,
500
+ fontFamily: "DinMedium",
501
+ marginBottom: 6,
502
+ },
503
+ input: {
504
+ backgroundColor: theme.background,
505
+ paddingHorizontal: 16,
506
+ paddingVertical: 10,
507
+ borderRadius: 8,
508
+ borderWidth: 1,
509
+ borderColor: theme.surfaceVariant,
510
+ color: theme.onSurface,
511
+ fontSize: 15,
512
+ fontFamily: "DinBold",
513
+ textAlign: "center",
514
+ },
321
515
  });
322
516
 
323
- export default RangeSlider;
517
+ export default RangeSlider;
@@ -1,14 +1,16 @@
1
1
  import React from "react";
2
2
  import { I18nManager, StyleSheet, Text, View } from "react-native";
3
3
  import Animated, {
4
- SharedValue,
5
- useAnimatedStyle,
6
- useDerivedValue,
7
- useSharedValue,
4
+ SharedValue,
5
+ useAnimatedStyle,
6
+ useDerivedValue,
7
+ useSharedValue,
8
8
  } from "react-native-reanimated";
9
9
  import { ThemeType, useTheme } from "../../theme";
10
10
 
11
11
  const LABEL_HEIGHT = 26;
12
+ const LABEL_PADDING = 8;
13
+ const MIN_GAP = 4;
12
14
 
13
15
  interface SliderLabelsProps {
14
16
  leftValue: string;
@@ -17,51 +19,100 @@ interface SliderLabelsProps {
17
19
  rightPosition: SharedValue<number>;
18
20
  sliderWidth: number;
19
21
  thumbSize: number;
20
- theme?: ThemeType
22
+ theme?: ThemeType;
21
23
  }
22
24
 
23
- interface CenteredLabelProps {
25
+ interface SingleLabelProps {
24
26
  value: string;
25
27
  position: SharedValue<number>;
26
28
  sliderWidth: number;
27
- thumbSize: number;
28
- theme?: ThemeType
29
+ onWidthChange: (width: number) => void;
30
+ isVisible: SharedValue<boolean>;
31
+ theme: ThemeType;
32
+ }
29
33
 
34
+ interface MergedLabelProps {
35
+ leftValue: string;
36
+ rightValue: string;
37
+ leftPosition: SharedValue<number>;
38
+ rightPosition: SharedValue<number>;
39
+ sliderWidth: number;
40
+ isVisible: SharedValue<boolean>;
41
+ theme: ThemeType;
30
42
  }
31
43
 
32
- const CenteredLabel: React.FC<CenteredLabelProps> = ({
44
+ const SingleLabel: React.FC<SingleLabelProps> = ({
33
45
  value,
34
46
  position,
35
47
  sliderWidth,
36
- thumbSize,
37
- theme
48
+ onWidthChange,
49
+ isVisible,
50
+ theme,
38
51
  }) => {
39
- const labelWidth = useSharedValue(0);
40
- const {theme: defaultTheme} = useTheme();
41
- const currTheme = theme || defaultTheme;
42
- const styles = getStyles(currTheme);
52
+ const styles = getStyles(theme);
53
+ const localWidth = useSharedValue(0);
43
54
 
44
- const animatedLabelStyle = useAnimatedStyle(() => {
45
- const rawCenter = position.value + thumbSize / 2;
46
- const shifted = rawCenter - labelWidth.value / 2;
55
+ const animatedStyle = useAnimatedStyle(() => {
56
+ const halfLabel = localWidth.value / 2;
57
+ const rawCenter = position.value;
58
+ const shifted = rawCenter - halfLabel;
59
+ const left = Math.min(Math.max(shifted, 0), sliderWidth - localWidth.value);
47
60
 
61
+ return {
62
+ left,
63
+ opacity: isVisible.value ? 1 : 0,
64
+ };
65
+ });
66
+
67
+ return (
68
+ <Animated.View
69
+ style={[styles.labelContainer, animatedStyle]}
70
+ onLayout={(e) => {
71
+ const width = e.nativeEvent.layout.width;
72
+ localWidth.value = width;
73
+ onWidthChange(width);
74
+ }}
75
+ >
76
+ <Text style={styles.labelText}>{value}</Text>
77
+ </Animated.View>
78
+ );
79
+ };
80
+
81
+ const MergedLabel: React.FC<MergedLabelProps> = ({
82
+ leftValue,
83
+ rightValue,
84
+ leftPosition,
85
+ rightPosition,
86
+ sliderWidth,
87
+ isVisible,
88
+ theme,
89
+ }) => {
90
+ const styles = getStyles(theme);
91
+ const labelWidth = useSharedValue(0);
92
+
93
+ const animatedStyle = useAnimatedStyle(() => {
94
+ const centerPosition = (leftPosition.value + rightPosition.value) / 2;
95
+ const halfLabel = labelWidth.value / 2;
96
+ const shifted = centerPosition - halfLabel;
48
97
  const left = Math.min(Math.max(shifted, 0), sliderWidth - labelWidth.value);
49
98
 
50
99
  return {
51
- left: left,
100
+ left,
101
+ opacity: isVisible.value ? 1 : 0,
52
102
  };
53
103
  });
54
104
 
105
+ const displayText =
106
+ leftValue === rightValue ? leftValue : `${leftValue} - ${rightValue}`;
107
+
55
108
  return (
56
109
  <Animated.View
57
- style={[styles.labelContainer, animatedLabelStyle]}
110
+ style={[styles.labelContainer, animatedStyle]}
58
111
  onLayout={(e) => {
59
112
  labelWidth.value = e.nativeEvent.layout.width;
60
113
  }}
61
114
  >
62
- <Text style={styles.labelText}>
63
- {value}
64
- </Text>
115
+ <Text style={styles.labelText}>{displayText}</Text>
65
116
  </Animated.View>
66
117
  );
67
118
  };
@@ -77,29 +128,62 @@ export const SliderLabels: React.FC<SliderLabelsProps> = ({
77
128
  }) => {
78
129
  const { theme: defaultTheme } = useTheme();
79
130
  const currTheme = theme || defaultTheme;
80
- const styles = getStyles(currTheme);
81
- const rightThumbLeftPosition = useDerivedValue(() => {
82
- return rightPosition.value - thumbSize;
83
- });
84
- const leftThumbLeftPosition = useDerivedValue(() => {
85
- return leftPosition.value - thumbSize;
131
+ const isRTL = I18nManager.isRTL;
132
+
133
+ // Track label widths in parent for overlap calculation
134
+ const leftLabelWidth = useSharedValue(0);
135
+ const rightLabelWidth = useSharedValue(0);
136
+
137
+ const shouldMerge = useDerivedValue(() => {
138
+ const leftCenter = leftPosition.value;
139
+ const rightCenter = rightPosition.value;
140
+
141
+ const leftEnd = leftCenter + leftLabelWidth.value / 2;
142
+ const rightStart = rightCenter - rightLabelWidth.value / 2;
143
+
144
+ if (isRTL) {
145
+ const rtlLeftEnd = rightCenter + rightLabelWidth.value / 2;
146
+ const rtlRightStart = leftCenter - leftLabelWidth.value / 2;
147
+ return rtlRightStart - rtlLeftEnd < MIN_GAP;
148
+ }
149
+
150
+ return rightStart - leftEnd < MIN_GAP;
86
151
  });
87
152
 
88
- const isRTL = I18nManager.isRTL;
153
+ const showSeparate = useDerivedValue(() => !shouldMerge.value);
154
+ const showMerged = useDerivedValue(() => shouldMerge.value);
89
155
 
90
156
  return (
91
- <View style={styles.wrapper} pointerEvents="none">
92
- <CenteredLabel
157
+ <View style={getStyles(currTheme).wrapper} pointerEvents="none">
158
+ <SingleLabel
93
159
  value={leftValue}
94
- thumbSize={thumbSize}
95
- position={isRTL ? leftThumbLeftPosition : leftPosition}
160
+ position={leftPosition}
96
161
  sliderWidth={sliderWidth}
162
+ onWidthChange={(width) => {
163
+ leftLabelWidth.value = width;
164
+ }}
165
+ isVisible={showSeparate}
166
+ theme={currTheme}
97
167
  />
98
- <CenteredLabel
168
+ <SingleLabel
99
169
  value={rightValue}
100
- thumbSize={thumbSize}
101
- position={isRTL ? rightPosition : rightThumbLeftPosition}
170
+ position={rightPosition}
171
+ sliderWidth={sliderWidth}
172
+ onWidthChange={(width) => {
173
+ rightLabelWidth.value = width;
174
+ }}
175
+ isVisible={showSeparate}
176
+ theme={currTheme}
177
+ />
178
+
179
+ <MergedLabel
180
+ leftValue={leftValue}
181
+ rightValue={rightValue}
182
+ leftPosition={leftPosition}
183
+ rightPosition={rightPosition}
102
184
  sliderWidth={sliderWidth}
185
+ isVisible={showMerged}
186
+ theme={currTheme}
103
187
  />
104
188
  </View>
105
189
  );
@@ -119,7 +203,7 @@ const getStyles = (theme: ThemeType) =>
119
203
  },
120
204
  labelText: {
121
205
  backgroundColor: theme.surface,
122
- paddingHorizontal: 8,
206
+ paddingHorizontal: LABEL_PADDING,
123
207
  paddingVertical: 4,
124
208
  borderRadius: 4,
125
209
  color: theme.onSurface,