@pushwoosh/dumb-components 1.1.186 → 1.1.188
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/DropdownMenu/components/DropdownMenu/DropdownMenu.js +3 -1
- package/NativeRichMediaPreview/components/NativeRichMediaButtonList/NativeRichMediaButtonList.js +5 -1
- package/NativeRichMediaPreview/components/NativeRichMediaRewardPanel/NativeRichMediaRewardPanel.js +5 -1
- package/NativeRichMediaPreview/components/NativeRichMediaRewardPanel/styles.d.ts +6 -21
- package/NativeRichMediaPreview/components/NativeRichMediaText/NativeRichMediaText.d.ts +4 -0
- package/NativeRichMediaPreview/components/NativeRichMediaText/NativeRichMediaText.js +17 -0
- package/NativeRichMediaPreview/components/NativeRichMediaText/index.d.ts +2 -1
- package/NativeRichMediaPreview/components/NativeRichMediaText/index.js +1 -1
- package/NativeRichMediaPreview/components/NativeRichMediaText/styles.d.ts +1 -1
- package/NativeRichMediaPreview/components/NativeRichMediaText/styles.js +2 -2
- package/NativeRichMediaPreview/components/NativeRichMediaText/types.d.ts +9 -0
- package/NativeRichMediaPreview/components/NativeRichMediaText/types.js +1 -0
- package/NativeRichMediaPreview/components/NativeRichMediaTitle/NativeRichMediaTitle.d.ts +4 -0
- package/NativeRichMediaPreview/components/NativeRichMediaTitle/NativeRichMediaTitle.js +17 -0
- package/NativeRichMediaPreview/components/NativeRichMediaTitle/index.d.ts +2 -1
- package/NativeRichMediaPreview/components/NativeRichMediaTitle/index.js +1 -1
- package/NativeRichMediaPreview/components/NativeRichMediaTitle/styles.d.ts +1 -1
- package/NativeRichMediaPreview/components/NativeRichMediaTitle/styles.js +2 -2
- package/NativeRichMediaPreview/components/NativeRichMediaTitle/types.d.ts +11 -0
- package/NativeRichMediaPreview/components/NativeRichMediaTitle/types.js +1 -0
- package/NativeRichMediaPreview/views/NativeRichMediaInvalidView/styles.d.ts +4 -8
- package/NativeRichMediaPreview/views/NativeRichMediaScratchcardView/styles.d.ts +5 -14
- package/NativeRichMediaPreview/views/NativeRichMediaSpinwheelView/NativeRichMediaSpinwheelView.js +5 -1
- package/NativeRichMediaPreview/views/NativeRichMediaSpinwheelView/styles.d.ts +2 -6
- package/RichMessageEditor/RichMessageViewer.js +3 -7
- package/RichMessageEditor/slate/helpers.d.ts +3 -13
- package/RichMessageEditor/slate/helpers.js +31 -46
- package/RichMessageEditor/slate/types.d.ts +2 -8
- package/package.json +1 -1
- package/shared/dynamicContent/DynamicContentChip.d.ts +11 -0
- package/shared/dynamicContent/DynamicContentChip.js +20 -0
- package/shared/dynamicContent/DynamicContentText.d.ts +11 -0
- package/shared/dynamicContent/DynamicContentText.js +22 -0
- package/shared/dynamicContent/index.d.ts +5 -0
- package/shared/dynamicContent/index.js +4 -0
- package/shared/dynamicContent/styles.d.ts +7 -0
- package/shared/dynamicContent/styles.js +20 -0
- package/shared/dynamicContent/token.d.ts +20 -0
- package/shared/dynamicContent/token.js +45 -0
- package/shared/dynamicContent/types.d.ts +3 -0
- package/shared/dynamicContent/types.js +1 -0
- package/RichMessageEditor/RichMessageViewer.styled.d.ts +0 -3
- package/RichMessageEditor/RichMessageViewer.styled.js +0 -14
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { autoPlacement, size, offset, useFloating } from '@floating-ui/react-dom';
|
|
2
|
+
import { autoPlacement, autoUpdate, size, offset, useFloating } from '@floating-ui/react-dom';
|
|
3
3
|
import { useState, useEffect, useCallback } from 'react';
|
|
4
4
|
import { createPortal, flushSync } from 'react-dom';
|
|
5
5
|
import { Place } from './styles';
|
|
@@ -48,7 +48,9 @@ export const DropdownMenu = ({
|
|
|
48
48
|
refs,
|
|
49
49
|
floatingStyles
|
|
50
50
|
} = useFloating({
|
|
51
|
+
open: isOpen,
|
|
51
52
|
strategy: 'fixed',
|
|
53
|
+
whileElementsMounted: autoUpdate,
|
|
52
54
|
middleware: [size({
|
|
53
55
|
apply({
|
|
54
56
|
rects
|
package/NativeRichMediaPreview/components/NativeRichMediaButtonList/NativeRichMediaButtonList.js
CHANGED
|
@@ -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:
|
|
22
|
+
children: _jsx(DynamicContentText, {
|
|
23
|
+
tone: "subtle",
|
|
24
|
+
children: b.text.text
|
|
25
|
+
})
|
|
22
26
|
}, `btn-${i}`))
|
|
23
27
|
});
|
|
24
28
|
}
|
package/NativeRichMediaPreview/components/NativeRichMediaRewardPanel/NativeRichMediaRewardPanel.js
CHANGED
|
@@ -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:
|
|
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<
|
|
15
|
-
$
|
|
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
|
|
30
|
-
$
|
|
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,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 './
|
|
1
|
+
export { NativeRichMediaText } from './NativeRichMediaText';
|
|
2
|
+
export type { NativeRichMediaTextProps } from './types';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { NativeRichMediaText } from './
|
|
1
|
+
export { NativeRichMediaText } from './NativeRichMediaText';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Footnote } from '@pushwoosh/kit-typography';
|
|
2
|
-
export declare const
|
|
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
|
|
4
|
-
displayName: "
|
|
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 @@
|
|
|
1
|
+
export {};
|
|
@@ -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 './
|
|
1
|
+
export { NativeRichMediaTitle } from './NativeRichMediaTitle';
|
|
2
|
+
export type { NativeRichMediaTitleProps } from './types';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { NativeRichMediaTitle } from './
|
|
1
|
+
export { NativeRichMediaTitle } from './NativeRichMediaTitle';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const
|
|
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
|
|
3
|
+
export const TitleRoot = styled(Text).attrs(({
|
|
4
4
|
$size
|
|
5
5
|
}) => ({
|
|
6
6
|
$variant: $size === 'h4' ? 'h4' : 'h3'
|
|
7
7
|
})).withConfig({
|
|
8
|
-
displayName: "
|
|
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
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -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
|
|
3
|
-
$color
|
|
4
|
-
$align
|
|
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
|
|
14
|
-
|
|
15
|
-
$align
|
|
16
|
-
$
|
|
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;
|
package/NativeRichMediaPreview/views/NativeRichMediaSpinwheelView/NativeRichMediaSpinwheelView.js
CHANGED
|
@@ -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:
|
|
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
|
|
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
|
|
23
|
-
|
|
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
|
|
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
|
-
|
|
73
|
-
|
|
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
|
-
|
|
110
|
-
children
|
|
111
|
-
|
|
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
|
-
|
|
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
|
@@ -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,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 @@
|
|
|
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;"]);
|