@windstream/react-shared-components 0.1.93 → 0.1.94
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 +6 -6
- package/dist/index.d.ts +2 -2
- package/dist/index.esm.js +13 -5
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +13 -5
- 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 -185
- package/src/components/accordion/Accordion.stories.tsx +230 -230
- package/src/components/accordion/index.test.tsx +270 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- package/src/components/checklist/index.tsx +96 -61
- package/src/components/checklist/types.ts +23 -17
- package/src/components/collapse/Collapse.stories.tsx +255 -255
- package/src/components/collapse/index.test.tsx +277 -0
- package/src/components/collapse/index.tsx +47 -46
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- package/src/contentful/blocks/accordion/index.tsx +114 -112
- package/src/contentful/blocks/accordion/types.ts +34 -34
- package/src/contentful/blocks/address-input-banner/index.test.tsx +132 -0
- 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 -0
- 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 -156
- package/src/contentful/blocks/blogs-grid/index.test.tsx +355 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- package/src/contentful/blocks/cards/index.tsx +13 -13
- package/src/contentful/blocks/cards/product-card/index.test.tsx +263 -0
- 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 -0
- 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 -0
- 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 -0
- package/src/contentful/blocks/carousel/helper.tsx +494 -494
- package/src/contentful/blocks/carousel/index.test.tsx +308 -0
- package/src/contentful/blocks/carousel/index.tsx +87 -87
- package/src/contentful/blocks/carousel/types.test.ts +16 -0
- package/src/contentful/blocks/carousel/types.ts +145 -145
- package/src/contentful/blocks/cart-retention-banner/index.test.tsx +409 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- package/src/contentful/blocks/email-input-block/index.tsx +121 -116
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- package/src/contentful/blocks/image-promo-bar/helper.tsx +28 -28
- package/src/contentful/blocks/image-promo-bar/index.test.tsx +467 -0
- package/src/contentful/blocks/image-promo-bar/index.tsx +246 -246
- package/src/contentful/blocks/image-promo-bar/types.ts +44 -44
- package/src/contentful/blocks/image-promo-bar/vimeo-embed.test.tsx +142 -0
- package/src/contentful/blocks/image-promo-bar/vimeo-embed.tsx +93 -93
- package/src/contentful/blocks/image-promo-bar/youtube-embed.test.tsx +104 -0
- 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 -0
- 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 -0
- package/src/contentful/blocks/navigation/desktop-link-groups.tsx/index.tsx +141 -141
- package/src/contentful/blocks/navigation/index.test.tsx +924 -0
- package/src/contentful/blocks/navigation/index.tsx +569 -569
- package/src/contentful/blocks/navigation/mobile-link-groups.tsx/index.test.tsx +131 -0
- 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 -0
- package/src/contentful/blocks/primary-hero/index.tsx +239 -236
- package/src/contentful/blocks/primary-hero/types.ts +37 -37
- package/src/contentful/blocks/search-block/index.test.tsx +268 -0
- 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 -0
- 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 -0
- 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 -0
- package/src/contentful/index.ts +105 -105
- package/src/global-mocks/contentful/to-document.ts +25 -0
- package/src/global-mocks/cookie.ts +48 -0
- package/src/global-mocks/cx.ts +37 -0
- package/src/global-mocks/index.ts +89 -0
- package/src/global-mocks/speed-card-bg.ts +27 -0
- package/src/global-mocks/utm.ts +49 -0
- package/src/hooks/contentful/use-contentful-rich-text.test.tsx +1758 -0
- package/src/hooks/contentful/use-contentful-rich-text.tsx +309 -309
- package/src/hooks/contentful/use-processed-check-list.test.tsx +277 -0
- package/src/hooks/contentful/use-processed-check-list.ts +63 -63
- package/src/hooks/use-body-scroll-lock.test.ts +134 -0
- package/src/hooks/use-body-scroll-lock.ts +34 -34
- package/src/hooks/use-carousel-swipe.test.ts +393 -0
- package/src/hooks/use-carousel-swipe.ts +264 -264
- package/src/hooks/use-outside-click.test.ts +142 -0
- package/src/hooks/use-outside-click.ts +17 -17
- package/src/index.ts +107 -107
- package/src/next/index.test.ts +7 -0
- package/src/next/index.ts +5 -5
- package/src/setupTests.ts +52 -46
- 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 -0
- package/src/utils/contentful/to-document.ts +24 -24
- package/src/utils/cookie.test.ts +180 -0
- package/src/utils/cookie.ts +84 -84
- package/src/utils/cx.test.ts +90 -0
- package/src/utils/cx.ts +49 -49
- package/src/utils/index.test.ts +115 -0
- package/src/utils/index.ts +41 -41
- package/src/utils/speed-card-bg.test.ts +46 -0
- package/src/utils/speed-card-bg.ts +24 -24
- package/src/utils/utm.test.ts +359 -0
- package/src/utils/utm.ts +221 -221
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import "@testing-library/jest-dom";
|
|
2
|
+
|
|
3
|
+
import React from "react";
|
|
4
|
+
import CookieBanner from "./index";
|
|
5
|
+
|
|
6
|
+
import { act, fireEvent, render, screen } from "@testing-library/react";
|
|
7
|
+
|
|
8
|
+
// Mock cookie utilities
|
|
9
|
+
const mockGetCookie = jest.fn();
|
|
10
|
+
const mockSetCookie = jest.fn();
|
|
11
|
+
|
|
12
|
+
jest.mock("../../../utils/cookie", () => ({
|
|
13
|
+
getCookie: (...args: any[]) => mockGetCookie(...args),
|
|
14
|
+
setCookie: (...args: any[]) => mockSetCookie(...args),
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
jest.mock("@shared/components/material-icon", () => ({
|
|
18
|
+
MaterialIcon: ({ name }: any) => (
|
|
19
|
+
<span data-testid={`icon-${name}`}>{name}</span>
|
|
20
|
+
),
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
jest.mock("@shared/contentful/blocks/button", () => ({
|
|
24
|
+
Button: (props: any) => (
|
|
25
|
+
<button onClick={props.onClick} data-testid="cookie-button">
|
|
26
|
+
{props.children}
|
|
27
|
+
</button>
|
|
28
|
+
),
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
describe("CookieBanner", () => {
|
|
32
|
+
const defaultContent = {
|
|
33
|
+
entryName: "Cookie Notice",
|
|
34
|
+
anchorId: "cookie-banner",
|
|
35
|
+
title: "Cookies",
|
|
36
|
+
richText: <p>We use cookies to improve your experience.</p>,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
beforeEach(() => {
|
|
40
|
+
jest.useFakeTimers();
|
|
41
|
+
mockGetCookie.mockReset();
|
|
42
|
+
mockSetCookie.mockReset();
|
|
43
|
+
// Default: cookie not set (banner should show)
|
|
44
|
+
mockGetCookie.mockReturnValue(null);
|
|
45
|
+
// Reset body classes
|
|
46
|
+
document.body.classList.remove("cookie-banner-visible");
|
|
47
|
+
// Reset CSS custom property
|
|
48
|
+
document.documentElement.style.removeProperty("--cookie-banner-height");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
afterEach(() => {
|
|
52
|
+
jest.useRealTimers();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe("cookie management", () => {
|
|
56
|
+
it("shows the banner when cookieBannerClosed cookie is not set", () => {
|
|
57
|
+
mockGetCookie.mockReturnValue(null);
|
|
58
|
+
render(<CookieBanner content={defaultContent} />);
|
|
59
|
+
expect(
|
|
60
|
+
screen.getByLabelText("Cookie usage notification")
|
|
61
|
+
).toBeInTheDocument();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("hides the banner when cookieBannerClosed cookie is true", () => {
|
|
65
|
+
mockGetCookie.mockReturnValue("true");
|
|
66
|
+
const { container } = render(<CookieBanner content={defaultContent} />);
|
|
67
|
+
expect(container.firstChild).toBeNull();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("calls getCookie with cookieBannerClosed key", () => {
|
|
71
|
+
render(<CookieBanner content={defaultContent} />);
|
|
72
|
+
expect(mockGetCookie).toHaveBeenCalledWith("cookieBannerClosed");
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("sets cookieBannerClosed cookie on close", () => {
|
|
76
|
+
mockGetCookie.mockReturnValue(null);
|
|
77
|
+
render(<CookieBanner content={defaultContent} />);
|
|
78
|
+
fireEvent.click(screen.getByTestId("cookie-button"));
|
|
79
|
+
expect(mockSetCookie).toHaveBeenCalledWith(
|
|
80
|
+
"cookieBannerClosed",
|
|
81
|
+
true,
|
|
82
|
+
expect.objectContaining({ expires: expect.any(Date) })
|
|
83
|
+
);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("sets cookie with correct expiration (30 days)", () => {
|
|
87
|
+
mockGetCookie.mockReturnValue(null);
|
|
88
|
+
render(<CookieBanner content={defaultContent} />);
|
|
89
|
+
|
|
90
|
+
const now = Date.now();
|
|
91
|
+
fireEvent.click(screen.getByTestId("cookie-button"));
|
|
92
|
+
|
|
93
|
+
const callArgs = mockSetCookie.mock.calls[0];
|
|
94
|
+
const expirationDate = callArgs[2].expires;
|
|
95
|
+
// 43200 minutes * 60 * 1000 = 30 days in milliseconds
|
|
96
|
+
const expectedMs = 43200 * 60 * 1000;
|
|
97
|
+
const diff = expirationDate.getTime() - now;
|
|
98
|
+
expect(diff).toBeGreaterThanOrEqual(expectedMs - 1000);
|
|
99
|
+
expect(diff).toBeLessThanOrEqual(expectedMs + 1000);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe("rendering", () => {
|
|
104
|
+
it("renders with fixed positioning", () => {
|
|
105
|
+
render(<CookieBanner content={defaultContent} />);
|
|
106
|
+
const banner = screen.getByLabelText("Cookie usage notification");
|
|
107
|
+
expect(banner.className).toContain("fixed");
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("renders the rich text content", () => {
|
|
111
|
+
render(<CookieBanner content={defaultContent} />);
|
|
112
|
+
expect(
|
|
113
|
+
screen.getByText("We use cookies to improve your experience.")
|
|
114
|
+
).toBeInTheDocument();
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it("does not render rich text when richText is falsy", () => {
|
|
118
|
+
const content = { ...defaultContent, richText: null as any };
|
|
119
|
+
render(<CookieBanner content={content} />);
|
|
120
|
+
const banner = screen.getByLabelText("Cookie usage notification");
|
|
121
|
+
// Banner is shown but no rich text inside
|
|
122
|
+
expect(banner.querySelector(".mx-auto")).toBeNull();
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("renders close button with close icon", () => {
|
|
126
|
+
render(<CookieBanner content={defaultContent} />);
|
|
127
|
+
expect(screen.getByTestId("icon-close")).toBeInTheDocument();
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it("has correct z-index class", () => {
|
|
131
|
+
render(<CookieBanner content={defaultContent} />);
|
|
132
|
+
const banner = screen.getByLabelText("Cookie usage notification");
|
|
133
|
+
expect(banner.className).toContain("z-[1000]");
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it("renders with correct max width", () => {
|
|
137
|
+
render(<CookieBanner content={defaultContent} />);
|
|
138
|
+
const banner = screen.getByLabelText("Cookie usage notification");
|
|
139
|
+
expect(banner.className).toContain("max-w-[350px]");
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("renders with correct positioning styles", () => {
|
|
143
|
+
render(<CookieBanner content={defaultContent} />);
|
|
144
|
+
const banner = screen.getByLabelText("Cookie usage notification");
|
|
145
|
+
expect(banner.style.bottom).toBe("0px");
|
|
146
|
+
expect(banner.style.right).toBe("20px");
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it("has id cookie-banner", () => {
|
|
150
|
+
render(<CookieBanner content={defaultContent} />);
|
|
151
|
+
expect(document.getElementById("cookie-banner")).toBeInTheDocument();
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
describe("close behavior", () => {
|
|
156
|
+
it("hides banner on close button click", () => {
|
|
157
|
+
mockGetCookie.mockReturnValue(null);
|
|
158
|
+
render(<CookieBanner content={defaultContent} />);
|
|
159
|
+
expect(
|
|
160
|
+
screen.getByLabelText("Cookie usage notification")
|
|
161
|
+
).toBeInTheDocument();
|
|
162
|
+
fireEvent.click(screen.getByTestId("cookie-button"));
|
|
163
|
+
expect(
|
|
164
|
+
screen.queryByLabelText("Cookie usage notification")
|
|
165
|
+
).not.toBeInTheDocument();
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
describe("body class management", () => {
|
|
170
|
+
it("adds cookie-banner-visible class to body when visible", () => {
|
|
171
|
+
mockGetCookie.mockReturnValue(null);
|
|
172
|
+
render(<CookieBanner content={defaultContent} />);
|
|
173
|
+
expect(document.body.classList.contains("cookie-banner-visible")).toBe(
|
|
174
|
+
true
|
|
175
|
+
);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it("removes cookie-banner-visible class when banner is hidden", () => {
|
|
179
|
+
mockGetCookie.mockReturnValue(null);
|
|
180
|
+
render(<CookieBanner content={defaultContent} />);
|
|
181
|
+
fireEvent.click(screen.getByTestId("cookie-button"));
|
|
182
|
+
expect(document.body.classList.contains("cookie-banner-visible")).toBe(
|
|
183
|
+
false
|
|
184
|
+
);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it("removes cookie-banner-visible class on unmount", () => {
|
|
188
|
+
mockGetCookie.mockReturnValue(null);
|
|
189
|
+
const { unmount } = render(<CookieBanner content={defaultContent} />);
|
|
190
|
+
expect(document.body.classList.contains("cookie-banner-visible")).toBe(
|
|
191
|
+
true
|
|
192
|
+
);
|
|
193
|
+
unmount();
|
|
194
|
+
expect(document.body.classList.contains("cookie-banner-visible")).toBe(
|
|
195
|
+
false
|
|
196
|
+
);
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
describe("sticky footer detection", () => {
|
|
201
|
+
it("uses larger margin when anchored-banner element exists", () => {
|
|
202
|
+
const anchoredBanner = document.createElement("div");
|
|
203
|
+
anchoredBanner.id = "anchored-banner";
|
|
204
|
+
document.body.appendChild(anchoredBanner);
|
|
205
|
+
|
|
206
|
+
mockGetCookie.mockReturnValue(null);
|
|
207
|
+
render(<CookieBanner content={defaultContent} />);
|
|
208
|
+
const banner = screen.getByLabelText("Cookie usage notification");
|
|
209
|
+
// marginBottom = 14 * 4 = 56px when anchored-banner exists
|
|
210
|
+
expect(banner.style.marginBottom).toBe("56px");
|
|
211
|
+
|
|
212
|
+
document.body.removeChild(anchoredBanner);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it("uses smaller margin when anchored-banner does not exist", () => {
|
|
216
|
+
mockGetCookie.mockReturnValue(null);
|
|
217
|
+
render(<CookieBanner content={defaultContent} />);
|
|
218
|
+
const banner = screen.getByLabelText("Cookie usage notification");
|
|
219
|
+
// marginBottom = 3 * 4 = 12px when no anchored-banner
|
|
220
|
+
expect(banner.style.marginBottom).toBe("12px");
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
describe("CSS custom property for height", () => {
|
|
225
|
+
it("calculates and sets --cookie-banner-height property", () => {
|
|
226
|
+
mockGetCookie.mockReturnValue(null);
|
|
227
|
+
render(<CookieBanner content={defaultContent} />);
|
|
228
|
+
|
|
229
|
+
act(() => {
|
|
230
|
+
jest.advanceTimersByTime(350);
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// The property should be set (value depends on getBoundingClientRect mock)
|
|
234
|
+
// In jsdom, getBoundingClientRect returns zeros, so spaceFromBottom = innerHeight - 0
|
|
235
|
+
const value = document.documentElement.style.getPropertyValue(
|
|
236
|
+
"--cookie-banner-height"
|
|
237
|
+
);
|
|
238
|
+
// Should be set (even though value may be 0px in jsdom)
|
|
239
|
+
expect(value).toBeDefined();
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
it("removes --cookie-banner-height on unmount", () => {
|
|
243
|
+
mockGetCookie.mockReturnValue(null);
|
|
244
|
+
const { unmount } = render(<CookieBanner content={defaultContent} />);
|
|
245
|
+
|
|
246
|
+
act(() => {
|
|
247
|
+
jest.advanceTimersByTime(350);
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
unmount();
|
|
251
|
+
const value = document.documentElement.style.getPropertyValue(
|
|
252
|
+
"--cookie-banner-height"
|
|
253
|
+
);
|
|
254
|
+
expect(value).toBe("");
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it("recalculates height on window resize", () => {
|
|
258
|
+
mockGetCookie.mockReturnValue(null);
|
|
259
|
+
render(<CookieBanner content={defaultContent} />);
|
|
260
|
+
|
|
261
|
+
act(() => {
|
|
262
|
+
jest.advanceTimersByTime(350);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
act(() => {
|
|
266
|
+
window.dispatchEvent(new Event("resize"));
|
|
267
|
+
jest.advanceTimersByTime(200);
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
// Should not throw and property remains set
|
|
271
|
+
const value = document.documentElement.style.getPropertyValue(
|
|
272
|
+
"--cookie-banner-height"
|
|
273
|
+
);
|
|
274
|
+
expect(value).toBeDefined();
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
});
|
|
@@ -1,146 +1,146 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useEffect, useRef, useState } from "react";
|
|
4
|
-
import { getCookie, setCookie } from "../../../utils/cookie";
|
|
5
|
-
import { TypeComponentRichTextFields } from "./type";
|
|
6
|
-
|
|
7
|
-
import { MaterialIcon } from "@shared/components/material-icon";
|
|
8
|
-
import { Button } from "@shared/contentful/blocks/button";
|
|
9
|
-
|
|
10
|
-
export default function CookieBanner({
|
|
11
|
-
content,
|
|
12
|
-
}: {
|
|
13
|
-
content: TypeComponentRichTextFields;
|
|
14
|
-
}) {
|
|
15
|
-
let marginBottom = 3;
|
|
16
|
-
const [isBannerVisible, setIsBannerVisible] = useState(false);
|
|
17
|
-
const [isStickyFooterPresent, setStickyFooterPresent] = useState(false);
|
|
18
|
-
const bannerRef = useRef<HTMLDivElement>(null);
|
|
19
|
-
|
|
20
|
-
useEffect(() => {
|
|
21
|
-
const cookieBannerClosed = getCookie("cookieBannerClosed");
|
|
22
|
-
if (cookieBannerClosed === "true") {
|
|
23
|
-
setIsBannerVisible(false);
|
|
24
|
-
} else {
|
|
25
|
-
setIsBannerVisible(true);
|
|
26
|
-
}
|
|
27
|
-
}, []);
|
|
28
|
-
|
|
29
|
-
useEffect(() => {
|
|
30
|
-
const checkElementPresence = () => {
|
|
31
|
-
const element = document.getElementById("anchored-banner");
|
|
32
|
-
setStickyFooterPresent(!!element);
|
|
33
|
-
};
|
|
34
|
-
checkElementPresence();
|
|
35
|
-
}, []);
|
|
36
|
-
|
|
37
|
-
// Add body class and calculate height for chat positioning
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
if (isBannerVisible) {
|
|
40
|
-
window?.document?.body?.classList.add("cookie-banner-visible");
|
|
41
|
-
} else {
|
|
42
|
-
window?.document?.body?.classList.remove("cookie-banner-visible");
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return () => {
|
|
46
|
-
window?.document?.body?.classList.remove("cookie-banner-visible");
|
|
47
|
-
};
|
|
48
|
-
}, [isBannerVisible]);
|
|
49
|
-
|
|
50
|
-
// Calculate cookie banner height and set CSS custom property
|
|
51
|
-
useEffect(() => {
|
|
52
|
-
if (!isBannerVisible) return;
|
|
53
|
-
|
|
54
|
-
const calculateCookieBannerHeight = () => {
|
|
55
|
-
if (bannerRef.current) {
|
|
56
|
-
const rect = bannerRef.current.getBoundingClientRect();
|
|
57
|
-
const viewportHeight = window.innerHeight;
|
|
58
|
-
|
|
59
|
-
// Calculate how much space the banner occupies from the bottom of the viewport
|
|
60
|
-
// This is: viewport height - distance from top
|
|
61
|
-
const spaceFromBottom = viewportHeight - rect.top;
|
|
62
|
-
|
|
63
|
-
document.documentElement.style.setProperty(
|
|
64
|
-
"--cookie-banner-height",
|
|
65
|
-
`${spaceFromBottom}px`
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
// Calculate initially after render and after a short delay to ensure layout is complete
|
|
71
|
-
const timer1 = setTimeout(calculateCookieBannerHeight, 100);
|
|
72
|
-
const timer2 = setTimeout(calculateCookieBannerHeight, 300);
|
|
73
|
-
|
|
74
|
-
// Recalculate on window resize with debounce
|
|
75
|
-
let resizeTimeout: ReturnType<typeof setTimeout>;
|
|
76
|
-
const handleResize = () => {
|
|
77
|
-
clearTimeout(resizeTimeout);
|
|
78
|
-
resizeTimeout = setTimeout(calculateCookieBannerHeight, 150);
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
window.addEventListener("resize", handleResize);
|
|
82
|
-
|
|
83
|
-
return () => {
|
|
84
|
-
clearTimeout(timer1);
|
|
85
|
-
clearTimeout(timer2);
|
|
86
|
-
clearTimeout(resizeTimeout);
|
|
87
|
-
window.removeEventListener("resize", handleResize);
|
|
88
|
-
document.documentElement.style.removeProperty("--cookie-banner-height");
|
|
89
|
-
};
|
|
90
|
-
}, [isBannerVisible, isStickyFooterPresent]);
|
|
91
|
-
|
|
92
|
-
const handleClose = () => {
|
|
93
|
-
const expirationDate = new Date(Date.now() + 43200 * 60 * 1000);
|
|
94
|
-
setIsBannerVisible(false);
|
|
95
|
-
setCookie("cookieBannerClosed", true, {
|
|
96
|
-
expires: expirationDate,
|
|
97
|
-
});
|
|
98
|
-
};
|
|
99
|
-
if (isStickyFooterPresent) marginBottom = 14;
|
|
100
|
-
|
|
101
|
-
// Calculate margin values in pixels for inline styles
|
|
102
|
-
const marginBottomPx = marginBottom * 4; // Tailwind: 3 = 12px, 14 = 56px (each unit is 4px)
|
|
103
|
-
const marginLeftPx = 12; // mx-3 = 12px
|
|
104
|
-
|
|
105
|
-
if (!isBannerVisible) return null;
|
|
106
|
-
|
|
107
|
-
return (
|
|
108
|
-
<div
|
|
109
|
-
id="cookie-banner"
|
|
110
|
-
ref={bannerRef}
|
|
111
|
-
className="fixed z-[1000] max-w-[350px] rounded-xl bg-white py-5 pl-6 pr-12 text-black shadow-lg ring-1 ring-gray-900/10 md:max-w-[656px]"
|
|
112
|
-
style={{
|
|
113
|
-
// maxWidth: maxWidth,
|
|
114
|
-
bottom: "0px",
|
|
115
|
-
right: "20px",
|
|
116
|
-
marginBottom: `${marginBottomPx}px`,
|
|
117
|
-
marginLeft: `${marginLeftPx}px`,
|
|
118
|
-
}}
|
|
119
|
-
aria-label="Cookie usage notification"
|
|
120
|
-
>
|
|
121
|
-
{" "}
|
|
122
|
-
{
|
|
123
|
-
<Button
|
|
124
|
-
showButtonAs="unstyled"
|
|
125
|
-
buttonClassName="absolute right-2 top-3 mr-2 mt-0 h-6 w-6 bg-white"
|
|
126
|
-
onClick={handleClose}
|
|
127
|
-
>
|
|
128
|
-
<MaterialIcon name="close" />
|
|
129
|
-
</Button>
|
|
130
|
-
}
|
|
131
|
-
{/* {content ? (
|
|
132
|
-
<div className="my-4 mx-auto [&>a]:footnote">
|
|
133
|
-
{renderContentfulRichText(
|
|
134
|
-
toDocument(content.richText),
|
|
135
|
-
false,
|
|
136
|
-
"footnote",
|
|
137
|
-
"footnote",
|
|
138
|
-
)}
|
|
139
|
-
</div>
|
|
140
|
-
) : null} */}
|
|
141
|
-
{content.richText ? (
|
|
142
|
-
<div className="mx-auto my-4 [&>a]:footnote">{content.richText}</div>
|
|
143
|
-
) : null}
|
|
144
|
-
</div>
|
|
145
|
-
);
|
|
146
|
-
}
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
import { getCookie, setCookie } from "../../../utils/cookie";
|
|
5
|
+
import { TypeComponentRichTextFields } from "./type";
|
|
6
|
+
|
|
7
|
+
import { MaterialIcon } from "@shared/components/material-icon";
|
|
8
|
+
import { Button } from "@shared/contentful/blocks/button";
|
|
9
|
+
|
|
10
|
+
export default function CookieBanner({
|
|
11
|
+
content,
|
|
12
|
+
}: {
|
|
13
|
+
content: TypeComponentRichTextFields;
|
|
14
|
+
}) {
|
|
15
|
+
let marginBottom = 3;
|
|
16
|
+
const [isBannerVisible, setIsBannerVisible] = useState(false);
|
|
17
|
+
const [isStickyFooterPresent, setStickyFooterPresent] = useState(false);
|
|
18
|
+
const bannerRef = useRef<HTMLDivElement>(null);
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
const cookieBannerClosed = getCookie("cookieBannerClosed");
|
|
22
|
+
if (cookieBannerClosed === "true") {
|
|
23
|
+
setIsBannerVisible(false);
|
|
24
|
+
} else {
|
|
25
|
+
setIsBannerVisible(true);
|
|
26
|
+
}
|
|
27
|
+
}, []);
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
const checkElementPresence = () => {
|
|
31
|
+
const element = document.getElementById("anchored-banner");
|
|
32
|
+
setStickyFooterPresent(!!element);
|
|
33
|
+
};
|
|
34
|
+
checkElementPresence();
|
|
35
|
+
}, []);
|
|
36
|
+
|
|
37
|
+
// Add body class and calculate height for chat positioning
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (isBannerVisible) {
|
|
40
|
+
window?.document?.body?.classList.add("cookie-banner-visible");
|
|
41
|
+
} else {
|
|
42
|
+
window?.document?.body?.classList.remove("cookie-banner-visible");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return () => {
|
|
46
|
+
window?.document?.body?.classList.remove("cookie-banner-visible");
|
|
47
|
+
};
|
|
48
|
+
}, [isBannerVisible]);
|
|
49
|
+
|
|
50
|
+
// Calculate cookie banner height and set CSS custom property
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (!isBannerVisible) return;
|
|
53
|
+
|
|
54
|
+
const calculateCookieBannerHeight = () => {
|
|
55
|
+
if (bannerRef.current) {
|
|
56
|
+
const rect = bannerRef.current.getBoundingClientRect();
|
|
57
|
+
const viewportHeight = window.innerHeight;
|
|
58
|
+
|
|
59
|
+
// Calculate how much space the banner occupies from the bottom of the viewport
|
|
60
|
+
// This is: viewport height - distance from top
|
|
61
|
+
const spaceFromBottom = viewportHeight - rect.top;
|
|
62
|
+
|
|
63
|
+
document.documentElement.style.setProperty(
|
|
64
|
+
"--cookie-banner-height",
|
|
65
|
+
`${spaceFromBottom}px`
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// Calculate initially after render and after a short delay to ensure layout is complete
|
|
71
|
+
const timer1 = setTimeout(calculateCookieBannerHeight, 100);
|
|
72
|
+
const timer2 = setTimeout(calculateCookieBannerHeight, 300);
|
|
73
|
+
|
|
74
|
+
// Recalculate on window resize with debounce
|
|
75
|
+
let resizeTimeout: ReturnType<typeof setTimeout>;
|
|
76
|
+
const handleResize = () => {
|
|
77
|
+
clearTimeout(resizeTimeout);
|
|
78
|
+
resizeTimeout = setTimeout(calculateCookieBannerHeight, 150);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
window.addEventListener("resize", handleResize);
|
|
82
|
+
|
|
83
|
+
return () => {
|
|
84
|
+
clearTimeout(timer1);
|
|
85
|
+
clearTimeout(timer2);
|
|
86
|
+
clearTimeout(resizeTimeout);
|
|
87
|
+
window.removeEventListener("resize", handleResize);
|
|
88
|
+
document.documentElement.style.removeProperty("--cookie-banner-height");
|
|
89
|
+
};
|
|
90
|
+
}, [isBannerVisible, isStickyFooterPresent]);
|
|
91
|
+
|
|
92
|
+
const handleClose = () => {
|
|
93
|
+
const expirationDate = new Date(Date.now() + 43200 * 60 * 1000);
|
|
94
|
+
setIsBannerVisible(false);
|
|
95
|
+
setCookie("cookieBannerClosed", true, {
|
|
96
|
+
expires: expirationDate,
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
if (isStickyFooterPresent) marginBottom = 14;
|
|
100
|
+
|
|
101
|
+
// Calculate margin values in pixels for inline styles
|
|
102
|
+
const marginBottomPx = marginBottom * 4; // Tailwind: 3 = 12px, 14 = 56px (each unit is 4px)
|
|
103
|
+
const marginLeftPx = 12; // mx-3 = 12px
|
|
104
|
+
|
|
105
|
+
if (!isBannerVisible) return null;
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<div
|
|
109
|
+
id="cookie-banner"
|
|
110
|
+
ref={bannerRef}
|
|
111
|
+
className="fixed z-[1000] max-w-[350px] rounded-xl bg-white py-5 pl-6 pr-12 text-black shadow-lg ring-1 ring-gray-900/10 md:max-w-[656px]"
|
|
112
|
+
style={{
|
|
113
|
+
// maxWidth: maxWidth,
|
|
114
|
+
bottom: "0px",
|
|
115
|
+
right: "20px",
|
|
116
|
+
marginBottom: `${marginBottomPx}px`,
|
|
117
|
+
marginLeft: `${marginLeftPx}px`,
|
|
118
|
+
}}
|
|
119
|
+
aria-label="Cookie usage notification"
|
|
120
|
+
>
|
|
121
|
+
{" "}
|
|
122
|
+
{
|
|
123
|
+
<Button
|
|
124
|
+
showButtonAs="unstyled"
|
|
125
|
+
buttonClassName="absolute right-2 top-3 mr-2 mt-0 h-6 w-6 bg-white"
|
|
126
|
+
onClick={handleClose}
|
|
127
|
+
>
|
|
128
|
+
<MaterialIcon name="close" />
|
|
129
|
+
</Button>
|
|
130
|
+
}
|
|
131
|
+
{/* {content ? (
|
|
132
|
+
<div className="my-4 mx-auto [&>a]:footnote">
|
|
133
|
+
{renderContentfulRichText(
|
|
134
|
+
toDocument(content.richText),
|
|
135
|
+
false,
|
|
136
|
+
"footnote",
|
|
137
|
+
"footnote",
|
|
138
|
+
)}
|
|
139
|
+
</div>
|
|
140
|
+
) : null} */}
|
|
141
|
+
{content.richText ? (
|
|
142
|
+
<div className="mx-auto my-4 [&>a]:footnote">{content.richText}</div>
|
|
143
|
+
) : null}
|
|
144
|
+
</div>
|
|
145
|
+
);
|
|
146
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export interface TypeComponentRichTextFields {
|
|
2
|
-
entryName?: string;
|
|
3
|
-
anchorId?: string;
|
|
4
|
-
title?: string;
|
|
5
|
-
isTargetBlank?: boolean;
|
|
6
|
-
richText: React.ReactNode;
|
|
7
|
-
}
|
|
1
|
+
export interface TypeComponentRichTextFields {
|
|
2
|
+
entryName?: string;
|
|
3
|
+
anchorId?: string;
|
|
4
|
+
title?: string;
|
|
5
|
+
isTargetBlank?: boolean;
|
|
6
|
+
richText: React.ReactNode;
|
|
7
|
+
}
|
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
import { CtaCallout } from "./index";
|
|
2
|
-
|
|
3
|
-
import { DocsPage } from "@shared/stories/DocsTemplate";
|
|
4
|
-
import type { Meta, StoryObj } from "@storybook/react";
|
|
5
|
-
|
|
6
|
-
const meta: Meta<typeof CtaCallout> = {
|
|
7
|
-
title: "Contentful Blocks/CtaCallout",
|
|
8
|
-
component: CtaCallout,
|
|
9
|
-
tags: ["autodocs"],
|
|
10
|
-
parameters: {
|
|
11
|
-
layout: "centered",
|
|
12
|
-
docs: {
|
|
13
|
-
page: DocsPage,
|
|
14
|
-
description: {
|
|
15
|
-
component:
|
|
16
|
-
"Contentful CTA callout block with title, description, and optional button.",
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
args: {
|
|
21
|
-
title: "Call to Action",
|
|
22
|
-
subTitle: "Subtitle",
|
|
23
|
-
description: "Description text.",
|
|
24
|
-
background: "white",
|
|
25
|
-
button: {
|
|
26
|
-
showButtonAs: "solid",
|
|
27
|
-
buttonVariant: "primary_brand",
|
|
28
|
-
buttonLabel: "Learn More",
|
|
29
|
-
buttonPrefix: "",
|
|
30
|
-
badge: "",
|
|
31
|
-
badgeIcon: "",
|
|
32
|
-
buttonIcon: "",
|
|
33
|
-
buttonIconPosition: "left",
|
|
34
|
-
href: "",
|
|
35
|
-
target: "_self",
|
|
36
|
-
anchorId: "",
|
|
37
|
-
preserveQueryParameters: false,
|
|
38
|
-
clickToOpen: "",
|
|
39
|
-
tabmodalNameToOpen: "",
|
|
40
|
-
preDefinedFunctionExecution: "",
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
};
|
|
44
|
-
export default meta;
|
|
45
|
-
type Story = StoryObj<typeof meta>;
|
|
46
|
-
export const Default: Story = {};
|
|
1
|
+
import { CtaCallout } from "./index";
|
|
2
|
+
|
|
3
|
+
import { DocsPage } from "@shared/stories/DocsTemplate";
|
|
4
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof CtaCallout> = {
|
|
7
|
+
title: "Contentful Blocks/CtaCallout",
|
|
8
|
+
component: CtaCallout,
|
|
9
|
+
tags: ["autodocs"],
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: "centered",
|
|
12
|
+
docs: {
|
|
13
|
+
page: DocsPage,
|
|
14
|
+
description: {
|
|
15
|
+
component:
|
|
16
|
+
"Contentful CTA callout block with title, description, and optional button.",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
args: {
|
|
21
|
+
title: "Call to Action",
|
|
22
|
+
subTitle: "Subtitle",
|
|
23
|
+
description: "Description text.",
|
|
24
|
+
background: "white",
|
|
25
|
+
button: {
|
|
26
|
+
showButtonAs: "solid",
|
|
27
|
+
buttonVariant: "primary_brand",
|
|
28
|
+
buttonLabel: "Learn More",
|
|
29
|
+
buttonPrefix: "",
|
|
30
|
+
badge: "",
|
|
31
|
+
badgeIcon: "",
|
|
32
|
+
buttonIcon: "",
|
|
33
|
+
buttonIconPosition: "left",
|
|
34
|
+
href: "",
|
|
35
|
+
target: "_self",
|
|
36
|
+
anchorId: "",
|
|
37
|
+
preserveQueryParameters: false,
|
|
38
|
+
clickToOpen: "",
|
|
39
|
+
tabmodalNameToOpen: "",
|
|
40
|
+
preDefinedFunctionExecution: "",
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
export default meta;
|
|
45
|
+
type Story = StoryObj<typeof meta>;
|
|
46
|
+
export const Default: Story = {};
|