@windstream/react-shared-components 0.2.21 → 0.2.22
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/dist/contentful/index.d.ts +1 -0
- package/dist/contentful/index.esm.js +2 -2
- package/dist/contentful/index.esm.js.map +1 -1
- package/dist/contentful/index.js +2 -2
- package/dist/contentful/index.js.map +1 -1
- package/dist/core.d.ts +11 -6
- package/dist/index.d.ts +9 -4
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/animation-wrapper/index.tsx +8 -2
- package/src/components/animation-wrapper/types.ts +6 -0
- package/src/components/brand-button/index.tsx +12 -3
- package/src/contentful/blocks/button/index.tsx +12 -3
- package/src/contentful/blocks/image-promo-bar/index.test.tsx +45 -4
- package/src/contentful/blocks/image-promo-bar/index.tsx +4 -1
- package/src/contentful/blocks/image-promo-bar/types.ts +1 -0
- package/src/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import React from "react";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
AnimationType,
|
|
6
|
+
AnimationWrapperProps,
|
|
7
|
+
DEFAULT_BUTTON_ANIMATION_TYPE,
|
|
8
|
+
} from "./types";
|
|
5
9
|
import { motion, useReducedMotion } from "framer-motion";
|
|
6
10
|
|
|
7
11
|
interface AnimationPreset {
|
|
@@ -66,7 +70,7 @@ function mergePresets(animationType?: AnimationType | AnimationType[]) {
|
|
|
66
70
|
|
|
67
71
|
export function AnimationWrapper({
|
|
68
72
|
children,
|
|
69
|
-
animationType,
|
|
73
|
+
animationType = DEFAULT_BUTTON_ANIMATION_TYPE,
|
|
70
74
|
// default to true for backward compatibility
|
|
71
75
|
disableAnimation = true,
|
|
72
76
|
whileHover,
|
|
@@ -84,6 +88,7 @@ export function AnimationWrapper({
|
|
|
84
88
|
return child;
|
|
85
89
|
}
|
|
86
90
|
|
|
91
|
+
// Use the provided animationType, falling back to the centralized default.
|
|
87
92
|
const preset = mergePresets(animationType);
|
|
88
93
|
|
|
89
94
|
const mergedWhileHover = preset
|
|
@@ -132,4 +137,5 @@ export function AnimationWrapper({
|
|
|
132
137
|
|
|
133
138
|
AnimationWrapper.displayName = "AnimationWrapper";
|
|
134
139
|
|
|
140
|
+
export { DEFAULT_BUTTON_ANIMATION_TYPE };
|
|
135
141
|
export type { AnimationWrapperProps, AnimationType };
|
|
@@ -9,6 +9,12 @@ export type AnimationType =
|
|
|
9
9
|
| "grow"
|
|
10
10
|
| "pop";
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Single source of truth for the default button animation type.
|
|
14
|
+
* Change this value to update the default button animation across the app.
|
|
15
|
+
*/
|
|
16
|
+
export const DEFAULT_BUTTON_ANIMATION_TYPE: AnimationType = "pop";
|
|
17
|
+
|
|
12
18
|
export interface AnimationWrapperProps
|
|
13
19
|
extends Omit<HTMLMotionProps<"div">, "children"> {
|
|
14
20
|
children: ReactElement;
|
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
import React, { forwardRef } from "react";
|
|
4
4
|
import { getLabelSizeBasedOnButtonSize, sizeToClassNames } from "./helpers";
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
AnimationWrapper,
|
|
8
|
+
DEFAULT_BUTTON_ANIMATION_TYPE,
|
|
9
|
+
} from "@shared/components/animation-wrapper";
|
|
7
10
|
import {
|
|
8
11
|
ButtonProps,
|
|
9
12
|
ButtonVariantsT,
|
|
@@ -29,9 +32,15 @@ export const BrandButton = forwardRef<
|
|
|
29
32
|
iconName,
|
|
30
33
|
iconSize = 24,
|
|
31
34
|
iconFill = 0,
|
|
35
|
+
// `disableAnimation` is intentionally NOT defaulted to `false` here.
|
|
36
|
+
// Animations are opt-in by design: when this prop is left undefined,
|
|
37
|
+
// AnimationWrapper falls back to its own default of `true` (animation
|
|
38
|
+
// disabled). This keeps behavior consistent with the CMS contract where
|
|
39
|
+
// an unset value means "no animation". Animation runs only when a caller
|
|
40
|
+
// (or Contentful) explicitly passes `disableAnimation={false}`.
|
|
41
|
+
disableAnimation,
|
|
42
|
+
animationType = DEFAULT_BUTTON_ANIMATION_TYPE,
|
|
32
43
|
as = "button",
|
|
33
|
-
disableAnimation = true,
|
|
34
|
-
animationType,
|
|
35
44
|
...props
|
|
36
45
|
},
|
|
37
46
|
ref
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { ButtonProps } from "./types";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
AnimationWrapper,
|
|
6
|
+
DEFAULT_BUTTON_ANIMATION_TYPE,
|
|
7
|
+
} from "@shared/components/animation-wrapper";
|
|
5
8
|
import { BrandButton, ButtonVariantsT } from "@shared/components/brand-button";
|
|
6
9
|
import { Button as CoreButton } from "@shared/components/button";
|
|
7
10
|
import { Link } from "@shared/components/link";
|
|
@@ -35,8 +38,8 @@ export const Button: React.FC<ButtonProps> = props => {
|
|
|
35
38
|
size,
|
|
36
39
|
iconSize = 24,
|
|
37
40
|
preserveQueryParameters,
|
|
38
|
-
disableAnimation
|
|
39
|
-
animationType,
|
|
41
|
+
disableAnimation,
|
|
42
|
+
animationType = DEFAULT_BUTTON_ANIMATION_TYPE,
|
|
40
43
|
...rest
|
|
41
44
|
} = props;
|
|
42
45
|
|
|
@@ -51,6 +54,12 @@ export const Button: React.FC<ButtonProps> = props => {
|
|
|
51
54
|
cta: { ...props },
|
|
52
55
|
});
|
|
53
56
|
return React.isValidElement(checkPlansNode) ? (
|
|
57
|
+
// `disableAnimation` is passed through as-is (not defaulted to `false`).
|
|
58
|
+
// Animations are opt-in: when unset, AnimationWrapper falls back to its
|
|
59
|
+
// default of `true` (disabled), matching the CMS contract where an unset
|
|
60
|
+
// value means "no animation". This stays consistent with the other
|
|
61
|
+
// branches in this block. Animation runs only when a caller explicitly
|
|
62
|
+
// passes `disableAnimation={false}`.
|
|
54
63
|
<AnimationWrapper
|
|
55
64
|
disableAnimation={disableAnimation}
|
|
56
65
|
animationType={animationType}
|
|
@@ -7,11 +7,21 @@ import { fireEvent, render, screen } from "@testing-library/react";
|
|
|
7
7
|
jest.mock("../button", () => ({
|
|
8
8
|
__esModule: true,
|
|
9
9
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
10
|
-
Button: ({ buttonLabel, ...rest }: any) => (
|
|
11
|
-
<button
|
|
10
|
+
Button: ({ buttonLabel, disableAnimation, ...rest }: any) => (
|
|
11
|
+
<button
|
|
12
|
+
data-testid="cta-button"
|
|
13
|
+
data-disable-animation={String(disableAnimation)}
|
|
14
|
+
>
|
|
15
|
+
{buttonLabel || "CTA"}
|
|
16
|
+
</button>
|
|
12
17
|
),
|
|
13
|
-
default: ({ buttonLabel }: any) => (
|
|
14
|
-
<button
|
|
18
|
+
default: ({ buttonLabel, disableAnimation }: any) => (
|
|
19
|
+
<button
|
|
20
|
+
data-testid="cta-button"
|
|
21
|
+
data-disable-animation={String(disableAnimation)}
|
|
22
|
+
>
|
|
23
|
+
{buttonLabel || "CTA"}
|
|
24
|
+
</button>
|
|
15
25
|
),
|
|
16
26
|
}));
|
|
17
27
|
|
|
@@ -245,6 +255,37 @@ describe("ImagePromoBar", () => {
|
|
|
245
255
|
const { container } = render(<ImagePromoBar {...defaultProps} />);
|
|
246
256
|
expect(container.querySelector(".primary-cta")).not.toBeInTheDocument();
|
|
247
257
|
});
|
|
258
|
+
|
|
259
|
+
it("keeps disableAnimation true on both CTAs by default", () => {
|
|
260
|
+
render(
|
|
261
|
+
<ImagePromoBar
|
|
262
|
+
{...defaultProps}
|
|
263
|
+
cta={{ buttonLabel: "Primary" }}
|
|
264
|
+
secondaryCta={{ buttonLabel: "Secondary" }}
|
|
265
|
+
/>
|
|
266
|
+
);
|
|
267
|
+
const buttons = screen.getAllByTestId("cta-button");
|
|
268
|
+
expect(buttons).toHaveLength(2);
|
|
269
|
+
buttons.forEach(button => {
|
|
270
|
+
expect(button).toHaveAttribute("data-disable-animation", "true");
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
it("passes disableAnimation false to both CTAs when enableAnimation is true", () => {
|
|
275
|
+
render(
|
|
276
|
+
<ImagePromoBar
|
|
277
|
+
{...defaultProps}
|
|
278
|
+
cta={{ buttonLabel: "Primary" }}
|
|
279
|
+
secondaryCta={{ buttonLabel: "Secondary" }}
|
|
280
|
+
enableAnimation={true}
|
|
281
|
+
/>
|
|
282
|
+
);
|
|
283
|
+
const buttons = screen.getAllByTestId("cta-button");
|
|
284
|
+
expect(buttons).toHaveLength(2);
|
|
285
|
+
buttons.forEach(button => {
|
|
286
|
+
expect(button).toHaveAttribute("data-disable-animation", "false");
|
|
287
|
+
});
|
|
288
|
+
});
|
|
248
289
|
});
|
|
249
290
|
|
|
250
291
|
describe("Image", () => {
|
|
@@ -36,6 +36,7 @@ export const ImagePromoBar: React.FC<ImagePromoBarProps> = ({
|
|
|
36
36
|
onModalButtonClick,
|
|
37
37
|
onClick,
|
|
38
38
|
renderCheckPlans,
|
|
39
|
+
enableAnimation = false,
|
|
39
40
|
}) => {
|
|
40
41
|
const [activeVideo, setActiveVideo] = useState("");
|
|
41
42
|
const [isHovered, setIsHovered] = useState(false);
|
|
@@ -138,11 +139,12 @@ export const ImagePromoBar: React.FC<ImagePromoBarProps> = ({
|
|
|
138
139
|
)}
|
|
139
140
|
{/* CTAs and Disclaimers */}
|
|
140
141
|
{(cta || secondaryCta) && (
|
|
141
|
-
<div className="flex w-full flex-col gap-
|
|
142
|
+
<div className="flex w-full flex-col gap-4 xl:flex-row">
|
|
142
143
|
{cta && (
|
|
143
144
|
<div className="primary-cta w-full xl:w-auto xl:shrink-0">
|
|
144
145
|
<Button
|
|
145
146
|
{...cta}
|
|
147
|
+
disableAnimation={!enableAnimation}
|
|
146
148
|
fullWidth={true}
|
|
147
149
|
size={{ base: "large" }}
|
|
148
150
|
renderCheckPlans={renderCheckPlans}
|
|
@@ -155,6 +157,7 @@ export const ImagePromoBar: React.FC<ImagePromoBarProps> = ({
|
|
|
155
157
|
<div className="secondary-cta w-full xl:w-auto xl:shrink-0">
|
|
156
158
|
<Button
|
|
157
159
|
{...secondaryCta}
|
|
160
|
+
disableAnimation={!enableAnimation}
|
|
158
161
|
fullWidth={true}
|
|
159
162
|
size={{ base: "large" }}
|
|
160
163
|
renderCheckPlans={renderCheckPlans}
|
|
@@ -36,6 +36,7 @@ export type ImagePromoBarProps = {
|
|
|
36
36
|
videoLink: VideoLinkProps;
|
|
37
37
|
maxWidth?: boolean;
|
|
38
38
|
color: "light" | "dark";
|
|
39
|
+
enableAnimation?: boolean;
|
|
39
40
|
onModalButtonClick?: (id?: string) => void;
|
|
40
41
|
onClick?: (event: React.MouseEvent, source: "primary" | "secondary") => void;
|
|
41
42
|
renderCheckPlans?: (overrides?: CheckPlansProps) => React.ReactNode;
|
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,
|