@windstream/react-shared-components 0.1.25 → 0.1.27

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 (160) hide show
  1. package/README.md +635 -635
  2. package/dist/contentful/index.d.ts +5 -1
  3. package/dist/contentful/index.esm.js +2 -2
  4. package/dist/contentful/index.esm.js.map +1 -1
  5. package/dist/contentful/index.js +2 -2
  6. package/dist/contentful/index.js.map +1 -1
  7. package/dist/index.d.ts +4 -4
  8. package/dist/index.js.map +1 -1
  9. package/dist/styles.css +1 -1
  10. package/package.json +182 -182
  11. package/src/components/accordion/Accordion.stories.tsx +230 -230
  12. package/src/components/accordion/types.ts +11 -11
  13. package/src/components/alert-card/AlertCard.stories.tsx +171 -171
  14. package/src/components/alert-card/index.tsx +41 -41
  15. package/src/components/alert-card/types.ts +13 -13
  16. package/src/components/brand-button/BrandButton.stories.tsx +223 -223
  17. package/src/components/brand-button/helpers.ts +35 -35
  18. package/src/components/brand-button/index.tsx +115 -115
  19. package/src/components/brand-button/types.ts +37 -37
  20. package/src/components/button/Button.stories.tsx +108 -108
  21. package/src/components/button/index.tsx +27 -27
  22. package/src/components/button/types.ts +14 -14
  23. package/src/components/call-button/CallButton.stories.tsx +324 -324
  24. package/src/components/call-button/index.tsx +86 -86
  25. package/src/components/call-button/types.ts +11 -11
  26. package/src/components/checkbox/Checkbox.stories.tsx +247 -247
  27. package/src/components/checkbox/index.tsx +197 -197
  28. package/src/components/checkbox/types.ts +27 -27
  29. package/src/components/checklist/Checklist.stories.tsx +150 -150
  30. package/src/components/checklist/index.tsx +59 -59
  31. package/src/components/checklist/types.ts +16 -16
  32. package/src/components/collapse/Collapse.stories.tsx +255 -255
  33. package/src/components/collapse/index.tsx +46 -46
  34. package/src/components/collapse/types.ts +6 -6
  35. package/src/components/divider/Divider.stories.tsx +205 -205
  36. package/src/components/divider/index.tsx +22 -22
  37. package/src/components/divider/type.ts +3 -3
  38. package/src/components/image/Image.stories.tsx +113 -113
  39. package/src/components/image/index.tsx +25 -25
  40. package/src/components/image/types.ts +40 -40
  41. package/src/components/input/Input.stories.tsx +325 -325
  42. package/src/components/input/index.tsx +177 -177
  43. package/src/components/input/types.ts +37 -37
  44. package/src/components/link/Link.stories.tsx +163 -163
  45. package/src/components/link/types.ts +25 -25
  46. package/src/components/list/List.stories.tsx +272 -272
  47. package/src/components/list/index.tsx +88 -88
  48. package/src/components/list/list-item/index.tsx +38 -38
  49. package/src/components/list/list-item/types.ts +13 -13
  50. package/src/components/list/types.ts +29 -29
  51. package/src/components/material-icon/MaterialIcon.stories.tsx +322 -322
  52. package/src/components/material-icon/constants.ts +98 -98
  53. package/src/components/material-icon/index.tsx +47 -47
  54. package/src/components/material-icon/types.ts +31 -31
  55. package/src/components/modal/Modal.stories.tsx +171 -171
  56. package/src/components/modal/index.tsx +164 -164
  57. package/src/components/modal/types.ts +24 -24
  58. package/src/components/next-image/index.tsx +54 -54
  59. package/src/components/next-image/types.ts +1 -1
  60. package/src/components/pagination/index.tsx +100 -100
  61. package/src/components/pagination/types.ts +6 -6
  62. package/src/components/radio-button/RadioButton.stories.tsx +307 -307
  63. package/src/components/radio-button/index.tsx +75 -75
  64. package/src/components/radio-button/types.ts +21 -21
  65. package/src/components/see-more/SeeMore.stories.tsx +181 -181
  66. package/src/components/see-more/index.tsx +44 -44
  67. package/src/components/see-more/types.ts +4 -4
  68. package/src/components/select/Select.stories.tsx +411 -411
  69. package/src/components/select/index.tsx +155 -155
  70. package/src/components/select/types.ts +36 -36
  71. package/src/components/select-plan-button/SelectPlanButton.stories.tsx +184 -184
  72. package/src/components/select-plan-button/index.tsx +57 -57
  73. package/src/components/select-plan-button/types.ts +14 -14
  74. package/src/components/skeleton/Skeleton.stories.tsx +179 -179
  75. package/src/components/skeleton/index.tsx +61 -61
  76. package/src/components/skeleton/types.ts +4 -4
  77. package/src/components/spinner/Spinner.stories.tsx +335 -335
  78. package/src/components/spinner/index.tsx +44 -44
  79. package/src/components/spinner/types.ts +5 -5
  80. package/src/components/text/Text.stories.tsx +321 -321
  81. package/src/components/text/index.tsx +25 -25
  82. package/src/components/text/types.ts +45 -45
  83. package/src/components/tooltip/Tooltip.stories.tsx +219 -219
  84. package/src/components/tooltip/index.tsx +74 -74
  85. package/src/components/tooltip/types.ts +7 -7
  86. package/src/components/view-cart-button/ViewCartButton.stories.tsx +252 -252
  87. package/src/components/view-cart-button/index.tsx +42 -42
  88. package/src/components/view-cart-button/types.ts +5 -5
  89. package/src/contentful/blocks/address-input-banner/index.tsx +52 -52
  90. package/src/contentful/blocks/address-input-banner/types.ts +14 -14
  91. package/src/contentful/blocks/blogs-grid/index.tsx +134 -134
  92. package/src/contentful/blocks/blogs-grid/types.ts +26 -26
  93. package/src/contentful/blocks/button/Button.stories.tsx +40 -40
  94. package/src/contentful/blocks/button/index.tsx +121 -121
  95. package/src/contentful/blocks/button/types.ts +36 -36
  96. package/src/contentful/blocks/callout/Callout.stories.tsx +23 -23
  97. package/src/contentful/blocks/callout/index.tsx +86 -86
  98. package/src/contentful/blocks/callout/types.ts +15 -15
  99. package/src/contentful/blocks/cards/Cards.stories.tsx +23 -23
  100. package/src/contentful/blocks/cards/blog-card/index.tsx +109 -109
  101. package/src/contentful/blocks/cards/blog-card/types.ts +16 -16
  102. package/src/contentful/blocks/cards/index.tsx +13 -13
  103. package/src/contentful/blocks/cards/product-card/index.tsx +208 -208
  104. package/src/contentful/blocks/cards/product-card/types.ts +28 -28
  105. package/src/contentful/blocks/cards/simple-card/index.tsx +1 -1
  106. package/src/contentful/blocks/cards/testimonial-card/index.tsx +88 -88
  107. package/src/contentful/blocks/cards/testimonial-card/types.tsx +12 -12
  108. package/src/contentful/blocks/cards/types.ts +1 -1
  109. package/src/contentful/blocks/carousel/Carousel.stories.tsx +23 -23
  110. package/src/contentful/blocks/carousel/helper.tsx +356 -356
  111. package/src/contentful/blocks/carousel/index.tsx +73 -73
  112. package/src/contentful/blocks/carousel/types.ts +143 -143
  113. package/src/contentful/blocks/cta-callout/CtaCallout.stories.tsx +46 -46
  114. package/src/contentful/blocks/cta-callout/index.tsx +60 -60
  115. package/src/contentful/blocks/cta-callout/types.ts +26 -26
  116. package/src/contentful/blocks/dynamic-tabs/index.tsx +204 -204
  117. package/src/contentful/blocks/dynamic-tabs/types.ts +21 -21
  118. package/src/contentful/blocks/find-kinetic/index.tsx +130 -130
  119. package/src/contentful/blocks/floating-banner/FloatingBanner.stories.tsx +34 -34
  120. package/src/contentful/blocks/floating-banner/index.tsx +93 -97
  121. package/src/contentful/blocks/floating-banner/types.ts +22 -22
  122. package/src/contentful/blocks/footer/Footer.stories.tsx +30 -30
  123. package/src/contentful/blocks/footer/index.tsx +6 -12
  124. package/src/contentful/blocks/image-promo-bar/ImagePromoBar.stories.tsx +23 -23
  125. package/src/contentful/blocks/image-promo-bar/helper.tsx +28 -28
  126. package/src/contentful/blocks/image-promo-bar/types.ts +44 -44
  127. package/src/contentful/blocks/image-promo-bar/vimeo-embed.tsx +93 -93
  128. package/src/contentful/blocks/image-promo-bar/youtube-embed.tsx +46 -46
  129. package/src/contentful/blocks/modal/constants.ts +53 -53
  130. package/src/contentful/blocks/modal/index.tsx +99 -94
  131. package/src/contentful/blocks/modal/types.ts +12 -12
  132. package/src/contentful/blocks/navigation/desktop-link-groups.tsx/index.tsx +113 -113
  133. package/src/contentful/blocks/navigation/index.tsx +394 -394
  134. package/src/contentful/blocks/navigation/mobile-link-groups.tsx/index.tsx +82 -82
  135. package/src/contentful/blocks/navigation/types.ts +41 -41
  136. package/src/contentful/blocks/primary-hero/PrimaryHero.stories.tsx +23 -23
  137. package/src/contentful/blocks/primary-hero/index.tsx +234 -234
  138. package/src/contentful/blocks/primary-hero/types.ts +35 -35
  139. package/src/contentful/blocks/search-block/index.tsx +90 -90
  140. package/src/contentful/blocks/shape-background-wrapper/ShapeBackgroundWrapper.stories.tsx +26 -26
  141. package/src/contentful/blocks/shape-background-wrapper/index.tsx +124 -124
  142. package/src/contentful/blocks/shape-background-wrapper/types.ts +36 -36
  143. package/src/contentful/blocks/text/Text.stories.tsx +23 -23
  144. package/src/contentful/blocks/text/index.tsx +12 -12
  145. package/src/contentful/blocks/text/types.ts +1 -1
  146. package/src/contentful/index.ts +75 -75
  147. package/src/hooks/use-body-scroll-lock.ts +34 -34
  148. package/src/hooks/use-outside-click.ts +17 -17
  149. package/src/index.ts +96 -96
  150. package/src/next/index.ts +5 -5
  151. package/src/setupTests.ts +46 -46
  152. package/src/stories/DocsTemplate.tsx +24 -24
  153. package/src/styles/globals.css +343 -343
  154. package/src/types/global.d.ts +9 -9
  155. package/src/types/micro-components.ts +99 -99
  156. package/src/types/utm.ts +49 -49
  157. package/src/utils/cookie.ts +58 -58
  158. package/src/utils/index.ts +65 -65
  159. package/src/utils/utm.ts +221 -221
  160. package/tailwind.config.cjs +1 -0
@@ -1,121 +1,121 @@
1
- import React from "react";
2
- import { ButtonProps } from "./types";
3
-
4
- import { BrandButton } from "@shared/components/brand-button";
5
- import { Button as CoreButton } from "@shared/components/button";
6
- import { Link } from "@shared/components/link";
7
- import { MaterialIcon } from "@shared/components/material-icon";
8
- import { buildPreservedQueryHref } from "@shared/utils/utm";
9
-
10
- export const Button: React.FC<ButtonProps> = props => {
11
- const {
12
- showButtonAs = "solid",
13
- buttonVariant = "primary_brand",
14
- buttonLabel,
15
- buttonPrefix,
16
- href,
17
- target = "_blank",
18
- anchorId,
19
- linkClassName,
20
- linkVariant,
21
- fullWidth,
22
- preDefinedFunctionExecution,
23
- renderCheckPlans,
24
- buttonClassName,
25
- clickToOpen,
26
- tabmodalNameToOpen,
27
- onModalButtonClick,
28
- onClick,
29
- iconName,
30
- size,
31
- preserveQueryParameters,
32
- ...rest
33
- } = props;
34
-
35
- if (preDefinedFunctionExecution === "check availability") {
36
- const checkPlansNode = renderCheckPlans?.({
37
- ctaText: buttonLabel,
38
- buttonVariant: buttonVariant,
39
- showButtonAs: showButtonAs,
40
- cta: { ...props },
41
- });
42
- return checkPlansNode;
43
- }
44
-
45
- function handleModalClick() {
46
- if (clickToOpen === "modal") {
47
- onModalButtonClick?.(tabmodalNameToOpen);
48
- }
49
- }
50
-
51
- function linkClick(event: React.MouseEvent<HTMLAnchorElement>) {
52
- handleModalClick();
53
- onClick?.(event);
54
- }
55
-
56
- function buttonClick(event: React.MouseEvent<HTMLButtonElement>) {
57
- handleModalClick();
58
- onClick?.(event);
59
- }
60
-
61
- // Resolve the final href — merge non-UTM query params when preserveQueryParameters is true
62
- const currentSearch =
63
- typeof window !== "undefined" ? window.location.search : "";
64
- const resolvedHref =
65
- href && preserveQueryParameters && currentSearch
66
- ? buildPreservedQueryHref(href, currentSearch)
67
- : href;
68
-
69
- let CTA = (
70
- <CoreButton onClick={buttonClick} className={buttonClassName} {...rest} />
71
- );
72
-
73
- switch (showButtonAs) {
74
- case "solid":
75
- CTA = resolvedHref ? (
76
- <BrandButton
77
- as="a"
78
- href={resolvedHref}
79
- id={anchorId}
80
- variant={buttonVariant}
81
- text={buttonLabel}
82
- label={buttonPrefix}
83
- fullWidth={fullWidth}
84
- size={size}
85
- onClick={linkClick}
86
- />
87
- ) : (
88
- <BrandButton
89
- id={anchorId}
90
- variant={buttonVariant}
91
- text={buttonLabel}
92
- label={buttonPrefix}
93
- fullWidth={fullWidth}
94
- size={size}
95
- onClick={buttonClick}
96
- />
97
- );
98
- break;
99
- case "text":
100
- CTA = (
101
- <Link
102
- href={resolvedHref}
103
- target={target}
104
- variant={linkVariant || "default"}
105
- className={`text-text-brand ${linkClassName || ""}`}
106
- onClick={linkClick}
107
- >
108
- {buttonLabel}{" "}
109
- {iconName && <MaterialIcon name={iconName as any} size={24} />}
110
- </Link>
111
- );
112
- break;
113
- case "unstyled": // For unstyled, we can use the CoreButton without any additional styling
114
- break;
115
- default: // For default, we can use the CoreButton without any additional styling
116
- break;
117
- }
118
-
119
- return CTA;
120
- };
121
- export default Button;
1
+ import React from "react";
2
+ import { ButtonProps } from "./types";
3
+
4
+ import { BrandButton } from "@shared/components/brand-button";
5
+ import { Button as CoreButton } from "@shared/components/button";
6
+ import { Link } from "@shared/components/link";
7
+ import { MaterialIcon } from "@shared/components/material-icon";
8
+ import { buildPreservedQueryHref } from "@shared/utils/utm";
9
+
10
+ export const Button: React.FC<ButtonProps> = props => {
11
+ const {
12
+ showButtonAs = "solid",
13
+ buttonVariant = "primary_brand",
14
+ buttonLabel,
15
+ buttonPrefix,
16
+ href,
17
+ target = "_blank",
18
+ anchorId,
19
+ linkClassName,
20
+ linkVariant,
21
+ fullWidth,
22
+ preDefinedFunctionExecution,
23
+ renderCheckPlans,
24
+ buttonClassName,
25
+ clickToOpen,
26
+ tabmodalNameToOpen,
27
+ onModalButtonClick,
28
+ onClick,
29
+ iconName,
30
+ size,
31
+ preserveQueryParameters,
32
+ ...rest
33
+ } = props;
34
+
35
+ if (preDefinedFunctionExecution === "check availability") {
36
+ const checkPlansNode = renderCheckPlans?.({
37
+ ctaText: buttonLabel,
38
+ buttonVariant: buttonVariant,
39
+ showButtonAs: showButtonAs,
40
+ cta: { ...props },
41
+ });
42
+ return checkPlansNode;
43
+ }
44
+
45
+ function handleModalClick() {
46
+ if (clickToOpen === "modal") {
47
+ onModalButtonClick?.(tabmodalNameToOpen);
48
+ }
49
+ }
50
+
51
+ function linkClick(event: React.MouseEvent<HTMLAnchorElement>) {
52
+ handleModalClick();
53
+ onClick?.(event);
54
+ }
55
+
56
+ function buttonClick(event: React.MouseEvent<HTMLButtonElement>) {
57
+ handleModalClick();
58
+ onClick?.(event);
59
+ }
60
+
61
+ // Resolve the final href — merge non-UTM query params when preserveQueryParameters is true
62
+ const currentSearch =
63
+ typeof window !== "undefined" ? window.location.search : "";
64
+ const resolvedHref =
65
+ href && preserveQueryParameters && currentSearch
66
+ ? buildPreservedQueryHref(href, currentSearch)
67
+ : href;
68
+
69
+ let CTA = (
70
+ <CoreButton onClick={buttonClick} className={buttonClassName} {...rest} />
71
+ );
72
+
73
+ switch (showButtonAs) {
74
+ case "solid":
75
+ CTA = resolvedHref ? (
76
+ <BrandButton
77
+ as="a"
78
+ href={resolvedHref}
79
+ id={anchorId}
80
+ variant={buttonVariant}
81
+ text={buttonLabel}
82
+ label={buttonPrefix}
83
+ fullWidth={fullWidth}
84
+ size={size}
85
+ onClick={linkClick}
86
+ />
87
+ ) : (
88
+ <BrandButton
89
+ id={anchorId}
90
+ variant={buttonVariant}
91
+ text={buttonLabel}
92
+ label={buttonPrefix}
93
+ fullWidth={fullWidth}
94
+ size={size}
95
+ onClick={buttonClick}
96
+ />
97
+ );
98
+ break;
99
+ case "text":
100
+ CTA = (
101
+ <Link
102
+ href={resolvedHref}
103
+ target={target}
104
+ variant={linkVariant || "default"}
105
+ className={`text-text-brand ${linkClassName || ""}`}
106
+ onClick={linkClick}
107
+ >
108
+ {buttonLabel}{" "}
109
+ {iconName && <MaterialIcon name={iconName as any} size={24} />}
110
+ </Link>
111
+ );
112
+ break;
113
+ case "unstyled": // For unstyled, we can use the CoreButton without any additional styling
114
+ break;
115
+ default: // For default, we can use the CoreButton without any additional styling
116
+ break;
117
+ }
118
+
119
+ return CTA;
120
+ };
121
+ export default Button;
@@ -1,36 +1,36 @@
1
- import React from "react";
2
-
3
- import { ResponsiveSize } from "@shared/components/brand-button/types";
4
- import { CheckPlansProps } from "@shared/types/micro-components";
5
-
6
- export type ButtonProps = {
7
- showButtonAs?: "solid" | "text" | "unstyled";
8
- buttonVariant?: "primary_brand" | "secondary" | "primary_inverse";
9
- buttonLabel?: string;
10
- buttonPrefix?: string;
11
- badge?: string;
12
- badgeIcon?: string;
13
- buttonIcon?: string;
14
- buttonIconPosition?: "left" | "right";
15
- href?: string;
16
- target?: "_self" | "_blank";
17
- anchorId?: string;
18
- preserveQueryParameters?: boolean;
19
- clickToOpen?: string;
20
- tabmodalNameToOpen?: string;
21
- preDefinedFunctionExecution?: string;
22
- renderCheckPlans?: (overrides?: CheckPlansProps) => React.ReactNode;
23
- linkClassName?: string;
24
- buttonClassName?: string;
25
- linkVariant?: "unstyled" | "default";
26
- fullWidth?: boolean;
27
- size?: ResponsiveSize;
28
- onClick?: (
29
- event: React.MouseEvent<HTMLAnchorElement | HTMLButtonElement>
30
- ) => void;
31
- children?: React.ReactNode;
32
- modalTitle?: string;
33
- modalSubtitle?: string;
34
- onModalButtonClick?: (id?: string) => void;
35
- iconName?: string;
36
- };
1
+ import React from "react";
2
+
3
+ import { ResponsiveSize } from "@shared/components/brand-button/types";
4
+ import { CheckPlansProps } from "@shared/types/micro-components";
5
+
6
+ export type ButtonProps = {
7
+ showButtonAs?: "solid" | "text" | "unstyled";
8
+ buttonVariant?: "primary_brand" | "secondary" | "primary_inverse";
9
+ buttonLabel?: string;
10
+ buttonPrefix?: string;
11
+ badge?: string;
12
+ badgeIcon?: string;
13
+ buttonIcon?: string;
14
+ buttonIconPosition?: "left" | "right";
15
+ href?: string;
16
+ target?: "_self" | "_blank";
17
+ anchorId?: string;
18
+ preserveQueryParameters?: boolean;
19
+ clickToOpen?: string;
20
+ tabmodalNameToOpen?: string;
21
+ preDefinedFunctionExecution?: string;
22
+ renderCheckPlans?: (overrides?: CheckPlansProps) => React.ReactNode;
23
+ linkClassName?: string;
24
+ buttonClassName?: string;
25
+ linkVariant?: "unstyled" | "default";
26
+ fullWidth?: boolean;
27
+ size?: ResponsiveSize;
28
+ onClick?: (
29
+ event: React.MouseEvent<HTMLAnchorElement | HTMLButtonElement>
30
+ ) => void;
31
+ children?: React.ReactNode;
32
+ modalTitle?: string;
33
+ modalSubtitle?: string;
34
+ onModalButtonClick?: (id?: string) => void;
35
+ iconName?: string;
36
+ };
@@ -1,23 +1,23 @@
1
- import { Callout } from "./index";
2
-
3
- import { DocsPage } from "@shared/stories/DocsTemplate";
4
- import type { Meta, StoryObj } from "@storybook/react";
5
-
6
- const meta: Meta<typeof Callout> = {
7
- title: "Contentful Blocks/Callout",
8
- component: Callout,
9
- tags: ["autodocs"],
10
- parameters: {
11
- layout: "centered",
12
- docs: {
13
- page: DocsPage,
14
- description: {
15
- component: "Contentful callout block.",
16
- },
17
- },
18
- },
19
- args: {},
20
- };
21
- export default meta;
22
- type Story = StoryObj<typeof meta>;
23
- export const Default: Story = {};
1
+ import { Callout } from "./index";
2
+
3
+ import { DocsPage } from "@shared/stories/DocsTemplate";
4
+ import type { Meta, StoryObj } from "@storybook/react";
5
+
6
+ const meta: Meta<typeof Callout> = {
7
+ title: "Contentful Blocks/Callout",
8
+ component: Callout,
9
+ tags: ["autodocs"],
10
+ parameters: {
11
+ layout: "centered",
12
+ docs: {
13
+ page: DocsPage,
14
+ description: {
15
+ component: "Contentful callout block.",
16
+ },
17
+ },
18
+ },
19
+ args: {},
20
+ };
21
+ export default meta;
22
+ type Story = StoryObj<typeof meta>;
23
+ export const Default: Story = {};
@@ -1,86 +1,86 @@
1
- import React from "react";
2
- import BlogCard from "../cards/blog-card";
3
- import SimpleCard from "../cards/simple-card";
4
- import { CalloutProps } from "./types";
5
-
6
- import { Text } from "@shared/components/text";
7
-
8
- export const Callout: React.FC<CalloutProps> = ({
9
- title,
10
- items,
11
- enableHeading = false,
12
- subtitle,
13
- color = "dark",
14
- maxWidth = true,
15
- maxCardsPerRow,
16
- cardType = "simple",
17
- }) => {
18
- const lgWidth =
19
- {
20
- 1: " lg:w-full",
21
- 2: " lg:w-[calc(50%-0.75rem)]",
22
- 3: " lg:w-[calc(33.3333%-1rem)]",
23
- 4: " lg:w-[calc(25%-1.125rem)]",
24
- }[maxCardsPerRow || 4] || " lg:w-[calc(25%-1.125rem)]";
25
-
26
- const mdWidth = items.length === 1 ? " md:w-full" : " md:w-[calc(50%-1rem)]";
27
-
28
- const renderCard = (item: CalloutProps["items"][number], index: number) => {
29
- if (cardType === "blog") {
30
- const blogItem = item as any;
31
- return (
32
- <BlogCard
33
- title={blogItem.title}
34
- href={blogItem.slug}
35
- description={blogItem.shortDescription}
36
- date={blogItem.blogCreationDate}
37
- category={blogItem.category}
38
- image={blogItem.cover}
39
- asGrid={false}
40
- />
41
- );
42
- }
43
- return (
44
- <SimpleCard
45
- key={index}
46
- card={item as any}
47
- lgWidth={lgWidth}
48
- mdWidth={mdWidth}
49
- />
50
- );
51
- };
52
-
53
- return (
54
- <div className="component-container">
55
- <div
56
- className={`mx-5 mb-5 mt-12 ${maxWidth ? "max-w-120 xl:mx-auto" : ""} ${color == "dark" ? "text-text" : "text-white"}`}
57
- >
58
- <div className="callout-container flex flex-col gap-8">
59
- <div className="title-holder">
60
- {title && (
61
- <Text
62
- as={enableHeading ? "h1" : "h2"}
63
- className="heading2 md:heading1 md:text-center"
64
- >
65
- {title}
66
- </Text>
67
- )}
68
- {subtitle && (
69
- <Text
70
- as={enableHeading ? "h2" : "h3"}
71
- className="subheading3 mt-3 md:subheading1 md:text-center"
72
- >
73
- {subtitle}
74
- </Text>
75
- )}
76
- </div>
77
- <div className="card-holder flex flex-wrap items-stretch justify-center gap-8 self-stretch lg:gap-6">
78
- {items.map((item, index: number) => renderCard(item, index))}
79
- </div>
80
- </div>
81
- </div>
82
- </div>
83
- );
84
- };
85
-
86
- export default Callout;
1
+ import React from "react";
2
+ import BlogCard from "../cards/blog-card";
3
+ import SimpleCard from "../cards/simple-card";
4
+ import { CalloutProps } from "./types";
5
+
6
+ import { Text } from "@shared/components/text";
7
+
8
+ export const Callout: React.FC<CalloutProps> = ({
9
+ title,
10
+ items,
11
+ enableHeading = false,
12
+ subtitle,
13
+ color = "dark",
14
+ maxWidth = true,
15
+ maxCardsPerRow,
16
+ cardType = "simple",
17
+ }) => {
18
+ const lgWidth =
19
+ {
20
+ 1: " lg:w-full",
21
+ 2: " lg:w-[calc(50%-0.75rem)]",
22
+ 3: " lg:w-[calc(33.3333%-1rem)]",
23
+ 4: " lg:w-[calc(25%-1.125rem)]",
24
+ }[maxCardsPerRow || 4] || " lg:w-[calc(25%-1.125rem)]";
25
+
26
+ const mdWidth = items.length === 1 ? " md:w-full" : " md:w-[calc(50%-1rem)]";
27
+
28
+ const renderCard = (item: CalloutProps["items"][number], index: number) => {
29
+ if (cardType === "blog") {
30
+ const blogItem = item as any;
31
+ return (
32
+ <BlogCard
33
+ title={blogItem.title}
34
+ href={blogItem.slug}
35
+ description={blogItem.shortDescription}
36
+ date={blogItem.blogCreationDate}
37
+ category={blogItem.category}
38
+ image={blogItem.cover}
39
+ asGrid={false}
40
+ />
41
+ );
42
+ }
43
+ return (
44
+ <SimpleCard
45
+ key={index}
46
+ card={item as any}
47
+ lgWidth={lgWidth}
48
+ mdWidth={mdWidth}
49
+ />
50
+ );
51
+ };
52
+
53
+ return (
54
+ <div className="component-container">
55
+ <div
56
+ className={`mx-5 mb-5 mt-12 ${maxWidth ? "max-w-120 xl:mx-auto" : ""} ${color == "dark" ? "text-text" : "text-white"}`}
57
+ >
58
+ <div className="callout-container flex flex-col gap-16">
59
+ <div className="title-holder">
60
+ {title && (
61
+ <Text
62
+ as={enableHeading ? "h1" : "h2"}
63
+ className="heading2 md:heading1 md:text-center"
64
+ >
65
+ {title}
66
+ </Text>
67
+ )}
68
+ {subtitle && (
69
+ <Text
70
+ as={enableHeading ? "h2" : "h3"}
71
+ className="subheading3 mt-3 md:subheading1 md:text-center"
72
+ >
73
+ {subtitle}
74
+ </Text>
75
+ )}
76
+ </div>
77
+ <div className="card-holder flex flex-wrap items-stretch justify-center gap-5 self-stretch md:gap-6">
78
+ {items.map((item, index: number) => renderCard(item, index))}
79
+ </div>
80
+ </div>
81
+ </div>
82
+ </div>
83
+ );
84
+ };
85
+
86
+ export default Callout;
@@ -1,15 +1,15 @@
1
- export type CalloutProps = {
2
- title?: string;
3
- enableHeading?: boolean;
4
- subtitle?: string;
5
- applyBoxShadow?: boolean;
6
- cardStackingMobile?: boolean;
7
- bottomText?: string;
8
- color?: "dark" | "light";
9
- cardsWidth?: string;
10
- maxCardsPerRow?: number;
11
- noGutter?: boolean;
12
- items: any[];
13
- maxWidth?: boolean;
14
- cardType?: "simple" | "blog";
15
- };
1
+ export type CalloutProps = {
2
+ title?: string;
3
+ enableHeading?: boolean;
4
+ subtitle?: string;
5
+ applyBoxShadow?: boolean;
6
+ cardStackingMobile?: boolean;
7
+ bottomText?: string;
8
+ color?: "dark" | "light";
9
+ cardsWidth?: string;
10
+ maxCardsPerRow?: number;
11
+ noGutter?: boolean;
12
+ items: any[];
13
+ maxWidth?: boolean;
14
+ cardType?: "simple" | "blog";
15
+ };
@@ -1,23 +1,23 @@
1
- import { Cards } from "./index";
2
-
3
- import { DocsPage } from "@shared/stories/DocsTemplate";
4
- import type { Meta, StoryObj } from "@storybook/react";
5
-
6
- const meta: Meta<typeof Cards> = {
7
- title: "Contentful Blocks/Cards",
8
- component: Cards,
9
- tags: ["autodocs"],
10
- parameters: {
11
- layout: "centered",
12
- docs: {
13
- page: DocsPage,
14
- description: {
15
- component: "Contentful cards block.",
16
- },
17
- },
18
- },
19
- args: { fields: {} },
20
- };
21
- export default meta;
22
- type Story = StoryObj<typeof meta>;
23
- export const Default: Story = {};
1
+ import { Cards } from "./index";
2
+
3
+ import { DocsPage } from "@shared/stories/DocsTemplate";
4
+ import type { Meta, StoryObj } from "@storybook/react";
5
+
6
+ const meta: Meta<typeof Cards> = {
7
+ title: "Contentful Blocks/Cards",
8
+ component: Cards,
9
+ tags: ["autodocs"],
10
+ parameters: {
11
+ layout: "centered",
12
+ docs: {
13
+ page: DocsPage,
14
+ description: {
15
+ component: "Contentful cards block.",
16
+ },
17
+ },
18
+ },
19
+ args: { fields: {} },
20
+ };
21
+ export default meta;
22
+ type Story = StoryObj<typeof meta>;
23
+ export const Default: Story = {};