@harshit-wander/component-lib 1.1.8 → 1.1.10

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
@@ -278,11 +278,12 @@ var EventBanner = react.forwardRef(
278
278
  );
279
279
  EventBanner.displayName = "EventBanner";
280
280
  var frameClass2 = "block w-full h-[300px] overflow-hidden rounded-md no-underline text-inherit focus-visible:outline-2 focus-visible:outline-accent focus-visible:outline-offset-2";
281
- var videoClass = "block w-full h-full object-cover";
281
+ var mediaClass = "block w-full h-full object-cover";
282
282
  var EventVideoBanner = react.forwardRef(
283
- ({ posterUrl, videoUrl, alt, href, className, ...rest }, ref) => {
283
+ ({ posterUrl, videoUrl, alt, href, isActive = true, className, ...rest }, ref) => {
284
284
  const videoRef = react.useRef(null);
285
285
  react.useEffect(() => {
286
+ if (!isActive) return;
286
287
  const video = videoRef.current;
287
288
  if (!video || !videoUrl) return;
288
289
  if (!videoUrl.includes(".m3u8")) {
@@ -306,8 +307,8 @@ var EventVideoBanner = react.forwardRef(
306
307
  const stored = video._hls;
307
308
  stored?.destroy();
308
309
  };
309
- }, [videoUrl]);
310
- const videoEl = /* @__PURE__ */ jsxRuntime.jsx(
310
+ }, [videoUrl, isActive]);
311
+ const mediaEl = isActive ? /* @__PURE__ */ jsxRuntime.jsx(
311
312
  "video",
312
313
  {
313
314
  ref: videoRef,
@@ -319,10 +320,10 @@ var EventVideoBanner = react.forwardRef(
319
320
  loop: true,
320
321
  playsInline: true,
321
322
  preload: "metadata",
322
- className: videoClass
323
+ className: mediaClass
323
324
  }
324
- );
325
- return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("shrink-0 w-full snap-start", className), ...rest, children: href ? /* @__PURE__ */ jsxRuntime.jsx("a", { href, className: frameClass2, children: videoEl }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: frameClass2, children: videoEl }) });
325
+ ) : /* @__PURE__ */ jsxRuntime.jsx("img", { src: posterUrl, alt, loading: "lazy", decoding: "async", className: mediaClass });
326
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("shrink-0 w-full snap-start", className), ...rest, children: href ? /* @__PURE__ */ jsxRuntime.jsx("a", { href, className: frameClass2, children: mediaEl }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: frameClass2, children: mediaEl }) });
326
327
  }
327
328
  );
328
329
  EventVideoBanner.displayName = "EventVideoBanner";
@@ -1574,7 +1575,9 @@ var useScrollSnap = (itemCount) => {
1574
1575
  setScrollProgress(maxScroll > 0 ? el.scrollLeft / maxScroll : 0);
1575
1576
  if (itemCount > 0) {
1576
1577
  const itemWidth = el.scrollWidth / itemCount;
1577
- setActiveIndex(Math.round(el.scrollLeft / itemWidth));
1578
+ if (itemWidth > 0) {
1579
+ setActiveIndex(Math.round(el.scrollLeft / itemWidth));
1580
+ }
1578
1581
  }
1579
1582
  }, [itemCount]);
1580
1583
  const setRef = react.useCallback(
@@ -1676,13 +1679,14 @@ var EventCarousel = react.forwardRef(
1676
1679
  ref: trackRef,
1677
1680
  className: "flex w-full gap-sm overflow-x-auto snap-x [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
1678
1681
  children: events.map(
1679
- (event) => "videoUrl" in event ? /* @__PURE__ */ jsxRuntime.jsx(
1682
+ (event, index) => "videoUrl" in event ? /* @__PURE__ */ jsxRuntime.jsx(
1680
1683
  EventVideoBanner,
1681
1684
  {
1682
1685
  posterUrl: event.posterUrl,
1683
1686
  videoUrl: event.videoUrl,
1684
1687
  alt: event.alt,
1685
- href: event.href
1688
+ href: event.href,
1689
+ isActive: index === activeIndex
1686
1690
  },
1687
1691
  `${event.videoUrl}|${event.alt}`
1688
1692
  ) : /* @__PURE__ */ jsxRuntime.jsx(
@@ -2715,6 +2719,34 @@ var TextSection = react.forwardRef(
2715
2719
  )
2716
2720
  );
2717
2721
  TextSection.displayName = "TextSection";
2722
+ var useDesktopVideoVisible = (ref, breakpointPx = 768) => {
2723
+ const [shouldRender, setShouldRender] = react.useState(false);
2724
+ react.useEffect(() => {
2725
+ if (typeof window === "undefined") return;
2726
+ const mq = window.matchMedia(`(min-width: ${breakpointPx}px)`);
2727
+ if (!mq.matches) {
2728
+ setShouldRender(false);
2729
+ return;
2730
+ }
2731
+ const el = ref.current;
2732
+ if (!el || typeof IntersectionObserver === "undefined") {
2733
+ setShouldRender(true);
2734
+ return;
2735
+ }
2736
+ const io = new IntersectionObserver(
2737
+ (entries) => {
2738
+ if (entries[0]?.isIntersecting) {
2739
+ setShouldRender(true);
2740
+ io.disconnect();
2741
+ }
2742
+ },
2743
+ { rootMargin: "200px" }
2744
+ );
2745
+ io.observe(el);
2746
+ return () => io.disconnect();
2747
+ }, [ref, breakpointPx]);
2748
+ return shouldRender;
2749
+ };
2718
2750
  var ChevronLeft5 = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(
2719
2751
  "path",
2720
2752
  {
@@ -2746,6 +2778,8 @@ var TripsCategorySection = react.forwardRef(
2746
2778
  canNext,
2747
2779
  scrollProgress
2748
2780
  } = useScrollSnap(trips.length);
2781
+ const heroRef = react.useRef(null);
2782
+ const showDesktopVideo = useDesktopVideoVisible(heroRef);
2749
2783
  const handleCtaClick = () => {
2750
2784
  if (cta.href) {
2751
2785
  window.location.assign(cta.href);
@@ -2754,134 +2788,152 @@ var TripsCategorySection = react.forwardRef(
2754
2788
  cta.onClick?.();
2755
2789
  };
2756
2790
  const progressWidth = Math.min(33 + scrollProgress * (120 - 33), 120);
2757
- return /* @__PURE__ */ jsxRuntime.jsxs("section", { ref, className: cn("relative flex flex-col bg-surface max-md:overflow-x-hidden", className), ...rest, children: [
2758
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative h-[318px] rounded-lg overflow-hidden max-md:h-[260px]", children: [
2759
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0", children: [
2760
- /* @__PURE__ */ jsxRuntime.jsx(
2761
- "img",
2791
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2792
+ "section",
2793
+ {
2794
+ ref,
2795
+ className: cn("relative flex flex-col bg-surface max-md:overflow-x-clip", className),
2796
+ ...rest,
2797
+ children: [
2798
+ /* @__PURE__ */ jsxRuntime.jsxs(
2799
+ "div",
2762
2800
  {
2763
- src: poster,
2764
- alt: "",
2765
- "aria-hidden": "true",
2766
- className: "w-full h-full object-cover md:hidden"
2801
+ ref: heroRef,
2802
+ className: "relative h-[318px] rounded-lg overflow-hidden max-md:h-[260px]",
2803
+ children: [
2804
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0", children: [
2805
+ /* @__PURE__ */ jsxRuntime.jsx(
2806
+ "img",
2807
+ {
2808
+ src: poster,
2809
+ alt: "",
2810
+ "aria-hidden": "true",
2811
+ className: "w-full h-full object-cover",
2812
+ loading: "lazy",
2813
+ decoding: "async"
2814
+ }
2815
+ ),
2816
+ showDesktopVideo && /* @__PURE__ */ jsxRuntime.jsx(
2817
+ "video",
2818
+ {
2819
+ autoPlay: true,
2820
+ muted: true,
2821
+ loop: true,
2822
+ playsInline: true,
2823
+ preload: "metadata",
2824
+ poster,
2825
+ src: videoSrc,
2826
+ className: "hidden md:block absolute inset-0 w-full h-full object-cover"
2827
+ }
2828
+ )
2829
+ ] }),
2830
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0 flex flex-col justify-center gap-lg p-[44px] max-md:p-[24px] text-on-image [text-shadow:0px_6px_24px_rgba(0,0,0,0.16)]", children: [
2831
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "m-0 text-hero-title max-w-[436px] max-md:text-secondary max-md:[text-shadow:none]", children: title }),
2832
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-md:hidden m-0 text-xs font-bold leading-5", children: description }),
2833
+ /* @__PURE__ */ jsxRuntime.jsx(
2834
+ "button",
2835
+ {
2836
+ type: "button",
2837
+ onClick: handleCtaClick,
2838
+ className: "max-md:hidden inline-flex items-center justify-center self-start h-11 px-xl bg-accent text-secondary border-none rounded-md font-[inherit] text-button cursor-pointer shadow-[inset_0_0_6px_rgba(0,0,0,0.14)] transition-colors duration-150 ease-in hover:bg-accent-hover focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2",
2839
+ children: cta.label
2840
+ }
2841
+ )
2842
+ ] })
2843
+ ]
2767
2844
  }
2768
2845
  ),
2769
- /* @__PURE__ */ jsxRuntime.jsx(
2770
- "video",
2771
- {
2772
- autoPlay: true,
2773
- muted: true,
2774
- loop: true,
2775
- playsInline: true,
2776
- poster,
2777
- src: videoSrc,
2778
- className: "hidden md:block w-full h-full object-cover"
2779
- }
2780
- )
2781
- ] }),
2782
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0 flex flex-col justify-center gap-lg p-[44px] max-md:p-[24px] text-on-image [text-shadow:0px_6px_24px_rgba(0,0,0,0.16)]", children: [
2783
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "m-0 text-hero-title max-w-[436px]", children: title }),
2784
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-md:hidden m-0 text-xs font-bold leading-5", children: description }),
2785
- /* @__PURE__ */ jsxRuntime.jsx(
2786
- "button",
2787
- {
2788
- type: "button",
2789
- onClick: handleCtaClick,
2790
- className: "max-md:hidden inline-flex items-center justify-center self-start h-11 px-xl bg-accent text-secondary border-none rounded-md font-[inherit] text-button cursor-pointer shadow-[inset_0_0_6px_rgba(0,0,0,0.14)] transition-colors duration-150 ease-in hover:bg-accent-hover focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2",
2791
- children: cta.label
2792
- }
2793
- )
2794
- ] })
2795
- ] }),
2796
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative -mt-[68px] py-sm px-[25px] hidden md:block", children: [
2797
- /* @__PURE__ */ jsxRuntime.jsx(
2798
- "button",
2799
- {
2800
- type: "button",
2801
- onClick: scrollPrev,
2802
- disabled: !canPrev,
2803
- "aria-label": "Previous trips",
2804
- className: cn(arrowBase4, "left-2"),
2805
- children: /* @__PURE__ */ jsxRuntime.jsx(ChevronLeft5, {})
2806
- }
2807
- ),
2808
- /* @__PURE__ */ jsxRuntime.jsx(
2809
- "div",
2810
- {
2811
- ref: trackRef,
2812
- className: "flex gap-sm overflow-x-auto snap-x [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
2813
- children: trips.map((trip) => /* @__PURE__ */ jsxRuntime.jsx(
2814
- TripCategoryCard,
2846
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative -mt-[68px] py-sm px-[25px] hidden md:block", children: [
2847
+ /* @__PURE__ */ jsxRuntime.jsx(
2848
+ "button",
2815
2849
  {
2816
- image: trip.image,
2817
- alt: trip.alt,
2818
- destination: trip.destination,
2819
- startingPrice: trip.startingPrice,
2820
- href: trip.href
2821
- },
2822
- `${trip.image}|${trip.destination}`
2823
- ))
2824
- }
2825
- ),
2826
- /* @__PURE__ */ jsxRuntime.jsx(
2827
- "button",
2828
- {
2829
- type: "button",
2830
- onClick: scrollNext,
2831
- disabled: !canNext,
2832
- "aria-label": "Next trips",
2833
- className: cn(arrowBase4, "right-2"),
2834
- children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRight5, {})
2835
- }
2836
- ),
2837
- /* @__PURE__ */ jsxRuntime.jsx(
2838
- "div",
2839
- {
2840
- role: "progressbar",
2841
- "aria-valuenow": Math.round(scrollProgress * 100),
2842
- "aria-valuemin": 0,
2843
- "aria-valuemax": 100,
2844
- "aria-label": "Scroll position",
2845
- className: "relative w-[120px] h-[6px] mt-md mx-auto bg-track rounded-[32px] overflow-hidden",
2846
- children: /* @__PURE__ */ jsxRuntime.jsx(
2847
- "span",
2850
+ type: "button",
2851
+ onClick: scrollPrev,
2852
+ disabled: !canPrev,
2853
+ "aria-label": "Previous trips",
2854
+ className: cn(arrowBase4, "left-2"),
2855
+ children: /* @__PURE__ */ jsxRuntime.jsx(ChevronLeft5, {})
2856
+ }
2857
+ ),
2858
+ /* @__PURE__ */ jsxRuntime.jsx(
2859
+ "div",
2848
2860
  {
2849
- className: "absolute top-0 left-0 h-full bg-primary rounded-[32px] transition-[width] duration-200 ease-in",
2850
- style: { width: `${progressWidth}px` }
2861
+ ref: trackRef,
2862
+ className: "flex gap-sm overflow-x-auto snap-x [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
2863
+ children: trips.map((trip) => /* @__PURE__ */ jsxRuntime.jsx(
2864
+ TripCategoryCard,
2865
+ {
2866
+ image: trip.image,
2867
+ alt: trip.alt,
2868
+ destination: trip.destination,
2869
+ startingPrice: trip.startingPrice,
2870
+ href: trip.href
2871
+ },
2872
+ `${trip.image}|${trip.destination}`
2873
+ ))
2874
+ }
2875
+ ),
2876
+ /* @__PURE__ */ jsxRuntime.jsx(
2877
+ "button",
2878
+ {
2879
+ type: "button",
2880
+ onClick: scrollNext,
2881
+ disabled: !canNext,
2882
+ "aria-label": "Next trips",
2883
+ className: cn(arrowBase4, "right-2"),
2884
+ children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRight5, {})
2885
+ }
2886
+ ),
2887
+ /* @__PURE__ */ jsxRuntime.jsx(
2888
+ "div",
2889
+ {
2890
+ role: "progressbar",
2891
+ "aria-valuenow": Math.round(scrollProgress * 100),
2892
+ "aria-valuemin": 0,
2893
+ "aria-valuemax": 100,
2894
+ "aria-label": "Scroll position",
2895
+ className: "relative w-[120px] h-[6px] mt-md mx-auto bg-track rounded-[32px] overflow-hidden",
2896
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2897
+ "span",
2898
+ {
2899
+ className: "absolute top-0 left-0 h-full bg-primary rounded-[32px] transition-[width] duration-200 ease-in",
2900
+ style: { width: `${progressWidth}px` }
2901
+ }
2902
+ )
2851
2903
  }
2852
2904
  )
2853
- }
2854
- )
2855
- ] }),
2856
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative -mt-[60px] pb-md md:hidden flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
2857
- react$1.Swiper,
2858
- {
2859
- effect: "cards",
2860
- grabCursor: true,
2861
- modules: [modules.EffectCards],
2862
- className: "w-[74vw] [aspect-ratio:289/367]",
2863
- style: { overflow: "visible" },
2864
- children: trips.map((trip) => /* @__PURE__ */ jsxRuntime.jsx(
2865
- react$1.SwiperSlide,
2905
+ ] }),
2906
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative -mt-[60px] pb-md md:hidden flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
2907
+ react$1.Swiper,
2866
2908
  {
2867
- style: { borderRadius: "12px", overflow: "hidden" },
2868
- children: /* @__PURE__ */ jsxRuntime.jsx(
2869
- TripCategoryCard,
2909
+ effect: "cards",
2910
+ grabCursor: true,
2911
+ modules: [modules.EffectCards],
2912
+ className: "w-[74vw] [aspect-ratio:289/367]",
2913
+ style: { overflow: "visible" },
2914
+ children: trips.map((trip) => /* @__PURE__ */ jsxRuntime.jsx(
2915
+ react$1.SwiperSlide,
2870
2916
  {
2871
- image: trip.image,
2872
- alt: trip.alt,
2873
- destination: trip.destination,
2874
- startingPrice: trip.startingPrice,
2875
- href: trip.href,
2876
- className: "w-full h-full rounded-xl shrink-0"
2877
- }
2878
- )
2879
- },
2880
- `${trip.image}|${trip.destination}|mobile`
2881
- ))
2882
- }
2883
- ) })
2884
- ] });
2917
+ style: { borderRadius: "12px", overflow: "hidden" },
2918
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2919
+ TripCategoryCard,
2920
+ {
2921
+ image: trip.image,
2922
+ alt: trip.alt,
2923
+ destination: trip.destination,
2924
+ startingPrice: trip.startingPrice,
2925
+ href: trip.href,
2926
+ className: "w-full h-full rounded-xl shrink-0"
2927
+ }
2928
+ )
2929
+ },
2930
+ `${trip.image}|${trip.destination}|mobile`
2931
+ ))
2932
+ }
2933
+ ) })
2934
+ ]
2935
+ }
2936
+ );
2885
2937
  }
2886
2938
  );
2887
2939
  TripsCategorySection.displayName = "TripsCategorySection";