@windstream/react-shared-components 0.1.20 → 0.1.22

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 (161) hide show
  1. package/README.md +635 -635
  2. package/dist/contentful/index.d.ts +1 -0
  3. package/dist/contentful/index.esm.js +3 -3
  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/core.d.ts +5 -2
  8. package/dist/index.d.ts +5 -2
  9. package/dist/index.esm.js +6 -6
  10. package/dist/index.esm.js.map +1 -1
  11. package/dist/index.js +6 -6
  12. package/dist/index.js.map +1 -1
  13. package/package.json +182 -182
  14. package/src/components/accordion/Accordion.stories.tsx +230 -230
  15. package/src/components/accordion/types.ts +11 -11
  16. package/src/components/alert-card/AlertCard.stories.tsx +171 -171
  17. package/src/components/alert-card/index.tsx +41 -41
  18. package/src/components/alert-card/types.ts +13 -13
  19. package/src/components/brand-button/BrandButton.stories.tsx +223 -223
  20. package/src/components/brand-button/helpers.ts +35 -35
  21. package/src/components/brand-button/index.tsx +115 -115
  22. package/src/components/brand-button/types.ts +37 -37
  23. package/src/components/button/Button.stories.tsx +108 -108
  24. package/src/components/button/index.tsx +27 -27
  25. package/src/components/button/types.ts +14 -14
  26. package/src/components/call-button/CallButton.stories.tsx +324 -324
  27. package/src/components/call-button/index.tsx +86 -86
  28. package/src/components/call-button/types.ts +11 -11
  29. package/src/components/checkbox/Checkbox.stories.tsx +247 -247
  30. package/src/components/checkbox/index.tsx +197 -197
  31. package/src/components/checkbox/types.ts +27 -27
  32. package/src/components/checklist/Checklist.stories.tsx +150 -150
  33. package/src/components/checklist/index.tsx +59 -59
  34. package/src/components/checklist/types.ts +16 -16
  35. package/src/components/collapse/Collapse.stories.tsx +255 -255
  36. package/src/components/collapse/index.tsx +46 -46
  37. package/src/components/collapse/types.ts +6 -6
  38. package/src/components/divider/Divider.stories.tsx +205 -205
  39. package/src/components/divider/index.tsx +22 -22
  40. package/src/components/divider/type.ts +3 -3
  41. package/src/components/image/Image.stories.tsx +113 -113
  42. package/src/components/image/index.tsx +25 -25
  43. package/src/components/image/types.ts +40 -40
  44. package/src/components/input/Input.stories.tsx +325 -325
  45. package/src/components/input/index.tsx +177 -177
  46. package/src/components/input/types.ts +37 -37
  47. package/src/components/link/Link.stories.tsx +163 -163
  48. package/src/components/link/index.tsx +14 -2
  49. package/src/components/link/types.ts +25 -25
  50. package/src/components/list/List.stories.tsx +272 -272
  51. package/src/components/list/index.tsx +88 -88
  52. package/src/components/list/list-item/index.tsx +38 -38
  53. package/src/components/list/list-item/types.ts +13 -13
  54. package/src/components/list/types.ts +29 -29
  55. package/src/components/material-icon/MaterialIcon.stories.tsx +322 -322
  56. package/src/components/material-icon/constants.ts +98 -98
  57. package/src/components/material-icon/index.tsx +47 -47
  58. package/src/components/material-icon/types.ts +31 -31
  59. package/src/components/modal/Modal.stories.tsx +171 -171
  60. package/src/components/modal/index.tsx +38 -31
  61. package/src/components/modal/types.ts +24 -24
  62. package/src/components/next-image/index.tsx +54 -54
  63. package/src/components/next-image/types.ts +1 -1
  64. package/src/components/pagination/index.tsx +100 -100
  65. package/src/components/pagination/types.ts +6 -6
  66. package/src/components/radio-button/RadioButton.stories.tsx +307 -307
  67. package/src/components/radio-button/index.tsx +75 -75
  68. package/src/components/radio-button/types.ts +21 -21
  69. package/src/components/see-more/SeeMore.stories.tsx +181 -181
  70. package/src/components/see-more/index.tsx +44 -44
  71. package/src/components/see-more/types.ts +4 -4
  72. package/src/components/select/Select.stories.tsx +411 -411
  73. package/src/components/select/index.tsx +155 -155
  74. package/src/components/select/types.ts +36 -36
  75. package/src/components/select-plan-button/SelectPlanButton.stories.tsx +184 -184
  76. package/src/components/select-plan-button/index.tsx +57 -57
  77. package/src/components/select-plan-button/types.ts +14 -14
  78. package/src/components/skeleton/Skeleton.stories.tsx +179 -179
  79. package/src/components/skeleton/index.tsx +61 -61
  80. package/src/components/skeleton/types.ts +4 -4
  81. package/src/components/spinner/Spinner.stories.tsx +335 -335
  82. package/src/components/spinner/index.tsx +44 -44
  83. package/src/components/spinner/types.ts +5 -5
  84. package/src/components/text/Text.stories.tsx +321 -321
  85. package/src/components/text/index.tsx +25 -25
  86. package/src/components/text/types.ts +45 -45
  87. package/src/components/tooltip/Tooltip.stories.tsx +219 -219
  88. package/src/components/tooltip/index.tsx +74 -74
  89. package/src/components/tooltip/types.ts +7 -7
  90. package/src/components/view-cart-button/ViewCartButton.stories.tsx +252 -252
  91. package/src/components/view-cart-button/index.tsx +42 -42
  92. package/src/components/view-cart-button/types.ts +5 -5
  93. package/src/contentful/blocks/address-input-banner/index.tsx +52 -52
  94. package/src/contentful/blocks/address-input-banner/types.ts +14 -14
  95. package/src/contentful/blocks/blogs-grid/index.tsx +134 -129
  96. package/src/contentful/blocks/blogs-grid/types.ts +26 -26
  97. package/src/contentful/blocks/button/Button.stories.tsx +40 -40
  98. package/src/contentful/blocks/button/index.tsx +121 -121
  99. package/src/contentful/blocks/button/types.ts +36 -36
  100. package/src/contentful/blocks/callout/Callout.stories.tsx +23 -23
  101. package/src/contentful/blocks/callout/index.tsx +86 -86
  102. package/src/contentful/blocks/callout/types.ts +15 -15
  103. package/src/contentful/blocks/cards/Cards.stories.tsx +23 -23
  104. package/src/contentful/blocks/cards/blog-card/index.tsx +109 -104
  105. package/src/contentful/blocks/cards/blog-card/types.ts +16 -15
  106. package/src/contentful/blocks/cards/index.tsx +13 -13
  107. package/src/contentful/blocks/cards/product-card/index.tsx +208 -208
  108. package/src/contentful/blocks/cards/product-card/types.ts +28 -28
  109. package/src/contentful/blocks/cards/testimonial-card/index.tsx +88 -88
  110. package/src/contentful/blocks/cards/testimonial-card/types.tsx +12 -12
  111. package/src/contentful/blocks/cards/types.ts +1 -1
  112. package/src/contentful/blocks/carousel/Carousel.stories.tsx +23 -23
  113. package/src/contentful/blocks/carousel/helper.tsx +356 -356
  114. package/src/contentful/blocks/carousel/index.tsx +73 -73
  115. package/src/contentful/blocks/carousel/types.ts +143 -143
  116. package/src/contentful/blocks/cta-callout/CtaCallout.stories.tsx +46 -46
  117. package/src/contentful/blocks/cta-callout/index.tsx +60 -60
  118. package/src/contentful/blocks/cta-callout/types.ts +26 -26
  119. package/src/contentful/blocks/dynamic-tabs/index.tsx +204 -204
  120. package/src/contentful/blocks/dynamic-tabs/types.ts +21 -21
  121. package/src/contentful/blocks/find-kinetic/index.tsx +130 -130
  122. package/src/contentful/blocks/floating-banner/FloatingBanner.stories.tsx +34 -34
  123. package/src/contentful/blocks/floating-banner/index.tsx +97 -97
  124. package/src/contentful/blocks/floating-banner/types.ts +22 -22
  125. package/src/contentful/blocks/footer/Footer.stories.tsx +30 -30
  126. package/src/contentful/blocks/image-promo-bar/ImagePromoBar.stories.tsx +23 -23
  127. package/src/contentful/blocks/image-promo-bar/helper.tsx +28 -28
  128. package/src/contentful/blocks/image-promo-bar/types.ts +44 -44
  129. package/src/contentful/blocks/image-promo-bar/vimeo-embed.tsx +93 -93
  130. package/src/contentful/blocks/image-promo-bar/youtube-embed.tsx +46 -46
  131. package/src/contentful/blocks/modal/constants.ts +53 -53
  132. package/src/contentful/blocks/modal/index.tsx +91 -91
  133. package/src/contentful/blocks/modal/types.ts +12 -12
  134. package/src/contentful/blocks/navigation/desktop-link-groups.tsx/index.tsx +113 -113
  135. package/src/contentful/blocks/navigation/index.tsx +394 -394
  136. package/src/contentful/blocks/navigation/mobile-link-groups.tsx/index.tsx +82 -82
  137. package/src/contentful/blocks/navigation/types.ts +41 -41
  138. package/src/contentful/blocks/primary-hero/PrimaryHero.stories.tsx +23 -23
  139. package/src/contentful/blocks/primary-hero/index.tsx +234 -234
  140. package/src/contentful/blocks/primary-hero/types.ts +35 -35
  141. package/src/contentful/blocks/search-block/index.tsx +90 -90
  142. package/src/contentful/blocks/shape-background-wrapper/ShapeBackgroundWrapper.stories.tsx +26 -26
  143. package/src/contentful/blocks/shape-background-wrapper/index.tsx +124 -124
  144. package/src/contentful/blocks/shape-background-wrapper/types.ts +36 -36
  145. package/src/contentful/blocks/text/Text.stories.tsx +23 -23
  146. package/src/contentful/blocks/text/index.tsx +12 -12
  147. package/src/contentful/blocks/text/types.ts +1 -1
  148. package/src/contentful/index.ts +75 -75
  149. package/src/hooks/use-body-scroll-lock.ts +34 -34
  150. package/src/hooks/use-outside-click.ts +17 -17
  151. package/src/index.ts +96 -96
  152. package/src/next/index.ts +5 -5
  153. package/src/setupTests.ts +46 -46
  154. package/src/stories/DocsTemplate.tsx +24 -24
  155. package/src/styles/globals.css +343 -343
  156. package/src/types/global.d.ts +9 -9
  157. package/src/types/micro-components.ts +99 -99
  158. package/src/types/utm.ts +49 -49
  159. package/src/utils/cookie.ts +58 -58
  160. package/src/utils/index.ts +65 -65
  161. package/src/utils/utm.ts +221 -221
@@ -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-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,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 = {};