related-ui-components 1.3.3 → 1.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/lib/commonjs/app.js +39 -20
  2. package/lib/commonjs/app.js.map +1 -1
  3. package/lib/commonjs/components/DateRangePicker/DateRangePicker.js +358 -0
  4. package/lib/commonjs/components/DateRangePicker/DateRangePicker.js.map +1 -0
  5. package/lib/commonjs/components/DateRangePicker/index.js +4 -0
  6. package/lib/commonjs/components/DateRangePicker/index.js.map +1 -0
  7. package/lib/commonjs/components/Filters/Filters.js +1 -1
  8. package/lib/commonjs/components/Filters/Filters.js.map +1 -1
  9. package/lib/commonjs/components/Input/Input.js +2 -2
  10. package/lib/commonjs/components/Input/Input.js.map +1 -1
  11. package/lib/commonjs/components/NumericStepper/NumericStepper.js +103 -0
  12. package/lib/commonjs/components/NumericStepper/NumericStepper.js.map +1 -0
  13. package/lib/commonjs/components/NumericStepper/index.js +29 -0
  14. package/lib/commonjs/components/NumericStepper/index.js.map +1 -0
  15. package/lib/commonjs/components/SelectAmount/SelectAmount.js +189 -0
  16. package/lib/commonjs/components/SelectAmount/SelectAmount.js.map +1 -0
  17. package/lib/commonjs/components/SelectAmount/index.js +4 -0
  18. package/lib/commonjs/components/SelectAmount/index.js.map +1 -0
  19. package/lib/commonjs/components/Suggestions/SuggestionList.js +98 -0
  20. package/lib/commonjs/components/Suggestions/SuggestionList.js.map +1 -0
  21. package/lib/commonjs/components/TravelBooking/CarRentalForm.js +370 -0
  22. package/lib/commonjs/components/TravelBooking/CarRentalForm.js.map +1 -0
  23. package/lib/commonjs/components/TravelBooking/FlightForm.js +347 -0
  24. package/lib/commonjs/components/TravelBooking/FlightForm.js.map +1 -0
  25. package/lib/commonjs/components/TravelBooking/FlightSummary.js +257 -0
  26. package/lib/commonjs/components/TravelBooking/FlightSummary.js.map +1 -0
  27. package/lib/commonjs/components/TravelBooking/HotelForm.js +290 -0
  28. package/lib/commonjs/components/TravelBooking/HotelForm.js.map +1 -0
  29. package/lib/commonjs/components/TravelBooking/HotelSummary.js +246 -0
  30. package/lib/commonjs/components/TravelBooking/HotelSummary.js.map +1 -0
  31. package/lib/commonjs/components/TravelBooking/README.md +421 -0
  32. package/lib/commonjs/components/TravelBooking/SummaryBar.js +181 -0
  33. package/lib/commonjs/components/TravelBooking/SummaryBar.js.map +1 -0
  34. package/lib/commonjs/components/TravelBooking/TabSelector.js +115 -0
  35. package/lib/commonjs/components/TravelBooking/TabSelector.js.map +1 -0
  36. package/lib/commonjs/components/TravelBooking/TravelBooking.js +261 -0
  37. package/lib/commonjs/components/TravelBooking/TravelBooking.js.map +1 -0
  38. package/lib/commonjs/components/TravelBooking/index.js +22 -0
  39. package/lib/commonjs/components/TravelBooking/index.js.map +1 -0
  40. package/lib/commonjs/components/TravelBooking/types.js +15 -0
  41. package/lib/commonjs/components/TravelBooking/types.js.map +1 -0
  42. package/lib/commonjs/components/UnlockRewards/UnlockRewards.js +2 -2
  43. package/lib/commonjs/components/UnlockRewards/UnlockRewards.js.map +1 -1
  44. package/lib/commonjs/index.js +0 -5
  45. package/lib/commonjs/index.js.map +1 -1
  46. package/lib/module/app.js +43 -24
  47. package/lib/module/app.js.map +1 -1
  48. package/lib/module/components/DateRangePicker/DateRangePicker.js +350 -0
  49. package/lib/module/components/DateRangePicker/DateRangePicker.js.map +1 -0
  50. package/lib/module/components/DateRangePicker/index.js +4 -0
  51. package/lib/module/components/DateRangePicker/index.js.map +1 -0
  52. package/lib/module/components/Filters/Filters.js +1 -1
  53. package/lib/module/components/Filters/Filters.js.map +1 -1
  54. package/lib/module/components/Input/Input.js +2 -2
  55. package/lib/module/components/Input/Input.js.map +1 -1
  56. package/lib/module/components/NumericStepper/NumericStepper.js +96 -0
  57. package/lib/module/components/NumericStepper/NumericStepper.js.map +1 -0
  58. package/lib/module/components/NumericStepper/index.js +5 -0
  59. package/lib/module/components/NumericStepper/index.js.map +1 -0
  60. package/lib/module/components/SelectAmount/SelectAmount.js +184 -0
  61. package/lib/module/components/SelectAmount/SelectAmount.js.map +1 -0
  62. package/lib/module/components/SelectAmount/index.js +4 -0
  63. package/lib/module/components/SelectAmount/index.js.map +1 -0
  64. package/lib/module/components/Suggestions/SuggestionList.js +92 -0
  65. package/lib/module/components/Suggestions/SuggestionList.js.map +1 -0
  66. package/lib/module/components/TravelBooking/CarRentalForm.js +363 -0
  67. package/lib/module/components/TravelBooking/CarRentalForm.js.map +1 -0
  68. package/lib/module/components/TravelBooking/FlightForm.js +340 -0
  69. package/lib/module/components/TravelBooking/FlightForm.js.map +1 -0
  70. package/lib/module/components/TravelBooking/FlightSummary.js +254 -0
  71. package/lib/module/components/TravelBooking/FlightSummary.js.map +1 -0
  72. package/lib/module/components/TravelBooking/HotelForm.js +286 -0
  73. package/lib/module/components/TravelBooking/HotelForm.js.map +1 -0
  74. package/lib/module/components/TravelBooking/HotelSummary.js +239 -0
  75. package/lib/module/components/TravelBooking/HotelSummary.js.map +1 -0
  76. package/lib/module/components/TravelBooking/README.md +421 -0
  77. package/lib/module/components/TravelBooking/SummaryBar.js +174 -0
  78. package/lib/module/components/TravelBooking/SummaryBar.js.map +1 -0
  79. package/lib/module/components/TravelBooking/TabSelector.js +110 -0
  80. package/lib/module/components/TravelBooking/TabSelector.js.map +1 -0
  81. package/lib/module/components/TravelBooking/TravelBooking.js +243 -0
  82. package/lib/module/components/TravelBooking/TravelBooking.js.map +1 -0
  83. package/lib/module/components/TravelBooking/index.js +22 -0
  84. package/lib/module/components/TravelBooking/index.js.map +1 -0
  85. package/lib/module/components/TravelBooking/types.js +11 -0
  86. package/lib/module/components/TravelBooking/types.js.map +1 -0
  87. package/lib/module/components/UnlockRewards/UnlockRewards.js +2 -2
  88. package/lib/module/components/UnlockRewards/UnlockRewards.js.map +1 -1
  89. package/lib/module/index.js +7 -4
  90. package/lib/module/index.js.map +1 -1
  91. package/lib/typescript/commonjs/app.d.ts.map +1 -1
  92. package/lib/typescript/commonjs/components/DateRangePicker/DateRangePicker.d.ts +25 -0
  93. package/lib/typescript/commonjs/components/DateRangePicker/DateRangePicker.d.ts.map +1 -0
  94. package/lib/typescript/commonjs/components/DateRangePicker/index.d.ts +1 -0
  95. package/lib/typescript/commonjs/components/DateRangePicker/index.d.ts.map +1 -0
  96. package/lib/typescript/commonjs/components/NumericStepper/NumericStepper.d.ts +19 -0
  97. package/lib/typescript/commonjs/components/NumericStepper/NumericStepper.d.ts.map +1 -0
  98. package/lib/typescript/commonjs/components/NumericStepper/index.d.ts +3 -0
  99. package/lib/typescript/commonjs/components/NumericStepper/index.d.ts.map +1 -0
  100. package/lib/typescript/commonjs/components/SelectAmount/SelectAmount.d.ts +29 -0
  101. package/lib/typescript/commonjs/components/SelectAmount/SelectAmount.d.ts.map +1 -0
  102. package/lib/typescript/commonjs/components/SelectAmount/index.d.ts +1 -0
  103. package/lib/typescript/commonjs/components/SelectAmount/index.d.ts.map +1 -0
  104. package/lib/typescript/commonjs/components/Suggestions/SuggestionList.d.ts +14 -0
  105. package/lib/typescript/commonjs/components/Suggestions/SuggestionList.d.ts.map +1 -0
  106. package/lib/typescript/commonjs/components/TravelBooking/CarRentalForm.d.ts +58 -0
  107. package/lib/typescript/commonjs/components/TravelBooking/CarRentalForm.d.ts.map +1 -0
  108. package/lib/typescript/commonjs/components/TravelBooking/FlightForm.d.ts +57 -0
  109. package/lib/typescript/commonjs/components/TravelBooking/FlightForm.d.ts.map +1 -0
  110. package/lib/typescript/commonjs/components/TravelBooking/FlightSummary.d.ts +41 -0
  111. package/lib/typescript/commonjs/components/TravelBooking/FlightSummary.d.ts.map +1 -0
  112. package/lib/typescript/commonjs/components/TravelBooking/HotelForm.d.ts +52 -0
  113. package/lib/typescript/commonjs/components/TravelBooking/HotelForm.d.ts.map +1 -0
  114. package/lib/typescript/commonjs/components/TravelBooking/HotelSummary.d.ts +44 -0
  115. package/lib/typescript/commonjs/components/TravelBooking/HotelSummary.d.ts.map +1 -0
  116. package/lib/typescript/commonjs/components/TravelBooking/SummaryBar.d.ts +17 -0
  117. package/lib/typescript/commonjs/components/TravelBooking/SummaryBar.d.ts.map +1 -0
  118. package/lib/typescript/commonjs/components/TravelBooking/TabSelector.d.ts +17 -0
  119. package/lib/typescript/commonjs/components/TravelBooking/TabSelector.d.ts.map +1 -0
  120. package/lib/typescript/commonjs/components/TravelBooking/TravelBooking.d.ts +84 -0
  121. package/lib/typescript/commonjs/components/TravelBooking/TravelBooking.d.ts.map +1 -0
  122. package/lib/typescript/commonjs/components/TravelBooking/index.d.ts +1 -0
  123. package/lib/typescript/commonjs/components/TravelBooking/index.d.ts.map +1 -0
  124. package/lib/typescript/commonjs/components/TravelBooking/types.d.ts +26 -0
  125. package/lib/typescript/commonjs/components/TravelBooking/types.d.ts.map +1 -0
  126. package/lib/typescript/commonjs/index.d.ts +0 -1
  127. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  128. package/lib/typescript/module/app.d.ts.map +1 -1
  129. package/lib/typescript/module/components/DateRangePicker/DateRangePicker.d.ts +25 -0
  130. package/lib/typescript/module/components/DateRangePicker/DateRangePicker.d.ts.map +1 -0
  131. package/lib/typescript/module/components/DateRangePicker/index.d.ts +1 -0
  132. package/lib/typescript/module/components/DateRangePicker/index.d.ts.map +1 -0
  133. package/lib/typescript/module/components/NumericStepper/NumericStepper.d.ts +19 -0
  134. package/lib/typescript/module/components/NumericStepper/NumericStepper.d.ts.map +1 -0
  135. package/lib/typescript/module/components/NumericStepper/index.d.ts +3 -0
  136. package/lib/typescript/module/components/NumericStepper/index.d.ts.map +1 -0
  137. package/lib/typescript/module/components/SelectAmount/SelectAmount.d.ts +29 -0
  138. package/lib/typescript/module/components/SelectAmount/SelectAmount.d.ts.map +1 -0
  139. package/lib/typescript/module/components/SelectAmount/index.d.ts +1 -0
  140. package/lib/typescript/module/components/SelectAmount/index.d.ts.map +1 -0
  141. package/lib/typescript/module/components/Suggestions/SuggestionList.d.ts +14 -0
  142. package/lib/typescript/module/components/Suggestions/SuggestionList.d.ts.map +1 -0
  143. package/lib/typescript/module/components/TravelBooking/CarRentalForm.d.ts +58 -0
  144. package/lib/typescript/module/components/TravelBooking/CarRentalForm.d.ts.map +1 -0
  145. package/lib/typescript/module/components/TravelBooking/FlightForm.d.ts +57 -0
  146. package/lib/typescript/module/components/TravelBooking/FlightForm.d.ts.map +1 -0
  147. package/lib/typescript/module/components/TravelBooking/FlightSummary.d.ts +41 -0
  148. package/lib/typescript/module/components/TravelBooking/FlightSummary.d.ts.map +1 -0
  149. package/lib/typescript/module/components/TravelBooking/HotelForm.d.ts +52 -0
  150. package/lib/typescript/module/components/TravelBooking/HotelForm.d.ts.map +1 -0
  151. package/lib/typescript/module/components/TravelBooking/HotelSummary.d.ts +44 -0
  152. package/lib/typescript/module/components/TravelBooking/HotelSummary.d.ts.map +1 -0
  153. package/lib/typescript/module/components/TravelBooking/SummaryBar.d.ts +17 -0
  154. package/lib/typescript/module/components/TravelBooking/SummaryBar.d.ts.map +1 -0
  155. package/lib/typescript/module/components/TravelBooking/TabSelector.d.ts +17 -0
  156. package/lib/typescript/module/components/TravelBooking/TabSelector.d.ts.map +1 -0
  157. package/lib/typescript/module/components/TravelBooking/TravelBooking.d.ts +84 -0
  158. package/lib/typescript/module/components/TravelBooking/TravelBooking.d.ts.map +1 -0
  159. package/lib/typescript/module/components/TravelBooking/index.d.ts +1 -0
  160. package/lib/typescript/module/components/TravelBooking/index.d.ts.map +1 -0
  161. package/lib/typescript/module/components/TravelBooking/types.d.ts +26 -0
  162. package/lib/typescript/module/components/TravelBooking/types.d.ts.map +1 -0
  163. package/lib/typescript/module/index.d.ts +0 -1
  164. package/lib/typescript/module/index.d.ts.map +1 -1
  165. package/package.json +12 -8
  166. package/src/app.tsx +77 -13
  167. package/src/components/DateRangePicker/DateRangePicker.tsx +410 -0
  168. package/src/components/DateRangePicker/index.ts +2 -0
  169. package/src/components/Filters/Filters.tsx +1 -1
  170. package/src/components/Input/Input.tsx +1 -1
  171. package/src/components/NumericStepper/NumericStepper.tsx +117 -0
  172. package/src/components/NumericStepper/index.ts +2 -0
  173. package/src/components/SelectAmount/SelectAmount.tsx +217 -0
  174. package/src/components/SelectAmount/index.ts +2 -0
  175. package/src/components/Suggestions/SuggestionList.tsx +106 -0
  176. package/src/components/TravelBooking/CarRentalForm.tsx +440 -0
  177. package/src/components/TravelBooking/FlightForm.tsx +452 -0
  178. package/src/components/TravelBooking/FlightSummary.tsx +388 -0
  179. package/src/components/TravelBooking/HotelForm.tsx +365 -0
  180. package/src/components/TravelBooking/HotelSummary.tsx +340 -0
  181. package/src/components/TravelBooking/README.md +421 -0
  182. package/src/components/TravelBooking/SummaryBar.tsx +239 -0
  183. package/src/components/TravelBooking/TabSelector.tsx +158 -0
  184. package/src/components/TravelBooking/TravelBooking.tsx +407 -0
  185. package/src/components/TravelBooking/index.ts +20 -0
  186. package/src/components/TravelBooking/types.ts +28 -0
  187. package/src/components/UnlockRewards/UnlockRewards.tsx +2 -2
  188. package/src/index.ts +4 -4
@@ -0,0 +1,440 @@
1
+ import { ThemeType, useTheme } from "@/theme";
2
+ import React, { useCallback, useMemo, useRef, useState } from "react";
3
+ import {
4
+ View,
5
+ Text,
6
+ TouchableOpacity,
7
+ StyleSheet,
8
+ StyleProp,
9
+ ViewStyle,
10
+ TextStyle,
11
+ } from "react-native";
12
+ import { Ionicons } from "@expo/vector-icons";
13
+ import CustomInput from "../Input/Input";
14
+ import DateRangePicker from "../DateRangePicker/DateRangePicker";
15
+ import { Picker } from "@react-native-picker/picker";
16
+ import SuggestionList from "../Suggestions/SuggestionList";
17
+ import { TextInput } from "react-native-gesture-handler";
18
+ import { CarSuggestions, FormInputType } from "./types";
19
+
20
+ export const mockCarSuggestions: CarSuggestions[] = [
21
+ { id: 1, city: "Beirut", country: "Lebanon", value: "BEIRUT, LEBANON" },
22
+ { id: 2, city: "Dubai", country: "UAE", value: "DUBAI, UAE" },
23
+ { id: 3, city: "London", country: "UK", value: "LONDON, UK" },
24
+ { id: 4, city: "Paris", country: "France", value: "PARIS, FRANCE" },
25
+ { id: 5, city: "New York", country: "USA", value: "NEW YORK, USA" },
26
+ ];
27
+
28
+ // --- Helper Types ---
29
+ type LocationData = string;
30
+
31
+ // --- Component Props ---
32
+ export interface CarRentalFormProps {
33
+ initialFromLocation?: LocationData;
34
+ initialToLocation?: LocationData;
35
+ initialPickupDate?: string; // Expect YYYY-MM-DD string
36
+ initialDropoffDate?: string; // Expect YYYY-MM-DD string
37
+
38
+ onTextChange?: (text: string) => void;
39
+ onInputFocus?: (input: FormInputType) => void;
40
+ onSwapPress?: (
41
+ currentFrom: LocationData | undefined,
42
+ currentTo: LocationData | undefined
43
+ ) => void;
44
+ onSearchPress?: (details: {
45
+ from: LocationData | undefined;
46
+ to: LocationData | undefined;
47
+ pickup: string | undefined; // Send YYYY-MM-DD
48
+ dropoff: string | undefined; // Send YYYY-MM-DD
49
+ driverAge: number | undefined;
50
+ }) => void;
51
+
52
+ fromLabel?: string;
53
+ fromPlaceholder?: string;
54
+
55
+ toLabel?: string;
56
+ toPlaceholder?: string;
57
+
58
+ pickupLabel?: string;
59
+ dropoffLabel?: string;
60
+ swapIconName?: keyof typeof Ionicons.glyphMap;
61
+ searchIconName?: keyof typeof Ionicons.glyphMap;
62
+ calendarThemeOverrides?: object; // Passed to DateRangePicker
63
+
64
+ isOneWay?: boolean;
65
+
66
+ suggestionData?: CarSuggestions[];
67
+
68
+ // --- Style Props ---
69
+ containerStyle?: StyleProp<ViewStyle>;
70
+ inputGroupContainerStyle?: StyleProp<ViewStyle>;
71
+ inputWrapperStyle?: StyleProp<ViewStyle>;
72
+ inputGroupStyle?: StyleProp<ViewStyle>;
73
+ labelStyle?: StyleProp<TextStyle>;
74
+ swapButtonContainerStyle?: StyleProp<ViewStyle>;
75
+ swapButtonStyle?: StyleProp<ViewStyle>;
76
+ swapIconStyle?: StyleProp<TextStyle>;
77
+ pickupRowStyle?: StyleProp<ViewStyle>;
78
+ searchButtonStyle?: StyleProp<ViewStyle>;
79
+ searchIconStyle?: StyleProp<TextStyle>;
80
+
81
+ // DateRangePicker specific styles (passed down)
82
+ dateRangePickerOuterContainerStyle?: StyleProp<ViewStyle>;
83
+ dateRangePickerLabelStyle?: StyleProp<TextStyle>;
84
+ dateRangePickerInputGroupStyle?: StyleProp<ViewStyle>;
85
+ dateRangePickerCalendarContainerStyle?: StyleProp<ViewStyle>;
86
+
87
+ // SuggestionList specific styles (passed down / used in renderItem)
88
+ suggestionListContainerStyle?: StyleProp<ViewStyle>;
89
+ suggestionItemStyle?: StyleProp<ViewStyle>;
90
+ suggestionItemTextStyle?: StyleProp<TextStyle>;
91
+
92
+ // Age Picker specific styles
93
+ agePickerWrapperStyle?: StyleProp<ViewStyle>;
94
+ agePickerLabelStyle?: StyleProp<TextStyle>;
95
+ pickerContainerStyle?: StyleProp<ViewStyle>;
96
+ pickerStyle?: StyleProp<ViewStyle>;
97
+ }
98
+
99
+ // --- Component ---
100
+ const CarRentalForm: React.FC<CarRentalFormProps> = ({
101
+ initialFromLocation,
102
+ initialToLocation,
103
+ initialPickupDate,
104
+ initialDropoffDate,
105
+ onSwapPress,
106
+ onSearchPress,
107
+ fromLabel = "PICK-UP",
108
+ toLabel = "DROP-OFF",
109
+ fromPlaceholder = "From Where?",
110
+ toPlaceholder = "To Where?",
111
+ pickupLabel = "PICK-UP DATE",
112
+ dropoffLabel = "DROP-OFF DATE",
113
+ swapIconName = "swap-horizontal",
114
+ searchIconName = "search",
115
+ calendarThemeOverrides = {},
116
+ containerStyle,
117
+ inputGroupContainerStyle, // Added
118
+ inputWrapperStyle, // Added
119
+ inputGroupStyle,
120
+ labelStyle,
121
+ swapButtonContainerStyle,
122
+ swapButtonStyle,
123
+ swapIconStyle,
124
+ pickupRowStyle,
125
+ searchButtonStyle,
126
+ searchIconStyle,
127
+ isOneWay,
128
+ suggestionData,
129
+ onInputFocus,
130
+ onTextChange,
131
+ dateRangePickerOuterContainerStyle,
132
+ dateRangePickerLabelStyle,
133
+ dateRangePickerInputGroupStyle,
134
+ dateRangePickerCalendarContainerStyle,
135
+ suggestionListContainerStyle,
136
+ suggestionItemStyle,
137
+ suggestionItemTextStyle,
138
+ agePickerWrapperStyle,
139
+ agePickerLabelStyle,
140
+ pickerContainerStyle,
141
+ pickerStyle,
142
+ }) => {
143
+ const { theme, isRTL } = useTheme();
144
+ const styles = useMemo(() => themedStyles(theme, isRTL), [theme, isRTL]);
145
+ const fromInputRef = useRef<TextInput>(null);
146
+ const toInputRef = useRef<TextInput>(null);
147
+
148
+ // --- State ---
149
+ const [fromLocation, setFromLocation] = useState<LocationData | undefined>(
150
+ initialFromLocation
151
+ );
152
+ const [toLocation, setToLocation] = useState<LocationData | undefined>(
153
+ initialToLocation
154
+ );
155
+ const [pickupDate, setPickupDate] = useState<string | undefined>(
156
+ initialPickupDate
157
+ );
158
+ const [dropoffDate, setDropoffDate] = useState<string | undefined>(
159
+ initialDropoffDate
160
+ );
161
+ const [age, setAge] = useState<number>();
162
+ const [focusedInput, setFocusedInput] = useState<FormInputType>();
163
+
164
+ // --- Handlers ---
165
+ const handleSwap = useCallback(() => {
166
+ const currentFrom = fromLocation;
167
+ const currentTo = toLocation;
168
+ setFromLocation(currentTo);
169
+ setToLocation(currentFrom);
170
+ onSwapPress?.(currentFrom, currentTo);
171
+ }, [fromLocation, toLocation, onSwapPress]);
172
+
173
+ const handleSearch = useCallback(() => {
174
+ onSearchPress?.({
175
+ from: fromLocation,
176
+ to: toLocation,
177
+ pickup: pickupDate,
178
+ dropoff: dropoffDate,
179
+ driverAge: age,
180
+ });
181
+ }, [fromLocation, toLocation, pickupDate, dropoffDate, age, onSearchPress]);
182
+
183
+ // --- Shared Suggestion Render Item ---
184
+ const suggestionRenderItem = (item: CarSuggestions) => (
185
+ <TouchableOpacity
186
+ key={item.id}
187
+ onPress={() => {
188
+ if (focusedInput === FormInputType.CAR_PICKUP) {
189
+ setFromLocation(item.value);
190
+ fromInputRef.current?.blur();
191
+ } else if (focusedInput === FormInputType.CAR_DROP_OFF) {
192
+ setToLocation(item.value);
193
+ toInputRef.current?.blur();
194
+ }
195
+ // setFocusedInput(undefined); // Hide suggestions after selection
196
+ }}
197
+ style={[styles.suggestionItem, suggestionItemStyle]} // Use new prop
198
+ >
199
+ <Text style={[styles.suggestionItemText, suggestionItemTextStyle]}>
200
+ {item.value}
201
+ </Text>
202
+ </TouchableOpacity>
203
+ );
204
+
205
+ return (
206
+ <View style={[styles.container, containerStyle]}>
207
+ {/* Apply inputGroupContainerStyle */}
208
+ <View style={[styles.inputGroupContainer, inputGroupContainerStyle]}>
209
+ {/* Apply inputWrapperStyle */}
210
+ <View style={[styles.inputWrapper, inputWrapperStyle]}>
211
+ <CustomInput
212
+ ref={fromInputRef}
213
+ onChangeText={(t) => {
214
+ onTextChange?.(t);
215
+ setFromLocation(t);
216
+ }}
217
+ label={fromLabel}
218
+ value={fromLocation}
219
+ labelStyle={[styles.label, labelStyle]}
220
+ placeholder={fromPlaceholder}
221
+ onFocus={() => {
222
+ onInputFocus?.(FormInputType.CAR_PICKUP);
223
+ setFocusedInput(FormInputType.CAR_PICKUP);
224
+ }}
225
+ onBlur={() => {
226
+ // Delay blur slightly to allow suggestion press
227
+ setTimeout(() => {
228
+ if (focusedInput === FormInputType.CAR_PICKUP) {
229
+ setFocusedInput(undefined);
230
+ }
231
+ }, 150);
232
+ }}
233
+ containerStyle={inputGroupStyle}
234
+ />
235
+ {suggestionData && (
236
+ <SuggestionList
237
+ data={suggestionData}
238
+ visible={focusedInput === FormInputType.CAR_PICKUP}
239
+ renderItemContent={suggestionRenderItem}
240
+ containerStyle={suggestionListContainerStyle}
241
+ />
242
+ )}
243
+ </View>
244
+
245
+ <View style={[styles.swapButtonContainer, swapButtonContainerStyle]}>
246
+ <TouchableOpacity
247
+ style={[styles.swapButton, swapButtonStyle]}
248
+ onPress={handleSwap}
249
+ activeOpacity={0.7}
250
+ >
251
+ <Ionicons
252
+ name={swapIconName}
253
+ size={20}
254
+ color={theme.onSurface}
255
+ style={swapIconStyle}
256
+ />
257
+ </TouchableOpacity>
258
+ </View>
259
+
260
+ {/* Apply inputWrapperStyle */}
261
+ <View style={[styles.inputWrapper, inputWrapperStyle]}>
262
+ <CustomInput
263
+ ref={toInputRef}
264
+ onChangeText={(t) => {
265
+ setToLocation(t);
266
+ onTextChange?.(t);
267
+ }}
268
+ label={toLabel}
269
+ value={toLocation}
270
+ labelStyle={[styles.label, labelStyle]}
271
+ placeholder={toPlaceholder}
272
+ onFocus={() => {
273
+ onInputFocus?.(FormInputType.CAR_DROP_OFF);
274
+ setFocusedInput(FormInputType.CAR_DROP_OFF);
275
+ }}
276
+ onBlur={() => {
277
+ setTimeout(() => {
278
+ if (focusedInput === FormInputType.CAR_DROP_OFF) {
279
+ setFocusedInput(undefined);
280
+ }
281
+ }, 150);
282
+ }}
283
+ containerStyle={inputGroupStyle}
284
+ />
285
+ {suggestionData && (
286
+ <SuggestionList
287
+ data={suggestionData}
288
+ visible={focusedInput === FormInputType.CAR_DROP_OFF}
289
+ renderItemContent={suggestionRenderItem}
290
+ containerStyle={suggestionListContainerStyle} // Use new prop
291
+ />
292
+ )}
293
+ </View>
294
+ </View>
295
+
296
+ <DateRangePicker
297
+ departureLabel={pickupLabel}
298
+ returnLabel={dropoffLabel}
299
+ outerContainerStyle={[
300
+ styles.dateRangePickerOuterContainer,
301
+ dateRangePickerOuterContainerStyle,
302
+ ]}
303
+ labelStyle={[labelStyle, dateRangePickerLabelStyle]}
304
+ inputGroupStyle={dateRangePickerInputGroupStyle}
305
+ calendarContainerStyle={dateRangePickerCalendarContainerStyle}
306
+ calendarThemeOverrides={calendarThemeOverrides}
307
+ onDatesChange={(d) => {
308
+ setDropoffDate(d.return);
309
+ setPickupDate(d.departure);
310
+ }}
311
+ isOneWay={isOneWay}
312
+ />
313
+
314
+ <View style={[styles.pickupRow, pickupRowStyle]}>
315
+ <View style={[styles.agePickerWrapper, agePickerWrapperStyle]}>
316
+ <Text style={[styles.label, labelStyle, agePickerLabelStyle]}>
317
+ Driver's Age
318
+ </Text>
319
+ <View style={[styles.pickerContainer, pickerContainerStyle]}>
320
+ <Picker
321
+ selectedValue={age}
322
+ onValueChange={setAge}
323
+ style={[styles.picker, pickerStyle]}
324
+ dropdownIconColor={theme.onSurface}
325
+ >
326
+ <Picker.Item label="Select Age" value={undefined} enabled={false} />
327
+ {Array.from({ length: 80 - 21 + 1 }, (_, i) => i + 21).map(
328
+ (n) => (
329
+ <Picker.Item key={n} label={n.toString()} value={n} />
330
+ )
331
+ )}
332
+ </Picker>
333
+ </View>
334
+ </View>
335
+ <TouchableOpacity
336
+ style={[styles.searchButton, searchButtonStyle]}
337
+ onPress={handleSearch}
338
+ activeOpacity={0.8}
339
+ >
340
+ <Ionicons
341
+ name={searchIconName}
342
+ size={24}
343
+ color={theme.onPrimary}
344
+ style={searchIconStyle}
345
+ />
346
+ </TouchableOpacity>
347
+ </View>
348
+ </View>
349
+ );
350
+ };
351
+
352
+ // --- Styles ---
353
+ const themedStyles = (theme: ThemeType, isRTL: boolean) =>
354
+ StyleSheet.create({
355
+ container: {
356
+ padding: 16,
357
+ backgroundColor: theme.surface,
358
+ borderBottomRightRadius: 8,
359
+ borderBottomLeftRadius: 8,
360
+ },
361
+ inputGroupContainer: {
362
+ position: "relative",
363
+ },
364
+ inputWrapper: {
365
+ marginBottom: 15,
366
+ position: "relative",
367
+ },
368
+ label: {
369
+ color: theme.labelText,
370
+ fontSize: 12,
371
+ fontWeight: "600",
372
+ textTransform: "uppercase",
373
+ textAlign: isRTL ? "right" : "left",
374
+ marginBottom: 6,
375
+ },
376
+ swapButtonContainer: {
377
+ // // Centering the button between the input wrappers
378
+ // position: "absolute",
379
+ // left: 0,
380
+ // right: 0,
381
+ // top: "50%", // Position roughly in the middle vertically
382
+ // transform: [{ translateY: -18 }], // Adjust based on button height / 2
383
+ alignItems: "center",
384
+ // zIndex: 1, // Ensure swap button is above inputs if they overlap slightly
385
+ },
386
+ swapButton: {
387
+ width: 36,
388
+ height: 36,
389
+ borderRadius: 18,
390
+ backgroundColor: theme.surface,
391
+ borderColor: theme.border,
392
+ borderWidth: 1,
393
+ justifyContent: "center",
394
+ alignItems: "center",
395
+ },
396
+ dateRangePickerOuterContainer: {
397
+ marginTop: 10, // Default margin, can be overridden
398
+ },
399
+ pickupRow: {
400
+ flexDirection: isRTL ? "row-reverse" : "row",
401
+ alignItems: "flex-end",
402
+ marginTop: 20,
403
+ gap: 10,
404
+ },
405
+ agePickerWrapper: {
406
+ flex: 1,
407
+ },
408
+ pickerContainer: {
409
+ borderWidth: 1,
410
+ borderColor: theme.border,
411
+ borderRadius: 8,
412
+ backgroundColor: theme.surface,
413
+ justifyContent: "center",
414
+ height: 50,
415
+ },
416
+ picker: {
417
+ width: "100%",
418
+ color: theme.onSurface,
419
+ },
420
+ searchButton: {
421
+ backgroundColor: theme.primary,
422
+ width: 50,
423
+ height: 50,
424
+ borderRadius: 8,
425
+ justifyContent: "center",
426
+ alignItems: "center",
427
+ },
428
+ suggestionItem: {
429
+ padding: 12,
430
+ borderBottomWidth: StyleSheet.hairlineWidth,
431
+ borderBottomColor: theme.border,
432
+ backgroundColor: theme.surface,
433
+ },
434
+ suggestionItemText: {
435
+ fontSize: 14,
436
+ color: theme.onSurface,
437
+ },
438
+ });
439
+
440
+ export default CarRentalForm;