@windstream/react-shared-components 0.1.87 → 0.1.89
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 +2 -2
- package/dist/index.d.ts +2 -2
- 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 +185 -185
- package/src/components/accordion/Accordion.stories.tsx +230 -230
- 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.tsx +41 -41
- package/src/components/alert-card/types.ts +13 -13
- 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.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.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.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.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.tsx +61 -61
- package/src/components/checklist/types.ts +17 -17
- package/src/components/collapse/Collapse.stories.tsx +255 -255
- package/src/components/collapse/index.tsx +46 -46
- package/src/components/collapse/types.ts +6 -6
- package/src/components/divider/Divider.stories.tsx +205 -205
- 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.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.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.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.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.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.tsx +164 -164
- package/src/components/modal/types.ts +24 -24
- package/src/components/next-image/index.tsx +74 -74
- package/src/components/next-image/types.ts +1 -1
- 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.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.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.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.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.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.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.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.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.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.tsx +112 -112
- package/src/contentful/blocks/accordion/types.ts +34 -34
- 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.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 +156 -156
- 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.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.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.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.tsx +279 -279
- 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.tsx +129 -129
- package/src/contentful/blocks/cards/blog-card/types.ts +34 -34
- 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.tsx +130 -130
- package/src/contentful/blocks/cards/full-image-card/types.ts +29 -29
- package/src/contentful/blocks/cards/index.tsx +13 -13
- 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.tsx +325 -325
- package/src/contentful/blocks/cards/simple-card/types.ts +71 -71
- 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.tsx +494 -494
- package/src/contentful/blocks/carousel/index.tsx +87 -87
- package/src/contentful/blocks/carousel/types.ts +145 -145
- package/src/contentful/blocks/cart-retention-banner/index.tsx +109 -105
- package/src/contentful/blocks/cart-retention-banner/types.ts +11 -11
- 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.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.tsx +71 -71
- package/src/contentful/blocks/cta-callout/types.ts +26 -26
- 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.tsx +116 -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.tsx +130 -130
- package/src/contentful/blocks/find-kinetic/types.ts +19 -19
- package/src/contentful/blocks/floating-banner/FloatingBanner.stories.tsx +34 -34
- 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.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.tsx +28 -28
- 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.tsx +93 -93
- 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.tsx +107 -107
- package/src/contentful/blocks/modal/types.ts +12 -12
- package/src/contentful/blocks/navigation/desktop-link-groups.tsx/index.tsx +139 -139
- package/src/contentful/blocks/navigation/index.tsx +568 -568
- 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.tsx +236 -236
- package/src/contentful/blocks/primary-hero/types.ts +37 -37
- 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.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.tsx +12 -12
- package/src/contentful/blocks/text/types.ts +1 -1
- package/src/contentful/index.ts +105 -105
- package/src/hooks/contentful/use-contentful-rich-text.tsx +309 -309
- package/src/hooks/contentful/use-processed-check-list.ts +63 -63
- package/src/hooks/use-body-scroll-lock.ts +34 -34
- package/src/hooks/use-carousel-swipe.ts +264 -264
- package/src/hooks/use-outside-click.ts +17 -17
- package/src/index.ts +107 -107
- package/src/next/index.ts +5 -5
- package/src/setupTests.ts +46 -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.ts +24 -24
- package/src/utils/cookie.ts +84 -84
- package/src/utils/cx.ts +49 -49
- package/src/utils/index.ts +41 -41
- package/src/utils/speed-card-bg.ts +24 -24
- package/src/utils/utm.ts +221 -221
|
@@ -1,71 +1,71 @@
|
|
|
1
|
-
import type { CSSProperties, ReactNode } from "react";
|
|
2
|
-
import type { ButtonProps } from "../../button/types";
|
|
3
|
-
|
|
4
|
-
export type PinwheelColor =
|
|
5
|
-
| "Blue-#307998"
|
|
6
|
-
| "Green-#209A61"
|
|
7
|
-
| "Orange-#DE7E0A"
|
|
8
|
-
| "Purple-#7E1458"
|
|
9
|
-
| (string & {});
|
|
10
|
-
|
|
11
|
-
export type SimpleCardCtaBottom = {
|
|
12
|
-
title?: string;
|
|
13
|
-
href?: string;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export type Item = {
|
|
17
|
-
title?: string;
|
|
18
|
-
image?: string;
|
|
19
|
-
imageAlt?: string;
|
|
20
|
-
imageWidth?: number;
|
|
21
|
-
imageHeight?: number;
|
|
22
|
-
imageAlignment?: "left" | "right" | "center";
|
|
23
|
-
iconAlignment?: "left" | "right" | "center";
|
|
24
|
-
/**
|
|
25
|
-
* Layout variant for the image. `standard` / `icon` render an inline
|
|
26
|
-
* icon above the content. `full` renders a full-bleed top image.
|
|
27
|
-
* `margin` is `full` with horizontal padding.
|
|
28
|
-
*/
|
|
29
|
-
imageView?: "standard" | "icon" | "full" | "margin" | "inset";
|
|
30
|
-
body?: ReactNode;
|
|
31
|
-
/** Optional secondary rich-text region (port of local `richText`). */
|
|
32
|
-
richText?: ReactNode;
|
|
33
|
-
cta?: ButtonProps;
|
|
34
|
-
ctaAlignment?: "left" | "right" | "center";
|
|
35
|
-
/** Top "location" CTA, rendered above the title with a `location_on` icon. */
|
|
36
|
-
ctaBottom?: SimpleCardCtaBottom;
|
|
37
|
-
ctaAlignmentBottom?: "left" | "right" | "center";
|
|
38
|
-
/** Legacy token-based card background (mapped via `backgroundColorMap`). */
|
|
39
|
-
backgroundColor?: string;
|
|
40
|
-
/** Raw color value used when `applyCardBackgroundColor` is true. */
|
|
41
|
-
applyCardBackgroundColor?: boolean;
|
|
42
|
-
textColor?: string;
|
|
43
|
-
showBackgroundImage?: boolean;
|
|
44
|
-
pinwheelColor?: PinwheelColor;
|
|
45
|
-
/** On `lg:` and up, lays out icon + content side-by-side. */
|
|
46
|
-
imageToRichTextAlignment?: boolean;
|
|
47
|
-
/** Bold label between title and the phone/hours table. */
|
|
48
|
-
titleLocation?: string;
|
|
49
|
-
phoneNumber?: string[];
|
|
50
|
-
/** Each entry uses a `label|value` separator. */
|
|
51
|
-
workingHours?: string[];
|
|
52
|
-
shadow?: boolean;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
export type SimpleCardProps = {
|
|
56
|
-
card: Item;
|
|
57
|
-
lgWidth?: string;
|
|
58
|
-
mdWidth?: string;
|
|
59
|
-
className?: string;
|
|
60
|
-
contentClassName?: string;
|
|
61
|
-
style?: CSSProperties;
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
export const backgroundColorMap: Record<string, string> = {
|
|
65
|
-
blue: "bg-fill-brand",
|
|
66
|
-
green: "bg-fill-brand-accent",
|
|
67
|
-
navy: "bg-fill-inverse",
|
|
68
|
-
purple: "bg-fill-brand-tertiary",
|
|
69
|
-
white: "bg-white",
|
|
70
|
-
yellow: "bg-[#F5FF1E]",
|
|
71
|
-
};
|
|
1
|
+
import type { CSSProperties, ReactNode } from "react";
|
|
2
|
+
import type { ButtonProps } from "../../button/types";
|
|
3
|
+
|
|
4
|
+
export type PinwheelColor =
|
|
5
|
+
| "Blue-#307998"
|
|
6
|
+
| "Green-#209A61"
|
|
7
|
+
| "Orange-#DE7E0A"
|
|
8
|
+
| "Purple-#7E1458"
|
|
9
|
+
| (string & {});
|
|
10
|
+
|
|
11
|
+
export type SimpleCardCtaBottom = {
|
|
12
|
+
title?: string;
|
|
13
|
+
href?: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type Item = {
|
|
17
|
+
title?: string;
|
|
18
|
+
image?: string;
|
|
19
|
+
imageAlt?: string;
|
|
20
|
+
imageWidth?: number;
|
|
21
|
+
imageHeight?: number;
|
|
22
|
+
imageAlignment?: "left" | "right" | "center";
|
|
23
|
+
iconAlignment?: "left" | "right" | "center";
|
|
24
|
+
/**
|
|
25
|
+
* Layout variant for the image. `standard` / `icon` render an inline
|
|
26
|
+
* icon above the content. `full` renders a full-bleed top image.
|
|
27
|
+
* `margin` is `full` with horizontal padding.
|
|
28
|
+
*/
|
|
29
|
+
imageView?: "standard" | "icon" | "full" | "margin" | "inset";
|
|
30
|
+
body?: ReactNode;
|
|
31
|
+
/** Optional secondary rich-text region (port of local `richText`). */
|
|
32
|
+
richText?: ReactNode;
|
|
33
|
+
cta?: ButtonProps;
|
|
34
|
+
ctaAlignment?: "left" | "right" | "center";
|
|
35
|
+
/** Top "location" CTA, rendered above the title with a `location_on` icon. */
|
|
36
|
+
ctaBottom?: SimpleCardCtaBottom;
|
|
37
|
+
ctaAlignmentBottom?: "left" | "right" | "center";
|
|
38
|
+
/** Legacy token-based card background (mapped via `backgroundColorMap`). */
|
|
39
|
+
backgroundColor?: string;
|
|
40
|
+
/** Raw color value used when `applyCardBackgroundColor` is true. */
|
|
41
|
+
applyCardBackgroundColor?: boolean;
|
|
42
|
+
textColor?: string;
|
|
43
|
+
showBackgroundImage?: boolean;
|
|
44
|
+
pinwheelColor?: PinwheelColor;
|
|
45
|
+
/** On `lg:` and up, lays out icon + content side-by-side. */
|
|
46
|
+
imageToRichTextAlignment?: boolean;
|
|
47
|
+
/** Bold label between title and the phone/hours table. */
|
|
48
|
+
titleLocation?: string;
|
|
49
|
+
phoneNumber?: string[];
|
|
50
|
+
/** Each entry uses a `label|value` separator. */
|
|
51
|
+
workingHours?: string[];
|
|
52
|
+
shadow?: boolean;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export type SimpleCardProps = {
|
|
56
|
+
card: Item;
|
|
57
|
+
lgWidth?: string;
|
|
58
|
+
mdWidth?: string;
|
|
59
|
+
className?: string;
|
|
60
|
+
contentClassName?: string;
|
|
61
|
+
style?: CSSProperties;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const backgroundColorMap: Record<string, string> = {
|
|
65
|
+
blue: "bg-fill-brand",
|
|
66
|
+
green: "bg-fill-brand-accent",
|
|
67
|
+
navy: "bg-fill-inverse",
|
|
68
|
+
purple: "bg-fill-brand-tertiary",
|
|
69
|
+
white: "bg-white",
|
|
70
|
+
yellow: "bg-[#F5FF1E]",
|
|
71
|
+
};
|
|
@@ -1,90 +1,90 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { TestimonialCardProps } from "./types";
|
|
3
|
-
import clsx from "clsx";
|
|
4
|
-
import Image from "next/image";
|
|
5
|
-
|
|
6
|
-
import { MaterialIcon } from "@shared/components/material-icon";
|
|
7
|
-
import { Text } from "@shared/components/text";
|
|
8
|
-
|
|
9
|
-
export const TestimonialCard: React.FC<TestimonialCardProps> = ({
|
|
10
|
-
title,
|
|
11
|
-
quote,
|
|
12
|
-
rating,
|
|
13
|
-
author,
|
|
14
|
-
role,
|
|
15
|
-
avatarUrl,
|
|
16
|
-
isActive = false,
|
|
17
|
-
className,
|
|
18
|
-
}) => {
|
|
19
|
-
return (
|
|
20
|
-
<figure
|
|
21
|
-
className={clsx(
|
|
22
|
-
"flex w-full flex-col gap-6 rounded-card-lg p-6 transition-all duration-300 md:gap-10 md:p-14",
|
|
23
|
-
isActive
|
|
24
|
-
? "bg-bg-surface-secondary shadow-drop"
|
|
25
|
-
: "bg-gray-50 opacity-40", // Active vs Inactive styles
|
|
26
|
-
className
|
|
27
|
-
)}
|
|
28
|
-
>
|
|
29
|
-
<div className="flex flex-col justify-start gap-3 md:gap-5">
|
|
30
|
-
<header>
|
|
31
|
-
<Text as="h3" className="label1 text-text">
|
|
32
|
-
{title}
|
|
33
|
-
</Text>
|
|
34
|
-
</header>
|
|
35
|
-
<blockquote className="body1 text-text">{quote}</blockquote>
|
|
36
|
-
|
|
37
|
-
{/* Rating Stars */}
|
|
38
|
-
{rating ? (
|
|
39
|
-
<div className="flex" aria-label={`Rating: ${rating} out of 5`}>
|
|
40
|
-
{[...Array(5)].map((_, i) => (
|
|
41
|
-
<MaterialIcon
|
|
42
|
-
key={i}
|
|
43
|
-
size={24}
|
|
44
|
-
name="star"
|
|
45
|
-
fill={1}
|
|
46
|
-
className={clsx(
|
|
47
|
-
"h-[21px] w-[21px]",
|
|
48
|
-
i < rating ? "text-text" : "text-gray-300"
|
|
49
|
-
)}
|
|
50
|
-
aria-hidden="true"
|
|
51
|
-
/>
|
|
52
|
-
))}
|
|
53
|
-
</div>
|
|
54
|
-
) : null}
|
|
55
|
-
</div>
|
|
56
|
-
|
|
57
|
-
{/* Author Block */}
|
|
58
|
-
{author && (
|
|
59
|
-
<figcaption className="flex gap-3 md:gap-5">
|
|
60
|
-
<div className="relative h-12 w-12 shrink-0 overflow-hidden rounded-full bg-gray-300">
|
|
61
|
-
{avatarUrl ? (
|
|
62
|
-
<Image
|
|
63
|
-
src={avatarUrl}
|
|
64
|
-
alt={author}
|
|
65
|
-
fill={true}
|
|
66
|
-
className="object-cover"
|
|
67
|
-
sizes="40px"
|
|
68
|
-
/>
|
|
69
|
-
) : (
|
|
70
|
-
<div className="flex h-full w-full items-center justify-center bg-gray-500 text-xs font-bold text-white">
|
|
71
|
-
{author.charAt(0)}
|
|
72
|
-
</div>
|
|
73
|
-
)}
|
|
74
|
-
</div>
|
|
75
|
-
|
|
76
|
-
<div className="flex flex-col">
|
|
77
|
-
<cite className="label3 font-bold not-italic text-text">
|
|
78
|
-
{author}
|
|
79
|
-
</cite>
|
|
80
|
-
<Text as="p" className="body3 text-text">
|
|
81
|
-
{role}
|
|
82
|
-
</Text>
|
|
83
|
-
</div>
|
|
84
|
-
</figcaption>
|
|
85
|
-
)}
|
|
86
|
-
</figure>
|
|
87
|
-
);
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
export default TestimonialCard;
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { TestimonialCardProps } from "./types";
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
import Image from "next/image";
|
|
5
|
+
|
|
6
|
+
import { MaterialIcon } from "@shared/components/material-icon";
|
|
7
|
+
import { Text } from "@shared/components/text";
|
|
8
|
+
|
|
9
|
+
export const TestimonialCard: React.FC<TestimonialCardProps> = ({
|
|
10
|
+
title,
|
|
11
|
+
quote,
|
|
12
|
+
rating,
|
|
13
|
+
author,
|
|
14
|
+
role,
|
|
15
|
+
avatarUrl,
|
|
16
|
+
isActive = false,
|
|
17
|
+
className,
|
|
18
|
+
}) => {
|
|
19
|
+
return (
|
|
20
|
+
<figure
|
|
21
|
+
className={clsx(
|
|
22
|
+
"flex w-full flex-col gap-6 rounded-card-lg p-6 transition-all duration-300 md:gap-10 md:p-14",
|
|
23
|
+
isActive
|
|
24
|
+
? "bg-bg-surface-secondary shadow-drop"
|
|
25
|
+
: "bg-gray-50 opacity-40", // Active vs Inactive styles
|
|
26
|
+
className
|
|
27
|
+
)}
|
|
28
|
+
>
|
|
29
|
+
<div className="flex flex-col justify-start gap-3 md:gap-5">
|
|
30
|
+
<header>
|
|
31
|
+
<Text as="h3" className="label1 text-text">
|
|
32
|
+
{title}
|
|
33
|
+
</Text>
|
|
34
|
+
</header>
|
|
35
|
+
<blockquote className="body1 text-text">{quote}</blockquote>
|
|
36
|
+
|
|
37
|
+
{/* Rating Stars */}
|
|
38
|
+
{rating ? (
|
|
39
|
+
<div className="flex" aria-label={`Rating: ${rating} out of 5`}>
|
|
40
|
+
{[...Array(5)].map((_, i) => (
|
|
41
|
+
<MaterialIcon
|
|
42
|
+
key={i}
|
|
43
|
+
size={24}
|
|
44
|
+
name="star"
|
|
45
|
+
fill={1}
|
|
46
|
+
className={clsx(
|
|
47
|
+
"h-[21px] w-[21px]",
|
|
48
|
+
i < rating ? "text-text" : "text-gray-300"
|
|
49
|
+
)}
|
|
50
|
+
aria-hidden="true"
|
|
51
|
+
/>
|
|
52
|
+
))}
|
|
53
|
+
</div>
|
|
54
|
+
) : null}
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
{/* Author Block */}
|
|
58
|
+
{author && (
|
|
59
|
+
<figcaption className="flex gap-3 md:gap-5">
|
|
60
|
+
<div className="relative h-12 w-12 shrink-0 overflow-hidden rounded-full bg-gray-300">
|
|
61
|
+
{avatarUrl ? (
|
|
62
|
+
<Image
|
|
63
|
+
src={avatarUrl}
|
|
64
|
+
alt={author}
|
|
65
|
+
fill={true}
|
|
66
|
+
className="object-cover"
|
|
67
|
+
sizes="40px"
|
|
68
|
+
/>
|
|
69
|
+
) : (
|
|
70
|
+
<div className="flex h-full w-full items-center justify-center bg-gray-500 text-xs font-bold text-white">
|
|
71
|
+
{author.charAt(0)}
|
|
72
|
+
</div>
|
|
73
|
+
)}
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<div className="flex flex-col">
|
|
77
|
+
<cite className="label3 font-bold not-italic text-text">
|
|
78
|
+
{author}
|
|
79
|
+
</cite>
|
|
80
|
+
<Text as="p" className="body3 text-text">
|
|
81
|
+
{role}
|
|
82
|
+
</Text>
|
|
83
|
+
</div>
|
|
84
|
+
</figcaption>
|
|
85
|
+
)}
|
|
86
|
+
</figure>
|
|
87
|
+
);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export default TestimonialCard;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { ReactNode } from "react";
|
|
2
|
-
|
|
3
|
-
export interface TestimonialCardProps {
|
|
4
|
-
title?: string;
|
|
5
|
-
quote?: ReactNode;
|
|
6
|
-
rating?: number;
|
|
7
|
-
author?: string;
|
|
8
|
-
role?: string;
|
|
9
|
-
avatarUrl?: string;
|
|
10
|
-
isActive?: boolean;
|
|
11
|
-
className?: string;
|
|
12
|
-
}
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
export interface TestimonialCardProps {
|
|
4
|
+
title?: string;
|
|
5
|
+
quote?: ReactNode;
|
|
6
|
+
rating?: number;
|
|
7
|
+
author?: string;
|
|
8
|
+
role?: string;
|
|
9
|
+
avatarUrl?: string;
|
|
10
|
+
isActive?: boolean;
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export type CardsProps = {};
|
|
1
|
+
export type CardsProps = {};
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { Carousel } from "./index";
|
|
2
|
-
|
|
3
|
-
import { DocsPage } from "@shared/stories/DocsTemplate";
|
|
4
|
-
import type { Meta, StoryObj } from "@storybook/react";
|
|
5
|
-
|
|
6
|
-
const meta: Meta<typeof Carousel> = {
|
|
7
|
-
title: "Contentful Blocks/Carousel",
|
|
8
|
-
component: Carousel,
|
|
9
|
-
tags: ["autodocs"],
|
|
10
|
-
parameters: {
|
|
11
|
-
layout: "centered",
|
|
12
|
-
docs: {
|
|
13
|
-
page: DocsPage,
|
|
14
|
-
description: {
|
|
15
|
-
component: "Contentful carousel block.",
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
args: {},
|
|
20
|
-
};
|
|
21
|
-
export default meta;
|
|
22
|
-
type Story = StoryObj<typeof meta>;
|
|
23
|
-
export const Default: Story = {};
|
|
1
|
+
import { Carousel } from "./index";
|
|
2
|
+
|
|
3
|
+
import { DocsPage } from "@shared/stories/DocsTemplate";
|
|
4
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof Carousel> = {
|
|
7
|
+
title: "Contentful Blocks/Carousel",
|
|
8
|
+
component: Carousel,
|
|
9
|
+
tags: ["autodocs"],
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: "centered",
|
|
12
|
+
docs: {
|
|
13
|
+
page: DocsPage,
|
|
14
|
+
description: {
|
|
15
|
+
component: "Contentful carousel block.",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
args: {},
|
|
20
|
+
};
|
|
21
|
+
export default meta;
|
|
22
|
+
type Story = StoryObj<typeof meta>;
|
|
23
|
+
export const Default: Story = {};
|