@windstream/react-shared-components 0.0.37 → 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 (57) 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 +2 -2
  7. package/dist/index.esm.js +1 -1
  8. package/dist/index.esm.js.map +1 -1
  9. package/dist/index.js +1 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/styles.css +1 -1
  12. package/package.json +1 -1
  13. package/src/components/accordion/index.tsx +49 -49
  14. package/src/components/alert-card/types.ts +9 -9
  15. package/src/components/brand-button/index.tsx +93 -93
  16. package/src/components/button/index.tsx +27 -27
  17. package/src/components/button/types.ts +14 -14
  18. package/src/components/checkbox/index.tsx +197 -197
  19. package/src/components/collapse/index.tsx +46 -46
  20. package/src/components/image/types.ts +33 -33
  21. package/src/components/input/index.tsx +6 -6
  22. package/src/components/link/index.tsx +97 -97
  23. package/src/components/link/types.ts +25 -25
  24. package/src/components/list/index.tsx +88 -88
  25. package/src/components/list/list-item/index.tsx +38 -38
  26. package/src/components/list/list-item/types.ts +13 -13
  27. package/src/components/list/types.ts +29 -29
  28. package/src/components/material-icon/index.tsx +44 -44
  29. package/src/components/material-icon/types.ts +31 -31
  30. package/src/components/modal/index.tsx +164 -164
  31. package/src/components/see-more/index.tsx +44 -44
  32. package/src/components/select/index.tsx +150 -150
  33. package/src/components/skeleton/index.tsx +61 -61
  34. package/src/components/text/index.tsx +25 -25
  35. package/src/components/text/types.ts +45 -45
  36. package/src/contentful/blocks/accordion/Accordion.stories.tsx +29 -29
  37. package/src/contentful/blocks/accordion/index.tsx +52 -52
  38. package/src/contentful/blocks/accordion/types.ts +17 -17
  39. package/src/contentful/blocks/button/index.tsx +5 -0
  40. package/src/contentful/blocks/button/types.ts +1 -0
  41. package/src/contentful/blocks/callout/Callout.stories.tsx +1 -1
  42. package/src/contentful/blocks/callout/index.tsx +15 -52
  43. package/src/contentful/blocks/callout/types.ts +1 -14
  44. package/src/contentful/blocks/find-kinetic/FindKinetic.stories.tsx +23 -23
  45. package/src/contentful/blocks/find-kinetic/index.tsx +80 -80
  46. package/src/contentful/blocks/find-kinetic/types.ts +18 -18
  47. package/src/contentful/blocks/footer/index.tsx +79 -79
  48. package/src/contentful/blocks/image-promo-bar/index.tsx +154 -154
  49. package/src/contentful/blocks/navigation/index.tsx +1 -2
  50. package/src/contentful/blocks/navigation/link-groups.tsx/index.tsx +64 -62
  51. package/src/contentful/blocks/primary-hero/index.tsx +163 -64
  52. package/src/contentful/blocks/primary-hero/types.ts +1 -0
  53. package/src/contentful/index.ts +45 -48
  54. package/src/hooks/use-body-scroll-lock.ts +34 -34
  55. package/src/setupTests.ts +46 -46
  56. package/src/contentful/blocks/cards/simple-card/index.tsx +0 -45
  57. package/src/contentful/blocks/cards/simple-card/types.ts +0 -11
@@ -1,75 +1,174 @@
1
1
  import React from "react";
2
2
  import { PrimaryHeroProps } from "./types";
3
3
 
4
- export const PrimaryHero: React.FC<PrimaryHeroProps> = ({
5
- maxWidth = true,
6
- title,
7
- showAsHeading,
8
- subTitle,
9
- price,
10
- priceSuffix,
11
- priceCallout,
12
- pricingDescription,
13
- pricingDescriptionDisclaimer,
14
- checklist,
15
- logoLockup,
16
- checkAvailabilityEyebrow,
17
- primaryCtaPrefix1,
18
- primaryCtaPrefix2,
19
- primaryCta1,
20
- primaryCta2,
21
- secondaryCtaPrefix,
22
- secondaryCta,
23
- carouselImages,
24
- squareImage,
25
- badgeImage,
26
- bottomLink,
27
- }) => {
4
+ import { Link } from "@shared/components/link";
5
+ import { Text } from "@shared/components/text";
6
+ import { cx } from "@shared/utils";
7
+
8
+ import { Button as ContentfulButton } from "@shared/contentful/blocks/button";
9
+ import { NextImage } from "@shared/components/next-image";
10
+ import { Checklist } from "@shared/components/checklist";
11
+
12
+
13
+ export const PrimaryHero: React.FC<PrimaryHeroProps> = (props) => {
14
+ const {
15
+ title,
16
+ showAsHeading,
17
+ subTitle,
18
+ pricingDescription,
19
+ primaryCta1,
20
+ carouselImages,
21
+ bottomLink,
22
+ price,
23
+ priceCallout,
24
+ priceSuffix,
25
+ checklist,
26
+ checkPlansJSX
27
+ } = props;
28
+
29
+ const bodyText = pricingDescription ?? subTitle;
30
+ const primaryCtaLabel = primaryCta1?.buttonLabel ?? primaryCta1?.label;
31
+ const bottomLinkLabel = bottomLink?.buttonLabel ?? bottomLink?.label;
32
+
28
33
  return (
29
- <div className="component-container">
34
+ <div className="component-container p-5 lg:p-0 lg:h-[724px]">
30
35
  <div
31
- className={`primary-hero-container ${maxWidth ? "mx-auto max-w-120" : ""}`}
32
- >
33
- {/* Text Content */}
34
- {title && <div>{title}</div>}
35
- {showAsHeading && <div>Heading Mode: {String(showAsHeading)}</div>}
36
- {subTitle && <div>{subTitle}</div>}
37
-
38
- {/* Pricing Section */}
39
- {price && <div>{price}</div>}
40
- {priceSuffix && <div>{priceSuffix}</div>}
41
- {priceCallout && <div>{priceCallout}</div>}
42
- {pricingDescription && <div>{pricingDescription}</div>}
43
- {pricingDescriptionDisclaimer && (
44
- <div>{pricingDescriptionDisclaimer}</div>
36
+ className={cx(
37
+ "primary-hero-container mx-auto lg:p-4 lg:gap-4 lg:h-full flex flex-col sm:text-center lg:text-left sm:items-center lg:flex-row lg:justify-between lg:items-center lg:max-w-120",
45
38
  )}
39
+ >
40
+ {/* Left column: navy background, headline, body, address, button, link */}
41
+ <div
42
+ className={cx(
43
+ "relative flex flex-col text-white w-[485px]",
44
+ )}
45
+ >
46
+ <div className="flex flex-col gap-5 lg:gap-6">
47
+ {title && (
48
+ <Text
49
+ as={showAsHeading ? "h1" : "h2"}
50
+ className="heading2 lg:heading1 font-bold"
51
+ >
52
+ {title}
53
+ </Text>
54
+ )}
55
+ {bodyText && (
56
+ <Text
57
+ as="p"
58
+ className="subheading3 lg:subheading1"
59
+ >
60
+ {bodyText}
61
+ </Text>
62
+ )}
63
+
64
+ {/* price callout */}
65
+ {price ? (
66
+ <div className="flex">
67
+ <div className="mr-2">
68
+ {priceCallout ? (
69
+ priceCallout.split('|').map(line => <Text as="p" className="body2">{line}</Text>)
70
+ ) : null}
71
+ </div>
72
+ <Text as="p" className="subheading1">$</Text>
73
+ <Text as="p" className="subheading5">{price}</Text>
74
+ {priceSuffix ? (
75
+ <Text as="p" className="subheading1">{priceSuffix}</Text>
76
+ ) : null}
77
+ </div>
78
+ ) : null}
79
+
80
+ {/* checklist */}
81
+ {checklist && <Checklist listItemClassName="text-white body2" items={checklist.map(item => item.title)} />}
82
+
83
+ {/* desktop CTA */}
84
+ {primaryCta1 && primaryCtaLabel && (
85
+ <div className={cx("hidden lg:flex flex-col gap-3")}>
86
+ <ContentfulButton
87
+ {...primaryCta1}
88
+ checkPlansJSX={checkPlansJSX}
89
+ buttonLabel={primaryCtaLabel}
90
+ />
91
+
92
+ {bottomLink && (bottomLinkLabel || bottomLink?.href) && (
93
+ <div>
94
+ <Link
95
+ href={bottomLink?.href ?? "#"}
96
+ target={bottomLink?.target}
97
+ external={bottomLink?.target === "_blank"}
98
+ className="text-footnote text-white underline hover:opacity-90"
99
+ >
100
+ {bottomLinkLabel}
101
+ </Link>
102
+ </div>
103
+ )}
104
+ </div>
105
+ )}
106
+
107
+ {/* desktop bottom link */}
108
+ {!primaryCta1 && bottomLink && (bottomLinkLabel || bottomLink?.href) && (
109
+ <div className="hidden lg:block">
110
+ <Link
111
+ href={bottomLink?.href ?? "#"}
112
+ target={bottomLink?.target}
113
+ external={bottomLink?.target === "_blank"}
114
+ className="text-footnote text-white underline hover:opacity-90"
115
+ >
116
+ {bottomLinkLabel}
117
+ </Link>
118
+ </div>
119
+ )}
120
+ </div>
121
+ </div>
122
+
123
+ {/* mobile hero image and bottom link */}
124
+ <div className="lg:hidden">
125
+ <div
126
+ className={"my-8"}
127
+ >
128
+ {carouselImages && carouselImages[0] ? (
129
+ <NextImage
130
+ src={carouselImages[0]}
131
+ alt={"Hero"}
132
+ className="object-cover aspect-[1.71:1] sm:aspect-[1.41:1] sm:h-[420px] object-center rounded-[40px]"
133
+ width={350}
134
+ height={205}
135
+ loading="eager"
136
+ />
137
+ ) : null}
46
138
 
47
- {/* Assets & Logos */}
48
- {logoLockup && <div>Logo: {logoLockup}</div>}
49
- {badgeImage && <div>Badge: {badgeImage}</div>}
50
- {squareImage && <div>Square Layout: {String(squareImage)}</div>}
51
-
52
- {/* Checklist */}
53
- {checklist?.map((item, index) => (
54
- <div key={`checklist-${index}`}>Checklist Item: {item.title}</div>
55
- ))}
56
-
57
- {/* CTAs & Availability */}
58
- {checkAvailabilityEyebrow && <div>{checkAvailabilityEyebrow}</div>}
59
- {primaryCtaPrefix1 && <div>{primaryCtaPrefix1}</div>}
60
- {primaryCta1 && <div>CTA 1: {primaryCta1.label}</div>}
61
- {primaryCtaPrefix2 && <div>{primaryCtaPrefix2}</div>}
62
- {primaryCta2 && <div>CTA 2: {primaryCta2.label}</div>}
63
- {secondaryCtaPrefix && <div>{secondaryCtaPrefix}</div>}
64
- {secondaryCta && <div>Secondary: {secondaryCta.label}</div>}
65
- {bottomLink && <div>Bottom Link: {bottomLink.label}</div>}
66
-
67
- {/* Carousel URLs via hook */}
68
- {carouselImages?.map((url, index) => (
69
- <div key={index}>
70
- Carousel Image {index + 1}: {url}
71
139
  </div>
72
- ))}
140
+ {bottomLink && (bottomLinkLabel || bottomLink?.href) && (
141
+ <div>
142
+ <Link
143
+ href={bottomLink?.href ?? "#"}
144
+ target={bottomLink?.target}
145
+ external={bottomLink?.target === "_blank"}
146
+ className="body3 text-white underline hover:opacity-90"
147
+ >
148
+ {bottomLinkLabel}
149
+ </Link>
150
+ </div>
151
+ )}
152
+ </div>
153
+
154
+
155
+ {/* Right column: bright blue background, diagonal top edge, hero image */}
156
+ <div
157
+ className={cx(
158
+ "relative hidden lg:block",
159
+ )}
160
+ >
161
+ {carouselImages && carouselImages[0] ? (
162
+ <NextImage
163
+ src={carouselImages[0]}
164
+ alt={"Hero"}
165
+ className="rounded-[40px] aspect-square object-cover object-center"
166
+ width={600}
167
+ height={600}
168
+ loading="eager"
169
+ />
170
+ ) : null}
171
+ </div>
73
172
  </div>
74
173
  </div>
75
174
  );
@@ -26,4 +26,5 @@ export type PrimaryHeroProps = {
26
26
  badgeImage?: string;
27
27
  textColor?: string;
28
28
  maxWidth?: boolean;
29
+ checkPlansJSX?: React.ReactNode;
29
30
  };
@@ -1,48 +1,45 @@
1
- // Contentful Blocks
2
- export { Accordion } from "./blocks/accordion";
3
- export type { AccordionProps } from "./blocks/accordion/types";
4
-
5
- export { Callout } from "./blocks/callout";
6
- export type { CalloutProps } from "./blocks/callout/types";
7
-
8
- export { Cards } from "./blocks/cards";
9
- export type { CardsProps } from "./blocks/cards/types";
10
-
11
- export { SimpleCards } from "./blocks/cards/simple-card";
12
- export type { SimpleCardsProps } from "./blocks/cards/simple-card/types";
13
-
14
- export { Carousel } from "./blocks/carousel";
15
- export type { CarouselProps } from "./blocks/carousel/types";
16
-
17
- export { FloatingBanner } from "./blocks/floating-banner";
18
- export type { FloatingBannerProps } from "./blocks/floating-banner/types";
19
-
20
- export { Footer } from "./blocks/footer";
21
- export type { FooterProps } from "./blocks/footer/types";
22
-
23
- export { ImagePromoBar } from "./blocks/image-promo-bar";
24
- export type { ImagePromoBarProps } from "./blocks/image-promo-bar/types";
25
-
26
- export { Navigation } from "./blocks/navigation";
27
- export type { NavigationProps } from "./blocks/navigation/types";
28
-
29
- export { PrimaryHero } from "./blocks/primary-hero";
30
- export type { PrimaryHeroProps } from "./blocks/primary-hero/types";
31
-
32
- export { Text } from "./blocks/text";
33
- export type { TextProps } from "./blocks/text/types";
34
-
35
- export { Button } from "./blocks/button";
36
- export type { ButtonProps } from "./blocks/button/types";
37
-
38
- export { Modal } from "./blocks/modal";
39
- export type { ModalProps } from "./blocks/modal/types";
40
-
41
- export { ShapeBackgroundWrapper } from "./blocks/shape-background-wrapper";
42
- export type { ShapeBackgroundWrapperProps } from "./blocks/shape-background-wrapper/types";
43
-
44
- export { CtaCallout } from "./blocks/cta-callout";
45
- export type { CtaCalloutProps } from "./blocks/cta-callout/types";
46
-
47
- export { FindKinetic } from "./blocks/find-kinetic";
48
- export type { FindKineticProps } from "./blocks/find-kinetic/types";
1
+ // Contentful Blocks
2
+ export { Accordion } from "./blocks/accordion";
3
+ export type { AccordionProps } from "./blocks/accordion/types";
4
+
5
+ export { Callout } from "./blocks/callout";
6
+ export type { CalloutProps } from "./blocks/callout/types";
7
+
8
+ export { Cards } from "./blocks/cards";
9
+ export type { CardsProps } from "./blocks/cards/types";
10
+
11
+ export { Carousel } from "./blocks/carousel";
12
+ export type { CarouselProps } from "./blocks/carousel/types";
13
+
14
+ export { FloatingBanner } from "./blocks/floating-banner";
15
+ export type { FloatingBannerProps } from "./blocks/floating-banner/types";
16
+
17
+ export { Footer } from "./blocks/footer";
18
+ export type { FooterProps } from "./blocks/footer/types";
19
+
20
+ export { ImagePromoBar } from "./blocks/image-promo-bar";
21
+ export type { ImagePromoBarProps } from "./blocks/image-promo-bar/types";
22
+
23
+ export { Navigation } from "./blocks/navigation";
24
+ export type { NavigationProps } from "./blocks/navigation/types";
25
+
26
+ export { PrimaryHero } from "./blocks/primary-hero";
27
+ export type { PrimaryHeroProps } from "./blocks/primary-hero/types";
28
+
29
+ export { Text } from "./blocks/text";
30
+ export type { TextProps } from "./blocks/text/types";
31
+
32
+ export { Button } from "./blocks/button";
33
+ export type { ButtonProps } from "./blocks/button/types";
34
+
35
+ export { Modal } from "./blocks/modal";
36
+ export type { ModalProps } from "./blocks/modal/types";
37
+
38
+ export { ShapeBackgroundWrapper } from "./blocks/shape-background-wrapper";
39
+ export type { ShapeBackgroundWrapperProps } from "./blocks/shape-background-wrapper/types";
40
+
41
+ export { CtaCallout } from "./blocks/cta-callout";
42
+ export type { CtaCalloutProps } from "./blocks/cta-callout/types";
43
+
44
+ export { FindKinetic } from "./blocks/find-kinetic";
45
+ export type { FindKineticProps } from "./blocks/find-kinetic/types";
@@ -1,34 +1,34 @@
1
- "use client";
2
-
3
- import { useEffect } from "react";
4
-
5
- /**
6
- * A custom hook that locks the body scroll based on the `isOpen` and `hideScrollOnIsOpenFalse` flags.
7
- *
8
- * @param {boolean} isOpen - Determines if the scroll should be locked (hidden).
9
- * @param {boolean} hideScrollOnIsOpenFalse - Determines if the scroll should be reset when `isOpen` is false.
10
- */
11
- function useBodyScrollLock(isOpen: boolean, hideScrollOnIsOpenFalse: boolean) {
12
- useEffect(() => {
13
- if (typeof document === "undefined") return;
14
-
15
- // To avoid content shifting when the scrollbar appears/disappears
16
- const scrollbarWidth =
17
- window.innerWidth - document.documentElement.clientWidth;
18
- document.body.style.marginRight = isOpen ? `${scrollbarWidth}px` : "unset";
19
-
20
- // Set the body overflow style based on the `isOpen` and `hideScrollOnIsOpenFalse` values.
21
- document.body.style.overflow = isOpen
22
- ? "hidden"
23
- : hideScrollOnIsOpenFalse
24
- ? "unset"
25
- : document.body.style.overflow;
26
-
27
- // Cleanup function to reset body overflow when the component unmounts or dependencies change.
28
- return () => {
29
- document.body.style.overflow = "unset";
30
- };
31
- }, [isOpen, hideScrollOnIsOpenFalse]);
32
- }
33
-
34
- export default useBodyScrollLock;
1
+ "use client";
2
+
3
+ import { useEffect } from "react";
4
+
5
+ /**
6
+ * A custom hook that locks the body scroll based on the `isOpen` and `hideScrollOnIsOpenFalse` flags.
7
+ *
8
+ * @param {boolean} isOpen - Determines if the scroll should be locked (hidden).
9
+ * @param {boolean} hideScrollOnIsOpenFalse - Determines if the scroll should be reset when `isOpen` is false.
10
+ */
11
+ function useBodyScrollLock(isOpen: boolean, hideScrollOnIsOpenFalse: boolean) {
12
+ useEffect(() => {
13
+ if (typeof document === "undefined") return;
14
+
15
+ // To avoid content shifting when the scrollbar appears/disappears
16
+ const scrollbarWidth =
17
+ window.innerWidth - document.documentElement.clientWidth;
18
+ document.body.style.marginRight = isOpen ? `${scrollbarWidth}px` : "unset";
19
+
20
+ // Set the body overflow style based on the `isOpen` and `hideScrollOnIsOpenFalse` values.
21
+ document.body.style.overflow = isOpen
22
+ ? "hidden"
23
+ : hideScrollOnIsOpenFalse
24
+ ? "unset"
25
+ : document.body.style.overflow;
26
+
27
+ // Cleanup function to reset body overflow when the component unmounts or dependencies change.
28
+ return () => {
29
+ document.body.style.overflow = "unset";
30
+ };
31
+ }, [isOpen, hideScrollOnIsOpenFalse]);
32
+ }
33
+
34
+ export default useBodyScrollLock;
package/src/setupTests.ts CHANGED
@@ -1,46 +1,46 @@
1
- import "@testing-library/jest-dom";
2
-
3
- // Mock window.matchMedia
4
- Object.defineProperty(window, "matchMedia", {
5
- writable: true,
6
- value: (query: string) => ({
7
- matches: false,
8
- media: query,
9
- onchange: null,
10
- addListener: () => {}, // deprecated
11
- removeListener: () => {}, // deprecated
12
- addEventListener: () => {},
13
- removeEventListener: () => {},
14
- dispatchEvent: () => true,
15
- }),
16
- });
17
-
18
- // Mock ResizeObserver
19
- global.ResizeObserver = class ResizeObserver {
20
- observe = () => {};
21
- unobserve = () => {};
22
- disconnect = () => {};
23
- constructor(_callback: ResizeObserverCallback) {}
24
- } as unknown as typeof ResizeObserver;
25
-
26
- // Mock IntersectionObserver
27
- global.IntersectionObserver = class IntersectionObserver {
28
- observe = () => {};
29
- unobserve = () => {};
30
- disconnect = () => {};
31
- constructor(_callback: IntersectionObserverCallback) {}
32
- } as unknown as typeof IntersectionObserver;
33
-
34
- // Mock scrollTo
35
- Object.defineProperty(window, "scrollTo", {
36
- writable: true,
37
- value: () => {},
38
- });
39
-
40
- // Mock getComputedStyle
41
- Object.defineProperty(window, "getComputedStyle", {
42
- writable: true,
43
- value: () => ({
44
- getPropertyValue: () => "",
45
- }),
46
- });
1
+ import "@testing-library/jest-dom";
2
+
3
+ // Mock window.matchMedia
4
+ Object.defineProperty(window, "matchMedia", {
5
+ writable: true,
6
+ value: (query: string) => ({
7
+ matches: false,
8
+ media: query,
9
+ onchange: null,
10
+ addListener: () => {}, // deprecated
11
+ removeListener: () => {}, // deprecated
12
+ addEventListener: () => {},
13
+ removeEventListener: () => {},
14
+ dispatchEvent: () => true,
15
+ }),
16
+ });
17
+
18
+ // Mock ResizeObserver
19
+ global.ResizeObserver = class ResizeObserver {
20
+ observe = () => {};
21
+ unobserve = () => {};
22
+ disconnect = () => {};
23
+ constructor(_callback: ResizeObserverCallback) {}
24
+ } as unknown as typeof ResizeObserver;
25
+
26
+ // Mock IntersectionObserver
27
+ global.IntersectionObserver = class IntersectionObserver {
28
+ observe = () => {};
29
+ unobserve = () => {};
30
+ disconnect = () => {};
31
+ constructor(_callback: IntersectionObserverCallback) {}
32
+ } as unknown as typeof IntersectionObserver;
33
+
34
+ // Mock scrollTo
35
+ Object.defineProperty(window, "scrollTo", {
36
+ writable: true,
37
+ value: () => {},
38
+ });
39
+
40
+ // Mock getComputedStyle
41
+ Object.defineProperty(window, "getComputedStyle", {
42
+ writable: true,
43
+ value: () => ({
44
+ getPropertyValue: () => "",
45
+ }),
46
+ });
@@ -1,45 +0,0 @@
1
- import React from "react";
2
- import type { SimpleCardsProps } from "./types";
3
-
4
- import { NextImage } from "@shared/components/next-image";
5
- import { Text } from "@shared/components/text";
6
-
7
- export const SimpleCards: React.FC<SimpleCardsProps> = ({ items = [] }) => {
8
- if (!items.length) return null;
9
-
10
- return (
11
- <div className="card-holder grid grid-cols-1 items-stretch gap-5 self-stretch lg:auto-cols-fr lg:grid-flow-col lg:gap-6 lg:overflow-x-auto">
12
- {items.map((item, index: number) => (
13
- <div className="callout-card h-full p-6 lg:p-8" key={`card-${index}`}>
14
- <div className="card-template flex flex-col gap-6 lg:items-start lg:gap-8">
15
- <div className="card-header">
16
- {item.image && (
17
- <NextImage
18
- width={88}
19
- height={88}
20
- src={item.image}
21
- alt={item.title ?? "card-icon"}
22
- />
23
- )}
24
- </div>
25
-
26
- <div className="card-body flex flex-col gap-3">
27
- {item.title && (
28
- <Text as="h3" className="heading6">
29
- {item.title}
30
- </Text>
31
- )}
32
- {item.BodyComponent && (
33
- <Text as="div" className="body1">
34
- <item.BodyComponent />
35
- </Text>
36
- )}
37
- </div>
38
- </div>
39
- </div>
40
- ))}
41
- </div>
42
- );
43
- };
44
-
45
- export default SimpleCards;
@@ -1,11 +0,0 @@
1
- import type { ComponentType } from "react";
2
-
3
- export type Item = {
4
- title?: string;
5
- image?: string;
6
- BodyComponent?: ComponentType;
7
- };
8
-
9
- export type SimpleCardsProps = {
10
- items: Item[];
11
- };