@windstream/react-shared-components 0.1.94 → 0.1.95
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/README.md +635 -635
- package/dist/contentful/index.esm.js +3 -3
- package/dist/contentful/index.esm.js.map +1 -1
- package/dist/contentful/index.js +3 -3
- package/dist/contentful/index.js.map +1 -1
- package/dist/core.d.ts +4 -4
- package/dist/index.esm.js +5 -13
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +5 -13
- package/dist/index.js.map +1 -1
- package/dist/next/index.esm.js +2 -2
- package/dist/next/index.esm.js.map +1 -1
- package/dist/next/index.js +2 -2
- package/dist/next/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/utils/index.esm.js +1 -1
- package/dist/utils/index.esm.js.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +191 -191
- package/src/components/accordion/Accordion.stories.tsx +230 -230
- package/src/components/accordion/index.test.tsx +270 -270
- package/src/components/accordion/index.tsx +70 -70
- package/src/components/accordion/types.ts +12 -12
- package/src/components/alert-card/AlertCard.stories.tsx +171 -171
- package/src/components/alert-card/index.test.tsx +152 -152
- package/src/components/alert-card/index.tsx +41 -41
- package/src/components/alert-card/types.ts +13 -13
- package/src/components/animation-wrapper/index.test.tsx +424 -424
- package/src/components/animation-wrapper/index.tsx +129 -129
- package/src/components/animation-wrapper/types.ts +11 -11
- package/src/components/brand-button/BrandButton.stories.tsx +223 -223
- package/src/components/brand-button/helpers.ts +35 -35
- package/src/components/brand-button/index.test.tsx +292 -292
- package/src/components/brand-button/index.tsx +120 -120
- package/src/components/brand-button/types.ts +38 -38
- package/src/components/button/Button.stories.tsx +108 -108
- package/src/components/button/index.test.tsx +91 -91
- package/src/components/button/index.tsx +27 -27
- package/src/components/button/types.ts +14 -14
- package/src/components/call-button/CallButton.stories.tsx +324 -324
- package/src/components/call-button/index.test.tsx +260 -260
- package/src/components/call-button/index.tsx +106 -106
- package/src/components/call-button/types.ts +16 -16
- package/src/components/checkbox/Checkbox.stories.tsx +247 -247
- package/src/components/checkbox/index.test.tsx +252 -252
- package/src/components/checkbox/index.tsx +197 -197
- package/src/components/checkbox/types.ts +27 -27
- package/src/components/checklist/Checklist.stories.tsx +150 -150
- package/src/components/checklist/index.test.tsx +231 -231
- package/src/components/checklist/index.tsx +96 -96
- package/src/components/checklist/types.ts +23 -23
- package/src/components/collapse/Collapse.stories.tsx +255 -255
- package/src/components/collapse/index.test.tsx +277 -277
- package/src/components/collapse/index.tsx +47 -47
- package/src/components/collapse/types.ts +6 -6
- package/src/components/divider/Divider.stories.tsx +205 -205
- package/src/components/divider/index.test.tsx +53 -53
- package/src/components/divider/index.tsx +22 -22
- package/src/components/divider/type.ts +3 -3
- package/src/components/image/Image.stories.tsx +113 -113
- package/src/components/image/index.test.tsx +174 -174
- package/src/components/image/index.tsx +25 -25
- package/src/components/image/types.ts +40 -40
- package/src/components/input/Input.stories.tsx +325 -325
- package/src/components/input/index.test.tsx +348 -348
- package/src/components/input/index.tsx +177 -177
- package/src/components/input/types.ts +37 -37
- package/src/components/link/Link.stories.tsx +163 -163
- package/src/components/link/index.test.tsx +199 -199
- package/src/components/link/index.tsx +116 -116
- package/src/components/link/types.ts +25 -25
- package/src/components/list/List.stories.tsx +272 -272
- package/src/components/list/index.test.tsx +166 -166
- 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/MaterialIcon.stories.tsx +322 -322
- package/src/components/material-icon/constants.ts +99 -99
- package/src/components/material-icon/index.test.tsx +130 -130
- package/src/components/material-icon/index.tsx +47 -47
- package/src/components/material-icon/types.ts +31 -31
- package/src/components/modal/Modal.stories.tsx +171 -171
- package/src/components/modal/index.test.tsx +310 -310
- package/src/components/modal/index.tsx +164 -164
- package/src/components/modal/types.ts +24 -24
- package/src/components/next-image/index.test.tsx +406 -406
- package/src/components/next-image/index.tsx +74 -74
- package/src/components/next-image/types.ts +1 -1
- package/src/components/pagination/index.test.tsx +521 -521
- package/src/components/pagination/index.tsx +91 -91
- package/src/components/pagination/types.ts +6 -6
- package/src/components/radio-button/RadioButton.stories.tsx +307 -307
- package/src/components/radio-button/index.test.tsx +151 -151
- package/src/components/radio-button/index.tsx +75 -75
- package/src/components/radio-button/types.ts +21 -21
- package/src/components/see-more/SeeMore.stories.tsx +181 -181
- package/src/components/see-more/index.test.tsx +96 -96
- package/src/components/see-more/index.tsx +44 -44
- package/src/components/see-more/types.ts +4 -4
- package/src/components/select/Select.stories.tsx +411 -411
- package/src/components/select/index.test.tsx +256 -256
- package/src/components/select/index.tsx +155 -155
- package/src/components/select/types.ts +36 -36
- package/src/components/select-plan-button/SelectPlanButton.stories.tsx +184 -184
- package/src/components/select-plan-button/index.test.tsx +173 -173
- package/src/components/select-plan-button/index.tsx +63 -63
- package/src/components/select-plan-button/types.ts +17 -17
- package/src/components/skeleton/Skeleton.stories.tsx +179 -179
- package/src/components/skeleton/index.test.tsx +74 -74
- package/src/components/skeleton/index.tsx +61 -61
- package/src/components/skeleton/types.ts +4 -4
- package/src/components/spinner/Spinner.stories.tsx +335 -335
- package/src/components/spinner/index.test.tsx +76 -76
- package/src/components/spinner/index.tsx +44 -44
- package/src/components/spinner/types.ts +5 -5
- package/src/components/text/Text.stories.tsx +321 -321
- package/src/components/text/index.test.tsx +65 -65
- package/src/components/text/index.tsx +25 -25
- package/src/components/text/types.ts +45 -45
- package/src/components/tooltip/Tooltip.stories.tsx +219 -219
- package/src/components/tooltip/index.test.tsx +50 -50
- package/src/components/tooltip/index.tsx +74 -74
- package/src/components/tooltip/types.ts +7 -7
- package/src/components/view-cart-button/ViewCartButton.stories.tsx +252 -252
- package/src/components/view-cart-button/index.test.tsx +57 -57
- package/src/components/view-cart-button/index.tsx +42 -42
- package/src/components/view-cart-button/types.ts +5 -5
- package/src/contentful/blocks/accordion/Accordion.stories.mocks.tsx +128 -128
- package/src/contentful/blocks/accordion/Accordion.stories.tsx +98 -98
- package/src/contentful/blocks/accordion/index.test.tsx +218 -218
- package/src/contentful/blocks/accordion/index.tsx +114 -114
- package/src/contentful/blocks/accordion/types.ts +34 -34
- package/src/contentful/blocks/address-input-banner/index.test.tsx +132 -132
- package/src/contentful/blocks/address-input-banner/index.tsx +52 -52
- package/src/contentful/blocks/address-input-banner/types.ts +14 -14
- package/src/contentful/blocks/anchored-bottom-banner/index.test.tsx +287 -287
- package/src/contentful/blocks/anchored-bottom-banner/index.tsx +181 -181
- package/src/contentful/blocks/anchored-bottom-banner/types.ts +13 -13
- package/src/contentful/blocks/blogs-grid/BlogGrid.stories.mocks.tsx +144 -144
- package/src/contentful/blocks/blogs-grid/BlogGrid.stories.tsx +157 -157
- package/src/contentful/blocks/blogs-grid/index.test.tsx +355 -355
- package/src/contentful/blocks/blogs-grid/index.tsx +134 -134
- package/src/contentful/blocks/blogs-grid/types.ts +26 -26
- package/src/contentful/blocks/blogs-grid-base/index.test.tsx +274 -274
- package/src/contentful/blocks/blogs-grid-base/index.tsx +119 -119
- package/src/contentful/blocks/blogs-grid-base/types.ts +36 -36
- package/src/contentful/blocks/breadcrumbs/BreadcrumbNavigation.stories.tsx +147 -147
- package/src/contentful/blocks/breadcrumbs/index.test.tsx +281 -281
- package/src/contentful/blocks/breadcrumbs/index.tsx +95 -95
- package/src/contentful/blocks/breadcrumbs/types.ts +8 -8
- package/src/contentful/blocks/button/Button.stories.tsx +40 -40
- package/src/contentful/blocks/button/index.test.tsx +339 -339
- package/src/contentful/blocks/button/index.tsx +131 -131
- package/src/contentful/blocks/button/types.ts +39 -39
- package/src/contentful/blocks/callout/Callout.stories.tsx +23 -23
- package/src/contentful/blocks/callout/index.test.tsx +539 -539
- package/src/contentful/blocks/callout/index.tsx +277 -277
- package/src/contentful/blocks/callout/types.ts +78 -78
- package/src/contentful/blocks/cards/Cards.stories.tsx +23 -23
- package/src/contentful/blocks/cards/blog-card/index.test.tsx +218 -218
- package/src/contentful/blocks/cards/blog-card/index.tsx +129 -129
- package/src/contentful/blocks/cards/blog-card/types.ts +34 -34
- package/src/contentful/blocks/cards/floating-image-card/index.test.tsx +201 -201
- package/src/contentful/blocks/cards/floating-image-card/index.tsx +119 -119
- package/src/contentful/blocks/cards/floating-image-card/types.ts +30 -30
- package/src/contentful/blocks/cards/full-image-card/index.test.tsx +216 -216
- package/src/contentful/blocks/cards/full-image-card/index.tsx +130 -130
- package/src/contentful/blocks/cards/full-image-card/types.ts +29 -29
- package/src/contentful/blocks/cards/index.test.tsx +39 -39
- package/src/contentful/blocks/cards/index.tsx +13 -13
- package/src/contentful/blocks/cards/product-card/index.test.tsx +263 -263
- package/src/contentful/blocks/cards/product-card/index.tsx +251 -251
- package/src/contentful/blocks/cards/product-card/types.ts +28 -28
- package/src/contentful/blocks/cards/simple-card/index.test.tsx +364 -364
- package/src/contentful/blocks/cards/simple-card/index.tsx +325 -325
- package/src/contentful/blocks/cards/simple-card/types.ts +71 -71
- package/src/contentful/blocks/cards/testimonial-card/index.test.tsx +180 -180
- package/src/contentful/blocks/cards/testimonial-card/index.tsx +90 -90
- package/src/contentful/blocks/cards/testimonial-card/types.tsx +12 -12
- package/src/contentful/blocks/cards/types.ts +1 -1
- package/src/contentful/blocks/carousel/Carousel.stories.tsx +23 -23
- package/src/contentful/blocks/carousel/helper.test.tsx +539 -539
- package/src/contentful/blocks/carousel/helper.tsx +494 -494
- package/src/contentful/blocks/carousel/index.test.tsx +308 -308
- package/src/contentful/blocks/carousel/index.tsx +87 -87
- package/src/contentful/blocks/carousel/types.test.ts +16 -16
- package/src/contentful/blocks/carousel/types.ts +145 -145
- package/src/contentful/blocks/cart-retention-banner/index.test.tsx +409 -409
- package/src/contentful/blocks/cart-retention-banner/index.tsx +109 -109
- package/src/contentful/blocks/cart-retention-banner/types.ts +11 -11
- package/src/contentful/blocks/comparison-table/index.test.tsx +114 -114
- package/src/contentful/blocks/comparison-table/index.tsx +29 -29
- package/src/contentful/blocks/comparison-table/types.ts +6 -6
- package/src/contentful/blocks/cookiebanner/index.test.tsx +277 -277
- package/src/contentful/blocks/cookiebanner/index.tsx +146 -146
- package/src/contentful/blocks/cookiebanner/type.ts +7 -7
- package/src/contentful/blocks/cta-callout/CtaCallout.stories.tsx +46 -46
- package/src/contentful/blocks/cta-callout/index.test.tsx +244 -244
- package/src/contentful/blocks/cta-callout/index.tsx +73 -73
- package/src/contentful/blocks/cta-callout/types.ts +26 -26
- package/src/contentful/blocks/dynamic-tabs/index.test.tsx +240 -240
- package/src/contentful/blocks/dynamic-tabs/index.tsx +204 -204
- package/src/contentful/blocks/dynamic-tabs/types.ts +21 -21
- package/src/contentful/blocks/email-input-block/index.test.tsx +213 -213
- package/src/contentful/blocks/email-input-block/index.tsx +121 -121
- package/src/contentful/blocks/email-input-block/types.ts +16 -16
- package/src/contentful/blocks/find-kinetic/FindKinetic.stories.tsx +23 -23
- package/src/contentful/blocks/find-kinetic/index.test.tsx +269 -269
- package/src/contentful/blocks/find-kinetic/index.tsx +138 -138
- package/src/contentful/blocks/find-kinetic/types.ts +20 -20
- package/src/contentful/blocks/floating-banner/FloatingBanner.stories.tsx +34 -34
- package/src/contentful/blocks/floating-banner/index.test.tsx +246 -246
- package/src/contentful/blocks/floating-banner/index.tsx +97 -97
- package/src/contentful/blocks/floating-banner/types.ts +22 -22
- package/src/contentful/blocks/footer/Footer.stories.tsx +317 -317
- package/src/contentful/blocks/footer/index.test.tsx +302 -302
- package/src/contentful/blocks/footer/index.tsx +91 -91
- package/src/contentful/blocks/footer/types.ts +13 -13
- package/src/contentful/blocks/image-promo-bar/ImagePromoBar.stories.tsx +23 -23
- package/src/contentful/blocks/image-promo-bar/helper.test.tsx +61 -61
- package/src/contentful/blocks/image-promo-bar/helper.tsx +28 -28
- package/src/contentful/blocks/image-promo-bar/index.test.tsx +467 -467
- package/src/contentful/blocks/image-promo-bar/index.tsx +8 -6
- package/src/contentful/blocks/image-promo-bar/types.ts +44 -44
- package/src/contentful/blocks/image-promo-bar/vimeo-embed.test.tsx +142 -142
- package/src/contentful/blocks/image-promo-bar/vimeo-embed.tsx +93 -93
- package/src/contentful/blocks/image-promo-bar/youtube-embed.test.tsx +104 -104
- package/src/contentful/blocks/image-promo-bar/youtube-embed.tsx +46 -46
- package/src/contentful/blocks/modal/constants.ts +53 -53
- package/src/contentful/blocks/modal/index.test.tsx +209 -209
- package/src/contentful/blocks/modal/index.tsx +108 -108
- package/src/contentful/blocks/modal/types.ts +12 -12
- package/src/contentful/blocks/navigation/Navigation.stories.mocks.tsx +78 -78
- package/src/contentful/blocks/navigation/Navigation.stories.tsx +138 -138
- package/src/contentful/blocks/navigation/desktop-link-groups.tsx/index.test.tsx +208 -208
- package/src/contentful/blocks/navigation/desktop-link-groups.tsx/index.tsx +141 -141
- package/src/contentful/blocks/navigation/index.test.tsx +924 -924
- package/src/contentful/blocks/navigation/index.tsx +569 -569
- package/src/contentful/blocks/navigation/mobile-link-groups.tsx/index.test.tsx +131 -131
- package/src/contentful/blocks/navigation/mobile-link-groups.tsx/index.tsx +82 -82
- package/src/contentful/blocks/navigation/types.ts +71 -71
- package/src/contentful/blocks/primary-hero/PrimaryHero.stories.tsx +23 -23
- package/src/contentful/blocks/primary-hero/index.test.tsx +286 -286
- package/src/contentful/blocks/primary-hero/index.tsx +239 -239
- package/src/contentful/blocks/primary-hero/types.ts +37 -37
- package/src/contentful/blocks/search-block/index.test.tsx +268 -268
- package/src/contentful/blocks/search-block/index.tsx +90 -90
- package/src/contentful/blocks/search-block/types.ts +15 -15
- package/src/contentful/blocks/shape-background-wrapper/ShapeBackgroundWrapper.stories.tsx +26 -26
- package/src/contentful/blocks/shape-background-wrapper/index.test.tsx +284 -284
- package/src/contentful/blocks/shape-background-wrapper/index.tsx +124 -124
- package/src/contentful/blocks/shape-background-wrapper/types.ts +36 -36
- package/src/contentful/blocks/text/Text.stories.tsx +23 -23
- package/src/contentful/blocks/text/index.test.tsx +36 -36
- package/src/contentful/blocks/text/index.tsx +12 -12
- package/src/contentful/blocks/text/types.ts +1 -1
- package/src/contentful/index.test.ts +45 -45
- package/src/contentful/index.ts +105 -105
- package/src/global-mocks/contentful/to-document.ts +25 -25
- package/src/global-mocks/cookie.ts +48 -48
- package/src/global-mocks/cx.ts +37 -37
- package/src/global-mocks/index.ts +89 -89
- package/src/global-mocks/speed-card-bg.ts +27 -27
- package/src/global-mocks/utm.ts +49 -49
- package/src/hooks/contentful/use-contentful-rich-text.test.tsx +1758 -1758
- package/src/hooks/contentful/use-contentful-rich-text.tsx +309 -309
- package/src/hooks/contentful/use-processed-check-list.test.tsx +277 -277
- package/src/hooks/contentful/use-processed-check-list.ts +63 -63
- package/src/hooks/use-body-scroll-lock.test.ts +134 -134
- package/src/hooks/use-body-scroll-lock.ts +34 -34
- package/src/hooks/use-carousel-swipe.test.ts +393 -393
- package/src/hooks/use-carousel-swipe.ts +264 -264
- package/src/hooks/use-outside-click.test.ts +142 -142
- package/src/hooks/use-outside-click.ts +17 -17
- package/src/index.ts +107 -107
- package/src/next/index.test.ts +7 -7
- package/src/next/index.ts +5 -5
- package/src/setupTests.ts +52 -52
- package/src/stories/DocsTemplate.tsx +24 -24
- package/src/styles/globals.css +343 -343
- package/src/types/global.d.ts +9 -9
- package/src/types/micro-components.ts +99 -99
- package/src/types/utm.ts +49 -49
- package/src/utils/contentful/to-document.test.ts +85 -85
- package/src/utils/contentful/to-document.ts +24 -24
- package/src/utils/cookie.test.ts +180 -180
- package/src/utils/cookie.ts +84 -84
- package/src/utils/cx.test.ts +90 -90
- package/src/utils/cx.ts +49 -49
- package/src/utils/index.test.ts +115 -115
- package/src/utils/index.ts +41 -41
- package/src/utils/speed-card-bg.test.ts +46 -46
- package/src/utils/speed-card-bg.ts +24 -24
- package/src/utils/utm.test.ts +359 -359
- package/src/utils/utm.ts +221 -221
|
@@ -1,201 +1,201 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { FloatingImageCard } from "./index";
|
|
3
|
-
|
|
4
|
-
import { render, screen } from "@testing-library/react";
|
|
5
|
-
|
|
6
|
-
jest.mock("@shared/components/next-image", () => ({
|
|
7
|
-
NextImage: ({ src, alt, width, height, className, onClick }: any) => (
|
|
8
|
-
<img
|
|
9
|
-
data-testid="next-image"
|
|
10
|
-
src={src}
|
|
11
|
-
alt={alt}
|
|
12
|
-
width={width}
|
|
13
|
-
height={height}
|
|
14
|
-
className={className}
|
|
15
|
-
onClick={onClick}
|
|
16
|
-
/>
|
|
17
|
-
),
|
|
18
|
-
}));
|
|
19
|
-
|
|
20
|
-
jest.mock("@shared/components/text", () => ({
|
|
21
|
-
Text: ({ as: Tag = "span", children, className }: any) => (
|
|
22
|
-
<Tag className={className}>{children}</Tag>
|
|
23
|
-
),
|
|
24
|
-
}));
|
|
25
|
-
|
|
26
|
-
jest.mock("../../button", () => ({
|
|
27
|
-
Button: ({ children, linkClassName, ...rest }: any) => (
|
|
28
|
-
<button data-testid="cta-button" className={linkClassName}>
|
|
29
|
-
{rest.buttonLabel || children}
|
|
30
|
-
</button>
|
|
31
|
-
),
|
|
32
|
-
}));
|
|
33
|
-
|
|
34
|
-
jest.mock("@shared/utils", () => ({
|
|
35
|
-
cx: (...args: any[]) => args.filter(Boolean).join(" "),
|
|
36
|
-
}));
|
|
37
|
-
|
|
38
|
-
describe("FloatingImageCard", () => {
|
|
39
|
-
const defaultCard = {
|
|
40
|
-
title: "Card Title",
|
|
41
|
-
header: "Card Header",
|
|
42
|
-
body: "Card body content",
|
|
43
|
-
image: { href: "/image.jpg", title: "Test Image", width: 400, height: 285 },
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
describe("Rendering", () => {
|
|
47
|
-
it("renders the section element", () => {
|
|
48
|
-
const { container } = render(<FloatingImageCard card={defaultCard} />);
|
|
49
|
-
expect(container.querySelector("section")).toBeInTheDocument();
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it("renders header text", () => {
|
|
53
|
-
render(<FloatingImageCard card={defaultCard} />);
|
|
54
|
-
expect(screen.getByText("Card Header")).toBeInTheDocument();
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("renders body text", () => {
|
|
58
|
-
render(<FloatingImageCard card={defaultCard} />);
|
|
59
|
-
expect(screen.getByText("Card body content")).toBeInTheDocument();
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it("renders image when provided", () => {
|
|
63
|
-
render(<FloatingImageCard card={defaultCard} />);
|
|
64
|
-
const img = screen.getByTestId("next-image");
|
|
65
|
-
expect(img).toHaveAttribute("src", "/image.jpg");
|
|
66
|
-
expect(img).toHaveAttribute("alt", "Test Image");
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it("does not render image when not provided", () => {
|
|
70
|
-
render(<FloatingImageCard card={{ ...defaultCard, image: undefined }} />);
|
|
71
|
-
expect(screen.queryByTestId("next-image")).not.toBeInTheDocument();
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it("does not render header when not provided", () => {
|
|
75
|
-
render(
|
|
76
|
-
<FloatingImageCard card={{ ...defaultCard, header: undefined }} />
|
|
77
|
-
);
|
|
78
|
-
expect(screen.queryByText("Card Header")).not.toBeInTheDocument();
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it("does not render body when not provided", () => {
|
|
82
|
-
render(<FloatingImageCard card={{ ...defaultCard, body: undefined }} />);
|
|
83
|
-
expect(screen.queryByText("Card body content")).not.toBeInTheDocument();
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
describe("CTA", () => {
|
|
88
|
-
it("renders CTA button when cta is provided", () => {
|
|
89
|
-
const card = {
|
|
90
|
-
...defaultCard,
|
|
91
|
-
cta: { buttonLabel: "Learn More", href: "/learn" },
|
|
92
|
-
};
|
|
93
|
-
render(<FloatingImageCard card={card} />);
|
|
94
|
-
expect(screen.getByTestId("cta-button")).toBeInTheDocument();
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it("does not render CTA when not provided", () => {
|
|
98
|
-
render(<FloatingImageCard card={defaultCard} />);
|
|
99
|
-
expect(screen.queryByTestId("cta-button")).not.toBeInTheDocument();
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
describe("CTA alignment", () => {
|
|
104
|
-
it("applies left alignment by default", () => {
|
|
105
|
-
const card = {
|
|
106
|
-
...defaultCard,
|
|
107
|
-
cta: { buttonLabel: "Click", href: "/click" },
|
|
108
|
-
};
|
|
109
|
-
render(<FloatingImageCard card={card} />);
|
|
110
|
-
const ctaWrapper = screen.getByTestId("cta-button").parentElement;
|
|
111
|
-
expect(ctaWrapper?.className).toContain("justify-start");
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it("applies center alignment", () => {
|
|
115
|
-
const card = {
|
|
116
|
-
...defaultCard,
|
|
117
|
-
cta: { buttonLabel: "Click", href: "/click" },
|
|
118
|
-
ctaAlignment: "center" as const,
|
|
119
|
-
};
|
|
120
|
-
render(<FloatingImageCard card={card} />);
|
|
121
|
-
const ctaWrapper = screen.getByTestId("cta-button").parentElement;
|
|
122
|
-
expect(ctaWrapper?.className).toContain("justify-center");
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
it("applies right alignment", () => {
|
|
126
|
-
const card = {
|
|
127
|
-
...defaultCard,
|
|
128
|
-
cta: { buttonLabel: "Click", href: "/click" },
|
|
129
|
-
ctaAlignment: "right" as const,
|
|
130
|
-
};
|
|
131
|
-
render(<FloatingImageCard card={card} />);
|
|
132
|
-
const ctaWrapper = screen.getByTestId("cta-button").parentElement;
|
|
133
|
-
expect(ctaWrapper?.className).toContain("justify-end");
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
describe("PromoBar mode", () => {
|
|
138
|
-
it("renders only image when isPromoBarImg is true", () => {
|
|
139
|
-
const card = {
|
|
140
|
-
...defaultCard,
|
|
141
|
-
isPromoBarImg: true,
|
|
142
|
-
};
|
|
143
|
-
const { container } = render(<FloatingImageCard card={card} />);
|
|
144
|
-
expect(container.querySelector("section")).not.toBeInTheDocument();
|
|
145
|
-
expect(screen.getByTestId("next-image")).toBeInTheDocument();
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it("returns null when isPromoBarImg is true and no image", () => {
|
|
149
|
-
const card = {
|
|
150
|
-
...defaultCard,
|
|
151
|
-
image: undefined,
|
|
152
|
-
isPromoBarImg: true,
|
|
153
|
-
};
|
|
154
|
-
const { container } = render(<FloatingImageCard card={card} />);
|
|
155
|
-
expect(container.firstChild).toBeNull();
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
describe("Image link", () => {
|
|
160
|
-
it("makes image clickable when imageLink is provided", () => {
|
|
161
|
-
const windowOpen = jest.spyOn(window, "open").mockImplementation();
|
|
162
|
-
const card = {
|
|
163
|
-
...defaultCard,
|
|
164
|
-
imageLink: "https://example.com",
|
|
165
|
-
};
|
|
166
|
-
render(<FloatingImageCard card={card} />);
|
|
167
|
-
const img = screen.getByTestId("next-image");
|
|
168
|
-
img.click();
|
|
169
|
-
expect(windowOpen).toHaveBeenCalledWith("https://example.com", "_blank");
|
|
170
|
-
windowOpen.mockRestore();
|
|
171
|
-
});
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
describe("Layout props", () => {
|
|
175
|
-
it("applies lgWidth class", () => {
|
|
176
|
-
const { container } = render(
|
|
177
|
-
<FloatingImageCard card={defaultCard} lgWidth="lg:w-1/3" />
|
|
178
|
-
);
|
|
179
|
-
expect(container.querySelector("section")?.className).toContain(
|
|
180
|
-
"lg:w-1/3"
|
|
181
|
-
);
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
it("applies mdWidth class", () => {
|
|
185
|
-
const { container } = render(
|
|
186
|
-
<FloatingImageCard card={defaultCard} mdWidth="md:w-1/2" />
|
|
187
|
-
);
|
|
188
|
-
expect(container.querySelector("section")?.className).toContain(
|
|
189
|
-
"md:w-1/2"
|
|
190
|
-
);
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
it("applies shadow class when shadow is true", () => {
|
|
194
|
-
const card = { ...defaultCard, shadow: true };
|
|
195
|
-
const { container } = render(<FloatingImageCard card={card} />);
|
|
196
|
-
expect(container.querySelector("section")?.className).toContain(
|
|
197
|
-
"shadow-card"
|
|
198
|
-
);
|
|
199
|
-
});
|
|
200
|
-
});
|
|
201
|
-
});
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { FloatingImageCard } from "./index";
|
|
3
|
+
|
|
4
|
+
import { render, screen } from "@testing-library/react";
|
|
5
|
+
|
|
6
|
+
jest.mock("@shared/components/next-image", () => ({
|
|
7
|
+
NextImage: ({ src, alt, width, height, className, onClick }: any) => (
|
|
8
|
+
<img
|
|
9
|
+
data-testid="next-image"
|
|
10
|
+
src={src}
|
|
11
|
+
alt={alt}
|
|
12
|
+
width={width}
|
|
13
|
+
height={height}
|
|
14
|
+
className={className}
|
|
15
|
+
onClick={onClick}
|
|
16
|
+
/>
|
|
17
|
+
),
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
jest.mock("@shared/components/text", () => ({
|
|
21
|
+
Text: ({ as: Tag = "span", children, className }: any) => (
|
|
22
|
+
<Tag className={className}>{children}</Tag>
|
|
23
|
+
),
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
jest.mock("../../button", () => ({
|
|
27
|
+
Button: ({ children, linkClassName, ...rest }: any) => (
|
|
28
|
+
<button data-testid="cta-button" className={linkClassName}>
|
|
29
|
+
{rest.buttonLabel || children}
|
|
30
|
+
</button>
|
|
31
|
+
),
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
jest.mock("@shared/utils", () => ({
|
|
35
|
+
cx: (...args: any[]) => args.filter(Boolean).join(" "),
|
|
36
|
+
}));
|
|
37
|
+
|
|
38
|
+
describe("FloatingImageCard", () => {
|
|
39
|
+
const defaultCard = {
|
|
40
|
+
title: "Card Title",
|
|
41
|
+
header: "Card Header",
|
|
42
|
+
body: "Card body content",
|
|
43
|
+
image: { href: "/image.jpg", title: "Test Image", width: 400, height: 285 },
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
describe("Rendering", () => {
|
|
47
|
+
it("renders the section element", () => {
|
|
48
|
+
const { container } = render(<FloatingImageCard card={defaultCard} />);
|
|
49
|
+
expect(container.querySelector("section")).toBeInTheDocument();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("renders header text", () => {
|
|
53
|
+
render(<FloatingImageCard card={defaultCard} />);
|
|
54
|
+
expect(screen.getByText("Card Header")).toBeInTheDocument();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("renders body text", () => {
|
|
58
|
+
render(<FloatingImageCard card={defaultCard} />);
|
|
59
|
+
expect(screen.getByText("Card body content")).toBeInTheDocument();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("renders image when provided", () => {
|
|
63
|
+
render(<FloatingImageCard card={defaultCard} />);
|
|
64
|
+
const img = screen.getByTestId("next-image");
|
|
65
|
+
expect(img).toHaveAttribute("src", "/image.jpg");
|
|
66
|
+
expect(img).toHaveAttribute("alt", "Test Image");
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("does not render image when not provided", () => {
|
|
70
|
+
render(<FloatingImageCard card={{ ...defaultCard, image: undefined }} />);
|
|
71
|
+
expect(screen.queryByTestId("next-image")).not.toBeInTheDocument();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("does not render header when not provided", () => {
|
|
75
|
+
render(
|
|
76
|
+
<FloatingImageCard card={{ ...defaultCard, header: undefined }} />
|
|
77
|
+
);
|
|
78
|
+
expect(screen.queryByText("Card Header")).not.toBeInTheDocument();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("does not render body when not provided", () => {
|
|
82
|
+
render(<FloatingImageCard card={{ ...defaultCard, body: undefined }} />);
|
|
83
|
+
expect(screen.queryByText("Card body content")).not.toBeInTheDocument();
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
describe("CTA", () => {
|
|
88
|
+
it("renders CTA button when cta is provided", () => {
|
|
89
|
+
const card = {
|
|
90
|
+
...defaultCard,
|
|
91
|
+
cta: { buttonLabel: "Learn More", href: "/learn" },
|
|
92
|
+
};
|
|
93
|
+
render(<FloatingImageCard card={card} />);
|
|
94
|
+
expect(screen.getByTestId("cta-button")).toBeInTheDocument();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("does not render CTA when not provided", () => {
|
|
98
|
+
render(<FloatingImageCard card={defaultCard} />);
|
|
99
|
+
expect(screen.queryByTestId("cta-button")).not.toBeInTheDocument();
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe("CTA alignment", () => {
|
|
104
|
+
it("applies left alignment by default", () => {
|
|
105
|
+
const card = {
|
|
106
|
+
...defaultCard,
|
|
107
|
+
cta: { buttonLabel: "Click", href: "/click" },
|
|
108
|
+
};
|
|
109
|
+
render(<FloatingImageCard card={card} />);
|
|
110
|
+
const ctaWrapper = screen.getByTestId("cta-button").parentElement;
|
|
111
|
+
expect(ctaWrapper?.className).toContain("justify-start");
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("applies center alignment", () => {
|
|
115
|
+
const card = {
|
|
116
|
+
...defaultCard,
|
|
117
|
+
cta: { buttonLabel: "Click", href: "/click" },
|
|
118
|
+
ctaAlignment: "center" as const,
|
|
119
|
+
};
|
|
120
|
+
render(<FloatingImageCard card={card} />);
|
|
121
|
+
const ctaWrapper = screen.getByTestId("cta-button").parentElement;
|
|
122
|
+
expect(ctaWrapper?.className).toContain("justify-center");
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("applies right alignment", () => {
|
|
126
|
+
const card = {
|
|
127
|
+
...defaultCard,
|
|
128
|
+
cta: { buttonLabel: "Click", href: "/click" },
|
|
129
|
+
ctaAlignment: "right" as const,
|
|
130
|
+
};
|
|
131
|
+
render(<FloatingImageCard card={card} />);
|
|
132
|
+
const ctaWrapper = screen.getByTestId("cta-button").parentElement;
|
|
133
|
+
expect(ctaWrapper?.className).toContain("justify-end");
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
describe("PromoBar mode", () => {
|
|
138
|
+
it("renders only image when isPromoBarImg is true", () => {
|
|
139
|
+
const card = {
|
|
140
|
+
...defaultCard,
|
|
141
|
+
isPromoBarImg: true,
|
|
142
|
+
};
|
|
143
|
+
const { container } = render(<FloatingImageCard card={card} />);
|
|
144
|
+
expect(container.querySelector("section")).not.toBeInTheDocument();
|
|
145
|
+
expect(screen.getByTestId("next-image")).toBeInTheDocument();
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it("returns null when isPromoBarImg is true and no image", () => {
|
|
149
|
+
const card = {
|
|
150
|
+
...defaultCard,
|
|
151
|
+
image: undefined,
|
|
152
|
+
isPromoBarImg: true,
|
|
153
|
+
};
|
|
154
|
+
const { container } = render(<FloatingImageCard card={card} />);
|
|
155
|
+
expect(container.firstChild).toBeNull();
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
describe("Image link", () => {
|
|
160
|
+
it("makes image clickable when imageLink is provided", () => {
|
|
161
|
+
const windowOpen = jest.spyOn(window, "open").mockImplementation();
|
|
162
|
+
const card = {
|
|
163
|
+
...defaultCard,
|
|
164
|
+
imageLink: "https://example.com",
|
|
165
|
+
};
|
|
166
|
+
render(<FloatingImageCard card={card} />);
|
|
167
|
+
const img = screen.getByTestId("next-image");
|
|
168
|
+
img.click();
|
|
169
|
+
expect(windowOpen).toHaveBeenCalledWith("https://example.com", "_blank");
|
|
170
|
+
windowOpen.mockRestore();
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
describe("Layout props", () => {
|
|
175
|
+
it("applies lgWidth class", () => {
|
|
176
|
+
const { container } = render(
|
|
177
|
+
<FloatingImageCard card={defaultCard} lgWidth="lg:w-1/3" />
|
|
178
|
+
);
|
|
179
|
+
expect(container.querySelector("section")?.className).toContain(
|
|
180
|
+
"lg:w-1/3"
|
|
181
|
+
);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it("applies mdWidth class", () => {
|
|
185
|
+
const { container } = render(
|
|
186
|
+
<FloatingImageCard card={defaultCard} mdWidth="md:w-1/2" />
|
|
187
|
+
);
|
|
188
|
+
expect(container.querySelector("section")?.className).toContain(
|
|
189
|
+
"md:w-1/2"
|
|
190
|
+
);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it("applies shadow class when shadow is true", () => {
|
|
194
|
+
const card = { ...defaultCard, shadow: true };
|
|
195
|
+
const { container } = render(<FloatingImageCard card={card} />);
|
|
196
|
+
expect(container.querySelector("section")?.className).toContain(
|
|
197
|
+
"shadow-card"
|
|
198
|
+
);
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
});
|
|
@@ -1,119 +1,119 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { Button } from "../../button";
|
|
3
|
-
import { FloatingImageCardProps } from "./types";
|
|
4
|
-
|
|
5
|
-
import { NextImage } from "@shared/components/next-image";
|
|
6
|
-
import { Text } from "@shared/components/text";
|
|
7
|
-
import { cx } from "@shared/utils";
|
|
8
|
-
|
|
9
|
-
const alignmentClasses: Record<string, string> = {
|
|
10
|
-
left: "flex w-full justify-start",
|
|
11
|
-
right: "flex w-full justify-end",
|
|
12
|
-
center: "flex w-full justify-center",
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export const FloatingImageCard: React.FC<FloatingImageCardProps> = ({
|
|
16
|
-
card,
|
|
17
|
-
lgWidth,
|
|
18
|
-
mdWidth,
|
|
19
|
-
}) => {
|
|
20
|
-
const {
|
|
21
|
-
image,
|
|
22
|
-
title,
|
|
23
|
-
header,
|
|
24
|
-
body,
|
|
25
|
-
cta,
|
|
26
|
-
ctaAlignment,
|
|
27
|
-
imageLink,
|
|
28
|
-
imageClassName,
|
|
29
|
-
className,
|
|
30
|
-
isPromoBarImg = false,
|
|
31
|
-
shadow = false,
|
|
32
|
-
} = card;
|
|
33
|
-
|
|
34
|
-
const ctaAlignmentClass = ctaAlignment
|
|
35
|
-
? alignmentClasses[ctaAlignment]
|
|
36
|
-
: alignmentClasses.left;
|
|
37
|
-
const imageLinkAvailableClass = imageLink ? "cursor-pointer" : "";
|
|
38
|
-
|
|
39
|
-
const handleImageClick = imageLink
|
|
40
|
-
? () => {
|
|
41
|
-
if (typeof window !== "undefined") {
|
|
42
|
-
window.open(imageLink, "_blank");
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
: undefined;
|
|
46
|
-
|
|
47
|
-
if (isPromoBarImg) {
|
|
48
|
-
return image?.href ? (
|
|
49
|
-
<NextImage
|
|
50
|
-
src={image.href}
|
|
51
|
-
alt={image.title ?? title ?? "promo-bar-image"}
|
|
52
|
-
width={148}
|
|
53
|
-
height={40}
|
|
54
|
-
onClick={handleImageClick}
|
|
55
|
-
className={imageLinkAvailableClass}
|
|
56
|
-
/>
|
|
57
|
-
) : null;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
<section
|
|
62
|
-
aria-labelledby="Image Card"
|
|
63
|
-
className={cx(
|
|
64
|
-
"callout-card relative flex h-full w-full flex-col gap-4 p-0 md:items-start lg:gap-6",
|
|
65
|
-
shadow && "rounded-3xl shadow-card",
|
|
66
|
-
mdWidth,
|
|
67
|
-
lgWidth,
|
|
68
|
-
className
|
|
69
|
-
)}
|
|
70
|
-
>
|
|
71
|
-
{image?.href ? (
|
|
72
|
-
<div
|
|
73
|
-
className={cx(
|
|
74
|
-
"relative aspect-video w-full overflow-hidden rounded-[40px] sm:mb-1 md:flex-none lg:mb-0",
|
|
75
|
-
imageClassName
|
|
76
|
-
)}
|
|
77
|
-
>
|
|
78
|
-
<NextImage
|
|
79
|
-
src={image.href}
|
|
80
|
-
alt={image.title ?? title ?? "card-image"}
|
|
81
|
-
width={image.width || 400}
|
|
82
|
-
height={image.height || 285}
|
|
83
|
-
onClick={handleImageClick}
|
|
84
|
-
className={cx(
|
|
85
|
-
"h-full max-h-[285px] w-full object-cover",
|
|
86
|
-
imageLinkAvailableClass
|
|
87
|
-
)}
|
|
88
|
-
/>
|
|
89
|
-
</div>
|
|
90
|
-
) : null}
|
|
91
|
-
|
|
92
|
-
{header ? (
|
|
93
|
-
<Text as="h6" className="heading6 font-black text-text lg:pb-2">
|
|
94
|
-
{header}
|
|
95
|
-
</Text>
|
|
96
|
-
) : null}
|
|
97
|
-
|
|
98
|
-
{body ? (
|
|
99
|
-
<Text as="div" className="body2 mb-0 flex-1 text-text">
|
|
100
|
-
{body}
|
|
101
|
-
</Text>
|
|
102
|
-
) : null}
|
|
103
|
-
|
|
104
|
-
<div className={cx(ctaAlignmentClass, "mt-auto")}>
|
|
105
|
-
{cta ? (
|
|
106
|
-
<Button
|
|
107
|
-
linkVariant="unstyled"
|
|
108
|
-
linkClassName="label1 flex items-center gap-2 text-text"
|
|
109
|
-
{...cta}
|
|
110
|
-
iconName="expand_circle_right"
|
|
111
|
-
iconFill={1}
|
|
112
|
-
/>
|
|
113
|
-
) : null}
|
|
114
|
-
</div>
|
|
115
|
-
</section>
|
|
116
|
-
);
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
export default FloatingImageCard;
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Button } from "../../button";
|
|
3
|
+
import { FloatingImageCardProps } from "./types";
|
|
4
|
+
|
|
5
|
+
import { NextImage } from "@shared/components/next-image";
|
|
6
|
+
import { Text } from "@shared/components/text";
|
|
7
|
+
import { cx } from "@shared/utils";
|
|
8
|
+
|
|
9
|
+
const alignmentClasses: Record<string, string> = {
|
|
10
|
+
left: "flex w-full justify-start",
|
|
11
|
+
right: "flex w-full justify-end",
|
|
12
|
+
center: "flex w-full justify-center",
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const FloatingImageCard: React.FC<FloatingImageCardProps> = ({
|
|
16
|
+
card,
|
|
17
|
+
lgWidth,
|
|
18
|
+
mdWidth,
|
|
19
|
+
}) => {
|
|
20
|
+
const {
|
|
21
|
+
image,
|
|
22
|
+
title,
|
|
23
|
+
header,
|
|
24
|
+
body,
|
|
25
|
+
cta,
|
|
26
|
+
ctaAlignment,
|
|
27
|
+
imageLink,
|
|
28
|
+
imageClassName,
|
|
29
|
+
className,
|
|
30
|
+
isPromoBarImg = false,
|
|
31
|
+
shadow = false,
|
|
32
|
+
} = card;
|
|
33
|
+
|
|
34
|
+
const ctaAlignmentClass = ctaAlignment
|
|
35
|
+
? alignmentClasses[ctaAlignment]
|
|
36
|
+
: alignmentClasses.left;
|
|
37
|
+
const imageLinkAvailableClass = imageLink ? "cursor-pointer" : "";
|
|
38
|
+
|
|
39
|
+
const handleImageClick = imageLink
|
|
40
|
+
? () => {
|
|
41
|
+
if (typeof window !== "undefined") {
|
|
42
|
+
window.open(imageLink, "_blank");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
: undefined;
|
|
46
|
+
|
|
47
|
+
if (isPromoBarImg) {
|
|
48
|
+
return image?.href ? (
|
|
49
|
+
<NextImage
|
|
50
|
+
src={image.href}
|
|
51
|
+
alt={image.title ?? title ?? "promo-bar-image"}
|
|
52
|
+
width={148}
|
|
53
|
+
height={40}
|
|
54
|
+
onClick={handleImageClick}
|
|
55
|
+
className={imageLinkAvailableClass}
|
|
56
|
+
/>
|
|
57
|
+
) : null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<section
|
|
62
|
+
aria-labelledby="Image Card"
|
|
63
|
+
className={cx(
|
|
64
|
+
"callout-card relative flex h-full w-full flex-col gap-4 p-0 md:items-start lg:gap-6",
|
|
65
|
+
shadow && "rounded-3xl shadow-card",
|
|
66
|
+
mdWidth,
|
|
67
|
+
lgWidth,
|
|
68
|
+
className
|
|
69
|
+
)}
|
|
70
|
+
>
|
|
71
|
+
{image?.href ? (
|
|
72
|
+
<div
|
|
73
|
+
className={cx(
|
|
74
|
+
"relative aspect-video w-full overflow-hidden rounded-[40px] sm:mb-1 md:flex-none lg:mb-0",
|
|
75
|
+
imageClassName
|
|
76
|
+
)}
|
|
77
|
+
>
|
|
78
|
+
<NextImage
|
|
79
|
+
src={image.href}
|
|
80
|
+
alt={image.title ?? title ?? "card-image"}
|
|
81
|
+
width={image.width || 400}
|
|
82
|
+
height={image.height || 285}
|
|
83
|
+
onClick={handleImageClick}
|
|
84
|
+
className={cx(
|
|
85
|
+
"h-full max-h-[285px] w-full object-cover",
|
|
86
|
+
imageLinkAvailableClass
|
|
87
|
+
)}
|
|
88
|
+
/>
|
|
89
|
+
</div>
|
|
90
|
+
) : null}
|
|
91
|
+
|
|
92
|
+
{header ? (
|
|
93
|
+
<Text as="h6" className="heading6 font-black text-text lg:pb-2">
|
|
94
|
+
{header}
|
|
95
|
+
</Text>
|
|
96
|
+
) : null}
|
|
97
|
+
|
|
98
|
+
{body ? (
|
|
99
|
+
<Text as="div" className="body2 mb-0 flex-1 text-text">
|
|
100
|
+
{body}
|
|
101
|
+
</Text>
|
|
102
|
+
) : null}
|
|
103
|
+
|
|
104
|
+
<div className={cx(ctaAlignmentClass, "mt-auto")}>
|
|
105
|
+
{cta ? (
|
|
106
|
+
<Button
|
|
107
|
+
linkVariant="unstyled"
|
|
108
|
+
linkClassName="label1 flex items-center gap-2 text-text"
|
|
109
|
+
{...cta}
|
|
110
|
+
iconName="expand_circle_right"
|
|
111
|
+
iconFill={1}
|
|
112
|
+
/>
|
|
113
|
+
) : null}
|
|
114
|
+
</div>
|
|
115
|
+
</section>
|
|
116
|
+
);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export default FloatingImageCard;
|