@planetaexo/design-system 0.94.0 → 0.95.1

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 CHANGED
@@ -18,6 +18,7 @@ var mergeProps = require('@base-ui/react/merge-props');
18
18
  var useRender = require('@base-ui/react/use-render');
19
19
  var reactDom = require('react-dom');
20
20
  var input = require('@base-ui/react/input');
21
+ var tooltip = require('@base-ui/react/tooltip');
21
22
 
22
23
  function _interopNamespace(e) {
23
24
  if (e && e.__esModule) return e;
@@ -12562,7 +12563,7 @@ function PhotoTile({
12562
12563
  onClick,
12563
12564
  showCredit = false
12564
12565
  }) {
12565
- var _a, _b;
12566
+ var _a, _b, _c;
12566
12567
  return /* @__PURE__ */ jsxRuntime.jsxs(
12567
12568
  "button",
12568
12569
  {
@@ -12577,8 +12578,8 @@ function PhotoTile({
12577
12578
  /* @__PURE__ */ jsxRuntime.jsx(
12578
12579
  Picture,
12579
12580
  {
12580
- src: photo.src,
12581
- alt: (_b = photo.alt) != null ? _b : `Photo ${index + 1}`,
12581
+ src: (_b = photo.thumbSrc) != null ? _b : photo.src,
12582
+ alt: (_c = photo.alt) != null ? _c : `Photo ${index + 1}`,
12582
12583
  title: photo.caption,
12583
12584
  className: "w-full h-full object-cover transition-transform duration-700 group-hover:scale-105",
12584
12585
  loading: "lazy"
@@ -12695,7 +12696,7 @@ function MasonryGallery({
12695
12696
  const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
12696
12697
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
12697
12698
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "columns-2 sm:columns-3 gap-1 [&>*]:break-inside-avoid [&>*]:mb-1", children: visible.map((p, i) => {
12698
- var _a, _b;
12699
+ var _a, _b, _c;
12699
12700
  return /* @__PURE__ */ jsxRuntime.jsxs(
12700
12701
  "button",
12701
12702
  {
@@ -12707,8 +12708,8 @@ function MasonryGallery({
12707
12708
  /* @__PURE__ */ jsxRuntime.jsx(
12708
12709
  Picture,
12709
12710
  {
12710
- src: p.src,
12711
- alt: (_b = p.alt) != null ? _b : `Photo ${i + 1}`,
12711
+ src: (_b = p.thumbSrc) != null ? _b : p.src,
12712
+ alt: (_c = p.alt) != null ? _c : `Photo ${i + 1}`,
12712
12713
  title: p.caption,
12713
12714
  className: "w-full h-auto object-cover transition-transform duration-700 group-hover:scale-105",
12714
12715
  loading: "lazy"
@@ -12736,7 +12737,7 @@ function FilmstripGallery({
12736
12737
  onOpen
12737
12738
  }) {
12738
12739
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto flex gap-1 snap-x snap-mandatory pb-1 scrollbar-none", children: photos.map((p, i) => {
12739
- var _a, _b;
12740
+ var _a, _b, _c;
12740
12741
  return /* @__PURE__ */ jsxRuntime.jsxs(
12741
12742
  "button",
12742
12743
  {
@@ -12748,8 +12749,8 @@ function FilmstripGallery({
12748
12749
  /* @__PURE__ */ jsxRuntime.jsx(
12749
12750
  Picture,
12750
12751
  {
12751
- src: p.src,
12752
- alt: (_b = p.alt) != null ? _b : `Photo ${i + 1}`,
12752
+ src: (_b = p.thumbSrc) != null ? _b : p.src,
12753
+ alt: (_c = p.alt) != null ? _c : `Photo ${i + 1}`,
12753
12754
  title: p.caption,
12754
12755
  className: "h-full w-full object-cover transition-transform duration-700 group-hover:scale-105",
12755
12756
  loading: "lazy"
@@ -12803,7 +12804,7 @@ function FeaturedGallery({
12803
12804
  ] })
12804
12805
  ] }),
12805
12806
  expanded && extra.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1.5 overflow-x-auto flex gap-1.5 snap-x snap-mandatory scrollbar-none rounded-xl overflow-hidden pb-0", children: extra.map((p, i) => {
12806
- var _a, _b;
12807
+ var _a, _b, _c;
12807
12808
  return /* @__PURE__ */ jsxRuntime.jsxs(
12808
12809
  "button",
12809
12810
  {
@@ -12815,8 +12816,8 @@ function FeaturedGallery({
12815
12816
  /* @__PURE__ */ jsxRuntime.jsx(
12816
12817
  Picture,
12817
12818
  {
12818
- src: p.src,
12819
- alt: (_b = p.alt) != null ? _b : `Photo ${i + 4}`,
12819
+ src: (_b = p.thumbSrc) != null ? _b : p.src,
12820
+ alt: (_c = p.alt) != null ? _c : `Photo ${i + 4}`,
12820
12821
  title: p.caption,
12821
12822
  className: "h-full w-full object-cover transition-transform duration-700 group-hover:scale-105",
12822
12823
  loading: "lazy"
@@ -18093,9 +18094,15 @@ var STATUS_MAP = {
18093
18094
  "operating": { label: "Operating", variant: "default", dot: "bg-primary-foreground" },
18094
18095
  "cancelled": { label: "Cancelled", variant: "destructive", dot: "bg-destructive" }
18095
18096
  };
18096
- function StatusBadge2({ status, dot = true, label, className }) {
18097
+ function StatusBadge2({
18098
+ status,
18099
+ dot = true,
18100
+ label,
18101
+ variant,
18102
+ className
18103
+ }) {
18097
18104
  const config = STATUS_MAP[status];
18098
- return /* @__PURE__ */ jsxRuntime.jsxs(Badge, { variant: config.variant, className: cn("gap-1.5", className), children: [
18105
+ return /* @__PURE__ */ jsxRuntime.jsxs(Badge, { variant: variant != null ? variant : config.variant, className: cn("gap-1.5", className), children: [
18099
18106
  dot && /* @__PURE__ */ jsxRuntime.jsx(
18100
18107
  "span",
18101
18108
  {
@@ -18590,6 +18597,561 @@ function StickyBookingCard({
18590
18597
  }
18591
18598
  );
18592
18599
  }
18600
+ function TooltipProvider(_a) {
18601
+ var _b = _a, {
18602
+ delay = 200,
18603
+ closeDelay = 0
18604
+ } = _b, props = __objRest(_b, [
18605
+ "delay",
18606
+ "closeDelay"
18607
+ ]);
18608
+ return /* @__PURE__ */ jsxRuntime.jsx(
18609
+ tooltip.Tooltip.Provider,
18610
+ __spreadValues({
18611
+ "data-slot": "tooltip-provider",
18612
+ delay,
18613
+ closeDelay
18614
+ }, props)
18615
+ );
18616
+ }
18617
+ function Tooltip(_a) {
18618
+ var props = __objRest(_a, []);
18619
+ return /* @__PURE__ */ jsxRuntime.jsx(tooltip.Tooltip.Root, __spreadValues({ "data-slot": "tooltip" }, props));
18620
+ }
18621
+ function TooltipTrigger(_a) {
18622
+ var props = __objRest(_a, []);
18623
+ return /* @__PURE__ */ jsxRuntime.jsx(tooltip.Tooltip.Trigger, __spreadValues({ "data-slot": "tooltip-trigger" }, props));
18624
+ }
18625
+ function TooltipContent(_a) {
18626
+ var _b = _a, {
18627
+ className,
18628
+ children,
18629
+ side = "top",
18630
+ sideOffset = 8,
18631
+ align = "center",
18632
+ showArrow = true
18633
+ } = _b, props = __objRest(_b, [
18634
+ "className",
18635
+ "children",
18636
+ "side",
18637
+ "sideOffset",
18638
+ "align",
18639
+ "showArrow"
18640
+ ]);
18641
+ return /* @__PURE__ */ jsxRuntime.jsx(tooltip.Tooltip.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
18642
+ tooltip.Tooltip.Positioner,
18643
+ {
18644
+ side,
18645
+ sideOffset,
18646
+ align,
18647
+ className: "isolate z-50",
18648
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
18649
+ tooltip.Tooltip.Popup,
18650
+ __spreadProps(__spreadValues({
18651
+ "data-slot": "tooltip-content",
18652
+ className: cn(
18653
+ // Legible system sans (not the display UI font), bumped size + padding,
18654
+ // strong contrast and a defined shadow/ring for visibility.
18655
+ "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]",
18656
+ "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",
18657
+ "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",
18658
+ className
18659
+ )
18660
+ }, props), {
18661
+ children: [
18662
+ showArrow && /* @__PURE__ */ jsxRuntime.jsx(tooltip.Tooltip.Arrow, { className: "data-[side=bottom]:top-[-7px] data-[side=top]:bottom-[-7px] data-[side=top]:rotate-180", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "14", height: "7", viewBox: "0 0 14 7", className: "fill-foreground", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M0 7 L7 0 L14 7 Z" }) }) }),
18663
+ children
18664
+ ]
18665
+ })
18666
+ )
18667
+ }
18668
+ ) });
18669
+ }
18670
+ var DEFAULT_LABELS15 = {
18671
+ title: "Join an existing group",
18672
+ chooseMonth: "Choose month",
18673
+ allMonths: "All",
18674
+ from: "From",
18675
+ travellers: (c, cap) => `${c}/${cap} travellers`,
18676
+ travellersOf: (c, cap) => `${c} of ${cap} travellers`,
18677
+ seeMore: (n) => `See more (${n})`,
18678
+ confirmsIn: (n) => `${n} more to confirm`,
18679
+ fillingFast: (n) => `Filling fast \xB7 ${n} ${n === 1 ? "spot" : "spots"} left`,
18680
+ atFull: "at full group",
18681
+ join: "Join this group",
18682
+ dynamicPricingTitle: "Dynamic pricing",
18683
+ dynamicPricingBody: "Adventure Together departure \u2014 the price per person drops as more travellers join.",
18684
+ startGroupTitle: "Can't find a date that suits you?",
18685
+ startGroupBody: "Start your own group on the dates you want.",
18686
+ startGroupCta: "Start a new group"
18687
+ };
18688
+ function isJoinable(d) {
18689
+ return d.travellers < d.capacity && d.status !== "cancelled" && d.status !== "full" && d.status !== "draft";
18690
+ }
18691
+ function pickFeatured(list) {
18692
+ const candidates = list.filter(isJoinable);
18693
+ if (!candidates.length) return void 0;
18694
+ return candidates.reduce(
18695
+ (best, d) => d.travellers / d.capacity > best.travellers / best.capacity ? d : best
18696
+ );
18697
+ }
18698
+ function fmtDates(d) {
18699
+ var _a;
18700
+ return (_a = d.dateLabel) != null ? _a : d.endDate ? `${d.startDate} to ${d.endDate}` : d.startDate;
18701
+ }
18702
+ function DeparturesList({
18703
+ departures,
18704
+ years,
18705
+ defaultYear,
18706
+ initialVisible = 4,
18707
+ featured = true,
18708
+ showStartGroup = true,
18709
+ startGroupHref,
18710
+ onStartGroup,
18711
+ onSelect,
18712
+ labels: labelsProp,
18713
+ className
18714
+ }) {
18715
+ const labels = React20__namespace.useMemo(
18716
+ () => __spreadValues(__spreadValues({}, DEFAULT_LABELS15), labelsProp),
18717
+ [labelsProp]
18718
+ );
18719
+ const yearList = React20__namespace.useMemo(() => {
18720
+ if (years && years.length) return years;
18721
+ return Array.from(new Set(departures.map((d) => d.year))).sort(
18722
+ (a, b) => a - b
18723
+ );
18724
+ }, [years, departures]);
18725
+ const [year, setYear] = React20__namespace.useState(defaultYear != null ? defaultYear : yearList[0]);
18726
+ const [month, setMonth] = React20__namespace.useState(null);
18727
+ const [expanded, setExpanded] = React20__namespace.useState(false);
18728
+ const selectYear = (y) => {
18729
+ setYear(y);
18730
+ setMonth(null);
18731
+ setExpanded(false);
18732
+ };
18733
+ const inYear = React20__namespace.useMemo(
18734
+ () => departures.filter((d) => d.year === year),
18735
+ [departures, year]
18736
+ );
18737
+ const months = React20__namespace.useMemo(() => {
18738
+ var _a;
18739
+ const counts = /* @__PURE__ */ new Map();
18740
+ for (const d of inYear) counts.set(d.month, ((_a = counts.get(d.month)) != null ? _a : 0) + 1);
18741
+ return Array.from(counts, ([name, count]) => ({ name, count }));
18742
+ }, [inYear]);
18743
+ const filtered = React20__namespace.useMemo(
18744
+ () => month ? inYear.filter((d) => d.month === month) : inYear,
18745
+ [inYear, month]
18746
+ );
18747
+ const featuredDeparture = React20__namespace.useMemo(() => {
18748
+ if (featured === false) return void 0;
18749
+ if (typeof featured === "string")
18750
+ return filtered.find((d) => d.id === featured);
18751
+ return pickFeatured(filtered);
18752
+ }, [featured, filtered]);
18753
+ const rows = React20__namespace.useMemo(
18754
+ () => filtered.filter((d) => d.id !== (featuredDeparture == null ? void 0 : featuredDeparture.id)),
18755
+ [filtered, featuredDeparture]
18756
+ );
18757
+ const visible = expanded ? rows : rows.slice(0, initialVisible);
18758
+ const remaining = rows.length - visible.length;
18759
+ return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(
18760
+ "section",
18761
+ {
18762
+ className: cn(
18763
+ "rounded-3xl border border-border bg-card p-5 text-card-foreground sm:p-6",
18764
+ className
18765
+ ),
18766
+ children: [
18767
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-display text-lg font-extrabold tracking-tight sm:text-xl", children: labels.title }),
18768
+ yearList.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 mb-2 flex items-center justify-between gap-3", children: [
18769
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-ui text-xs uppercase tracking-wider text-muted-foreground", children: labels.chooseMonth }),
18770
+ /* @__PURE__ */ jsxRuntime.jsx(
18771
+ "div",
18772
+ {
18773
+ role: "tablist",
18774
+ "aria-label": "Year",
18775
+ className: "inline-flex rounded-full border border-border p-0.5",
18776
+ children: yearList.map((y) => {
18777
+ const active = y === year;
18778
+ return /* @__PURE__ */ jsxRuntime.jsx(
18779
+ "button",
18780
+ {
18781
+ role: "tab",
18782
+ type: "button",
18783
+ "aria-selected": active,
18784
+ onClick: () => selectYear(y),
18785
+ className: cn(
18786
+ "cursor-pointer rounded-full px-3.5 py-1 font-ui text-xs font-bold leading-none transition-colors",
18787
+ active ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:text-foreground"
18788
+ ),
18789
+ children: y
18790
+ },
18791
+ y
18792
+ );
18793
+ })
18794
+ }
18795
+ )
18796
+ ] }),
18797
+ months.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs(
18798
+ "div",
18799
+ {
18800
+ role: "tablist",
18801
+ "aria-label": labels.chooseMonth,
18802
+ className: "-mx-1 flex gap-1.5 overflow-x-auto px-1 py-1 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
18803
+ children: [
18804
+ /* @__PURE__ */ jsxRuntime.jsx(
18805
+ MonthChip,
18806
+ {
18807
+ label: labels.allMonths,
18808
+ selected: month === null,
18809
+ onClick: () => {
18810
+ setMonth(null);
18811
+ setExpanded(false);
18812
+ }
18813
+ }
18814
+ ),
18815
+ months.map((m) => /* @__PURE__ */ jsxRuntime.jsx(
18816
+ MonthChip,
18817
+ {
18818
+ label: m.name,
18819
+ count: m.count,
18820
+ selected: month === m.name,
18821
+ onClick: () => {
18822
+ setMonth(m.name);
18823
+ setExpanded(false);
18824
+ }
18825
+ },
18826
+ m.name
18827
+ ))
18828
+ ]
18829
+ }
18830
+ ),
18831
+ featuredDeparture && /* @__PURE__ */ jsxRuntime.jsx(
18832
+ FeaturedDeparture,
18833
+ {
18834
+ departure: featuredDeparture,
18835
+ labels,
18836
+ onSelect
18837
+ }
18838
+ ),
18839
+ visible.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 flex flex-col gap-2.5", children: visible.map((d) => /* @__PURE__ */ jsxRuntime.jsx(
18840
+ DepartureRow,
18841
+ {
18842
+ departure: d,
18843
+ labels,
18844
+ onSelect
18845
+ },
18846
+ d.id
18847
+ )) }),
18848
+ remaining > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs(
18849
+ "button",
18850
+ {
18851
+ type: "button",
18852
+ onClick: () => setExpanded(true),
18853
+ 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",
18854
+ children: [
18855
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: "size-4" }),
18856
+ labels.seeMore(remaining)
18857
+ ]
18858
+ }
18859
+ ) }),
18860
+ showStartGroup && /* @__PURE__ */ jsxRuntime.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: [
18861
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-44 flex-1", children: [
18862
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { className: "block font-display text-base font-extrabold leading-tight text-foreground sm:text-lg", children: labels.startGroupTitle }),
18863
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-0.5 block text-sm leading-snug text-primary-800 dark:text-primary-300", children: labels.startGroupBody })
18864
+ ] }),
18865
+ /* @__PURE__ */ jsxRuntime.jsx(
18866
+ StartGroupCta,
18867
+ {
18868
+ href: startGroupHref,
18869
+ onClick: onStartGroup,
18870
+ label: labels.startGroupCta
18871
+ }
18872
+ )
18873
+ ] })
18874
+ ]
18875
+ }
18876
+ ) });
18877
+ }
18878
+ function FeaturedDeparture({
18879
+ departure: d,
18880
+ labels,
18881
+ onSelect
18882
+ }) {
18883
+ var _a;
18884
+ const spotsLeft = d.capacity - d.travellers;
18885
+ const needsQuorum = d.min != null && d.travellers < d.min;
18886
+ const eyebrow = needsQuorum ? labels.confirmsIn(d.min - d.travellers) : labels.fillingFast(spotsLeft);
18887
+ const ladder = d.dynamicPricing && d.lowestPrice && spotsLeft > 0;
18888
+ const cta = d.href ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: d.href, className: buttonVariants({ variant: "primary", size: "md" }), children: labels.join }) : /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "primary", size: "md", onClick: () => onSelect == null ? void 0 : onSelect(d), children: labels.join });
18889
+ return /* @__PURE__ */ jsxRuntime.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: [
18890
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
18891
+ /* @__PURE__ */ jsxRuntime.jsx(
18892
+ "span",
18893
+ {
18894
+ "aria-hidden": true,
18895
+ className: "size-1.5 rounded-full bg-primary motion-safe:animate-pulse"
18896
+ }
18897
+ ),
18898
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-ui text-[11px] font-bold uppercase tracking-wider text-primary-800 dark:text-primary-400", children: eyebrow })
18899
+ ] }),
18900
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-x-3 gap-y-2", children: [
18901
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-display text-lg font-extrabold tracking-tight whitespace-nowrap", children: fmtDates(d) }),
18902
+ /* @__PURE__ */ jsxRuntime.jsx(StatusChip, { status: d.status }),
18903
+ d.dynamicPricing && /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
18904
+ /* @__PURE__ */ jsxRuntime.jsx(
18905
+ TooltipTrigger,
18906
+ {
18907
+ render: /* @__PURE__ */ jsxRuntime.jsx(
18908
+ "button",
18909
+ {
18910
+ type: "button",
18911
+ "aria-label": labels.dynamicPricingTitle,
18912
+ className: "ml-auto inline-flex cursor-help items-center text-primary"
18913
+ }
18914
+ ),
18915
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SparklesIcon, { className: "size-[18px]", strokeWidth: 1.8 })
18916
+ }
18917
+ ),
18918
+ /* @__PURE__ */ jsxRuntime.jsxs(TooltipContent, { children: [
18919
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block font-bold", children: labels.dynamicPricingTitle }),
18920
+ labels.dynamicPricingBody
18921
+ ] })
18922
+ ] })
18923
+ ] }),
18924
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-x-3 gap-y-2", children: [
18925
+ d.participants && d.participants.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(AvatarStack, { participants: d.participants, capacity: d.capacity }),
18926
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5 font-sans text-sm text-muted-foreground", children: [
18927
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UsersIcon, { className: "size-4", strokeWidth: 1.6, "aria-hidden": true }),
18928
+ labels.travellersOf(d.travellers, d.capacity)
18929
+ ] })
18930
+ ] }),
18931
+ /* @__PURE__ */ jsxRuntime.jsx(
18932
+ GroupProgressBar,
18933
+ {
18934
+ className: "mt-3",
18935
+ current: d.travellers,
18936
+ min: (_a = d.min) != null ? _a : d.travellers,
18937
+ max: d.capacity,
18938
+ hideLabels: d.min == null
18939
+ }
18940
+ ),
18941
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 flex flex-wrap items-end justify-between gap-3", children: [
18942
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2", children: [
18943
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-display text-xl font-extrabold tracking-tight whitespace-nowrap", children: [
18944
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mr-1 align-middle text-[10px] font-bold uppercase tracking-wider text-muted-foreground", children: labels.from }),
18945
+ d.price
18946
+ ] }),
18947
+ ladder && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5 font-sans text-sm font-semibold text-success whitespace-nowrap", children: [
18948
+ /* @__PURE__ */ jsxRuntime.jsx(
18949
+ lucideReact.ArrowRightIcon,
18950
+ {
18951
+ className: "size-3.5 text-muted-foreground",
18952
+ strokeWidth: 2.2,
18953
+ "aria-hidden": true
18954
+ }
18955
+ ),
18956
+ d.lowestPrice,
18957
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-normal text-muted-foreground", children: labels.atFull })
18958
+ ] })
18959
+ ] }),
18960
+ cta
18961
+ ] })
18962
+ ] });
18963
+ }
18964
+ function AvatarStack({
18965
+ participants,
18966
+ capacity
18967
+ }) {
18968
+ const shown = participants.slice(0, 4);
18969
+ const extra = Math.max(0, participants.length - shown.length);
18970
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center -space-x-2", "aria-hidden": true, children: [
18971
+ shown.map((p, i) => {
18972
+ var _a;
18973
+ return /* @__PURE__ */ jsxRuntime.jsx(
18974
+ "span",
18975
+ {
18976
+ title: p.country ? `${p.firstName} \xB7 ${p.country}` : p.firstName,
18977
+ className: "flex size-7 items-center justify-center rounded-full border-2 border-card bg-primary/10 text-sm ring-0",
18978
+ children: (_a = p.flag) != null ? _a : p.firstName.charAt(0)
18979
+ },
18980
+ `${p.firstName}-${i}`
18981
+ );
18982
+ }),
18983
+ extra > 0 && /* @__PURE__ */ jsxRuntime.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: [
18984
+ "+",
18985
+ extra
18986
+ ] }),
18987
+ capacity > participants.length && participants.length < 5 && /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx("span", { className: "text-base leading-none", children: "+" }) })
18988
+ ] });
18989
+ }
18990
+ function MonthChip({
18991
+ label,
18992
+ count,
18993
+ selected,
18994
+ onClick
18995
+ }) {
18996
+ return /* @__PURE__ */ jsxRuntime.jsxs(
18997
+ "button",
18998
+ {
18999
+ role: "tab",
19000
+ type: "button",
19001
+ "aria-selected": selected,
19002
+ onClick,
19003
+ className: cn(
19004
+ "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",
19005
+ selected ? "border-primary bg-primary/10 font-semibold text-primary-800 dark:text-primary-400" : "border-border text-foreground hover:border-foreground/30"
19006
+ ),
19007
+ children: [
19008
+ label,
19009
+ count != null && /* @__PURE__ */ jsxRuntime.jsx(
19010
+ "span",
19011
+ {
19012
+ className: cn(
19013
+ "inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-full px-1 text-[11px]",
19014
+ selected ? "bg-primary/15 text-primary-800 dark:text-primary-400" : "bg-muted text-muted-foreground"
19015
+ ),
19016
+ children: count
19017
+ }
19018
+ )
19019
+ ]
19020
+ }
19021
+ );
19022
+ }
19023
+ function StatusChip({ status }) {
19024
+ return /* @__PURE__ */ jsxRuntime.jsx(
19025
+ Chip,
19026
+ {
19027
+ variant: "solid",
19028
+ size: "sm",
19029
+ className: "hover:bg-muted hover:text-foreground/80",
19030
+ children: STATUS_MAP[status].label
19031
+ }
19032
+ );
19033
+ }
19034
+ function DepartureRow({
19035
+ departure: d,
19036
+ labels,
19037
+ onSelect
19038
+ }) {
19039
+ var _a;
19040
+ const dateLabel = fmtDates(d);
19041
+ const statusTip = (_a = labels.statusTooltips) == null ? void 0 : _a[d.status];
19042
+ const pct = Math.max(0, Math.min(100, d.travellers / d.capacity * 100));
19043
+ const overlayClass = "absolute inset-0 z-0 rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary";
19044
+ const statusBadge = statusTip ? /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
19045
+ /* @__PURE__ */ jsxRuntime.jsx(
19046
+ TooltipTrigger,
19047
+ {
19048
+ render: /* @__PURE__ */ jsxRuntime.jsx(
19049
+ "span",
19050
+ {
19051
+ tabIndex: 0,
19052
+ className: "pointer-events-auto cursor-help outline-hidden"
19053
+ }
19054
+ ),
19055
+ children: /* @__PURE__ */ jsxRuntime.jsx(StatusChip, { status: d.status })
19056
+ }
19057
+ ),
19058
+ /* @__PURE__ */ jsxRuntime.jsxs(TooltipContent, { children: [
19059
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block font-bold", children: statusTip.title }),
19060
+ statusTip.body
19061
+ ] })
19062
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(StatusChip, { status: d.status });
19063
+ return /* @__PURE__ */ jsxRuntime.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: [
19064
+ d.href ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: d.href, "aria-label": dateLabel, className: overlayClass }) : /* @__PURE__ */ jsxRuntime.jsx(
19065
+ "button",
19066
+ {
19067
+ type: "button",
19068
+ "aria-label": dateLabel,
19069
+ onClick: () => onSelect == null ? void 0 : onSelect(d),
19070
+ className: cn(overlayClass, "w-full text-left")
19071
+ }
19072
+ ),
19073
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pointer-events-none relative z-10 font-display text-sm font-extrabold tracking-tight whitespace-nowrap sm:order-1", children: dateLabel }),
19074
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pointer-events-none relative z-10 justify-self-end sm:order-3 sm:ml-auto", children: statusBadge }),
19075
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pointer-events-none relative z-10 inline-flex items-center gap-2 sm:order-2", children: [
19076
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5 font-sans text-sm text-muted-foreground whitespace-nowrap", children: [
19077
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UsersIcon, { className: "size-4", strokeWidth: 1.6 }),
19078
+ labels.travellers(d.travellers, d.capacity)
19079
+ ] }),
19080
+ d.dynamicPricing && /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
19081
+ /* @__PURE__ */ jsxRuntime.jsx(
19082
+ TooltipTrigger,
19083
+ {
19084
+ render: /* @__PURE__ */ jsxRuntime.jsx(
19085
+ "button",
19086
+ {
19087
+ type: "button",
19088
+ "aria-label": labels.dynamicPricingTitle,
19089
+ className: "pointer-events-auto inline-flex cursor-help items-center text-primary"
19090
+ }
19091
+ ),
19092
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SparklesIcon, { className: "size-[18px]", strokeWidth: 1.8 })
19093
+ }
19094
+ ),
19095
+ /* @__PURE__ */ jsxRuntime.jsxs(TooltipContent, { children: [
19096
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block font-bold", children: labels.dynamicPricingTitle }),
19097
+ labels.dynamicPricingBody
19098
+ ] })
19099
+ ] })
19100
+ ] }),
19101
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pointer-events-none relative z-10 flex items-center justify-self-end gap-3 sm:order-4", children: [
19102
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "w-[88px] text-right font-display text-sm font-extrabold whitespace-nowrap", children: [
19103
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-[10px] font-bold uppercase tracking-wider text-muted-foreground", children: labels.from }),
19104
+ d.price
19105
+ ] }),
19106
+ /* @__PURE__ */ jsxRuntime.jsx(
19107
+ lucideReact.ArrowRightIcon,
19108
+ {
19109
+ className: "size-5 shrink-0 text-primary transition-transform group-hover:translate-x-0.5",
19110
+ strokeWidth: 2.2,
19111
+ "aria-hidden": true
19112
+ }
19113
+ )
19114
+ ] }),
19115
+ /* @__PURE__ */ jsxRuntime.jsx(
19116
+ "span",
19117
+ {
19118
+ "aria-hidden": true,
19119
+ className: "pointer-events-none absolute inset-x-0 bottom-0 h-[3px] bg-transparent",
19120
+ children: /* @__PURE__ */ jsxRuntime.jsx(
19121
+ "span",
19122
+ {
19123
+ className: cn(
19124
+ "block h-full rounded-full transition-[width] duration-500",
19125
+ d.travellers >= d.capacity ? "bg-success/60" : "bg-primary/45"
19126
+ ),
19127
+ style: { width: `${pct}%` }
19128
+ }
19129
+ )
19130
+ }
19131
+ )
19132
+ ] });
19133
+ }
19134
+ function StartGroupCta({
19135
+ href,
19136
+ onClick,
19137
+ label
19138
+ }) {
19139
+ 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";
19140
+ const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
19141
+ label,
19142
+ /* @__PURE__ */ jsxRuntime.jsx(
19143
+ lucideReact.ArrowRightIcon,
19144
+ {
19145
+ className: "size-4 transition-transform group-hover/cta:translate-x-0.5",
19146
+ strokeWidth: 2.2
19147
+ }
19148
+ )
19149
+ ] });
19150
+ if (href) {
19151
+ return /* @__PURE__ */ jsxRuntime.jsx("a", { href, className: cls, children: content });
19152
+ }
19153
+ return /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick, className: cls, children: content });
19154
+ }
18593
19155
  var DEFAULT_TRUSTPILOT = {
18594
19156
  businessUnitId: "6171e6a56fc555750dd81ae7",
18595
19157
  templateId: "5419b732fbfb950b10de65e5",
@@ -20542,6 +21104,7 @@ exports.DEFAULT_HEADER_LINKS = DEFAULT_HEADER_LINKS;
20542
21104
  exports.DEFAULT_LANGUAGES = DEFAULT_LANGUAGES;
20543
21105
  exports.DEPARTURE_STATUS_MAP = STATUS_MAP;
20544
21106
  exports.DatePickerField = DatePickerField;
21107
+ exports.DeparturesList = DeparturesList;
20545
21108
  exports.Dialog = Dialog;
20546
21109
  exports.DialogClose = DialogClose;
20547
21110
  exports.DialogContent = DialogContent;