@nuskin/marketing-components 1.19.0 → 1.21.0

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 (44) hide show
  1. package/dist/button/Button.styled.d.ts +1 -1
  2. package/dist/bynder-media/BynderMedia.d.ts +3 -0
  3. package/dist/bynder-media/BynderMedia.styled.d.ts +20 -0
  4. package/dist/bynder-media/index.d.ts +3 -0
  5. package/dist/{utils/bynder-utils.d.ts → bynder-media/types.d.ts} +7 -2
  6. package/dist/bynder-media/utils.d.ts +3 -0
  7. package/dist/content-card/ContentCard.d.ts +4 -0
  8. package/dist/content-card/ContentCard.stories.d.ts +15 -0
  9. package/dist/content-card/ContentCard.styled.d.ts +50 -0
  10. package/dist/content-card/Media.d.ts +7 -0
  11. package/dist/content-card/constants.d.ts +4 -0
  12. package/dist/content-card/index.d.ts +2 -0
  13. package/dist/content-card/specs/ContentCard.spec.d.ts +1 -0
  14. package/dist/content-card/specs/Media.spec.d.ts +1 -0
  15. package/dist/content-card/specs/helpers.spec.d.ts +1 -0
  16. package/dist/content-card/specs/mockData.d.ts +129 -0
  17. package/dist/content-card/types.d.ts +50 -0
  18. package/dist/content-card/utils/helpers.d.ts +33 -0
  19. package/dist/index.d.ts +2 -0
  20. package/dist/index.js +1 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/index.mjs +1 -1
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/marketing-banner/MarketingBanner.d.ts +2 -2
  25. package/dist/marketing-banner/MarketingBanner.stories.d.ts +202 -10
  26. package/dist/marketing-banner/MarketingBanner.styled.d.ts +4 -0
  27. package/dist/marketing-banner/components/BannerText.d.ts +1 -1
  28. package/dist/marketing-banner/components/index.d.ts +0 -2
  29. package/dist/marketing-banner/index.d.ts +0 -1
  30. package/dist/marketing-banner/specs/mockData.d.ts +14 -51
  31. package/dist/marketing-banner/specs/utils.spec.d.ts +1 -0
  32. package/dist/marketing-banner/types.d.ts +25 -164
  33. package/dist/marketing-banner/utils/index.d.ts +1 -1
  34. package/dist/marketing-banner/utils/utils.d.ts +4 -0
  35. package/package.json +1 -1
  36. package/dist/marketing-banner/components/BannerCTA.d.ts +0 -7
  37. package/dist/marketing-banner/components/BannerCTA.styled.d.ts +0 -7
  38. package/dist/marketing-banner/components/BannerMedia.d.ts +0 -7
  39. package/dist/marketing-banner/components/specs/BannerMedia.spec.d.ts +0 -5
  40. package/dist/marketing-banner/specs/transform.spec.d.ts +0 -5
  41. package/dist/marketing-banner/utils/transform.d.ts +0 -12
  42. /package/dist/{utils → bynder-media}/specs/bynder-utils.spec.d.ts +0 -0
  43. /package/dist/{utils → bynder-media}/specs/mockData.d.ts +0 -0
  44. /package/dist/{marketing-banner/components/BannerMedia.styled.d.ts → content-card/Media.styled.d.ts} +0 -0
@@ -20,7 +20,7 @@ interface StyledButtonProps {
20
20
  $focusRing: string;
21
21
  href?: string;
22
22
  }
23
- export declare const StyledButton: import("@emotion/styled").StyledComponent<Pick<import("@mui/material/Button").ButtonProps, "color" | "fullWidth" | "href" | "className" | "variant" | "onClick" | "type" | "aria-label" | "disabled" | "endIcon" | "size" | "startIcon" | "onFocus" | "onBlur" | "onChange"> & {
23
+ export declare const StyledButton: import("@emotion/styled").StyledComponent<Pick<import("@mui/material/Button").ButtonProps, "color" | "fullWidth" | "href" | "className" | "variant" | "type" | "disabled" | "endIcon" | "size" | "startIcon" | "aria-label" | "onFocus" | "onBlur" | "onChange" | "onClick"> & {
24
24
  iconOnly?: boolean;
25
25
  darkModeEnabled?: boolean;
26
26
  startIconName?: import("@nuskin/foundation-ui-components").NsIconProps["name"];
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import type { BynderMediaProps } from './types';
3
+ export declare function BynderMedia({ bynder_media, $ }: Readonly<BynderMediaProps>): React.ReactElement | null;
@@ -0,0 +1,20 @@
1
+ export declare const MediaContainer: import("@emotion/styled").StyledComponent<{
2
+ theme?: import("@emotion/react").Theme;
3
+ as?: React.ElementType;
4
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
5
+ export declare const StyledImage: import("@emotion/styled").StyledComponent<{
6
+ theme?: import("@emotion/react").Theme;
7
+ as?: React.ElementType;
8
+ }, import("react").DetailedHTMLProps<import("react").ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, {}>;
9
+ export declare const StyledVideo: import("@emotion/styled").StyledComponent<{
10
+ theme?: import("@emotion/react").Theme;
11
+ as?: React.ElementType;
12
+ }, import("react").DetailedHTMLProps<import("react").VideoHTMLAttributes<HTMLVideoElement>, HTMLVideoElement>, {}>;
13
+ export declare const PictureElement: import("@emotion/styled").StyledComponent<{
14
+ theme?: import("@emotion/react").Theme;
15
+ as?: React.ElementType;
16
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLElement>, HTMLElement>, {}>;
17
+ export declare const SourceElement: import("@emotion/styled").StyledComponent<{
18
+ theme?: import("@emotion/react").Theme;
19
+ as?: React.ElementType;
20
+ }, import("react").DetailedHTMLProps<import("react").SourceHTMLAttributes<HTMLSourceElement>, HTMLSourceElement>, {}>;
@@ -0,0 +1,3 @@
1
+ export { BynderMedia } from './BynderMedia';
2
+ export type { BynderMediaProps, BynderMediaType, BynderMediaExtracted, BynderImageDataType } from './types';
3
+ export { extractBynderMedia, getMediaUrl } from './utils';
@@ -1,4 +1,11 @@
1
1
  export type BynderMediaType = 'image' | 'gif' | 'video';
2
+ export type CSEditTags = Record<string, any>;
3
+ export interface BynderMediaProps {
4
+ /** JSON string from Contentstack bynder_media field */
5
+ readonly bynder_media?: string;
6
+ /** Contentstack edit tags */
7
+ readonly $?: CSEditTags;
8
+ }
2
9
  export type BynderMediaExtracted = {
3
10
  url: string;
4
11
  type: BynderMediaType;
@@ -45,5 +52,3 @@ export type BynderImageDataType = {
45
52
  };
46
53
  };
47
54
  };
48
- export declare function getMediaUrl(selected: BynderImageDataType['selected'], isPublic: boolean, previewUrls: BynderImageDataType['previewUrls']): string;
49
- export declare function extractBynderMedia(mediaJson?: string): BynderMediaExtracted | null;
@@ -0,0 +1,3 @@
1
+ import { BynderImageDataType, BynderMediaExtracted } from './types';
2
+ export declare function getMediaUrl(selected: BynderImageDataType['selected'], isPublic: boolean, previewUrls: BynderImageDataType['previewUrls']): string;
3
+ export declare function extractBynderMedia(mediaJson?: string): BynderMediaExtracted | null;
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { ContentCardProps } from './types';
3
+ declare const ContentCard: React.FC<ContentCardProps>;
4
+ export default ContentCard;
@@ -0,0 +1,15 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import ContentCard from './ContentCard';
3
+ declare const meta: Meta<typeof ContentCard>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof ContentCard>;
6
+ export declare const ImageCard: Story;
7
+ export declare const GifCard: Story;
8
+ export declare const VideoCard: Story;
9
+ export declare const BynderJsonMedia: Story;
10
+ export declare const NoCta: Story;
11
+ export declare const ButtonOpenInNewTab: Story;
12
+ export declare const CardLinkOpenInNewTab: Story;
13
+ export declare const ButtonNoLink: Story;
14
+ export declare const RightAligned: Story;
15
+ export declare const EditingPlaceholder: Story;
@@ -0,0 +1,50 @@
1
+ export declare const Card: import("@emotion/styled").StyledComponent<{
2
+ theme?: import("@emotion/react").Theme;
3
+ as?: React.ElementType;
4
+ } & {
5
+ align?: "left" | "center" | "right";
6
+ borderRadius?: string;
7
+ backgroundColor?: string;
8
+ backgroundOpacity?: number;
9
+ textColor?: string;
10
+ textOpacity?: number;
11
+ $maxHeight?: number;
12
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLElement>, HTMLElement>, {}>;
13
+ export declare const MediaWrapper: import("@emotion/styled").StyledComponent<{
14
+ theme?: import("@emotion/react").Theme;
15
+ as?: React.ElementType;
16
+ } & {
17
+ $mediaHeight?: number;
18
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
19
+ export declare const Content: import("@emotion/styled").StyledComponent<{
20
+ theme?: import("@emotion/react").Theme;
21
+ as?: React.ElementType;
22
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
23
+ export declare const Title: import("@emotion/styled").StyledComponent<{
24
+ theme?: import("@emotion/react").Theme;
25
+ as?: React.ElementType;
26
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>, {}>;
27
+ export declare const Subtitle: import("@emotion/styled").StyledComponent<{
28
+ theme?: import("@emotion/react").Theme;
29
+ as?: React.ElementType;
30
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, {}>;
31
+ export declare const Body: import("@emotion/styled").StyledComponent<{
32
+ theme?: import("@emotion/react").Theme;
33
+ as?: React.ElementType;
34
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, {}>;
35
+ export declare const CtaWrapper: import("@emotion/styled").StyledComponent<{
36
+ theme?: import("@emotion/react").Theme;
37
+ as?: React.ElementType;
38
+ } & {
39
+ $height?: number;
40
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
41
+ export declare const MediaPlaceholderWrapper: import("@emotion/styled").StyledComponent<{
42
+ theme?: import("@emotion/react").Theme;
43
+ as?: React.ElementType;
44
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
45
+ export declare const ContentInner: import("@emotion/styled").StyledComponent<{
46
+ theme?: import("@emotion/react").Theme;
47
+ as?: React.ElementType;
48
+ } & {
49
+ $contentMinHeight?: number;
50
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * BannerMedia Sub-Component
3
+ * Renders responsive media (image/gif/video) with lazy loading and fallback support
4
+ */
5
+ import React from 'react';
6
+ import { MediaProps } from './types';
7
+ export declare function Media(props: Readonly<MediaProps>): React.ReactElement;
@@ -0,0 +1,4 @@
1
+ export declare const MEDIA_RATIO = 0.5;
2
+ export declare const CTA_BUTTON_HEIGHT = 80;
3
+ /** Content area vertical space: padding (16*2) + gap before CTA (8). */
4
+ export declare const CONTENT_VERTICAL_SPACE = 40;
@@ -0,0 +1,2 @@
1
+ export { default as ContentCard } from './ContentCard';
2
+ export type { ContentCardProps } from './types';
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Mock Data for Bynder Utils Tests
3
+ * Contains test data for Bynder media extraction functions
4
+ */
5
+ export declare const mockSelectedImage: {
6
+ url: string;
7
+ type: "IMAGE";
8
+ fileSize: number;
9
+ width: number;
10
+ height: number;
11
+ fit: "cover";
12
+ position: string;
13
+ bgColor: string;
14
+ };
15
+ export declare const mockSelectedVideo: {
16
+ url: string;
17
+ type: "VIDEO";
18
+ fileSize: number;
19
+ width: number;
20
+ height: number;
21
+ fit: "cover";
22
+ position: string;
23
+ bgColor: string;
24
+ };
25
+ export declare const mockSelectedWithAltText: {
26
+ url: string;
27
+ type: string;
28
+ altText: string;
29
+ imageType: string;
30
+ fit: string;
31
+ position: string;
32
+ bgColor: string;
33
+ };
34
+ export declare const mockSelectedGif: {
35
+ url: string;
36
+ type: string;
37
+ altText: string;
38
+ imageType: string;
39
+ fit: string;
40
+ position: string;
41
+ bgColor: string;
42
+ };
43
+ export declare const mockSelectedGifUppercase: {
44
+ url: string;
45
+ type: string;
46
+ altText: string;
47
+ imageType: string;
48
+ fit: string;
49
+ position: string;
50
+ bgColor: string;
51
+ };
52
+ export declare const mockSelectedVideoWithAlt: {
53
+ url: string;
54
+ type: string;
55
+ altText: string;
56
+ imageType: string;
57
+ fit: string;
58
+ position: string;
59
+ bgColor: string;
60
+ };
61
+ export declare const mockSelectedWithDescriptiveAlt: {
62
+ url: string;
63
+ type: string;
64
+ altText: string;
65
+ imageType: string;
66
+ fit: string;
67
+ position: string;
68
+ bgColor: string;
69
+ };
70
+ export declare const mockSelectedWithoutAlt: {
71
+ url: string;
72
+ type: string;
73
+ imageType: string;
74
+ fit: string;
75
+ position: string;
76
+ bgColor: string;
77
+ };
78
+ export declare const mockSelectedCustomTransformation: {
79
+ url: string;
80
+ type: string;
81
+ altText: string;
82
+ imageType: string;
83
+ fit: string;
84
+ position: string;
85
+ bgColor: string;
86
+ };
87
+ export declare const mockSelectedCustomTransformationSimple: {
88
+ url: string;
89
+ type: string;
90
+ altText: string;
91
+ imageType: string;
92
+ fit: string;
93
+ position: string;
94
+ bgColor: string;
95
+ };
96
+ export declare const mockSelectedWithExistingQuality: {
97
+ url: string;
98
+ type: string;
99
+ altText: string;
100
+ imageType: string;
101
+ fit: string;
102
+ position: string;
103
+ bgColor: string;
104
+ };
105
+ export declare const mockSelectedWithMultipleParams: {
106
+ url: string;
107
+ type: string;
108
+ altText: string;
109
+ imageType: string;
110
+ fit: string;
111
+ position: string;
112
+ bgColor: string;
113
+ };
114
+ export declare const mockPreviewUrls: string[];
115
+ export declare const mockMediaJsonImage: string;
116
+ export declare const mockMediaJsonGif: string;
117
+ export declare const mockMediaJsonGifUppercase: string;
118
+ export declare const mockMediaJsonVideo: string;
119
+ export declare const mockMediaJsonWithDescriptiveAlt: string;
120
+ export declare const mockMediaJsonWithoutAlt: string;
121
+ export declare const mockMediaJsonCustomTransformation: string;
122
+ export declare const mockMediaJsonCustomTransformationSimple: string;
123
+ export declare const mockMediaJsonDefaultTransform: string;
124
+ export declare const mockMediaJsonVideoNoTransform: string;
125
+ export declare const mockMediaJsonGifNoTransform: string;
126
+ export declare const mockMediaJsonWithExistingQuality: string;
127
+ export declare const mockMediaJsonWithMultipleParams: string;
128
+ export declare const mockMediaJsonRealCustomTransformation: string;
129
+ export declare const mockMediaJsonVideoIntegration: string;
@@ -0,0 +1,50 @@
1
+ import { ButtonProps } from "@/button/types";
2
+ export type MediaType = 'image' | 'gif' | 'video';
3
+ export type MediaProvider = 'bynder';
4
+ export type ContentAlignment = 'left' | 'center' | 'right';
5
+ export type CtaStyle = 'card' | 'button' | 'none';
6
+ export type ButtonVariant = 'primary' | 'secondary' | 'tertiary';
7
+ export type IconPosition = 'left' | 'right';
8
+ export type LinkTarget = '_self' | '_blank';
9
+ export interface MediaProps {
10
+ readonly mediaUrl: string;
11
+ readonly fallbackMediaUrl?: string;
12
+ readonly mediaType?: MediaType;
13
+ readonly mediaAlt?: string;
14
+ readonly onError?: () => void;
15
+ readonly testId?: string;
16
+ readonly $?: Record<string, unknown>;
17
+ readonly isResponsive?: boolean;
18
+ readonly desktopUrl?: string;
19
+ readonly mobileUrl?: string;
20
+ }
21
+ export type BynderMediaType = 'image' | 'gif' | 'video';
22
+ export interface BynderMediaExtracted {
23
+ url: string;
24
+ type: BynderMediaType;
25
+ alt: string;
26
+ isResponsive?: boolean;
27
+ desktopUrl?: string;
28
+ mobileUrl?: string;
29
+ }
30
+ export interface ContentCardProps {
31
+ title?: string;
32
+ subtitle?: string;
33
+ body?: string;
34
+ media?: MediaProps | string;
35
+ cta?: ButtonProps;
36
+ cta_style?: CtaStyle;
37
+ content_alignment?: ContentAlignment;
38
+ _metadata?: {
39
+ uid?: string;
40
+ };
41
+ max_height?: number;
42
+ background_color?: string;
43
+ background_opacity?: number;
44
+ text_color?: string;
45
+ text_opacity?: number;
46
+ border_radius?: string;
47
+ isEditing?: boolean;
48
+ parent$?: Record<string, unknown>;
49
+ $?: Record<string, unknown>;
50
+ }
@@ -0,0 +1,33 @@
1
+ import type { ContentAlignment, CtaStyle, LinkTarget, MediaProps } from '../types';
2
+ /**
3
+ * Validates that the value is a hex color (#rgb or #rrggbb).
4
+ * Returns the trimmed hex string, or defaultColor when invalid.
5
+ */
6
+ export declare function validateHex(color: string, defaultColor: string): string;
7
+ /**
8
+ * Converts a hex color to rgba using the given opacity.
9
+ * If hex is invalid or empty, returns defRgba when provided.
10
+ */
11
+ export declare function hexToRgba(hex: string, opacity: number, defaultRgba?: string): string;
12
+ /** Card background as rgba; uses hex default and fallback. */
13
+ export declare function toCardBackgroundRgba(backgroundColor?: string, backgroundOpacity?: number): string;
14
+ /** Card text color as rgba; uses hex default and fallback. */
15
+ export declare function toCardTextRgba(textColor?: string, textOpacity?: number): string;
16
+ export declare const calculateMediaHeight: (maxHeight?: number) => number;
17
+ export declare const getMaxHeight: (maxHeight: number) => number;
18
+ export declare const getTitle: (title: string, isEditing: boolean) => string;
19
+ /** Normalize content alignment string to 'left' | 'center' | 'right'. */
20
+ export declare function normalizeContentAlignment(alignment?: string | null): ContentAlignment;
21
+ /** Normalize CTA style string to 'card' | 'button' | 'none'. */
22
+ export declare function normalizeCtaStyle(value?: string | null): CtaStyle;
23
+ /**
24
+ * Normalize media prop (string or object) to MediaProps or undefined.
25
+ * - string: parsed as Bynder JSON, then mapped to MediaProps (with $ passthrough).
26
+ * - object with mediaUrl: returned as-is.
27
+ * - other: returned as MediaProps for legacy/custom shapes.
28
+ */
29
+ export declare function normalizeContentCardMedia(media: MediaProps | string | undefined, $: Record<string, unknown>): MediaProps | undefined;
30
+ /** Content inner min/max height so card total height fits within maxHeight. */
31
+ export declare function calculateContentMinHeight(maxHeight: number, mediaHeight: number, ctaHeight: number): number;
32
+ /** Resolve target from open_in_new_tab string. */
33
+ export declare function resolveTarget(target?: 'Yes' | 'No' | null): LinkTarget | undefined;
package/dist/index.d.ts CHANGED
@@ -3,6 +3,8 @@ export * from './image';
3
3
  export * from './marketing-banner';
4
4
  export * from './spacing-divider';
5
5
  export * from './column-control';
6
+ export * from './content-card';
6
7
  export * from './hero-banner';
7
8
  export * from './button';
8
9
  export * from './rich-text';
10
+ export * from './bynder-media';