@windstream/react-shared-components 0.1.77 → 0.1.78

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.
Files changed (201) hide show
  1. package/README.md +635 -635
  2. package/dist/contentful/index.d.ts +5 -1
  3. package/dist/contentful/index.esm.js +3 -3
  4. package/dist/contentful/index.esm.js.map +1 -1
  5. package/dist/contentful/index.js +2 -2
  6. package/dist/contentful/index.js.map +1 -1
  7. package/dist/core.d.ts +1 -1
  8. package/dist/index.d.ts +1 -1
  9. package/dist/index.esm.js.map +1 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/next/index.esm.js.map +1 -1
  12. package/dist/next/index.js.map +1 -1
  13. package/dist/styles.css +1 -1
  14. package/dist/utils/index.esm.js.map +1 -1
  15. package/dist/utils/index.js.map +1 -1
  16. package/package.json +185 -185
  17. package/src/components/accordion/Accordion.stories.tsx +230 -230
  18. package/src/components/accordion/index.tsx +70 -70
  19. package/src/components/accordion/types.ts +12 -12
  20. package/src/components/alert-card/AlertCard.stories.tsx +171 -171
  21. package/src/components/alert-card/index.tsx +41 -41
  22. package/src/components/alert-card/types.ts +13 -13
  23. package/src/components/brand-button/BrandButton.stories.tsx +223 -223
  24. package/src/components/brand-button/helpers.ts +35 -35
  25. package/src/components/brand-button/index.tsx +120 -120
  26. package/src/components/brand-button/types.ts +38 -38
  27. package/src/components/button/Button.stories.tsx +108 -108
  28. package/src/components/button/index.tsx +27 -27
  29. package/src/components/button/types.ts +14 -14
  30. package/src/components/call-button/CallButton.stories.tsx +324 -324
  31. package/src/components/call-button/index.tsx +106 -106
  32. package/src/components/call-button/types.ts +16 -16
  33. package/src/components/checkbox/Checkbox.stories.tsx +247 -247
  34. package/src/components/checkbox/index.tsx +197 -197
  35. package/src/components/checkbox/types.ts +27 -27
  36. package/src/components/checklist/Checklist.stories.tsx +150 -150
  37. package/src/components/checklist/index.tsx +61 -61
  38. package/src/components/checklist/types.ts +17 -17
  39. package/src/components/collapse/Collapse.stories.tsx +255 -255
  40. package/src/components/collapse/index.tsx +46 -46
  41. package/src/components/collapse/types.ts +6 -6
  42. package/src/components/divider/Divider.stories.tsx +205 -205
  43. package/src/components/divider/index.tsx +22 -22
  44. package/src/components/divider/type.ts +3 -3
  45. package/src/components/image/Image.stories.tsx +113 -113
  46. package/src/components/image/index.tsx +25 -25
  47. package/src/components/image/types.ts +40 -40
  48. package/src/components/input/Input.stories.tsx +325 -325
  49. package/src/components/input/index.tsx +177 -177
  50. package/src/components/input/types.ts +37 -37
  51. package/src/components/link/Link.stories.tsx +163 -163
  52. package/src/components/link/index.tsx +116 -116
  53. package/src/components/link/types.ts +25 -25
  54. package/src/components/list/List.stories.tsx +272 -272
  55. package/src/components/list/index.tsx +88 -88
  56. package/src/components/list/list-item/index.tsx +38 -38
  57. package/src/components/list/list-item/types.ts +13 -13
  58. package/src/components/list/types.ts +29 -29
  59. package/src/components/material-icon/MaterialIcon.stories.tsx +322 -322
  60. package/src/components/material-icon/constants.ts +99 -99
  61. package/src/components/material-icon/index.tsx +47 -47
  62. package/src/components/material-icon/types.ts +31 -31
  63. package/src/components/modal/Modal.stories.tsx +171 -171
  64. package/src/components/modal/index.tsx +164 -164
  65. package/src/components/modal/types.ts +24 -24
  66. package/src/components/next-image/index.tsx +74 -74
  67. package/src/components/next-image/types.ts +1 -1
  68. package/src/components/pagination/index.tsx +91 -91
  69. package/src/components/pagination/types.ts +6 -6
  70. package/src/components/radio-button/RadioButton.stories.tsx +307 -307
  71. package/src/components/radio-button/index.tsx +75 -75
  72. package/src/components/radio-button/types.ts +21 -21
  73. package/src/components/see-more/SeeMore.stories.tsx +181 -181
  74. package/src/components/see-more/index.tsx +44 -44
  75. package/src/components/see-more/types.ts +4 -4
  76. package/src/components/select/Select.stories.tsx +411 -411
  77. package/src/components/select/index.tsx +155 -155
  78. package/src/components/select/types.ts +36 -36
  79. package/src/components/select-plan-button/SelectPlanButton.stories.tsx +184 -184
  80. package/src/components/select-plan-button/index.tsx +63 -63
  81. package/src/components/select-plan-button/types.ts +17 -17
  82. package/src/components/skeleton/Skeleton.stories.tsx +179 -179
  83. package/src/components/skeleton/index.tsx +61 -61
  84. package/src/components/skeleton/types.ts +4 -4
  85. package/src/components/spinner/Spinner.stories.tsx +335 -335
  86. package/src/components/spinner/index.tsx +44 -44
  87. package/src/components/spinner/types.ts +5 -5
  88. package/src/components/text/Text.stories.tsx +321 -321
  89. package/src/components/text/index.tsx +25 -25
  90. package/src/components/text/types.ts +45 -45
  91. package/src/components/tooltip/Tooltip.stories.tsx +219 -219
  92. package/src/components/tooltip/index.tsx +74 -74
  93. package/src/components/tooltip/types.ts +7 -7
  94. package/src/components/view-cart-button/ViewCartButton.stories.tsx +252 -252
  95. package/src/components/view-cart-button/index.tsx +42 -42
  96. package/src/components/view-cart-button/types.ts +5 -5
  97. package/src/contentful/blocks/accordion/Accordion.stories.mocks.tsx +128 -128
  98. package/src/contentful/blocks/accordion/Accordion.stories.tsx +98 -98
  99. package/src/contentful/blocks/accordion/index.tsx +112 -112
  100. package/src/contentful/blocks/accordion/types.ts +34 -34
  101. package/src/contentful/blocks/address-input-banner/index.tsx +52 -52
  102. package/src/contentful/blocks/address-input-banner/types.ts +14 -14
  103. package/src/contentful/blocks/anchored-bottom-banner/index.tsx +181 -181
  104. package/src/contentful/blocks/anchored-bottom-banner/types.ts +13 -13
  105. package/src/contentful/blocks/blogs-grid/index.tsx +134 -134
  106. package/src/contentful/blocks/blogs-grid/types.ts +26 -26
  107. package/src/contentful/blocks/blogs-grid-base/index.tsx +119 -119
  108. package/src/contentful/blocks/blogs-grid-base/types.ts +36 -36
  109. package/src/contentful/blocks/breadcrumbs/index.tsx +81 -81
  110. package/src/contentful/blocks/breadcrumbs/types.ts +6 -6
  111. package/src/contentful/blocks/button/Button.stories.tsx +40 -40
  112. package/src/contentful/blocks/button/index.tsx +131 -131
  113. package/src/contentful/blocks/button/types.ts +39 -39
  114. package/src/contentful/blocks/callout/Callout.stories.tsx +23 -23
  115. package/src/contentful/blocks/callout/index.tsx +265 -252
  116. package/src/contentful/blocks/callout/types.ts +72 -68
  117. package/src/contentful/blocks/cards/Cards.stories.tsx +23 -23
  118. package/src/contentful/blocks/cards/blog-card/index.tsx +129 -129
  119. package/src/contentful/blocks/cards/blog-card/types.ts +34 -34
  120. package/src/contentful/blocks/cards/floating-image-card/index.tsx +119 -119
  121. package/src/contentful/blocks/cards/floating-image-card/types.ts +30 -30
  122. package/src/contentful/blocks/cards/full-image-card/index.tsx +130 -130
  123. package/src/contentful/blocks/cards/full-image-card/types.ts +29 -29
  124. package/src/contentful/blocks/cards/index.tsx +13 -13
  125. package/src/contentful/blocks/cards/product-card/index.tsx +251 -251
  126. package/src/contentful/blocks/cards/product-card/types.ts +28 -28
  127. package/src/contentful/blocks/cards/simple-card/index.tsx +325 -325
  128. package/src/contentful/blocks/cards/simple-card/types.ts +71 -71
  129. package/src/contentful/blocks/cards/testimonial-card/index.tsx +90 -90
  130. package/src/contentful/blocks/cards/testimonial-card/types.tsx +12 -12
  131. package/src/contentful/blocks/cards/types.ts +1 -1
  132. package/src/contentful/blocks/carousel/Carousel.stories.tsx +23 -23
  133. package/src/contentful/blocks/carousel/helper.tsx +440 -440
  134. package/src/contentful/blocks/carousel/index.tsx +85 -85
  135. package/src/contentful/blocks/carousel/types.ts +144 -144
  136. package/src/contentful/blocks/cart-retention-banner/index.tsx +105 -105
  137. package/src/contentful/blocks/cart-retention-banner/types.ts +11 -11
  138. package/src/contentful/blocks/comparison-table/index.tsx +29 -29
  139. package/src/contentful/blocks/comparison-table/types.ts +6 -6
  140. package/src/contentful/blocks/cookiebanner/index.tsx +146 -146
  141. package/src/contentful/blocks/cookiebanner/type.ts +7 -7
  142. package/src/contentful/blocks/cta-callout/CtaCallout.stories.tsx +46 -46
  143. package/src/contentful/blocks/cta-callout/index.tsx +71 -71
  144. package/src/contentful/blocks/cta-callout/types.ts +26 -26
  145. package/src/contentful/blocks/dynamic-tabs/index.tsx +204 -204
  146. package/src/contentful/blocks/dynamic-tabs/types.ts +21 -21
  147. package/src/contentful/blocks/email-input-block/index.tsx +116 -116
  148. package/src/contentful/blocks/email-input-block/types.ts +16 -16
  149. package/src/contentful/blocks/find-kinetic/FindKinetic.stories.tsx +23 -23
  150. package/src/contentful/blocks/find-kinetic/index.tsx +130 -130
  151. package/src/contentful/blocks/find-kinetic/types.ts +19 -19
  152. package/src/contentful/blocks/floating-banner/FloatingBanner.stories.tsx +34 -34
  153. package/src/contentful/blocks/floating-banner/index.tsx +97 -97
  154. package/src/contentful/blocks/floating-banner/types.ts +22 -22
  155. package/src/contentful/blocks/footer/Footer.stories.tsx +317 -317
  156. package/src/contentful/blocks/footer/index.tsx +91 -91
  157. package/src/contentful/blocks/footer/types.ts +13 -13
  158. package/src/contentful/blocks/image-promo-bar/ImagePromoBar.stories.tsx +23 -23
  159. package/src/contentful/blocks/image-promo-bar/helper.tsx +28 -28
  160. package/src/contentful/blocks/image-promo-bar/index.tsx +246 -246
  161. package/src/contentful/blocks/image-promo-bar/types.ts +44 -44
  162. package/src/contentful/blocks/image-promo-bar/vimeo-embed.tsx +93 -93
  163. package/src/contentful/blocks/image-promo-bar/youtube-embed.tsx +46 -46
  164. package/src/contentful/blocks/modal/constants.ts +53 -53
  165. package/src/contentful/blocks/modal/index.tsx +107 -107
  166. package/src/contentful/blocks/modal/types.ts +12 -12
  167. package/src/contentful/blocks/navigation/desktop-link-groups.tsx/index.tsx +139 -139
  168. package/src/contentful/blocks/navigation/index.tsx +568 -567
  169. package/src/contentful/blocks/navigation/mobile-link-groups.tsx/index.tsx +82 -82
  170. package/src/contentful/blocks/navigation/types.ts +71 -71
  171. package/src/contentful/blocks/primary-hero/PrimaryHero.stories.tsx +23 -23
  172. package/src/contentful/blocks/primary-hero/index.tsx +236 -236
  173. package/src/contentful/blocks/primary-hero/types.ts +37 -37
  174. package/src/contentful/blocks/search-block/index.tsx +90 -90
  175. package/src/contentful/blocks/search-block/types.ts +15 -15
  176. package/src/contentful/blocks/shape-background-wrapper/ShapeBackgroundWrapper.stories.tsx +26 -26
  177. package/src/contentful/blocks/shape-background-wrapper/index.tsx +124 -124
  178. package/src/contentful/blocks/shape-background-wrapper/types.ts +36 -36
  179. package/src/contentful/blocks/text/Text.stories.tsx +23 -23
  180. package/src/contentful/blocks/text/index.tsx +12 -12
  181. package/src/contentful/blocks/text/types.ts +1 -1
  182. package/src/contentful/index.ts +105 -105
  183. package/src/hooks/contentful/use-contentful-rich-text.tsx +309 -309
  184. package/src/hooks/contentful/use-processed-check-list.ts +63 -63
  185. package/src/hooks/use-body-scroll-lock.ts +34 -34
  186. package/src/hooks/use-carousel-swipe.ts +264 -264
  187. package/src/hooks/use-outside-click.ts +17 -17
  188. package/src/index.ts +101 -101
  189. package/src/next/index.ts +5 -5
  190. package/src/setupTests.ts +46 -46
  191. package/src/stories/DocsTemplate.tsx +24 -24
  192. package/src/styles/globals.css +343 -343
  193. package/src/types/global.d.ts +9 -9
  194. package/src/types/micro-components.ts +99 -99
  195. package/src/types/utm.ts +49 -49
  196. package/src/utils/contentful/to-document.ts +24 -24
  197. package/src/utils/cookie.ts +84 -84
  198. package/src/utils/cx.ts +49 -49
  199. package/src/utils/index.ts +41 -41
  200. package/src/utils/speed-card-bg.ts +24 -24
  201. package/src/utils/utm.ts +221 -221
@@ -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;
@@ -1,44 +1,44 @@
1
- import React from "react";
2
-
3
- import { CheckPlansProps } from "@shared/types/micro-components";
4
-
5
- export type VideoLinkProps = {
6
- image?: string;
7
- videoPopup?: boolean;
8
- link?: string;
9
- };
10
-
11
- export type VideoEmbedProps = {
12
- containerClassName?: string;
13
- autoplay?: boolean;
14
- debug?: boolean;
15
- } & VideoLinkProps;
16
-
17
- export type ImagePromoBarProps = {
18
- brow: string;
19
- enableHeading: boolean;
20
- title: string;
21
- subTitle: string;
22
- image: string;
23
- imageWidth: number;
24
- imageHeight: number;
25
- mediaPosition: boolean;
26
- description: React.ReactNode;
27
- openDescriptionLinksOnANewTab: boolean;
28
- checklist: string[];
29
- disclaimer: React.ReactNode;
30
- imageLinks: { url: string; image: string }[];
31
- cta: any;
32
- secondaryCta: any;
33
- ctaDisclaimer: React.ReactNode;
34
- videoLink: VideoLinkProps;
35
- maxWidth?: boolean;
36
- color: "light" | "dark";
37
- onModalButtonClick?: (id?: string) => void;
38
- renderCheckPlans?: (overrides?: CheckPlansProps) => React.ReactNode;
39
- };
40
-
41
- export type PlayButtonProps = {
42
- isHovered?: boolean;
43
- containerClassName?: string;
44
- };
1
+ import React from "react";
2
+
3
+ import { CheckPlansProps } from "@shared/types/micro-components";
4
+
5
+ export type VideoLinkProps = {
6
+ image?: string;
7
+ videoPopup?: boolean;
8
+ link?: string;
9
+ };
10
+
11
+ export type VideoEmbedProps = {
12
+ containerClassName?: string;
13
+ autoplay?: boolean;
14
+ debug?: boolean;
15
+ } & VideoLinkProps;
16
+
17
+ export type ImagePromoBarProps = {
18
+ brow: string;
19
+ enableHeading: boolean;
20
+ title: string;
21
+ subTitle: string;
22
+ image: string;
23
+ imageWidth: number;
24
+ imageHeight: number;
25
+ mediaPosition: boolean;
26
+ description: React.ReactNode;
27
+ openDescriptionLinksOnANewTab: boolean;
28
+ checklist: string[];
29
+ disclaimer: React.ReactNode;
30
+ imageLinks: { url: string; image: string }[];
31
+ cta: any;
32
+ secondaryCta: any;
33
+ ctaDisclaimer: React.ReactNode;
34
+ videoLink: VideoLinkProps;
35
+ maxWidth?: boolean;
36
+ color: "light" | "dark";
37
+ onModalButtonClick?: (id?: string) => void;
38
+ renderCheckPlans?: (overrides?: CheckPlansProps) => React.ReactNode;
39
+ };
40
+
41
+ export type PlayButtonProps = {
42
+ isHovered?: boolean;
43
+ containerClassName?: string;
44
+ };