@travelswitchhq/flight-search-react 1.1.8 → 1.2.0
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/dist/index.cjs +99 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +99 -42
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -80,7 +80,6 @@ var flightSearchWidgetStyles = `
|
|
|
80
80
|
-webkit-font-smoothing: antialiased;
|
|
81
81
|
-moz-osx-font-smoothing: grayscale;
|
|
82
82
|
-webkit-tap-highlight-color: transparent;
|
|
83
|
-
background: var(--sw-widget-bg);
|
|
84
83
|
*,
|
|
85
84
|
*::before,
|
|
86
85
|
*::after {
|
|
@@ -196,10 +195,10 @@ var flightSearchWidgetStyles = `
|
|
|
196
195
|
min-width: 0;
|
|
197
196
|
overflow: visible;
|
|
198
197
|
}
|
|
199
|
-
.sw-srh-form-
|
|
198
|
+
.sw-srh-form-field.sw-is-invalid {
|
|
200
199
|
box-shadow: inset 0 0 0 1px var(--sw-error);
|
|
201
200
|
}
|
|
202
|
-
.sw-srh-form-
|
|
201
|
+
.sw-srh-form-field.sw-is-invalid label {
|
|
203
202
|
color: var(--sw-error);
|
|
204
203
|
}
|
|
205
204
|
.sw-custom-dropdown.sw-has-error .sw-custom-dropdown-trigger {
|
|
@@ -208,7 +207,7 @@ var flightSearchWidgetStyles = `
|
|
|
208
207
|
.sw-custom-dropdown.sw-has-error .sw-custom-dropdown-trigger::placeholder {
|
|
209
208
|
color: var(--sw-error) !important;
|
|
210
209
|
}
|
|
211
|
-
.sw-form-field label {
|
|
210
|
+
.sw-srh-form-field label {
|
|
212
211
|
display: block;
|
|
213
212
|
width: 100%;
|
|
214
213
|
margin: 0;
|
|
@@ -222,6 +221,13 @@ var flightSearchWidgetStyles = `
|
|
|
222
221
|
text-overflow: ellipsis;
|
|
223
222
|
text-align: initial;
|
|
224
223
|
}
|
|
224
|
+
.sw-field-error {
|
|
225
|
+
margin: 2px 0 0;
|
|
226
|
+
color: #f60b0b !important;
|
|
227
|
+
font-size: 12px;
|
|
228
|
+
font-weight: 500;
|
|
229
|
+
line-height: 1.2;
|
|
230
|
+
}
|
|
225
231
|
.p-button-label {
|
|
226
232
|
flex: unset;
|
|
227
233
|
}
|
|
@@ -317,6 +323,10 @@ padding-inline-start: 25px;
|
|
|
317
323
|
border-radius: var(--sw-radius);
|
|
318
324
|
box-shadow: var(--sw-widget-shadow);
|
|
319
325
|
}
|
|
326
|
+
.p-autocomplete-panel ul {
|
|
327
|
+
margin-bottom: 0 !important;
|
|
328
|
+
padding-left: 0 !important;
|
|
329
|
+
}
|
|
320
330
|
.sw-dropdown::-webkit-scrollbar {
|
|
321
331
|
display: none;
|
|
322
332
|
}
|
|
@@ -1005,6 +1015,9 @@ padding-inline-start: 25px;
|
|
|
1005
1015
|
font-size: 12px;
|
|
1006
1016
|
font-weight: 400;
|
|
1007
1017
|
}
|
|
1018
|
+
.sw-airline-autocomplete .p-autocomplete-loader {
|
|
1019
|
+
display: none !important;
|
|
1020
|
+
}
|
|
1008
1021
|
.sw-fsrh-adv-cont {
|
|
1009
1022
|
display: flex;
|
|
1010
1023
|
align-items: center;
|
|
@@ -1487,6 +1500,10 @@ function formatDisplayDate(date) {
|
|
|
1487
1500
|
if (!date || !(date instanceof Date) || isNaN(date.getTime())) return "Select date";
|
|
1488
1501
|
return date.toLocaleDateString("en-GB", { day: "2-digit", month: "short", year: "numeric" });
|
|
1489
1502
|
}
|
|
1503
|
+
var isEmptyLocationValue = (value, placeholder) => {
|
|
1504
|
+
const trimmed = (value ?? "").trim();
|
|
1505
|
+
return trimmed.length === 0 || trimmed === placeholder;
|
|
1506
|
+
};
|
|
1490
1507
|
function FlightSearchWidget({
|
|
1491
1508
|
config,
|
|
1492
1509
|
ssoUser
|
|
@@ -1549,6 +1566,8 @@ function FlightSearchWidget({
|
|
|
1549
1566
|
const [isOriginDropdownOpen, setIsOriginDropdownOpen] = (0, import_react.useState)(false);
|
|
1550
1567
|
const [isDestinationDropdownOpen, setIsDestinationDropdownOpen] = (0, import_react.useState)(false);
|
|
1551
1568
|
const [isRoomsGuestsMenuOpen, setIsRoomsGuestsMenuOpen] = (0, import_react.useState)(false);
|
|
1569
|
+
const [roundTripMinDate, setRoundTripMinDate] = (0, import_react.useState)(/* @__PURE__ */ new Date());
|
|
1570
|
+
const [activeRoundTripField, setActiveRoundTripField] = (0, import_react.useState)("departure");
|
|
1552
1571
|
const originDropdownRef = (0, import_react.useRef)(null);
|
|
1553
1572
|
const firstOriginDesktopInputRef = (0, import_react.useRef)(null);
|
|
1554
1573
|
const destinationDropdownRef = (0, import_react.useRef)(null);
|
|
@@ -1758,6 +1777,12 @@ function FlightSearchWidget({
|
|
|
1758
1777
|
getAirlineListBySearch(value).then(setAirlineSuggestions);
|
|
1759
1778
|
}, DEBOUNCE_MS);
|
|
1760
1779
|
}, [getAirlineListBySearch]);
|
|
1780
|
+
(0, import_react.useEffect)(() => {
|
|
1781
|
+
if (typeof window === "undefined") return;
|
|
1782
|
+
if (window.matchMedia("(max-width: 768px)").matches) {
|
|
1783
|
+
setIsOriginDropdownOpen(false);
|
|
1784
|
+
}
|
|
1785
|
+
}, []);
|
|
1761
1786
|
(0, import_react.useEffect)(() => () => {
|
|
1762
1787
|
if (searchDebounceRef.current) clearTimeout(searchDebounceRef.current);
|
|
1763
1788
|
if (airlineSearchDebounceRef.current) clearTimeout(airlineSearchDebounceRef.current);
|
|
@@ -2001,7 +2026,12 @@ function FlightSearchWidget({
|
|
|
2001
2026
|
};
|
|
2002
2027
|
const extractAirportCode = (location) => {
|
|
2003
2028
|
const match = location.match(/\(([A-Z]{3})\)/);
|
|
2004
|
-
return match ? match[1] : location;
|
|
2029
|
+
return match ? match[1] : location.trim();
|
|
2030
|
+
};
|
|
2031
|
+
const getComparableLocation = (location) => {
|
|
2032
|
+
const code = extractAirportCode(location).trim().toUpperCase();
|
|
2033
|
+
if (code.length === 3 && /^[A-Z]{3}$/.test(code)) return code;
|
|
2034
|
+
return location.trim().toLowerCase().replace(/\s+/g, " ");
|
|
2005
2035
|
};
|
|
2006
2036
|
const MONTH_NAMES = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
2007
2037
|
const formatDate = (date) => {
|
|
@@ -2162,13 +2192,22 @@ function FlightSearchWidget({
|
|
|
2162
2192
|
const segmentsToValidate = isMultiCityOrCustom ? segments : segments.slice(0, 1);
|
|
2163
2193
|
const nextErrors = {};
|
|
2164
2194
|
segmentsToValidate.forEach((segment, index) => {
|
|
2165
|
-
const
|
|
2166
|
-
const
|
|
2195
|
+
const originValue = typeof segment.origin === "string" ? segment.origin : "";
|
|
2196
|
+
const destinationValue = typeof segment.destination === "string" ? segment.destination : "";
|
|
2197
|
+
const originInvalid = isEmptyLocationValue(originValue, "Origin");
|
|
2198
|
+
const destinationInvalid = isEmptyLocationValue(destinationValue, "Destination");
|
|
2167
2199
|
if (originInvalid || destinationInvalid) {
|
|
2168
2200
|
nextErrors[index] = {
|
|
2169
2201
|
origin: originInvalid,
|
|
2170
2202
|
destination: destinationInvalid
|
|
2171
2203
|
};
|
|
2204
|
+
return;
|
|
2205
|
+
}
|
|
2206
|
+
if (getComparableLocation(originValue) === getComparableLocation(destinationValue)) {
|
|
2207
|
+
nextErrors[index] = {
|
|
2208
|
+
origin: true,
|
|
2209
|
+
destination: true
|
|
2210
|
+
};
|
|
2172
2211
|
}
|
|
2173
2212
|
});
|
|
2174
2213
|
if (Object.keys(nextErrors).length > 0) {
|
|
@@ -2275,6 +2314,47 @@ function FlightSearchWidget({
|
|
|
2275
2314
|
if (prev instanceof Date && !isNaN(prev.getTime())) return prev;
|
|
2276
2315
|
return today;
|
|
2277
2316
|
};
|
|
2317
|
+
const openRoundTripCalendar = (mode) => {
|
|
2318
|
+
const today = /* @__PURE__ */ new Date();
|
|
2319
|
+
const selectedDeparture = segments[0]?.dateRange?.[0] ?? segments[0]?.departureDate ?? null;
|
|
2320
|
+
const validDeparture = selectedDeparture instanceof Date && !isNaN(selectedDeparture.getTime()) ? selectedDeparture : today;
|
|
2321
|
+
setActiveRoundTripField(mode);
|
|
2322
|
+
setRoundTripMinDate(mode === "return" ? validDeparture : today);
|
|
2323
|
+
dateRangeCalendarRef.current?.show?.();
|
|
2324
|
+
mobileDateRangeCalendarRef.current?.show?.();
|
|
2325
|
+
};
|
|
2326
|
+
const applyRoundTripRangeChange = (range) => {
|
|
2327
|
+
setSegments((prev) => {
|
|
2328
|
+
const updated = [...prev];
|
|
2329
|
+
if (!updated[0]) return prev;
|
|
2330
|
+
const current = updated[0];
|
|
2331
|
+
const currentDeparture = current.dateRange?.[0] ?? current.departureDate ?? /* @__PURE__ */ new Date();
|
|
2332
|
+
if (activeRoundTripField === "return") {
|
|
2333
|
+
const pickedReturn = range?.[1] ?? range?.[0] ?? currentDeparture;
|
|
2334
|
+
const safeReturn = pickedReturn instanceof Date && pickedReturn.getTime() >= currentDeparture.getTime() ? pickedReturn : currentDeparture;
|
|
2335
|
+
updated[0] = {
|
|
2336
|
+
...current,
|
|
2337
|
+
dateRange: [currentDeparture, safeReturn],
|
|
2338
|
+
departureDate: currentDeparture,
|
|
2339
|
+
returnDate: safeReturn
|
|
2340
|
+
};
|
|
2341
|
+
return updated;
|
|
2342
|
+
}
|
|
2343
|
+
updated[0] = {
|
|
2344
|
+
...current,
|
|
2345
|
+
dateRange: range,
|
|
2346
|
+
departureDate: range?.[0] ?? /* @__PURE__ */ new Date(),
|
|
2347
|
+
returnDate: range?.[1] ?? /* @__PURE__ */ new Date()
|
|
2348
|
+
};
|
|
2349
|
+
return updated;
|
|
2350
|
+
});
|
|
2351
|
+
if (activeRoundTripField === "return") {
|
|
2352
|
+
setTimeout(() => {
|
|
2353
|
+
dateRangeCalendarRef.current?.hide?.();
|
|
2354
|
+
mobileDateRangeCalendarRef.current?.hide?.();
|
|
2355
|
+
}, 50);
|
|
2356
|
+
}
|
|
2357
|
+
};
|
|
2278
2358
|
const renderFlightSegment = (index, segment, isMultiCityOrCustom) => {
|
|
2279
2359
|
const canRemove = segments.length > 2 && index > 0 && isMultiCityOrCustom;
|
|
2280
2360
|
const originRef = (el) => {
|
|
@@ -2414,10 +2494,7 @@ function FlightSearchWidget({
|
|
|
2414
2494
|
renderAirportDropdown(0, "destination", destinationDropdownRef, isDestinationDropdownOpen, () => setIsDestinationDropdownOpen(true))
|
|
2415
2495
|
] }),
|
|
2416
2496
|
(tripType === "round-trip" || tripType === "one-way") && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "sw-srh-wrap sw-pos-rel mobiBox", children: tripType === "round-trip" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
2417
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { cursor: "pointer" }, onClick: () =>
|
|
2418
|
-
dateRangeCalendarRef.current?.show?.();
|
|
2419
|
-
mobileDateRangeCalendarRef.current?.show?.();
|
|
2420
|
-
}, className: "sw-srh-form-field sw-com-cal", children: [
|
|
2497
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { cursor: "pointer" }, onClick: () => openRoundTripCalendar("departure"), className: "sw-srh-form-field sw-com-cal", children: [
|
|
2421
2498
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
2422
2499
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { children: "Departure" }),
|
|
2423
2500
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: segments[0]?.dateRange?.[0]?.toLocaleDateString("en-GB", { day: "2-digit", month: "short", year: "numeric" }) })
|
|
@@ -2431,23 +2508,15 @@ function FlightSearchWidget({
|
|
|
2431
2508
|
appendTo: "self",
|
|
2432
2509
|
selectionMode: "range",
|
|
2433
2510
|
value: segments[0]?.dateRange ?? null,
|
|
2434
|
-
minDate:
|
|
2511
|
+
minDate: roundTripMinDate,
|
|
2435
2512
|
onChange: (e) => {
|
|
2436
2513
|
const range = e.value;
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
departureDate: range?.[0] ?? /* @__PURE__ */ new Date(),
|
|
2444
|
-
returnDate: range?.[1] ?? /* @__PURE__ */ new Date()
|
|
2445
|
-
};
|
|
2446
|
-
return u;
|
|
2447
|
-
});
|
|
2448
|
-
if (range?.[0] && range?.[1]) setTimeout(() => {
|
|
2449
|
-
dateRangeCalendarRef.current?.hide?.();
|
|
2450
|
-
}, 150);
|
|
2514
|
+
applyRoundTripRangeChange(range);
|
|
2515
|
+
if (activeRoundTripField === "departure" && range?.[0] && range?.[1]) {
|
|
2516
|
+
setTimeout(() => {
|
|
2517
|
+
dateRangeCalendarRef.current?.hide?.();
|
|
2518
|
+
}, 150);
|
|
2519
|
+
}
|
|
2451
2520
|
},
|
|
2452
2521
|
dateFormat: "dd M yy",
|
|
2453
2522
|
placeholder: "Select date range",
|
|
@@ -2463,20 +2532,10 @@ function FlightSearchWidget({
|
|
|
2463
2532
|
appendTo: "self",
|
|
2464
2533
|
selectionMode: "range",
|
|
2465
2534
|
value: segments[0]?.dateRange ?? null,
|
|
2466
|
-
minDate:
|
|
2535
|
+
minDate: roundTripMinDate,
|
|
2467
2536
|
onChange: (e) => {
|
|
2468
2537
|
const range = e.value;
|
|
2469
|
-
|
|
2470
|
-
const u = [...prev];
|
|
2471
|
-
if (!u[0]) return prev;
|
|
2472
|
-
u[0] = {
|
|
2473
|
-
...u[0],
|
|
2474
|
-
dateRange: range,
|
|
2475
|
-
departureDate: range?.[0] ?? /* @__PURE__ */ new Date(),
|
|
2476
|
-
returnDate: range?.[1] ?? /* @__PURE__ */ new Date()
|
|
2477
|
-
};
|
|
2478
|
-
return u;
|
|
2479
|
-
});
|
|
2538
|
+
applyRoundTripRangeChange(range);
|
|
2480
2539
|
},
|
|
2481
2540
|
dateFormat: "dd M yy",
|
|
2482
2541
|
placeholder: "Select date range",
|
|
@@ -2506,10 +2565,7 @@ function FlightSearchWidget({
|
|
|
2506
2565
|
}
|
|
2507
2566
|
)
|
|
2508
2567
|
] }),
|
|
2509
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { cursor: "pointer" }, className: "sw-srh-form-field sw-com-cal", onClick: () => {
|
|
2510
|
-
dateRangeCalendarRef.current?.show?.();
|
|
2511
|
-
mobileDateRangeCalendarRef.current?.show?.();
|
|
2512
|
-
}, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
2568
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { cursor: "pointer" }, className: "sw-srh-form-field sw-com-cal", onClick: () => openRoundTripCalendar("return"), children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
2513
2569
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { children: "Return" }),
|
|
2514
2570
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: (segments[0]?.dateRange?.[1] ?? segments[0]?.dateRange?.[0])?.toLocaleDateString("en-GB", { day: "2-digit", month: "short", year: "numeric" }) })
|
|
2515
2571
|
] }) })
|
|
@@ -2770,6 +2826,7 @@ function FlightSearchWidget({
|
|
|
2770
2826
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2771
2827
|
import_autocomplete.AutoComplete,
|
|
2772
2828
|
{
|
|
2829
|
+
className: "sw-airline-autocomplete",
|
|
2773
2830
|
value: selectedAirlines,
|
|
2774
2831
|
suggestions: airlineSuggestions,
|
|
2775
2832
|
completeMethod: (e) => {
|