@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.
- package/dist/contentful/index.d.ts +9 -29
- package/dist/contentful/index.esm.js +1 -1
- package/dist/contentful/index.esm.js.map +1 -1
- package/dist/contentful/index.js +1 -1
- package/dist/contentful/index.js.map +1 -1
- package/dist/core.d.ts +2 -2
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/components/accordion/index.tsx +49 -49
- package/src/components/alert-card/types.ts +9 -9
- package/src/components/brand-button/index.tsx +93 -93
- package/src/components/button/index.tsx +27 -27
- package/src/components/button/types.ts +14 -14
- package/src/components/checkbox/index.tsx +197 -197
- package/src/components/collapse/index.tsx +46 -46
- package/src/components/image/types.ts +33 -33
- package/src/components/input/index.tsx +6 -6
- package/src/components/link/index.tsx +97 -97
- package/src/components/link/types.ts +25 -25
- package/src/components/list/index.tsx +88 -88
- package/src/components/list/list-item/index.tsx +38 -38
- package/src/components/list/list-item/types.ts +13 -13
- package/src/components/list/types.ts +29 -29
- package/src/components/material-icon/index.tsx +44 -44
- package/src/components/material-icon/types.ts +31 -31
- package/src/components/modal/index.tsx +164 -164
- package/src/components/see-more/index.tsx +44 -44
- package/src/components/select/index.tsx +150 -150
- package/src/components/skeleton/index.tsx +61 -61
- package/src/components/text/index.tsx +25 -25
- package/src/components/text/types.ts +45 -45
- package/src/contentful/blocks/accordion/Accordion.stories.tsx +29 -29
- package/src/contentful/blocks/accordion/index.tsx +52 -52
- package/src/contentful/blocks/accordion/types.ts +17 -17
- package/src/contentful/blocks/button/index.tsx +5 -0
- package/src/contentful/blocks/button/types.ts +1 -0
- package/src/contentful/blocks/callout/Callout.stories.tsx +1 -1
- package/src/contentful/blocks/callout/index.tsx +15 -52
- package/src/contentful/blocks/callout/types.ts +1 -14
- package/src/contentful/blocks/find-kinetic/FindKinetic.stories.tsx +23 -23
- package/src/contentful/blocks/find-kinetic/index.tsx +80 -80
- package/src/contentful/blocks/find-kinetic/types.ts +18 -18
- package/src/contentful/blocks/footer/index.tsx +79 -79
- package/src/contentful/blocks/image-promo-bar/index.tsx +154 -154
- package/src/contentful/blocks/navigation/index.tsx +1 -2
- package/src/contentful/blocks/navigation/link-groups.tsx/index.tsx +64 -62
- package/src/contentful/blocks/primary-hero/index.tsx +163 -64
- package/src/contentful/blocks/primary-hero/types.ts +1 -0
- package/src/contentful/index.ts +45 -48
- package/src/hooks/use-body-scroll-lock.ts +34 -34
- package/src/setupTests.ts +46 -46
- package/src/contentful/blocks/cards/simple-card/index.tsx +0 -45
- 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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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={
|
|
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
|
);
|
package/src/contentful/index.ts
CHANGED
|
@@ -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 {
|
|
12
|
-
export type {
|
|
13
|
-
|
|
14
|
-
export {
|
|
15
|
-
export type {
|
|
16
|
-
|
|
17
|
-
export {
|
|
18
|
-
export type {
|
|
19
|
-
|
|
20
|
-
export {
|
|
21
|
-
export type {
|
|
22
|
-
|
|
23
|
-
export {
|
|
24
|
-
export type {
|
|
25
|
-
|
|
26
|
-
export {
|
|
27
|
-
export type {
|
|
28
|
-
|
|
29
|
-
export {
|
|
30
|
-
export type {
|
|
31
|
-
|
|
32
|
-
export {
|
|
33
|
-
export type {
|
|
34
|
-
|
|
35
|
-
export {
|
|
36
|
-
export type {
|
|
37
|
-
|
|
38
|
-
export {
|
|
39
|
-
export type {
|
|
40
|
-
|
|
41
|
-
export {
|
|
42
|
-
export type {
|
|
43
|
-
|
|
44
|
-
export {
|
|
45
|
-
export type {
|
|
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;
|