@gosalesdeal/blog 0.1.0 → 0.3.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/README.md +265 -34
- package/dist/client/blogClient.js +79 -13
- package/dist/client/blogClient.js.map +1 -1
- package/dist/components/BlogPost.d.ts +12 -1
- package/dist/components/BlogPost.js +27 -16
- package/dist/components/BlogPost.js.map +1 -1
- package/dist/components/BlogPostHeader.d.ts +15 -0
- package/dist/components/BlogPostHeader.js +41 -0
- package/dist/components/BlogPostHeader.js.map +1 -0
- package/dist/components/landing/BlogLayoutComponents.d.ts +14 -0
- package/dist/components/landing/BlogLayoutComponents.js +198 -0
- package/dist/components/landing/BlogLayoutComponents.js.map +1 -0
- package/dist/components/landing/FlexibleLayoutComponent.d.ts +40 -0
- package/dist/components/landing/FlexibleLayoutComponent.js +352 -0
- package/dist/components/landing/FlexibleLayoutComponent.js.map +1 -0
- package/dist/components/landing/HeroFeatureBanner.d.ts +36 -0
- package/dist/components/landing/HeroFeatureBanner.js +88 -0
- package/dist/components/landing/HeroFeatureBanner.js.map +1 -0
- package/dist/components/landing/HeroFeatureBannerComponent.d.ts +4 -0
- package/dist/components/landing/HeroFeatureBannerComponent.js +100 -0
- package/dist/components/landing/HeroFeatureBannerComponent.js.map +1 -0
- package/dist/components/landing/HeroFeatureBannerVideo.d.ts +34 -0
- package/dist/components/landing/HeroFeatureBannerVideo.js +261 -0
- package/dist/components/landing/HeroFeatureBannerVideo.js.map +1 -0
- package/dist/components/landing/HeroFeatureBannerVideoComponent.d.ts +5 -0
- package/dist/components/landing/HeroFeatureBannerVideoComponent.js +69 -0
- package/dist/components/landing/HeroFeatureBannerVideoComponent.js.map +1 -0
- package/dist/components/landing/VarietyReviewslistComponent.d.ts +4 -0
- package/dist/components/landing/VarietyReviewslistComponent.js +172 -0
- package/dist/components/landing/VarietyReviewslistComponent.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +25 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/postUtils.d.ts +3 -0
- package/dist/lib/postUtils.js +8 -0
- package/dist/lib/postUtils.js.map +1 -0
- package/dist/lib/resolveMediaSrc.d.ts +2 -0
- package/dist/lib/resolveMediaSrc.js +21 -0
- package/dist/lib/resolveMediaSrc.js.map +1 -0
- package/dist/render/BlockRenderer.js +5 -0
- package/dist/render/BlockRenderer.js.map +1 -1
- package/dist/render/LandingPageRenderer.d.ts +5 -0
- package/dist/render/LandingPageRenderer.js +50 -0
- package/dist/render/LandingPageRenderer.js.map +1 -0
- package/dist/render/landingPageHtml.d.ts +28 -0
- package/dist/render/landingPageHtml.js +205 -0
- package/dist/render/landingPageHtml.js.map +1 -0
- package/dist/styles.css +27 -0
- package/dist/types/blog.d.ts +8 -2
- package/package.json +13 -3
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import Link from "next/link";
|
|
5
|
+
import Image from "next/image";
|
|
6
|
+
const HeroFeatureBannerComponent = ({ props }) => {
|
|
7
|
+
const bullets = Array.isArray(props.bullets) ? props.bullets : [];
|
|
8
|
+
let headingNode = props.heading || "";
|
|
9
|
+
if (typeof headingNode === "string" && headingNode.includes("\n")) {
|
|
10
|
+
const parts = headingNode.split("\n");
|
|
11
|
+
headingNode = /* @__PURE__ */ jsx(Fragment, { children: parts.map((part, i) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
12
|
+
i > 0 && /* @__PURE__ */ jsx("br", {}),
|
|
13
|
+
part
|
|
14
|
+
] }, i)) });
|
|
15
|
+
}
|
|
16
|
+
return /* @__PURE__ */ jsx("div", { className: `hero-feature-banner ${props.wrapperClassName || ""}`, children: /* @__PURE__ */ jsxs("div", { className: props.sectionBgClassName || "", children: [
|
|
17
|
+
/* @__PURE__ */ jsx("style", { children: `
|
|
18
|
+
.hfb-tint { position: absolute; inset: 0; pointer-events: none; z-index: 1; }
|
|
19
|
+
.hfb-content { position: relative; z-index: 2; }
|
|
20
|
+
.hfb-bullet i { color: ${props.bulletIconColor || "var(--primary-color, #f97316)"}; font-size: 1.1rem; }
|
|
21
|
+
` }),
|
|
22
|
+
props.customCSS && /* @__PURE__ */ jsx("style", { children: props.customCSS }),
|
|
23
|
+
/* @__PURE__ */ jsxs(
|
|
24
|
+
"section",
|
|
25
|
+
{
|
|
26
|
+
className: `relative w-full ${props.rounded || ""} overflow-hidden ${props.className || ""}`,
|
|
27
|
+
style: { minHeight: props.height || 560 },
|
|
28
|
+
children: [
|
|
29
|
+
/* @__PURE__ */ jsx(
|
|
30
|
+
Image,
|
|
31
|
+
{
|
|
32
|
+
src: props.bgImageSrc,
|
|
33
|
+
alt: props.bgAlt || "",
|
|
34
|
+
fill: true,
|
|
35
|
+
priority: true,
|
|
36
|
+
quality: 90,
|
|
37
|
+
sizes: "100vw",
|
|
38
|
+
style: {
|
|
39
|
+
objectFit: "cover",
|
|
40
|
+
objectPosition: "center right"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
),
|
|
44
|
+
props.leftTint && /* @__PURE__ */ jsx("div", { className: "hfb-tint" }),
|
|
45
|
+
/* @__PURE__ */ jsxs("div", { className: "hfb-content w-full h-full container", style: { position: "relative" }, children: [
|
|
46
|
+
/* @__PURE__ */ jsx("div", { className: "p-4 p-md-5", style: { height: "100%", display: "flex", flexDirection: "column", justifyContent: props.ctaPosition === "center" ? "center" : "flex-start" }, children: /* @__PURE__ */ jsxs("div", { style: { maxWidth: props.contentMaxWidth || 720 }, children: [
|
|
47
|
+
/* @__PURE__ */ jsx("h1", { className: props.headingClassName || "m-0 text-900", style: { fontSize: props.headingFontSize || 56, lineHeight: 1.05, fontWeight: 800, color: props.headingColor || void 0 }, children: headingNode }),
|
|
48
|
+
bullets.length > 0 && /* @__PURE__ */ jsx("ul", { className: "list-none m-0 p-0 mt-4", children: bullets.map((b, i) => /* @__PURE__ */ jsxs("li", { className: "flex align-items-center gap-3 mb-3 hfb-bullet", children: [
|
|
49
|
+
/* @__PURE__ */ jsx("span", { className: "flex align-items-center justify-content-center", style: { width: 34, height: 34, background: props.bulletIconBgColor || "rgba(255,100,50,.12)" }, children: /* @__PURE__ */ jsx("i", { className: `pi ${b.icon || "pi-check-circle"}` }) }),
|
|
50
|
+
/* @__PURE__ */ jsx("span", { className: props.bulletTextClassName || "text-800", style: { fontSize: 18, color: props.bulletTextColor || void 0 }, children: b.text })
|
|
51
|
+
] }, i)) }),
|
|
52
|
+
props.ctaLabel && (!props.ctaPosition || props.ctaPosition === "left") && /* @__PURE__ */ jsx("div", { className: "mt-5", children: /* @__PURE__ */ jsxs(
|
|
53
|
+
Link,
|
|
54
|
+
{
|
|
55
|
+
href: props.ctaHref || "#",
|
|
56
|
+
className: props.ctaClassName || "no-underline inline-flex align-items-center gap-2 bg-primary text-white px-4 py-3 border-round-lg font-semibold",
|
|
57
|
+
style: { fontSize: 16, textDecoration: "none", color: props.ctaColor || void 0, backgroundColor: props.ctaBgColor || void 0 },
|
|
58
|
+
children: [
|
|
59
|
+
props.ctaIcon && /* @__PURE__ */ jsx("i", { className: props.ctaIcon }),
|
|
60
|
+
/* @__PURE__ */ jsx("span", { children: props.ctaLabel })
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
) })
|
|
64
|
+
] }) }),
|
|
65
|
+
props.ctaLabel && props.ctaPosition && props.ctaPosition !== "left" && /* @__PURE__ */ jsx(
|
|
66
|
+
"div",
|
|
67
|
+
{
|
|
68
|
+
style: {
|
|
69
|
+
position: "absolute",
|
|
70
|
+
zIndex: 3,
|
|
71
|
+
...props.ctaPosition === "center" && { top: "50%", left: "50%", transform: "translate(-50%, -50%)" },
|
|
72
|
+
...props.ctaPosition === "top-left" && { top: "2rem", left: "2rem" },
|
|
73
|
+
...props.ctaPosition === "top-right" && { top: "2rem", right: "2rem" },
|
|
74
|
+
...props.ctaPosition === "bottom-left" && { bottom: "2rem", left: "2rem" },
|
|
75
|
+
...props.ctaPosition === "bottom-right" && { bottom: "2rem", right: "2rem" }
|
|
76
|
+
},
|
|
77
|
+
children: /* @__PURE__ */ jsxs(
|
|
78
|
+
Link,
|
|
79
|
+
{
|
|
80
|
+
href: props.ctaHref || "#",
|
|
81
|
+
className: props.ctaClassName || "no-underline inline-flex align-items-center gap-2 bg-primary text-white px-4 py-3 border-round-lg font-semibold",
|
|
82
|
+
style: { fontSize: 16, textDecoration: "none", color: props.ctaColor || void 0, backgroundColor: props.ctaBgColor || void 0 },
|
|
83
|
+
children: [
|
|
84
|
+
props.ctaIcon && /* @__PURE__ */ jsx("i", { className: props.ctaIcon }),
|
|
85
|
+
/* @__PURE__ */ jsx("span", { children: props.ctaLabel })
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
)
|
|
91
|
+
] })
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
] }) });
|
|
96
|
+
};
|
|
97
|
+
export {
|
|
98
|
+
HeroFeatureBannerComponent
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=HeroFeatureBannerComponent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HeroFeatureBannerComponent.js","sources":["../../../src/components/landing/HeroFeatureBannerComponent.tsx"],"sourcesContent":["'use client';\n\nimport React from 'react';\nimport Link from 'next/link';\nimport Image from 'next/image';\n\nexport const HeroFeatureBannerComponent: React.FC<{ props: Record<string, any> }> = ({ props }) => {\n const bullets: any[] = Array.isArray(props.bullets) ? props.bullets : [];\n\n // Transform heading line breaks\n let headingNode: React.ReactNode = props.heading || '';\n if (typeof headingNode === 'string' && headingNode.includes('\\n')) {\n const parts = (headingNode as string).split('\\n');\n headingNode = (\n <>\n {parts.map((part: string, i: number) => (\n <React.Fragment key={i}>\n {i > 0 && <br />}\n {part}\n </React.Fragment>\n ))}\n </>\n );\n }\n\n return (\n <div className={`hero-feature-banner ${props.wrapperClassName || ''}`}>\n <div className={props.sectionBgClassName || ''}>\n <style>{`\n .hfb-tint { position: absolute; inset: 0; pointer-events: none; z-index: 1; }\n .hfb-content { position: relative; z-index: 2; }\n .hfb-bullet i { color: ${props.bulletIconColor || 'var(--primary-color, #f97316)'}; font-size: 1.1rem; }\n `}</style>\n {props.customCSS && <style>{props.customCSS}</style>}\n <section\n className={`relative w-full ${props.rounded || ''} overflow-hidden ${props.className || ''}`}\n style={{ minHeight: props.height || 560 }}\n >\n {/* Background Image using Next.js Image */}\n <Image\n src={props.bgImageSrc}\n alt={props.bgAlt || ''}\n fill\n priority\n quality={90}\n sizes=\"100vw\"\n style={{\n objectFit: 'cover',\n objectPosition: 'center right',\n }}\n />\n\n {props.leftTint && <div className=\"hfb-tint\" />}\n\n <div className=\"hfb-content w-full h-full container\" style={{ position: 'relative' }}>\n <div className=\"p-4 p-md-5\" style={{ height: '100%', display: 'flex', flexDirection: 'column', justifyContent: props.ctaPosition === 'center' ? 'center' : 'flex-start' }}>\n <div style={{ maxWidth: props.contentMaxWidth || 720 }}>\n <h1 className={props.headingClassName || 'm-0 text-900'} style={{ fontSize: props.headingFontSize || 56, lineHeight: 1.05, fontWeight: 800, color: props.headingColor || undefined }}>\n {headingNode}\n </h1>\n\n {bullets.length > 0 && (\n <ul className=\"list-none m-0 p-0 mt-4\">\n {bullets.map((b: any, i: number) => (\n <li key={i} className=\"flex align-items-center gap-3 mb-3 hfb-bullet\">\n <span className=\"flex align-items-center justify-content-center\" style={{ width: 34, height: 34, background: props.bulletIconBgColor || 'rgba(255,100,50,.12)' }}>\n <i className={`pi ${b.icon || 'pi-check-circle'}`} />\n </span>\n <span className={props.bulletTextClassName || 'text-800'} style={{ fontSize: 18, color: props.bulletTextColor || undefined }}>{b.text}</span>\n </li>\n ))}\n </ul>\n )}\n\n {props.ctaLabel && (!props.ctaPosition || props.ctaPosition === 'left') && (\n <div className=\"mt-5\">\n <Link\n href={props.ctaHref || '#'}\n className={props.ctaClassName || 'no-underline inline-flex align-items-center gap-2 bg-primary text-white px-4 py-3 border-round-lg font-semibold'}\n style={{ fontSize: 16, textDecoration: 'none', color: props.ctaColor || undefined, backgroundColor: props.ctaBgColor || undefined }}\n >\n {props.ctaIcon && <i className={props.ctaIcon} />}\n <span>{props.ctaLabel}</span>\n </Link>\n </div>\n )}\n </div>\n </div>\n \n {/* Positioned CTA button */}\n {props.ctaLabel && props.ctaPosition && props.ctaPosition !== 'left' && (\n <div \n style={{\n position: 'absolute',\n zIndex: 3,\n ...(props.ctaPosition === 'center' && { top: '50%', left: '50%', transform: 'translate(-50%, -50%)' }),\n ...(props.ctaPosition === 'top-left' && { top: '2rem', left: '2rem' }),\n ...(props.ctaPosition === 'top-right' && { top: '2rem', right: '2rem' }),\n ...(props.ctaPosition === 'bottom-left' && { bottom: '2rem', left: '2rem' }),\n ...(props.ctaPosition === 'bottom-right' && { bottom: '2rem', right: '2rem' }),\n }}\n >\n <Link\n href={props.ctaHref || '#'}\n className={props.ctaClassName || 'no-underline inline-flex align-items-center gap-2 bg-primary text-white px-4 py-3 border-round-lg font-semibold'}\n style={{ fontSize: 16, textDecoration: 'none', color: props.ctaColor || undefined, backgroundColor: props.ctaBgColor || undefined }}\n >\n {props.ctaIcon && <i className={props.ctaIcon} />}\n <span>{props.ctaLabel}</span>\n </Link>\n </div>\n )}\n </div>\n </section>\n </div>\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export type HeroBullet = {
|
|
3
|
+
icon?: string;
|
|
4
|
+
text: React.ReactNode;
|
|
5
|
+
};
|
|
6
|
+
export type HeroFeatureBannerVideoProps = {
|
|
7
|
+
bgVideoSrc?: string;
|
|
8
|
+
bgPosterSrc?: string;
|
|
9
|
+
bgPosterAlt?: string;
|
|
10
|
+
videoAutoplay?: boolean;
|
|
11
|
+
videoMuted?: boolean;
|
|
12
|
+
videoLoop?: boolean;
|
|
13
|
+
videoLazyLoad?: boolean;
|
|
14
|
+
/** Prioritize fetch/decode for above-the-fold hero usage */
|
|
15
|
+
videoPriority?: boolean;
|
|
16
|
+
heading: React.ReactNode;
|
|
17
|
+
bullets?: HeroBullet[];
|
|
18
|
+
cta?: {
|
|
19
|
+
label: string;
|
|
20
|
+
href?: string;
|
|
21
|
+
onClick?: () => void;
|
|
22
|
+
icon?: string;
|
|
23
|
+
backgroundColor?: string;
|
|
24
|
+
className?: string;
|
|
25
|
+
};
|
|
26
|
+
ctaPosition?: 'left' | 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
27
|
+
height?: number;
|
|
28
|
+
rounded?: string;
|
|
29
|
+
leftTint?: boolean;
|
|
30
|
+
contentMaxWidth?: number;
|
|
31
|
+
className?: string;
|
|
32
|
+
};
|
|
33
|
+
declare const HeroFeatureBannerVideo: React.FC<HeroFeatureBannerVideoProps>;
|
|
34
|
+
export default HeroFeatureBannerVideo;
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useRef, useState, useEffect } from "react";
|
|
4
|
+
function configureMobileVideo(video, muted) {
|
|
5
|
+
video.muted = muted;
|
|
6
|
+
video.defaultMuted = muted;
|
|
7
|
+
video.playsInline = true;
|
|
8
|
+
video.setAttribute("playsinline", "");
|
|
9
|
+
video.setAttribute("webkit-playsinline", "");
|
|
10
|
+
}
|
|
11
|
+
const HeroBackgroundVideo = ({ src, autoplay, muted, loop, lazyLoad, priority }) => {
|
|
12
|
+
const containerRef = useRef(null);
|
|
13
|
+
const videoRef = useRef(null);
|
|
14
|
+
const [shouldLoad, setShouldLoad] = useState(!lazyLoad);
|
|
15
|
+
const [isReady, setIsReady] = useState(false);
|
|
16
|
+
const [reduceMotion, setReduceMotion] = useState(false);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
19
|
+
const update = () => setReduceMotion(mq.matches);
|
|
20
|
+
update();
|
|
21
|
+
mq.addEventListener("change", update);
|
|
22
|
+
return () => mq.removeEventListener("change", update);
|
|
23
|
+
}, []);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (!lazyLoad || shouldLoad || reduceMotion) return;
|
|
26
|
+
const node = containerRef.current;
|
|
27
|
+
if (!node || typeof IntersectionObserver === "undefined") {
|
|
28
|
+
setShouldLoad(true);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const observer = new IntersectionObserver(
|
|
32
|
+
(entries) => {
|
|
33
|
+
if (entries.some((entry) => entry.isIntersecting)) {
|
|
34
|
+
setShouldLoad(true);
|
|
35
|
+
observer.disconnect();
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
{ rootMargin: "200px 0px", threshold: 0.01 }
|
|
39
|
+
);
|
|
40
|
+
observer.observe(node);
|
|
41
|
+
return () => observer.disconnect();
|
|
42
|
+
}, [lazyLoad, shouldLoad, reduceMotion]);
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
setIsReady(false);
|
|
45
|
+
}, [src]);
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
const video = videoRef.current;
|
|
48
|
+
if (!video || !shouldLoad || reduceMotion) return;
|
|
49
|
+
configureMobileVideo(video, muted);
|
|
50
|
+
const tryPlay = () => {
|
|
51
|
+
setIsReady(true);
|
|
52
|
+
if (!autoplay) return;
|
|
53
|
+
configureMobileVideo(video, muted);
|
|
54
|
+
void video.play().catch(() => {
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
const onLoadedData = () => tryPlay();
|
|
58
|
+
const onCanPlay = () => tryPlay();
|
|
59
|
+
const onVisibilityChange = () => {
|
|
60
|
+
if (!document.hidden && autoplay && video.paused) {
|
|
61
|
+
configureMobileVideo(video, muted);
|
|
62
|
+
void video.play().catch(() => {
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const hardFallback = window.setTimeout(tryPlay, 2e3);
|
|
67
|
+
if (video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA) {
|
|
68
|
+
tryPlay();
|
|
69
|
+
}
|
|
70
|
+
video.addEventListener("loadeddata", onLoadedData);
|
|
71
|
+
video.addEventListener("canplay", onCanPlay);
|
|
72
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
73
|
+
return () => {
|
|
74
|
+
window.clearTimeout(hardFallback);
|
|
75
|
+
video.removeEventListener("loadeddata", onLoadedData);
|
|
76
|
+
video.removeEventListener("canplay", onCanPlay);
|
|
77
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
78
|
+
};
|
|
79
|
+
}, [shouldLoad, autoplay, muted, reduceMotion, src]);
|
|
80
|
+
const setVideoRef = (node) => {
|
|
81
|
+
videoRef.current = node;
|
|
82
|
+
if (node) {
|
|
83
|
+
configureMobileVideo(node, muted);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
if (reduceMotion || !src) {
|
|
87
|
+
return /* @__PURE__ */ jsx("div", { ref: containerRef, className: "hfbv-media-layer", "aria-hidden": "true" });
|
|
88
|
+
}
|
|
89
|
+
return /* @__PURE__ */ jsx("div", { ref: containerRef, className: "hfbv-media-layer", "aria-hidden": "true", children: shouldLoad && /* @__PURE__ */ jsx(
|
|
90
|
+
"video",
|
|
91
|
+
{
|
|
92
|
+
ref: setVideoRef,
|
|
93
|
+
className: `hfbv-video${isReady ? " hfbv-video--ready" : ""}`,
|
|
94
|
+
src,
|
|
95
|
+
muted,
|
|
96
|
+
loop,
|
|
97
|
+
autoPlay: autoplay,
|
|
98
|
+
playsInline: true,
|
|
99
|
+
preload: priority ? "auto" : "metadata",
|
|
100
|
+
fetchPriority: priority ? "high" : "auto",
|
|
101
|
+
disablePictureInPicture: true,
|
|
102
|
+
disableRemotePlayback: true,
|
|
103
|
+
tabIndex: -1
|
|
104
|
+
}
|
|
105
|
+
) });
|
|
106
|
+
};
|
|
107
|
+
const HeroFeatureBannerVideo = ({
|
|
108
|
+
bgVideoSrc,
|
|
109
|
+
videoAutoplay = true,
|
|
110
|
+
videoMuted = true,
|
|
111
|
+
videoLoop = true,
|
|
112
|
+
videoLazyLoad = false,
|
|
113
|
+
videoPriority = true,
|
|
114
|
+
heading,
|
|
115
|
+
bullets = [],
|
|
116
|
+
cta,
|
|
117
|
+
ctaPosition = "left",
|
|
118
|
+
height = 560,
|
|
119
|
+
rounded = "",
|
|
120
|
+
leftTint = true,
|
|
121
|
+
contentMaxWidth = 720,
|
|
122
|
+
className = ""
|
|
123
|
+
}) => {
|
|
124
|
+
return /* @__PURE__ */ jsxs(
|
|
125
|
+
"section",
|
|
126
|
+
{
|
|
127
|
+
className: `relative w-full ${rounded} overflow-hidden ${className}`,
|
|
128
|
+
"aria-label": "Hero feature banner",
|
|
129
|
+
style: { minHeight: height },
|
|
130
|
+
children: [
|
|
131
|
+
/* @__PURE__ */ jsx("style", { children: `
|
|
132
|
+
.hfbv-media-stack { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
|
|
133
|
+
.hfbv-media-layer { position: absolute; inset: 0; width: 100%; height: 100%; }
|
|
134
|
+
.hfbv-video {
|
|
135
|
+
position: absolute;
|
|
136
|
+
inset: 0;
|
|
137
|
+
width: 100%;
|
|
138
|
+
height: 100%;
|
|
139
|
+
object-fit: cover;
|
|
140
|
+
object-position: center right;
|
|
141
|
+
opacity: 0;
|
|
142
|
+
transition: opacity 0.35s ease;
|
|
143
|
+
transform: translate3d(0, 0, 0);
|
|
144
|
+
backface-visibility: hidden;
|
|
145
|
+
-webkit-backface-visibility: hidden;
|
|
146
|
+
}
|
|
147
|
+
.hfbv-video--ready { opacity: 1; }
|
|
148
|
+
.hfbv-tint { position: absolute; inset: 0; pointer-events: none; z-index: 1; }
|
|
149
|
+
.hfbv-content { position: relative; z-index: 2; }
|
|
150
|
+
.hfbv-bullet i { color: var(--primary-color); font-size: 1.1rem; }
|
|
151
|
+
` }),
|
|
152
|
+
/* @__PURE__ */ jsx("div", { className: "hfbv-media-stack", children: bgVideoSrc && /* @__PURE__ */ jsx(
|
|
153
|
+
HeroBackgroundVideo,
|
|
154
|
+
{
|
|
155
|
+
src: bgVideoSrc,
|
|
156
|
+
autoplay: videoAutoplay,
|
|
157
|
+
muted: videoMuted,
|
|
158
|
+
loop: videoLoop,
|
|
159
|
+
lazyLoad: videoLazyLoad,
|
|
160
|
+
priority: videoPriority
|
|
161
|
+
}
|
|
162
|
+
) }),
|
|
163
|
+
leftTint && /* @__PURE__ */ jsx("div", { className: "hfbv-tint" }),
|
|
164
|
+
/* @__PURE__ */ jsxs("div", { className: "hfbv-content w-full h-full container", style: { position: "relative" }, children: [
|
|
165
|
+
/* @__PURE__ */ jsx(
|
|
166
|
+
"div",
|
|
167
|
+
{
|
|
168
|
+
className: "p-4 p-md-5",
|
|
169
|
+
style: {
|
|
170
|
+
height: "100%",
|
|
171
|
+
display: "flex",
|
|
172
|
+
flexDirection: "column",
|
|
173
|
+
justifyContent: ctaPosition === "center" ? "center" : "flex-start"
|
|
174
|
+
},
|
|
175
|
+
children: /* @__PURE__ */ jsxs("div", { style: { maxWidth: contentMaxWidth }, children: [
|
|
176
|
+
/* @__PURE__ */ jsx("h1", { className: "m-0 text-900", style: { fontSize: 56, lineHeight: 1.05, fontWeight: 800 }, children: heading }),
|
|
177
|
+
bullets.length > 0 && /* @__PURE__ */ jsx("ul", { className: "list-none m-0 p-0 mt-4", children: bullets.map((b, i) => /* @__PURE__ */ jsxs("li", { className: "flex align-items-center gap-3 mb-3 hfbv-bullet", children: [
|
|
178
|
+
/* @__PURE__ */ jsx(
|
|
179
|
+
"span",
|
|
180
|
+
{
|
|
181
|
+
className: "flex align-items-center justify-content-center",
|
|
182
|
+
style: { width: 34, height: 34, background: "rgba(255,100,50,.12)" },
|
|
183
|
+
children: /* @__PURE__ */ jsx("i", { className: `pi ${b.icon ?? "pi-check-circle"}` })
|
|
184
|
+
}
|
|
185
|
+
),
|
|
186
|
+
/* @__PURE__ */ jsx("span", { className: "text-800", style: { fontSize: 18 }, children: b.text })
|
|
187
|
+
] }, i)) }),
|
|
188
|
+
cta && ctaPosition === "left" && /* @__PURE__ */ jsx("div", { className: "mt-5", children: cta.href ? /* @__PURE__ */ jsxs(
|
|
189
|
+
"a",
|
|
190
|
+
{
|
|
191
|
+
href: cta.href,
|
|
192
|
+
className: `p-button p-component p-button-rounded p-button-lg ${cta.className || ""}`,
|
|
193
|
+
style: { textDecoration: "none", backgroundColor: cta.backgroundColor },
|
|
194
|
+
children: [
|
|
195
|
+
/* @__PURE__ */ jsx("span", { className: "p-button-icon p-button-icon-left pi pi-arrow-right" }),
|
|
196
|
+
/* @__PURE__ */ jsx("span", { className: "p-button-label", children: cta.label })
|
|
197
|
+
]
|
|
198
|
+
}
|
|
199
|
+
) : /* @__PURE__ */ jsxs(
|
|
200
|
+
"button",
|
|
201
|
+
{
|
|
202
|
+
type: "button",
|
|
203
|
+
className: `p-button p-component p-button-rounded p-button-lg ${cta.className || ""}`,
|
|
204
|
+
onClick: cta.onClick,
|
|
205
|
+
style: { backgroundColor: cta.backgroundColor },
|
|
206
|
+
children: [
|
|
207
|
+
/* @__PURE__ */ jsx("span", { className: "p-button-icon p-button-icon-left pi pi-arrow-right" }),
|
|
208
|
+
/* @__PURE__ */ jsx("span", { className: "p-button-label", children: cta.label })
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
) })
|
|
212
|
+
] })
|
|
213
|
+
}
|
|
214
|
+
),
|
|
215
|
+
cta && ctaPosition !== "left" && /* @__PURE__ */ jsx(
|
|
216
|
+
"div",
|
|
217
|
+
{
|
|
218
|
+
style: {
|
|
219
|
+
position: "absolute",
|
|
220
|
+
zIndex: 3,
|
|
221
|
+
...ctaPosition === "center" && { top: "50%", left: "50%", transform: "translate(-50%, -50%)" },
|
|
222
|
+
...ctaPosition === "top-left" && { top: "2rem", left: "2rem" },
|
|
223
|
+
...ctaPosition === "top-right" && { top: "2rem", right: "2rem" },
|
|
224
|
+
...ctaPosition === "bottom-left" && { bottom: "2rem", left: "2rem" },
|
|
225
|
+
...ctaPosition === "bottom-right" && { bottom: "2rem", right: "2rem" }
|
|
226
|
+
},
|
|
227
|
+
children: cta.href ? /* @__PURE__ */ jsxs(
|
|
228
|
+
"a",
|
|
229
|
+
{
|
|
230
|
+
href: cta.href,
|
|
231
|
+
className: `p-button p-component p-button-rounded p-button-lg ${cta.className || ""}`,
|
|
232
|
+
style: { textDecoration: "none", backgroundColor: cta.backgroundColor },
|
|
233
|
+
children: [
|
|
234
|
+
/* @__PURE__ */ jsx("span", { className: "p-button-icon p-button-icon-left pi pi-arrow-right" }),
|
|
235
|
+
/* @__PURE__ */ jsx("span", { className: "p-button-label", children: cta.label })
|
|
236
|
+
]
|
|
237
|
+
}
|
|
238
|
+
) : /* @__PURE__ */ jsxs(
|
|
239
|
+
"button",
|
|
240
|
+
{
|
|
241
|
+
type: "button",
|
|
242
|
+
className: `p-button p-component p-button-rounded p-button-lg ${cta.className || ""}`,
|
|
243
|
+
onClick: cta.onClick,
|
|
244
|
+
style: { backgroundColor: cta.backgroundColor },
|
|
245
|
+
children: [
|
|
246
|
+
/* @__PURE__ */ jsx("span", { className: "p-button-icon p-button-icon-left pi pi-arrow-right" }),
|
|
247
|
+
/* @__PURE__ */ jsx("span", { className: "p-button-label", children: cta.label })
|
|
248
|
+
]
|
|
249
|
+
}
|
|
250
|
+
)
|
|
251
|
+
}
|
|
252
|
+
)
|
|
253
|
+
] })
|
|
254
|
+
]
|
|
255
|
+
}
|
|
256
|
+
);
|
|
257
|
+
};
|
|
258
|
+
export {
|
|
259
|
+
HeroFeatureBannerVideo as default
|
|
260
|
+
};
|
|
261
|
+
//# sourceMappingURL=HeroFeatureBannerVideo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HeroFeatureBannerVideo.js","sources":["../../../src/components/landing/HeroFeatureBannerVideo.tsx"],"sourcesContent":["'use client';\n\nimport React, { useEffect, useRef, useState } from 'react';\n\nexport type HeroBullet = {\n icon?: string;\n text: React.ReactNode;\n};\n\nexport type HeroFeatureBannerVideoProps = {\n bgVideoSrc?: string;\n bgPosterSrc?: string;\n bgPosterAlt?: string;\n videoAutoplay?: boolean;\n videoMuted?: boolean;\n videoLoop?: boolean;\n videoLazyLoad?: boolean;\n /** Prioritize fetch/decode for above-the-fold hero usage */\n videoPriority?: boolean;\n heading: React.ReactNode;\n bullets?: HeroBullet[];\n cta?: {\n label: string;\n href?: string;\n onClick?: () => void;\n icon?: string;\n backgroundColor?: string;\n className?: string;\n };\n ctaPosition?: 'left' | 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n height?: number;\n rounded?: string;\n leftTint?: boolean;\n contentMaxWidth?: number;\n className?: string;\n};\n\nfunction configureMobileVideo(video: HTMLVideoElement, muted: boolean) {\n video.muted = muted;\n video.defaultMuted = muted;\n video.playsInline = true;\n video.setAttribute('playsinline', '');\n video.setAttribute('webkit-playsinline', '');\n}\n\nconst HeroBackgroundVideo: React.FC<{\n src: string;\n autoplay: boolean;\n muted: boolean;\n loop: boolean;\n lazyLoad: boolean;\n priority: boolean;\n}> = ({ src, autoplay, muted, loop, lazyLoad, priority }) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const videoRef = useRef<HTMLVideoElement>(null);\n const [shouldLoad, setShouldLoad] = useState(!lazyLoad);\n const [isReady, setIsReady] = useState(false);\n const [reduceMotion, setReduceMotion] = useState(false);\n\n useEffect(() => {\n const mq = window.matchMedia('(prefers-reduced-motion: reduce)');\n const update = () => setReduceMotion(mq.matches);\n update();\n mq.addEventListener('change', update);\n return () => mq.removeEventListener('change', update);\n }, []);\n\n useEffect(() => {\n if (!lazyLoad || shouldLoad || reduceMotion) return;\n\n const node = containerRef.current;\n if (!node || typeof IntersectionObserver === 'undefined') {\n setShouldLoad(true);\n return;\n }\n\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries.some((entry) => entry.isIntersecting)) {\n setShouldLoad(true);\n observer.disconnect();\n }\n },\n { rootMargin: '200px 0px', threshold: 0.01 }\n );\n\n observer.observe(node);\n return () => observer.disconnect();\n }, [lazyLoad, shouldLoad, reduceMotion]);\n\n useEffect(() => {\n setIsReady(false);\n }, [src]);\n\n useEffect(() => {\n const video = videoRef.current;\n if (!video || !shouldLoad || reduceMotion) return;\n\n configureMobileVideo(video, muted);\n\n const tryPlay = () => {\n setIsReady(true);\n if (!autoplay) return;\n configureMobileVideo(video, muted);\n void video.play().catch(() => {\n // Autoplay may be blocked until a user gesture on some mobile browsers\n });\n };\n\n const onLoadedData = () => tryPlay();\n const onCanPlay = () => tryPlay();\n\n const onVisibilityChange = () => {\n if (!document.hidden && autoplay && video.paused) {\n configureMobileVideo(video, muted);\n void video.play().catch(() => {});\n }\n };\n\n // iOS Safari often never fires canplaythrough for large files — use loadeddata/canplay instead\n const hardFallback = window.setTimeout(tryPlay, 2000);\n\n if (video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA) {\n tryPlay();\n }\n\n video.addEventListener('loadeddata', onLoadedData);\n video.addEventListener('canplay', onCanPlay);\n document.addEventListener('visibilitychange', onVisibilityChange);\n\n return () => {\n window.clearTimeout(hardFallback);\n video.removeEventListener('loadeddata', onLoadedData);\n video.removeEventListener('canplay', onCanPlay);\n document.removeEventListener('visibilitychange', onVisibilityChange);\n };\n }, [shouldLoad, autoplay, muted, reduceMotion, src]);\n\n const setVideoRef = (node: HTMLVideoElement | null) => {\n videoRef.current = node;\n if (node) {\n configureMobileVideo(node, muted);\n }\n };\n\n if (reduceMotion || !src) {\n return <div ref={containerRef} className=\"hfbv-media-layer\" aria-hidden=\"true\" />;\n }\n\n return (\n <div ref={containerRef} className=\"hfbv-media-layer\" aria-hidden=\"true\">\n {shouldLoad && (\n <video\n ref={setVideoRef}\n className={`hfbv-video${isReady ? ' hfbv-video--ready' : ''}`}\n src={src}\n muted={muted}\n loop={loop}\n autoPlay={autoplay}\n playsInline\n preload={priority ? 'auto' : 'metadata'}\n // @ts-expect-error fetchPriority is supported in modern browsers\n fetchPriority={priority ? 'high' : 'auto'}\n disablePictureInPicture\n disableRemotePlayback\n tabIndex={-1}\n />\n )}\n </div>\n );\n};\n\nconst HeroFeatureBannerVideo: React.FC<HeroFeatureBannerVideoProps> = ({\n bgVideoSrc,\n videoAutoplay = true,\n videoMuted = true,\n videoLoop = true,\n videoLazyLoad = false,\n videoPriority = true,\n heading,\n bullets = [],\n cta,\n ctaPosition = 'left',\n height = 560,\n rounded = '',\n leftTint = true,\n contentMaxWidth = 720,\n className = '',\n}) => {\n return (\n <section\n className={`relative w-full ${rounded} overflow-hidden ${className}`}\n aria-label=\"Hero feature banner\"\n style={{ minHeight: height }}\n >\n <style>{`\n .hfbv-media-stack { position: absolute; inset: 0; z-index: 0; overflow: hidden; }\n .hfbv-media-layer { position: absolute; inset: 0; width: 100%; height: 100%; }\n .hfbv-video {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n object-position: center right;\n opacity: 0;\n transition: opacity 0.35s ease;\n transform: translate3d(0, 0, 0);\n backface-visibility: hidden;\n -webkit-backface-visibility: hidden;\n }\n .hfbv-video--ready { opacity: 1; }\n .hfbv-tint { position: absolute; inset: 0; pointer-events: none; z-index: 1; }\n .hfbv-content { position: relative; z-index: 2; }\n .hfbv-bullet i { color: var(--primary-color); font-size: 1.1rem; }\n `}</style>\n\n <div className=\"hfbv-media-stack\">\n {bgVideoSrc && (\n <HeroBackgroundVideo\n src={bgVideoSrc}\n autoplay={videoAutoplay}\n muted={videoMuted}\n loop={videoLoop}\n lazyLoad={videoLazyLoad}\n priority={videoPriority}\n />\n )}\n </div>\n\n {leftTint && <div className=\"hfbv-tint\" />}\n\n <div className=\"hfbv-content w-full h-full container\" style={{ position: 'relative' }}>\n <div\n className=\"p-4 p-md-5\"\n style={{\n height: '100%',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: ctaPosition === 'center' ? 'center' : 'flex-start',\n }}\n >\n <div style={{ maxWidth: contentMaxWidth }}>\n <h1 className=\"m-0 text-900\" style={{ fontSize: 56, lineHeight: 1.05, fontWeight: 800 }}>\n {heading}\n </h1>\n\n {bullets.length > 0 && (\n <ul className=\"list-none m-0 p-0 mt-4\">\n {bullets.map((b, i) => (\n <li key={i} className=\"flex align-items-center gap-3 mb-3 hfbv-bullet\">\n <span\n className=\"flex align-items-center justify-content-center\"\n style={{ width: 34, height: 34, background: 'rgba(255,100,50,.12)' }}\n >\n <i className={`pi ${b.icon ?? 'pi-check-circle'}`} />\n </span>\n <span className=\"text-800\" style={{ fontSize: 18 }}>\n {b.text}\n </span>\n </li>\n ))}\n </ul>\n )}\n\n {cta && ctaPosition === 'left' && (\n <div className=\"mt-5\">\n {cta.href ? (\n <a\n href={cta.href}\n className={`p-button p-component p-button-rounded p-button-lg ${cta.className || ''}`}\n style={{ textDecoration: 'none', backgroundColor: cta.backgroundColor }}\n >\n <span className=\"p-button-icon p-button-icon-left pi pi-arrow-right\" />\n <span className=\"p-button-label\">{cta.label}</span>\n </a>\n ) : (\n <button\n type=\"button\"\n className={`p-button p-component p-button-rounded p-button-lg ${cta.className || ''}`}\n onClick={cta.onClick}\n style={{ backgroundColor: cta.backgroundColor }}\n >\n <span className=\"p-button-icon p-button-icon-left pi pi-arrow-right\" />\n <span className=\"p-button-label\">{cta.label}</span>\n </button>\n )}\n </div>\n )}\n </div>\n </div>\n\n {cta && ctaPosition !== 'left' && (\n <div\n style={{\n position: 'absolute',\n zIndex: 3,\n ...(ctaPosition === 'center' && { top: '50%', left: '50%', transform: 'translate(-50%, -50%)' }),\n ...(ctaPosition === 'top-left' && { top: '2rem', left: '2rem' }),\n ...(ctaPosition === 'top-right' && { top: '2rem', right: '2rem' }),\n ...(ctaPosition === 'bottom-left' && { bottom: '2rem', left: '2rem' }),\n ...(ctaPosition === 'bottom-right' && { bottom: '2rem', right: '2rem' }),\n }}\n >\n {cta.href ? (\n <a\n href={cta.href}\n className={`p-button p-component p-button-rounded p-button-lg ${cta.className || ''}`}\n style={{ textDecoration: 'none', backgroundColor: cta.backgroundColor }}\n >\n <span className=\"p-button-icon p-button-icon-left pi pi-arrow-right\" />\n <span className=\"p-button-label\">{cta.label}</span>\n </a>\n ) : (\n <button\n type=\"button\"\n className={`p-button p-component p-button-rounded p-button-lg ${cta.className || ''}`}\n onClick={cta.onClick}\n style={{ backgroundColor: cta.backgroundColor }}\n >\n <span className=\"p-button-icon p-button-icon-left pi pi-arrow-right\" />\n <span className=\"p-button-label\">{cta.label}</span>\n </button>\n )}\n </div>\n )}\n </div>\n </section>\n );\n};\n\nexport default HeroFeatureBannerVideo;\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import React, { useEffect } from "react";
|
|
4
|
+
import HeroFeatureBannerVideo from "./HeroFeatureBannerVideo.js";
|
|
5
|
+
import { resolveMediaSrc } from "../../lib/resolveMediaSrc.js";
|
|
6
|
+
function useHeroVideoPreload(src, enabled = true) {
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
if (!src || !enabled) return;
|
|
9
|
+
const existing = document.querySelector(`link[data-hfbv-preload="${src}"]`);
|
|
10
|
+
if (existing) return;
|
|
11
|
+
const link = document.createElement("link");
|
|
12
|
+
link.rel = "preload";
|
|
13
|
+
link.as = "video";
|
|
14
|
+
link.href = src;
|
|
15
|
+
link.setAttribute("fetchpriority", "high");
|
|
16
|
+
link.setAttribute("data-hfbv-preload", src);
|
|
17
|
+
document.head.appendChild(link);
|
|
18
|
+
return () => {
|
|
19
|
+
link.remove();
|
|
20
|
+
};
|
|
21
|
+
}, [src, enabled]);
|
|
22
|
+
}
|
|
23
|
+
const HeroFeatureBannerVideoComponent = ({ props, isAboveFold: _isAboveFold = false }) => {
|
|
24
|
+
const bullets = Array.isArray(props.bullets) ? props.bullets : [];
|
|
25
|
+
let headingNode = props.heading || "";
|
|
26
|
+
if (typeof headingNode === "string" && headingNode.includes("\n")) {
|
|
27
|
+
const parts = headingNode.split("\n");
|
|
28
|
+
headingNode = /* @__PURE__ */ jsx(Fragment, { children: parts.map((part, i) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
29
|
+
i > 0 && /* @__PURE__ */ jsx("br", {}),
|
|
30
|
+
part
|
|
31
|
+
] }, i)) });
|
|
32
|
+
}
|
|
33
|
+
const cta = props.ctaLabel ? {
|
|
34
|
+
label: props.ctaLabel,
|
|
35
|
+
href: props.ctaHref,
|
|
36
|
+
icon: props.ctaIcon,
|
|
37
|
+
backgroundColor: props.ctaBgColor,
|
|
38
|
+
className: props.ctaClassName
|
|
39
|
+
} : void 0;
|
|
40
|
+
const bgVideoSrc = resolveMediaSrc(props.bgVideoSrc, props.bgVideoSrcNew);
|
|
41
|
+
useHeroVideoPreload(bgVideoSrc, Boolean(bgVideoSrc));
|
|
42
|
+
return /* @__PURE__ */ jsx("div", { className: `hero-feature-banner-video ${props.wrapperClassName || ""}`, children: /* @__PURE__ */ jsxs("div", { className: props.sectionBgClassName || "", children: [
|
|
43
|
+
props.customCSS && /* @__PURE__ */ jsx("style", { children: props.customCSS }),
|
|
44
|
+
/* @__PURE__ */ jsx(
|
|
45
|
+
HeroFeatureBannerVideo,
|
|
46
|
+
{
|
|
47
|
+
bgVideoSrc,
|
|
48
|
+
videoAutoplay: Boolean(bgVideoSrc),
|
|
49
|
+
videoMuted: true,
|
|
50
|
+
videoLoop: props.videoLoop !== false,
|
|
51
|
+
videoLazyLoad: false,
|
|
52
|
+
videoPriority: true,
|
|
53
|
+
heading: headingNode,
|
|
54
|
+
bullets,
|
|
55
|
+
cta,
|
|
56
|
+
ctaPosition: props.ctaPosition || "left",
|
|
57
|
+
height: props.height || 560,
|
|
58
|
+
rounded: props.rounded || "",
|
|
59
|
+
leftTint: props.leftTint !== false,
|
|
60
|
+
contentMaxWidth: props.contentMaxWidth || 720,
|
|
61
|
+
className: props.className || ""
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
] }) });
|
|
65
|
+
};
|
|
66
|
+
export {
|
|
67
|
+
HeroFeatureBannerVideoComponent
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=HeroFeatureBannerVideoComponent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HeroFeatureBannerVideoComponent.js","sources":["../../../src/components/landing/HeroFeatureBannerVideoComponent.tsx"],"sourcesContent":["'use client';\n\nimport React, { useEffect } from 'react';\nimport HeroFeatureBannerVideo from './HeroFeatureBannerVideo';\nimport { resolveMediaSrc } from '../../lib/resolveMediaSrc';\n\nfunction useHeroVideoPreload(src?: string, enabled = true) {\n useEffect(() => {\n if (!src || !enabled) return;\n\n const existing = document.querySelector<HTMLLinkElement>(`link[data-hfbv-preload=\"${src}\"]`);\n if (existing) return;\n\n const link = document.createElement('link');\n link.rel = 'preload';\n link.as = 'video';\n link.href = src;\n link.setAttribute('fetchpriority', 'high');\n link.setAttribute('data-hfbv-preload', src);\n document.head.appendChild(link);\n\n return () => {\n link.remove();\n };\n }, [src, enabled]);\n}\n\nexport const HeroFeatureBannerVideoComponent: React.FC<{\n props: Record<string, any>;\n isAboveFold?: boolean;\n}> = ({ props, isAboveFold: _isAboveFold = false }) => {\n const bullets: any[] = Array.isArray(props.bullets) ? props.bullets : [];\n\n let headingNode: React.ReactNode = props.heading || '';\n if (typeof headingNode === 'string' && headingNode.includes('\\n')) {\n const parts = (headingNode as string).split('\\n');\n headingNode = (\n <>\n {parts.map((part: string, i: number) => (\n <React.Fragment key={i}>\n {i > 0 && <br />}\n {part}\n </React.Fragment>\n ))}\n </>\n );\n }\n\n const cta =\n props.ctaLabel\n ? {\n label: props.ctaLabel,\n href: props.ctaHref,\n icon: props.ctaIcon,\n backgroundColor: props.ctaBgColor,\n className: props.ctaClassName\n }\n : undefined;\n\n const bgVideoSrc = resolveMediaSrc(props.bgVideoSrc, props.bgVideoSrcNew);\n\n // Hero videos must load immediately — lazy load breaks mobile autoplay (especially iOS Safari)\n useHeroVideoPreload(bgVideoSrc, Boolean(bgVideoSrc));\n\n return (\n <div className={`hero-feature-banner-video ${props.wrapperClassName || ''}`}>\n <div className={props.sectionBgClassName || ''}>\n {props.customCSS && <style>{props.customCSS}</style>}\n <HeroFeatureBannerVideo\n bgVideoSrc={bgVideoSrc}\n videoAutoplay={Boolean(bgVideoSrc)}\n videoMuted\n videoLoop={props.videoLoop !== false}\n videoLazyLoad={false}\n videoPriority\n heading={headingNode}\n bullets={bullets}\n cta={cta}\n ctaPosition={props.ctaPosition || 'left'}\n height={props.height || 560}\n rounded={props.rounded || ''}\n leftTint={props.leftTint !== false}\n contentMaxWidth={props.contentMaxWidth || 720}\n className={props.className || ''}\n />\n </div>\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;AAMA,SAAS,oBAAoB,KAAc,UAAU,MAAM;AACzD,YAAU,MAAM;AACd,QAAI,CAAC,OAAO,CAAC,QAAS;AAEtB,UAAM,WAAW,SAAS,cAA+B,2BAA2B,GAAG,IAAI;AAC3F,QAAI,SAAU;AAEd,UAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,SAAK,MAAM;AACX,SAAK,KAAK;AACV,SAAK,OAAO;AACZ,SAAK,aAAa,iBAAiB,MAAM;AACzC,SAAK,aAAa,qBAAqB,GAAG;AAC1C,aAAS,KAAK,YAAY,IAAI;AAE9B,WAAO,MAAM;AACX,WAAK,OAAA;AAAA,IACP;AAAA,EACF,GAAG,CAAC,KAAK,OAAO,CAAC;AACnB;AAEO,MAAM,kCAGR,CAAC,EAAE,OAAO,aAAa,eAAe,YAAY;AACrD,QAAM,UAAiB,MAAM,QAAQ,MAAM,OAAO,IAAI,MAAM,UAAU,CAAA;AAEtE,MAAI,cAA+B,MAAM,WAAW;AACpD,MAAI,OAAO,gBAAgB,YAAY,YAAY,SAAS,IAAI,GAAG;AACjE,UAAM,QAAS,YAAuB,MAAM,IAAI;AAChD,kBACE,oBAAA,UAAA,EACG,gBAAM,IAAI,CAAC,MAAc,MACxB,qBAAC,MAAM,UAAN,EACE,UAAA;AAAA,MAAA,IAAI,yBAAM,MAAA,CAAA,CAAG;AAAA,MACb;AAAA,IAAA,KAFkB,CAGrB,CACD,GACH;AAAA,EAEJ;AAEA,QAAM,MACJ,MAAM,WACF;AAAA,IACE,OAAO,MAAM;AAAA,IACb,MAAM,MAAM;AAAA,IACZ,MAAM,MAAM;AAAA,IACZ,iBAAiB,MAAM;AAAA,IACvB,WAAW,MAAM;AAAA,EAAA,IAEnB;AAEN,QAAM,aAAa,gBAAgB,MAAM,YAAY,MAAM,aAAa;AAGxE,sBAAoB,YAAY,QAAQ,UAAU,CAAC;AAEnD,SACE,oBAAC,OAAA,EAAI,WAAW,6BAA6B,MAAM,oBAAoB,EAAE,IACvE,UAAA,qBAAC,OAAA,EAAI,WAAW,MAAM,sBAAsB,IACzC,UAAA;AAAA,IAAA,MAAM,aAAa,oBAAC,SAAA,EAAO,UAAA,MAAM,WAAU;AAAA,IAC5C;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAe,QAAQ,UAAU;AAAA,QACjC,YAAU;AAAA,QACV,WAAW,MAAM,cAAc;AAAA,QAC/B,eAAe;AAAA,QACf,eAAa;AAAA,QACb,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA,aAAa,MAAM,eAAe;AAAA,QAClC,QAAQ,MAAM,UAAU;AAAA,QACxB,SAAS,MAAM,WAAW;AAAA,QAC1B,UAAU,MAAM,aAAa;AAAA,QAC7B,iBAAiB,MAAM,mBAAmB;AAAA,QAC1C,WAAW,MAAM,aAAa;AAAA,MAAA;AAAA,IAAA;AAAA,EAChC,EAAA,CACF,EAAA,CACF;AAEJ;"}
|