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,452 @@
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 SuggestionList from "../Suggestions/SuggestionList";
16
+ import { FlightSuggestions, FormInputType } from "./types";
17
+ import { TextInput } from "react-native-gesture-handler";
18
+
19
+ // --- Helper Types ---
20
+ type LocationData = string;
21
+
22
+ // --- Component Props ---
23
+ export interface FlightFormProps {
24
+ initialFromLocation?: LocationData;
25
+ initialToLocation?: LocationData;
26
+ initialDepartureDate?: string; // Expect YYYY-MM-DD string
27
+ initialReturnDate?: string; // Expect YYYY-MM-DD string
28
+
29
+ onInputFocus?: (input: FormInputType) => void;
30
+ onSwapPress?: (
31
+ currentFrom: LocationData | undefined,
32
+ currentTo: LocationData | undefined
33
+ ) => void;
34
+ onSearchPress?: (details: {
35
+ from: LocationData | undefined;
36
+ to: LocationData | undefined;
37
+ departure: string | undefined; // Send YYYY-MM-DD
38
+ return?: string | undefined; // Send YYYY-MM-DD
39
+ }) => void;
40
+ onTextChange?: (text: string) => void;
41
+
42
+ fromLabel?: string;
43
+ fromPlaceholder?: string;
44
+
45
+ toLabel?: string;
46
+ toPlaceholder?: string;
47
+
48
+ departureLabel?: string;
49
+ returnLabel?: string;
50
+ swapIconName?: keyof typeof Ionicons.glyphMap;
51
+ searchIconName?: keyof typeof Ionicons.glyphMap;
52
+ calendarThemeOverrides?: object; // Passed to DateRangePicker
53
+
54
+ isOneWay?: boolean;
55
+
56
+ suggestionData?: FlightSuggestions[];
57
+
58
+ // --- Style Props ---
59
+ containerStyle?: StyleProp<ViewStyle>;
60
+ inputGroupContainerStyle?: StyleProp<ViewStyle>;
61
+ inputWrapperStyle?: StyleProp<ViewStyle>;
62
+ customInputContainerStyle?: StyleProp<ViewStyle>;
63
+ labelStyle?: StyleProp<TextStyle>;
64
+ swapButtonContainerStyle?: StyleProp<ViewStyle>;
65
+ swapButtonStyle?: StyleProp<ViewStyle>;
66
+ swapIconStyle?: StyleProp<TextStyle>;
67
+ departureRowStyle?: StyleProp<ViewStyle>;
68
+ searchButtonStyle?: StyleProp<ViewStyle>;
69
+ searchIconStyle?: StyleProp<TextStyle>;
70
+
71
+ // DateRangePicker specific styles (passed down)
72
+ dateRangePickerOuterContainerStyle?: StyleProp<ViewStyle>;
73
+ dateRangePickerLabelStyle?: StyleProp<TextStyle>;
74
+ dateRangePickerInputGroupStyle?: StyleProp<ViewStyle>;
75
+ dateRangePickerCalendarContainerStyle?: StyleProp<ViewStyle>;
76
+
77
+ // SuggestionList specific styles
78
+ suggestionListContainerStyle?: StyleProp<ViewStyle>;
79
+ // Styles for the default suggestion item rendering
80
+ suggestionItemGroupStyle?: StyleProp<ViewStyle>;
81
+ suggestionCityRowStyle?: StyleProp<ViewStyle>;
82
+ suggestionCityIconStyle?: StyleProp<TextStyle>;
83
+ suggestionCityTextStyle?: StyleProp<TextStyle>;
84
+ suggestionAirportTouchableStyle?: StyleProp<ViewStyle>;
85
+ suggestionAirportIconStyle?: StyleProp<TextStyle>;
86
+ suggestionAirportTextStyle?: StyleProp<TextStyle>;
87
+ }
88
+ // --- Component ---
89
+ const FlightForm: React.FC<FlightFormProps> = ({
90
+ initialFromLocation = "Beirut, Beirut Intl Arpt - BEY",
91
+ initialToLocation = "Dubai, Dubai Intl Arpt - DXB",
92
+ initialDepartureDate,
93
+ initialReturnDate,
94
+ onSwapPress,
95
+ onSearchPress,
96
+ onInputFocus,
97
+ onTextChange,
98
+ fromLabel = "FROM",
99
+ toLabel = "TO",
100
+ fromPlaceholder = "From Where?",
101
+ toPlaceholder = "To Where?",
102
+ departureLabel = "DEPARTURE",
103
+ returnLabel = "RETURN",
104
+ swapIconName = "swap-horizontal",
105
+ searchIconName = "search",
106
+ calendarThemeOverrides = {},
107
+ isOneWay,
108
+ suggestionData,
109
+ // Style Props
110
+ containerStyle,
111
+ inputGroupContainerStyle,
112
+ inputWrapperStyle,
113
+ customInputContainerStyle, // Renamed from inputStyle for clarity
114
+ labelStyle,
115
+ swapButtonContainerStyle,
116
+ swapButtonStyle,
117
+ swapIconStyle,
118
+ departureRowStyle,
119
+ searchButtonStyle,
120
+ searchIconStyle,
121
+ dateRangePickerOuterContainerStyle,
122
+ dateRangePickerLabelStyle,
123
+ dateRangePickerInputGroupStyle,
124
+ dateRangePickerCalendarContainerStyle,
125
+ suggestionListContainerStyle,
126
+ suggestionItemGroupStyle,
127
+ suggestionCityRowStyle,
128
+ suggestionCityIconStyle,
129
+ suggestionCityTextStyle,
130
+ suggestionAirportTouchableStyle,
131
+ suggestionAirportIconStyle,
132
+ suggestionAirportTextStyle,
133
+ }) => {
134
+ const { theme, isRTL } = useTheme();
135
+ const styles = useMemo(() => themedStyles(theme, isRTL), [theme, isRTL]);
136
+ const toLocationInput = useRef<TextInput>(null);
137
+ const fromLocationInput = useRef<TextInput>(null);
138
+
139
+ // --- State ---
140
+ const [fromLocation, setFromLocation] = useState<LocationData | undefined>(
141
+ initialFromLocation
142
+ );
143
+ const [toLocation, setToLocation] = useState<LocationData | undefined>(
144
+ initialToLocation
145
+ );
146
+ const [departureDate, setDepartureDate] = useState<string | undefined>(
147
+ initialDepartureDate
148
+ );
149
+ const [returnDate, setReturnDate] = useState<string | undefined>(
150
+ initialReturnDate
151
+ );
152
+ const [focusedInput, setFocusedInput] = useState<FormInputType>();
153
+
154
+ // --- Handlers ---
155
+ const handleSwap = useCallback(() => {
156
+ const currentFrom = fromLocation;
157
+ const currentTo = toLocation;
158
+ setFromLocation(currentTo);
159
+ setToLocation(currentFrom);
160
+ onSwapPress?.(currentFrom, currentTo);
161
+ }, [fromLocation, toLocation, onSwapPress]);
162
+
163
+ const handleSearch = useCallback(() => {
164
+ onSearchPress?.({
165
+ from: fromLocation,
166
+ to: toLocation,
167
+ departure: departureDate,
168
+ return: isOneWay ? undefined : returnDate, // Only send return if not one way
169
+ });
170
+ }, [
171
+ fromLocation,
172
+ toLocation,
173
+ departureDate,
174
+ returnDate,
175
+ isOneWay,
176
+ onSearchPress,
177
+ ]);
178
+
179
+ // --- Default Suggestion Renderer (Now Stylable) ---
180
+ const suggestionRenderItem = (item: FlightSuggestions) => (
181
+ <View key={item.id} style={[styles.suggestionItemGroup, suggestionItemGroupStyle]}>
182
+ <View style={[styles.suggestionCityRow, suggestionCityRowStyle]}>
183
+ <Ionicons
184
+ name="airplane" // Consider making icon name a prop too if needed
185
+ size={20}
186
+ color={theme.primary}
187
+ style={[styles.suggestionCityIcon, suggestionCityIconStyle]}
188
+ />
189
+ <Text style={[styles.suggestionCityText, suggestionCityTextStyle]}>
190
+ {item.city}
191
+ </Text>
192
+ </View>
193
+ {item.airports.map((airport, index) => (
194
+ <TouchableOpacity
195
+ key={`${item.id}-${index}`}
196
+ style={[
197
+ styles.suggestionAirportTouchable,
198
+ suggestionAirportTouchableStyle,
199
+ ]}
200
+ onPress={() => {
201
+ if (focusedInput == FormInputType.FLIGHT_TO) {
202
+ setToLocation(airport);
203
+ toLocationInput.current?.blur();
204
+ } else {
205
+ setFromLocation(airport);
206
+ fromLocationInput.current?.blur();
207
+ }
208
+ }}
209
+ >
210
+ <Ionicons
211
+ name="arrow-forward"
212
+ size={18}
213
+ color={theme.primary}
214
+ style={[styles.suggestionAirportIcon, suggestionAirportIconStyle]}
215
+ />
216
+ <Text
217
+ style={[styles.suggestionAirportText, suggestionAirportTextStyle]}
218
+ >
219
+ {airport}
220
+ </Text>
221
+ </TouchableOpacity>
222
+ ))}
223
+ </View>
224
+ );
225
+
226
+ return (
227
+ <View style={[styles.container, containerStyle]}>
228
+ <View style={[styles.inputGroupContainer, inputGroupContainerStyle]}>
229
+ <View style={[styles.inputWrapper, inputWrapperStyle]}>
230
+ <CustomInput
231
+ ref={fromLocationInput}
232
+ onChangeText={(text) => {
233
+ setFromLocation(text);
234
+ onTextChange?.(text);
235
+ }}
236
+ label={fromLabel}
237
+ value={fromLocation}
238
+ labelStyle={[styles.label, labelStyle]}
239
+ placeholder={fromPlaceholder}
240
+ onFocus={() => {
241
+ setFocusedInput(FormInputType.FLIGHT_FROM);
242
+ onInputFocus?.(FormInputType.FLIGHT_FROM);
243
+ }}
244
+ onBlur={() => {
245
+ setTimeout(() => {
246
+ if (focusedInput === FormInputType.FLIGHT_FROM) {
247
+ setFocusedInput(undefined);
248
+ }
249
+ }, 150);
250
+ }}
251
+ containerStyle={customInputContainerStyle}
252
+ />
253
+ {suggestionData && (
254
+ <SuggestionList
255
+ data={suggestionData}
256
+ visible={focusedInput === FormInputType.FLIGHT_FROM}
257
+ renderItemContent={suggestionRenderItem}
258
+ containerStyle={suggestionListContainerStyle}
259
+ />
260
+ )}
261
+ </View>
262
+
263
+ <View style={[styles.swapButtonContainer, swapButtonContainerStyle]}>
264
+ <TouchableOpacity
265
+ style={[styles.swapButton, swapButtonStyle]}
266
+ onPress={handleSwap}
267
+ activeOpacity={0.7}
268
+ >
269
+ <Ionicons
270
+ name={swapIconName}
271
+ size={20}
272
+ color={theme.onSurface}
273
+ style={swapIconStyle}
274
+ />
275
+ </TouchableOpacity>
276
+ </View>
277
+
278
+ {/* Apply inputWrapperStyle */}
279
+ <View style={[styles.inputWrapper, inputWrapperStyle]}>
280
+ <CustomInput
281
+ ref={toLocationInput}
282
+ onChangeText={(text) => {
283
+ setToLocation(text);
284
+ onTextChange?.(text);
285
+ }}
286
+ label={toLabel}
287
+ value={toLocation}
288
+ labelStyle={[styles.label, labelStyle]}
289
+ placeholder={toPlaceholder}
290
+ onFocus={() => {
291
+ setFocusedInput(FormInputType.FLIGHT_TO);
292
+ onInputFocus?.(FormInputType.FLIGHT_TO);
293
+ }}
294
+ onBlur={() => {
295
+ // Delay blur slightly to allow suggestion press
296
+ setTimeout(() => {
297
+ if (focusedInput === FormInputType.FLIGHT_TO) {
298
+ setFocusedInput(undefined);
299
+ }
300
+ }, 150);
301
+ }}
302
+ // Apply customInputContainerStyle (passed to CustomInput)
303
+ containerStyle={customInputContainerStyle}
304
+ />
305
+ {suggestionData && (
306
+ <SuggestionList
307
+ data={suggestionData}
308
+ visible={focusedInput === FormInputType.FLIGHT_TO}
309
+ renderItemContent={suggestionRenderItem}
310
+ // Apply suggestionListContainerStyle
311
+ containerStyle={suggestionListContainerStyle}
312
+ />
313
+ )}
314
+ </View>
315
+ </View>
316
+
317
+ {/* Apply departureRowStyle */}
318
+ <View style={[styles.departureRow, departureRowStyle]}>
319
+ <DateRangePicker
320
+ returnLabel={returnLabel}
321
+ departureLabel={departureLabel}
322
+ outerContainerStyle={[
323
+ styles.dateRangePickerOuterContainer,
324
+ dateRangePickerOuterContainerStyle,
325
+ ]}
326
+ labelStyle={[labelStyle, dateRangePickerLabelStyle]}
327
+ inputGroupStyle={dateRangePickerInputGroupStyle}
328
+ calendarContainerStyle={dateRangePickerCalendarContainerStyle}
329
+ calendarThemeOverrides={calendarThemeOverrides}
330
+ onDatesChange={(d) => {
331
+ setDepartureDate(d.departure);
332
+ setReturnDate(d.return);
333
+ }}
334
+ isOneWay={isOneWay}
335
+ initialDepartureDate={initialDepartureDate}
336
+ initialReturnDate={initialReturnDate}
337
+ />
338
+ {/* Search Button */}
339
+ <TouchableOpacity
340
+ style={[styles.searchButton, searchButtonStyle]}
341
+ onPress={handleSearch}
342
+ activeOpacity={0.8}
343
+ >
344
+ <Ionicons
345
+ name={searchIconName}
346
+ size={24}
347
+ color={theme.onPrimary}
348
+ style={searchIconStyle}
349
+ />
350
+ </TouchableOpacity>
351
+ </View>
352
+ </View>
353
+ );
354
+ };
355
+
356
+ // --- Styles ---
357
+ const themedStyles = (theme: ThemeType, isRTL: boolean) =>
358
+ StyleSheet.create({
359
+ container: {
360
+ padding: 16,
361
+ backgroundColor: theme.surface,
362
+ borderBottomRightRadius: 8,
363
+ borderBottomLeftRadius: 8,
364
+ },
365
+ inputGroupContainer: {
366
+ position: "relative",
367
+ },
368
+ inputWrapper: {
369
+ marginBottom: 15,
370
+ position: "relative",
371
+ },
372
+ label: {
373
+ color: theme.labelText,
374
+ fontSize: 12,
375
+ fontWeight: "600",
376
+ textTransform: "uppercase",
377
+ textAlign: isRTL ? "right" : "left",
378
+ marginBottom: 6,
379
+ },
380
+ swapButtonContainer: {
381
+ // Position swap button between the two input wrappers
382
+ // position: "absolute",
383
+ // left: 0,
384
+ // right: 0,
385
+ // top: "50%", // Adjust as needed based on CustomInput height
386
+ // transform: [{ translateY: -18 }], // Half the button height
387
+ alignItems: "center",
388
+ // zIndex: 1, // Ensure button is clickable above inputs
389
+ },
390
+ swapButton: {
391
+ width: 36,
392
+ height: 36,
393
+ borderRadius: 18,
394
+ backgroundColor: theme.surface,
395
+ borderColor: theme.border,
396
+ borderWidth: 1,
397
+ justifyContent: "center",
398
+ alignItems: "center",
399
+ },
400
+ departureRow: {
401
+ flexDirection: isRTL ? "row-reverse" : "row",
402
+ alignItems: "flex-end",
403
+ marginTop: 10,
404
+ gap: 10,
405
+ },
406
+ dateRangePickerOuterContainer: {
407
+ flex: 1,
408
+ },
409
+ searchButton: {
410
+ backgroundColor: theme.primary,
411
+ width: 50,
412
+ height: 50,
413
+ borderRadius: 8,
414
+ justifyContent: "center",
415
+ alignItems: "center",
416
+ },
417
+ suggestionItemGroup: {
418
+ paddingVertical: 8,
419
+ paddingHorizontal: 12,
420
+ borderBottomWidth: StyleSheet.hairlineWidth,
421
+ borderBottomColor: theme.border,
422
+ backgroundColor: theme.surface,
423
+ },
424
+ suggestionCityRow: {
425
+ flexDirection: "row",
426
+ alignItems: "center",
427
+ gap: 10,
428
+ marginBottom: 5,
429
+ },
430
+ suggestionCityIcon: {
431
+ },
432
+ suggestionCityText: {
433
+ fontSize: 15,
434
+ fontWeight: "600",
435
+ color: theme.onSurface,
436
+ },
437
+ suggestionAirportTouchable: {
438
+ flexDirection: "row",
439
+ alignItems: "center",
440
+ gap: 10,
441
+ paddingVertical: 4,
442
+ marginLeft: 25,
443
+ },
444
+ suggestionAirportIcon: {
445
+ },
446
+ suggestionAirportText: {
447
+ fontSize: 14,
448
+ color: theme.onSurfaceVariant,
449
+ },
450
+ });
451
+
452
+ export default FlightForm;