@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.
- package/dist/contentful/index.d.ts +6 -0
- package/dist/contentful/index.esm.js +1 -1
- package/dist/contentful/index.esm.js.map +1 -1
- package/dist/contentful/index.js +3 -3
- package/dist/contentful/index.js.map +1 -1
- package/dist/core.d.ts +2 -2
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/contentful/blocks/callout/index.tsx +1 -1
- package/src/contentful/blocks/cards/floating-image-card/index.tsx +12 -0
- package/src/contentful/blocks/cards/floating-image-card/types.ts +2 -0
- package/src/contentful/blocks/carousel/index.tsx +1 -1
- package/src/contentful/blocks/primary-hero/PrimaryHero.stories.tsx +39 -0
- package/src/contentful/blocks/primary-hero/index.test.tsx +68 -0
- package/src/contentful/blocks/primary-hero/index.tsx +87 -48
- package/src/contentful/blocks/primary-hero/types.ts +7 -0
|
@@ -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
|
-
{
|
|
239
|
-
<
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
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
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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
|
-
|
|
295
|
-
{
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
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";
|