@windstream/react-shared-components 0.2.28 → 0.2.30

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.
@@ -31,6 +31,8 @@ export const PrimaryHero: React.FC<PrimaryHeroProps> = props => {
31
31
  hideOnMobileCta2,
32
32
  textColor = "light",
33
33
  logoLockup,
34
+ heroVideo,
35
+ heroVideoMobile,
34
36
  } = props;
35
37
 
36
38
  const isButtonType = (cta: any) => {
@@ -46,13 +48,31 @@ export const PrimaryHero: React.FC<PrimaryHeroProps> = props => {
46
48
  isButtonType(primaryCta1) &&
47
49
  isButtonType(primaryCta2);
48
50
 
51
+ const desktopVideoUrl = heroVideo?.url?.trim();
52
+ const mobileVideoUrl = heroVideoMobile?.url?.trim();
53
+ const hasDesktopVideo = !!desktopVideoUrl;
54
+ const hasMobileVideo = !!mobileVideoUrl;
49
55
  const bottomLinkLabel = bottomLink?.buttonLabel ?? bottomLink?.label;
50
56
  const textColorClass = textColor === "light" ? " text-white" : " text-text";
51
57
  return (
52
- <div className="component-container p-5 xl:flex xl:min-h-[724px] xl:items-center xl:p-0 xl:py-4">
58
+ <div className="component-container relative overflow-hidden p-5 xl:flex xl:min-h-[724px] xl:items-center xl:p-0 xl:py-4">
59
+ {hasDesktopVideo ? (
60
+ <video
61
+ autoPlay={true}
62
+ muted={true}
63
+ loop={true}
64
+ playsInline={true}
65
+ preload="auto"
66
+ aria-label={heroVideo?.title || title || "Hero background video"}
67
+ className="absolute inset-0 z-0 hidden h-full w-full object-fill xl:block"
68
+ data-testid="hero-background-video-desktop"
69
+ >
70
+ <source src={desktopVideoUrl} type="video/mp4" />
71
+ </video>
72
+ ) : null}
53
73
  <div
54
74
  className={cx(
55
- "primary-hero-container mx-auto flex w-full flex-col sm:items-center sm:text-center xl:h-full xl:max-w-120 xl:flex-row xl:items-center xl:justify-between xl:gap-4 xl:text-left"
75
+ "primary-hero-container relative z-10 mx-auto flex w-full flex-col sm:items-center sm:text-center xl:h-full xl:max-w-120 xl:flex-row xl:items-center xl:justify-between xl:gap-4 xl:text-left"
56
76
  )}
57
77
  >
58
78
  {/* Left column: navy background, headline, body, address, button, link */}
@@ -235,29 +255,46 @@ export const PrimaryHero: React.FC<PrimaryHeroProps> = props => {
235
255
  {/* mobile hero image and bottom link */}
236
256
  <div className="xl:hidden">
237
257
  <div className={"relative my-8"}>
238
- {badgeImage ? (
239
- <NextImage
240
- src={badgeImage}
241
- alt={"Badge"}
242
- className="absolute left-5 top-5 aspect-square w-26 object-cover object-center"
243
- width={104}
244
- height={104}
245
- quality={90}
246
- loading="eager"
247
- />
248
- ) : null}
249
- {carouselImages && carouselImages[0] ? (
250
- <NextImage
251
- src={carouselImages[0]}
252
- alt={"Hero"}
258
+ {hasMobileVideo ? (
259
+ <video
260
+ autoPlay={true}
261
+ muted={true}
262
+ loop={true}
263
+ playsInline={true}
264
+ preload="auto"
265
+ aria-label={heroVideoMobile?.title || title || "Hero video"}
253
266
  className="aspect-[1.71:1] sm:aspect-[1.41:1] w-full rounded-[40px] object-cover object-center sm:h-[420px]"
254
- width={1024}
255
- height={600}
256
- sizes="100vw"
257
- quality={90}
258
- loading="eager"
259
- />
260
- ) : null}
267
+ data-testid="hero-video-mobile"
268
+ >
269
+ <source src={mobileVideoUrl} type="video/mp4" />
270
+ </video>
271
+ ) : (
272
+ <>
273
+ {badgeImage ? (
274
+ <NextImage
275
+ src={badgeImage}
276
+ alt={"Badge"}
277
+ className="absolute left-5 top-5 aspect-square w-26 object-cover object-center"
278
+ width={104}
279
+ height={104}
280
+ quality={90}
281
+ loading="eager"
282
+ />
283
+ ) : null}
284
+ {carouselImages && carouselImages[0] ? (
285
+ <NextImage
286
+ src={carouselImages[0]}
287
+ alt={"Hero"}
288
+ className="aspect-[1.71:1] sm:aspect-[1.41:1] w-full rounded-[40px] object-cover object-center sm:h-[420px]"
289
+ width={1024}
290
+ height={600}
291
+ sizes="100vw"
292
+ quality={90}
293
+ loading="eager"
294
+ />
295
+ ) : null}
296
+ </>
297
+ )}
261
298
  </div>
262
299
 
263
300
  {bottomLink && (bottomLinkLabel || bottomLink?.href) && (
@@ -291,30 +328,32 @@ export const PrimaryHero: React.FC<PrimaryHeroProps> = props => {
291
328
  </div>
292
329
 
293
330
  {/* Right column: bright blue background, diagonal top edge, hero image */}
294
- <div className={cx("relative hidden xl:block")}>
295
- {badgeImage ? (
296
- <NextImage
297
- src={badgeImage}
298
- alt={"Badge"}
299
- className="absolute -left-26 top-18 aspect-square w-52 object-cover object-center"
300
- width={208}
301
- height={208}
302
- quality={90}
303
- loading="eager"
304
- />
305
- ) : null}
306
- {carouselImages && carouselImages[0] ? (
307
- <NextImage
308
- src={carouselImages[0]}
309
- alt={"Hero"}
310
- className="aspect-square rounded-[40px] object-cover object-center"
311
- width={600}
312
- height={600}
313
- quality={90}
314
- loading="eager"
315
- />
316
- ) : null}
317
- </div>
331
+ {!hasDesktopVideo ? (
332
+ <div className={cx("relative hidden xl:block")}>
333
+ {badgeImage ? (
334
+ <NextImage
335
+ src={badgeImage}
336
+ alt={"Badge"}
337
+ className="absolute -left-26 top-18 aspect-square w-52 object-cover object-center"
338
+ width={208}
339
+ height={208}
340
+ quality={90}
341
+ loading="eager"
342
+ />
343
+ ) : null}
344
+ {carouselImages && carouselImages[0] ? (
345
+ <NextImage
346
+ src={carouselImages[0]}
347
+ alt={"Hero"}
348
+ className="aspect-square rounded-[40px] object-cover object-center"
349
+ width={600}
350
+ height={600}
351
+ quality={90}
352
+ loading="eager"
353
+ />
354
+ ) : null}
355
+ </div>
356
+ ) : null}
318
357
  </div>
319
358
  </div>
320
359
  );
@@ -2,6 +2,11 @@ import React from "react";
2
2
 
3
3
  import { CheckPlansProps } from "@shared/types/micro-components";
4
4
 
5
+ export type PrimaryHeroVideo = {
6
+ url?: string;
7
+ title?: string;
8
+ };
9
+
5
10
  export type PrimaryHeroProps = {
6
11
  title: string;
7
12
  showAsHeading?: boolean;
@@ -28,6 +33,8 @@ export type PrimaryHeroProps = {
28
33
  secondaryCta?: any;
29
34
  bottomLink?: any;
30
35
  carouselImages?: string[];
36
+ heroVideo?: PrimaryHeroVideo;
37
+ heroVideoMobile?: PrimaryHeroVideo;
31
38
  squareImage?: boolean;
32
39
  badgeImage?: string;
33
40
  textColor?: "light" | "dark";