@pushwoosh/dumb-components 1.1.186 → 1.1.187

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 (42) hide show
  1. package/NativeRichMediaPreview/components/NativeRichMediaButtonList/NativeRichMediaButtonList.js +5 -1
  2. package/NativeRichMediaPreview/components/NativeRichMediaRewardPanel/NativeRichMediaRewardPanel.js +5 -1
  3. package/NativeRichMediaPreview/components/NativeRichMediaRewardPanel/styles.d.ts +6 -21
  4. package/NativeRichMediaPreview/components/NativeRichMediaText/NativeRichMediaText.d.ts +4 -0
  5. package/NativeRichMediaPreview/components/NativeRichMediaText/NativeRichMediaText.js +17 -0
  6. package/NativeRichMediaPreview/components/NativeRichMediaText/index.d.ts +2 -1
  7. package/NativeRichMediaPreview/components/NativeRichMediaText/index.js +1 -1
  8. package/NativeRichMediaPreview/components/NativeRichMediaText/styles.d.ts +1 -1
  9. package/NativeRichMediaPreview/components/NativeRichMediaText/styles.js +2 -2
  10. package/NativeRichMediaPreview/components/NativeRichMediaText/types.d.ts +9 -0
  11. package/NativeRichMediaPreview/components/NativeRichMediaText/types.js +1 -0
  12. package/NativeRichMediaPreview/components/NativeRichMediaTitle/NativeRichMediaTitle.d.ts +4 -0
  13. package/NativeRichMediaPreview/components/NativeRichMediaTitle/NativeRichMediaTitle.js +17 -0
  14. package/NativeRichMediaPreview/components/NativeRichMediaTitle/index.d.ts +2 -1
  15. package/NativeRichMediaPreview/components/NativeRichMediaTitle/index.js +1 -1
  16. package/NativeRichMediaPreview/components/NativeRichMediaTitle/styles.d.ts +1 -1
  17. package/NativeRichMediaPreview/components/NativeRichMediaTitle/styles.js +2 -2
  18. package/NativeRichMediaPreview/components/NativeRichMediaTitle/types.d.ts +11 -0
  19. package/NativeRichMediaPreview/components/NativeRichMediaTitle/types.js +1 -0
  20. package/NativeRichMediaPreview/views/NativeRichMediaInvalidView/styles.d.ts +4 -8
  21. package/NativeRichMediaPreview/views/NativeRichMediaScratchcardView/styles.d.ts +5 -14
  22. package/NativeRichMediaPreview/views/NativeRichMediaSpinwheelView/NativeRichMediaSpinwheelView.js +5 -1
  23. package/NativeRichMediaPreview/views/NativeRichMediaSpinwheelView/styles.d.ts +2 -6
  24. package/RichMessageEditor/RichMessageViewer.js +3 -7
  25. package/RichMessageEditor/slate/helpers.d.ts +3 -13
  26. package/RichMessageEditor/slate/helpers.js +31 -46
  27. package/RichMessageEditor/slate/types.d.ts +2 -8
  28. package/package.json +1 -1
  29. package/shared/dynamicContent/DynamicContentChip.d.ts +11 -0
  30. package/shared/dynamicContent/DynamicContentChip.js +20 -0
  31. package/shared/dynamicContent/DynamicContentText.d.ts +11 -0
  32. package/shared/dynamicContent/DynamicContentText.js +22 -0
  33. package/shared/dynamicContent/index.d.ts +5 -0
  34. package/shared/dynamicContent/index.js +4 -0
  35. package/shared/dynamicContent/styles.d.ts +7 -0
  36. package/shared/dynamicContent/styles.js +20 -0
  37. package/shared/dynamicContent/token.d.ts +20 -0
  38. package/shared/dynamicContent/token.js +45 -0
  39. package/shared/dynamicContent/types.d.ts +3 -0
  40. package/shared/dynamicContent/types.js +1 -0
  41. package/RichMessageEditor/RichMessageViewer.styled.d.ts +0 -3
  42. package/RichMessageEditor/RichMessageViewer.styled.js +0 -14
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Vertical } from '@pushwoosh/kit-helpers';
3
+ import { DynamicContentText } from '../../../shared/dynamicContent';
3
4
  import { ButtonRow } from '../../styles';
4
5
  export function NativeRichMediaButtonList(props) {
5
6
  const {
@@ -18,7 +19,10 @@ export function NativeRichMediaButtonList(props) {
18
19
  "$background": b.background,
19
20
  "$color": b.text.color,
20
21
  "$border": `1px solid ${b.border.color}`,
21
- children: b.text.text
22
+ children: _jsx(DynamicContentText, {
23
+ tone: "subtle",
24
+ children: b.text.text
25
+ })
22
26
  }, `btn-${i}`))
23
27
  });
24
28
  }
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { CodeBox, CodeText, RewardMessage, RewardTitle } from './styles';
3
+ import { DynamicContentText } from '../../../shared/dynamicContent';
3
4
  import { SECONDARY_LABEL, asButtonValue, asText, asTextValue, contrastOn, isLightHex, withAlpha } from '../../helpers';
4
5
  import { CopyIcon } from '../../icons';
5
6
  import { ButtonRow } from '../../styles';
@@ -50,7 +51,10 @@ export function NativeRichMediaRewardPanel(props) {
50
51
  "$background": button.background,
51
52
  "$color": button.text.color,
52
53
  "$border": `1px solid ${button.border.color}`,
53
- children: button.text.text
54
+ children: _jsx(DynamicContentText, {
55
+ tone: "subtle",
56
+ children: button.text.text
57
+ })
54
58
  })]
55
59
  });
56
60
  }
@@ -1,3 +1,5 @@
1
+ import { NativeRichMediaText } from '../NativeRichMediaText';
2
+ import { NativeRichMediaTitle } from '../NativeRichMediaTitle';
1
3
  export declare const CodeBox: import("styled-components").StyledComponent<"div", any, {
2
4
  $background: string;
3
5
  $border: string;
@@ -11,26 +13,9 @@ export declare const CodeText: import("styled-components").StyledComponent<"span
11
13
  } & {
12
14
  $variant: string;
13
15
  }, "$variant">;
14
- export declare const RewardTitle: import("styled-components").StyledComponent<"span", any, {
15
- $color?: string | undefined;
16
- $uppercase?: boolean | undefined;
17
- $ellipsis?: boolean | undefined;
18
- $variant?: import("@pushwoosh/kit-typography").TypographyVariant | undefined;
19
- } & {
20
- $color?: string;
21
- $align?: "center";
22
- $marginTop?: number;
23
- $size?: "h3" | "h4";
24
- $truncate?: boolean;
25
- $clamp?: number;
26
- } & {
27
- $align: string;
16
+ export declare const RewardTitle: import("styled-components").StyledComponent<typeof NativeRichMediaTitle, any, {
17
+ $align: "center";
28
18
  }, "$align">;
29
- export declare const RewardMessage: import("styled-components").StyledComponent<typeof import("@pushwoosh/kit-typography").Footnote, any, {
30
- $color?: string;
31
- $align?: "center";
32
- $clamp?: number;
33
- $marginTop?: number;
34
- } & {
35
- $align: string;
19
+ export declare const RewardMessage: import("styled-components").StyledComponent<typeof NativeRichMediaText, any, {
20
+ $align: "center";
36
21
  }, "$align">;
@@ -0,0 +1,4 @@
1
+ import { type ReactElement } from 'react';
2
+ import type { NativeRichMediaTextProps } from './types';
3
+ /** Preview body text; dynamic-content tokens are highlighted as chips. */
4
+ export declare function NativeRichMediaText(props: NativeRichMediaTextProps): ReactElement;
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { TextRoot } from './styles';
3
+ import { DynamicContentText } from '../../../shared/dynamicContent';
4
+ /** Preview body text; dynamic-content tokens are highlighted as chips. */
5
+ export function NativeRichMediaText(props) {
6
+ const {
7
+ children,
8
+ ...rest
9
+ } = props;
10
+ return _jsx(TextRoot, {
11
+ ...rest,
12
+ children: _jsx(DynamicContentText, {
13
+ tone: "subtle",
14
+ children: children
15
+ })
16
+ });
17
+ }
@@ -1 +1,2 @@
1
- export { NativeRichMediaText } from './styles';
1
+ export { NativeRichMediaText } from './NativeRichMediaText';
2
+ export type { NativeRichMediaTextProps } from './types';
@@ -1 +1 @@
1
- export { NativeRichMediaText } from './styles';
1
+ export { NativeRichMediaText } from './NativeRichMediaText';
@@ -1,5 +1,5 @@
1
1
  import { Footnote } from '@pushwoosh/kit-typography';
2
- export declare const NativeRichMediaText: import("styled-components").StyledComponent<typeof Footnote, any, {
2
+ export declare const TextRoot: import("styled-components").StyledComponent<typeof Footnote, any, {
3
3
  $color?: string;
4
4
  $align?: "center";
5
5
  $clamp?: number;
@@ -1,7 +1,7 @@
1
1
  import styled from 'styled-components';
2
2
  import { Footnote } from '@pushwoosh/kit-typography';
3
- export const NativeRichMediaText = styled(Footnote).withConfig({
4
- displayName: "NativeRichMediaText",
3
+ export const TextRoot = styled(Footnote).withConfig({
4
+ displayName: "TextRoot",
5
5
  componentId: "sc-1e1cjl8-0"
6
6
  })(["display:block;color:", ";", " ", " ", ""], ({
7
7
  $color
@@ -0,0 +1,9 @@
1
+ import type { ReactNode } from 'react';
2
+ export type NativeRichMediaTextProps = {
3
+ children?: ReactNode;
4
+ className?: string;
5
+ $color?: string;
6
+ $align?: 'center';
7
+ $clamp?: number;
8
+ $marginTop?: number;
9
+ };
@@ -0,0 +1,4 @@
1
+ import { type ReactElement } from 'react';
2
+ import type { NativeRichMediaTitleProps } from './types';
3
+ /** Preview title text; dynamic-content tokens are highlighted as chips. */
4
+ export declare function NativeRichMediaTitle(props: NativeRichMediaTitleProps): ReactElement;
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { TitleRoot } from './styles';
3
+ import { DynamicContentText } from '../../../shared/dynamicContent';
4
+ /** Preview title text; dynamic-content tokens are highlighted as chips. */
5
+ export function NativeRichMediaTitle(props) {
6
+ const {
7
+ children,
8
+ ...rest
9
+ } = props;
10
+ return _jsx(TitleRoot, {
11
+ ...rest,
12
+ children: _jsx(DynamicContentText, {
13
+ tone: "subtle",
14
+ children: children
15
+ })
16
+ });
17
+ }
@@ -1 +1,2 @@
1
- export { NativeRichMediaTitle } from './styles';
1
+ export { NativeRichMediaTitle } from './NativeRichMediaTitle';
2
+ export type { NativeRichMediaTitleProps } from './types';
@@ -1 +1 @@
1
- export { NativeRichMediaTitle } from './styles';
1
+ export { NativeRichMediaTitle } from './NativeRichMediaTitle';
@@ -1,4 +1,4 @@
1
- export declare const NativeRichMediaTitle: import("styled-components").StyledComponent<"span", any, {
1
+ export declare const TitleRoot: import("styled-components").StyledComponent<"span", any, {
2
2
  $color?: string | undefined;
3
3
  $uppercase?: boolean | undefined;
4
4
  $ellipsis?: boolean | undefined;
@@ -1,11 +1,11 @@
1
1
  import styled from 'styled-components';
2
2
  import { Text } from '@pushwoosh/kit-typography';
3
- export const NativeRichMediaTitle = styled(Text).attrs(({
3
+ export const TitleRoot = styled(Text).attrs(({
4
4
  $size
5
5
  }) => ({
6
6
  $variant: $size === 'h4' ? 'h4' : 'h3'
7
7
  })).withConfig({
8
- displayName: "NativeRichMediaTitle",
8
+ displayName: "TitleRoot",
9
9
  componentId: "sc-1oklc22-0"
10
10
  })(["display:block;color:", ";", " ", " ", " ", ""], ({
11
11
  $color
@@ -0,0 +1,11 @@
1
+ import type { ReactNode } from 'react';
2
+ export type NativeRichMediaTitleProps = {
3
+ children?: ReactNode;
4
+ className?: string;
5
+ $color?: string;
6
+ $align?: 'center';
7
+ $marginTop?: number;
8
+ $size?: 'h3' | 'h4';
9
+ $truncate?: boolean;
10
+ $clamp?: number;
11
+ };
@@ -1,10 +1,6 @@
1
+ import { NativeRichMediaText } from '../../components/NativeRichMediaText';
1
2
  export declare const Placeholder: import("styled-components").StyledComponent<"div", any, {}, never>;
2
- export declare const PlaceholderText: import("styled-components").StyledComponent<typeof import("@pushwoosh/kit-typography").Footnote, any, {
3
- $color?: string;
4
- $align?: "center";
5
- $clamp?: number;
6
- $marginTop?: number;
7
- } & {
8
- $color: string;
9
- $align: string;
3
+ export declare const PlaceholderText: import("styled-components").StyledComponent<typeof NativeRichMediaText, any, {
4
+ $color: "rgba(60,60,67,0.6)";
5
+ $align: "center";
10
6
  }, "$color" | "$align">;
@@ -1,3 +1,4 @@
1
+ import { NativeRichMediaText } from '../../components/NativeRichMediaText';
1
2
  export declare const Card: import("styled-components").StyledComponent<"div", any, {
2
3
  $background: string;
3
4
  $padding: string;
@@ -10,20 +11,10 @@ export declare const RewardSlot: import("styled-components").StyledComponent<"di
10
11
  export declare const HintOverlay: import("styled-components").StyledComponent<"div", any, {
11
12
  $coverBase: string;
12
13
  }, never>;
13
- export declare const HintText: import("styled-components").StyledComponent<typeof import("@pushwoosh/kit-typography").Footnote, any, {
14
- $color?: string;
15
- $align?: "center";
16
- $clamp?: number;
17
- $marginTop?: number;
18
- }, never>;
19
- export declare const RevealButtonText: import("styled-components").StyledComponent<typeof import("@pushwoosh/kit-typography").Footnote, any, {
20
- $color?: string;
21
- $align?: "center";
22
- $clamp?: number;
23
- $marginTop?: number;
24
- } & {
25
- $align: string;
26
- $marginTop: number;
14
+ export declare const HintText: import("styled-components").StyledComponent<typeof NativeRichMediaText, any, {}, never>;
15
+ export declare const RevealButtonText: import("styled-components").StyledComponent<typeof NativeRichMediaText, any, {
16
+ $align: "center";
17
+ $marginTop: 14;
27
18
  } & {
28
19
  $background: string;
29
20
  $radius: number;
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Fragment } from 'react';
3
3
  import { Card, Hub, Pointer, Ring, SegmentLabel, Tick, Wheel } from './styles';
4
+ import { DynamicContentText } from '../../../shared/dynamicContent';
4
5
  import { NativeRichMediaCloseChip } from '../../components/NativeRichMediaCloseChip';
5
6
  import { NativeRichMediaText } from '../../components/NativeRichMediaText';
6
7
  import { NativeRichMediaTitle } from '../../components/NativeRichMediaTitle';
@@ -48,7 +49,10 @@ export function NativeRichMediaSpinwheelView(props) {
48
49
  "$background": spinButton?.background,
49
50
  "$color": spinButton?.text.color,
50
51
  "$borderColor": spinButton?.border.color,
51
- children: spinButton?.text.text || 'SPIN'
52
+ children: _jsx(DynamicContentText, {
53
+ tone: "subtle",
54
+ children: spinButton?.text.text || 'SPIN'
55
+ })
52
56
  })]
53
57
  }), block.showClose && _jsx(NativeRichMediaCloseChip, {
54
58
  top: 16,
@@ -1,3 +1,4 @@
1
+ import { NativeRichMediaText } from '../../components/NativeRichMediaText';
1
2
  export declare const Card: import("styled-components").StyledComponent<"div", any, {
2
3
  $background: string;
3
4
  $padding: string;
@@ -11,12 +12,7 @@ export declare const Ring: import("styled-components").StyledComponent<"div", an
11
12
  export declare const Tick: import("styled-components").StyledComponent<"div", any, {
12
13
  $rotate: number;
13
14
  }, never>;
14
- export declare const SegmentLabel: import("styled-components").StyledComponent<typeof import("@pushwoosh/kit-typography").Footnote, any, {
15
- $color?: string;
16
- $align?: "center";
17
- $clamp?: number;
18
- $marginTop?: number;
19
- } & {
15
+ export declare const SegmentLabel: import("styled-components").StyledComponent<typeof NativeRichMediaText, any, {
20
16
  $rotate: number;
21
17
  }, never>;
22
18
  export declare const Pointer: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Fragment, useMemo } from 'react';
3
- import { DynamicContentBracket, DynamicContentRoot, Paragraph } from './RichMessageViewer.styled';
4
3
  import { isElement, string2content } from './slate/helpers';
4
+ import { DynamicContentChip, Paragraph } from '../shared/dynamicContent';
5
5
  /**
6
6
  * Read-only renderer for {@link RichMessageEditor} output, displaying text and
7
7
  * personalization tokens. Accepts structured content or a serialized string.
@@ -19,12 +19,8 @@ export const RichMessageViewer = ({
19
19
  return content.map((node, index) => {
20
20
  const children = node.children.map((child, idx) => {
21
21
  if (isElement(child) && child.type === 'dc') {
22
- return _jsxs(DynamicContentRoot, {
23
- children: [_jsx(DynamicContentBracket, {
24
- children: '{'
25
- }), "\u00A0", child.dc.tagName, "\u00A0", _jsx(DynamicContentBracket, {
26
- children: '}'
27
- })]
22
+ return _jsx(DynamicContentChip, {
23
+ dc: child.dc
28
24
  }, idx);
29
25
  }
30
26
  return child.text;
@@ -1,5 +1,6 @@
1
1
  import type { Descendant } from 'slate';
2
- import { type CustomElement, type DynamicContent, type DynamicContentElement, type SlateEditorContent } from './types';
2
+ import { type CustomElement, type DynamicContentElement, type SlateEditorContent } from './types';
3
+ import { parseDc, stringifyDc } from '../../shared/dynamicContent';
3
4
  /**
4
5
  * Checks if a Slate node is a custom element
5
6
  * @param x - The node to check
@@ -26,18 +27,7 @@ export declare function findAllDc(value: SlateEditorContent): DynamicContentElem
26
27
  * @returns Array of indices representing the path to the element, empty if not found
27
28
  */
28
29
  export declare function findPath(value: SlateEditorContent, elToFind: Descendant): number[];
29
- /**
30
- * Parses a dynamic content string into a DynamicContent object
31
- * @param value - String in format "{tagName|modifier|defaultValue}"
32
- * @returns DynamicContent object with parsed components
33
- */
34
- export declare function parseDc(value: string): DynamicContent;
35
- /**
36
- * Converts a DynamicContent object to its string representation
37
- * @param dc - The DynamicContent object
38
- * @returns String representation in format "{tagName|modifier|defaultValue}"
39
- */
40
- export declare function stringifyDc(dc: DynamicContent): string;
30
+ export { parseDc, stringifyDc };
41
31
  /**
42
32
  * Converts a string to Slate editor content, parsing dynamic content tags
43
33
  * @param value - The input string to convert
@@ -1,3 +1,4 @@
1
+ import { parseDc, splitDynamicContent, stringifyDc } from '../../shared/dynamicContent';
1
2
  /**
2
3
  * Checks if a Slate node is a custom element
3
4
  * @param x - The node to check
@@ -68,60 +69,44 @@ export function findPath(value, elToFind) {
68
69
  }
69
70
  return [];
70
71
  }
71
- /**
72
- * Parses a dynamic content string into a DynamicContent object
73
- * @param value - String in format "{tagName|modifier|defaultValue}"
74
- * @returns DynamicContent object with parsed components
75
- */
76
- export function parseDc(value) {
77
- const [tagName, modifier, defaultValue = ''] = value.slice(1, -1).split('|');
78
- return {
79
- tagName,
80
- modifier,
81
- defaultValue
82
- };
83
- }
84
- /**
85
- * Converts a DynamicContent object to its string representation
86
- * @param dc - The DynamicContent object
87
- * @returns String representation in format "{tagName|modifier|defaultValue}"
88
- */
89
- export function stringifyDc(dc) {
90
- const {
91
- tagName,
92
- modifier,
93
- defaultValue
94
- } = dc;
95
- return `{${tagName}|${modifier}${defaultValue ? `|${defaultValue}` : ''}}`;
96
- }
97
- // Regular expression to match dynamic content tags in the format "{tagName|modifier|defaultValue}"
98
- // The regex captures the entire tag, including the curly braces and pipe characters
99
- // It uses a positive lookahead to ensure that there is at least one pipe character in the tag
100
- // This allows for the presence of a default value, but does not require it
101
- const DynamicContentRegex = /(\{(?=[^}]*\|).*?})/;
72
+ // Re-exported so existing import paths keep working; the token format itself
73
+ // now lives in shared/dynamicContent, shared with the read-only renderers.
74
+ export { parseDc, stringifyDc };
102
75
  /**
103
76
  * Converts a string to Slate editor content, parsing dynamic content tags
104
77
  * @param value - The input string to convert
105
78
  * @returns SlateEditorContent with properly structured paragraphs and dynamic content
106
79
  */
107
80
  export function string2content(value) {
108
- return value.split('\n').map(line => ({
109
- type: 'paragraph',
110
- children: line.split(DynamicContentRegex).map((text, index) => {
111
- if (index % 2 === 1) {
112
- return {
113
- type: 'dc',
114
- dc: parseDc(text),
115
- children: [{
116
- text: ''
117
- }]
118
- };
119
- }
81
+ return value.split('\n').map(line => {
82
+ const parts = splitDynamicContent(line);
83
+ // Slate rejects a paragraph with no children, so an empty line keeps one empty text node.
84
+ if (parts.length === 0) {
120
85
  return {
121
- text
86
+ type: 'paragraph',
87
+ children: [{
88
+ text: ''
89
+ }]
122
90
  };
123
- })
124
- }));
91
+ }
92
+ return {
93
+ type: 'paragraph',
94
+ children: parts.map(part => {
95
+ if (part.isToken) {
96
+ return {
97
+ type: 'dc',
98
+ dc: parseDc(part.text),
99
+ children: [{
100
+ text: ''
101
+ }]
102
+ };
103
+ }
104
+ return {
105
+ text: part.text
106
+ };
107
+ })
108
+ };
109
+ });
125
110
  }
126
111
  /**
127
112
  * Converts Slate editor content to a string, including dynamic content tags
@@ -1,15 +1,9 @@
1
1
  import type { Descendant } from 'slate';
2
+ import type { DynamicContent } from '../../shared/dynamicContent';
2
3
  /** Editor document model — an array of Slate nodes (exported publicly as `RichMessageEditorContent`). */
3
4
  export type SlateEditorContent = Descendant[];
4
5
  /** A dynamic-content (personalization) token embedded in the message. */
5
- export type DynamicContent = {
6
- /** Personalization tag name (e.g. a tag or attribute key). */
7
- tagName: string;
8
- /** Optional value modifier/formatter. */
9
- modifier: string;
10
- /** Fallback value used when the tag resolves to nothing. */
11
- defaultValue: string;
12
- };
6
+ export type { DynamicContent };
13
7
  export type ParagraphElement = {
14
8
  type: 'paragraph';
15
9
  children: SlateEditorContent;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushwoosh/dumb-components",
3
- "version": "1.1.186",
3
+ "version": "1.1.187",
4
4
  "description": "React components to build Pushwoosh products",
5
5
  "main": "index.js",
6
6
  "module": "index.js",
@@ -0,0 +1,11 @@
1
+ import { type ReactElement } from 'react';
2
+ import { type DynamicContent, type DynamicContentTone } from './types';
3
+ /** Props of {@link DynamicContentChip}. */
4
+ export type DynamicContentChipProps = {
5
+ /** Token to display; only its tag name is shown. */
6
+ dc: DynamicContent;
7
+ /** `solid` for opaque surfaces, `subtle` over author-chosen backgrounds. */
8
+ tone?: DynamicContentTone;
9
+ };
10
+ /** Renders one dynamic-content token as `{ tagName }`. */
11
+ export declare function DynamicContentChip(props: DynamicContentChipProps): ReactElement;
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Bracket, Chip } from './styles';
3
+ /** Renders one dynamic-content token as `{ tagName }`. */
4
+ export function DynamicContentChip(props) {
5
+ const {
6
+ dc,
7
+ tone = 'solid'
8
+ } = props;
9
+ return _jsxs(Chip, {
10
+ "$tone": tone,
11
+ "data-dc-token": true,
12
+ children: [_jsx(Bracket, {
13
+ "$tone": tone,
14
+ children: '{'
15
+ }), "\u00A0", dc.tagName, "\u00A0", _jsx(Bracket, {
16
+ "$tone": tone,
17
+ children: '}'
18
+ })]
19
+ });
20
+ }
@@ -0,0 +1,11 @@
1
+ import { type ReactElement, type ReactNode } from 'react';
2
+ import { type DynamicContentTone } from './types';
3
+ /** Props of {@link DynamicContentText}. */
4
+ export type DynamicContentTextProps = {
5
+ /** Text to render; dynamic-content tokens inside it become chips. Non-string children pass through. */
6
+ children?: ReactNode;
7
+ /** Chip appearance. */
8
+ tone?: DynamicContentTone;
9
+ };
10
+ /** Renders text with every dynamic-content token displayed as a chip. */
11
+ export declare function DynamicContentText(props: DynamicContentTextProps): ReactElement;
@@ -0,0 +1,22 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import { DynamicContentChip } from './DynamicContentChip';
3
+ import { parseDc, splitDynamicContent } from './token';
4
+ /** Renders text with every dynamic-content token displayed as a chip. */
5
+ export function DynamicContentText(props) {
6
+ const {
7
+ children,
8
+ tone
9
+ } = props;
10
+ if (typeof children !== 'string') {
11
+ return _jsx(_Fragment, {
12
+ children: children
13
+ });
14
+ }
15
+ const parts = splitDynamicContent(children);
16
+ return _jsx(_Fragment, {
17
+ children: parts.map((part, index) => part.isToken ? _jsx(DynamicContentChip, {
18
+ dc: parseDc(part.text),
19
+ tone: tone
20
+ }, index) : part.text)
21
+ });
22
+ }
@@ -0,0 +1,5 @@
1
+ export { DynamicContentChip, type DynamicContentChipProps } from './DynamicContentChip';
2
+ export { DynamicContentText, type DynamicContentTextProps } from './DynamicContentText';
3
+ export { parseDc, splitDynamicContent, stringifyDc } from './token';
4
+ export { Paragraph } from './styles';
5
+ export type { DynamicContent, DynamicContentPart, DynamicContentTone } from './types';
@@ -0,0 +1,4 @@
1
+ export { DynamicContentChip } from './DynamicContentChip';
2
+ export { DynamicContentText } from './DynamicContentText';
3
+ export { parseDc, splitDynamicContent, stringifyDc } from './token';
4
+ export { Paragraph } from './styles';
@@ -0,0 +1,7 @@
1
+ export declare const Chip: import("styled-components").StyledComponent<"span", any, {
2
+ $tone: "solid" | "subtle";
3
+ }, never>;
4
+ export declare const Bracket: import("styled-components").StyledComponent<"span", any, {
5
+ $tone: "solid" | "subtle";
6
+ }, never>;
7
+ export declare const Paragraph: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -0,0 +1,20 @@
1
+ import styled, { css } from 'styled-components';
2
+ import { Color, FontWeight, ShapeRadius } from '@pushwoosh/kit-constants';
3
+ // `subtle` exists because the native rich media preview draws text over
4
+ // author-chosen backgrounds, where the opaque kit tokens can swallow the label.
5
+ export const Chip = styled.span.withConfig({
6
+ displayName: "Chip",
7
+ componentId: "sc-1p4g9n3-0"
8
+ })(["border-radius:", ";white-space:nowrap;font-weight:", ";padding:0 2px;", ""], ShapeRadius.CONTROL, FontWeight.MEDIUM, ({
9
+ $tone
10
+ }) => $tone === 'solid' ? css(["background-color:", ";"], Color.EXCEPTIONAL_LIGHT) : css(["background-color:rgba(88,86,214,0.16);box-shadow:inset 0 0 0 1px rgba(88,86,214,0.32);color:inherit;"]));
11
+ export const Bracket = styled.span.withConfig({
12
+ displayName: "Bracket",
13
+ componentId: "sc-1p4g9n3-1"
14
+ })(["", ""], ({
15
+ $tone
16
+ }) => $tone === 'solid' ? css(["color:", ";"], Color.EXCEPTIONAL) : css(["color:inherit;opacity:0.7;"]));
17
+ export const Paragraph = styled.div.withConfig({
18
+ displayName: "Paragraph",
19
+ componentId: "sc-1p4g9n3-2"
20
+ })(["min-height:1em;"]);
@@ -0,0 +1,20 @@
1
+ /** A run of text: either literal text or a dynamic-content token. */
2
+ export type DynamicContentPart = {
3
+ text: string;
4
+ isToken: boolean;
5
+ };
6
+ /** A dynamic-content (personalization) token embedded in a message. */
7
+ export type DynamicContent = {
8
+ /** Personalization tag name (e.g. a tag or attribute key). */
9
+ tagName: string;
10
+ /** Optional value modifier/formatter. */
11
+ modifier: string;
12
+ /** Fallback value used when the tag resolves to nothing. */
13
+ defaultValue: string;
14
+ };
15
+ /** Splits text into literal runs and dynamic-content tokens. */
16
+ export declare function splitDynamicContent(text: string): DynamicContentPart[];
17
+ /** Parses `{tagName|modifier|defaultValue}` into its parts. */
18
+ export declare function parseDc(value: string): DynamicContent;
19
+ /** Serializes a token back to `{tagName|modifier|defaultValue}`. */
20
+ export declare function stringifyDc(dc: DynamicContent): string;
@@ -0,0 +1,45 @@
1
+ // Localization placeholders (`{{key|text}}`) contain a token-shaped substring,
2
+ // so they are matched first and kept literal.
3
+ const PART_REGEX = /(\{\{[^{}]*\}\}|\{(?=[^{}]*\|)[^{}]*\})/;
4
+ /** Splits text into literal runs and dynamic-content tokens. */
5
+ export function splitDynamicContent(text) {
6
+ if (!text) {
7
+ return [];
8
+ }
9
+ const parts = [];
10
+ text.split(PART_REGEX).forEach((part, index) => {
11
+ if (part === '') {
12
+ return;
13
+ }
14
+ // Odd indices are the captured separators; a token is one not starting with `{{`.
15
+ const isToken = index % 2 === 1 && !part.startsWith('{{');
16
+ const previous = parts[parts.length - 1];
17
+ if (!isToken && previous && !previous.isToken) {
18
+ previous.text += part;
19
+ return;
20
+ }
21
+ parts.push({
22
+ text: part,
23
+ isToken
24
+ });
25
+ });
26
+ return parts;
27
+ }
28
+ /** Parses `{tagName|modifier|defaultValue}` into its parts. */
29
+ export function parseDc(value) {
30
+ const [tagName, modifier, defaultValue = ''] = value.slice(1, -1).split('|');
31
+ return {
32
+ tagName,
33
+ modifier,
34
+ defaultValue
35
+ };
36
+ }
37
+ /** Serializes a token back to `{tagName|modifier|defaultValue}`. */
38
+ export function stringifyDc(dc) {
39
+ const {
40
+ tagName,
41
+ modifier,
42
+ defaultValue
43
+ } = dc;
44
+ return `{${tagName}|${modifier}${defaultValue ? `|${defaultValue}` : ''}}`;
45
+ }
@@ -0,0 +1,3 @@
1
+ export type { DynamicContent, DynamicContentPart } from './token';
2
+ /** Chip appearance: `solid` on flat surfaces, `subtle` over arbitrary backgrounds. */
3
+ export type DynamicContentTone = 'solid' | 'subtle';
@@ -0,0 +1 @@
1
+ export {};
@@ -1,3 +0,0 @@
1
- export declare const DynamicContentRoot: import("styled-components").StyledComponent<"span", any, {}, never>;
2
- export declare const DynamicContentBracket: import("styled-components").StyledComponent<"span", any, {}, never>;
3
- export declare const Paragraph: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -1,14 +0,0 @@
1
- import styled from 'styled-components';
2
- import { Color, FontWeight, ShapeRadius } from '@pushwoosh/kit-constants';
3
- export const DynamicContentRoot = styled.span.withConfig({
4
- displayName: "DynamicContentRoot",
5
- componentId: "sc-f10jz5-0"
6
- })(["background-color:", ";border-radius:", ";white-space:nowrap;font-weight:", ";padding:0 2px;"], Color.EXCEPTIONAL_LIGHT, ShapeRadius.CONTROL, FontWeight.MEDIUM);
7
- export const DynamicContentBracket = styled.span.withConfig({
8
- displayName: "DynamicContentBracket",
9
- componentId: "sc-f10jz5-1"
10
- })(["color:", ";"], Color.EXCEPTIONAL);
11
- export const Paragraph = styled.div.withConfig({
12
- displayName: "Paragraph",
13
- componentId: "sc-f10jz5-2"
14
- })(["min-height:1em;"]);