@planetaexo/design-system 0.95.0 → 0.95.2

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
@@ -4,7 +4,7 @@ import { cva } from 'class-variance-authority';
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
- import { XIcon, ChevronDownIcon, CalendarIcon, SearchIcon, ChevronRightIcon, ArrowLeftIcon, CheckCircle2Icon, MapIcon, LogOutIcon, UsersIcon, CreditCardIcon, AlertCircleIcon, MinusIcon, PlusIcon, CircleCheckIcon, SlidersHorizontalIcon, ChevronLeftIcon, HomeIcon, SailboatIcon, CarIcon, WavesIcon, FootprintsIcon, InfoIcon, ClockIcon, CheckIcon, ChevronUpIcon, MenuIcon, UserIcon, SunIcon, MoonIcon, MapPinIcon, TwitterIcon, YoutubeIcon, LinkedinIcon, InstagramIcon, FacebookIcon, ArrowRightIcon, PackageIcon, BedDoubleIcon, UtensilsIcon, CompassIcon, BackpackIcon, CherryIcon, ReceiptIcon, Loader2Icon, SendIcon, CheckCircleIcon, ArrowDownIcon, SparkleIcon, Share2Icon, CopyIcon, Info, MailIcon, PhoneIcon, MessageCircleIcon, UserPlusIcon, ExternalLinkIcon, PencilIcon, Trash2Icon, UserMinusIcon, AlertTriangleIcon, ZoomInIcon, StarIcon as StarIcon$1, LayoutGridIcon } from 'lucide-react';
7
+ import { XIcon, ChevronDownIcon, CalendarIcon, SearchIcon, ChevronRightIcon, ArrowLeftIcon, CheckCircle2Icon, MapIcon, LogOutIcon, UsersIcon, CreditCardIcon, AlertCircleIcon, MinusIcon, PlusIcon, CircleCheckIcon, SlidersHorizontalIcon, ChevronLeftIcon, HomeIcon, SailboatIcon, CarIcon, WavesIcon, FootprintsIcon, InfoIcon, ClockIcon, CheckIcon, ChevronUpIcon, MenuIcon, UserIcon, SunIcon, MoonIcon, MapPinIcon, TwitterIcon, YoutubeIcon, LinkedinIcon, InstagramIcon, FacebookIcon, ArrowRightIcon, PackageIcon, BedDoubleIcon, UtensilsIcon, CompassIcon, BackpackIcon, CherryIcon, ReceiptIcon, Loader2Icon, SendIcon, CheckCircleIcon, ArrowDownIcon, SparkleIcon, Share2Icon, CopyIcon, SparklesIcon, Info, MailIcon, PhoneIcon, MessageCircleIcon, UserPlusIcon, ExternalLinkIcon, PencilIcon, Trash2Icon, UserMinusIcon, AlertTriangleIcon, ZoomInIcon, StarIcon as StarIcon$1, LayoutGridIcon } from 'lucide-react';
8
8
  import { Separator as Separator$1 } from '@base-ui/react/separator';
9
9
  import { Dialog as Dialog$1 } from '@base-ui/react/dialog';
10
10
  import { Button as Button$1 } from '@base-ui/react/button';
@@ -17,6 +17,7 @@ import { mergeProps } from '@base-ui/react/merge-props';
17
17
  import { useRender } from '@base-ui/react/use-render';
18
18
  import { createPortal } from 'react-dom';
19
19
  import { Input as Input$1 } from '@base-ui/react/input';
20
+ import { Tooltip as Tooltip$1 } from '@base-ui/react/tooltip';
20
21
 
21
22
  var __defProp = Object.defineProperty;
22
23
  var __defProps = Object.defineProperties;
@@ -18072,9 +18073,15 @@ var STATUS_MAP = {
18072
18073
  "operating": { label: "Operating", variant: "default", dot: "bg-primary-foreground" },
18073
18074
  "cancelled": { label: "Cancelled", variant: "destructive", dot: "bg-destructive" }
18074
18075
  };
18075
- function StatusBadge2({ status, dot = true, label, className }) {
18076
+ function StatusBadge2({
18077
+ status,
18078
+ dot = true,
18079
+ label,
18080
+ variant,
18081
+ className
18082
+ }) {
18076
18083
  const config = STATUS_MAP[status];
18077
- return /* @__PURE__ */ jsxs(Badge, { variant: config.variant, className: cn("gap-1.5", className), children: [
18084
+ return /* @__PURE__ */ jsxs(Badge, { variant: variant != null ? variant : config.variant, className: cn("gap-1.5", className), children: [
18078
18085
  dot && /* @__PURE__ */ jsx(
18079
18086
  "span",
18080
18087
  {
@@ -18569,6 +18576,561 @@ function StickyBookingCard({
18569
18576
  }
18570
18577
  );
18571
18578
  }
18579
+ function TooltipProvider(_a) {
18580
+ var _b = _a, {
18581
+ delay = 200,
18582
+ closeDelay = 0
18583
+ } = _b, props = __objRest(_b, [
18584
+ "delay",
18585
+ "closeDelay"
18586
+ ]);
18587
+ return /* @__PURE__ */ jsx(
18588
+ Tooltip$1.Provider,
18589
+ __spreadValues({
18590
+ "data-slot": "tooltip-provider",
18591
+ delay,
18592
+ closeDelay
18593
+ }, props)
18594
+ );
18595
+ }
18596
+ function Tooltip(_a) {
18597
+ var props = __objRest(_a, []);
18598
+ return /* @__PURE__ */ jsx(Tooltip$1.Root, __spreadValues({ "data-slot": "tooltip" }, props));
18599
+ }
18600
+ function TooltipTrigger(_a) {
18601
+ var props = __objRest(_a, []);
18602
+ return /* @__PURE__ */ jsx(Tooltip$1.Trigger, __spreadValues({ "data-slot": "tooltip-trigger" }, props));
18603
+ }
18604
+ function TooltipContent(_a) {
18605
+ var _b = _a, {
18606
+ className,
18607
+ children,
18608
+ side = "top",
18609
+ sideOffset = 8,
18610
+ align = "center",
18611
+ showArrow = true
18612
+ } = _b, props = __objRest(_b, [
18613
+ "className",
18614
+ "children",
18615
+ "side",
18616
+ "sideOffset",
18617
+ "align",
18618
+ "showArrow"
18619
+ ]);
18620
+ return /* @__PURE__ */ jsx(Tooltip$1.Portal, { children: /* @__PURE__ */ jsx(
18621
+ Tooltip$1.Positioner,
18622
+ {
18623
+ side,
18624
+ sideOffset,
18625
+ align,
18626
+ className: "isolate z-50",
18627
+ children: /* @__PURE__ */ jsxs(
18628
+ Tooltip$1.Popup,
18629
+ __spreadProps(__spreadValues({
18630
+ "data-slot": "tooltip-content",
18631
+ className: cn(
18632
+ // Legible system sans (not the display UI font), bumped size + padding,
18633
+ // strong contrast and a defined shadow/ring for visibility.
18634
+ "z-50 w-max max-w-72 origin-(--transform-origin) rounded-xl bg-foreground px-3.5 py-2.5 text-[13px] font-normal leading-snug text-background shadow-lg ring-1 ring-foreground/10 outline-hidden [font-family:ui-sans-serif,system-ui,-apple-system,'Segoe_UI',Roboto,Helvetica,Arial,sans-serif]",
18635
+ "data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1",
18636
+ "data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
18637
+ className
18638
+ )
18639
+ }, props), {
18640
+ children: [
18641
+ showArrow && /* @__PURE__ */ jsx(Tooltip$1.Arrow, { className: "data-[side=bottom]:top-[-7px] data-[side=top]:bottom-[-7px] data-[side=top]:rotate-180", children: /* @__PURE__ */ jsx("svg", { width: "14", height: "7", viewBox: "0 0 14 7", className: "fill-foreground", children: /* @__PURE__ */ jsx("path", { d: "M0 7 L7 0 L14 7 Z" }) }) }),
18642
+ children
18643
+ ]
18644
+ })
18645
+ )
18646
+ }
18647
+ ) });
18648
+ }
18649
+ var DEFAULT_LABELS15 = {
18650
+ title: "Join an existing group",
18651
+ chooseMonth: "Choose month",
18652
+ allMonths: "All",
18653
+ from: "From",
18654
+ travellers: (c, cap) => `${c}/${cap} travellers`,
18655
+ travellersOf: (c, cap) => `${c} of ${cap} travellers`,
18656
+ seeMore: (n) => `See more (${n})`,
18657
+ confirmsIn: (n) => `${n} more to confirm`,
18658
+ fillingFast: (n) => `Filling fast \xB7 ${n} ${n === 1 ? "spot" : "spots"} left`,
18659
+ atFull: "at full group",
18660
+ join: "Join this group",
18661
+ dynamicPricingTitle: "Dynamic pricing",
18662
+ dynamicPricingBody: "Adventure Together departure \u2014 the price per person drops as more travellers join.",
18663
+ startGroupTitle: "Can't find a date that suits you?",
18664
+ startGroupBody: "Start your own group on the dates you want.",
18665
+ startGroupCta: "Start a new group"
18666
+ };
18667
+ function isJoinable(d) {
18668
+ return d.travellers < d.capacity && d.status !== "cancelled" && d.status !== "full" && d.status !== "draft";
18669
+ }
18670
+ function pickFeatured(list) {
18671
+ const candidates = list.filter(isJoinable);
18672
+ if (!candidates.length) return void 0;
18673
+ return candidates.reduce(
18674
+ (best, d) => d.travellers / d.capacity > best.travellers / best.capacity ? d : best
18675
+ );
18676
+ }
18677
+ function fmtDates(d) {
18678
+ var _a;
18679
+ return (_a = d.dateLabel) != null ? _a : d.endDate ? `${d.startDate} to ${d.endDate}` : d.startDate;
18680
+ }
18681
+ function DeparturesList({
18682
+ departures,
18683
+ years,
18684
+ defaultYear,
18685
+ initialVisible = 4,
18686
+ featured = true,
18687
+ showStartGroup = true,
18688
+ startGroupHref,
18689
+ onStartGroup,
18690
+ onSelect,
18691
+ labels: labelsProp,
18692
+ className
18693
+ }) {
18694
+ const labels = React20.useMemo(
18695
+ () => __spreadValues(__spreadValues({}, DEFAULT_LABELS15), labelsProp),
18696
+ [labelsProp]
18697
+ );
18698
+ const yearList = React20.useMemo(() => {
18699
+ if (years && years.length) return years;
18700
+ return Array.from(new Set(departures.map((d) => d.year))).sort(
18701
+ (a, b) => a - b
18702
+ );
18703
+ }, [years, departures]);
18704
+ const [year, setYear] = React20.useState(defaultYear != null ? defaultYear : yearList[0]);
18705
+ const [month, setMonth] = React20.useState(null);
18706
+ const [expanded, setExpanded] = React20.useState(false);
18707
+ const selectYear = (y) => {
18708
+ setYear(y);
18709
+ setMonth(null);
18710
+ setExpanded(false);
18711
+ };
18712
+ const inYear = React20.useMemo(
18713
+ () => departures.filter((d) => d.year === year),
18714
+ [departures, year]
18715
+ );
18716
+ const months = React20.useMemo(() => {
18717
+ var _a;
18718
+ const counts = /* @__PURE__ */ new Map();
18719
+ for (const d of inYear) counts.set(d.month, ((_a = counts.get(d.month)) != null ? _a : 0) + 1);
18720
+ return Array.from(counts, ([name, count]) => ({ name, count }));
18721
+ }, [inYear]);
18722
+ const filtered = React20.useMemo(
18723
+ () => month ? inYear.filter((d) => d.month === month) : inYear,
18724
+ [inYear, month]
18725
+ );
18726
+ const featuredDeparture = React20.useMemo(() => {
18727
+ if (featured === false) return void 0;
18728
+ if (typeof featured === "string")
18729
+ return filtered.find((d) => d.id === featured);
18730
+ return pickFeatured(filtered);
18731
+ }, [featured, filtered]);
18732
+ const rows = React20.useMemo(
18733
+ () => filtered.filter((d) => d.id !== (featuredDeparture == null ? void 0 : featuredDeparture.id)),
18734
+ [filtered, featuredDeparture]
18735
+ );
18736
+ const visible = expanded ? rows : rows.slice(0, initialVisible);
18737
+ const remaining = rows.length - visible.length;
18738
+ return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(
18739
+ "section",
18740
+ {
18741
+ className: cn(
18742
+ "rounded-3xl border border-border bg-card p-5 text-card-foreground sm:p-6",
18743
+ className
18744
+ ),
18745
+ children: [
18746
+ /* @__PURE__ */ jsx("h3", { className: "font-display text-lg font-extrabold tracking-tight sm:text-xl", children: labels.title }),
18747
+ yearList.length > 1 && /* @__PURE__ */ jsxs("div", { className: "mt-4 mb-2 flex items-center justify-between gap-3", children: [
18748
+ /* @__PURE__ */ jsx("p", { className: "font-ui text-xs uppercase tracking-wider text-muted-foreground", children: labels.chooseMonth }),
18749
+ /* @__PURE__ */ jsx(
18750
+ "div",
18751
+ {
18752
+ role: "tablist",
18753
+ "aria-label": "Year",
18754
+ className: "inline-flex rounded-full border border-border p-0.5",
18755
+ children: yearList.map((y) => {
18756
+ const active = y === year;
18757
+ return /* @__PURE__ */ jsx(
18758
+ "button",
18759
+ {
18760
+ role: "tab",
18761
+ type: "button",
18762
+ "aria-selected": active,
18763
+ onClick: () => selectYear(y),
18764
+ className: cn(
18765
+ "cursor-pointer rounded-full px-3.5 py-1 font-ui text-xs font-bold leading-none transition-colors",
18766
+ active ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:text-foreground"
18767
+ ),
18768
+ children: y
18769
+ },
18770
+ y
18771
+ );
18772
+ })
18773
+ }
18774
+ )
18775
+ ] }),
18776
+ months.length > 1 && /* @__PURE__ */ jsxs(
18777
+ "div",
18778
+ {
18779
+ role: "tablist",
18780
+ "aria-label": labels.chooseMonth,
18781
+ className: "-mx-1 flex gap-1.5 overflow-x-auto px-1 py-1 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
18782
+ children: [
18783
+ /* @__PURE__ */ jsx(
18784
+ MonthChip,
18785
+ {
18786
+ label: labels.allMonths,
18787
+ selected: month === null,
18788
+ onClick: () => {
18789
+ setMonth(null);
18790
+ setExpanded(false);
18791
+ }
18792
+ }
18793
+ ),
18794
+ months.map((m) => /* @__PURE__ */ jsx(
18795
+ MonthChip,
18796
+ {
18797
+ label: m.name,
18798
+ count: m.count,
18799
+ selected: month === m.name,
18800
+ onClick: () => {
18801
+ setMonth(m.name);
18802
+ setExpanded(false);
18803
+ }
18804
+ },
18805
+ m.name
18806
+ ))
18807
+ ]
18808
+ }
18809
+ ),
18810
+ featuredDeparture && /* @__PURE__ */ jsx(
18811
+ FeaturedDeparture,
18812
+ {
18813
+ departure: featuredDeparture,
18814
+ labels,
18815
+ onSelect
18816
+ }
18817
+ ),
18818
+ visible.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-col gap-2.5", children: visible.map((d) => /* @__PURE__ */ jsx(
18819
+ DepartureRow,
18820
+ {
18821
+ departure: d,
18822
+ labels,
18823
+ onSelect
18824
+ },
18825
+ d.id
18826
+ )) }),
18827
+ remaining > 0 && /* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxs(
18828
+ "button",
18829
+ {
18830
+ type: "button",
18831
+ onClick: () => setExpanded(true),
18832
+ className: "inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-border bg-card px-4 py-2 font-display text-xs font-bold text-foreground transition-colors hover:bg-muted/50",
18833
+ children: [
18834
+ /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4" }),
18835
+ labels.seeMore(remaining)
18836
+ ]
18837
+ }
18838
+ ) }),
18839
+ showStartGroup && /* @__PURE__ */ jsxs("div", { className: "mt-5 flex flex-wrap items-center gap-4 rounded-2xl border border-primary/25 bg-primary/10 p-5 sm:p-6", children: [
18840
+ /* @__PURE__ */ jsxs("div", { className: "min-w-44 flex-1", children: [
18841
+ /* @__PURE__ */ jsx("strong", { className: "block font-display text-base font-extrabold leading-tight text-foreground sm:text-lg", children: labels.startGroupTitle }),
18842
+ /* @__PURE__ */ jsx("span", { className: "mt-0.5 block text-sm leading-snug text-primary-800 dark:text-primary-300", children: labels.startGroupBody })
18843
+ ] }),
18844
+ /* @__PURE__ */ jsx(
18845
+ StartGroupCta,
18846
+ {
18847
+ href: startGroupHref,
18848
+ onClick: onStartGroup,
18849
+ label: labels.startGroupCta
18850
+ }
18851
+ )
18852
+ ] })
18853
+ ]
18854
+ }
18855
+ ) });
18856
+ }
18857
+ function FeaturedDeparture({
18858
+ departure: d,
18859
+ labels,
18860
+ onSelect
18861
+ }) {
18862
+ var _a;
18863
+ const spotsLeft = d.capacity - d.travellers;
18864
+ const needsQuorum = d.min != null && d.travellers < d.min;
18865
+ const eyebrow = needsQuorum ? labels.confirmsIn(d.min - d.travellers) : labels.fillingFast(spotsLeft);
18866
+ const ladder = d.dynamicPricing && d.lowestPrice && spotsLeft > 0;
18867
+ const cta = d.href ? /* @__PURE__ */ jsx("a", { href: d.href, className: buttonVariants({ variant: "primary", size: "md" }), children: labels.join }) : /* @__PURE__ */ jsx(Button, { variant: "primary", size: "md", onClick: () => onSelect == null ? void 0 : onSelect(d), children: labels.join });
18868
+ return /* @__PURE__ */ jsxs("div", { className: "mt-4 rounded-2xl border border-primary/30 bg-gradient-to-b from-primary/[0.07] to-primary/[0.02] p-4 sm:p-5", children: [
18869
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
18870
+ /* @__PURE__ */ jsx(
18871
+ "span",
18872
+ {
18873
+ "aria-hidden": true,
18874
+ className: "size-1.5 rounded-full bg-primary motion-safe:animate-pulse"
18875
+ }
18876
+ ),
18877
+ /* @__PURE__ */ jsx("span", { className: "font-ui text-[11px] font-bold uppercase tracking-wider text-primary-800 dark:text-primary-400", children: eyebrow })
18878
+ ] }),
18879
+ /* @__PURE__ */ jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-x-3 gap-y-2", children: [
18880
+ /* @__PURE__ */ jsx("span", { className: "font-display text-lg font-extrabold tracking-tight whitespace-nowrap", children: fmtDates(d) }),
18881
+ /* @__PURE__ */ jsx(StatusChip, { status: d.status }),
18882
+ d.dynamicPricing && /* @__PURE__ */ jsxs(Tooltip, { children: [
18883
+ /* @__PURE__ */ jsx(
18884
+ TooltipTrigger,
18885
+ {
18886
+ render: /* @__PURE__ */ jsx(
18887
+ "button",
18888
+ {
18889
+ type: "button",
18890
+ "aria-label": labels.dynamicPricingTitle,
18891
+ className: "ml-auto inline-flex cursor-help items-center text-primary"
18892
+ }
18893
+ ),
18894
+ children: /* @__PURE__ */ jsx(SparklesIcon, { className: "size-[18px]", strokeWidth: 1.8 })
18895
+ }
18896
+ ),
18897
+ /* @__PURE__ */ jsxs(TooltipContent, { children: [
18898
+ /* @__PURE__ */ jsx("span", { className: "block font-bold", children: labels.dynamicPricingTitle }),
18899
+ labels.dynamicPricingBody
18900
+ ] })
18901
+ ] })
18902
+ ] }),
18903
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-x-3 gap-y-2", children: [
18904
+ d.participants && d.participants.length > 0 && /* @__PURE__ */ jsx(AvatarStack, { participants: d.participants, capacity: d.capacity }),
18905
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 font-sans text-sm text-muted-foreground", children: [
18906
+ /* @__PURE__ */ jsx(UsersIcon, { className: "size-4", strokeWidth: 1.6, "aria-hidden": true }),
18907
+ labels.travellersOf(d.travellers, d.capacity)
18908
+ ] })
18909
+ ] }),
18910
+ /* @__PURE__ */ jsx(
18911
+ GroupProgressBar,
18912
+ {
18913
+ className: "mt-3",
18914
+ current: d.travellers,
18915
+ min: (_a = d.min) != null ? _a : d.travellers,
18916
+ max: d.capacity,
18917
+ hideLabels: d.min == null
18918
+ }
18919
+ ),
18920
+ /* @__PURE__ */ jsxs("div", { className: "mt-4 flex flex-wrap items-end justify-between gap-3", children: [
18921
+ /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-2", children: [
18922
+ /* @__PURE__ */ jsxs("span", { className: "font-display text-xl font-extrabold tracking-tight whitespace-nowrap", children: [
18923
+ /* @__PURE__ */ jsx("span", { className: "mr-1 align-middle text-[10px] font-bold uppercase tracking-wider text-muted-foreground", children: labels.from }),
18924
+ d.price
18925
+ ] }),
18926
+ ladder && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 font-sans text-sm font-semibold text-success whitespace-nowrap", children: [
18927
+ /* @__PURE__ */ jsx(
18928
+ ArrowRightIcon,
18929
+ {
18930
+ className: "size-3.5 text-muted-foreground",
18931
+ strokeWidth: 2.2,
18932
+ "aria-hidden": true
18933
+ }
18934
+ ),
18935
+ d.lowestPrice,
18936
+ /* @__PURE__ */ jsx("span", { className: "font-normal text-muted-foreground", children: labels.atFull })
18937
+ ] })
18938
+ ] }),
18939
+ cta
18940
+ ] })
18941
+ ] });
18942
+ }
18943
+ function AvatarStack({
18944
+ participants,
18945
+ capacity
18946
+ }) {
18947
+ const shown = participants.slice(0, 4);
18948
+ const extra = Math.max(0, participants.length - shown.length);
18949
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center -space-x-2", "aria-hidden": true, children: [
18950
+ shown.map((p, i) => {
18951
+ var _a;
18952
+ return /* @__PURE__ */ jsx(
18953
+ "span",
18954
+ {
18955
+ title: p.country ? `${p.firstName} \xB7 ${p.country}` : p.firstName,
18956
+ className: "flex size-7 items-center justify-center rounded-full border-2 border-card bg-primary/10 text-sm ring-0",
18957
+ children: (_a = p.flag) != null ? _a : p.firstName.charAt(0)
18958
+ },
18959
+ `${p.firstName}-${i}`
18960
+ );
18961
+ }),
18962
+ extra > 0 && /* @__PURE__ */ jsxs("span", { className: "flex size-7 items-center justify-center rounded-full border-2 border-card bg-muted font-ui text-[11px] font-bold text-muted-foreground", children: [
18963
+ "+",
18964
+ extra
18965
+ ] }),
18966
+ capacity > participants.length && participants.length < 5 && /* @__PURE__ */ jsx("span", { className: "flex size-7 items-center justify-center rounded-full border-2 border-dashed border-border bg-card text-muted-foreground/50", children: /* @__PURE__ */ jsx("span", { className: "text-base leading-none", children: "+" }) })
18967
+ ] });
18968
+ }
18969
+ function MonthChip({
18970
+ label,
18971
+ count,
18972
+ selected,
18973
+ onClick
18974
+ }) {
18975
+ return /* @__PURE__ */ jsxs(
18976
+ "button",
18977
+ {
18978
+ role: "tab",
18979
+ type: "button",
18980
+ "aria-selected": selected,
18981
+ onClick,
18982
+ className: cn(
18983
+ "inline-flex shrink-0 cursor-pointer items-center gap-1.5 rounded-full border px-3 py-1.5 font-ui text-xs leading-none transition-colors",
18984
+ selected ? "border-primary bg-primary/10 font-semibold text-primary-800 dark:text-primary-400" : "border-border text-foreground hover:border-foreground/30"
18985
+ ),
18986
+ children: [
18987
+ label,
18988
+ count != null && /* @__PURE__ */ jsx(
18989
+ "span",
18990
+ {
18991
+ className: cn(
18992
+ "inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-full px-1 text-[11px]",
18993
+ selected ? "bg-primary/15 text-primary-800 dark:text-primary-400" : "bg-muted text-muted-foreground"
18994
+ ),
18995
+ children: count
18996
+ }
18997
+ )
18998
+ ]
18999
+ }
19000
+ );
19001
+ }
19002
+ function StatusChip({ status }) {
19003
+ return /* @__PURE__ */ jsx(
19004
+ Chip,
19005
+ {
19006
+ variant: "solid",
19007
+ size: "sm",
19008
+ className: "hover:bg-muted hover:text-foreground/80",
19009
+ children: STATUS_MAP[status].label
19010
+ }
19011
+ );
19012
+ }
19013
+ function DepartureRow({
19014
+ departure: d,
19015
+ labels,
19016
+ onSelect
19017
+ }) {
19018
+ var _a;
19019
+ const dateLabel = fmtDates(d);
19020
+ const statusTip = (_a = labels.statusTooltips) == null ? void 0 : _a[d.status];
19021
+ const pct = Math.max(0, Math.min(100, d.travellers / d.capacity * 100));
19022
+ const overlayClass = "absolute inset-0 z-0 rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary";
19023
+ const statusBadge = statusTip ? /* @__PURE__ */ jsxs(Tooltip, { children: [
19024
+ /* @__PURE__ */ jsx(
19025
+ TooltipTrigger,
19026
+ {
19027
+ render: /* @__PURE__ */ jsx(
19028
+ "span",
19029
+ {
19030
+ tabIndex: 0,
19031
+ className: "pointer-events-auto cursor-help outline-hidden"
19032
+ }
19033
+ ),
19034
+ children: /* @__PURE__ */ jsx(StatusChip, { status: d.status })
19035
+ }
19036
+ ),
19037
+ /* @__PURE__ */ jsxs(TooltipContent, { children: [
19038
+ /* @__PURE__ */ jsx("span", { className: "block font-bold", children: statusTip.title }),
19039
+ statusTip.body
19040
+ ] })
19041
+ ] }) : /* @__PURE__ */ jsx(StatusChip, { status: d.status });
19042
+ return /* @__PURE__ */ jsxs("div", { className: "group relative grid grid-cols-[1fr_auto] items-center gap-x-3 gap-y-2 overflow-hidden rounded-2xl border border-border p-3.5 pb-4 transition-colors hover:border-foreground/25 hover:bg-muted/40 has-focus-visible:border-foreground/25 sm:flex sm:flex-nowrap sm:gap-4", children: [
19043
+ d.href ? /* @__PURE__ */ jsx("a", { href: d.href, "aria-label": dateLabel, className: overlayClass }) : /* @__PURE__ */ jsx(
19044
+ "button",
19045
+ {
19046
+ type: "button",
19047
+ "aria-label": dateLabel,
19048
+ onClick: () => onSelect == null ? void 0 : onSelect(d),
19049
+ className: cn(overlayClass, "w-full text-left")
19050
+ }
19051
+ ),
19052
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none relative z-10 font-display text-sm font-extrabold tracking-tight whitespace-nowrap sm:order-1", children: dateLabel }),
19053
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none relative z-10 justify-self-end sm:order-3 sm:ml-auto", children: statusBadge }),
19054
+ /* @__PURE__ */ jsxs("span", { className: "pointer-events-none relative z-10 inline-flex items-center gap-2 sm:order-2", children: [
19055
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 font-sans text-sm text-muted-foreground whitespace-nowrap", children: [
19056
+ /* @__PURE__ */ jsx(UsersIcon, { className: "size-4", strokeWidth: 1.6 }),
19057
+ labels.travellers(d.travellers, d.capacity)
19058
+ ] }),
19059
+ d.dynamicPricing && /* @__PURE__ */ jsxs(Tooltip, { children: [
19060
+ /* @__PURE__ */ jsx(
19061
+ TooltipTrigger,
19062
+ {
19063
+ render: /* @__PURE__ */ jsx(
19064
+ "button",
19065
+ {
19066
+ type: "button",
19067
+ "aria-label": labels.dynamicPricingTitle,
19068
+ className: "pointer-events-auto inline-flex cursor-help items-center text-primary"
19069
+ }
19070
+ ),
19071
+ children: /* @__PURE__ */ jsx(SparklesIcon, { className: "size-[18px]", strokeWidth: 1.8 })
19072
+ }
19073
+ ),
19074
+ /* @__PURE__ */ jsxs(TooltipContent, { children: [
19075
+ /* @__PURE__ */ jsx("span", { className: "block font-bold", children: labels.dynamicPricingTitle }),
19076
+ labels.dynamicPricingBody
19077
+ ] })
19078
+ ] })
19079
+ ] }),
19080
+ /* @__PURE__ */ jsxs("span", { className: "pointer-events-none relative z-10 flex items-center justify-self-end gap-3 sm:order-4", children: [
19081
+ /* @__PURE__ */ jsxs("span", { className: "w-[88px] text-right font-display text-sm font-extrabold whitespace-nowrap", children: [
19082
+ /* @__PURE__ */ jsx("span", { className: "block text-[10px] font-bold uppercase tracking-wider text-muted-foreground", children: labels.from }),
19083
+ d.price
19084
+ ] }),
19085
+ /* @__PURE__ */ jsx(
19086
+ ArrowRightIcon,
19087
+ {
19088
+ className: "size-5 shrink-0 text-primary transition-transform group-hover:translate-x-0.5",
19089
+ strokeWidth: 2.2,
19090
+ "aria-hidden": true
19091
+ }
19092
+ )
19093
+ ] }),
19094
+ /* @__PURE__ */ jsx(
19095
+ "span",
19096
+ {
19097
+ "aria-hidden": true,
19098
+ className: "pointer-events-none absolute inset-x-0 bottom-0 h-[3px] bg-transparent",
19099
+ children: /* @__PURE__ */ jsx(
19100
+ "span",
19101
+ {
19102
+ className: cn(
19103
+ "block h-full rounded-full transition-[width] duration-500",
19104
+ d.travellers >= d.capacity ? "bg-success/60" : "bg-primary/45"
19105
+ ),
19106
+ style: { width: `${pct}%` }
19107
+ }
19108
+ )
19109
+ }
19110
+ )
19111
+ ] });
19112
+ }
19113
+ function StartGroupCta({
19114
+ href,
19115
+ onClick,
19116
+ label
19117
+ }) {
19118
+ const cls = "group/cta inline-flex shrink-0 cursor-pointer items-center gap-2 rounded-full bg-primary px-6 py-3 font-display text-sm font-bold text-primary-foreground shadow-sm transition-all hover:bg-primary/90 hover:shadow-md";
19119
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
19120
+ label,
19121
+ /* @__PURE__ */ jsx(
19122
+ ArrowRightIcon,
19123
+ {
19124
+ className: "size-4 transition-transform group-hover/cta:translate-x-0.5",
19125
+ strokeWidth: 2.2
19126
+ }
19127
+ )
19128
+ ] });
19129
+ if (href) {
19130
+ return /* @__PURE__ */ jsx("a", { href, className: cls, children: content });
19131
+ }
19132
+ return /* @__PURE__ */ jsx("button", { type: "button", onClick, className: cls, children: content });
19133
+ }
18572
19134
  var DEFAULT_TRUSTPILOT = {
18573
19135
  businessUnitId: "6171e6a56fc555750dd81ae7",
18574
19136
  templateId: "5419b732fbfb950b10de65e5",
@@ -20481,6 +21043,6 @@ function SegmentedControl({
20481
21043
  );
20482
21044
  }
20483
21045
 
20484
- export { ActivityCard, AdventureExplorer, AgentContactCard, Alert, AskExo, BirthDateField, BlogCard, BlogJournal, BlogPost, BookingAdventureCard, BookingCancellationEmail, BookingConfirmedCard, BookingCreatedEmail, BookingDetails, BookingForm, BookingOtpEmail, BookingPartialCancellationEmail, BookingPaymentConfirmationEmail, BookingShell, BookingSummary, Button, COUNTRIES, CancellationForm, CancellationRequestReceivedEmail, CategoryPage2, Chip, CounterField, CountrySearchField, CtaBanner, DEFAULT_FOOTER_BADGES, DEFAULT_FOOTER_DESTINATIONS, DEFAULT_FOOTER_LANGUAGES, DEFAULT_FOOTER_LEGAL, DEFAULT_FOOTER_PAGES, DEFAULT_FOOTER_SOCIALS, DEFAULT_FOOTER_THEMES, DEFAULT_HEADER_LINKS, DEFAULT_LANGUAGES, STATUS_MAP as DEPARTURE_STATUS_MAP, DatePickerField, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, ExoOrb, FilterPanel, FloatingInput, FloatingSelect, GroupProgressBar, GroupStatusBanner, HomeHeader, Itinerary, ItineraryDay, LOGO_PLANETAEXO_DATA_URI, LeadCapturePopup, MenuTrip, NewHome, NotificationEmail, OTPCodeInput, Offer, OfferAdventureCard, ParticipantCounter, ParticipantList, PartnerBookingCreatedEmail, PartnerRegistrationCompleteEmail, PaymentAmountSelector, PaymentDetailsBlock, PaymentMethodSelector, PaymentModalShell, PaymentReceiptEmail, PaymentReminderEmail, PhoneCountrySelect, PhotoGallery, PhotoTourProvider, Picture, PopularSearches, PriceProgress, PricingMatrixCard, PricingTrip, RegistrationForm, RegistrationProgressBar, RegistrationReminderEmail, RegistrationReminderIndividualEmail, RegistrationSuccessCard, ReviewsSpotlight, SegmentedControl, ShareWidget, SiteFooter, SiteHeader, StatusBadge2 as StatusBadge, StickyBookingCard, TERMS_ACCEPT_KEY, TermsSection, ThemeToggle, Toast, TransferDetailsBlock, TravellerFormInviteEmail, TripCard, TripHeader, TripPage, TrustpilotEmbed, USP, USPBand, buttonVariants, chipVariants, cn, emailTokens, formatCpf, getStripeAppearance, itineraryDaySpecIcons, stripeAppearance, validateCpf, webpVariantUrl, wrapEmailHtml };
21046
+ export { ActivityCard, AdventureExplorer, AgentContactCard, Alert, AskExo, BirthDateField, BlogCard, BlogJournal, BlogPost, BookingAdventureCard, BookingCancellationEmail, BookingConfirmedCard, BookingCreatedEmail, BookingDetails, BookingForm, BookingOtpEmail, BookingPartialCancellationEmail, BookingPaymentConfirmationEmail, BookingShell, BookingSummary, Button, COUNTRIES, CancellationForm, CancellationRequestReceivedEmail, CategoryPage2, Chip, CounterField, CountrySearchField, CtaBanner, DEFAULT_FOOTER_BADGES, DEFAULT_FOOTER_DESTINATIONS, DEFAULT_FOOTER_LANGUAGES, DEFAULT_FOOTER_LEGAL, DEFAULT_FOOTER_PAGES, DEFAULT_FOOTER_SOCIALS, DEFAULT_FOOTER_THEMES, DEFAULT_HEADER_LINKS, DEFAULT_LANGUAGES, STATUS_MAP as DEPARTURE_STATUS_MAP, DatePickerField, DeparturesList, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, ExoOrb, FilterPanel, FloatingInput, FloatingSelect, GroupProgressBar, GroupStatusBanner, HomeHeader, Itinerary, ItineraryDay, LOGO_PLANETAEXO_DATA_URI, LeadCapturePopup, MenuTrip, NewHome, NotificationEmail, OTPCodeInput, Offer, OfferAdventureCard, ParticipantCounter, ParticipantList, PartnerBookingCreatedEmail, PartnerRegistrationCompleteEmail, PaymentAmountSelector, PaymentDetailsBlock, PaymentMethodSelector, PaymentModalShell, PaymentReceiptEmail, PaymentReminderEmail, PhoneCountrySelect, PhotoGallery, PhotoTourProvider, Picture, PopularSearches, PriceProgress, PricingMatrixCard, PricingTrip, RegistrationForm, RegistrationProgressBar, RegistrationReminderEmail, RegistrationReminderIndividualEmail, RegistrationSuccessCard, ReviewsSpotlight, SegmentedControl, ShareWidget, SiteFooter, SiteHeader, StatusBadge2 as StatusBadge, StickyBookingCard, TERMS_ACCEPT_KEY, TermsSection, ThemeToggle, Toast, TransferDetailsBlock, TravellerFormInviteEmail, TripCard, TripHeader, TripPage, TrustpilotEmbed, USP, USPBand, buttonVariants, chipVariants, cn, emailTokens, formatCpf, getStripeAppearance, itineraryDaySpecIcons, stripeAppearance, validateCpf, webpVariantUrl, wrapEmailHtml };
20485
21047
  //# sourceMappingURL=index.js.map
20486
21048
  //# sourceMappingURL=index.js.map