@windstream/react-shared-components 0.0.36 → 0.0.38

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 (58) hide show
  1. package/dist/contentful/index.d.ts +9 -29
  2. package/dist/contentful/index.esm.js +1 -1
  3. package/dist/contentful/index.esm.js.map +1 -1
  4. package/dist/contentful/index.js +1 -1
  5. package/dist/contentful/index.js.map +1 -1
  6. package/dist/core.d.ts +1 -1
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.esm.js +1 -1
  9. package/dist/index.esm.js.map +1 -1
  10. package/dist/index.js +1 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/styles.css +1 -1
  13. package/package.json +1 -1
  14. package/src/components/accordion/index.tsx +49 -49
  15. package/src/components/alert-card/types.ts +9 -9
  16. package/src/components/brand-button/index.tsx +93 -93
  17. package/src/components/button/index.tsx +27 -27
  18. package/src/components/button/types.ts +14 -14
  19. package/src/components/checkbox/index.tsx +197 -197
  20. package/src/components/collapse/index.tsx +46 -46
  21. package/src/components/image/types.ts +33 -33
  22. package/src/components/input/index.tsx +6 -6
  23. package/src/components/link/index.tsx +97 -97
  24. package/src/components/link/types.ts +25 -25
  25. package/src/components/list/index.tsx +88 -88
  26. package/src/components/list/list-item/index.tsx +38 -38
  27. package/src/components/list/list-item/types.ts +13 -13
  28. package/src/components/list/types.ts +29 -29
  29. package/src/components/material-icon/index.tsx +44 -44
  30. package/src/components/material-icon/types.ts +31 -31
  31. package/src/components/modal/index.tsx +164 -164
  32. package/src/components/see-more/index.tsx +44 -44
  33. package/src/components/select/index.tsx +150 -150
  34. package/src/components/skeleton/index.tsx +61 -61
  35. package/src/components/text/index.tsx +25 -25
  36. package/src/components/text/types.ts +45 -45
  37. package/src/contentful/blocks/accordion/Accordion.stories.tsx +29 -29
  38. package/src/contentful/blocks/accordion/index.tsx +52 -52
  39. package/src/contentful/blocks/accordion/types.ts +17 -17
  40. package/src/contentful/blocks/button/index.tsx +5 -0
  41. package/src/contentful/blocks/button/types.ts +1 -0
  42. package/src/contentful/blocks/callout/Callout.stories.tsx +1 -1
  43. package/src/contentful/blocks/callout/index.tsx +15 -52
  44. package/src/contentful/blocks/callout/types.ts +1 -14
  45. package/src/contentful/blocks/find-kinetic/FindKinetic.stories.tsx +23 -23
  46. package/src/contentful/blocks/find-kinetic/index.tsx +80 -80
  47. package/src/contentful/blocks/find-kinetic/types.ts +18 -18
  48. package/src/contentful/blocks/footer/index.tsx +79 -79
  49. package/src/contentful/blocks/image-promo-bar/index.tsx +154 -154
  50. package/src/contentful/blocks/navigation/index.tsx +1 -2
  51. package/src/contentful/blocks/navigation/link-groups.tsx/index.tsx +64 -62
  52. package/src/contentful/blocks/primary-hero/index.tsx +163 -64
  53. package/src/contentful/blocks/primary-hero/types.ts +1 -0
  54. package/src/contentful/index.ts +45 -48
  55. package/src/hooks/use-body-scroll-lock.ts +34 -34
  56. package/src/setupTests.ts +46 -46
  57. package/src/contentful/blocks/cards/simple-card/index.tsx +0 -45
  58. package/src/contentful/blocks/cards/simple-card/types.ts +0 -11
@@ -1,197 +1,197 @@
1
- "use client";
2
-
3
- import React, { useCallback } from "react";
4
- import { CheckboxProps } from "./types";
5
-
6
- import { Button } from "@shared/components/button";
7
- import { cx } from "@shared/utils";
8
-
9
- export const Checkbox: React.FC<CheckboxProps> = ({
10
- state,
11
- checked = false,
12
- onChange,
13
- className,
14
- label,
15
- labelClassName,
16
- containerClassName,
17
- name,
18
- value,
19
- id,
20
- disabled = false,
21
- required = false,
22
- error = false,
23
- "data-cy": dataCy,
24
- renderInfoIcon,
25
- ...rest
26
- }) => {
27
- const isDisabled = disabled || state === "disabled";
28
- const isFocused = state === "focus";
29
- const inputId = id || name;
30
-
31
- const checkboxClasses = cx(
32
- "flex items-center justify-center w-6 h-6 rounded-[4px] outline-offset-2",
33
- isFocused && "outline",
34
- className
35
- );
36
-
37
- const handleInputChange = useCallback(
38
- (e: React.ChangeEvent<HTMLInputElement>) => {
39
- if (!isDisabled) {
40
- if (onChange) {
41
- // Check if onChange expects a boolean parameter (new signature)
42
- if (onChange.length === 1) {
43
- (onChange as (isChecked: boolean) => void)(e.target.checked);
44
- } else {
45
- // Old signature - just call without parameters
46
- (onChange as () => void)();
47
- }
48
- }
49
- }
50
- },
51
- [isDisabled, onChange]
52
- );
53
-
54
- const renderIcon = () => {
55
- if (checked) {
56
- return (
57
- <svg
58
- xmlns="http://www.w3.org/2000/svg"
59
- width="24"
60
- height="24"
61
- viewBox="0 0 24 24"
62
- fill="none"
63
- >
64
- <rect
65
- width="24"
66
- height="24"
67
- rx="4"
68
- className={cx(
69
- isDisabled
70
- ? "fill-checkbox-bg-surface-selected-disabled"
71
- : "fill-bg-fill-brand"
72
- )}
73
- />
74
- <path
75
- d="M8 11.9593L11.0316 15L17 9"
76
- stroke="white"
77
- strokeWidth="2.2"
78
- strokeLinecap="round"
79
- strokeLinejoin="round"
80
- />
81
- </svg>
82
- );
83
- }
84
- return (
85
- <svg
86
- xmlns="http://www.w3.org/2000/svg"
87
- width="24"
88
- height="24"
89
- viewBox="0 0 24 24"
90
- fill="none"
91
- >
92
- <rect
93
- x="0.5"
94
- y="0.5"
95
- width="23"
96
- height="23"
97
- rx="3.5"
98
- className={cx(
99
- isDisabled ? "fill-checkbox-bg-surface-disabled" : "fill-white"
100
- )}
101
- />
102
- <rect
103
- x="0.5"
104
- y="0.5"
105
- width="23"
106
- height="23"
107
- rx="3.5"
108
- stroke="#CECECE"
109
- />
110
- </svg>
111
- );
112
- };
113
-
114
- const checkboxElement = (
115
- <div className={cx("flex items-center gap-3", containerClassName)}>
116
- <div className="relative">
117
- <input
118
- type="checkbox"
119
- id={inputId}
120
- name={name}
121
- value={value}
122
- checked={checked}
123
- onChange={handleInputChange}
124
- disabled={isDisabled}
125
- required={required}
126
- className="peer sr-only"
127
- data-cy={dataCy}
128
- {...rest}
129
- />
130
- <label
131
- htmlFor={inputId}
132
- className={cx("peer-focus:outline", checkboxClasses)}
133
- style={{ pointerEvents: isDisabled ? "none" : "auto" }}
134
- >
135
- {renderIcon()}
136
- </label>
137
- </div>
138
- {label && (
139
- <label
140
- htmlFor={inputId}
141
- className={cx(
142
- "cursor-pointer",
143
- error && "text-text-critical",
144
- labelClassName
145
- )}
146
- >
147
- {label}
148
- </label>
149
- )}
150
- {renderInfoIcon && (
151
- <Button
152
- type="button"
153
- onClick={renderInfoIcon.onClick}
154
- data-testid={renderInfoIcon.dataTestId}
155
- className="ml-2 cursor-pointer text-icon-info"
156
- aria-label="More information"
157
- >
158
- <svg
159
- xmlns="http://www.w3.org/2000/svg"
160
- width="24"
161
- height="24"
162
- viewBox="0 0 24 24"
163
- fill="none"
164
- >
165
- <circle
166
- cx="12"
167
- cy="12"
168
- r="10"
169
- stroke="currentColor"
170
- strokeWidth="2"
171
- />
172
- <path
173
- d="M12 16v-4"
174
- stroke="currentColor"
175
- strokeWidth="2"
176
- strokeLinecap="round"
177
- strokeLinejoin="round"
178
- />
179
- <path
180
- d="M12 8h.01"
181
- stroke="currentColor"
182
- strokeWidth="2"
183
- strokeLinecap="round"
184
- strokeLinejoin="round"
185
- />
186
- </svg>
187
- </Button>
188
- )}
189
- </div>
190
- );
191
-
192
- return checkboxElement;
193
- };
194
-
195
- Checkbox.displayName = "Checkbox";
196
-
197
- export type { CheckboxProps };
1
+ "use client";
2
+
3
+ import React, { useCallback } from "react";
4
+ import { CheckboxProps } from "./types";
5
+
6
+ import { Button } from "@shared/components/button";
7
+ import { cx } from "@shared/utils";
8
+
9
+ export const Checkbox: React.FC<CheckboxProps> = ({
10
+ state,
11
+ checked = false,
12
+ onChange,
13
+ className,
14
+ label,
15
+ labelClassName,
16
+ containerClassName,
17
+ name,
18
+ value,
19
+ id,
20
+ disabled = false,
21
+ required = false,
22
+ error = false,
23
+ "data-cy": dataCy,
24
+ renderInfoIcon,
25
+ ...rest
26
+ }) => {
27
+ const isDisabled = disabled || state === "disabled";
28
+ const isFocused = state === "focus";
29
+ const inputId = id || name;
30
+
31
+ const checkboxClasses = cx(
32
+ "flex items-center justify-center w-6 h-6 rounded-[4px] outline-offset-2",
33
+ isFocused && "outline",
34
+ className
35
+ );
36
+
37
+ const handleInputChange = useCallback(
38
+ (e: React.ChangeEvent<HTMLInputElement>) => {
39
+ if (!isDisabled) {
40
+ if (onChange) {
41
+ // Check if onChange expects a boolean parameter (new signature)
42
+ if (onChange.length === 1) {
43
+ (onChange as (isChecked: boolean) => void)(e.target.checked);
44
+ } else {
45
+ // Old signature - just call without parameters
46
+ (onChange as () => void)();
47
+ }
48
+ }
49
+ }
50
+ },
51
+ [isDisabled, onChange]
52
+ );
53
+
54
+ const renderIcon = () => {
55
+ if (checked) {
56
+ return (
57
+ <svg
58
+ xmlns="http://www.w3.org/2000/svg"
59
+ width="24"
60
+ height="24"
61
+ viewBox="0 0 24 24"
62
+ fill="none"
63
+ >
64
+ <rect
65
+ width="24"
66
+ height="24"
67
+ rx="4"
68
+ className={cx(
69
+ isDisabled
70
+ ? "fill-checkbox-bg-surface-selected-disabled"
71
+ : "fill-bg-fill-brand"
72
+ )}
73
+ />
74
+ <path
75
+ d="M8 11.9593L11.0316 15L17 9"
76
+ stroke="white"
77
+ strokeWidth="2.2"
78
+ strokeLinecap="round"
79
+ strokeLinejoin="round"
80
+ />
81
+ </svg>
82
+ );
83
+ }
84
+ return (
85
+ <svg
86
+ xmlns="http://www.w3.org/2000/svg"
87
+ width="24"
88
+ height="24"
89
+ viewBox="0 0 24 24"
90
+ fill="none"
91
+ >
92
+ <rect
93
+ x="0.5"
94
+ y="0.5"
95
+ width="23"
96
+ height="23"
97
+ rx="3.5"
98
+ className={cx(
99
+ isDisabled ? "fill-checkbox-bg-surface-disabled" : "fill-white"
100
+ )}
101
+ />
102
+ <rect
103
+ x="0.5"
104
+ y="0.5"
105
+ width="23"
106
+ height="23"
107
+ rx="3.5"
108
+ stroke="#CECECE"
109
+ />
110
+ </svg>
111
+ );
112
+ };
113
+
114
+ const checkboxElement = (
115
+ <div className={cx("flex items-center gap-3", containerClassName)}>
116
+ <div className="relative">
117
+ <input
118
+ type="checkbox"
119
+ id={inputId}
120
+ name={name}
121
+ value={value}
122
+ checked={checked}
123
+ onChange={handleInputChange}
124
+ disabled={isDisabled}
125
+ required={required}
126
+ className="peer sr-only"
127
+ data-cy={dataCy}
128
+ {...rest}
129
+ />
130
+ <label
131
+ htmlFor={inputId}
132
+ className={cx("peer-focus:outline", checkboxClasses)}
133
+ style={{ pointerEvents: isDisabled ? "none" : "auto" }}
134
+ >
135
+ {renderIcon()}
136
+ </label>
137
+ </div>
138
+ {label && (
139
+ <label
140
+ htmlFor={inputId}
141
+ className={cx(
142
+ "cursor-pointer",
143
+ error && "text-text-critical",
144
+ labelClassName
145
+ )}
146
+ >
147
+ {label}
148
+ </label>
149
+ )}
150
+ {renderInfoIcon && (
151
+ <Button
152
+ type="button"
153
+ onClick={renderInfoIcon.onClick}
154
+ data-testid={renderInfoIcon.dataTestId}
155
+ className="ml-2 cursor-pointer text-icon-info"
156
+ aria-label="More information"
157
+ >
158
+ <svg
159
+ xmlns="http://www.w3.org/2000/svg"
160
+ width="24"
161
+ height="24"
162
+ viewBox="0 0 24 24"
163
+ fill="none"
164
+ >
165
+ <circle
166
+ cx="12"
167
+ cy="12"
168
+ r="10"
169
+ stroke="currentColor"
170
+ strokeWidth="2"
171
+ />
172
+ <path
173
+ d="M12 16v-4"
174
+ stroke="currentColor"
175
+ strokeWidth="2"
176
+ strokeLinecap="round"
177
+ strokeLinejoin="round"
178
+ />
179
+ <path
180
+ d="M12 8h.01"
181
+ stroke="currentColor"
182
+ strokeWidth="2"
183
+ strokeLinecap="round"
184
+ strokeLinejoin="round"
185
+ />
186
+ </svg>
187
+ </Button>
188
+ )}
189
+ </div>
190
+ );
191
+
192
+ return checkboxElement;
193
+ };
194
+
195
+ Checkbox.displayName = "Checkbox";
196
+
197
+ export type { CheckboxProps };
@@ -1,46 +1,46 @@
1
- "use client";
2
-
3
- import { useEffect, useRef, useState } from "react";
4
- import { CollapsibleProps } from "./types";
5
-
6
- // Collapsible with smooth height/opacity transition
7
- export const Collapse = (props: CollapsibleProps) => {
8
- const { open, children } = props;
9
- const contentRef = useRef<HTMLDivElement | null>(null);
10
- const [maxHeight, setMaxHeight] = useState<number>(0);
11
-
12
- useEffect(() => {
13
- const el = contentRef.current;
14
- if (!el) return;
15
-
16
- const updateHeight = () => {
17
- setMaxHeight(open ? el.scrollHeight : 0);
18
- };
19
-
20
- updateHeight();
21
-
22
- let resizeObserver: ResizeObserver | undefined;
23
- if (open) {
24
- resizeObserver = new ResizeObserver(() => updateHeight());
25
- resizeObserver.observe(el);
26
- }
27
-
28
- return () => {
29
- if (resizeObserver) resizeObserver.disconnect();
30
- };
31
- }, [open, children]);
32
-
33
- return (
34
- <div
35
- className="overflow-hidden transition-all duration-300 ease-in-out"
36
- style={{ maxHeight: maxHeight, opacity: open ? 1 : 0 }}
37
- aria-hidden={!open}
38
- >
39
- <div ref={contentRef}>{children}</div>
40
- </div>
41
- );
42
- };
43
-
44
- Collapse.displayName = "Collapse";
45
-
46
- export type { CollapsibleProps };
1
+ "use client";
2
+
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { CollapsibleProps } from "./types";
5
+
6
+ // Collapsible with smooth height/opacity transition
7
+ export const Collapse = (props: CollapsibleProps) => {
8
+ const { open, children } = props;
9
+ const contentRef = useRef<HTMLDivElement | null>(null);
10
+ const [maxHeight, setMaxHeight] = useState<number>(0);
11
+
12
+ useEffect(() => {
13
+ const el = contentRef.current;
14
+ if (!el) return;
15
+
16
+ const updateHeight = () => {
17
+ setMaxHeight(open ? el.scrollHeight : 0);
18
+ };
19
+
20
+ updateHeight();
21
+
22
+ let resizeObserver: ResizeObserver | undefined;
23
+ if (open) {
24
+ resizeObserver = new ResizeObserver(() => updateHeight());
25
+ resizeObserver.observe(el);
26
+ }
27
+
28
+ return () => {
29
+ if (resizeObserver) resizeObserver.disconnect();
30
+ };
31
+ }, [open, children]);
32
+
33
+ return (
34
+ <div
35
+ className="overflow-hidden transition-all duration-300 ease-in-out"
36
+ style={{ maxHeight: maxHeight, opacity: open ? 1 : 0 }}
37
+ aria-hidden={!open}
38
+ >
39
+ <div ref={contentRef}>{children}</div>
40
+ </div>
41
+ );
42
+ };
43
+
44
+ Collapse.displayName = "Collapse";
45
+
46
+ export type { CollapsibleProps };
@@ -1,33 +1,33 @@
1
- import type { ComponentType, ForwardRefExoticComponent, ImgHTMLAttributes, RefAttributes } from "react";
2
-
3
- /**
4
- * Props passed to the custom image component when using the `as` prop.
5
- * Covers native img attributes plus optional Next.js Image props (fill, sizes, priority, etc.).
6
- */
7
- export interface ImageComponentProps
8
- extends Omit<ImgHTMLAttributes<HTMLImageElement>, "alt"> {
9
- /** Image source URL */
10
- src: string;
11
- /** Alt text (required for accessibility; use "" for decorative images) */
12
- alt: string;
13
- /** Optional; used by Next.js Image when using fill layout */
14
- fill?: boolean;
15
- /** Optional; used by Next.js Image for responsive sizes */
16
- sizes?: string;
17
- /** Optional; used by Next.js Image for priority loading */
18
- priority?: boolean;
19
- /** Optional; used by Next.js Image for blur placeholder */
20
- placeholder?: "blur" | "empty";
21
- /** Optional; used by Next.js Image for quality (1–100) */
22
- quality?: number;
23
- }
24
-
25
- /** Type for custom image component that supports ref forwarding */
26
- type ImageComponent =
27
- | ComponentType<ImageComponentProps>
28
- | ForwardRefExoticComponent<ImageComponentProps & RefAttributes<HTMLImageElement>>;
29
-
30
- export interface ImageProps extends ImageComponentProps {
31
- /** Custom component to render instead of native img (e.g. next/image) */
32
- as?: ImageComponent;
33
- }
1
+ import type { ComponentType, ForwardRefExoticComponent, ImgHTMLAttributes, RefAttributes } from "react";
2
+
3
+ /**
4
+ * Props passed to the custom image component when using the `as` prop.
5
+ * Covers native img attributes plus optional Next.js Image props (fill, sizes, priority, etc.).
6
+ */
7
+ export interface ImageComponentProps
8
+ extends Omit<ImgHTMLAttributes<HTMLImageElement>, "alt"> {
9
+ /** Image source URL */
10
+ src: string;
11
+ /** Alt text (required for accessibility; use "" for decorative images) */
12
+ alt: string;
13
+ /** Optional; used by Next.js Image when using fill layout */
14
+ fill?: boolean;
15
+ /** Optional; used by Next.js Image for responsive sizes */
16
+ sizes?: string;
17
+ /** Optional; used by Next.js Image for priority loading */
18
+ priority?: boolean;
19
+ /** Optional; used by Next.js Image for blur placeholder */
20
+ placeholder?: "blur" | "empty";
21
+ /** Optional; used by Next.js Image for quality (1–100) */
22
+ quality?: number;
23
+ }
24
+
25
+ /** Type for custom image component that supports ref forwarding */
26
+ type ImageComponent =
27
+ | ComponentType<ImageComponentProps>
28
+ | ForwardRefExoticComponent<ImageComponentProps & RefAttributes<HTMLImageElement>>;
29
+
30
+ export interface ImageProps extends ImageComponentProps {
31
+ /** Custom component to render instead of native img (e.g. next/image) */
32
+ as?: ImageComponent;
33
+ }
@@ -88,19 +88,19 @@ export const InputField: ForwardRefRenderFunction<
88
88
 
89
89
  <div
90
90
  className={cx(
91
- "relative flex w-80 flex-row items-center overflow-hidden rounded-xl border border-input-border bg-input-bg-surface",
91
+ "relative flex flex-row items-center overflow-hidden rounded-xl border border-input-border bg-input-bg-surface",
92
92
  sizeClasses[size || "medium"],
93
93
  containerClassName,
94
94
  (isHovered || effectiveState === "hover") &&
95
- !isFocused &&
96
- effectiveState !== "error" &&
97
- "border-input-border-hover",
95
+ !isFocused &&
96
+ effectiveState !== "error" &&
97
+ "border-input-border-hover",
98
98
  (isFocused ||
99
99
  effectiveState === "focus" ||
100
100
  effectiveState === "active") &&
101
- "border-input-border-selected outline outline-1 outline-input-border-selected",
101
+ "border-input-border-selected outline outline-1 outline-input-border-selected",
102
102
  effectiveState === "error" &&
103
- "border-input-border-critical outline outline-1 outline-input-border-critical"
103
+ "border-input-border-critical outline outline-1 outline-input-border-critical"
104
104
  )}
105
105
  >
106
106
  {prefixIconName ? (