@planetaexo/design-system 0.54.0 → 0.55.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.js CHANGED
@@ -1,4 +1,4 @@
1
- import * as React28 from 'react';
1
+ import * as React29 from 'react';
2
2
  import { useState, useRef, useCallback, useEffect, useId } from 'react';
3
3
  import { cva } from 'class-variance-authority';
4
4
  import { clsx } from 'clsx';
@@ -81,7 +81,7 @@ var buttonVariants = cva(
81
81
  }
82
82
  }
83
83
  );
84
- var Button = React28.forwardRef(
84
+ var Button = React29.forwardRef(
85
85
  (_a, ref) => {
86
86
  var _b = _a, { className, variant, size } = _b, props = __objRest(_b, ["className", "variant", "size"]);
87
87
  return /* @__PURE__ */ jsx(
@@ -310,10 +310,10 @@ function DialogDescription(_a) {
310
310
  }, props)
311
311
  );
312
312
  }
313
- var FloatingInput = React28.forwardRef(
313
+ var FloatingInput = React29.forwardRef(
314
314
  (_a, ref) => {
315
315
  var _b = _a, { label, error, id, className, required } = _b, props = __objRest(_b, ["label", "error", "id", "className", "required"]);
316
- const inputId = id != null ? id : React28.useId();
316
+ const inputId = id != null ? id : React29.useId();
317
317
  return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
318
318
  /* @__PURE__ */ jsx(
319
319
  "input",
@@ -353,10 +353,10 @@ var FloatingInput = React28.forwardRef(
353
353
  }
354
354
  );
355
355
  FloatingInput.displayName = "FloatingInput";
356
- var FloatingSelect = React28.forwardRef(
356
+ var FloatingSelect = React29.forwardRef(
357
357
  (_a, ref) => {
358
358
  var _b = _a, { label, error, id, className, required, children, value } = _b, props = __objRest(_b, ["label", "error", "id", "className", "required", "children", "value"]);
359
- const inputId = id != null ? id : React28.useId();
359
+ const inputId = id != null ? id : React29.useId();
360
360
  const hasValue = typeof value === "string" ? value !== "" : value !== void 0 && value !== null;
361
361
  return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
362
362
  /* @__PURE__ */ jsx(
@@ -620,11 +620,11 @@ function PhoneCountrySelect({
620
620
  disabled
621
621
  }) {
622
622
  var _a;
623
- const [open, setOpen] = React28.useState(false);
624
- const containerRef = React28.useRef(null);
625
- const listRef = React28.useRef(null);
623
+ const [open, setOpen] = React29.useState(false);
624
+ const containerRef = React29.useRef(null);
625
+ const listRef = React29.useRef(null);
626
626
  const selected = (_a = PHONE_COUNTRIES.find((c) => c.code === value)) != null ? _a : PHONE_COUNTRIES[0];
627
- React28.useEffect(() => {
627
+ React29.useEffect(() => {
628
628
  if (!open) return;
629
629
  const handler = (e) => {
630
630
  var _a2;
@@ -635,7 +635,7 @@ function PhoneCountrySelect({
635
635
  document.addEventListener("mousedown", handler);
636
636
  return () => document.removeEventListener("mousedown", handler);
637
637
  }, [open]);
638
- React28.useEffect(() => {
638
+ React29.useEffect(() => {
639
639
  if (!open || !listRef.current) return;
640
640
  const activeEl = listRef.current.querySelector("[data-selected=true]");
641
641
  activeEl == null ? void 0 : activeEl.scrollIntoView({ block: "nearest" });
@@ -905,8 +905,8 @@ function CalendarDayButton(_a) {
905
905
  "locale"
906
906
  ]);
907
907
  const defaultClassNames = getDefaultClassNames();
908
- const ref = React28.useRef(null);
909
- React28.useEffect(() => {
908
+ const ref = React29.useRef(null);
909
+ React29.useEffect(() => {
910
910
  var _a2;
911
911
  if (modifiers.focused) (_a2 = ref.current) == null ? void 0 : _a2.focus();
912
912
  }, [modifiers.focused]);
@@ -937,16 +937,16 @@ function BirthDateField({
937
937
  className,
938
938
  disabled
939
939
  }) {
940
- const [open, setOpen] = React28.useState(false);
941
- const [text, setText] = React28.useState(
940
+ const [open, setOpen] = React29.useState(false);
941
+ const [text, setText] = React29.useState(
942
942
  value ? format(value, "dd/MM/yyyy") : ""
943
943
  );
944
- const containerRef = React28.useRef(null);
945
- const inputId = React28.useId();
946
- React28.useEffect(() => {
944
+ const containerRef = React29.useRef(null);
945
+ const inputId = React29.useId();
946
+ React29.useEffect(() => {
947
947
  setText(value ? format(value, "dd/MM/yyyy") : "");
948
948
  }, [value]);
949
- React28.useEffect(() => {
949
+ React29.useEffect(() => {
950
950
  if (!open) return;
951
951
  const handler = (e) => {
952
952
  var _a;
@@ -1155,14 +1155,14 @@ function CountrySearchField({
1155
1155
  }) {
1156
1156
  var _a;
1157
1157
  const list = countries != null ? countries : COUNTRIES;
1158
- const [query, setQuery] = React28.useState("");
1159
- const [open, setOpen] = React28.useState(false);
1160
- const containerRef = React28.useRef(null);
1161
- const searchRef = React28.useRef(null);
1158
+ const [query, setQuery] = React29.useState("");
1159
+ const [open, setOpen] = React29.useState(false);
1160
+ const containerRef = React29.useRef(null);
1161
+ const searchRef = React29.useRef(null);
1162
1162
  const selected = list.find((c) => c.code === value);
1163
1163
  const isFloated = open || !!selected;
1164
1164
  const filtered = query.trim() ? list.filter((c) => c.name.toLowerCase().includes(query.toLowerCase())) : list;
1165
- React28.useEffect(() => {
1165
+ React29.useEffect(() => {
1166
1166
  if (!open) return;
1167
1167
  const handler = (e) => {
1168
1168
  var _a2;
@@ -1307,10 +1307,10 @@ function AdventureCard({
1307
1307
  }) {
1308
1308
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
1309
1309
  const isControlled = (_b = (_a = adventure.optionals) == null ? void 0 : _a.some((o) => o.onCheckedChange !== void 0)) != null ? _b : false;
1310
- const [checkedInternal, setCheckedInternal] = React28.useState(
1310
+ const [checkedInternal, setCheckedInternal] = React29.useState(
1311
1311
  new Set((_d = (_c = adventure.optionals) == null ? void 0 : _c.filter((o) => o.defaultChecked).map((o) => o.id)) != null ? _d : [])
1312
1312
  );
1313
- const [openDescriptionId, setOpenDescriptionId] = React28.useState(null);
1313
+ const [openDescriptionId, setOpenDescriptionId] = React29.useState(null);
1314
1314
  const openDescriptionOptional = openDescriptionId ? (_e = adventure.optionals) == null ? void 0 : _e.find((o) => o.id === openDescriptionId) : void 0;
1315
1315
  const isChecked = (opt) => {
1316
1316
  var _a2;
@@ -1740,7 +1740,7 @@ function BookingShell({
1740
1740
  return /* @__PURE__ */ jsxs("div", { className: "rounded-2xl border border-border bg-card overflow-hidden", children: [
1741
1741
  /* @__PURE__ */ jsxs("div", { className: "border-b border-border px-5 py-4 bg-muted/20", children: [
1742
1742
  /* @__PURE__ */ jsx("h3", { className: "text-base font-bold text-foreground font-heading mb-2", children: title }),
1743
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: steps.map((label, i) => /* @__PURE__ */ jsxs(React28.Fragment, { children: [
1743
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: steps.map((label, i) => /* @__PURE__ */ jsxs(React29.Fragment, { children: [
1744
1744
  /* @__PURE__ */ jsx(
1745
1745
  "span",
1746
1746
  {
@@ -1939,7 +1939,7 @@ function TermsSection({
1939
1939
  termsContent
1940
1940
  }) {
1941
1941
  var _a;
1942
- const [modalOpen, setModalOpen] = React28.useState(false);
1942
+ const [modalOpen, setModalOpen] = React29.useState(false);
1943
1943
  const i18n = (_a = TERMS_I18N[locale]) != null ? _a : TERMS_I18N.en;
1944
1944
  return /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-border p-4 flex flex-col gap-3", children: [
1945
1945
  /* @__PURE__ */ jsx("p", { className: "text-xs font-bold text-muted-foreground font-heading uppercase tracking-widest", children: title }),
@@ -2077,9 +2077,9 @@ function BookingWizard({
2077
2077
  }) {
2078
2078
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T;
2079
2079
  const wizardSteps = WIZARD_STEPS_FN(labels);
2080
- const [step, setStep] = React28.useState("responsible");
2081
- const [error, setError] = React28.useState(null);
2082
- const [responsible, setResponsible] = React28.useState({
2080
+ const [step, setStep] = React29.useState("responsible");
2081
+ const [error, setError] = React29.useState(null);
2082
+ const [responsible, setResponsible] = React29.useState({
2083
2083
  firstName: "",
2084
2084
  lastName: "",
2085
2085
  email: "",
@@ -2098,7 +2098,7 @@ function BookingWizard({
2098
2098
  return s + ((_b2 = (_a2 = a.slots) == null ? void 0 : _a2.children) != null ? _b2 : 0);
2099
2099
  }, 0);
2100
2100
  const totalPax = totalAdults + totalChildren;
2101
- const [travellers, setTravellers] = React28.useState(
2101
+ const [travellers, setTravellers] = React29.useState(
2102
2102
  Array.from({ length: Math.max(totalPax, 1) }, () => ({
2103
2103
  firstName: "",
2104
2104
  lastName: "",
@@ -2106,9 +2106,9 @@ function BookingWizard({
2106
2106
  email: ""
2107
2107
  }))
2108
2108
  );
2109
- const [payAmount, setPayAmount] = React28.useState("full");
2110
- const [payMethod, setPayMethod] = React28.useState("stripe");
2111
- const [termsAccepted, setTermsAccepted] = React28.useState(false);
2109
+ const [payAmount, setPayAmount] = React29.useState("full");
2110
+ const [payMethod, setPayMethod] = React29.useState("stripe");
2111
+ const [termsAccepted, setTermsAccepted] = React29.useState(false);
2112
2112
  const setR = (k, v) => setResponsible((p) => __spreadProps(__spreadValues({}, p), { [k]: v }));
2113
2113
  const setT = (i, k, v) => setTravellers((prev) => prev.map((t, idx) => idx === i ? __spreadProps(__spreadValues({}, t), { [k]: v }) : t));
2114
2114
  const setTDob = (i, v) => setTravellers((prev) => prev.map((t, idx) => idx === i ? __spreadProps(__spreadValues({}, t), { dateOfBirth: v }) : t));
@@ -2336,7 +2336,7 @@ function Offer({
2336
2336
  className
2337
2337
  }) {
2338
2338
  var _a, _b, _c;
2339
- const [showBooking, setShowBooking] = React28.useState(false);
2339
+ const [showBooking, setShowBooking] = React29.useState(false);
2340
2340
  const isShowingCheckout = !confirmedState && (!!checkoutSlot || internalDemoCheckout && showBooking);
2341
2341
  const handleBook = () => {
2342
2342
  if (!checkoutSlot && !externalBookingFlow && internalDemoCheckout) {
@@ -2703,7 +2703,7 @@ function AdventureSection({
2703
2703
  labels
2704
2704
  }) {
2705
2705
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
2706
- const [detailsOpen, setDetailsOpen] = React28.useState(false);
2706
+ const [detailsOpen, setDetailsOpen] = React29.useState(false);
2707
2707
  const handleCopyUrl = (url) => {
2708
2708
  if (onCopyFormLink) {
2709
2709
  onCopyFormLink(url);
@@ -3216,8 +3216,8 @@ function AddTravellerDialog({
3216
3216
  errorMessage
3217
3217
  }) {
3218
3218
  var _a, _b, _c, _d, _e;
3219
- const [form, setForm] = React28.useState(() => createInitialAddFormData(config));
3220
- React28.useEffect(() => {
3219
+ const [form, setForm] = React29.useState(() => createInitialAddFormData(config));
3220
+ React29.useEffect(() => {
3221
3221
  if (open) {
3222
3222
  setForm(createInitialAddFormData(config));
3223
3223
  }
@@ -3277,7 +3277,7 @@ function EditTravellerDialog({
3277
3277
  errorMessage
3278
3278
  }) {
3279
3279
  var _a, _b, _c, _d, _e;
3280
- const [form, setForm] = React28.useState(() => ({
3280
+ const [form, setForm] = React29.useState(() => ({
3281
3281
  firstName: "",
3282
3282
  lastName: "",
3283
3283
  email: "",
@@ -3286,7 +3286,7 @@ function EditTravellerDialog({
3286
3286
  birthDate: "",
3287
3287
  personType: "ADULT"
3288
3288
  }));
3289
- React28.useEffect(() => {
3289
+ React29.useEffect(() => {
3290
3290
  var _a2, _b2, _c2, _d2, _e2, _f;
3291
3291
  if (open && traveller) {
3292
3292
  setForm({
@@ -3622,48 +3622,48 @@ function BookingDetails({
3622
3622
  const hasSubmitAddTraveller = !!onSubmitAddTraveller;
3623
3623
  const hasSubmitEditTraveller = !!onSubmitEditTraveller;
3624
3624
  const hasConfirmRemoveTraveller = !!onConfirmRemoveTraveller;
3625
- const [addModalState, setAddModalState] = React28.useState({
3625
+ const [addModalState, setAddModalState] = React29.useState({
3626
3626
  open: false,
3627
3627
  adventureId: null
3628
3628
  });
3629
- const [editModalState, setEditModalState] = React28.useState({ open: false, adventureId: null, traveller: null });
3630
- const [deleteModalState, setDeleteModalState] = React28.useState({ open: false, adventureId: null, traveller: null });
3631
- const [resendInviteDialogState, setResendInviteDialogState] = React28.useState({ open: false, traveller: null });
3632
- const handleRequestOpenAddModal = React28.useCallback((adventureId) => {
3629
+ const [editModalState, setEditModalState] = React29.useState({ open: false, adventureId: null, traveller: null });
3630
+ const [deleteModalState, setDeleteModalState] = React29.useState({ open: false, adventureId: null, traveller: null });
3631
+ const [resendInviteDialogState, setResendInviteDialogState] = React29.useState({ open: false, traveller: null });
3632
+ const handleRequestOpenAddModal = React29.useCallback((adventureId) => {
3633
3633
  setAddModalState({ open: true, adventureId });
3634
3634
  }, []);
3635
- const handleRequestOpenEditModal = React28.useCallback(
3635
+ const handleRequestOpenEditModal = React29.useCallback(
3636
3636
  (adventureId, traveller) => {
3637
3637
  setEditModalState({ open: true, adventureId, traveller });
3638
3638
  },
3639
3639
  []
3640
3640
  );
3641
- const handleRequestOpenDeleteModal = React28.useCallback(
3641
+ const handleRequestOpenDeleteModal = React29.useCallback(
3642
3642
  (adventureId, traveller) => {
3643
3643
  setDeleteModalState({ open: true, adventureId, traveller });
3644
3644
  },
3645
3645
  []
3646
3646
  );
3647
- const handleRequestOpenResendInviteDialog = React28.useCallback(
3647
+ const handleRequestOpenResendInviteDialog = React29.useCallback(
3648
3648
  (traveller) => {
3649
3649
  setResendInviteDialogState({ open: true, traveller });
3650
3650
  },
3651
3651
  []
3652
3652
  );
3653
- const closeAddModal = React28.useCallback(() => {
3653
+ const closeAddModal = React29.useCallback(() => {
3654
3654
  setAddModalState({ open: false, adventureId: null });
3655
3655
  }, []);
3656
- const closeEditModal = React28.useCallback(() => {
3656
+ const closeEditModal = React29.useCallback(() => {
3657
3657
  setEditModalState({ open: false, adventureId: null, traveller: null });
3658
3658
  }, []);
3659
- const closeDeleteModal = React28.useCallback(() => {
3659
+ const closeDeleteModal = React29.useCallback(() => {
3660
3660
  setDeleteModalState({ open: false, adventureId: null, traveller: null });
3661
3661
  }, []);
3662
- const closeResendInviteDialog = React28.useCallback(() => {
3662
+ const closeResendInviteDialog = React29.useCallback(() => {
3663
3663
  setResendInviteDialogState({ open: false, traveller: null });
3664
3664
  }, []);
3665
- const submitInFlightRef = React28.useRef(false);
3666
- const handleAddSubmit = React28.useCallback(
3665
+ const submitInFlightRef = React29.useRef(false);
3666
+ const handleAddSubmit = React29.useCallback(
3667
3667
  async (adventureId, data) => {
3668
3668
  if (!onSubmitAddTraveller) return;
3669
3669
  if (submitInFlightRef.current) return;
@@ -3678,7 +3678,7 @@ function BookingDetails({
3678
3678
  },
3679
3679
  [onSubmitAddTraveller, closeAddModal]
3680
3680
  );
3681
- const handleEditSubmit = React28.useCallback(
3681
+ const handleEditSubmit = React29.useCallback(
3682
3682
  async (adventureId, travellerId, data) => {
3683
3683
  if (!onSubmitEditTraveller) return;
3684
3684
  if (submitInFlightRef.current) return;
@@ -3693,7 +3693,7 @@ function BookingDetails({
3693
3693
  },
3694
3694
  [onSubmitEditTraveller, closeEditModal]
3695
3695
  );
3696
- const handleDeleteConfirm = React28.useCallback(
3696
+ const handleDeleteConfirm = React29.useCallback(
3697
3697
  async (adventureId, travellerId) => {
3698
3698
  if (!onConfirmRemoveTraveller) return;
3699
3699
  if (submitInFlightRef.current) return;
@@ -5269,7 +5269,7 @@ function BookingCreatedEmail({
5269
5269
  }, children: i + 1 }) }),
5270
5270
  /* @__PURE__ */ jsx("td", { style: { verticalAlign: "top" }, children: /* @__PURE__ */ jsx("p", { style: { fontSize: "14px", color: emailTokens.bodyText, lineHeight: "1.6", margin: 0 }, children: step }) })
5271
5271
  ] }) }) }, i)) }),
5272
- nextStepsImportant && nextStepsImportant.trim().length > 0 && /* @__PURE__ */ jsx("p", { style: { marginBottom: "32px", fontSize: "14px", color: emailTokens.foreground, lineHeight: "1.6" }, children: nextStepsImportant.split("\n").map((line, idx, arr) => /* @__PURE__ */ jsxs(React28.Fragment, { children: [
5272
+ nextStepsImportant && nextStepsImportant.trim().length > 0 && /* @__PURE__ */ jsx("p", { style: { marginBottom: "32px", fontSize: "14px", color: emailTokens.foreground, lineHeight: "1.6" }, children: nextStepsImportant.split("\n").map((line, idx, arr) => /* @__PURE__ */ jsxs(React29.Fragment, { children: [
5273
5273
  idx === 0 ? /* @__PURE__ */ jsx("strong", { children: line }) : line,
5274
5274
  idx < arr.length - 1 ? /* @__PURE__ */ jsx("br", {}) : null
5275
5275
  ] }, idx)) })
@@ -7289,11 +7289,11 @@ function DatePickerField({
7289
7289
  fromDate,
7290
7290
  className
7291
7291
  }) {
7292
- const [open, setOpen] = React28.useState(false);
7293
- const containerRef = React28.useRef(null);
7294
- const [calendarWidth, setCalendarWidth] = React28.useState();
7292
+ const [open, setOpen] = React29.useState(false);
7293
+ const containerRef = React29.useRef(null);
7294
+ const [calendarWidth, setCalendarWidth] = React29.useState();
7295
7295
  const hasValue = !!value;
7296
- React28.useEffect(() => {
7296
+ React29.useEffect(() => {
7297
7297
  if (!containerRef.current) return;
7298
7298
  const observer = new ResizeObserver(([entry]) => {
7299
7299
  setCalendarWidth(entry.contentRect.width);
@@ -7402,7 +7402,7 @@ function BookingForm({
7402
7402
  subtitle = "Free enquiry \u2013 no commitment",
7403
7403
  className
7404
7404
  }) {
7405
- const [values, setValues] = React28.useState(__spreadValues(__spreadValues({}, defaultInitial), defaultValues));
7405
+ const [values, setValues] = React29.useState(__spreadValues(__spreadValues({}, defaultInitial), defaultValues));
7406
7406
  const set = (key, value) => setValues((prev) => __spreadProps(__spreadValues({}, prev), { [key]: value }));
7407
7407
  const handleSubmit = (e) => {
7408
7408
  e.preventDefault();
@@ -7970,11 +7970,11 @@ function FloatingTextarea({
7970
7970
  }
7971
7971
  function SelectField({ field, value, onChange, error, disabled }) {
7972
7972
  var _a, _b, _c;
7973
- const [open, setOpen] = React28.useState(false);
7974
- const containerRef = React28.useRef(null);
7973
+ const [open, setOpen] = React29.useState(false);
7974
+ const containerRef = React29.useRef(null);
7975
7975
  const options = (_a = field.options) != null ? _a : [];
7976
7976
  const selectedOpt = (_b = options.find((o) => o.value === value)) != null ? _b : null;
7977
- React28.useEffect(() => {
7977
+ React29.useEffect(() => {
7978
7978
  if (!open) return;
7979
7979
  const handleOutside = (e) => {
7980
7980
  if (containerRef.current && !containerRef.current.contains(e.target)) {
@@ -8439,11 +8439,11 @@ function RegistrationForm({
8439
8439
  readOnly = false
8440
8440
  }) {
8441
8441
  var _a;
8442
- const L = React28.useMemo(
8442
+ const L = React29.useMemo(
8443
8443
  () => __spreadValues(__spreadValues({}, DEFAULT_LABELS12), labels != null ? labels : {}),
8444
8444
  [labels]
8445
8445
  );
8446
- const sortedFields = React28.useMemo(
8446
+ const sortedFields = React29.useMemo(
8447
8447
  () => [...fields].sort((a, b) => {
8448
8448
  var _a2, _b;
8449
8449
  return ((_a2 = a.order) != null ? _a2 : 0) - ((_b = b.order) != null ? _b : 0);
@@ -8451,7 +8451,7 @@ function RegistrationForm({
8451
8451
  [fields]
8452
8452
  );
8453
8453
  const isControlled = values !== void 0;
8454
- const [internal, setInternal] = React28.useState(
8454
+ const [internal, setInternal] = React29.useState(
8455
8455
  () => initializeValues(
8456
8456
  sortedFields,
8457
8457
  defaultValues != null ? defaultValues : {},
@@ -8459,9 +8459,9 @@ function RegistrationForm({
8459
8459
  includeTerms
8460
8460
  )
8461
8461
  );
8462
- const [submitAttempted, setSubmitAttempted] = React28.useState(false);
8463
- const [validationErrors, setValidationErrors] = React28.useState({});
8464
- React28.useEffect(() => {
8462
+ const [submitAttempted, setSubmitAttempted] = React29.useState(false);
8463
+ const [validationErrors, setValidationErrors] = React29.useState({});
8464
+ React29.useEffect(() => {
8465
8465
  if (isControlled) return;
8466
8466
  setInternal((prev) => {
8467
8467
  const next = initializeValues(
@@ -8518,7 +8518,7 @@ function RegistrationForm({
8518
8518
  const termsError = submitAttempted && termsEnabled && !termsAccepted;
8519
8519
  const firstErrorFieldId = Object.keys(fieldErrors)[0];
8520
8520
  const scrollTargetId = firstErrorFieldId ? `rf-${firstErrorFieldId}` : termsError ? "rf-terms" : null;
8521
- React28.useEffect(() => {
8521
+ React29.useEffect(() => {
8522
8522
  if (!submitAttempted || !scrollTargetId) return;
8523
8523
  const timer = setTimeout(() => {
8524
8524
  const elem = document.getElementById(scrollTargetId);
@@ -8980,10 +8980,10 @@ var OTPCodeInput = ({
8980
8980
  id,
8981
8981
  required
8982
8982
  }) => {
8983
- const baseId = id != null ? id : React28.useId();
8984
- const inputRef = React28.useRef(null);
8985
- const [focused, setFocused] = React28.useState(false);
8986
- const digits = React28.useMemo(() => {
8983
+ const baseId = id != null ? id : React29.useId();
8984
+ const inputRef = React29.useRef(null);
8985
+ const [focused, setFocused] = React29.useState(false);
8986
+ const digits = React29.useMemo(() => {
8987
8987
  const arr = value.split("").slice(0, length);
8988
8988
  while (arr.length < length) arr.push("");
8989
8989
  return arr;
@@ -9096,7 +9096,7 @@ function Checkbox(_a) {
9096
9096
  })
9097
9097
  );
9098
9098
  }
9099
- var AccordionVariantContext = React28.createContext("default");
9099
+ var AccordionVariantContext = React29.createContext("default");
9100
9100
  function Accordion(_a) {
9101
9101
  var _b = _a, { className, variant = "default" } = _b, props = __objRest(_b, ["className", "variant"]);
9102
9102
  return /* @__PURE__ */ jsx(AccordionVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsx(
@@ -9114,7 +9114,7 @@ function Accordion(_a) {
9114
9114
  }
9115
9115
  function AccordionItem(_a) {
9116
9116
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
9117
- const variant = React28.useContext(AccordionVariantContext);
9117
+ const variant = React29.useContext(AccordionVariantContext);
9118
9118
  return /* @__PURE__ */ jsx(
9119
9119
  Accordion$1.Item,
9120
9120
  __spreadValues({
@@ -9135,7 +9135,7 @@ function AccordionTrigger(_a) {
9135
9135
  "className",
9136
9136
  "children"
9137
9137
  ]);
9138
- const variant = React28.useContext(AccordionVariantContext);
9138
+ const variant = React29.useContext(AccordionVariantContext);
9139
9139
  return /* @__PURE__ */ jsx(Accordion$1.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
9140
9140
  Accordion$1.Trigger,
9141
9141
  __spreadProps(__spreadValues({
@@ -9189,7 +9189,7 @@ function AccordionContent(_a) {
9189
9189
  "className",
9190
9190
  "children"
9191
9191
  ]);
9192
- const variant = React28.useContext(AccordionVariantContext);
9192
+ const variant = React29.useContext(AccordionVariantContext);
9193
9193
  return /* @__PURE__ */ jsx(
9194
9194
  Accordion$1.Panel,
9195
9195
  __spreadProps(__spreadValues({
@@ -9407,15 +9407,15 @@ function FilterPanel({
9407
9407
  onSortChange
9408
9408
  }) {
9409
9409
  var _a, _b;
9410
- const resolvedGroups = React28.useMemo(() => resolveGroups(groups), [groups]);
9411
- const [internalValue, setInternalValue] = React28.useState(
9410
+ const resolvedGroups = React29.useMemo(() => resolveGroups(groups), [groups]);
9411
+ const [internalValue, setInternalValue] = React29.useState(
9412
9412
  () => Object.fromEntries(groups.map((g) => [g.id, []]))
9413
9413
  );
9414
9414
  const selected = value != null ? value : internalValue;
9415
- const [expandedItems, setExpandedItems] = React28.useState(
9415
+ const [expandedItems, setExpandedItems] = React29.useState(
9416
9416
  () => new Set(groups.flatMap((g) => getDefaultExpandedIds(g.items)))
9417
9417
  );
9418
- const toggleExpanded = React28.useCallback((id) => {
9418
+ const toggleExpanded = React29.useCallback((id) => {
9419
9419
  setExpandedItems((prev) => {
9420
9420
  const next = new Set(prev);
9421
9421
  if (next.has(id)) next.delete(id);
@@ -9799,11 +9799,11 @@ function FilterPanel({
9799
9799
  var TRUSTPILOT_SCRIPT_SRC = "https://widget.trustpilot.com/bootstrap/v5/tp.widget.bootstrap.min.js";
9800
9800
  function TrustpilotEmbed({ config }) {
9801
9801
  var _a, _b, _c, _d, _e, _f;
9802
- const ref = React28.useRef(null);
9803
- const [widgetReady, setWidgetReady] = React28.useState(false);
9804
- const [delayPassed, setDelayPassed] = React28.useState(false);
9802
+ const ref = React29.useRef(null);
9803
+ const [widgetReady, setWidgetReady] = React29.useState(false);
9804
+ const [delayPassed, setDelayPassed] = React29.useState(false);
9805
9805
  const showFallback = delayPassed && !widgetReady;
9806
- React28.useEffect(() => {
9806
+ React29.useEffect(() => {
9807
9807
  var _a2;
9808
9808
  if (typeof document === "undefined" || !ref.current) return;
9809
9809
  const node = ref.current;
@@ -9990,16 +9990,73 @@ function webpVariantUrl(src) {
9990
9990
  const withoutQuery = query ? src.slice(0, -query.length) : src;
9991
9991
  return `${withoutQuery}.webp${query}`;
9992
9992
  }
9993
+ var PLACEHOLDER_SRC = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
9993
9994
  function Picture(_a) {
9994
- var _b = _a, { src, extraSources } = _b, imgProps = __objRest(_b, ["src", "extraSources"]);
9995
+ var _b = _a, {
9996
+ src,
9997
+ extraSources,
9998
+ eager = false,
9999
+ rootMargin = "200px",
10000
+ decoding,
10001
+ loading
10002
+ } = _b, imgProps = __objRest(_b, [
10003
+ "src",
10004
+ "extraSources",
10005
+ "eager",
10006
+ "rootMargin",
10007
+ "decoding",
10008
+ "loading"
10009
+ ]);
10010
+ const ref = React29.useRef(null);
10011
+ const [visible, setVisible] = React29.useState(eager);
10012
+ React29.useEffect(() => {
10013
+ if (eager || visible) return;
10014
+ const el = ref.current;
10015
+ if (!el || typeof IntersectionObserver === "undefined") {
10016
+ setVisible(true);
10017
+ return;
10018
+ }
10019
+ const io = new IntersectionObserver(
10020
+ (entries) => {
10021
+ if (entries.some((e) => e.isIntersecting)) {
10022
+ setVisible(true);
10023
+ io.disconnect();
10024
+ }
10025
+ },
10026
+ { rootMargin }
10027
+ );
10028
+ io.observe(el);
10029
+ return () => io.disconnect();
10030
+ }, [eager, visible, rootMargin]);
9995
10031
  const webp = webpVariantUrl(src);
10032
+ const realSrc = visible ? src : PLACEHOLDER_SRC;
10033
+ const decodingResolved = decoding != null ? decoding : eager ? void 0 : "async";
9996
10034
  if (!webp) {
9997
- return /* @__PURE__ */ jsx("img", __spreadValues({ src }, imgProps));
10035
+ return /* @__PURE__ */ jsx(
10036
+ "img",
10037
+ __spreadValues({
10038
+ ref,
10039
+ src: realSrc,
10040
+ "data-src": visible ? void 0 : src,
10041
+ decoding: decodingResolved,
10042
+ loading: loading != null ? loading : eager ? void 0 : "lazy"
10043
+ }, imgProps)
10044
+ );
9998
10045
  }
9999
10046
  return /* @__PURE__ */ jsxs("picture", { style: { display: "contents" }, children: [
10000
- /* @__PURE__ */ jsx("source", { srcSet: webp, type: "image/webp" }),
10047
+ visible && /* @__PURE__ */ jsx("source", { srcSet: webp, type: "image/webp" }),
10001
10048
  extraSources,
10002
- /* @__PURE__ */ jsx("img", __spreadValues({ src }, imgProps))
10049
+ /* @__PURE__ */ jsx(
10050
+ "img",
10051
+ __spreadValues({
10052
+ ref,
10053
+ src: realSrc,
10054
+ "data-src": visible ? void 0 : src,
10055
+ "data-srcset-webp": visible ? void 0 : webp,
10056
+ decoding: decodingResolved,
10057
+ loading: loading != null ? loading : eager ? void 0 : "lazy"
10058
+ }, imgProps)
10059
+ )
10003
10060
  ] });
10004
10061
  }
10005
10062
  function ItineraryDayCard({
@@ -10068,11 +10125,11 @@ function ItineraryModal({
10068
10125
  onNext
10069
10126
  }) {
10070
10127
  var _a, _b, _c;
10071
- const [imgIndex, setImgIndex] = React28.useState(0);
10128
+ const [imgIndex, setImgIndex] = React29.useState(0);
10072
10129
  const images = stop ? [stop.coverImage, ...(_a = stop.images) != null ? _a : []] : [];
10073
10130
  const isFirst = (stop == null ? void 0 : stop.dayNumber) === ((_b = allStops[0]) == null ? void 0 : _b.dayNumber);
10074
10131
  const isLast = (stop == null ? void 0 : stop.dayNumber) === ((_c = allStops[allStops.length - 1]) == null ? void 0 : _c.dayNumber);
10075
- React28.useEffect(() => {
10132
+ React29.useEffect(() => {
10076
10133
  setImgIndex(0);
10077
10134
  }, [stop == null ? void 0 : stop.dayNumber]);
10078
10135
  if (!stop) return null;
@@ -10199,8 +10256,8 @@ function ItineraryModal({
10199
10256
  ) });
10200
10257
  }
10201
10258
  function Itinerary({ title, subtitle, stops, className }) {
10202
- const [activeIndex, setActiveIndex] = React28.useState(null);
10203
- const scrollRef = React28.useRef(null);
10259
+ const [activeIndex, setActiveIndex] = React29.useState(null);
10260
+ const scrollRef = React29.useRef(null);
10204
10261
  const activeStop = activeIndex !== null ? stops[activeIndex] : null;
10205
10262
  const scrollBy = (dir) => {
10206
10263
  if (!scrollRef.current) return;
@@ -10292,18 +10349,18 @@ function Lightbox({
10292
10349
  onClose
10293
10350
  }) {
10294
10351
  var _a;
10295
- const [index, setIndex] = React28.useState(initialIndex);
10352
+ const [index, setIndex] = React29.useState(initialIndex);
10296
10353
  const total = photos.length;
10297
10354
  const photo = photos[index];
10298
- const prev = React28.useCallback(
10355
+ const prev = React29.useCallback(
10299
10356
  () => setIndex((i) => (i - 1 + total) % total),
10300
10357
  [total]
10301
10358
  );
10302
- const next = React28.useCallback(
10359
+ const next = React29.useCallback(
10303
10360
  () => setIndex((i) => (i + 1) % total),
10304
10361
  [total]
10305
10362
  );
10306
- React28.useEffect(() => {
10363
+ React29.useEffect(() => {
10307
10364
  const onKey = (e) => {
10308
10365
  if (e.key === "Escape") onClose();
10309
10366
  if (e.key === "ArrowLeft") prev();
@@ -10469,7 +10526,7 @@ function GridGallery({
10469
10526
  initialVisible,
10470
10527
  onOpen
10471
10528
  }) {
10472
- const [expanded, setExpanded] = React28.useState(false);
10529
+ const [expanded, setExpanded] = React29.useState(false);
10473
10530
  const cols = gridCols(photos.length);
10474
10531
  const hasMore = photos.length > initialVisible;
10475
10532
  const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
@@ -10499,7 +10556,7 @@ function CompactGridGallery({
10499
10556
  initialVisible,
10500
10557
  onOpen
10501
10558
  }) {
10502
- const [expanded, setExpanded] = React28.useState(false);
10559
+ const [expanded, setExpanded] = React29.useState(false);
10503
10560
  const hasMore = photos.length > initialVisible;
10504
10561
  const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
10505
10562
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -10528,7 +10585,7 @@ function MasonryGallery({
10528
10585
  initialVisible,
10529
10586
  onOpen
10530
10587
  }) {
10531
- const [expanded, setExpanded] = React28.useState(false);
10588
+ const [expanded, setExpanded] = React29.useState(false);
10532
10589
  const hasMore = photos.length > initialVisible;
10533
10590
  const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
10534
10591
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -10601,7 +10658,7 @@ function FeaturedGallery({
10601
10658
  photos,
10602
10659
  onOpen
10603
10660
  }) {
10604
- const [expanded, setExpanded] = React28.useState(false);
10661
+ const [expanded, setExpanded] = React29.useState(false);
10605
10662
  const featured = photos.slice(0, 3);
10606
10663
  const extra = photos.slice(3);
10607
10664
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -10768,9 +10825,9 @@ function PhotoGallery({
10768
10825
  onPhotoClick,
10769
10826
  className
10770
10827
  }) {
10771
- const [lightboxIndex, setLightboxIndex] = React28.useState(null);
10772
- const [carouselIndex, setCarouselIndex] = React28.useState(0);
10773
- const normalised = React28.useMemo(() => photos.map(normalise), [photos]);
10828
+ const [lightboxIndex, setLightboxIndex] = React29.useState(null);
10829
+ const [carouselIndex, setCarouselIndex] = React29.useState(0);
10830
+ const normalised = React29.useMemo(() => photos.map(normalise), [photos]);
10774
10831
  const handleOpen = (index) => {
10775
10832
  setLightboxIndex(index);
10776
10833
  onPhotoClick == null ? void 0 : onPhotoClick(normalised[index].src, index);
@@ -10854,7 +10911,7 @@ function ItineraryDay({
10854
10911
  photoLayout = "rounded",
10855
10912
  className
10856
10913
  }) {
10857
- const photoList = React28.useMemo(() => normalisePhotos(photos), [photos]);
10914
+ const photoList = React29.useMemo(() => normalisePhotos(photos), [photos]);
10858
10915
  const isFullBleed = photoLayout === "fullBleed" || photoLayout === "fullBleedBottom";
10859
10916
  const photoPosition = photoLayout === "fullBleedBottom" ? "bottom" : "top";
10860
10917
  const gallery = photoList.length > 0 && /* @__PURE__ */ jsx(
@@ -10909,8 +10966,8 @@ function MenuTrip({
10909
10966
  bold = true,
10910
10967
  className
10911
10968
  }) {
10912
- const scrollRef = React28.useRef(null);
10913
- React28.useEffect(() => {
10969
+ const scrollRef = React29.useRef(null);
10970
+ React29.useEffect(() => {
10914
10971
  if (!scrollRef.current || !activeSection) return;
10915
10972
  const container = scrollRef.current;
10916
10973
  const btn = container.querySelector(
@@ -11106,8 +11163,8 @@ function PricingTrip({
11106
11163
  className
11107
11164
  }) {
11108
11165
  const rOuter = sharp ? "rounded-none" : "rounded-2xl";
11109
- const [showEstimates, setShowEstimates] = React28.useState(false);
11110
- const [showPriceInfo, setShowPriceInfo] = React28.useState(false);
11166
+ const [showEstimates, setShowEstimates] = React29.useState(false);
11167
+ const [showPriceInfo, setShowPriceInfo] = React29.useState(false);
11111
11168
  if (variant === "compact") {
11112
11169
  const showOverlay = showPriceInfo && (!!priceInfo || !!currencyEstimates && currencyEstimates.length > 0);
11113
11170
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
@@ -11547,14 +11604,14 @@ function SiteHeader({
11547
11604
  }) {
11548
11605
  const t = VARIANT[variant];
11549
11606
  const resolvedLogo = logoSrc != null ? logoSrc : variant === "white" ? logoSrcDark : logoSrcLight;
11550
- const [openMenu, setOpenMenu] = React28.useState(null);
11551
- const [langOpen, setLangOpen] = React28.useState(false);
11552
- const [mobileOpen, setMobileOpen] = React28.useState(false);
11553
- const [openMobileSection, setOpenMobileSection] = React28.useState(null);
11554
- const [activeLang, setActiveLang] = React28.useState(currentLanguage);
11607
+ const [openMenu, setOpenMenu] = React29.useState(null);
11608
+ const [langOpen, setLangOpen] = React29.useState(false);
11609
+ const [mobileOpen, setMobileOpen] = React29.useState(false);
11610
+ const [openMobileSection, setOpenMobileSection] = React29.useState(null);
11611
+ const [activeLang, setActiveLang] = React29.useState(currentLanguage);
11555
11612
  const toggleMobileSection = (label) => setOpenMobileSection((prev) => prev === label ? null : label);
11556
- const menuCloseTimer = React28.useRef(void 0);
11557
- const langCloseTimer = React28.useRef(void 0);
11613
+ const menuCloseTimer = React29.useRef(void 0);
11614
+ const langCloseTimer = React29.useRef(void 0);
11558
11615
  const handleMenuEnter = (label) => {
11559
11616
  clearTimeout(menuCloseTimer.current);
11560
11617
  setOpenMenu(label);
@@ -11575,7 +11632,7 @@ function SiteHeader({
11575
11632
  setOpenMenu(null);
11576
11633
  setLangOpen(false);
11577
11634
  };
11578
- React28.useEffect(() => () => {
11635
+ React29.useEffect(() => () => {
11579
11636
  clearTimeout(menuCloseTimer.current);
11580
11637
  clearTimeout(langCloseTimer.current);
11581
11638
  }, []);
@@ -11851,7 +11908,7 @@ function SiteHeader({
11851
11908
  ), children: [
11852
11909
  /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: languages.map((lang, i) => {
11853
11910
  const isActive = lang.code === activeLang;
11854
- return /* @__PURE__ */ jsxs(React28.Fragment, { children: [
11911
+ return /* @__PURE__ */ jsxs(React29.Fragment, { children: [
11855
11912
  i > 0 && /* @__PURE__ */ jsx("span", { className: cn(
11856
11913
  "text-xs select-none",
11857
11914
  variant === "white" ? "text-border" : "text-white/15"
@@ -11913,8 +11970,8 @@ function SiteHeader({
11913
11970
  );
11914
11971
  }
11915
11972
  function ThemeToggle({ className }) {
11916
- const [dark, setDark] = React28.useState(false);
11917
- React28.useEffect(() => {
11973
+ const [dark, setDark] = React29.useState(false);
11974
+ React29.useEffect(() => {
11918
11975
  const saved = localStorage.getItem("theme");
11919
11976
  const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
11920
11977
  const isDark = saved === "dark" || !saved && prefersDark;
@@ -11964,7 +12021,7 @@ var chipVariants = cva(
11964
12021
  }
11965
12022
  }
11966
12023
  );
11967
- var Chip = React28.forwardRef(function Chip2(_a, ref) {
12024
+ var Chip = React29.forwardRef(function Chip2(_a, ref) {
11968
12025
  var _b = _a, { className, variant, size, href, children } = _b, props = __objRest(_b, ["className", "variant", "size", "href", "children"]);
11969
12026
  const classes = cn(chipVariants({ variant, size }), className);
11970
12027
  if (href) {
@@ -12064,7 +12121,7 @@ function TripCardEditorial(props) {
12064
12121
  difficulty,
12065
12122
  tag
12066
12123
  } = props;
12067
- const [internalFav, setInternalFav] = React28.useState(false);
12124
+ const [internalFav, setInternalFav] = React29.useState(false);
12068
12125
  const favorited = favoritedProp != null ? favoritedProp : internalFav;
12069
12126
  const handleFav = (e) => {
12070
12127
  e.preventDefault();
@@ -12209,7 +12266,7 @@ function TripCard(props) {
12209
12266
  );
12210
12267
  }
12211
12268
  function useHlsVideo(videoRef, src) {
12212
- React28.useEffect(() => {
12269
+ React29.useEffect(() => {
12213
12270
  if (!src || !videoRef.current) return;
12214
12271
  const video = videoRef.current;
12215
12272
  if (!src.includes(".m3u8")) return;
@@ -12253,11 +12310,11 @@ function TripHeader({
12253
12310
  className
12254
12311
  }) {
12255
12312
  var _a;
12256
- const [heroIndex, setHeroIndex] = React28.useState(0);
12257
- const [videoReady, setVideoReady] = React28.useState(false);
12258
- const videoRef = React28.useRef(null);
12313
+ const [heroIndex, setHeroIndex] = React29.useState(0);
12314
+ const [videoReady, setVideoReady] = React29.useState(false);
12315
+ const videoRef = React29.useRef(null);
12259
12316
  const isHls = !!(videoUrl == null ? void 0 : videoUrl.includes(".m3u8"));
12260
- const validImages = React28.useMemo(
12317
+ const validImages = React29.useMemo(
12261
12318
  () => images.map((u) => u == null ? void 0 : u.trim()).filter(Boolean),
12262
12319
  [images]
12263
12320
  );
@@ -12272,7 +12329,7 @@ function TripHeader({
12272
12329
  const nights = duration ? (_a = duration.nights) != null ? _a : Math.max(duration.days - 1, 1) : null;
12273
12330
  const hasMeta = !!(destination || duration);
12274
12331
  useHlsVideo(videoRef, isHls ? videoUrl : void 0);
12275
- React28.useEffect(() => {
12332
+ React29.useEffect(() => {
12276
12333
  if (!videoUrl) return;
12277
12334
  const el = videoRef.current;
12278
12335
  if (!el) return;
@@ -12320,6 +12377,7 @@ function TripHeader({
12320
12377
  alt: "",
12321
12378
  "aria-hidden": true,
12322
12379
  fetchPriority: "high",
12380
+ eager: true,
12323
12381
  className: cn(
12324
12382
  "absolute inset-0 h-full w-full object-cover transition-opacity duration-700",
12325
12383
  videoReady ? "opacity-0 pointer-events-none" : "opacity-100"
@@ -12356,6 +12414,7 @@ function TripHeader({
12356
12414
  src: currentSrc,
12357
12415
  alt: title,
12358
12416
  fetchPriority: safeIndex === 0 ? "high" : "auto",
12417
+ eager: safeIndex === 0,
12359
12418
  className: "absolute inset-0 h-full w-full object-cover transition-opacity duration-700"
12360
12419
  }
12361
12420
  ) : null,
@@ -12413,7 +12472,7 @@ function TripHeader({
12413
12472
  chips && chips.length > 0 ? siteHeader ? "-mt-[200px] sm:-mt-[214px]" : "-mt-[168px] sm:-mt-[182px]" : siteHeader ? "-mt-44" : "-mt-36"
12414
12473
  ),
12415
12474
  children: [
12416
- breadcrumb && breadcrumb.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-3 flex items-center gap-1.5 flex-wrap", children: breadcrumb.map((crumb, i) => /* @__PURE__ */ jsxs(React28.Fragment, { children: [
12475
+ breadcrumb && breadcrumb.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-3 flex items-center gap-1.5 flex-wrap", children: breadcrumb.map((crumb, i) => /* @__PURE__ */ jsxs(React29.Fragment, { children: [
12417
12476
  i > 0 && /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-3 w-3 text-white/50 shrink-0" }),
12418
12477
  /* @__PURE__ */ jsx("span", { className: "text-xs text-white/70 font-ui hover:text-white/90 cursor-default", children: crumb.label })
12419
12478
  ] }, i)) }),
@@ -12579,10 +12638,10 @@ function LanguagePicker({
12579
12638
  }) {
12580
12639
  var _a;
12581
12640
  const t = VARIANT2[variant];
12582
- const [open, setOpen] = React28.useState(false);
12583
- const ref = React28.useRef(null);
12641
+ const [open, setOpen] = React29.useState(false);
12642
+ const ref = React29.useRef(null);
12584
12643
  const active = (_a = languages.find((l) => l.code === currentLanguage)) != null ? _a : languages[0];
12585
- React28.useEffect(() => {
12644
+ React29.useEffect(() => {
12586
12645
  if (!open) return;
12587
12646
  const onDocClick = (e) => {
12588
12647
  if (ref.current && !ref.current.contains(e.target)) {
@@ -12783,7 +12842,7 @@ function SiteFooter({
12783
12842
  children: wrapper
12784
12843
  },
12785
12844
  b.alt + i
12786
- ) : /* @__PURE__ */ jsx(React28.Fragment, { children: wrapper }, b.alt + i);
12845
+ ) : /* @__PURE__ */ jsx(React29.Fragment, { children: wrapper }, b.alt + i);
12787
12846
  }) })
12788
12847
  ] }),
12789
12848
  themes.length > 0 && /* @__PURE__ */ jsxs("div", { className: "lg:col-span-3", children: [
@@ -12958,10 +13017,10 @@ function TripPage({
12958
13017
  className
12959
13018
  }) {
12960
13019
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
12961
- const [activeSection, setActiveSection] = React28.useState("");
12962
- const [accordionValue, setAccordionValue] = React28.useState([]);
12963
- const [faqsExpanded, setFaqsExpanded] = React28.useState(false);
12964
- const accordionSectionIds = React28.useMemo(
13020
+ const [activeSection, setActiveSection] = React29.useState("");
13021
+ const [accordionValue, setAccordionValue] = React29.useState([]);
13022
+ const [faqsExpanded, setFaqsExpanded] = React29.useState(false);
13023
+ const accordionSectionIds = React29.useMemo(
12965
13024
  () => /* @__PURE__ */ new Set([
12966
13025
  "when-it-operates",
12967
13026
  "how-to-get-there",
@@ -12975,18 +13034,18 @@ function TripPage({
12975
13034
  ]),
12976
13035
  []
12977
13036
  );
12978
- const [navFloating, setNavFloating] = React28.useState(false);
12979
- const [navHidden, setNavHidden] = React28.useState(false);
12980
- const [isFloating, setIsFloating] = React28.useState(false);
12981
- const [sidebarPos, setSidebarPos] = React28.useState(null);
12982
- const [pricingBarVisible, setPricingBarVisible] = React28.useState(false);
12983
- const navRef = React28.useRef(null);
12984
- const navSentinelRef = React28.useRef(null);
12985
- const sentinelRef = React28.useRef(null);
12986
- const sidebarPlaceholderRef = React28.useRef(null);
12987
- const pricingBarRef = React28.useRef(null);
12988
- const galleryRef = React28.useRef(null);
12989
- const sections = React28.useMemo(
13037
+ const [navFloating, setNavFloating] = React29.useState(false);
13038
+ const [navHidden, setNavHidden] = React29.useState(false);
13039
+ const [isFloating, setIsFloating] = React29.useState(false);
13040
+ const [sidebarPos, setSidebarPos] = React29.useState(null);
13041
+ const [pricingBarVisible, setPricingBarVisible] = React29.useState(false);
13042
+ const navRef = React29.useRef(null);
13043
+ const navSentinelRef = React29.useRef(null);
13044
+ const sentinelRef = React29.useRef(null);
13045
+ const sidebarPlaceholderRef = React29.useRef(null);
13046
+ const pricingBarRef = React29.useRef(null);
13047
+ const galleryRef = React29.useRef(null);
13048
+ const sections = React29.useMemo(
12990
13049
  () => {
12991
13050
  var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2;
12992
13051
  return [
@@ -13008,7 +13067,7 @@ function TripPage({
13008
13067
  // eslint-disable-next-line react-hooks/exhaustive-deps
13009
13068
  []
13010
13069
  );
13011
- React28.useEffect(() => {
13070
+ React29.useEffect(() => {
13012
13071
  const sentinel = navSentinelRef.current;
13013
13072
  if (!sentinel) return;
13014
13073
  const update = () => setNavFloating(sentinel.getBoundingClientRect().top < 1);
@@ -13016,7 +13075,7 @@ function TripPage({
13016
13075
  update();
13017
13076
  return () => document.removeEventListener("scroll", update, { capture: true });
13018
13077
  }, []);
13019
- React28.useEffect(() => {
13078
+ React29.useEffect(() => {
13020
13079
  const sentinel = sentinelRef.current;
13021
13080
  if (!sentinel) return;
13022
13081
  const update = () => setIsFloating(sentinel.getBoundingClientRect().top < 1);
@@ -13024,7 +13083,7 @@ function TripPage({
13024
13083
  update();
13025
13084
  return () => document.removeEventListener("scroll", update, { capture: true });
13026
13085
  }, []);
13027
- React28.useEffect(() => {
13086
+ React29.useEffect(() => {
13028
13087
  const measure = () => {
13029
13088
  if (!sidebarPlaceholderRef.current) return;
13030
13089
  const rect = sidebarPlaceholderRef.current.getBoundingClientRect();
@@ -13034,7 +13093,7 @@ function TripPage({
13034
13093
  window.addEventListener("resize", measure);
13035
13094
  return () => window.removeEventListener("resize", measure);
13036
13095
  }, [isFloating]);
13037
- React28.useEffect(() => {
13096
+ React29.useEffect(() => {
13038
13097
  const check = () => {
13039
13098
  var _a2;
13040
13099
  const target = (_a2 = galleryRef.current) != null ? _a2 : pricingBarRef.current;
@@ -13045,7 +13104,7 @@ function TripPage({
13045
13104
  check();
13046
13105
  return () => document.removeEventListener("scroll", check, { capture: true });
13047
13106
  }, []);
13048
- React28.useEffect(() => {
13107
+ React29.useEffect(() => {
13049
13108
  const check = () => {
13050
13109
  if (!pricingBarRef.current) return;
13051
13110
  setNavHidden(pricingBarRef.current.getBoundingClientRect().top < window.innerHeight * 0.92);
@@ -13054,7 +13113,7 @@ function TripPage({
13054
13113
  check();
13055
13114
  return () => document.removeEventListener("scroll", check, { capture: true });
13056
13115
  }, []);
13057
- React28.useEffect(() => {
13116
+ React29.useEffect(() => {
13058
13117
  if (sections.length === 0) return;
13059
13118
  setActiveSection(sections[0].id);
13060
13119
  const update = () => {
@@ -13692,20 +13751,62 @@ function CategoryPage2({
13692
13751
  className
13693
13752
  }) {
13694
13753
  var _a;
13695
- const [faqsExpanded, setFaqsExpanded] = React28.useState(false);
13696
- const [tripsExpanded, setTripsExpanded] = React28.useState(false);
13697
- const [filterValue, setFilterValue] = React28.useState({});
13698
- const [sort, setSort] = React28.useState(
13754
+ const [faqsExpanded, setFaqsExpanded] = React29.useState(false);
13755
+ const [tripsExpanded, setTripsExpanded] = React29.useState(false);
13756
+ const [filterValue, setFilterValue] = React29.useState({});
13757
+ const [sort, setSort] = React29.useState(
13699
13758
  defaultSort != null ? defaultSort : (_a = sortOptions == null ? void 0 : sortOptions[0]) == null ? void 0 : _a.id
13700
13759
  );
13701
- const sortedTrips = React28.useMemo(
13702
- () => [...trips].sort((a, b) => {
13703
- const af = a.featured ? 1 : 0;
13704
- const bf = b.featured ? 1 : 0;
13705
- return bf - af;
13706
- }),
13707
- [trips]
13708
- );
13760
+ const sortedTrips = React29.useMemo(() => {
13761
+ const active = Object.entries(filterValue).filter(
13762
+ ([, vals]) => vals && vals.length > 0
13763
+ );
13764
+ const filtered = active.length ? trips.filter(
13765
+ (trip) => active.every(([groupId, selected]) => {
13766
+ var _a2, _b;
13767
+ const groupHasData = trips.some(
13768
+ (t) => {
13769
+ var _a3, _b2, _c;
13770
+ return ((_c = (_b2 = (_a3 = t.filterTags) == null ? void 0 : _a3[groupId]) == null ? void 0 : _b2.length) != null ? _c : 0) > 0;
13771
+ }
13772
+ );
13773
+ if (!groupHasData) return true;
13774
+ const tags = (_b = (_a2 = trip.filterTags) == null ? void 0 : _a2[groupId]) != null ? _b : [];
13775
+ return selected.some((id) => tags.includes(id));
13776
+ })
13777
+ ) : trips;
13778
+ const list = [...filtered];
13779
+ switch (sort) {
13780
+ case "price-asc":
13781
+ list.sort((a, b) => {
13782
+ var _a2, _b;
13783
+ return ((_a2 = a.priceValue) != null ? _a2 : Infinity) - ((_b = b.priceValue) != null ? _b : Infinity);
13784
+ });
13785
+ break;
13786
+ case "price-desc":
13787
+ list.sort((a, b) => {
13788
+ var _a2, _b;
13789
+ return ((_a2 = b.priceValue) != null ? _a2 : -Infinity) - ((_b = a.priceValue) != null ? _b : -Infinity);
13790
+ });
13791
+ break;
13792
+ case "duration-asc":
13793
+ list.sort((a, b) => {
13794
+ var _a2, _b;
13795
+ return ((_a2 = a.nights) != null ? _a2 : Infinity) - ((_b = b.nights) != null ? _b : Infinity);
13796
+ });
13797
+ break;
13798
+ case "duration-desc":
13799
+ list.sort((a, b) => {
13800
+ var _a2, _b;
13801
+ return ((_a2 = b.nights) != null ? _a2 : -Infinity) - ((_b = a.nights) != null ? _b : -Infinity);
13802
+ });
13803
+ break;
13804
+ default:
13805
+ list.sort((a, b) => (b.featured ? 1 : 0) - (a.featured ? 1 : 0));
13806
+ break;
13807
+ }
13808
+ return list;
13809
+ }, [trips, filterValue, sort]);
13709
13810
  return /* @__PURE__ */ jsxs("div", { className: cn("w-full", className), children: [
13710
13811
  /* @__PURE__ */ jsxs(
13711
13812
  "section",
@@ -13732,13 +13833,12 @@ function CategoryPage2({
13732
13833
  ] }),
13733
13834
  siteHeader && /* @__PURE__ */ jsx(
13734
13835
  SiteHeader,
13735
- {
13736
- links: Array.isArray(siteHeader) ? siteHeader : void 0,
13836
+ __spreadProps(__spreadValues({}, Array.isArray(siteHeader) ? { links: siteHeader } : typeof siteHeader === "object" ? siteHeader : {}), {
13737
13837
  position: "overlay"
13738
- }
13838
+ })
13739
13839
  ),
13740
13840
  /* @__PURE__ */ jsxs("div", { className: "relative mx-auto w-full max-w-6xl px-6 sm:px-8", children: [
13741
- breadcrumb && breadcrumb.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-3 flex items-center gap-1.5 flex-wrap", children: breadcrumb.map((crumb, i) => /* @__PURE__ */ jsxs(React28.Fragment, { children: [
13841
+ breadcrumb && breadcrumb.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-3 flex items-center gap-1.5 flex-wrap", children: breadcrumb.map((crumb, i) => /* @__PURE__ */ jsxs(React29.Fragment, { children: [
13742
13842
  i > 0 && /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-3 w-3 text-white/50 shrink-0" }),
13743
13843
  /* @__PURE__ */ jsx("span", { className: "text-xs text-white/70 font-ui", children: crumb.label })
13744
13844
  ] }, i)) }),
@@ -13759,7 +13859,7 @@ function CategoryPage2({
13759
13859
  ),
13760
13860
  /* @__PURE__ */ jsx("div", { className: "-mx-6 sm:-mx-8 px-6 sm:px-8 overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]", children: /* @__PURE__ */ jsx("div", { className: "inline-flex gap-5 min-w-max pb-2", children: popularTours.map((trip, i) => {
13761
13861
  var _b;
13762
- const _a2 = trip, { featured: _featured, variant: _variant } = _a2, cardProps = __objRest(_a2, ["featured", "variant"]);
13862
+ const _a2 = trip, { featured: _featured, variant: _variant, filterTags: _filterTags, priceValue: _priceValue } = _a2, cardProps = __objRest(_a2, ["featured", "variant", "filterTags", "priceValue"]);
13763
13863
  return /* @__PURE__ */ jsx(
13764
13864
  TripCard,
13765
13865
  __spreadProps(__spreadValues({}, cardProps), {
@@ -13786,9 +13886,9 @@ function CategoryPage2({
13786
13886
  }
13787
13887
  ) }),
13788
13888
  /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground font-ui mb-5", children: [
13789
- trips.length,
13889
+ sortedTrips.length,
13790
13890
  " ",
13791
- trips.length === 1 ? "trip" : "trips",
13891
+ sortedTrips.length === 1 ? "trip" : "trips",
13792
13892
  " found"
13793
13893
  ] }),
13794
13894
  (() => {
@@ -13796,7 +13896,7 @@ function CategoryPage2({
13796
13896
  const hiddenCount = sortedTrips.length - visibleTrips.length;
13797
13897
  return /* @__PURE__ */ jsxs(Fragment, { children: [
13798
13898
  /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-x-6 gap-y-8 lg:gap-x-[35px] lg:gap-y-[38px]", children: visibleTrips.map((trip, i) => {
13799
- const _a2 = trip, { featured: _featured } = _a2, cardProps = __objRest(_a2, ["featured"]);
13899
+ const _a2 = trip, { featured: _featured, filterTags: _filterTags, priceValue: _priceValue } = _a2, cardProps = __objRest(_a2, ["featured", "filterTags", "priceValue"]);
13800
13900
  return /* @__PURE__ */ jsx(
13801
13901
  TripCard,
13802
13902
  __spreadProps(__spreadValues({}, cardProps), {
@@ -14008,12 +14108,12 @@ function Toast({
14008
14108
  duration = 6e3,
14009
14109
  className
14010
14110
  }) {
14011
- const [mounted, setMounted] = React28.useState(false);
14012
- const [visible, setVisible] = React28.useState(true);
14013
- React28.useEffect(() => {
14111
+ const [mounted, setMounted] = React29.useState(false);
14112
+ const [visible, setVisible] = React29.useState(true);
14113
+ React29.useEffect(() => {
14014
14114
  setMounted(true);
14015
14115
  }, []);
14016
- React28.useEffect(() => {
14116
+ React29.useEffect(() => {
14017
14117
  if (duration === 0) return;
14018
14118
  const t = setTimeout(() => {
14019
14119
  setVisible(false);
@@ -15515,8 +15615,8 @@ function ShareWidget({
15515
15615
  title = "Invite friends & lower the price",
15516
15616
  className
15517
15617
  }) {
15518
- const [copied, setCopied] = React28.useState(false);
15519
- const [showToast, setShowToast] = React28.useState(false);
15618
+ const [copied, setCopied] = React29.useState(false);
15619
+ const [showToast, setShowToast] = React29.useState(false);
15520
15620
  const encodedUrl = encodeURIComponent(url);
15521
15621
  const encodedMsg = encodeURIComponent(`${message} ${url}`);
15522
15622
  const channels = [