@windstream/react-shared-components 0.1.38 → 0.1.41

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