@windstream/react-shared-components 0.1.67 → 0.1.69
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 +635 -635
- package/dist/contentful/index.d.ts +23 -0
- package/dist/contentful/index.esm.js +3 -3
- 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/index.d.ts +3 -3
- package/dist/index.esm.js +13 -5
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +13 -5
- package/dist/index.js.map +1 -1
- package/dist/next/index.esm.js +2 -2
- package/dist/next/index.esm.js.map +1 -1
- package/dist/next/index.js +2 -2
- package/dist/next/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/utils/index.esm.js +1 -1
- package/dist/utils/index.esm.js.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +185 -185
- package/src/components/accordion/Accordion.stories.tsx +230 -230
- package/src/components/accordion/index.tsx +70 -70
- package/src/components/accordion/types.ts +12 -12
- package/src/components/alert-card/AlertCard.stories.tsx +171 -171
- package/src/components/alert-card/index.tsx +41 -41
- package/src/components/alert-card/types.ts +13 -13
- package/src/components/brand-button/BrandButton.stories.tsx +223 -223
- package/src/components/brand-button/helpers.ts +35 -35
- package/src/components/brand-button/index.tsx +120 -120
- package/src/components/brand-button/types.ts +38 -38
- package/src/components/button/Button.stories.tsx +108 -108
- package/src/components/button/index.tsx +27 -27
- package/src/components/button/types.ts +14 -14
- package/src/components/call-button/CallButton.stories.tsx +324 -324
- package/src/components/call-button/index.tsx +106 -86
- package/src/components/call-button/types.ts +16 -11
- package/src/components/checkbox/Checkbox.stories.tsx +247 -247
- package/src/components/checkbox/index.tsx +197 -197
- package/src/components/checkbox/types.ts +27 -27
- package/src/components/checklist/Checklist.stories.tsx +150 -150
- package/src/components/checklist/index.tsx +61 -61
- package/src/components/checklist/types.ts +17 -17
- package/src/components/collapse/Collapse.stories.tsx +255 -255
- package/src/components/collapse/index.tsx +46 -46
- package/src/components/collapse/types.ts +6 -6
- package/src/components/divider/Divider.stories.tsx +205 -205
- package/src/components/divider/index.tsx +22 -22
- package/src/components/divider/type.ts +3 -3
- package/src/components/image/Image.stories.tsx +113 -113
- package/src/components/image/index.tsx +25 -25
- package/src/components/image/types.ts +40 -40
- package/src/components/input/Input.stories.tsx +325 -325
- package/src/components/input/index.tsx +177 -177
- package/src/components/input/types.ts +37 -37
- package/src/components/link/Link.stories.tsx +163 -163
- package/src/components/link/index.tsx +116 -109
- package/src/components/link/types.ts +25 -25
- package/src/components/list/List.stories.tsx +272 -272
- package/src/components/list/index.tsx +88 -88
- package/src/components/list/list-item/index.tsx +38 -38
- package/src/components/list/list-item/types.ts +13 -13
- package/src/components/list/types.ts +29 -29
- package/src/components/material-icon/MaterialIcon.stories.tsx +322 -322
- package/src/components/material-icon/constants.ts +99 -98
- package/src/components/material-icon/index.tsx +47 -47
- package/src/components/material-icon/types.ts +31 -31
- package/src/components/modal/Modal.stories.tsx +171 -171
- package/src/components/modal/index.tsx +164 -164
- package/src/components/modal/types.ts +24 -24
- package/src/components/next-image/index.tsx +72 -54
- package/src/components/next-image/types.ts +1 -1
- package/src/components/pagination/index.tsx +91 -91
- package/src/components/pagination/types.ts +6 -6
- package/src/components/radio-button/RadioButton.stories.tsx +307 -307
- package/src/components/radio-button/index.tsx +75 -75
- package/src/components/radio-button/types.ts +21 -21
- package/src/components/see-more/SeeMore.stories.tsx +181 -181
- package/src/components/see-more/index.tsx +44 -44
- package/src/components/see-more/types.ts +4 -4
- package/src/components/select/Select.stories.tsx +411 -411
- package/src/components/select/index.tsx +155 -155
- package/src/components/select/types.ts +36 -36
- package/src/components/select-plan-button/SelectPlanButton.stories.tsx +184 -184
- package/src/components/select-plan-button/index.tsx +63 -63
- package/src/components/select-plan-button/types.ts +17 -17
- package/src/components/skeleton/Skeleton.stories.tsx +179 -179
- package/src/components/skeleton/index.tsx +61 -61
- package/src/components/skeleton/types.ts +4 -4
- package/src/components/spinner/Spinner.stories.tsx +335 -335
- package/src/components/spinner/index.tsx +44 -44
- package/src/components/spinner/types.ts +5 -5
- package/src/components/text/Text.stories.tsx +321 -321
- package/src/components/text/index.tsx +25 -25
- package/src/components/text/types.ts +45 -45
- package/src/components/tooltip/Tooltip.stories.tsx +219 -219
- package/src/components/tooltip/index.tsx +74 -74
- package/src/components/tooltip/types.ts +7 -7
- package/src/components/view-cart-button/ViewCartButton.stories.tsx +252 -252
- package/src/components/view-cart-button/index.tsx +42 -42
- package/src/components/view-cart-button/types.ts +5 -5
- package/src/contentful/blocks/accordion/Accordion.stories.mocks.tsx +127 -127
- package/src/contentful/blocks/accordion/Accordion.stories.tsx +105 -105
- package/src/contentful/blocks/accordion/index.tsx +112 -112
- package/src/contentful/blocks/accordion/types.ts +34 -34
- package/src/contentful/blocks/address-input-banner/index.tsx +52 -52
- package/src/contentful/blocks/address-input-banner/types.ts +14 -14
- package/src/contentful/blocks/anchored-bottom-banner/index.tsx +70 -70
- package/src/contentful/blocks/anchored-bottom-banner/types.ts +10 -10
- package/src/contentful/blocks/blogs-grid/index.tsx +134 -134
- package/src/contentful/blocks/blogs-grid/types.ts +26 -26
- package/src/contentful/blocks/blogs-grid-base/index.tsx +119 -119
- package/src/contentful/blocks/blogs-grid-base/types.ts +35 -35
- package/src/contentful/blocks/breadcrumbs/types.ts +6 -6
- package/src/contentful/blocks/button/Button.stories.tsx +40 -40
- package/src/contentful/blocks/button/index.tsx +131 -131
- package/src/contentful/blocks/button/types.ts +39 -39
- package/src/contentful/blocks/callout/Callout.stories.tsx +23 -23
- package/src/contentful/blocks/callout/index.tsx +88 -88
- package/src/contentful/blocks/callout/types.ts +15 -15
- package/src/contentful/blocks/cards/Cards.stories.tsx +23 -23
- package/src/contentful/blocks/cards/blog-card/index.tsx +129 -129
- package/src/contentful/blocks/cards/blog-card/types.ts +34 -34
- package/src/contentful/blocks/cards/index.tsx +13 -13
- package/src/contentful/blocks/cards/product-card/index.tsx +251 -251
- package/src/contentful/blocks/cards/product-card/types.ts +28 -28
- package/src/contentful/blocks/cards/simple-card/index.tsx +89 -89
- package/src/contentful/blocks/cards/simple-card/types.ts +28 -28
- package/src/contentful/blocks/cards/testimonial-card/index.tsx +90 -90
- package/src/contentful/blocks/cards/testimonial-card/types.tsx +12 -12
- package/src/contentful/blocks/cards/types.ts +1 -1
- package/src/contentful/blocks/carousel/Carousel.stories.tsx +23 -23
- package/src/contentful/blocks/carousel/helper.tsx +440 -440
- package/src/contentful/blocks/carousel/index.tsx +85 -85
- package/src/contentful/blocks/carousel/types.ts +144 -144
- package/src/contentful/blocks/cart-retention-banner/index.tsx +105 -105
- package/src/contentful/blocks/cart-retention-banner/types.ts +11 -11
- package/src/contentful/blocks/comparison-table/index.tsx +27 -27
- package/src/contentful/blocks/comparison-table/types.ts +6 -6
- package/src/contentful/blocks/cookiebanner/index.tsx +146 -146
- package/src/contentful/blocks/cookiebanner/type.ts +7 -7
- package/src/contentful/blocks/cta-callout/CtaCallout.stories.tsx +46 -46
- package/src/contentful/blocks/cta-callout/index.tsx +71 -71
- package/src/contentful/blocks/cta-callout/types.ts +26 -26
- package/src/contentful/blocks/dynamic-tabs/index.tsx +204 -204
- package/src/contentful/blocks/dynamic-tabs/types.ts +21 -21
- package/src/contentful/blocks/email-input-block/index.tsx +117 -117
- package/src/contentful/blocks/email-input-block/types.ts +16 -16
- package/src/contentful/blocks/find-kinetic/FindKinetic.stories.tsx +23 -23
- package/src/contentful/blocks/find-kinetic/index.tsx +130 -130
- package/src/contentful/blocks/find-kinetic/types.ts +19 -19
- package/src/contentful/blocks/floating-banner/FloatingBanner.stories.tsx +34 -34
- package/src/contentful/blocks/floating-banner/index.tsx +97 -97
- package/src/contentful/blocks/floating-banner/types.ts +22 -22
- package/src/contentful/blocks/footer/Footer.stories.tsx +203 -203
- package/src/contentful/blocks/footer/index.tsx +91 -91
- package/src/contentful/blocks/footer/types.ts +13 -13
- package/src/contentful/blocks/image-promo-bar/ImagePromoBar.stories.tsx +23 -23
- package/src/contentful/blocks/image-promo-bar/helper.tsx +28 -28
- package/src/contentful/blocks/image-promo-bar/index.tsx +246 -246
- package/src/contentful/blocks/image-promo-bar/types.ts +44 -44
- package/src/contentful/blocks/image-promo-bar/vimeo-embed.tsx +93 -93
- package/src/contentful/blocks/image-promo-bar/youtube-embed.tsx +46 -46
- package/src/contentful/blocks/modal/constants.ts +53 -53
- package/src/contentful/blocks/modal/index.tsx +107 -107
- package/src/contentful/blocks/modal/types.ts +12 -12
- package/src/contentful/blocks/navigation/desktop-link-groups.tsx/index.tsx +124 -113
- package/src/contentful/blocks/navigation/index.tsx +462 -394
- package/src/contentful/blocks/navigation/mobile-link-groups.tsx/index.tsx +82 -82
- package/src/contentful/blocks/navigation/types.ts +64 -41
- package/src/contentful/blocks/primary-hero/PrimaryHero.stories.tsx +23 -23
- package/src/contentful/blocks/primary-hero/index.tsx +236 -236
- package/src/contentful/blocks/primary-hero/types.ts +37 -37
- package/src/contentful/blocks/search-block/index.tsx +90 -90
- package/src/contentful/blocks/search-block/types.ts +15 -15
- package/src/contentful/blocks/shape-background-wrapper/ShapeBackgroundWrapper.stories.tsx +26 -26
- package/src/contentful/blocks/shape-background-wrapper/index.tsx +124 -124
- package/src/contentful/blocks/shape-background-wrapper/types.ts +36 -36
- package/src/contentful/blocks/text/Text.stories.tsx +23 -23
- package/src/contentful/blocks/text/index.tsx +12 -12
- package/src/contentful/blocks/text/types.ts +1 -1
- package/src/contentful/index.ts +106 -106
- package/src/hooks/contentful/use-contentful-rich-text.tsx +310 -310
- package/src/hooks/contentful/use-processed-check-list.ts +63 -63
- package/src/hooks/use-body-scroll-lock.ts +34 -34
- package/src/hooks/use-carousel-swipe.ts +264 -264
- package/src/hooks/use-outside-click.ts +17 -17
- package/src/index.ts +101 -101
- package/src/next/index.ts +5 -5
- package/src/setupTests.ts +46 -46
- package/src/stories/DocsTemplate.tsx +24 -24
- package/src/styles/globals.css +343 -343
- package/src/types/global.d.ts +9 -9
- package/src/types/micro-components.ts +99 -99
- package/src/types/utm.ts +49 -49
- package/src/utils/contentful/to-document.ts +24 -24
- package/src/utils/cookie.ts +84 -84
- package/src/utils/cx.ts +49 -49
- package/src/utils/index.ts +38 -38
- package/src/utils/utm.ts +221 -221
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { ImagePromoBar } from "./index";
|
|
2
|
-
|
|
3
|
-
import { DocsPage } from "@shared/stories/DocsTemplate";
|
|
4
|
-
import type { Meta, StoryObj } from "@storybook/react";
|
|
5
|
-
|
|
6
|
-
const meta: Meta<typeof ImagePromoBar> = {
|
|
7
|
-
title: "Contentful Blocks/ImagePromoBar",
|
|
8
|
-
component: ImagePromoBar,
|
|
9
|
-
tags: ["autodocs"],
|
|
10
|
-
parameters: {
|
|
11
|
-
layout: "centered",
|
|
12
|
-
docs: {
|
|
13
|
-
page: DocsPage,
|
|
14
|
-
description: {
|
|
15
|
-
component: "Contentful image promo bar block.",
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
args: {},
|
|
20
|
-
};
|
|
21
|
-
export default meta;
|
|
22
|
-
type Story = StoryObj<typeof meta>;
|
|
23
|
-
export const Default: Story = {};
|
|
1
|
+
import { ImagePromoBar } from "./index";
|
|
2
|
+
|
|
3
|
+
import { DocsPage } from "@shared/stories/DocsTemplate";
|
|
4
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof ImagePromoBar> = {
|
|
7
|
+
title: "Contentful Blocks/ImagePromoBar",
|
|
8
|
+
component: ImagePromoBar,
|
|
9
|
+
tags: ["autodocs"],
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: "centered",
|
|
12
|
+
docs: {
|
|
13
|
+
page: DocsPage,
|
|
14
|
+
description: {
|
|
15
|
+
component: "Contentful image promo bar block.",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
args: {},
|
|
20
|
+
};
|
|
21
|
+
export default meta;
|
|
22
|
+
type Story = StoryObj<typeof meta>;
|
|
23
|
+
export const Default: Story = {};
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { PlayButtonProps } from "./types";
|
|
3
|
-
|
|
4
|
-
import { MaterialIcon } from "@shared/components/material-icon";
|
|
5
|
-
|
|
6
|
-
export const PlayButton: React.FC<PlayButtonProps> = ({
|
|
7
|
-
isHovered: isOuterHovered,
|
|
8
|
-
containerClassName,
|
|
9
|
-
}) => {
|
|
10
|
-
return (
|
|
11
|
-
<button
|
|
12
|
-
tabIndex={-1}
|
|
13
|
-
className={`group flex h-20 w-20 items-center justify-center rounded-full bg-white shadow-xl transition-all duration-300 hover:scale-110 active:scale-95 ${containerClassName || ""}`}
|
|
14
|
-
aria-label="Play button"
|
|
15
|
-
>
|
|
16
|
-
<MaterialIcon
|
|
17
|
-
name="play_arrow"
|
|
18
|
-
size={72 as any}
|
|
19
|
-
fill={1}
|
|
20
|
-
className={`transition-colors duration-300 ${
|
|
21
|
-
isOuterHovered
|
|
22
|
-
? "text-text-brand"
|
|
23
|
-
: "text-slate-500 group-hover:text-text-brand"
|
|
24
|
-
}`}
|
|
25
|
-
/>
|
|
26
|
-
</button>
|
|
27
|
-
);
|
|
28
|
-
};
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { PlayButtonProps } from "./types";
|
|
3
|
+
|
|
4
|
+
import { MaterialIcon } from "@shared/components/material-icon";
|
|
5
|
+
|
|
6
|
+
export const PlayButton: React.FC<PlayButtonProps> = ({
|
|
7
|
+
isHovered: isOuterHovered,
|
|
8
|
+
containerClassName,
|
|
9
|
+
}) => {
|
|
10
|
+
return (
|
|
11
|
+
<button
|
|
12
|
+
tabIndex={-1}
|
|
13
|
+
className={`group flex h-20 w-20 items-center justify-center rounded-full bg-white shadow-xl transition-all duration-300 hover:scale-110 active:scale-95 ${containerClassName || ""}`}
|
|
14
|
+
aria-label="Play button"
|
|
15
|
+
>
|
|
16
|
+
<MaterialIcon
|
|
17
|
+
name="play_arrow"
|
|
18
|
+
size={72 as any}
|
|
19
|
+
fill={1}
|
|
20
|
+
className={`transition-colors duration-300 ${
|
|
21
|
+
isOuterHovered
|
|
22
|
+
? "text-text-brand"
|
|
23
|
+
: "text-slate-500 group-hover:text-text-brand"
|
|
24
|
+
}`}
|
|
25
|
+
/>
|
|
26
|
+
</button>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
@@ -1,246 +1,246 @@
|
|
|
1
|
-
import React, { useState } from "react";
|
|
2
|
-
import { Button } from "../button";
|
|
3
|
-
import { PlayButton } from "./helper";
|
|
4
|
-
import { ImagePromoBarProps } from "./types";
|
|
5
|
-
import { VimeoEmbed } from "./vimeo-embed";
|
|
6
|
-
import { YoutubeEmbed } from "./youtube-embed";
|
|
7
|
-
|
|
8
|
-
import { Checklist } from "@shared/components/checklist";
|
|
9
|
-
import { Image } from "@shared/components/image";
|
|
10
|
-
import { Link } from "@shared/components/link";
|
|
11
|
-
import { NextImage } from "@shared/components/next-image";
|
|
12
|
-
import { Text } from "@shared/components/text";
|
|
13
|
-
import { cx } from "@shared/utils";
|
|
14
|
-
|
|
15
|
-
export const ImagePromoBar: React.FC<ImagePromoBarProps> = ({
|
|
16
|
-
brow,
|
|
17
|
-
enableHeading,
|
|
18
|
-
title,
|
|
19
|
-
subTitle,
|
|
20
|
-
ctaDisclaimer,
|
|
21
|
-
disclaimer,
|
|
22
|
-
description,
|
|
23
|
-
image,
|
|
24
|
-
imageLinks,
|
|
25
|
-
mediaPosition = true,
|
|
26
|
-
checklist,
|
|
27
|
-
secondaryCta,
|
|
28
|
-
cta,
|
|
29
|
-
videoLink,
|
|
30
|
-
maxWidth = true,
|
|
31
|
-
color = "light",
|
|
32
|
-
imageWidth = 660,
|
|
33
|
-
imageHeight = 660,
|
|
34
|
-
onModalButtonClick,
|
|
35
|
-
renderCheckPlans,
|
|
36
|
-
}) => {
|
|
37
|
-
const [activeVideo, setActiveVideo] = useState("");
|
|
38
|
-
const [isHovered, setIsHovered] = useState(false);
|
|
39
|
-
|
|
40
|
-
const handlePlayClick = () => {
|
|
41
|
-
setActiveVideo(videoLink?.link ?? "");
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
const handleCloseVideo = (e: React.MouseEvent) => {
|
|
45
|
-
e.stopPropagation();
|
|
46
|
-
setActiveVideo("");
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const videoHref = videoLink?.link ?? "";
|
|
50
|
-
const videoImage = videoLink?.image;
|
|
51
|
-
const videoPopup = videoLink?.videoPopup ?? false;
|
|
52
|
-
const isPlaying = Boolean(activeVideo && activeVideo === videoHref);
|
|
53
|
-
|
|
54
|
-
const embedSelector = () => {
|
|
55
|
-
if (videoHref.includes("vimeo")) {
|
|
56
|
-
return <VimeoEmbed link={videoHref} autoplay={isPlaying} />;
|
|
57
|
-
} else {
|
|
58
|
-
return <YoutubeEmbed link={videoHref} autoplay={isPlaying} />;
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
const contentVideo = videoLink && videoImage ? embedSelector() : null;
|
|
62
|
-
|
|
63
|
-
return (
|
|
64
|
-
<div className="component-container">
|
|
65
|
-
<div
|
|
66
|
-
className={`image-promo-bar-content ${maxWidth ? "max-w-120 lg:mx-auto" : ""} mx-5 my-16`}
|
|
67
|
-
>
|
|
68
|
-
<div
|
|
69
|
-
className={`flex shrink-0 flex-col items-center gap-8 lg:items-stretch lg:gap-10 xl:gap-[126px] ${mediaPosition ? "lg:flex-row-reverse" : "lg:flex-row"}`}
|
|
70
|
-
>
|
|
71
|
-
<div
|
|
72
|
-
className={`flex flex-[1_0_0] flex-col items-start justify-center gap-8 lg:gap-10 ${color == "dark" ? "text-text" : "text-white"}`}
|
|
73
|
-
>
|
|
74
|
-
<div className="heading holder">
|
|
75
|
-
{brow && (
|
|
76
|
-
<Text
|
|
77
|
-
as="div"
|
|
78
|
-
className="subheading4 mb-4 text-text-brand xl:subheading2 xl:mb-3"
|
|
79
|
-
>
|
|
80
|
-
{brow}
|
|
81
|
-
</Text>
|
|
82
|
-
)}
|
|
83
|
-
{title && (
|
|
84
|
-
<Text
|
|
85
|
-
as={enableHeading ? "h1" : "h2"}
|
|
86
|
-
className="heading2 xl:heading1"
|
|
87
|
-
>
|
|
88
|
-
{title}
|
|
89
|
-
</Text>
|
|
90
|
-
)}
|
|
91
|
-
{subTitle && (
|
|
92
|
-
<Text
|
|
93
|
-
as={enableHeading ? "h2" : "h3"}
|
|
94
|
-
className="subheading3 mt-3 md:subheading1"
|
|
95
|
-
>
|
|
96
|
-
{subTitle}
|
|
97
|
-
</Text>
|
|
98
|
-
)}
|
|
99
|
-
</div>
|
|
100
|
-
{/* Content Section */}
|
|
101
|
-
{description && (
|
|
102
|
-
<Text as="div" className="body1">
|
|
103
|
-
{description}
|
|
104
|
-
</Text>
|
|
105
|
-
)}
|
|
106
|
-
{/* Checklist Rendering */}
|
|
107
|
-
{checklist.length > 0 && (
|
|
108
|
-
<Checklist
|
|
109
|
-
items={checklist}
|
|
110
|
-
iconPosition="top"
|
|
111
|
-
iconSize={24}
|
|
112
|
-
listItemClassName="body1 text-text"
|
|
113
|
-
listContainerClassName="mt-0 space-y-0 flex flex-col gap-3"
|
|
114
|
-
/>
|
|
115
|
-
)}
|
|
116
|
-
{imageLinks.length > 0 && (
|
|
117
|
-
<div className="flex gap-4">
|
|
118
|
-
{/* Image Links Collection */}
|
|
119
|
-
{imageLinks?.map(
|
|
120
|
-
(link: { url: string; image: string }, index: number) => (
|
|
121
|
-
<div key={index} className="image-link w-[147px]">
|
|
122
|
-
<Link
|
|
123
|
-
variant="unstyled"
|
|
124
|
-
href={link.url}
|
|
125
|
-
target="_blank"
|
|
126
|
-
rel="noopener noreferrer"
|
|
127
|
-
>
|
|
128
|
-
<Image src={link.image} alt="icon-link" />
|
|
129
|
-
</Link>
|
|
130
|
-
</div>
|
|
131
|
-
)
|
|
132
|
-
)}
|
|
133
|
-
</div>
|
|
134
|
-
)}
|
|
135
|
-
{/* CTAs and Disclaimers */}
|
|
136
|
-
{(cta || secondaryCta) && (
|
|
137
|
-
<div className="flex w-full flex-col gap-3 xl:flex-row">
|
|
138
|
-
{cta && (
|
|
139
|
-
<div className="primary-cta w-full xl:w-auto xl:shrink-0">
|
|
140
|
-
<Button
|
|
141
|
-
{...cta}
|
|
142
|
-
fullWidth={true}
|
|
143
|
-
size={{ base: "large" }}
|
|
144
|
-
renderCheckPlans={renderCheckPlans}
|
|
145
|
-
onModalButtonClick={onModalButtonClick}
|
|
146
|
-
/>
|
|
147
|
-
</div>
|
|
148
|
-
)}
|
|
149
|
-
{secondaryCta && (
|
|
150
|
-
<div className="secondary-cta w-full xl:w-auto xl:shrink-0">
|
|
151
|
-
<Button
|
|
152
|
-
{...secondaryCta}
|
|
153
|
-
fullWidth={true}
|
|
154
|
-
size={{ base: "large" }}
|
|
155
|
-
renderCheckPlans={renderCheckPlans}
|
|
156
|
-
onModalButtonClick={onModalButtonClick}
|
|
157
|
-
/>
|
|
158
|
-
</div>
|
|
159
|
-
)}
|
|
160
|
-
</div>
|
|
161
|
-
)}
|
|
162
|
-
{ctaDisclaimer && <div>{ctaDisclaimer}</div>}
|
|
163
|
-
{disclaimer && <div>{disclaimer}</div>}
|
|
164
|
-
</div>
|
|
165
|
-
<aside className="flex w-full shrink-0 items-center justify-center lg:w-auto">
|
|
166
|
-
{/* Media Section */}
|
|
167
|
-
{image && (
|
|
168
|
-
<div className="relative h-[334px] w-[334px] overflow-hidden rounded-image md:h-[486px] md:w-[486px]">
|
|
169
|
-
<NextImage
|
|
170
|
-
src={image}
|
|
171
|
-
alt="section-image"
|
|
172
|
-
fill
|
|
173
|
-
sizes="(min-width: 768px) 486px, 334px"
|
|
174
|
-
className="object-cover"
|
|
175
|
-
/>
|
|
176
|
-
</div>
|
|
177
|
-
)}
|
|
178
|
-
{/* Video Link Section */}
|
|
179
|
-
{videoLink?.link && (
|
|
180
|
-
<div
|
|
181
|
-
className={cx(
|
|
182
|
-
"video-section relative w-full cursor-pointer overflow-hidden rounded-image transition-all duration-300 lg:w-[486px]",
|
|
183
|
-
!isPlaying && "hover:shadow-2xl"
|
|
184
|
-
)}
|
|
185
|
-
onClick={handlePlayClick}
|
|
186
|
-
onMouseEnter={() => setIsHovered(true)}
|
|
187
|
-
onMouseLeave={() => setIsHovered(false)}
|
|
188
|
-
>
|
|
189
|
-
{/* Preview Image & Play Button */}
|
|
190
|
-
<div
|
|
191
|
-
className={cx(
|
|
192
|
-
isPlaying && !videoPopup && "hidden",
|
|
193
|
-
isPlaying && !videoPopup ? "opacity-0" : "opacity-100",
|
|
194
|
-
"relative aspect-[16/9] w-full transition-opacity duration-300 xl:aspect-square"
|
|
195
|
-
)}
|
|
196
|
-
>
|
|
197
|
-
{videoLink.image && (
|
|
198
|
-
<NextImage
|
|
199
|
-
src={videoLink.image}
|
|
200
|
-
alt="Video preview"
|
|
201
|
-
width={486}
|
|
202
|
-
height={486}
|
|
203
|
-
className="absolute inset-0 h-full w-full rounded-image object-cover"
|
|
204
|
-
/>
|
|
205
|
-
)}
|
|
206
|
-
<div className="absolute inset-0 flex items-center justify-center">
|
|
207
|
-
<PlayButton isHovered={isHovered} />
|
|
208
|
-
</div>
|
|
209
|
-
</div>
|
|
210
|
-
|
|
211
|
-
{/* Inline Player (if not popup) */}
|
|
212
|
-
{!videoPopup && isPlaying && (
|
|
213
|
-
<div
|
|
214
|
-
className={cx(
|
|
215
|
-
"aspect-[16/9] w-full overflow-hidden rounded-image transition-opacity duration-300",
|
|
216
|
-
isPlaying ? "opacity-100" : "opacity-0"
|
|
217
|
-
)}
|
|
218
|
-
>
|
|
219
|
-
{contentVideo}
|
|
220
|
-
</div>
|
|
221
|
-
)}
|
|
222
|
-
</div>
|
|
223
|
-
)}
|
|
224
|
-
</aside>
|
|
225
|
-
</div>
|
|
226
|
-
</div>
|
|
227
|
-
|
|
228
|
-
{/* Video Popup Overlay */}
|
|
229
|
-
{videoPopup && isPlaying && (
|
|
230
|
-
<div
|
|
231
|
-
className="fixed inset-0 top-20 z-[100] flex items-center justify-center bg-black/80 p-4 transition-all duration-300"
|
|
232
|
-
onClick={handleCloseVideo}
|
|
233
|
-
>
|
|
234
|
-
<div
|
|
235
|
-
className="max-w-6xl aspect-video w-full overflow-hidden rounded-3xl bg-black shadow-2xl md:w-4/6"
|
|
236
|
-
onClick={e => e.stopPropagation()}
|
|
237
|
-
>
|
|
238
|
-
{contentVideo}
|
|
239
|
-
</div>
|
|
240
|
-
</div>
|
|
241
|
-
)}
|
|
242
|
-
</div>
|
|
243
|
-
);
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
export default ImagePromoBar;
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { Button } from "../button";
|
|
3
|
+
import { PlayButton } from "./helper";
|
|
4
|
+
import { ImagePromoBarProps } from "./types";
|
|
5
|
+
import { VimeoEmbed } from "./vimeo-embed";
|
|
6
|
+
import { YoutubeEmbed } from "./youtube-embed";
|
|
7
|
+
|
|
8
|
+
import { Checklist } from "@shared/components/checklist";
|
|
9
|
+
import { Image } from "@shared/components/image";
|
|
10
|
+
import { Link } from "@shared/components/link";
|
|
11
|
+
import { NextImage } from "@shared/components/next-image";
|
|
12
|
+
import { Text } from "@shared/components/text";
|
|
13
|
+
import { cx } from "@shared/utils";
|
|
14
|
+
|
|
15
|
+
export const ImagePromoBar: React.FC<ImagePromoBarProps> = ({
|
|
16
|
+
brow,
|
|
17
|
+
enableHeading,
|
|
18
|
+
title,
|
|
19
|
+
subTitle,
|
|
20
|
+
ctaDisclaimer,
|
|
21
|
+
disclaimer,
|
|
22
|
+
description,
|
|
23
|
+
image,
|
|
24
|
+
imageLinks,
|
|
25
|
+
mediaPosition = true,
|
|
26
|
+
checklist,
|
|
27
|
+
secondaryCta,
|
|
28
|
+
cta,
|
|
29
|
+
videoLink,
|
|
30
|
+
maxWidth = true,
|
|
31
|
+
color = "light",
|
|
32
|
+
imageWidth = 660,
|
|
33
|
+
imageHeight = 660,
|
|
34
|
+
onModalButtonClick,
|
|
35
|
+
renderCheckPlans,
|
|
36
|
+
}) => {
|
|
37
|
+
const [activeVideo, setActiveVideo] = useState("");
|
|
38
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
39
|
+
|
|
40
|
+
const handlePlayClick = () => {
|
|
41
|
+
setActiveVideo(videoLink?.link ?? "");
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const handleCloseVideo = (e: React.MouseEvent) => {
|
|
45
|
+
e.stopPropagation();
|
|
46
|
+
setActiveVideo("");
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const videoHref = videoLink?.link ?? "";
|
|
50
|
+
const videoImage = videoLink?.image;
|
|
51
|
+
const videoPopup = videoLink?.videoPopup ?? false;
|
|
52
|
+
const isPlaying = Boolean(activeVideo && activeVideo === videoHref);
|
|
53
|
+
|
|
54
|
+
const embedSelector = () => {
|
|
55
|
+
if (videoHref.includes("vimeo")) {
|
|
56
|
+
return <VimeoEmbed link={videoHref} autoplay={isPlaying} />;
|
|
57
|
+
} else {
|
|
58
|
+
return <YoutubeEmbed link={videoHref} autoplay={isPlaying} />;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const contentVideo = videoLink && videoImage ? embedSelector() : null;
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<div className="component-container">
|
|
65
|
+
<div
|
|
66
|
+
className={`image-promo-bar-content ${maxWidth ? "max-w-120 lg:mx-auto" : ""} mx-5 my-16`}
|
|
67
|
+
>
|
|
68
|
+
<div
|
|
69
|
+
className={`flex shrink-0 flex-col items-center gap-8 lg:items-stretch lg:gap-10 xl:gap-[126px] ${mediaPosition ? "lg:flex-row-reverse" : "lg:flex-row"}`}
|
|
70
|
+
>
|
|
71
|
+
<div
|
|
72
|
+
className={`flex flex-[1_0_0] flex-col items-start justify-center gap-8 lg:gap-10 ${color == "dark" ? "text-text" : "text-white"}`}
|
|
73
|
+
>
|
|
74
|
+
<div className="heading holder">
|
|
75
|
+
{brow && (
|
|
76
|
+
<Text
|
|
77
|
+
as="div"
|
|
78
|
+
className="subheading4 mb-4 text-text-brand xl:subheading2 xl:mb-3"
|
|
79
|
+
>
|
|
80
|
+
{brow}
|
|
81
|
+
</Text>
|
|
82
|
+
)}
|
|
83
|
+
{title && (
|
|
84
|
+
<Text
|
|
85
|
+
as={enableHeading ? "h1" : "h2"}
|
|
86
|
+
className="heading2 xl:heading1"
|
|
87
|
+
>
|
|
88
|
+
{title}
|
|
89
|
+
</Text>
|
|
90
|
+
)}
|
|
91
|
+
{subTitle && (
|
|
92
|
+
<Text
|
|
93
|
+
as={enableHeading ? "h2" : "h3"}
|
|
94
|
+
className="subheading3 mt-3 md:subheading1"
|
|
95
|
+
>
|
|
96
|
+
{subTitle}
|
|
97
|
+
</Text>
|
|
98
|
+
)}
|
|
99
|
+
</div>
|
|
100
|
+
{/* Content Section */}
|
|
101
|
+
{description && (
|
|
102
|
+
<Text as="div" className="body1">
|
|
103
|
+
{description}
|
|
104
|
+
</Text>
|
|
105
|
+
)}
|
|
106
|
+
{/* Checklist Rendering */}
|
|
107
|
+
{checklist.length > 0 && (
|
|
108
|
+
<Checklist
|
|
109
|
+
items={checklist}
|
|
110
|
+
iconPosition="top"
|
|
111
|
+
iconSize={24}
|
|
112
|
+
listItemClassName="body1 text-text"
|
|
113
|
+
listContainerClassName="mt-0 space-y-0 flex flex-col gap-3"
|
|
114
|
+
/>
|
|
115
|
+
)}
|
|
116
|
+
{imageLinks.length > 0 && (
|
|
117
|
+
<div className="flex gap-4">
|
|
118
|
+
{/* Image Links Collection */}
|
|
119
|
+
{imageLinks?.map(
|
|
120
|
+
(link: { url: string; image: string }, index: number) => (
|
|
121
|
+
<div key={index} className="image-link w-[147px]">
|
|
122
|
+
<Link
|
|
123
|
+
variant="unstyled"
|
|
124
|
+
href={link.url}
|
|
125
|
+
target="_blank"
|
|
126
|
+
rel="noopener noreferrer"
|
|
127
|
+
>
|
|
128
|
+
<Image src={link.image} alt="icon-link" />
|
|
129
|
+
</Link>
|
|
130
|
+
</div>
|
|
131
|
+
)
|
|
132
|
+
)}
|
|
133
|
+
</div>
|
|
134
|
+
)}
|
|
135
|
+
{/* CTAs and Disclaimers */}
|
|
136
|
+
{(cta || secondaryCta) && (
|
|
137
|
+
<div className="flex w-full flex-col gap-3 xl:flex-row">
|
|
138
|
+
{cta && (
|
|
139
|
+
<div className="primary-cta w-full xl:w-auto xl:shrink-0">
|
|
140
|
+
<Button
|
|
141
|
+
{...cta}
|
|
142
|
+
fullWidth={true}
|
|
143
|
+
size={{ base: "large" }}
|
|
144
|
+
renderCheckPlans={renderCheckPlans}
|
|
145
|
+
onModalButtonClick={onModalButtonClick}
|
|
146
|
+
/>
|
|
147
|
+
</div>
|
|
148
|
+
)}
|
|
149
|
+
{secondaryCta && (
|
|
150
|
+
<div className="secondary-cta w-full xl:w-auto xl:shrink-0">
|
|
151
|
+
<Button
|
|
152
|
+
{...secondaryCta}
|
|
153
|
+
fullWidth={true}
|
|
154
|
+
size={{ base: "large" }}
|
|
155
|
+
renderCheckPlans={renderCheckPlans}
|
|
156
|
+
onModalButtonClick={onModalButtonClick}
|
|
157
|
+
/>
|
|
158
|
+
</div>
|
|
159
|
+
)}
|
|
160
|
+
</div>
|
|
161
|
+
)}
|
|
162
|
+
{ctaDisclaimer && <div>{ctaDisclaimer}</div>}
|
|
163
|
+
{disclaimer && <div>{disclaimer}</div>}
|
|
164
|
+
</div>
|
|
165
|
+
<aside className="flex w-full shrink-0 items-center justify-center lg:w-auto">
|
|
166
|
+
{/* Media Section */}
|
|
167
|
+
{image && (
|
|
168
|
+
<div className="relative h-[334px] w-[334px] overflow-hidden rounded-image md:h-[486px] md:w-[486px]">
|
|
169
|
+
<NextImage
|
|
170
|
+
src={image}
|
|
171
|
+
alt="section-image"
|
|
172
|
+
fill
|
|
173
|
+
sizes="(min-width: 768px) 486px, 334px"
|
|
174
|
+
className="object-cover"
|
|
175
|
+
/>
|
|
176
|
+
</div>
|
|
177
|
+
)}
|
|
178
|
+
{/* Video Link Section */}
|
|
179
|
+
{videoLink?.link && (
|
|
180
|
+
<div
|
|
181
|
+
className={cx(
|
|
182
|
+
"video-section relative w-full cursor-pointer overflow-hidden rounded-image transition-all duration-300 lg:w-[486px]",
|
|
183
|
+
!isPlaying && "hover:shadow-2xl"
|
|
184
|
+
)}
|
|
185
|
+
onClick={handlePlayClick}
|
|
186
|
+
onMouseEnter={() => setIsHovered(true)}
|
|
187
|
+
onMouseLeave={() => setIsHovered(false)}
|
|
188
|
+
>
|
|
189
|
+
{/* Preview Image & Play Button */}
|
|
190
|
+
<div
|
|
191
|
+
className={cx(
|
|
192
|
+
isPlaying && !videoPopup && "hidden",
|
|
193
|
+
isPlaying && !videoPopup ? "opacity-0" : "opacity-100",
|
|
194
|
+
"relative aspect-[16/9] w-full transition-opacity duration-300 xl:aspect-square"
|
|
195
|
+
)}
|
|
196
|
+
>
|
|
197
|
+
{videoLink.image && (
|
|
198
|
+
<NextImage
|
|
199
|
+
src={videoLink.image}
|
|
200
|
+
alt="Video preview"
|
|
201
|
+
width={486}
|
|
202
|
+
height={486}
|
|
203
|
+
className="absolute inset-0 h-full w-full rounded-image object-cover"
|
|
204
|
+
/>
|
|
205
|
+
)}
|
|
206
|
+
<div className="absolute inset-0 flex items-center justify-center">
|
|
207
|
+
<PlayButton isHovered={isHovered} />
|
|
208
|
+
</div>
|
|
209
|
+
</div>
|
|
210
|
+
|
|
211
|
+
{/* Inline Player (if not popup) */}
|
|
212
|
+
{!videoPopup && isPlaying && (
|
|
213
|
+
<div
|
|
214
|
+
className={cx(
|
|
215
|
+
"aspect-[16/9] w-full overflow-hidden rounded-image transition-opacity duration-300",
|
|
216
|
+
isPlaying ? "opacity-100" : "opacity-0"
|
|
217
|
+
)}
|
|
218
|
+
>
|
|
219
|
+
{contentVideo}
|
|
220
|
+
</div>
|
|
221
|
+
)}
|
|
222
|
+
</div>
|
|
223
|
+
)}
|
|
224
|
+
</aside>
|
|
225
|
+
</div>
|
|
226
|
+
</div>
|
|
227
|
+
|
|
228
|
+
{/* Video Popup Overlay */}
|
|
229
|
+
{videoPopup && isPlaying && (
|
|
230
|
+
<div
|
|
231
|
+
className="fixed inset-0 top-20 z-[100] flex items-center justify-center bg-black/80 p-4 transition-all duration-300"
|
|
232
|
+
onClick={handleCloseVideo}
|
|
233
|
+
>
|
|
234
|
+
<div
|
|
235
|
+
className="max-w-6xl aspect-video w-full overflow-hidden rounded-3xl bg-black shadow-2xl md:w-4/6"
|
|
236
|
+
onClick={e => e.stopPropagation()}
|
|
237
|
+
>
|
|
238
|
+
{contentVideo}
|
|
239
|
+
</div>
|
|
240
|
+
</div>
|
|
241
|
+
)}
|
|
242
|
+
</div>
|
|
243
|
+
);
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
export default ImagePromoBar;
|