@windstream/react-shared-components 0.2.6 → 0.2.7

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/index.d.ts CHANGED
@@ -170,7 +170,7 @@ interface ListItemProps extends LiHTMLAttributes<HTMLLIElement> {
170
170
 
171
171
  declare const ListItem: React$1.ForwardRefExoticComponent<ListItemProps & React$1.RefAttributes<HTMLLIElement>>;
172
172
 
173
- declare const List: React__default.ForwardRefExoticComponent<ListProps & React__default.RefAttributes<HTMLOListElement | HTMLUListElement>>;
173
+ declare const List: React__default.ForwardRefExoticComponent<ListProps & React__default.RefAttributes<HTMLUListElement | HTMLOListElement>>;
174
174
 
175
175
  declare const iconNameList: readonly ["info", "download", "featured_seasonal_and_gifts", "visibility", "paid", "check_box", "check_box_outline_blank", "radio_button_unchecked", "radio_button_checked", "counter_1", "counter_2", "counter_3", "error", "search", "cancel", "router", "broadcast_on_home", "check", "check_circle", "lock", "shield_lock", "phone_in_talk", "call", "chevron_left", "chevron_right", "keyboard_arrow_down", "keyboard_arrow_up", "arrow_back", "arrow_forward", "help", "home_pin", "location_on", "timer", "schedule", "add", "remove", "bolt", "rocket", "cloud_sync", "close", "groups", "speed", "mail", "credit_card", "language", "forum", "contract", "local_atm", "headset_mic", "sensors", "wifi", "settings", "home", "devices", "build", "thumb_up", "desktop_windows", "block", "all_inclusive", "verified_user", "extension", "stadia_controller", "visibility_off", "close_fullscreen", "progress_activity", "travel_explore", "share", "business_center", "upload", "videocam", "expand_circle_right", "add_circle", "do_not_disturb_on", "expand_circle_up", "expand_circle_down", "replay", "fiber_manual_record", "menu", "dangerous", "star", "play_arrow", "calendar_clock", "shopping_cart"];
176
176
  declare const OpticalSizes: readonly ["20dp", "24dp", "40dp", "48dp"];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windstream/react-shared-components",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "type": "module",
5
5
  "description": "Shared React components for Kinetic applications",
6
6
  "main": "dist/index.js",
@@ -1,277 +1,277 @@
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
- useOriginalImageAspectRatio = false,
35
- isAboveTheFold = false,
36
- onModalButtonClick,
37
- onClick,
38
- renderCheckPlans,
39
- }) => {
40
- const [activeVideo, setActiveVideo] = useState("");
41
- const [isHovered, setIsHovered] = useState(false);
42
-
43
- const handlePlayClick = () => {
44
- setActiveVideo(videoLink?.link ?? "");
45
- };
46
-
47
- const handleCloseVideo = (e: React.MouseEvent) => {
48
- e.stopPropagation();
49
- setActiveVideo("");
50
- };
51
-
52
- const videoHref = videoLink?.link ?? "";
53
- const videoImage = videoLink?.image;
54
- const videoPopup = videoLink?.videoPopup ?? false;
55
- const isPlaying = Boolean(activeVideo && activeVideo === videoHref);
56
-
57
- const embedSelector = () => {
58
- if (videoHref.includes("vimeo")) {
59
- return <VimeoEmbed link={videoHref} autoplay={isPlaying} />;
60
- } else {
61
- return <YoutubeEmbed link={videoHref} autoplay={isPlaying} />;
62
- }
63
- };
64
- const contentVideo = videoLink && videoImage ? embedSelector() : null;
65
-
66
- return (
67
- <div className="component-container shared-component-ipb pb-16 pt-16">
68
- <div
69
- className={`image-promo-bar-content ${maxWidth ? "max-w-120 xl:mx-auto" : ""} px-5 pb-8 pt-8 md:px-10`}
70
- >
71
- <div
72
- className={`flex shrink-0 flex-col items-center gap-8 xl:items-stretch xl:gap-10 xl:gap-[126px] ${mediaPosition ? "xl:flex-row-reverse" : "xl:flex-row"}`}
73
- >
74
- <div
75
- className={`flex flex-[1_0_0] flex-col items-start justify-center gap-8 xl:gap-10 ${color == "dark" ? "text-text" : "text-white"}`}
76
- >
77
- <div className="heading holder">
78
- {brow && (
79
- <Text
80
- as="div"
81
- className="subheading4 mb-4 text-text-brand xl:subheading2 xl:mb-3"
82
- >
83
- {brow}
84
- </Text>
85
- )}
86
- {title && (
87
- <Text
88
- as={enableHeading ? "h1" : "h2"}
89
- className="heading2 xl:heading1"
90
- >
91
- {title}
92
- </Text>
93
- )}
94
- {subTitle && (
95
- <Text
96
- as={enableHeading ? "h2" : "h3"}
97
- className="subheading3 mt-3 md:subheading1"
98
- >
99
- {subTitle}
100
- </Text>
101
- )}
102
- </div>
103
- {/* Content Section */}
104
- {description && (
105
- <Text as="div" className="body1">
106
- {description}
107
- </Text>
108
- )}
109
- {/* Checklist Rendering */}
110
- {checklist.length > 0 && (
111
- <Checklist
112
- items={checklist}
113
- iconPosition="top"
114
- iconSize={24}
115
- listItemClassName="body1 text-text"
116
- listContainerClassName="mt-0 space-y-0 flex flex-col gap-3"
117
- />
118
- )}
119
- {ctaDisclaimer && <div>{ctaDisclaimer}</div>}
120
- {imageLinks.length > 0 && (
121
- <div className="flex gap-4">
122
- {/* Image Links Collection */}
123
- {imageLinks?.map(
124
- (link: { url: string; image: string }, index: number) => (
125
- <div key={index} className="image-link w-[147px]">
126
- <Link
127
- variant="unstyled"
128
- href={link.url}
129
- target="_blank"
130
- rel="noopener noreferrer"
131
- >
132
- <Image src={link.image} alt="icon-link" />
133
- </Link>
134
- </div>
135
- )
136
- )}
137
- </div>
138
- )}
139
- {/* CTAs and Disclaimers */}
140
- {(cta || secondaryCta) && (
141
- <div className="flex w-full flex-col gap-3 xl:flex-row">
142
- {cta && (
143
- <div className="primary-cta w-full xl:w-auto xl:shrink-0">
144
- <Button
145
- {...cta}
146
- fullWidth={true}
147
- size={{ base: "large" }}
148
- renderCheckPlans={renderCheckPlans}
149
- onModalButtonClick={onModalButtonClick}
150
- onClick={(e: React.MouseEvent) => onClick?.(e, "primary")}
151
- />
152
- </div>
153
- )}
154
- {secondaryCta && (
155
- <div className="secondary-cta w-full xl:w-auto xl:shrink-0">
156
- <Button
157
- {...secondaryCta}
158
- fullWidth={true}
159
- size={{ base: "large" }}
160
- renderCheckPlans={renderCheckPlans}
161
- onModalButtonClick={onModalButtonClick}
162
- onClick={(e: React.MouseEvent) =>
163
- onClick?.(e, "secondary")
164
- }
165
- />
166
- </div>
167
- )}
168
- </div>
169
- )}
170
- </div>
171
- <aside className="flex w-full flex-1 shrink-0 items-center justify-center lg:w-auto">
172
- {/* Media Section */}
173
- {image && (
174
- <div
175
- className={cx(
176
- !useOriginalImageAspectRatio
177
- ? "relative aspect-[16/9] w-full overflow-hidden rounded-image lg:h-[486px] xl:aspect-square xl:max-h-[486px] xl:w-[486px]"
178
- : "overflow-hidden rounded-image"
179
- )}
180
- >
181
- <NextImage
182
- src={image}
183
- alt="section-image"
184
- priority={isAboveTheFold}
185
- fill={!useOriginalImageAspectRatio}
186
- width={
187
- !useOriginalImageAspectRatio ? undefined : imageWidth || 660
188
- }
189
- height={
190
- !useOriginalImageAspectRatio
191
- ? undefined
192
- : imageHeight || 660
193
- }
194
- sizes="(max-width: 430px) 100vw, (max-width: 834px) 100vw, 50vw"
195
- className={cx(
196
- !useOriginalImageAspectRatio ? "object-cover" : "w-full"
197
- )}
198
- />
199
- </div>
200
- )}
201
- {/* Video Link Section */}
202
- {videoLink?.link && (
203
- <div
204
- className={cx(
205
- "video-section relative w-full cursor-pointer rounded-image transition-all duration-300 lg:w-[486px]",
206
- !isPlaying && "hover:ring-2 hover:ring-border-focus"
207
- )}
208
- onClick={handlePlayClick}
209
- onMouseEnter={() => setIsHovered(true)}
210
- onMouseLeave={() => setIsHovered(false)}
211
- >
212
- {/* Preview Image & Play Button */}
213
- <div
214
- className={cx(
215
- isPlaying && !videoPopup && "hidden",
216
- isPlaying && !videoPopup ? "opacity-0" : "opacity-100",
217
- "relative w-full transition-opacity duration-300"
218
- )}
219
- >
220
- {videoLink.image && (
221
- <NextImage
222
- src={videoLink.image}
223
- alt="Video preview"
224
- width={0}
225
- height={0}
226
- sizes="(max-width: 430px) 100vw, (max-width: 834px) 100vw, 50vw"
227
- className="h-auto w-full rounded-image"
228
- />
229
- )}
230
- <div className="absolute inset-0 flex items-center justify-center">
231
- <PlayButton isHovered={isHovered} />
232
- </div>
233
- </div>
234
-
235
- {/* Inline Player (if not popup) */}
236
- {!videoPopup && isPlaying && (
237
- <div
238
- className={cx(
239
- "aspect-[16/9] w-full overflow-hidden rounded-image transition-opacity duration-300",
240
- isPlaying ? "opacity-100" : "opacity-0",
241
- !useOriginalImageAspectRatio &&
242
- "xl:aspect-square xl:max-h-[486px] xl:w-[486px]"
243
- )}
244
- >
245
- {contentVideo}
246
- </div>
247
- )}
248
- </div>
249
- )}
250
- </aside>
251
- </div>
252
- </div>
253
-
254
- {/* Video Popup Overlay */}
255
- {videoPopup && isPlaying && (
256
- <div
257
- className="fixed inset-0 top-20 z-[100] flex items-center justify-center bg-black/80 p-4 transition-all duration-300"
258
- onClick={handleCloseVideo}
259
- >
260
- <div
261
- className="max-w-6xl aspect-video w-full overflow-hidden rounded-3xl bg-black shadow-2xl md:w-4/6"
262
- onClick={e => e.stopPropagation()}
263
- >
264
- {contentVideo}
265
- </div>
266
- </div>
267
- )}
268
- {disclaimer && (
269
- <div className="mt-10 flex justify-center xl:mt-18">
270
- <div>{disclaimer}</div>
271
- </div>
272
- )}
273
- </div>
274
- );
275
- };
276
-
277
- 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
+ useOriginalImageAspectRatio = false,
35
+ isAboveTheFold = false,
36
+ onModalButtonClick,
37
+ onClick,
38
+ renderCheckPlans,
39
+ }) => {
40
+ const [activeVideo, setActiveVideo] = useState("");
41
+ const [isHovered, setIsHovered] = useState(false);
42
+
43
+ const handlePlayClick = () => {
44
+ setActiveVideo(videoLink?.link ?? "");
45
+ };
46
+
47
+ const handleCloseVideo = (e: React.MouseEvent) => {
48
+ e.stopPropagation();
49
+ setActiveVideo("");
50
+ };
51
+
52
+ const videoHref = videoLink?.link ?? "";
53
+ const videoImage = videoLink?.image;
54
+ const videoPopup = videoLink?.videoPopup ?? false;
55
+ const isPlaying = Boolean(activeVideo && activeVideo === videoHref);
56
+
57
+ const embedSelector = () => {
58
+ if (videoHref.includes("vimeo")) {
59
+ return <VimeoEmbed link={videoHref} autoplay={isPlaying} />;
60
+ } else {
61
+ return <YoutubeEmbed link={videoHref} autoplay={isPlaying} />;
62
+ }
63
+ };
64
+ const contentVideo = videoLink && videoImage ? embedSelector() : null;
65
+
66
+ return (
67
+ <div className="component-container shared-component-ipb pb-16 pt-16">
68
+ <div
69
+ className={`image-promo-bar-content ${maxWidth ? "max-w-120 xl:mx-auto" : ""} px-5 pb-8 pt-8 md:px-10`}
70
+ >
71
+ <div
72
+ className={`flex shrink-0 flex-col items-center gap-8 xl:items-stretch xl:gap-10 xl:gap-[126px] ${mediaPosition ? "xl:flex-row-reverse" : "xl:flex-row"}`}
73
+ >
74
+ <div
75
+ className={`flex flex-[1_0_0] flex-col items-start justify-center gap-8 xl:gap-10 ${color == "dark" ? "text-text" : "text-white"}`}
76
+ >
77
+ <div className="heading holder">
78
+ {brow && (
79
+ <Text
80
+ as="div"
81
+ className="subheading4 mb-4 text-text-brand xl:subheading2 xl:mb-3"
82
+ >
83
+ {brow}
84
+ </Text>
85
+ )}
86
+ {title && (
87
+ <Text
88
+ as={enableHeading ? "h1" : "h2"}
89
+ className="heading2 xl:heading1"
90
+ >
91
+ {title}
92
+ </Text>
93
+ )}
94
+ {subTitle && (
95
+ <Text
96
+ as={enableHeading ? "h2" : "h3"}
97
+ className="subheading3 mt-3 md:subheading1"
98
+ >
99
+ {subTitle}
100
+ </Text>
101
+ )}
102
+ </div>
103
+ {/* Content Section */}
104
+ {description && (
105
+ <Text as="div" className="body1">
106
+ {description}
107
+ </Text>
108
+ )}
109
+ {/* Checklist Rendering */}
110
+ {checklist.length > 0 && (
111
+ <Checklist
112
+ items={checklist}
113
+ iconPosition="top"
114
+ iconSize={24}
115
+ listItemClassName="body1 text-text"
116
+ listContainerClassName="mt-0 space-y-0 flex flex-col gap-3"
117
+ />
118
+ )}
119
+ {ctaDisclaimer && <div>{ctaDisclaimer}</div>}
120
+ {imageLinks.length > 0 && (
121
+ <div className="flex gap-4">
122
+ {/* Image Links Collection */}
123
+ {imageLinks?.map(
124
+ (link: { url: string; image: string }, index: number) => (
125
+ <div key={index} className="image-link w-[147px]">
126
+ <Link
127
+ variant="unstyled"
128
+ href={link.url}
129
+ target="_blank"
130
+ rel="noopener noreferrer"
131
+ >
132
+ <Image src={link.image} alt="icon-link" />
133
+ </Link>
134
+ </div>
135
+ )
136
+ )}
137
+ </div>
138
+ )}
139
+ {/* CTAs and Disclaimers */}
140
+ {(cta || secondaryCta) && (
141
+ <div className="flex w-full flex-col gap-3 xl:flex-row">
142
+ {cta && (
143
+ <div className="primary-cta w-full xl:w-auto xl:shrink-0">
144
+ <Button
145
+ {...cta}
146
+ fullWidth={true}
147
+ size={{ base: "large" }}
148
+ renderCheckPlans={renderCheckPlans}
149
+ onModalButtonClick={onModalButtonClick}
150
+ onClick={(e: React.MouseEvent) => onClick?.(e, "primary")}
151
+ />
152
+ </div>
153
+ )}
154
+ {secondaryCta && (
155
+ <div className="secondary-cta w-full xl:w-auto xl:shrink-0">
156
+ <Button
157
+ {...secondaryCta}
158
+ fullWidth={true}
159
+ size={{ base: "large" }}
160
+ renderCheckPlans={renderCheckPlans}
161
+ onModalButtonClick={onModalButtonClick}
162
+ onClick={(e: React.MouseEvent) =>
163
+ onClick?.(e, "secondary")
164
+ }
165
+ />
166
+ </div>
167
+ )}
168
+ </div>
169
+ )}
170
+ </div>
171
+ <aside className="flex w-full flex-1 shrink-0 items-center justify-center lg:w-auto">
172
+ {/* Media Section */}
173
+ {image && (
174
+ <div
175
+ className={cx(
176
+ !useOriginalImageAspectRatio
177
+ ? "relative aspect-[16/9] w-full overflow-hidden rounded-image lg:h-[486px] xl:aspect-square xl:max-h-[486px] xl:w-[486px]"
178
+ : "overflow-hidden rounded-image"
179
+ )}
180
+ >
181
+ <NextImage
182
+ src={image}
183
+ alt="section-image"
184
+ priority={isAboveTheFold}
185
+ fill={!useOriginalImageAspectRatio}
186
+ width={
187
+ !useOriginalImageAspectRatio ? undefined : imageWidth || 660
188
+ }
189
+ height={
190
+ !useOriginalImageAspectRatio
191
+ ? undefined
192
+ : imageHeight || 660
193
+ }
194
+ sizes="(max-width: 430px) 100vw, (max-width: 834px) 100vw, 50vw"
195
+ className={cx(
196
+ !useOriginalImageAspectRatio ? "object-cover" : "w-full"
197
+ )}
198
+ />
199
+ </div>
200
+ )}
201
+ {/* Video Link Section */}
202
+ {videoLink?.link && (
203
+ <div
204
+ className={cx(
205
+ "video-section relative w-full cursor-pointer rounded-image transition-all duration-300 lg:w-[486px]",
206
+ !isPlaying && "hover:ring-2 hover:ring-border-focus"
207
+ )}
208
+ onClick={handlePlayClick}
209
+ onMouseEnter={() => setIsHovered(true)}
210
+ onMouseLeave={() => setIsHovered(false)}
211
+ >
212
+ {/* Preview Image & Play Button */}
213
+ <div
214
+ className={cx(
215
+ isPlaying && !videoPopup && "hidden",
216
+ isPlaying && !videoPopup ? "opacity-0" : "opacity-100",
217
+ "relative w-full transition-opacity duration-300"
218
+ )}
219
+ >
220
+ {videoLink.image && (
221
+ <NextImage
222
+ src={videoLink.image}
223
+ alt="Video preview"
224
+ width={imageWidth || 660}
225
+ height={imageHeight || 660}
226
+ sizes="(max-width: 430px) 100vw, (max-width: 834px) 100vw, 50vw"
227
+ className="h-auto w-full rounded-image"
228
+ />
229
+ )}
230
+ <div className="absolute inset-0 flex items-center justify-center">
231
+ <PlayButton isHovered={isHovered} />
232
+ </div>
233
+ </div>
234
+
235
+ {/* Inline Player (if not popup) */}
236
+ {!videoPopup && isPlaying && (
237
+ <div
238
+ className={cx(
239
+ "aspect-[16/9] w-full overflow-hidden rounded-image transition-opacity duration-300",
240
+ isPlaying ? "opacity-100" : "opacity-0",
241
+ !useOriginalImageAspectRatio &&
242
+ "xl:aspect-square xl:max-h-[486px] xl:w-[486px]"
243
+ )}
244
+ >
245
+ {contentVideo}
246
+ </div>
247
+ )}
248
+ </div>
249
+ )}
250
+ </aside>
251
+ </div>
252
+ </div>
253
+
254
+ {/* Video Popup Overlay */}
255
+ {videoPopup && isPlaying && (
256
+ <div
257
+ className="fixed inset-0 top-20 z-[100] flex items-center justify-center bg-black/80 p-4 transition-all duration-300"
258
+ onClick={handleCloseVideo}
259
+ >
260
+ <div
261
+ className="max-w-6xl aspect-video w-full overflow-hidden rounded-3xl bg-black shadow-2xl md:w-4/6"
262
+ onClick={e => e.stopPropagation()}
263
+ >
264
+ {contentVideo}
265
+ </div>
266
+ </div>
267
+ )}
268
+ {disclaimer && (
269
+ <div className="mt-10 flex justify-center xl:mt-18">
270
+ <div>{disclaimer}</div>
271
+ </div>
272
+ )}
273
+ </div>
274
+ );
275
+ };
276
+
277
+ export default ImagePromoBar;