@windstream/react-shared-components 0.2.21 → 0.2.23

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 (37) hide show
  1. package/dist/contentful/index.d.ts +6 -3
  2. package/dist/contentful/index.esm.js +3 -3
  3. package/dist/contentful/index.esm.js.map +1 -1
  4. package/dist/contentful/index.js +2 -2
  5. package/dist/contentful/index.js.map +1 -1
  6. package/dist/core.d.ts +10 -5
  7. package/dist/index.d.ts +6 -1
  8. package/dist/index.esm.js +1 -1
  9. package/dist/index.esm.js.map +1 -1
  10. package/dist/index.js +5 -5
  11. package/dist/index.js.map +1 -1
  12. package/dist/styles.css +1 -1
  13. package/dist/utils/index.d.ts +3 -1
  14. package/dist/utils/index.esm.js +1 -1
  15. package/dist/utils/index.esm.js.map +1 -1
  16. package/dist/utils/index.js +1 -1
  17. package/dist/utils/index.js.map +1 -1
  18. package/package.json +1 -1
  19. package/src/components/animation-wrapper/index.tsx +8 -2
  20. package/src/components/animation-wrapper/types.ts +6 -0
  21. package/src/components/brand-button/index.tsx +12 -3
  22. package/src/contentful/blocks/anchored-bottom-banner/AnchoredBottomBanner.stories.tsx +155 -0
  23. package/src/contentful/blocks/button/index.tsx +12 -3
  24. package/src/contentful/blocks/callout/Callout.stories.mocks.ts +327 -0
  25. package/src/contentful/blocks/callout/Callout.stories.tsx +315 -2
  26. package/src/contentful/blocks/callout/types.ts +1 -2
  27. package/src/contentful/blocks/email-input-block/index.tsx +41 -17
  28. package/src/contentful/blocks/email-input-block/types.ts +2 -1
  29. package/src/contentful/blocks/image-promo-bar/index.test.tsx +45 -4
  30. package/src/contentful/blocks/image-promo-bar/index.tsx +4 -1
  31. package/src/contentful/blocks/image-promo-bar/types.ts +1 -0
  32. package/src/contentful/blocks/primary-hero/index.test.tsx +63 -0
  33. package/src/contentful/blocks/primary-hero/index.tsx +66 -9
  34. package/src/hooks/contentful/use-contentful-rich-text.test.tsx +29 -0
  35. package/src/hooks/contentful/use-contentful-rich-text.tsx +20 -9
  36. package/src/index.ts +1 -0
  37. package/src/types/global.d.ts +5 -0
@@ -13,6 +13,7 @@ export const PrimaryHero: React.FC<PrimaryHeroProps> = props => {
13
13
  showAsHeading,
14
14
  subTitle,
15
15
  primaryCta1,
16
+ primaryCta2,
16
17
  carouselImages,
17
18
  bottomLink,
18
19
  price,
@@ -27,10 +28,24 @@ export const PrimaryHero: React.FC<PrimaryHeroProps> = props => {
27
28
  secondaryCtaPrefix,
28
29
  onModalButtonClick,
29
30
  hideOnMobileCta1,
31
+ hideOnMobileCta2,
30
32
  textColor = "light",
31
33
  logoLockup,
32
34
  } = props;
33
35
 
36
+ const isButtonType = (cta: any) => {
37
+ const type = cta?.showButtonAs ?? "solid";
38
+ return (
39
+ type === "solid" || type === "button-with-icon" || type === "unstyled"
40
+ );
41
+ };
42
+
43
+ const showCtasSideBySide =
44
+ primaryCta1 &&
45
+ primaryCta2 &&
46
+ isButtonType(primaryCta1) &&
47
+ isButtonType(primaryCta2);
48
+
34
49
  const bottomLinkLabel = bottomLink?.buttonLabel ?? bottomLink?.label;
35
50
  const textColorClass = textColor === "light" ? " text-white" : " text-text";
36
51
  return (
@@ -133,16 +148,58 @@ export const PrimaryHero: React.FC<PrimaryHeroProps> = props => {
133
148
  {/* CTA section */}
134
149
  <div className="flex flex-col gap-3">
135
150
  {/* desktop CTA */}
136
- {primaryCta1 && (
137
- <div className={cx("md:block", hideOnMobileCta1 && "hidden")}>
138
- <Button
139
- {...primaryCta1}
140
- renderCheckPlans={renderCheckPlans}
141
- onModalButtonClick={onModalButtonClick}
142
- fullWidth={true}
143
- buttonClassName="md:w-auto"
144
- />
151
+ {showCtasSideBySide ? (
152
+ <div className="flex flex-col justify-center gap-3 sm:flex-row sm:gap-4">
153
+ <div className={cx(hideOnMobileCta1 && "hidden md:block")}>
154
+ <Button
155
+ {...primaryCta1}
156
+ renderCheckPlans={renderCheckPlans}
157
+ onModalButtonClick={onModalButtonClick}
158
+ fullWidth={true}
159
+ size={{ base: "large" }}
160
+ buttonClassName="md:w-auto text-center"
161
+ />
162
+ </div>
163
+ <div className={cx(hideOnMobileCta2 && "hidden md:block")}>
164
+ <Button
165
+ {...primaryCta2}
166
+ renderCheckPlans={renderCheckPlans}
167
+ onModalButtonClick={onModalButtonClick}
168
+ fullWidth={true}
169
+ size={{ base: "large" }}
170
+ buttonClassName="md:w-auto text-center"
171
+ />
172
+ </div>
145
173
  </div>
174
+ ) : (
175
+ <>
176
+ {primaryCta1 && (
177
+ <div
178
+ className={cx("md:block", hideOnMobileCta1 && "hidden")}
179
+ >
180
+ <Button
181
+ {...primaryCta1}
182
+ renderCheckPlans={renderCheckPlans}
183
+ onModalButtonClick={onModalButtonClick}
184
+ fullWidth={true}
185
+ buttonClassName="md:w-auto text-center"
186
+ />
187
+ </div>
188
+ )}
189
+ {primaryCta2 && (
190
+ <div
191
+ className={cx("md:block", hideOnMobileCta2 && "hidden")}
192
+ >
193
+ <Button
194
+ {...primaryCta2}
195
+ renderCheckPlans={renderCheckPlans}
196
+ onModalButtonClick={onModalButtonClick}
197
+ fullWidth={true}
198
+ buttonClassName="md:w-auto text-center"
199
+ />
200
+ </div>
201
+ )}
202
+ </>
146
203
  )}
147
204
  {secondaryCtaPrefix && secondaryCta ? (
148
205
  <div className="hidden md:flex">
@@ -707,6 +707,35 @@ describe("useContentfulRichText", () => {
707
707
  expect(screen.getByTestId("custom-bold")).toHaveTextContent("Custom bold");
708
708
  });
709
709
 
710
+ it("supports optional bold class name", () => {
711
+ const doc = makeDoc(makeMarkedText("Styled bold", MARKS.BOLD));
712
+ const { result } = renderHook(() =>
713
+ useContentfulRichText(doc, undefined, { boldClassName: "label3" })
714
+ );
715
+ const { container } = render(<>{result.current}</>);
716
+ const strong = container.querySelector("strong")!;
717
+ expect(strong).toHaveClass("label3");
718
+ expect(strong).toHaveTextContent("Styled bold");
719
+ });
720
+
721
+ it("keeps custom renderMark bold precedence over boldClassName", () => {
722
+ const doc = makeDoc(makeMarkedText("Priority", MARKS.BOLD));
723
+ const customOpts = {
724
+ renderMark: {
725
+ [MARKS.BOLD]: (text: any) => (
726
+ <b data-testid="custom-priority-bold">{text}</b>
727
+ ),
728
+ },
729
+ };
730
+ const { result } = renderHook(() =>
731
+ useContentfulRichText(doc, customOpts, { boldClassName: "label3" })
732
+ );
733
+ render(<>{result.current}</>);
734
+ expect(screen.getByTestId("custom-priority-bold")).toHaveTextContent(
735
+ "Priority"
736
+ );
737
+ });
738
+
710
739
  it("memoizes result for same doc reference", () => {
711
740
  const doc = makeDoc(makeParagraph("Memoized"));
712
741
  const { result, rerender } = renderHook(
@@ -18,7 +18,7 @@ import { toDocument } from "@shared/utils/contentful/to-document";
18
18
 
19
19
  const defaultOptions: Options = {
20
20
  renderMark: {
21
- [MARKS.BOLD]: text => <strong className="label3">{text}</strong>,
21
+ [MARKS.BOLD]: text => <strong>{text}</strong>,
22
22
  [MARKS.ITALIC]: text => <em>{text}</em>,
23
23
  [MARKS.UNDERLINE]: text => <u>{text}</u>,
24
24
  [MARKS.CODE]: text => <code>{text}</code>,
@@ -35,27 +35,27 @@ const defaultOptions: Options = {
35
35
  );
36
36
  },
37
37
  [BLOCKS.HEADING_2]: (node, children) => (
38
- <Text as="h2" className={"heading6 md:heading5"}>
38
+ <Text as="h2" className={"heading3 md:heading2"}>
39
39
  {children}
40
40
  </Text>
41
41
  ),
42
42
  [BLOCKS.HEADING_3]: (node, children) => (
43
- <Text as="h3" className={"heading6 md:heading5"}>
43
+ <Text as="h3" className={"heading4 md:heading3"}>
44
44
  {children}
45
45
  </Text>
46
46
  ),
47
47
  [BLOCKS.HEADING_4]: (node, children) => (
48
- <Text as="h3" className={"headingClass"}>
48
+ <Text as="h4" className={"heading5 md:heading4"}>
49
49
  {children}
50
50
  </Text>
51
51
  ),
52
52
  [BLOCKS.HEADING_5]: (node, children) => (
53
- <Text as="h3" className={"heading6 md:heading5"}>
53
+ <Text as="h5" className={"heading6 md:heading5"}>
54
54
  {children}
55
55
  </Text>
56
56
  ),
57
57
  [BLOCKS.HEADING_6]: (node, children) => (
58
- <Text as="h3" className={"heading6"}>
58
+ <Text as="h6" className={"heading6"}>
59
59
  {children}
60
60
  </Text>
61
61
  ),
@@ -187,17 +187,28 @@ export function renderContentfulRichText(
187
187
 
188
188
  export function useContentfulRichText(
189
189
  doc: Document | null | undefined,
190
- options?: Options
190
+ options?: Options,
191
+ config?: { boldClassName?: string }
191
192
  ): ReactNode | null {
192
193
  return useMemo(() => {
193
194
  if (!doc || !Array.isArray(doc.content)) return null;
194
195
  const merged: Options = {
195
196
  ...defaultOptions,
196
- renderMark: { ...defaultOptions.renderMark, ...options?.renderMark },
197
+ renderMark: {
198
+ ...defaultOptions.renderMark,
199
+ ...(config?.boldClassName
200
+ ? {
201
+ [MARKS.BOLD]: text => (
202
+ <strong className={config.boldClassName}>{text}</strong>
203
+ ),
204
+ }
205
+ : {}),
206
+ ...options?.renderMark,
207
+ },
197
208
  renderNode: { ...defaultOptions.renderNode, ...options?.renderNode },
198
209
  };
199
210
  return documentToReactComponents(doc, merged);
200
- }, [doc, options]);
211
+ }, [doc, options, config?.boldClassName]);
201
212
  }
202
213
  // 1. Remove useMemo and React Hook imports from this specific function's logic
203
214
  export function renderContentfulRichTextTable(
package/src/index.ts CHANGED
@@ -84,6 +84,7 @@ export { Tooltip } from "./components/tooltip";
84
84
  export type { ToolTipProps } from "./components/tooltip";
85
85
 
86
86
  export { AnimationWrapper } from "./components/animation-wrapper";
87
+ export { DEFAULT_BUTTON_ANIMATION_TYPE } from "./components/animation-wrapper";
87
88
  export type {
88
89
  AnimationWrapperProps,
89
90
  AnimationType,
@@ -7,3 +7,8 @@ declare module "*.css" {
7
7
  const content: string;
8
8
  export default content;
9
9
  }
10
+
11
+ declare module "*.svg" {
12
+ const src: string;
13
+ export default src;
14
+ }