@windstream/react-shared-components 0.1.45 → 0.1.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/README.md +635 -635
  2. package/dist/contentful/index.d.ts +2 -2
  3. package/dist/contentful/index.esm.js +2 -4
  4. package/dist/contentful/index.esm.js.map +1 -1
  5. package/dist/contentful/index.js +2 -4
  6. package/dist/contentful/index.js.map +1 -1
  7. package/dist/core.d.ts +1 -1
  8. package/dist/index.d.ts +3 -3
  9. package/dist/index.esm.js +5 -7
  10. package/dist/index.esm.js.map +1 -1
  11. package/dist/index.js +5 -7
  12. package/dist/index.js.map +1 -1
  13. package/dist/next/index.esm.js +1 -3
  14. package/dist/next/index.esm.js.map +1 -1
  15. package/dist/next/index.js +1 -3
  16. package/dist/next/index.js.map +1 -1
  17. package/dist/styles.css +1 -1
  18. package/dist/utils/index.d.ts +2 -3
  19. package/dist/utils/index.esm.js +1 -1
  20. package/dist/utils/index.esm.js.map +1 -1
  21. package/dist/utils/index.js +1 -1
  22. package/dist/utils/index.js.map +1 -1
  23. package/package.json +185 -185
  24. package/src/components/accordion/Accordion.stories.tsx +230 -230
  25. package/src/components/accordion/index.tsx +70 -70
  26. package/src/components/accordion/types.ts +12 -12
  27. package/src/components/alert-card/AlertCard.stories.tsx +171 -171
  28. package/src/components/alert-card/index.tsx +41 -41
  29. package/src/components/alert-card/types.ts +13 -13
  30. package/src/components/brand-button/BrandButton.stories.tsx +223 -223
  31. package/src/components/brand-button/helpers.ts +35 -35
  32. package/src/components/brand-button/index.tsx +120 -120
  33. package/src/components/brand-button/types.ts +38 -38
  34. package/src/components/button/Button.stories.tsx +108 -108
  35. package/src/components/button/index.tsx +27 -27
  36. package/src/components/button/types.ts +14 -14
  37. package/src/components/call-button/CallButton.stories.tsx +324 -324
  38. package/src/components/call-button/index.tsx +86 -86
  39. package/src/components/call-button/types.ts +11 -11
  40. package/src/components/checkbox/Checkbox.stories.tsx +247 -247
  41. package/src/components/checkbox/index.tsx +197 -197
  42. package/src/components/checkbox/types.ts +27 -27
  43. package/src/components/checklist/Checklist.stories.tsx +150 -150
  44. package/src/components/checklist/index.tsx +61 -61
  45. package/src/components/checklist/types.ts +17 -17
  46. package/src/components/collapse/Collapse.stories.tsx +255 -255
  47. package/src/components/collapse/index.tsx +46 -46
  48. package/src/components/collapse/types.ts +6 -6
  49. package/src/components/divider/Divider.stories.tsx +205 -205
  50. package/src/components/divider/index.tsx +22 -22
  51. package/src/components/divider/type.ts +3 -3
  52. package/src/components/image/Image.stories.tsx +113 -113
  53. package/src/components/image/index.tsx +25 -25
  54. package/src/components/image/types.ts +40 -40
  55. package/src/components/input/Input.stories.tsx +325 -325
  56. package/src/components/input/index.tsx +177 -177
  57. package/src/components/input/types.ts +37 -37
  58. package/src/components/link/Link.stories.tsx +163 -163
  59. package/src/components/link/index.tsx +109 -109
  60. package/src/components/link/types.ts +25 -25
  61. package/src/components/list/List.stories.tsx +272 -272
  62. package/src/components/list/index.tsx +88 -88
  63. package/src/components/list/list-item/index.tsx +38 -38
  64. package/src/components/list/list-item/types.ts +13 -13
  65. package/src/components/list/types.ts +29 -29
  66. package/src/components/material-icon/MaterialIcon.stories.tsx +322 -322
  67. package/src/components/material-icon/constants.ts +98 -98
  68. package/src/components/material-icon/index.tsx +47 -47
  69. package/src/components/material-icon/types.ts +31 -31
  70. package/src/components/modal/Modal.stories.tsx +171 -171
  71. package/src/components/modal/index.tsx +164 -164
  72. package/src/components/modal/types.ts +24 -24
  73. package/src/components/next-image/index.tsx +54 -54
  74. package/src/components/next-image/types.ts +1 -1
  75. package/src/components/pagination/index.tsx +100 -100
  76. package/src/components/pagination/types.ts +6 -6
  77. package/src/components/radio-button/RadioButton.stories.tsx +307 -307
  78. package/src/components/radio-button/index.tsx +75 -75
  79. package/src/components/radio-button/types.ts +21 -21
  80. package/src/components/see-more/SeeMore.stories.tsx +181 -181
  81. package/src/components/see-more/index.tsx +44 -44
  82. package/src/components/see-more/types.ts +4 -4
  83. package/src/components/select/Select.stories.tsx +411 -411
  84. package/src/components/select/index.tsx +155 -155
  85. package/src/components/select/types.ts +36 -36
  86. package/src/components/select-plan-button/SelectPlanButton.stories.tsx +184 -184
  87. package/src/components/select-plan-button/index.tsx +63 -63
  88. package/src/components/select-plan-button/types.ts +17 -17
  89. package/src/components/skeleton/Skeleton.stories.tsx +179 -179
  90. package/src/components/skeleton/index.tsx +61 -61
  91. package/src/components/skeleton/types.ts +4 -4
  92. package/src/components/spinner/Spinner.stories.tsx +335 -335
  93. package/src/components/spinner/index.tsx +44 -44
  94. package/src/components/spinner/types.ts +5 -5
  95. package/src/components/text/Text.stories.tsx +321 -321
  96. package/src/components/text/index.tsx +25 -25
  97. package/src/components/text/types.ts +45 -45
  98. package/src/components/tooltip/Tooltip.stories.tsx +219 -219
  99. package/src/components/tooltip/index.tsx +74 -74
  100. package/src/components/tooltip/types.ts +7 -7
  101. package/src/components/view-cart-button/ViewCartButton.stories.tsx +252 -252
  102. package/src/components/view-cart-button/index.tsx +42 -42
  103. package/src/components/view-cart-button/types.ts +5 -5
  104. package/src/contentful/blocks/accordion/Accordion.stories.tsx +34 -34
  105. package/src/contentful/blocks/accordion/index.tsx +112 -112
  106. package/src/contentful/blocks/accordion/types.ts +34 -34
  107. package/src/contentful/blocks/address-input-banner/index.tsx +52 -52
  108. package/src/contentful/blocks/address-input-banner/types.ts +14 -14
  109. package/src/contentful/blocks/anchored-bottom-banner/index.tsx +70 -70
  110. package/src/contentful/blocks/anchored-bottom-banner/types.ts +10 -10
  111. package/src/contentful/blocks/blogs-grid/index.tsx +134 -134
  112. package/src/contentful/blocks/blogs-grid/types.ts +26 -26
  113. package/src/contentful/blocks/breadcrumbs/index.tsx +51 -51
  114. package/src/contentful/blocks/breadcrumbs/types.ts +5 -5
  115. package/src/contentful/blocks/button/Button.stories.tsx +40 -40
  116. package/src/contentful/blocks/button/index.tsx +130 -130
  117. package/src/contentful/blocks/button/types.ts +39 -39
  118. package/src/contentful/blocks/callout/Callout.stories.tsx +23 -23
  119. package/src/contentful/blocks/callout/index.tsx +88 -88
  120. package/src/contentful/blocks/callout/types.ts +15 -15
  121. package/src/contentful/blocks/cards/Cards.stories.tsx +23 -23
  122. package/src/contentful/blocks/cards/blog-card/index.tsx +110 -110
  123. package/src/contentful/blocks/cards/blog-card/types.ts +18 -18
  124. package/src/contentful/blocks/cards/index.tsx +13 -13
  125. package/src/contentful/blocks/cards/product-card/index.tsx +251 -251
  126. package/src/contentful/blocks/cards/product-card/types.ts +28 -28
  127. package/src/contentful/blocks/cards/simple-card/index.tsx +89 -89
  128. package/src/contentful/blocks/cards/simple-card/types.ts +28 -28
  129. package/src/contentful/blocks/cards/testimonial-card/index.tsx +90 -90
  130. package/src/contentful/blocks/cards/testimonial-card/types.tsx +12 -12
  131. package/src/contentful/blocks/cards/types.ts +1 -1
  132. package/src/contentful/blocks/carousel/Carousel.stories.tsx +23 -23
  133. package/src/contentful/blocks/carousel/helper.tsx +440 -440
  134. package/src/contentful/blocks/carousel/index.tsx +85 -85
  135. package/src/contentful/blocks/carousel/types.ts +144 -144
  136. package/src/contentful/blocks/cartretentionbanner/CartRetentionBanner.tsx +99 -0
  137. package/src/contentful/blocks/cartretentionbanner/types.ts +11 -0
  138. package/src/contentful/blocks/comparison-table/index.tsx +27 -27
  139. package/src/contentful/blocks/comparison-table/types.ts +6 -6
  140. package/src/contentful/blocks/cookiebanner/index.tsx +146 -146
  141. package/src/contentful/blocks/cookiebanner/type.ts +7 -7
  142. package/src/contentful/blocks/cta-callout/CtaCallout.stories.tsx +46 -46
  143. package/src/contentful/blocks/cta-callout/index.tsx +71 -71
  144. package/src/contentful/blocks/cta-callout/types.ts +26 -26
  145. package/src/contentful/blocks/dynamic-tabs/index.tsx +204 -204
  146. package/src/contentful/blocks/dynamic-tabs/types.ts +21 -21
  147. package/src/contentful/blocks/email-input-block/index.tsx +117 -117
  148. package/src/contentful/blocks/email-input-block/types.ts +16 -16
  149. package/src/contentful/blocks/find-kinetic/FindKinetic.stories.tsx +23 -23
  150. package/src/contentful/blocks/find-kinetic/index.tsx +130 -130
  151. package/src/contentful/blocks/find-kinetic/types.ts +19 -19
  152. package/src/contentful/blocks/floating-banner/FloatingBanner.stories.tsx +34 -34
  153. package/src/contentful/blocks/floating-banner/index.tsx +97 -97
  154. package/src/contentful/blocks/floating-banner/types.ts +22 -22
  155. package/src/contentful/blocks/footer/Footer.stories.tsx +30 -30
  156. package/src/contentful/blocks/footer/index.tsx +91 -91
  157. package/src/contentful/blocks/footer/types.ts +13 -13
  158. package/src/contentful/blocks/image-promo-bar/ImagePromoBar.stories.tsx +23 -23
  159. package/src/contentful/blocks/image-promo-bar/helper.tsx +28 -28
  160. package/src/contentful/blocks/image-promo-bar/index.tsx +246 -246
  161. package/src/contentful/blocks/image-promo-bar/types.ts +44 -44
  162. package/src/contentful/blocks/image-promo-bar/vimeo-embed.tsx +93 -93
  163. package/src/contentful/blocks/image-promo-bar/youtube-embed.tsx +46 -46
  164. package/src/contentful/blocks/modal/constants.ts +53 -53
  165. package/src/contentful/blocks/modal/index.tsx +107 -107
  166. package/src/contentful/blocks/modal/types.ts +12 -12
  167. package/src/contentful/blocks/navigation/desktop-link-groups.tsx/index.tsx +113 -113
  168. package/src/contentful/blocks/navigation/index.tsx +394 -394
  169. package/src/contentful/blocks/navigation/mobile-link-groups.tsx/index.tsx +82 -82
  170. package/src/contentful/blocks/navigation/types.ts +41 -41
  171. package/src/contentful/blocks/primary-hero/PrimaryHero.stories.tsx +23 -23
  172. package/src/contentful/blocks/primary-hero/index.tsx +236 -236
  173. package/src/contentful/blocks/primary-hero/types.ts +37 -37
  174. package/src/contentful/blocks/search-block/index.tsx +90 -90
  175. package/src/contentful/blocks/search-block/types.ts +15 -15
  176. package/src/contentful/blocks/shape-background-wrapper/ShapeBackgroundWrapper.stories.tsx +26 -26
  177. package/src/contentful/blocks/shape-background-wrapper/index.tsx +124 -124
  178. package/src/contentful/blocks/shape-background-wrapper/types.ts +36 -36
  179. package/src/contentful/blocks/text/Text.stories.tsx +23 -23
  180. package/src/contentful/blocks/text/index.tsx +12 -12
  181. package/src/contentful/blocks/text/types.ts +1 -1
  182. package/src/contentful/index.ts +99 -99
  183. package/src/hooks/contentful/use-contentful-rich-text.tsx +310 -310
  184. package/src/hooks/contentful/use-processed-check-list.ts +63 -63
  185. package/src/hooks/use-body-scroll-lock.ts +34 -34
  186. package/src/hooks/use-carousel-swipe.ts +264 -264
  187. package/src/hooks/use-outside-click.ts +17 -17
  188. package/src/index.ts +101 -101
  189. package/src/next/index.ts +5 -5
  190. package/src/setupTests.ts +46 -46
  191. package/src/stories/DocsTemplate.tsx +24 -24
  192. package/src/styles/globals.css +343 -343
  193. package/src/types/global.d.ts +9 -9
  194. package/src/types/micro-components.ts +99 -99
  195. package/src/types/utm.ts +49 -49
  196. package/src/utils/contentful/to-document.ts +24 -24
  197. package/src/utils/cookie.ts +84 -84
  198. package/src/utils/cx.ts +49 -49
  199. package/src/utils/index.ts +38 -38
  200. package/src/utils/utm.ts +221 -221
@@ -1,89 +1,89 @@
1
- import React from "react";
2
- import { Button } from "../../button";
3
- import { backgroundColorMap, Item, SimpleCardProps } from "./types";
4
-
5
- import { NextImage } from "@shared/components/next-image";
6
- import { Text } from "@shared/components/text";
7
-
8
- export const SimpleCard: React.FC<SimpleCardProps> = ({
9
- card,
10
- lgWidth,
11
- mdWidth,
12
- }) => {
13
- const imageRenderer = (item: Item) => {
14
- if (!item.image) return null;
15
-
16
- // Handle both lowercase and capitalized versions from Contentful
17
- const view = item.imageView?.toLowerCase();
18
-
19
- switch (view) {
20
- case "full":
21
- return (
22
- <NextImage
23
- width={400}
24
- height={280}
25
- src={item.image}
26
- alt={item.title ?? "card-icon"}
27
- className="rounded-3xl"
28
- />
29
- );
30
- case "icon":
31
- case "inset":
32
- default:
33
- return (
34
- <NextImage
35
- width={88}
36
- height={88}
37
- src={item.image}
38
- alt={item.title ?? "card-icon"}
39
- />
40
- );
41
- }
42
- };
43
-
44
- const imageAlignment = card.imageAlignment?.toLowerCase() || "left";
45
- const imageAlignClass =
46
- imageAlignment === "left"
47
- ? "lg:items-start"
48
- : imageAlignment === "right"
49
- ? "lg:items-end"
50
- : "lg:items-center";
51
-
52
- return (
53
- <div
54
- className={`callout-card ${mdWidth} ${lgWidth} w-full ${backgroundColorMap[card.backgroundColor ?? ""] ?? ""}`}
55
- >
56
- <div
57
- className={`card-template flex h-full flex-col gap-6 p-6 text-center md:gap-8 md:p-8 ${imageAlignClass}`}
58
- >
59
- <div className="card-header">{imageRenderer(card)}</div>
60
-
61
- <div className="card-body flex flex-col gap-3 text-start md:gap-4">
62
- {card.title && (
63
- <Text as="h5" className="heading6 text-text md:heading5">
64
- {card.title}
65
- </Text>
66
- )}
67
- {card.body && (
68
- <Text as="div" className="body1 text-text">
69
- {card.body}
70
- </Text>
71
- )}
72
- </div>
73
- {card.cta && (
74
- <div className="card-footer">
75
- <Button
76
- linkVariant="unstyled"
77
- linkClassName="label1 flex items-center text-text gap-2"
78
- {...card.cta}
79
- iconName={"expand_circle_right"}
80
- iconFill={1}
81
- />
82
- </div>
83
- )}
84
- </div>
85
- </div>
86
- );
87
- };
88
-
89
- export default SimpleCard;
1
+ import React from "react";
2
+ import { Button } from "../../button";
3
+ import { backgroundColorMap, Item, SimpleCardProps } from "./types";
4
+
5
+ import { NextImage } from "@shared/components/next-image";
6
+ import { Text } from "@shared/components/text";
7
+
8
+ export const SimpleCard: React.FC<SimpleCardProps> = ({
9
+ card,
10
+ lgWidth,
11
+ mdWidth,
12
+ }) => {
13
+ const imageRenderer = (item: Item) => {
14
+ if (!item.image) return null;
15
+
16
+ // Handle both lowercase and capitalized versions from Contentful
17
+ const view = item.imageView?.toLowerCase();
18
+
19
+ switch (view) {
20
+ case "full":
21
+ return (
22
+ <NextImage
23
+ width={400}
24
+ height={280}
25
+ src={item.image}
26
+ alt={item.title ?? "card-icon"}
27
+ className="rounded-3xl"
28
+ />
29
+ );
30
+ case "icon":
31
+ case "inset":
32
+ default:
33
+ return (
34
+ <NextImage
35
+ width={88}
36
+ height={88}
37
+ src={item.image}
38
+ alt={item.title ?? "card-icon"}
39
+ />
40
+ );
41
+ }
42
+ };
43
+
44
+ const imageAlignment = card.imageAlignment?.toLowerCase() || "left";
45
+ const imageAlignClass =
46
+ imageAlignment === "left"
47
+ ? "lg:items-start"
48
+ : imageAlignment === "right"
49
+ ? "lg:items-end"
50
+ : "lg:items-center";
51
+
52
+ return (
53
+ <div
54
+ className={`callout-card ${mdWidth} ${lgWidth} w-full ${backgroundColorMap[card.backgroundColor ?? ""] ?? ""}`}
55
+ >
56
+ <div
57
+ className={`card-template flex h-full flex-col gap-6 p-6 text-center md:gap-8 md:p-8 ${imageAlignClass}`}
58
+ >
59
+ <div className="card-header">{imageRenderer(card)}</div>
60
+
61
+ <div className="card-body flex flex-col gap-3 text-start md:gap-4">
62
+ {card.title && (
63
+ <Text as="h5" className="heading6 text-text md:heading5">
64
+ {card.title}
65
+ </Text>
66
+ )}
67
+ {card.body && (
68
+ <Text as="div" className="body1 text-text">
69
+ {card.body}
70
+ </Text>
71
+ )}
72
+ </div>
73
+ {card.cta && (
74
+ <div className="card-footer">
75
+ <Button
76
+ linkVariant="unstyled"
77
+ linkClassName="label1 flex items-center text-text gap-2"
78
+ {...card.cta}
79
+ iconName={"expand_circle_right"}
80
+ iconFill={1}
81
+ />
82
+ </div>
83
+ )}
84
+ </div>
85
+ </div>
86
+ );
87
+ };
88
+
89
+ export default SimpleCard;
@@ -1,28 +1,28 @@
1
- import { ReactNode } from "react";
2
- import { ButtonProps } from "../../button/types";
3
-
4
- export type Item = {
5
- title?: string;
6
- image?: string;
7
- imageAlignment?: "left" | "right" | "center";
8
- imageView?: "standard" | "icon" | "full";
9
- cta?: ButtonProps;
10
- ctaAlignment?: "left" | "right" | "center";
11
- body?: ReactNode;
12
- backgroundColor?: string;
13
- };
14
-
15
- export type SimpleCardProps = {
16
- card: Item;
17
- lgWidth?: string;
18
- mdWidth?: string;
19
- };
20
-
21
- export const backgroundColorMap: Record<string, string> = {
22
- blue: "bg-fill-brand",
23
- green: "bg-fill-brand-accent",
24
- navy: "bg-fill-inverse",
25
- purple: "bg-fill-brand-tertiary",
26
- white: "bg-white",
27
- yellow: "bg-[#F5FF1E]",
28
- };
1
+ import { ReactNode } from "react";
2
+ import { ButtonProps } from "../../button/types";
3
+
4
+ export type Item = {
5
+ title?: string;
6
+ image?: string;
7
+ imageAlignment?: "left" | "right" | "center";
8
+ imageView?: "standard" | "icon" | "full";
9
+ cta?: ButtonProps;
10
+ ctaAlignment?: "left" | "right" | "center";
11
+ body?: ReactNode;
12
+ backgroundColor?: string;
13
+ };
14
+
15
+ export type SimpleCardProps = {
16
+ card: Item;
17
+ lgWidth?: string;
18
+ mdWidth?: string;
19
+ };
20
+
21
+ export const backgroundColorMap: Record<string, string> = {
22
+ blue: "bg-fill-brand",
23
+ green: "bg-fill-brand-accent",
24
+ navy: "bg-fill-inverse",
25
+ purple: "bg-fill-brand-tertiary",
26
+ white: "bg-white",
27
+ yellow: "bg-[#F5FF1E]",
28
+ };
@@ -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 = {};