related-ui-components 3.2.9 → 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.
- package/lib/module/components/Card/templates/SelaDealCard.js +0 -10
- package/lib/module/components/Card/templates/SelaDealCard.js.map +1 -1
- package/lib/module/components/RangeSlider/RangeSlider.js +260 -26
- package/lib/module/components/RangeSlider/RangeSlider.js.map +1 -1
- package/lib/module/components/RangeSlider/SliderLabel.js +93 -30
- package/lib/module/components/RangeSlider/SliderLabel.js.map +1 -1
- package/lib/typescript/src/components/Card/templates/SelaDealCard.d.ts.map +1 -1
- package/lib/typescript/src/components/RangeSlider/RangeSlider.d.ts +13 -0
- package/lib/typescript/src/components/RangeSlider/RangeSlider.d.ts.map +1 -1
- package/lib/typescript/src/components/RangeSlider/SliderLabel.d.ts.map +1 -1
- package/package.json +81 -81
- package/src/components/Card/templates/SelaDealCard.tsx +0 -11
- package/src/components/RangeSlider/RangeSlider.tsx +349 -50
- package/src/components/RangeSlider/SliderLabel.tsx +122 -38
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useCallback, useState } from "react";
|
|
1
|
+
import React, { useCallback, useMemo, useState } from "react";
|
|
2
2
|
import { I18nManager, StyleSheet, View } from "react-native";
|
|
3
3
|
import { Gesture, GestureDetector } from "react-native-gesture-handler";
|
|
4
4
|
import Animated, {
|
|
@@ -6,13 +6,17 @@ 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
|
|
|
18
|
+
type ScaleType = "linear" | "logarithmic" | "percentile";
|
|
19
|
+
|
|
16
20
|
interface RangeSliderProps {
|
|
17
21
|
min: number;
|
|
18
22
|
max: number;
|
|
@@ -21,8 +25,64 @@ interface RangeSliderProps {
|
|
|
21
25
|
initialMinValue: number;
|
|
22
26
|
initialMaxValue: number;
|
|
23
27
|
onValueChange: (values: { min: number; max: number }) => void;
|
|
28
|
+
theme?: ThemeType;
|
|
29
|
+
scale?: ScaleType;
|
|
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;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Creates percentile breakpoints from data
|
|
45
|
+
* Returns sorted unique values that represent the distribution
|
|
46
|
+
*/
|
|
47
|
+
function createPercentileBreakpoints(data: number[]): number[] {
|
|
48
|
+
const sorted = [...new Set(data)].sort((a, b) => a - b);
|
|
49
|
+
|
|
50
|
+
if (sorted.length <= 100) {
|
|
51
|
+
return sorted;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const breakpoints: number[] = [];
|
|
55
|
+
const numBreakpoints = 100;
|
|
24
56
|
|
|
25
|
-
|
|
57
|
+
for (let i = 0; i <= numBreakpoints; i++) {
|
|
58
|
+
const index = Math.floor((i / numBreakpoints) * (sorted.length - 1));
|
|
59
|
+
const value = sorted[index];
|
|
60
|
+
if (breakpoints[breakpoints.length - 1] !== value) {
|
|
61
|
+
breakpoints.push(value);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return breakpoints;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Binary search to find position in breakpoints
|
|
70
|
+
*/
|
|
71
|
+
function findBreakpointIndex(breakpoints: number[], value: number): number {
|
|
72
|
+
"worklet";
|
|
73
|
+
let left = 0;
|
|
74
|
+
let right = breakpoints.length - 1;
|
|
75
|
+
|
|
76
|
+
while (left < right) {
|
|
77
|
+
const mid = Math.floor((left + right) / 2);
|
|
78
|
+
if (breakpoints[mid] < value) {
|
|
79
|
+
left = mid + 1;
|
|
80
|
+
} else {
|
|
81
|
+
right = mid;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return left;
|
|
26
86
|
}
|
|
27
87
|
|
|
28
88
|
const RangeSlider: React.FC<RangeSliderProps> = ({
|
|
@@ -33,45 +93,125 @@ const RangeSlider: React.FC<RangeSliderProps> = ({
|
|
|
33
93
|
initialMinValue,
|
|
34
94
|
initialMaxValue,
|
|
35
95
|
onValueChange,
|
|
36
|
-
theme
|
|
96
|
+
theme,
|
|
97
|
+
scale = "linear",
|
|
98
|
+
dataPoints,
|
|
99
|
+
showCustomInputs = false,
|
|
100
|
+
inputPlaceholders,
|
|
101
|
+
inputLabels,
|
|
102
|
+
isBottomSheet = false,
|
|
37
103
|
}) => {
|
|
38
|
-
const { theme: defaultTheme} = useTheme();
|
|
39
|
-
|
|
104
|
+
const { theme: defaultTheme } = useTheme();
|
|
40
105
|
const currTheme = theme || defaultTheme;
|
|
41
|
-
|
|
42
106
|
const styles = getStyles(currTheme);
|
|
43
|
-
|
|
44
107
|
const isRTL = I18nManager.isRTL;
|
|
45
108
|
|
|
46
|
-
// State for label text values, passed down to the SliderLabels component
|
|
47
109
|
const [leftLabel, setLeftLabel] = useState(initialMinValue.toLocaleString());
|
|
48
110
|
const [rightLabel, setRightLabel] = useState(
|
|
49
|
-
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(),
|
|
50
120
|
);
|
|
51
121
|
|
|
122
|
+
// The effective track width (where thumb CENTER can travel)
|
|
123
|
+
const effectiveWidth = sliderWidth - THUMB_SIZE;
|
|
124
|
+
|
|
125
|
+
// Pre-compute breakpoints for percentile scale
|
|
126
|
+
const breakpoints = useMemo(() => {
|
|
127
|
+
if (scale === "percentile" && dataPoints?.length) {
|
|
128
|
+
return createPercentileBreakpoints(dataPoints);
|
|
129
|
+
}
|
|
130
|
+
return [];
|
|
131
|
+
}, [scale, dataPoints]);
|
|
132
|
+
|
|
133
|
+
const safeMin = scale === "logarithmic" ? Math.max(min, 0.001) : min;
|
|
134
|
+
|
|
52
135
|
const valueToPosition = useCallback(
|
|
53
136
|
(value: number) => {
|
|
54
137
|
"worklet";
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
138
|
+
let percentage: number;
|
|
139
|
+
|
|
140
|
+
if (scale === "percentile" && breakpoints.length > 1) {
|
|
141
|
+
const index = findBreakpointIndex(breakpoints, value);
|
|
142
|
+
|
|
143
|
+
if (index === 0) {
|
|
144
|
+
percentage = 0;
|
|
145
|
+
} else if (index >= breakpoints.length - 1) {
|
|
146
|
+
percentage = 1;
|
|
147
|
+
} else {
|
|
148
|
+
const lowerVal = breakpoints[index - 1];
|
|
149
|
+
const upperVal = breakpoints[index];
|
|
150
|
+
const lowerPct = (index - 1) / (breakpoints.length - 1);
|
|
151
|
+
const upperPct = index / (breakpoints.length - 1);
|
|
152
|
+
|
|
153
|
+
if (upperVal === lowerVal) {
|
|
154
|
+
percentage = lowerPct;
|
|
155
|
+
} else {
|
|
156
|
+
const ratio = (value - lowerVal) / (upperVal - lowerVal);
|
|
157
|
+
percentage = lowerPct + ratio * (upperPct - lowerPct);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
} else if (scale === "logarithmic") {
|
|
161
|
+
const logMin = Math.log(safeMin);
|
|
162
|
+
const logMax = Math.log(max);
|
|
163
|
+
const logValue = Math.log(Math.max(value, safeMin));
|
|
164
|
+
percentage = (logValue - logMin) / (logMax - logMin);
|
|
165
|
+
} else {
|
|
166
|
+
percentage = (value - min) / (max - min);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Map to effective width, offset by thumb radius
|
|
170
|
+
const position = percentage * effectiveWidth + THUMB_RADIUS;
|
|
171
|
+
return isRTL ? sliderWidth - position : position;
|
|
60
172
|
},
|
|
61
|
-
[min, max, sliderWidth, isRTL]
|
|
173
|
+
[min, max, safeMin, sliderWidth, effectiveWidth, isRTL, scale, breakpoints],
|
|
62
174
|
);
|
|
63
175
|
|
|
64
176
|
const positionToValue = useCallback(
|
|
65
177
|
(position: number) => {
|
|
66
178
|
"worklet";
|
|
67
|
-
//
|
|
68
|
-
const
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
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));
|
|
183
|
+
|
|
184
|
+
let rawValue: number;
|
|
185
|
+
|
|
186
|
+
if (scale === "percentile" && breakpoints.length > 1) {
|
|
187
|
+
const exactIndex = clampedPercentage * (breakpoints.length - 1);
|
|
188
|
+
const lowerIndex = Math.floor(exactIndex);
|
|
189
|
+
const upperIndex = Math.min(lowerIndex + 1, breakpoints.length - 1);
|
|
190
|
+
const ratio = exactIndex - lowerIndex;
|
|
191
|
+
rawValue =
|
|
192
|
+
breakpoints[lowerIndex] +
|
|
193
|
+
ratio * (breakpoints[upperIndex] - breakpoints[lowerIndex]);
|
|
194
|
+
} else if (scale === "logarithmic") {
|
|
195
|
+
const logMin = Math.log(safeMin);
|
|
196
|
+
const logMax = Math.log(max);
|
|
197
|
+
rawValue = Math.exp(logMin + clampedPercentage * (logMax - logMin));
|
|
198
|
+
} else {
|
|
199
|
+
rawValue = clampedPercentage * (max - min) + min;
|
|
200
|
+
}
|
|
201
|
+
|
|
72
202
|
return Math.round(rawValue / step) * step;
|
|
73
203
|
},
|
|
74
|
-
[
|
|
204
|
+
[
|
|
205
|
+
min,
|
|
206
|
+
max,
|
|
207
|
+
safeMin,
|
|
208
|
+
step,
|
|
209
|
+
sliderWidth,
|
|
210
|
+
effectiveWidth,
|
|
211
|
+
isRTL,
|
|
212
|
+
scale,
|
|
213
|
+
breakpoints,
|
|
214
|
+
],
|
|
75
215
|
);
|
|
76
216
|
|
|
77
217
|
const leftPosition = useSharedValue(valueToPosition(initialMinValue));
|
|
@@ -95,25 +235,30 @@ const RangeSlider: React.FC<RangeSliderProps> = ({
|
|
|
95
235
|
if (activeThumb.value === null) return;
|
|
96
236
|
const newPos = context.value.x + e.translationX;
|
|
97
237
|
|
|
98
|
-
// 5. Adjust clamping logic for RTL
|
|
99
238
|
if (activeThumb.value === "left") {
|
|
100
|
-
const lowerBound = isRTL
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
239
|
+
const lowerBound = isRTL
|
|
240
|
+
? rightPosition.value + THUMB_SIZE
|
|
241
|
+
: THUMB_RADIUS;
|
|
242
|
+
const upperBound = isRTL
|
|
243
|
+
? sliderWidth - THUMB_RADIUS
|
|
244
|
+
: rightPosition.value - THUMB_SIZE;
|
|
245
|
+
const clampedPos = Math.max(Math.min(newPos, upperBound), lowerBound);
|
|
106
246
|
leftPosition.value = clampedPos;
|
|
107
|
-
|
|
247
|
+
const newValue = positionToValue(clampedPos);
|
|
248
|
+
runOnJS(setLeftLabel)(newValue.toLocaleString());
|
|
249
|
+
runOnJS(setMinInputValue)(newValue.toString());
|
|
108
250
|
} else {
|
|
109
|
-
const lowerBound = isRTL
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
251
|
+
const lowerBound = isRTL
|
|
252
|
+
? THUMB_RADIUS
|
|
253
|
+
: leftPosition.value + THUMB_SIZE;
|
|
254
|
+
const upperBound = isRTL
|
|
255
|
+
? leftPosition.value - THUMB_SIZE
|
|
256
|
+
: sliderWidth - THUMB_RADIUS;
|
|
257
|
+
const clampedPos = Math.max(Math.min(newPos, upperBound), lowerBound);
|
|
115
258
|
rightPosition.value = clampedPos;
|
|
116
|
-
|
|
259
|
+
const newValue = positionToValue(clampedPos);
|
|
260
|
+
runOnJS(setRightLabel)(newValue.toLocaleString());
|
|
261
|
+
runOnJS(setMaxInputValue)(newValue.toString());
|
|
117
262
|
}
|
|
118
263
|
})
|
|
119
264
|
.onEnd(() => {
|
|
@@ -124,17 +269,102 @@ const RangeSlider: React.FC<RangeSliderProps> = ({
|
|
|
124
269
|
activeThumb.value = null;
|
|
125
270
|
});
|
|
126
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
|
+
]);
|
|
127
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
|
|
128
359
|
const animatedLeftThumbStyle = useAnimatedStyle(() => ({
|
|
129
|
-
transform: [{ translateX: leftPosition.value -
|
|
360
|
+
transform: [{ translateX: leftPosition.value - THUMB_RADIUS }],
|
|
130
361
|
}));
|
|
131
362
|
|
|
132
363
|
const animatedRightThumbStyle = useAnimatedStyle(() => ({
|
|
133
|
-
transform: [{ translateX: rightPosition.value -
|
|
364
|
+
transform: [{ translateX: rightPosition.value - THUMB_RADIUS }],
|
|
134
365
|
}));
|
|
135
366
|
|
|
136
367
|
const animatedActiveRailStyle = useAnimatedStyle(() => {
|
|
137
|
-
// 6. Use Math.min and Math.max to correctly draw the active rail in both LTR and RTL
|
|
138
368
|
const start = Math.min(leftPosition.value, rightPosition.value);
|
|
139
369
|
const end = Math.max(leftPosition.value, rightPosition.value);
|
|
140
370
|
return {
|
|
@@ -144,15 +374,53 @@ const RangeSlider: React.FC<RangeSliderProps> = ({
|
|
|
144
374
|
});
|
|
145
375
|
|
|
146
376
|
return (
|
|
147
|
-
<View
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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
|
+
)}
|
|
156
424
|
|
|
157
425
|
<GestureDetector gesture={panGesture}>
|
|
158
426
|
<View style={styles.railContainer}>
|
|
@@ -182,7 +450,10 @@ const getStyles = (theme: ThemeType) =>
|
|
|
182
450
|
height: LABEL_HEIGHT + THUMB_SIZE,
|
|
183
451
|
justifyContent: "center",
|
|
184
452
|
marginTop: LABEL_HEIGHT,
|
|
185
|
-
direction: "ltr"
|
|
453
|
+
direction: "ltr",
|
|
454
|
+
},
|
|
455
|
+
containerWithInputs: {
|
|
456
|
+
direction: "ltr",
|
|
186
457
|
},
|
|
187
458
|
railContainer: {
|
|
188
459
|
justifyContent: "center",
|
|
@@ -213,6 +484,34 @@ const getStyles = (theme: ThemeType) =>
|
|
|
213
484
|
borderColor: theme.primary,
|
|
214
485
|
borderWidth: 5,
|
|
215
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
|
+
},
|
|
216
515
|
});
|
|
217
516
|
|
|
218
517
|
export default RangeSlider;
|