related-ui-components 1.6.5 → 1.6.6

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.
@@ -1,479 +1,492 @@
1
- import React, { useCallback, useEffect, useRef, useState } from "react";
2
- import {
3
- View,
4
- Text,
5
- StyleSheet,
6
- TouchableOpacity,
7
- TextStyle,
8
- ViewStyle,
9
- ImageSourcePropType,
10
- I18nManager,
11
- TouchableWithoutFeedback,
12
- } from "react-native";
13
- import { GestureHandlerRootView } from "react-native-gesture-handler";
14
- import BottomSheet, { BottomSheetView } from "@gorhom/bottom-sheet";
15
- import PointsRangeSelector from "./PointsRangeSelector";
16
- import { BrandIcon } from "../BrandIcon";
17
- import { Ionicons } from "@expo/vector-icons";
18
- import Checkbox from "expo-checkbox";
19
- import { useTheme, ThemeType } from "../../theme"; // Import ThemeType
1
+ import React, { useCallback, useEffect, useRef, useState } from "react";
2
+ import {
3
+ View,
4
+ Text,
5
+ StyleSheet,
6
+ TouchableOpacity,
7
+ TextStyle,
8
+ ViewStyle,
9
+ ImageSourcePropType,
10
+ I18nManager,
11
+ // Remove TouchableWithoutFeedback as it's no longer needed for the overlay
12
+ } from "react-native";
13
+ import { GestureHandlerRootView } from "react-native-gesture-handler";
14
+ import BottomSheet, {
15
+ BottomSheetView,
16
+ BottomSheetBackdrop, // Import BottomSheetBackdrop
17
+ BottomSheetBackdropProps, // Import props type for type safety
18
+ } from "@gorhom/bottom-sheet";
19
+ import PointsRangeSelector from "./PointsRangeSelector";
20
+ import { BrandIcon } from "../BrandIcon";
21
+ import { Ionicons } from "@expo/vector-icons";
22
+ import Checkbox from "expo-checkbox";
23
+ import { useTheme, ThemeType } from "../../theme"; // Import ThemeType
20
24
 
21
- type SortOption = {
22
- name: string;
23
- value: string;
24
- id: number;
25
- checked?: boolean;
26
- };
27
- export type Brand = {
28
- id: string;
29
- name: string;
30
- logo: ImageSourcePropType;
31
- checked?: boolean;
32
- };
33
- export type FilterResult = {
34
- sort: SortOption | undefined;
35
- pointsRange: { min: number; max: number };
36
- selectedBrands: Brand[];
37
- };
38
- interface FiltersProps {
39
- isRTL?: boolean;
40
- sortOptions?: SortOption[];
41
- sortSectionTitle?: string;
42
- sectionTitleStyle?: TextStyle;
43
- sortSectionStyle?: ViewStyle;
44
- rangeMinLimit?: number;
45
- rangeMaxLimit?: number;
46
- rangeInitialMin?: number;
47
- rangeInitialMax?: number;
48
- showPointsRange?: boolean;
49
- pointsRangeSectionTitle?: string;
50
- pointsRangeContainerStyle?: ViewStyle;
51
- pointsRangeInputsContainerStyle?: ViewStyle;
52
- pointsRangeCustomInputContainerStyle?: ViewStyle;
53
- pointsRangeCustomInputFieldStyle?: ViewStyle;
54
- pointsRangeSliderContainerStyle?: ViewStyle;
55
- pointsRangeMultiSliderContainerStyle?: ViewStyle;
56
- pointsRangeTrackStyle?: ViewStyle;
57
- pointsRangeSelectedTrackStyle?: ViewStyle;
58
- pointsRangeUnselectedTrackStyle?: ViewStyle;
59
- pointsRangeMarkerStyle?: ViewStyle;
60
- pointsRangeMarkerEnabledStyle?: ViewStyle;
61
- pointsRangeMarkerDisabledStyle?: ViewStyle;
62
- pointsRangeMarkerDotStyle?: ViewStyle;
63
- pointsRangeInputProps?: any;
64
- pointsRangeMultiSliderProps?: any;
65
- brands?: Brand[];
66
- brandContainerStyle?: ViewStyle;
67
- brandActiveIcon?: React.ReactNode;
68
- brandActiveIconStyle?: ViewStyle;
69
- brandSectionTile?: string;
70
- onActionButtonPress?: (result: FilterResult) => void;
71
- containerStyle?: ViewStyle;
72
- headerStyle?: ViewStyle;
73
- titleStyle?: TextStyle;
74
- resetTextStyle?: TextStyle;
75
- sectionStyle?: ViewStyle;
76
- optionRowStyle?: ViewStyle;
77
- optionTextStyle?: TextStyle;
78
- checkboxColor?: string;
79
- applyButtonStyle?: ViewStyle;
80
- applyButtonTextStyle?: TextStyle;
81
- bottomSheetStyle?: ViewStyle;
82
- headerTitleText?: string;
83
- headerResetText?: string;
84
- bottomSheetIndex?: number;
85
- snapPoints?: string[];
86
- handleIndicatorStyle?: ViewStyle;
87
- applyButtonText?: string;
88
- overlayColor?: string;
89
- onClose?: () => void;
90
- visible?: boolean;
91
- }
25
+ // ... (Keep existing type definitions: SortOption, Brand, FilterResult) ...
26
+ type SortOption = {
27
+ name: string;
28
+ value: string;
29
+ id: number;
30
+ checked?: boolean;
31
+ };
32
+ export type Brand = {
33
+ id: string;
34
+ name: string;
35
+ logo: ImageSourcePropType;
36
+ checked?: boolean;
37
+ };
38
+ export type FilterResult = {
39
+ sort: SortOption | undefined;
40
+ pointsRange: { min: number; max: number };
41
+ selectedBrands: Brand[];
42
+ };
92
43
 
93
- const Filters: React.FC<FiltersProps> = ({
94
- isRTL = I18nManager.isRTL,
95
- sortOptions = [],
96
- sortSectionTitle = "Sort",
97
- sectionTitleStyle,
98
- sortSectionStyle,
99
- onActionButtonPress,
100
- rangeInitialMax = 1000,
101
- rangeInitialMin = 0,
102
- rangeMaxLimit = 1000,
103
- rangeMinLimit = 0,
104
- pointsRangeContainerStyle,
105
- pointsRangeInputsContainerStyle,
106
- pointsRangeCustomInputContainerStyle,
107
- pointsRangeCustomInputFieldStyle,
108
- pointsRangeSliderContainerStyle,
109
- pointsRangeMultiSliderContainerStyle,
110
- pointsRangeTrackStyle,
111
- pointsRangeSelectedTrackStyle,
112
- pointsRangeUnselectedTrackStyle,
113
- pointsRangeMarkerStyle,
114
- pointsRangeMarkerEnabledStyle,
115
- pointsRangeMarkerDisabledStyle,
116
- pointsRangeMarkerDotStyle,
117
- pointsRangeInputProps,
118
- pointsRangeMultiSliderProps,
119
- containerStyle,
120
- headerStyle,
121
- titleStyle,
122
- resetTextStyle,
123
- sectionStyle,
124
- optionRowStyle,
125
- optionTextStyle,
126
- checkboxColor: checkboxColorProp,
127
- applyButtonStyle,
128
- applyButtonTextStyle,
129
- bottomSheetStyle,
130
- bottomSheetIndex = 0,
131
- snapPoints = ["50%", "90%"],
132
- handleIndicatorStyle,
133
- brands = [],
134
- brandContainerStyle,
135
- brandActiveIcon,
136
- showPointsRange = true,
137
- pointsRangeSectionTitle = "Points range",
138
- brandActiveIconStyle,
139
- brandSectionTile = "Brands",
140
- applyButtonText = "Apply Filter",
141
- headerResetText = "Reset All",
142
- headerTitleText = "Filter",
143
- overlayColor = "rgba(0, 0, 0, 0.5)",
144
- onClose,
145
- visible = true,
146
- }) => {
147
- const {theme, isRTL : rtl} = useTheme();
148
- isRTL = rtl || isRTL;
149
- const bottomSheetRef = useRef<BottomSheet>(null);
150
- const styles = createStyles(theme, isRTL);
151
- const checkboxColor = checkboxColorProp ?? theme.primary;
152
- const [isVisible, setIsVisible] = useState(visible);
44
+ interface FiltersProps {
45
+ isRTL?: boolean;
46
+ sortOptions?: SortOption[];
47
+ sortSectionTitle?: string;
48
+ sectionTitleStyle?: TextStyle;
49
+ sortSectionStyle?: ViewStyle;
50
+ rangeMinLimit?: number;
51
+ rangeMaxLimit?: number;
52
+ rangeInitialMin?: number;
53
+ rangeInitialMax?: number;
54
+ showPointsRange?: boolean;
55
+ pointsRangeSectionTitle?: string;
56
+ pointsRangeContainerStyle?: ViewStyle;
57
+ pointsRangeInputsContainerStyle?: ViewStyle;
58
+ pointsRangeCustomInputContainerStyle?: ViewStyle;
59
+ pointsRangeCustomInputFieldStyle?: ViewStyle;
60
+ pointsRangeSliderContainerStyle?: ViewStyle;
61
+ pointsRangeMultiSliderContainerStyle?: ViewStyle;
62
+ pointsRangeTrackStyle?: ViewStyle;
63
+ pointsRangeSelectedTrackStyle?: ViewStyle;
64
+ pointsRangeUnselectedTrackStyle?: ViewStyle;
65
+ pointsRangeMarkerStyle?: ViewStyle;
66
+ pointsRangeMarkerEnabledStyle?: ViewStyle;
67
+ pointsRangeMarkerDisabledStyle?: ViewStyle;
68
+ pointsRangeMarkerDotStyle?: ViewStyle;
69
+ pointsRangeInputProps?: any;
70
+ pointsRangeMultiSliderProps?: any;
71
+ brands?: Brand[];
72
+ brandContainerStyle?: ViewStyle;
73
+ brandActiveIcon?: React.ReactNode;
74
+ brandActiveIconStyle?: ViewStyle;
75
+ brandSectionTile?: string;
76
+ onActionButtonPress?: (result: FilterResult) => void;
77
+ containerStyle?: ViewStyle;
78
+ headerStyle?: ViewStyle;
79
+ titleStyle?: TextStyle;
80
+ resetTextStyle?: TextStyle;
81
+ sectionStyle?: ViewStyle;
82
+ optionRowStyle?: ViewStyle;
83
+ optionTextStyle?: TextStyle;
84
+ checkboxColor?: string;
85
+ applyButtonStyle?: ViewStyle;
86
+ applyButtonTextStyle?: TextStyle;
87
+ bottomSheetStyle?: ViewStyle;
88
+ headerTitleText?: string;
89
+ headerResetText?: string;
90
+ bottomSheetIndex?: number;
91
+ snapPoints?: string[];
92
+ handleIndicatorStyle?: ViewStyle;
93
+ applyButtonText?: string;
94
+ overlayColor?: string;
95
+ onClose?: () => void;
96
+ visible?: boolean;
97
+ }
153
98
 
154
- // Sync the internal isVisible state with the visible prop
155
- useEffect(() => {
156
- setIsVisible(visible);
157
- if (visible && bottomSheetRef.current) {
158
- bottomSheetRef.current.snapToIndex(0);
159
- }
160
- }, [visible]);
99
+ const Filters: React.FC<FiltersProps> = ({
100
+ isRTL: isRTLProp,
101
+ sortOptions = [],
102
+ sortSectionTitle = "Sort",
103
+ sectionTitleStyle,
104
+ sortSectionStyle,
105
+ onActionButtonPress,
106
+ rangeInitialMax = 1000,
107
+ rangeInitialMin = 0,
108
+ rangeMaxLimit = 1000,
109
+ rangeMinLimit = 0,
110
+ pointsRangeContainerStyle,
111
+ pointsRangeInputsContainerStyle,
112
+ pointsRangeCustomInputContainerStyle,
113
+ pointsRangeCustomInputFieldStyle,
114
+ pointsRangeSliderContainerStyle,
115
+ pointsRangeMultiSliderContainerStyle,
116
+ pointsRangeTrackStyle,
117
+ pointsRangeSelectedTrackStyle,
118
+ pointsRangeUnselectedTrackStyle,
119
+ pointsRangeMarkerStyle,
120
+ pointsRangeMarkerEnabledStyle,
121
+ pointsRangeMarkerDisabledStyle,
122
+ pointsRangeMarkerDotStyle,
123
+ pointsRangeInputProps,
124
+ pointsRangeMultiSliderProps,
125
+ containerStyle,
126
+ headerStyle,
127
+ titleStyle,
128
+ resetTextStyle,
129
+ sectionStyle,
130
+ optionRowStyle,
131
+ optionTextStyle,
132
+ checkboxColor: checkboxColorProp,
133
+ applyButtonStyle,
134
+ applyButtonTextStyle,
135
+ bottomSheetStyle,
136
+ bottomSheetIndex = 0,
137
+ snapPoints = ["50%", "90%"],
138
+ handleIndicatorStyle,
139
+ brands = [],
140
+ brandContainerStyle,
141
+ brandActiveIcon,
142
+ showPointsRange = true,
143
+ pointsRangeSectionTitle = "Points range",
144
+ brandActiveIconStyle,
145
+ brandSectionTile = "Brands",
146
+ applyButtonText = "Apply Filter",
147
+ headerResetText = "Reset All",
148
+ headerTitleText = "Filter",
149
+ onClose,
150
+ visible = true,
151
+ }) => {
152
+ const { theme, isRTL: themeIsRTL } = useTheme();
153
+ const isRTL = isRTLProp ?? themeIsRTL ?? I18nManager.isRTL;
154
+ const bottomSheetRef = useRef<BottomSheet>(null);
155
+ const styles = createStyles(theme, isRTL);
156
+ const checkboxColor = checkboxColorProp ?? theme.primary;
157
+ const [isVisible, setIsVisible] = useState(visible);
158
+
159
+ useEffect(() => {
160
+ if (visible) {
161
+ setIsVisible(true);
162
+ setTimeout(() => bottomSheetRef.current?.snapToIndex(bottomSheetIndex), 0);
163
+ } else {
164
+ bottomSheetRef.current?.close();
165
+ setIsVisible(false);
166
+ }
167
+ }, [visible, bottomSheetIndex]);
161
168
 
162
- const handleSheetChanges = useCallback((index: number) => {
169
+ const handleSheetChanges = useCallback(
170
+ (index: number) => {
163
171
  if (index === -1) {
164
172
  setIsVisible(false);
173
+ if (onClose) {
174
+ onClose();
175
+ }
165
176
  }
166
- }, []);
167
-
168
- const [resetCounter, setResetCounter] = useState(0);
177
+ },
178
+ [onClose]
179
+ );
169
180
 
181
+ const [resetCounter, setResetCounter] = useState(0);
170
182
 
171
- const [checkedItem, setCheckedItem] = useState<number | null>(
172
- sortOptions.find(option => option.checked)?.id || null
173
- );
183
+ const [checkedItem, setCheckedItem] = useState<number | null>(
184
+ sortOptions.find((option) => option.checked)?.id || null
185
+ );
174
186
 
175
- const [selectedBrands, setSelectedBrands] = useState<Record<string, boolean>>(
176
- brands.reduce((acc, option) => {
177
- acc[option.id] = option.checked || false;
178
- return acc;
179
- }, {} as Record<string, boolean>)
180
- );
181
- const [pointsRange, setPointsRange] = useState<{ min: number; max: number }>({
187
+ const [selectedBrands, setSelectedBrands] = useState<
188
+ Record<string, boolean>
189
+ >(
190
+ brands.reduce((acc, option) => {
191
+ acc[option.id] = option.checked || false;
192
+ return acc;
193
+ }, {} as Record<string, boolean>)
194
+ );
195
+ const [pointsRange, setPointsRange] = useState<{ min: number; max: number }>(
196
+ {
182
197
  min: rangeInitialMin,
183
198
  max: rangeInitialMax,
184
- });
199
+ }
200
+ );
185
201
 
186
- const handleCheckboxChange = (id: number) => {
187
- setCheckedItem(id);
188
- };
202
+ const handleCheckboxChange = (id: number) => {
203
+ setCheckedItem(id);
204
+ };
189
205
 
190
- const handleBrandSelect = (id: string) => {
191
- setSelectedBrands((prevState) => ({
192
- ...prevState,
193
- [id]: !prevState[id],
194
- }));
195
- };
206
+ const handleBrandSelect = (id: string) => {
207
+ setSelectedBrands((prevState) => ({
208
+ ...prevState,
209
+ [id]: !prevState[id],
210
+ }));
211
+ };
196
212
 
197
- const handleApplyFilter = () => {
198
- if (onActionButtonPress) {
199
- const selectedSortOption = sortOptions.find(
200
- (option) => option.id == checkedItem
201
- );
213
+ const closeBottomSheet = useCallback(() => {
214
+ bottomSheetRef.current?.close();
215
+ }, [/* onClose */]);
202
216
 
203
- const selectedBrandsList = brands.filter(
204
- (brand) => selectedBrands[brand.id]
205
- );
217
+ const handleApplyFilter = () => {
218
+ if (onActionButtonPress) {
219
+ const selectedSortOption = sortOptions.find(
220
+ (option) => option.id == checkedItem
221
+ );
206
222
 
207
- const filterResult: FilterResult = {
208
- sort: selectedSortOption,
209
- pointsRange: pointsRange,
210
- selectedBrands: selectedBrandsList,
211
- };
223
+ const selectedBrandsList = brands.filter(
224
+ (brand) => selectedBrands[brand.id]
225
+ );
212
226
 
213
- onActionButtonPress(filterResult);
214
- closeBottomSheet(); // Close the filter after applying
215
- }
216
- };
227
+ const filterResult: FilterResult = {
228
+ sort: selectedSortOption,
229
+ pointsRange: pointsRange,
230
+ selectedBrands: selectedBrandsList,
231
+ };
217
232
 
218
- const handleResetAll = () => {
219
- const resetBrands = brands.reduce((acc, option) => {
220
- acc[option.id] = false;
221
- return acc;
222
- }, {} as Record<string, boolean>);
233
+ onActionButtonPress(filterResult);
234
+ }
235
+ closeBottomSheet();
236
+ };
223
237
 
224
- setCheckedItem(null);
225
- setSelectedBrands(resetBrands);
226
- setPointsRange({ min: rangeMinLimit, max: rangeInitialMax });
227
- setResetCounter((prev) => prev + 1);
228
- };
238
+ const handleResetAll = () => {
239
+ const resetBrands = brands.reduce((acc, option) => {
240
+ acc[option.id] = false;
241
+ return acc;
242
+ }, {} as Record<string, boolean>);
229
243
 
230
- const closeBottomSheet = useCallback(() => {
231
- if (bottomSheetRef.current) {
232
- bottomSheetRef.current.close();
233
- }
234
- setIsVisible(false);
235
- if (onClose) {
236
- onClose();
237
- }
238
- }, [onClose]);
244
+ setCheckedItem(null);
245
+ setSelectedBrands(resetBrands);
246
+ setPointsRange({ min: rangeMinLimit, max: rangeInitialMax });
247
+ setResetCounter((prev) => prev + 1);
248
+ };
239
249
 
240
- // If not visible, don't render anything
241
- if (!isVisible) {
242
- return null;
243
- }
250
+ const renderBackdrop = useCallback(
251
+ (props: BottomSheetBackdropProps) => (
252
+ <BottomSheetBackdrop
253
+ {...props}
254
+ appearsOnIndex={0}
255
+ disappearsOnIndex={-1}
256
+ pressBehavior="close"
257
+ opacity={0.5}
258
+ />
259
+ ),
260
+ []
261
+ );
262
+
263
+ if (!visible) {
264
+ return null;
265
+ }
244
266
 
245
- return (
246
- <GestureHandlerRootView style={styles.overlayContainer}>
247
- {/* Semi-transparent overlay */}
248
- <TouchableWithoutFeedback onPress={closeBottomSheet}>
249
- <View style={[styles.overlay, { backgroundColor: overlayColor }]} />
250
- </TouchableWithoutFeedback>
251
-
252
- <BottomSheet
253
- ref={bottomSheetRef}
254
- index={bottomSheetIndex}
255
- handleComponent={() => null}
256
- onChange={handleSheetChanges}
257
- style={bottomSheetStyle}
258
- backgroundStyle={{ backgroundColor: theme.surface }}
259
- handleIndicatorStyle={[styles.handleIndicator, handleIndicatorStyle]}
260
- // snapPoints={snapPoints}
261
- enablePanDownToClose={true}
262
- onClose={() => {
263
- setIsVisible(false);
264
- if (onClose) onClose();
265
- }}
266
- >
267
- <View style={[styles.container, containerStyle]}>
268
- <View style={[styles.header, headerStyle]}>
269
- <Text style={[styles.title, titleStyle]}>{headerTitleText}</Text>
270
- <TouchableOpacity onPress={handleResetAll}>
271
- <Text style={[styles.resetText, resetTextStyle]}>
272
- {headerResetText}
267
+ return (
268
+ <GestureHandlerRootView style={styles.gestureHandlerRoot}>
269
+ <BottomSheet
270
+ ref={bottomSheetRef}
271
+ index={isVisible ? bottomSheetIndex : -1}
272
+ snapPoints={snapPoints}
273
+ onChange={handleSheetChanges}
274
+ handleComponent={() => null}
275
+ style={bottomSheetStyle}
276
+ backgroundStyle={{ backgroundColor: theme.surface }}
277
+ handleIndicatorStyle={[styles.handleIndicator, handleIndicatorStyle]}
278
+ enablePanDownToClose={true}
279
+ backdropComponent={renderBackdrop}
280
+ >
281
+ <View style={[styles.container, containerStyle]}>
282
+ <View style={[styles.header, headerStyle]}>
283
+ <Text style={[styles.title, titleStyle]}>{headerTitleText}</Text>
284
+ <TouchableOpacity onPress={handleResetAll}>
285
+ <Text style={[styles.resetText, resetTextStyle]}>
286
+ {headerResetText}
287
+ </Text>
288
+ </TouchableOpacity>
289
+ </View>
290
+ <BottomSheetView style={{ paddingBottom: 75 }}>
291
+ {sortOptions && sortOptions.length > 0 && (
292
+ <View style={[styles.section, sectionStyle, sortSectionStyle]}>
293
+ <Text style={[styles.sectionTitle, sectionTitleStyle]}>
294
+ {sortSectionTitle}
273
295
  </Text>
274
- </TouchableOpacity>
275
- </View>
276
- <BottomSheetView style={{ paddingBottom: 75 }}>
277
- {sortOptions && sortOptions.length > 0 && (
278
- <View style={[styles.section, sectionStyle, sortSectionStyle]}>
279
- <Text style={[styles.sectionTitle, sectionTitleStyle]}>
280
- {sortSectionTitle}
281
- </Text>
282
- {sortOptions.map((option) => (
283
- <View
284
- style={[styles.optionRow, optionRowStyle]}
285
- key={option.id}
286
- >
287
- <Checkbox
288
- value={option.id == checkedItem}
289
- color={checkboxColor}
290
- hitSlop={{ top: 10, right: 10, bottom: 10, left: 10 }}
291
- onValueChange={() =>
292
- handleCheckboxChange(option.id)
293
- }
294
- />
295
- <Text style={[styles.optionText, optionTextStyle]}>
296
- {option.name}
297
- </Text>
298
- </View>
299
- ))}
300
- </View>
301
- )}
296
+ {sortOptions.map((option) => (
297
+ <View
298
+ style={[styles.optionRow, optionRowStyle]}
299
+ key={option.id}
300
+ >
301
+ <Checkbox
302
+ value={option.id == checkedItem}
303
+ color={checkboxColor}
304
+ hitSlop={{ top: 10, right: 10, bottom: 10, left: 10 }}
305
+ onValueChange={() => handleCheckboxChange(option.id)}
306
+ />
307
+ <Text style={[styles.optionText, optionTextStyle]}>
308
+ {option.name}
309
+ </Text>
310
+ </View>
311
+ ))}
312
+ </View>
313
+ )}
302
314
 
303
- {showPointsRange && (
304
- <View style={[styles.section, sectionStyle]}>
305
- <Text style={[styles.sectionTitle, sectionTitleStyle]}>
306
- {pointsRangeSectionTitle}
307
- </Text>
308
- <PointsRangeSelector
309
- resetKey={resetCounter}
310
- initialMax={rangeInitialMax}
311
- initialMin={rangeInitialMin}
312
- minLimit={rangeMinLimit}
313
- maxLimit={rangeMaxLimit}
314
- isRTL={isRTL}
315
- containerStyle={pointsRangeContainerStyle}
316
- inputsContainerStyle={pointsRangeInputsContainerStyle}
317
- customInputContainerStyle={
318
- pointsRangeCustomInputContainerStyle
319
- }
320
- customInputFieldStyle={pointsRangeCustomInputFieldStyle}
321
- sliderContainerStyle={pointsRangeSliderContainerStyle}
322
- multiSliderContainerStyle={
323
- pointsRangeMultiSliderContainerStyle
324
- }
325
- trackStyle={pointsRangeTrackStyle}
326
- selectedTrackStyle={pointsRangeSelectedTrackStyle}
327
- unselectedTrackStyle={pointsRangeUnselectedTrackStyle}
328
- markerStyle={pointsRangeMarkerStyle}
329
- markerEnabledStyle={pointsRangeMarkerEnabledStyle}
330
- markerDisabledStyle={pointsRangeMarkerDisabledStyle}
331
- markerDotStyle={pointsRangeMarkerDotStyle}
332
- inputProps={pointsRangeInputProps}
333
- multiSliderProps={pointsRangeMultiSliderProps}
334
- onChange={(min: number, max: number) => {
335
- setPointsRange({ min, max });
336
- }}
337
- />
338
- </View>
339
- )}
315
+ {showPointsRange && (
316
+ <View style={[styles.section, sectionStyle]}>
317
+ <Text style={[styles.sectionTitle, sectionTitleStyle]}>
318
+ {pointsRangeSectionTitle}
319
+ </Text>
320
+ <PointsRangeSelector
321
+ resetKey={resetCounter}
322
+ initialMax={rangeInitialMax}
323
+ initialMin={rangeInitialMin}
324
+ minLimit={rangeMinLimit}
325
+ maxLimit={rangeMaxLimit}
326
+ isRTL={isRTL}
327
+ containerStyle={pointsRangeContainerStyle}
328
+ inputsContainerStyle={pointsRangeInputsContainerStyle}
329
+ customInputContainerStyle={
330
+ pointsRangeCustomInputContainerStyle
331
+ }
332
+ customInputFieldStyle={pointsRangeCustomInputFieldStyle}
333
+ sliderContainerStyle={pointsRangeSliderContainerStyle}
334
+ multiSliderContainerStyle={
335
+ pointsRangeMultiSliderContainerStyle
336
+ }
337
+ trackStyle={pointsRangeTrackStyle}
338
+ selectedTrackStyle={pointsRangeSelectedTrackStyle}
339
+ unselectedTrackStyle={pointsRangeUnselectedTrackStyle}
340
+ markerStyle={pointsRangeMarkerStyle}
341
+ markerEnabledStyle={pointsRangeMarkerEnabledStyle}
342
+ markerDisabledStyle={pointsRangeMarkerDisabledStyle}
343
+ markerDotStyle={pointsRangeMarkerDotStyle}
344
+ inputProps={pointsRangeInputProps}
345
+ multiSliderProps={pointsRangeMultiSliderProps}
346
+ onChange={(min: number, max: number) => {
347
+ setPointsRange({ min, max });
348
+ }}
349
+ />
350
+ </View>
351
+ )}
340
352
 
341
- {brands && brands.length > 0 && (
342
- <View style={[styles.section, sectionStyle]}>
343
- <Text style={[styles.sectionTitle, sectionTitleStyle]}>
344
- {brandSectionTile}
345
- </Text>
346
- <View style={[styles.brandsGrid, brandContainerStyle]}>
347
- {brands.map((brand) => (
348
- <BrandIcon
349
- key={brand.id}
350
- size={50}
351
- selected={selectedBrands[brand.id]}
352
- onPress={() => handleBrandSelect(brand.id.toString())}
353
- brand={{
354
- id: brand.id,
355
- name: brand.name,
356
- logo: brand.logo,
357
- }}
358
- selectionIndicatorIcon={
359
- brandActiveIcon || (
360
- <Ionicons
361
- name="checkmark-outline"
362
- color={theme.onPrimary}
363
- />
364
- )
365
- }
366
- selectionIndicatorStyle={brandActiveIconStyle}
367
- />
368
- ))}
369
- </View>
353
+ {brands && brands.length > 0 && (
354
+ <View style={[styles.section, sectionStyle]}>
355
+ <Text style={[styles.sectionTitle, sectionTitleStyle]}>
356
+ {brandSectionTile}
357
+ </Text>
358
+ <View style={[styles.brandsGrid, brandContainerStyle]}>
359
+ {brands.map((brand) => (
360
+ <BrandIcon
361
+ key={brand.id}
362
+ size={50}
363
+ selected={selectedBrands[brand.id]}
364
+ onPress={() => handleBrandSelect(brand.id.toString())}
365
+ brand={{
366
+ id: brand.id,
367
+ name: brand.name,
368
+ logo: brand.logo,
369
+ }}
370
+ selectionIndicatorIcon={
371
+ brandActiveIcon || (
372
+ <Ionicons
373
+ name="checkmark-outline"
374
+ color={theme.onPrimary}
375
+ />
376
+ )
377
+ }
378
+ selectionIndicatorStyle={brandActiveIconStyle}
379
+ />
380
+ ))}
370
381
  </View>
371
- )}
382
+ </View>
383
+ )}
372
384
 
373
- <TouchableOpacity
374
- style={[styles.applyButton, applyButtonStyle]}
375
- onPress={handleApplyFilter}
376
- >
377
- <Text style={[styles.applyButtonText, applyButtonTextStyle]}>
378
- {applyButtonText}
379
- </Text>
380
- </TouchableOpacity>
381
- </BottomSheetView>
382
- </View>
383
- </BottomSheet>
384
- </GestureHandlerRootView>
385
- );
386
- };
385
+ <TouchableOpacity
386
+ style={[styles.applyButton, applyButtonStyle]}
387
+ onPress={handleApplyFilter}
388
+ >
389
+ <Text style={[styles.applyButtonText, applyButtonTextStyle]}>
390
+ {applyButtonText}
391
+ </Text>
392
+ </TouchableOpacity>
393
+ </BottomSheetView>
394
+ </View>
395
+ </BottomSheet>
396
+ </GestureHandlerRootView>
397
+ );
398
+ };
387
399
 
388
- const createStyles = (theme: ThemeType, isRTL: boolean) =>
389
- StyleSheet.create({
390
- overlayContainer: {
391
- flex: 1,
392
- position: 'absolute',
393
- top: 0,
394
- left: 0,
395
- right: 0,
396
- bottom: 0,
397
- zIndex: 1000,
398
- },
399
- overlay: {
400
- ...StyleSheet.absoluteFillObject,
401
- backgroundColor: 'rgba(0, 0, 0, 0.5)',
402
- },
403
- container: {
404
- flex: 1,
405
- paddingHorizontal: 25,
406
- backgroundColor: theme.surface,
407
- },
408
- handleIndicator: {
409
- width: 40,
410
- height: 4,
411
- backgroundColor: theme.border,
412
- alignSelf: "center",
413
- marginTop: 8,
414
- borderRadius: 2,
415
- },
416
- header: {
417
- flexDirection: isRTL ? "row-reverse" : "row",
418
- justifyContent: "space-between",
419
- alignItems: "center",
420
- paddingVertical: 15,
421
- borderBottomWidth: 1,
422
- borderBottomColor: theme.border,
423
- },
424
- title: {
425
- fontSize: 18,
426
- fontWeight: "bold",
427
- color: theme.text,
428
- textAlign: isRTL ? "right" : "left",
429
- },
430
- resetText: {
431
- fontSize: 14,
432
- color: theme.primary,
433
- fontWeight: "500",
434
- textAlign: isRTL ? "left" : "right",
435
- },
436
- section: {
437
- marginTop: 20,
438
- },
439
- sectionTitle: {
440
- fontSize: 16,
441
- fontWeight: "500",
442
- color: theme.helper,
443
- marginBottom: 15,
444
- textAlign: isRTL ? "right" : "left",
445
- },
446
- optionRow: {
447
- flexDirection: isRTL ? "row-reverse" : "row",
448
- alignItems: "center",
449
- marginBottom: 15,
450
- gap: 5,
451
- },
452
- optionText: {
453
- fontSize: 15,
454
- color: theme.text,
455
- textAlign: isRTL ? "right" : "left",
456
- marginLeft: isRTL ? 0 : 8,
457
- marginRight: isRTL ? 8 : 0,
458
- },
459
- brandsGrid: {
460
- flexDirection: "row",
461
- flexWrap: "wrap",
462
- gap: 10,
463
- justifyContent: isRTL ? "flex-end" : "flex-start",
464
- },
465
- applyButton: {
466
- backgroundColor: theme.primary,
467
- borderRadius: 30,
468
- paddingVertical: 15,
469
- alignItems: "center",
470
- marginTop: 30,
471
- },
472
- applyButtonText: {
473
- color: theme.onPrimary,
474
- fontSize: 16,
475
- fontWeight: "bold",
476
- },
477
- });
400
+ const createStyles = (theme: ThemeType, isRTL: boolean) =>
401
+ StyleSheet.create({
402
+ // overlayContainer is likely not needed anymore
403
+ // overlay: { ... }, // Removed - handled by backdropComponent
404
+ gestureHandlerRoot: {
405
+ // Style needed for GestureHandlerRootView if it needs specific layout,
406
+ // often just flex: 1 or position absolute covering the screen
407
+ position: 'absolute',
408
+ top: 0,
409
+ left: 0,
410
+ right: 0,
411
+ bottom: 0,
412
+ zIndex: 1000, // Ensure it's above other content
413
+ },
414
+ container: {
415
+ flex: 1,
416
+ paddingHorizontal: 25,
417
+ backgroundColor: theme.surface, // Background is set on BottomSheet backgroundStyle now
418
+ },
419
+ handleIndicator: {
420
+ width: 40,
421
+ height: 4,
422
+ backgroundColor: theme.border,
423
+ alignSelf: "center",
424
+ marginTop: 8,
425
+ borderRadius: 2,
426
+ },
427
+ header: {
428
+ flexDirection: isRTL ? "row-reverse" : "row",
429
+ justifyContent: "space-between",
430
+ alignItems: "center",
431
+ paddingVertical: 15,
432
+ borderBottomWidth: 1,
433
+ borderBottomColor: theme.border,
434
+ },
435
+ title: {
436
+ fontSize: 18,
437
+ fontWeight: "bold",
438
+ color: theme.text,
439
+ textAlign: isRTL ? "right" : "left",
440
+ },
441
+ resetText: {
442
+ fontSize: 14,
443
+ color: theme.primary,
444
+ fontWeight: "500",
445
+ textAlign: isRTL ? "left" : "right",
446
+ },
447
+ section: {
448
+ marginTop: 20,
449
+ },
450
+ sectionTitle: {
451
+ fontSize: 16,
452
+ fontWeight: "500",
453
+ color: theme.helper,
454
+ marginBottom: 15,
455
+ textAlign: isRTL ? "right" : "left",
456
+ },
457
+ optionRow: {
458
+ flexDirection: isRTL ? "row-reverse" : "row",
459
+ alignItems: "center",
460
+ marginBottom: 15,
461
+ gap: 5,
462
+ },
463
+ optionText: {
464
+ fontSize: 15,
465
+ color: theme.text,
466
+ textAlign: isRTL ? "right" : "left",
467
+ marginLeft: isRTL ? 0 : 8,
468
+ marginRight: isRTL ? 8 : 0,
469
+ },
470
+ brandsGrid: {
471
+ flexDirection: "row",
472
+ flexWrap: "wrap",
473
+ gap: 10,
474
+ justifyContent: isRTL ? "flex-end" : "flex-start",
475
+ },
476
+ applyButton: {
477
+ backgroundColor: theme.primary,
478
+ borderRadius: 30,
479
+ paddingVertical: 15,
480
+ alignItems: "center",
481
+ marginTop: 30,
482
+ // Consider adding marginBottom if needed, especially inside BottomSheetView
483
+ // marginBottom: 20,
484
+ },
485
+ applyButtonText: {
486
+ color: theme.onPrimary,
487
+ fontSize: 16,
488
+ fontWeight: "bold",
489
+ },
490
+ });
478
491
 
479
- export default Filters;
492
+ export default Filters;