@windstream/react-shared-components 0.0.51 → 0.0.53

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windstream/react-shared-components",
3
- "version": "0.0.51",
3
+ "version": "0.0.53",
4
4
  "type": "module",
5
5
  "description": "Shared React components for Kinetic applications",
6
6
  "main": "dist/index.js",
@@ -1,39 +1,52 @@
1
- import React from "react";
2
-
3
- import { ChecklistProps } from "@shared/components/checklist/types";
4
- import { List, ListItem } from "@shared/components/list";
5
- import { MaterialIcon } from "@shared/components/material-icon";
6
- import { Text } from "@shared/components/text";
7
- import { cx } from "@shared/utils";
8
-
9
- export const Checklist: React.FC<ChecklistProps> = props => {
10
- const { items, listIconName = "check", listItemClassName } = props;
11
-
12
- if (!items?.length) return null;
13
-
14
- return (
15
- <List className="mt-2 space-y-1">
16
- {items.map((text, idx) => (
17
- <ListItem
18
- key={idx}
19
- className={cx(
20
- "flex items-center gap-2 text-text-secondary",
21
- listItemClassName
22
- )}
23
- >
24
- <MaterialIcon
25
- name={listIconName}
26
- size={20}
27
- weight="600"
28
- className="text-icon-brand"
29
- />
30
- <Text as="span">{text}</Text>
31
- </ListItem>
32
- ))}
33
- </List>
34
- );
35
- };
36
-
37
- Checklist.displayName = "Checklist";
38
-
39
- export type { ChecklistProps };
1
+ import React from "react";
2
+
3
+ import { ChecklistProps } from "@shared/components/checklist/types";
4
+ import { List, ListItem } from "@shared/components/list";
5
+ import { MaterialIcon } from "@shared/components/material-icon";
6
+ import { Text } from "@shared/components/text";
7
+ import { cx } from "@shared/utils";
8
+
9
+ export const Checklist: React.FC<ChecklistProps> = props => {
10
+ const {
11
+ items,
12
+ listIconName = "check",
13
+ listItemClassName,
14
+ iconSize = 20,
15
+ } = props;
16
+ const showIcons = listIconName !== "disc";
17
+ if (!items?.length) return null;
18
+
19
+ return (
20
+ <List
21
+ className="mt-2 space-y-1"
22
+ variant={showIcons ? "default" : "unstyled"}
23
+ >
24
+ {items.map((text, idx) => (
25
+ <ListItem
26
+ variant={showIcons ? "default" : "unstyled"}
27
+ key={idx}
28
+ className={cx(
29
+ "flex items-center gap-2 text-text-secondary",
30
+ listItemClassName
31
+ )}
32
+ >
33
+ {showIcons && (
34
+ <div>
35
+ <MaterialIcon
36
+ name={listIconName}
37
+ size={iconSize}
38
+ weight="600"
39
+ className="text-icon-brand"
40
+ />
41
+ </div>
42
+ )}
43
+ <Text as="span">{text}</Text>
44
+ </ListItem>
45
+ ))}
46
+ </List>
47
+ );
48
+ };
49
+
50
+ Checklist.displayName = "Checklist";
51
+
52
+ export type { ChecklistProps };
@@ -1,6 +1,7 @@
1
- export type ChecklistProps = {
2
- items: string[];
3
- // TODO: add icon names as needed
4
- listIconName?: "check";
5
- listItemClassName?: string;
6
- };
1
+ export type ChecklistProps = {
2
+ items: React.ReactNode[];
3
+ // TODO: add icon names as needed
4
+ listIconName?: "check" | "disc";
5
+ listItemClassName?: string;
6
+ iconSize?: 20 | 24 | 32 | 40 | 48 | 52 | undefined;
7
+ };
@@ -1,97 +1,97 @@
1
- "use client";
2
-
3
- import React, { forwardRef } from "react";
4
- import { cx } from "../../utils";
5
- import { LinkProps } from "./types";
6
-
7
- export const Link = forwardRef<HTMLAnchorElement, LinkProps>(
8
- (
9
- {
10
- children,
11
- href,
12
- className = "",
13
- onClick,
14
- variant = "unstyled",
15
- style,
16
- external = false,
17
- disabled = false,
18
- ...props
19
- },
20
- ref
21
- ) => {
22
- // Get Tailwind classes for different variants
23
- const getVariantClasses = () => {
24
- if (variant === "unstyled") return "";
25
-
26
- // TODO: Add styles based on the figma design for all variants
27
- const baseClasses =
28
- "transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2";
29
-
30
- const variantClasses = {
31
- default: "text-text underline",
32
- };
33
-
34
- const stateClasses = [
35
- disabled
36
- ? "opacity-60 cursor-not-allowed pointer-events-none"
37
- : "cursor-pointer",
38
- ]
39
- .filter(Boolean)
40
- .join(" ");
41
-
42
- return [
43
- baseClasses,
44
- variantClasses[variant as keyof typeof variantClasses] ||
45
- variantClasses.default,
46
- stateClasses,
47
- ]
48
- .filter(Boolean)
49
- .join(" ");
50
- };
51
-
52
- const tailwindClasses = getVariantClasses();
53
-
54
- // Handle click events
55
- const handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
56
- if (disabled) {
57
- event.preventDefault();
58
- return;
59
- }
60
-
61
- onClick?.(event);
62
- };
63
-
64
- // Combine all classes
65
- const combinedClassName = cx(
66
- tailwindClasses,
67
- `link--${variant}`,
68
- disabled && "link--disabled",
69
- className
70
- );
71
-
72
- // Determine link props based on external/internal
73
- const linkProps = {
74
- ...props,
75
- ref,
76
- className: combinedClassName,
77
- style,
78
- href: disabled ? undefined : href,
79
- onClick: handleClick,
80
- ...(external &&
81
- !disabled && {
82
- target: "_blank",
83
- rel: "noopener noreferrer",
84
- }),
85
- ...(disabled && {
86
- "aria-disabled": true,
87
- tabIndex: -1,
88
- }),
89
- };
90
-
91
- return <a {...linkProps}>{children}</a>;
92
- }
93
- );
94
-
95
- Link.displayName = "Link";
96
-
97
- export type { LinkProps };
1
+ "use client";
2
+
3
+ import React, { forwardRef } from "react";
4
+ import { cx } from "../../utils";
5
+ import { LinkProps } from "./types";
6
+
7
+ export const Link = forwardRef<HTMLAnchorElement, LinkProps>(
8
+ (
9
+ {
10
+ children,
11
+ href,
12
+ className = "",
13
+ onClick,
14
+ variant = "unstyled",
15
+ style,
16
+ external = false,
17
+ disabled = false,
18
+ ...props
19
+ },
20
+ ref
21
+ ) => {
22
+ // Get Tailwind classes for different variants
23
+ const getVariantClasses = () => {
24
+ if (variant === "unstyled") return "";
25
+
26
+ // TODO: Add styles based on the figma design for all variants
27
+ const baseClasses =
28
+ "transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2";
29
+
30
+ const variantClasses = {
31
+ default: "text-text underline",
32
+ };
33
+
34
+ const stateClasses = [
35
+ disabled
36
+ ? "opacity-60 cursor-not-allowed pointer-events-none"
37
+ : "cursor-pointer",
38
+ ]
39
+ .filter(Boolean)
40
+ .join(" ");
41
+
42
+ return [
43
+ baseClasses,
44
+ variantClasses[variant as keyof typeof variantClasses] ||
45
+ variantClasses.default,
46
+ stateClasses,
47
+ ]
48
+ .filter(Boolean)
49
+ .join(" ");
50
+ };
51
+
52
+ const tailwindClasses = getVariantClasses();
53
+
54
+ // Handle click events
55
+ const handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
56
+ if (disabled) {
57
+ event.preventDefault();
58
+ return;
59
+ }
60
+
61
+ onClick?.(event);
62
+ };
63
+
64
+ // Combine all classes
65
+ const combinedClassName = cx(
66
+ tailwindClasses,
67
+ `link--${variant}`,
68
+ disabled && "link--disabled",
69
+ className
70
+ );
71
+
72
+ // Determine link props based on external/internal
73
+ const linkProps = {
74
+ ...props,
75
+ ref,
76
+ className: combinedClassName,
77
+ style,
78
+ href: disabled ? undefined : href,
79
+ onClick: handleClick,
80
+ ...(external &&
81
+ !disabled && {
82
+ target: "_blank",
83
+ rel: "noopener noreferrer",
84
+ }),
85
+ ...(disabled && {
86
+ "aria-disabled": true,
87
+ tabIndex: -1,
88
+ }),
89
+ };
90
+
91
+ return <a {...linkProps}>{children}</a>;
92
+ }
93
+ );
94
+
95
+ Link.displayName = "Link";
96
+
97
+ export type { LinkProps };
@@ -1,133 +1,133 @@
1
- import React from "react";
2
- import { Button } from "../button";
3
- import { ImagePromoBarProps } from "./types";
4
-
5
- import { Checklist } from "@shared/components/checklist";
6
- import { Image } from "@shared/components/image";
7
- import { NextImage } from "@shared/components/next-image";
8
- import { Text } from "@shared/components/text";
9
-
10
- export const ImagePromoBar: React.FC<ImagePromoBarProps> = ({
11
- brow,
12
- enableHeading,
13
- title,
14
- subTitle,
15
- ctaDisclaimer,
16
- disclaimer,
17
- description,
18
- image,
19
- imageLinks,
20
- mediaPosition = true,
21
- checklist,
22
- secondaryCta,
23
- cta,
24
- videoLink,
25
- maxWidth = true,
26
- color = "light",
27
- imageWidth = 660,
28
- imageHeight = 660,
29
- }) => {
30
- return (
31
- <div className="component-container">
32
- <div
33
- className={`image-promo-bar-content ${maxWidth ? "max-w-120 xl:mx-auto" : ""} mx-5 mb-8 mt-16`}
34
- >
35
- <div
36
- className={`flex shrink-0 flex-col items-center gap-8 xl:gap-[126px] ${mediaPosition ? "flex-row xl:flex-row-reverse" : "xl:flex-row"}`}
37
- >
38
- <div
39
- className={`flex flex-[1_0_0] flex-col items-start justify-center gap-8 xl:gap-10 ${color == "dark" ? "text-text" : "text-white"}`}
40
- >
41
- <div className="heading holder">
42
- {brow && (
43
- <Text
44
- as="div"
45
- className="subheading4 mb-4 text-text-brand xl:subheading2 xl:mb-3"
46
- >
47
- {brow}
48
- </Text>
49
- )}
50
- {title && (
51
- <Text
52
- as={enableHeading ? "h1" : "h2"}
53
- className="heading2 xl:heading1"
54
- >
55
- {title}
56
- </Text>
57
- )}
58
- {subTitle && (
59
- <Text
60
- as={enableHeading ? "h2" : "h3"}
61
- className="subheading1 mt-3"
62
- >
63
- {subTitle}
64
- </Text>
65
- )}
66
- </div>
67
- {/* Content Section */}
68
- {description && (
69
- <Text as="div" className="body1">
70
- {description}
71
- </Text>
72
- )}
73
- {/* Checklist Rendering */}
74
- {checklist.length > 0 && <Checklist items={checklist} />}
75
- {/* Image Links Collection */}
76
- {imageLinks?.map((link, index) => (
77
- <div key={index} className="image-link">
78
- <Image src={link.url} alt="icon-link" />
79
- </div>
80
- ))}
81
- {/* CTAs and Disclaimers */}
82
- <div className="flex w-full flex-col gap-8 xl:flex-row xl:gap-3">
83
- {cta && (
84
- <div className="primary-cta w-full xl:w-auto">
85
- <Button {...cta} fullWidth={true} />
86
- </div>
87
- )}
88
- {secondaryCta && (
89
- <div className="secondary-cta">
90
- <Button {...secondaryCta} fullWidth={true} />
91
- </div>
92
- )}
93
- </div>
94
- {ctaDisclaimer && <div>{ctaDisclaimer}</div>}
95
- {disclaimer && <div>{disclaimer}</div>}
96
- </div>
97
- <aside className="flex shrink-0 content-center items-center">
98
- <div className="relative aspect-[16/9] w-full xl:aspect-square xl:max-h-[486px] xl:w-[486px]">
99
- {/* Media Section */}
100
- {image && (
101
- <NextImage
102
- src={image}
103
- alt="section-image"
104
- width={imageWidth}
105
- height={imageHeight}
106
- className=" rounded-[40px] h-full object-cover left-0 right-0 bottom-0 top-0"
107
- />
108
- )}
109
- </div>
110
- <div>
111
- {/* Video Link Section */}
112
- {videoLink?.link && (
113
- <div className="video-section">
114
- {videoLink.image && (
115
- <NextImage
116
- src={videoLink.image}
117
- alt="Video preview"
118
- width={486}
119
- height={100}
120
- className="rounded-[40px]"
121
- />
122
- )}
123
- </div>
124
- )}
125
- </div>
126
- </aside>
127
- </div>
128
- </div>
129
- </div>
130
- );
131
- };
132
-
133
- export default ImagePromoBar;
1
+ import React from "react";
2
+ import { Button } from "../button";
3
+ import { ImagePromoBarProps } from "./types";
4
+
5
+ import { Checklist } from "@shared/components/checklist";
6
+ import { Image } from "@shared/components/image";
7
+ import { NextImage } from "@shared/components/next-image";
8
+ import { Text } from "@shared/components/text";
9
+
10
+ export const ImagePromoBar: React.FC<ImagePromoBarProps> = ({
11
+ brow,
12
+ enableHeading,
13
+ title,
14
+ subTitle,
15
+ ctaDisclaimer,
16
+ disclaimer,
17
+ description,
18
+ image,
19
+ imageLinks,
20
+ mediaPosition = true,
21
+ checklist,
22
+ secondaryCta,
23
+ cta,
24
+ videoLink,
25
+ maxWidth = true,
26
+ color = "light",
27
+ imageWidth = 660,
28
+ imageHeight = 660,
29
+ }) => {
30
+ return (
31
+ <div className="component-container">
32
+ <div
33
+ className={`image-promo-bar-content ${maxWidth ? "max-w-120 xl:mx-auto" : ""} mx-5 mb-8 mt-16`}
34
+ >
35
+ <div
36
+ className={`flex shrink-0 flex-col items-center gap-8 xl:gap-[126px] ${mediaPosition ? "flex-row xl:flex-row-reverse" : "xl:flex-row"}`}
37
+ >
38
+ <div
39
+ className={`flex flex-[1_0_0] flex-col items-start justify-center gap-8 xl:gap-10 ${color == "dark" ? "text-text" : "text-white"}`}
40
+ >
41
+ <div className="heading holder">
42
+ {brow && (
43
+ <Text
44
+ as="div"
45
+ className="subheading4 mb-4 text-text-brand xl:subheading2 xl:mb-3"
46
+ >
47
+ {brow}
48
+ </Text>
49
+ )}
50
+ {title && (
51
+ <Text
52
+ as={enableHeading ? "h1" : "h2"}
53
+ className="heading2 xl:heading1"
54
+ >
55
+ {title}
56
+ </Text>
57
+ )}
58
+ {subTitle && (
59
+ <Text
60
+ as={enableHeading ? "h2" : "h3"}
61
+ className="subheading1 mt-3"
62
+ >
63
+ {subTitle}
64
+ </Text>
65
+ )}
66
+ </div>
67
+ {/* Content Section */}
68
+ {description && (
69
+ <Text as="div" className="body1">
70
+ {description}
71
+ </Text>
72
+ )}
73
+ {/* Checklist Rendering */}
74
+ {checklist.length > 0 && <Checklist items={checklist} />}
75
+ {/* Image Links Collection */}
76
+ {imageLinks?.map((link, index) => (
77
+ <div key={index} className="image-link">
78
+ <Image src={link.url} alt="icon-link" />
79
+ </div>
80
+ ))}
81
+ {/* CTAs and Disclaimers */}
82
+ <div className="flex w-full flex-col gap-8 xl:flex-row xl:gap-3">
83
+ {cta && (
84
+ <div className="primary-cta w-full xl:w-auto">
85
+ <Button {...cta} fullWidth={true} />
86
+ </div>
87
+ )}
88
+ {secondaryCta && (
89
+ <div className="secondary-cta">
90
+ <Button {...secondaryCta} fullWidth={true} />
91
+ </div>
92
+ )}
93
+ </div>
94
+ {ctaDisclaimer && <div>{ctaDisclaimer}</div>}
95
+ {disclaimer && <div>{disclaimer}</div>}
96
+ </div>
97
+ <aside className="flex shrink-0 content-center items-center">
98
+ <div className="relative aspect-[16/9] w-full xl:aspect-square xl:max-h-[486px] xl:w-[486px]">
99
+ {/* Media Section */}
100
+ {image && (
101
+ <NextImage
102
+ src={image}
103
+ alt="section-image"
104
+ width={imageWidth}
105
+ height={imageHeight}
106
+ className=" rounded-[40px] h-full object-cover left-0 right-0 bottom-0 top-0"
107
+ />
108
+ )}
109
+ </div>
110
+ <div>
111
+ {/* Video Link Section */}
112
+ {videoLink?.link && (
113
+ <div className="video-section">
114
+ {videoLink.image && (
115
+ <NextImage
116
+ src={videoLink.image}
117
+ alt="Video preview"
118
+ width={486}
119
+ height={100}
120
+ className="rounded-[40px]"
121
+ />
122
+ )}
123
+ </div>
124
+ )}
125
+ </div>
126
+ </aside>
127
+ </div>
128
+ </div>
129
+ </div>
130
+ );
131
+ };
132
+
133
+ export default ImagePromoBar;