@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,150 +1,150 @@
1
- "use client";
2
-
3
- import React, { useMemo } from "react";
4
- import { cx } from "../../utils";
5
- import { Text } from "../text";
6
- import { FilterOptions, SelectOption, SelectProps } from "./types";
7
- import ReactSelect, { createFilter } from "react-select";
8
-
9
- export const Select: React.FC<SelectProps> = React.memo(
10
- ({
11
- options,
12
- className,
13
- controlClassName,
14
- value,
15
- isCustomStyle = false,
16
- placeholder,
17
- required,
18
- onChange,
19
- filterOptions,
20
- hasError,
21
- error,
22
- helperText,
23
- label,
24
- labelClassName,
25
- size = "md",
26
- variant = "default",
27
- "data-cy": dataCy,
28
- "data-testid": dataTestId,
29
- ...rest
30
- }) => {
31
- const memoizedFilterOption = useMemo(
32
- () => createFilter(filterOptions),
33
- [filterOptions]
34
- );
35
-
36
- const getSizeClasses = () => {
37
- switch (size) {
38
- case "sm":
39
- return "h-[48px] px-3 rounded-lg";
40
- case "md":
41
- default:
42
- return "h-[56px] px-3 rounded-xl";
43
- }
44
- };
45
-
46
- const memoizedClassNames = useMemo(
47
- () => ({
48
- control: ({ isFocused }: any) =>
49
- cx(
50
- getSizeClasses(),
51
- "border border-input-border bg-white hover:not-focus:border-input-border-hover",
52
- {
53
- "border-input-border-selected outline outline-2 outline-input-border-selected":
54
- isFocused && !hasError,
55
- "border-input-border-critical shadow-none": hasError,
56
- },
57
- controlClassName
58
- ),
59
- indicatorSeparator: () => "hidden",
60
- dropdownIndicator: ({ selectProps }: any) =>
61
- isCustomStyle
62
- ? selectProps.value
63
- ? "hidden"
64
- : "block"
65
- : `block text-icon-default ${hasError ? "text-icon-critical" : ""}`,
66
- singleValue: () =>
67
- cx(
68
- isCustomStyle
69
- ? "text-text text-body1 whitespace-normal"
70
- : "text-text-secondary"
71
- ),
72
- menu: () => "z-20 mt-2",
73
- option: ({ isFocused, isSelected, label }: any) =>
74
- cx(
75
- "min-h-[40px] px-4 py-2 cursor-pointer",
76
- isSelected
77
- ? "bg-gray-200 text-text font-semibold"
78
- : "bg-white text-text-secondary",
79
- !isSelected && "hover:bg-bg-surface-hover",
80
- !isSelected && isFocused && "bg-bg-surface-hover",
81
- isCustomStyle ? "text-body1 text-text" : "",
82
- !isCustomStyle || options[options.length - 1]?.label === label
83
- ? ""
84
- : "border-b border-border-brand"
85
- ),
86
- placeholder: () => "text-input-text-placeholder",
87
- input: () => "text-text",
88
- valueContainer: () => "px-0",
89
- }),
90
- [isCustomStyle, controlClassName, options, hasError, size]
91
- );
92
-
93
- if (variant === "unstyled") {
94
- return (
95
- <ReactSelect
96
- options={options}
97
- value={value}
98
- placeholder={required ? `${placeholder}*` : placeholder}
99
- onChange={onChange}
100
- filterOption={memoizedFilterOption}
101
- className={cx("rounded-xl", className)}
102
- classNames={memoizedClassNames}
103
- data-cy={dataCy}
104
- data-testid={dataTestId}
105
- {...rest}
106
- />
107
- );
108
- }
109
-
110
- return (
111
- <div className="w-full">
112
- {label && (
113
- <label
114
- className={cx(
115
- "mb-1 block text-sm font-medium text-text-secondary",
116
- labelClassName
117
- )}
118
- >
119
- {label}
120
- </label>
121
- )}
122
-
123
- <ReactSelect
124
- options={options}
125
- value={value}
126
- placeholder={required ? `${placeholder}*` : placeholder}
127
- onChange={onChange}
128
- filterOption={memoizedFilterOption}
129
- className={cx("rounded-xl", className)}
130
- classNames={memoizedClassNames}
131
- data-cy={dataCy}
132
- data-testid={dataTestId}
133
- {...rest}
134
- />
135
-
136
- {error && (
137
- <Text className="footnote mt-1 text-text-critical">{error}</Text>
138
- )}
139
-
140
- {!error && helperText && (
141
- <Text className="footnote mt-1 text-text-info">{helperText}</Text>
142
- )}
143
- </div>
144
- );
145
- }
146
- );
147
-
148
- Select.displayName = "Select";
149
-
150
- export type { SelectOption, SelectProps, FilterOptions };
1
+ "use client";
2
+
3
+ import React, { useMemo } from "react";
4
+ import { cx } from "../../utils";
5
+ import { Text } from "../text";
6
+ import { FilterOptions, SelectOption, SelectProps } from "./types";
7
+ import ReactSelect, { createFilter } from "react-select";
8
+
9
+ export const Select: React.FC<SelectProps> = React.memo(
10
+ ({
11
+ options,
12
+ className,
13
+ controlClassName,
14
+ value,
15
+ isCustomStyle = false,
16
+ placeholder,
17
+ required,
18
+ onChange,
19
+ filterOptions,
20
+ hasError,
21
+ error,
22
+ helperText,
23
+ label,
24
+ labelClassName,
25
+ size = "md",
26
+ variant = "default",
27
+ "data-cy": dataCy,
28
+ "data-testid": dataTestId,
29
+ ...rest
30
+ }) => {
31
+ const memoizedFilterOption = useMemo(
32
+ () => createFilter(filterOptions),
33
+ [filterOptions]
34
+ );
35
+
36
+ const getSizeClasses = () => {
37
+ switch (size) {
38
+ case "sm":
39
+ return "h-[48px] px-3 rounded-lg";
40
+ case "md":
41
+ default:
42
+ return "h-[56px] px-3 rounded-xl";
43
+ }
44
+ };
45
+
46
+ const memoizedClassNames = useMemo(
47
+ () => ({
48
+ control: ({ isFocused }: any) =>
49
+ cx(
50
+ getSizeClasses(),
51
+ "border border-input-border bg-white hover:not-focus:border-input-border-hover",
52
+ {
53
+ "border-input-border-selected outline outline-2 outline-input-border-selected":
54
+ isFocused && !hasError,
55
+ "border-input-border-critical shadow-none": hasError,
56
+ },
57
+ controlClassName
58
+ ),
59
+ indicatorSeparator: () => "hidden",
60
+ dropdownIndicator: ({ selectProps }: any) =>
61
+ isCustomStyle
62
+ ? selectProps.value
63
+ ? "hidden"
64
+ : "block"
65
+ : `block text-icon-default ${hasError ? "text-icon-critical" : ""}`,
66
+ singleValue: () =>
67
+ cx(
68
+ isCustomStyle
69
+ ? "text-text text-body1 whitespace-normal"
70
+ : "text-text-secondary"
71
+ ),
72
+ menu: () => "z-20 mt-2",
73
+ option: ({ isFocused, isSelected, label }: any) =>
74
+ cx(
75
+ "min-h-[40px] px-4 py-2 cursor-pointer",
76
+ isSelected
77
+ ? "bg-gray-200 text-text font-semibold"
78
+ : "bg-white text-text-secondary",
79
+ !isSelected && "hover:bg-bg-surface-hover",
80
+ !isSelected && isFocused && "bg-bg-surface-hover",
81
+ isCustomStyle ? "text-body1 text-text" : "",
82
+ !isCustomStyle || options[options.length - 1]?.label === label
83
+ ? ""
84
+ : "border-b border-border-brand"
85
+ ),
86
+ placeholder: () => "text-input-text-placeholder",
87
+ input: () => "text-text",
88
+ valueContainer: () => "px-0",
89
+ }),
90
+ [isCustomStyle, controlClassName, options, hasError, size]
91
+ );
92
+
93
+ if (variant === "unstyled") {
94
+ return (
95
+ <ReactSelect
96
+ options={options}
97
+ value={value}
98
+ placeholder={required ? `${placeholder}*` : placeholder}
99
+ onChange={onChange}
100
+ filterOption={memoizedFilterOption}
101
+ className={cx("rounded-xl", className)}
102
+ classNames={memoizedClassNames}
103
+ data-cy={dataCy}
104
+ data-testid={dataTestId}
105
+ {...rest}
106
+ />
107
+ );
108
+ }
109
+
110
+ return (
111
+ <div className="w-full">
112
+ {label && (
113
+ <label
114
+ className={cx(
115
+ "mb-1 block text-sm font-medium text-text-secondary",
116
+ labelClassName
117
+ )}
118
+ >
119
+ {label}
120
+ </label>
121
+ )}
122
+
123
+ <ReactSelect
124
+ options={options}
125
+ value={value}
126
+ placeholder={required ? `${placeholder}*` : placeholder}
127
+ onChange={onChange}
128
+ filterOption={memoizedFilterOption}
129
+ className={cx("rounded-xl", className)}
130
+ classNames={memoizedClassNames}
131
+ data-cy={dataCy}
132
+ data-testid={dataTestId}
133
+ {...rest}
134
+ />
135
+
136
+ {error && (
137
+ <Text className="footnote mt-1 text-text-critical">{error}</Text>
138
+ )}
139
+
140
+ {!error && helperText && (
141
+ <Text className="footnote mt-1 text-text-info">{helperText}</Text>
142
+ )}
143
+ </div>
144
+ );
145
+ }
146
+ );
147
+
148
+ Select.displayName = "Select";
149
+
150
+ export type { SelectOption, SelectProps, FilterOptions };
@@ -1,61 +1,61 @@
1
- import { FC } from "react";
2
- import { SkeletonProps } from "./types";
3
-
4
- export const Skeleton: FC<SkeletonProps> = ({ className = "", count = 1 }) => {
5
- return (
6
- <div className="animate-pulse space-y-4">
7
- {Array.from({ length: count }).map((_, index) => (
8
- <div
9
- key={index}
10
- className={`h-8 rounded bg-skeleton-bg-start ${className}`}
11
- style={{ opacity: 1 - index * 0.1 }}
12
- />
13
- ))}
14
- </div>
15
- );
16
- };
17
-
18
- Skeleton.displayName = "Skeleton";
19
-
20
- export type { SkeletonProps };
21
-
22
- export const PageSkeleton: FC = () => {
23
- return (
24
- <div
25
- className="item-center mx-auto mt-4 flex animate-pulse flex-col justify-center gap-10 px-1 md:max-w-[48.375rem] md:gap-16 md:px-0"
26
- data-testid="generic-skeleton"
27
- >
28
- {/* Title */}
29
- <div
30
- className="h-12 w-full rounded-lg bg-skeleton-bg-start"
31
- data-testid="title"
32
- />
33
-
34
- {/* Subtitle */}
35
- <div className="item-center flex flex-col gap-6" data-testid="subtitle">
36
- <div className="h-5 w-full rounded-lg bg-skeleton-bg-start" />
37
- <div className="h-5 w-full rounded-lg bg-skeleton-bg-start" />
38
- </div>
39
-
40
- {/* Content */}
41
- <div className="item-center flex flex-col gap-3" data-testid="content">
42
- <div className="h-12 w-full rounded-lg bg-skeleton-bg-start" />
43
- <div className="h-12 w-full rounded-lg bg-skeleton-bg-start" />
44
- </div>
45
-
46
- {/* Additional Information */}
47
- <div
48
- className="item-center flex flex-col gap-6"
49
- data-testid="additional-info"
50
- >
51
- <div className="h-5 w-full rounded-lg bg-skeleton-bg-end" />
52
- <div className="h-5 w-full rounded-lg bg-skeleton-bg-end" />
53
- </div>
54
-
55
- {/* CTA button */}
56
- <div className="item-center flex justify-center" data-testid="cta-button">
57
- <div className="h-12 w-full rounded-lg bg-skeleton-bg-end md:w-[22.125rem]" />
58
- </div>
59
- </div>
60
- );
61
- };
1
+ import { FC } from "react";
2
+ import { SkeletonProps } from "./types";
3
+
4
+ export const Skeleton: FC<SkeletonProps> = ({ className = "", count = 1 }) => {
5
+ return (
6
+ <div className="animate-pulse space-y-4">
7
+ {Array.from({ length: count }).map((_, index) => (
8
+ <div
9
+ key={index}
10
+ className={`h-8 rounded bg-skeleton-bg-start ${className}`}
11
+ style={{ opacity: 1 - index * 0.1 }}
12
+ />
13
+ ))}
14
+ </div>
15
+ );
16
+ };
17
+
18
+ Skeleton.displayName = "Skeleton";
19
+
20
+ export type { SkeletonProps };
21
+
22
+ export const PageSkeleton: FC = () => {
23
+ return (
24
+ <div
25
+ className="item-center mx-auto mt-4 flex animate-pulse flex-col justify-center gap-10 px-1 md:max-w-[48.375rem] md:gap-16 md:px-0"
26
+ data-testid="generic-skeleton"
27
+ >
28
+ {/* Title */}
29
+ <div
30
+ className="h-12 w-full rounded-lg bg-skeleton-bg-start"
31
+ data-testid="title"
32
+ />
33
+
34
+ {/* Subtitle */}
35
+ <div className="item-center flex flex-col gap-6" data-testid="subtitle">
36
+ <div className="h-5 w-full rounded-lg bg-skeleton-bg-start" />
37
+ <div className="h-5 w-full rounded-lg bg-skeleton-bg-start" />
38
+ </div>
39
+
40
+ {/* Content */}
41
+ <div className="item-center flex flex-col gap-3" data-testid="content">
42
+ <div className="h-12 w-full rounded-lg bg-skeleton-bg-start" />
43
+ <div className="h-12 w-full rounded-lg bg-skeleton-bg-start" />
44
+ </div>
45
+
46
+ {/* Additional Information */}
47
+ <div
48
+ className="item-center flex flex-col gap-6"
49
+ data-testid="additional-info"
50
+ >
51
+ <div className="h-5 w-full rounded-lg bg-skeleton-bg-end" />
52
+ <div className="h-5 w-full rounded-lg bg-skeleton-bg-end" />
53
+ </div>
54
+
55
+ {/* CTA button */}
56
+ <div className="item-center flex justify-center" data-testid="cta-button">
57
+ <div className="h-12 w-full rounded-lg bg-skeleton-bg-end md:w-[22.125rem]" />
58
+ </div>
59
+ </div>
60
+ );
61
+ };
@@ -1,25 +1,25 @@
1
- "use client";
2
-
3
- import React, { forwardRef } from "react";
4
- import { TextProps, TextVariant } from "./types";
5
-
6
- export const Text = forwardRef<HTMLElement, TextProps>(
7
- ({ children, as, className = "", style, ...props }, ref) => {
8
- const elementType = as || "p";
9
-
10
- return React.createElement(
11
- elementType,
12
- {
13
- ref,
14
- className,
15
- style,
16
- ...props,
17
- },
18
- children
19
- );
20
- }
21
- );
22
-
23
- Text.displayName = "Text";
24
-
25
- export type { TextProps, TextVariant };
1
+ "use client";
2
+
3
+ import React, { forwardRef } from "react";
4
+ import { TextProps, TextVariant } from "./types";
5
+
6
+ export const Text = forwardRef<HTMLElement, TextProps>(
7
+ ({ children, as, className = "", style, ...props }, ref) => {
8
+ const elementType = as || "p";
9
+
10
+ return React.createElement(
11
+ elementType,
12
+ {
13
+ ref,
14
+ className,
15
+ style,
16
+ ...props,
17
+ },
18
+ children
19
+ );
20
+ }
21
+ );
22
+
23
+ Text.displayName = "Text";
24
+
25
+ export type { TextProps, TextVariant };
@@ -1,45 +1,45 @@
1
- import { type CSSProperties, type HTMLAttributes, type ReactNode } from "react";
2
-
3
- export type TextVariant =
4
- | "heading1"
5
- | "heading2"
6
- | "heading3"
7
- | "heading4"
8
- | "heading5"
9
- | "heading6"
10
- | "subheading1"
11
- | "subheading2"
12
- | "subheading3"
13
- | "subheading4"
14
- | "subheading5"
15
- | "subheading6"
16
- | "body1"
17
- | "body2"
18
- | "body3"
19
- | "footnote"
20
- | "micro"
21
- | "label1"
22
- | "label2"
23
- | "label3"
24
- | "label4"
25
- | "error"
26
- | "unstyled";
27
- export type TextWeight =
28
- | "thin"
29
- | "normal"
30
- | "medium"
31
- | "semibold"
32
- | "bold"
33
- | "extrabold"
34
- | "black"
35
- | undefined;
36
- export interface TextProps extends HTMLAttributes<HTMLElement> {
37
- /** Content to render inside the text element */
38
- children?: ReactNode;
39
- /** Custom HTML element to render as */
40
- as?: keyof import("react").JSX.IntrinsicElements;
41
- /** Custom className for the text */
42
- className?: string;
43
- /** Custom styles */
44
- style?: CSSProperties;
45
- }
1
+ import { type CSSProperties, type HTMLAttributes, type ReactNode } from "react";
2
+
3
+ export type TextVariant =
4
+ | "heading1"
5
+ | "heading2"
6
+ | "heading3"
7
+ | "heading4"
8
+ | "heading5"
9
+ | "heading6"
10
+ | "subheading1"
11
+ | "subheading2"
12
+ | "subheading3"
13
+ | "subheading4"
14
+ | "subheading5"
15
+ | "subheading6"
16
+ | "body1"
17
+ | "body2"
18
+ | "body3"
19
+ | "footnote"
20
+ | "micro"
21
+ | "label1"
22
+ | "label2"
23
+ | "label3"
24
+ | "label4"
25
+ | "error"
26
+ | "unstyled";
27
+ export type TextWeight =
28
+ | "thin"
29
+ | "normal"
30
+ | "medium"
31
+ | "semibold"
32
+ | "bold"
33
+ | "extrabold"
34
+ | "black"
35
+ | undefined;
36
+ export interface TextProps extends HTMLAttributes<HTMLElement> {
37
+ /** Content to render inside the text element */
38
+ children?: ReactNode;
39
+ /** Custom HTML element to render as */
40
+ as?: keyof import("react").JSX.IntrinsicElements;
41
+ /** Custom className for the text */
42
+ className?: string;
43
+ /** Custom styles */
44
+ style?: CSSProperties;
45
+ }
@@ -1,29 +1,29 @@
1
- import { Accordion } from "./index";
2
-
3
- import { DocsPage } from "@shared/stories/DocsTemplate";
4
- import type { Meta, StoryObj } from "@storybook/react";
5
-
6
- const meta: Meta<typeof Accordion> = {
7
- title: "Contentful Blocks/Accordion",
8
- component: Accordion,
9
- tags: ["autodocs"],
10
- parameters: {
11
- layout: "centered",
12
- docs: {
13
- page: DocsPage,
14
- description: {
15
- component: "Contentful accordion block.",
16
- },
17
- },
18
- },
19
- args: {
20
- background: "white",
21
- enableHeading: false,
22
- items: [],
23
- maxWidth: true,
24
- title: "test",
25
- },
26
- };
27
- export default meta;
28
- type Story = StoryObj<typeof meta>;
29
- export const Default: Story = {};
1
+ import { Accordion } from "./index";
2
+
3
+ import { DocsPage } from "@shared/stories/DocsTemplate";
4
+ import type { Meta, StoryObj } from "@storybook/react";
5
+
6
+ const meta: Meta<typeof Accordion> = {
7
+ title: "Contentful Blocks/Accordion",
8
+ component: Accordion,
9
+ tags: ["autodocs"],
10
+ parameters: {
11
+ layout: "centered",
12
+ docs: {
13
+ page: DocsPage,
14
+ description: {
15
+ component: "Contentful accordion block.",
16
+ },
17
+ },
18
+ },
19
+ args: {
20
+ background: "white",
21
+ enableHeading: false,
22
+ items: [],
23
+ maxWidth: true,
24
+ title: "test",
25
+ },
26
+ };
27
+ export default meta;
28
+ type Story = StoryObj<typeof meta>;
29
+ export const Default: Story = {};