@pushwoosh/dumb-components 1.1.84 → 1.1.86

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.
@@ -12,7 +12,7 @@ export const RootBox = styled.div.withConfig({
12
12
  export const ImgPreview = styled.img.withConfig({
13
13
  displayName: "ImgPreview",
14
14
  componentId: "sc-irvho3-1"
15
- })(["width:", ";height:", ";border-radius:", ";opacity:", ";z-index:1;"], ({
15
+ })(["width:", ";height:", ";border-radius:", ";opacity:", ";"], ({
16
16
  width
17
17
  }) => toCssValue(width), ({
18
18
  height
@@ -22,7 +22,7 @@ export const ImgPreview = styled.img.withConfig({
22
22
  export const PlaceholderWrapper = styled.div.withConfig({
23
23
  displayName: "PlaceholderWrapper",
24
24
  componentId: "sc-irvho3-2"
25
- })(["width:", ";height:", ";display:flex;align-items:center;justify-content:center;border-radius:", ";position:absolute;top:0;left:0;z-index:2;background:", ";"], ({
25
+ })(["width:", ";height:", ";display:flex;align-items:center;justify-content:center;border-radius:", ";position:absolute;top:0;left:0;background:", ";"], ({
26
26
  width
27
27
  }) => toCssValue(width), ({
28
28
  height
@@ -0,0 +1,3 @@
1
+ import { type ReactElement } from 'react';
2
+ import type { RichmediaPreviewProps } from './types';
3
+ export declare function RichmediaPreview(props: RichmediaPreviewProps): ReactElement;
@@ -0,0 +1,48 @@
1
+ import React, { useRef, useEffect } from 'react';
2
+ import { Color } from '@pushwoosh/kit-constants';
3
+ import { Spinner } from '../Spinner';
4
+ import { useRichmediaHtml } from './hooks';
5
+ import { RichMediaPreviewContainer, RichMediaPreviewIframe } from './styles';
6
+ export function RichmediaPreview(props) {
7
+ const {
8
+ name,
9
+ params,
10
+ content = '',
11
+ defaultLanguage = 'en',
12
+ baseUrl = '',
13
+ width = 304,
14
+ height = 480,
15
+ isLoading,
16
+ language
17
+ } = props;
18
+ const $ref = useRef(null);
19
+ const richmediaHtml = useRichmediaHtml({
20
+ content,
21
+ params,
22
+ language,
23
+ defaultLanguage,
24
+ baseUrl
25
+ });
26
+ useEffect(() => {
27
+ var _$ref$current;
28
+ if (!($ref !== null && $ref !== void 0 && (_$ref$current = $ref.current) !== null && _$ref$current !== void 0 && (_$ref$current = _$ref$current.contentWindow) !== null && _$ref$current !== void 0 && _$ref$current.document)) {
29
+ return;
30
+ }
31
+ $ref.current.contentWindow.document.open('text/html', 'replace');
32
+ $ref.current.contentWindow.document.write(richmediaHtml);
33
+ $ref.current.contentWindow.document.close();
34
+ }, [$ref, richmediaHtml]);
35
+ return React.createElement(RichMediaPreviewContainer, {
36
+ width: width,
37
+ height: height,
38
+ "$isLoading": isLoading,
39
+ "$placeItems": "center"
40
+ }, isLoading ? React.createElement(Spinner, {
41
+ size: "medium",
42
+ color: Color.LOCKED
43
+ }) : React.createElement(RichMediaPreviewIframe, {
44
+ ref: $ref,
45
+ title: name,
46
+ sandbox: "allow-same-origin allow-scripts"
47
+ }));
48
+ }
@@ -0,0 +1,13 @@
1
+ import type { ObjectItem } from '../../types';
2
+ export declare class Template {
3
+ private baseUrl;
4
+ private vars;
5
+ private params;
6
+ private template?;
7
+ private replacers?;
8
+ constructor(html: string, vars: ObjectItem, params: ObjectItem, baseUrl: string);
9
+ injectBaseUrl(str: string): string;
10
+ getParamValue(varName: string): any;
11
+ parseHtml(html: string): void;
12
+ run(): any;
13
+ }
@@ -0,0 +1,42 @@
1
+ import { getName, getVarPlaceholder, reStr } from '../../helpers';
2
+ export class Template {
3
+ baseUrl;
4
+ vars;
5
+ params;
6
+ template;
7
+ replacers;
8
+ constructor(html, vars, params, baseUrl) {
9
+ this.baseUrl = baseUrl;
10
+ this.vars = vars;
11
+ this.params = params;
12
+ this.parseHtml(html);
13
+ }
14
+ injectBaseUrl(str) {
15
+ return str.replace(/<head[^>]*>/i, founded => `${founded}<base href="${this.baseUrl}" />`);
16
+ }
17
+ getParamValue(varName) {
18
+ return this.params && Object.prototype.hasOwnProperty.call(this.params, varName) ? this.params[varName] : this.vars[varName].defaults;
19
+ }
20
+ parseHtml(html) {
21
+ const replacers = [];
22
+ const replacePlaceholders = (full, cb, getReplacer) => full.replace(new RegExp(reStr, 'g'), fullPlaceholderText => {
23
+ const varName = getName(fullPlaceholderText);
24
+ const placeholder = getVarPlaceholder(varName);
25
+ if (cb) {
26
+ cb(varName);
27
+ }
28
+ replacers.push({
29
+ placeholder,
30
+ replacer: getReplacer ? getReplacer(varName) : () => this.getParamValue(varName)
31
+ });
32
+ return placeholder;
33
+ });
34
+ let template = html.replace(/<head[^>]*>([\s\S]*)<\/head[^>]*>/im, full => this.injectBaseUrl(replacePlaceholders(full)));
35
+ template = replacePlaceholders(template, undefined, varName => this.getParamValue(varName));
36
+ this.template = template;
37
+ this.replacers = replacers;
38
+ }
39
+ run() {
40
+ return this.replacers.reduce((src, rep) => src.replace(rep.placeholder, rep.replacer), this.template);
41
+ }
42
+ }
@@ -0,0 +1 @@
1
+ export { Template } from './Template';
@@ -0,0 +1 @@
1
+ export { Template } from './Template';
@@ -0,0 +1,5 @@
1
+ import type { ObjectItem } from './types';
2
+ export declare const reStr = "\\{\\{([^}]+)\\}\\}";
3
+ export declare function getName(placeholder: string): string;
4
+ export declare function getVarPlaceholder(varName: string): string;
5
+ export declare function findAllVars(text: string): ObjectItem;
@@ -0,0 +1,38 @@
1
+ export const reStr = '\\{\\{([^}]+)\\}\\}';
2
+ const reGetName = /{{([^|]+)|/; // regex for get param name
3
+ export function getName(placeholder) {
4
+ const f = placeholder.match(reGetName) || [];
5
+ return f[1];
6
+ }
7
+ export function getVarPlaceholder(varName) {
8
+ return `<|<${varName}>|>`;
9
+ }
10
+ export function findAllVars(text) {
11
+ const re = new RegExp(reStr, 'g');
12
+ const vars = {};
13
+ let i = 0;
14
+ let founded = re.exec(text);
15
+ while (founded) {
16
+ i += 1;
17
+ const [title, type, defaultsRaw] = founded[1].split('|');
18
+ let defaults = defaultsRaw;
19
+ const name = title;
20
+ const className = `var-${i}`;
21
+ if (!defaults) {
22
+ if (type === 'color') {
23
+ defaults = 'F00';
24
+ } else {
25
+ defaults = title;
26
+ }
27
+ }
28
+ vars[name] = {
29
+ name,
30
+ type,
31
+ title,
32
+ defaults,
33
+ className
34
+ };
35
+ founded = re.exec(text);
36
+ }
37
+ return vars;
38
+ }
@@ -0,0 +1,2 @@
1
+ import type { BuildRichmediaHtmlArgs } from './types';
2
+ export declare function useRichmediaHtml({ content, params, language, defaultLanguage, baseUrl, }: BuildRichmediaHtmlArgs): string;
@@ -0,0 +1,53 @@
1
+ import { useMemo } from 'react';
2
+ import { Template } from './components/Template';
3
+ import { findAllVars } from './helpers';
4
+ function normalizeParams(params, language, defaultLanguage = 'en') {
5
+ let jsonParams = params;
6
+ if (typeof jsonParams === 'string') {
7
+ try {
8
+ jsonParams = JSON.parse(jsonParams);
9
+ } catch {
10
+ return {};
11
+ }
12
+ }
13
+ if (!jsonParams || Array.isArray(jsonParams) || typeof jsonParams !== 'object') {
14
+ return {};
15
+ }
16
+ let formattedParams = Object.values(jsonParams).length ? language && jsonParams[language] || jsonParams[defaultLanguage || 'en'] || Object.values(jsonParams)[0] : {};
17
+ if (!formattedParams || Array.isArray(formattedParams)) {
18
+ formattedParams = {};
19
+ }
20
+ return formattedParams;
21
+ }
22
+ function buildRichmediaHtml({
23
+ content,
24
+ params,
25
+ language,
26
+ defaultLanguage = 'en',
27
+ baseUrl = ''
28
+ }) {
29
+ if (!content) {
30
+ return '';
31
+ }
32
+ const formattedParams = normalizeParams(params, language, defaultLanguage);
33
+ const vars = findAllVars(content);
34
+ const template = new Template(content, vars, formattedParams, `${window.location.protocol}//${window.location.host}${baseUrl}/`);
35
+ return template.run();
36
+ }
37
+ export function useRichmediaHtml({
38
+ content,
39
+ params,
40
+ language,
41
+ defaultLanguage,
42
+ baseUrl
43
+ }) {
44
+ return useMemo(() => {
45
+ return buildRichmediaHtml({
46
+ content,
47
+ params,
48
+ language,
49
+ defaultLanguage,
50
+ baseUrl
51
+ });
52
+ }, [content, params, language, defaultLanguage, baseUrl]);
53
+ }
@@ -0,0 +1,2 @@
1
+ export { RichmediaPreview } from './RichmediaPreview';
2
+ export { useRichmediaHtml } from './hooks';
@@ -0,0 +1,2 @@
1
+ export { RichmediaPreview } from './RichmediaPreview';
2
+ export { useRichmediaHtml } from './hooks';
@@ -0,0 +1,61 @@
1
+ export declare const RichMediaPreviewContainer: import("styled-components").StyledComponent<"div", any, {
2
+ $alignContent?: "end" | "start" | "center" | "space-between" | "space-around" | "space-evenly" | "stretch" | undefined;
3
+ $alignItems?: "end" | "start" | "center" | "stretch" | "baseline" | undefined;
4
+ $bgColor?: string | undefined;
5
+ $border?: string | ({
6
+ top?: string | undefined;
7
+ right?: string | undefined;
8
+ bottom?: string | undefined;
9
+ left?: string | undefined;
10
+ } | {
11
+ horizontal: string;
12
+ top?: string | undefined;
13
+ bottom?: string | undefined;
14
+ } | {
15
+ vertical: string;
16
+ right?: string | undefined;
17
+ left?: string | undefined;
18
+ }) | undefined;
19
+ $borderRadius?: (string | number) | undefined;
20
+ $boxShadow?: string | undefined;
21
+ $gap?: (string | number) | undefined;
22
+ $gridAutoFlow?: "row" | "column" | "dense" | "row dense" | "column dense" | undefined;
23
+ $justifyContent?: "end" | "start" | "center" | "space-between" | "space-around" | "space-evenly" | "stretch" | undefined;
24
+ $justifyItems?: "end" | "start" | "center" | "stretch" | "baseline" | undefined;
25
+ $margin?: (string | number) | ({
26
+ top?: (string | number) | undefined;
27
+ right?: (string | number) | undefined;
28
+ bottom?: (string | number) | undefined;
29
+ left?: (string | number) | undefined;
30
+ } | {
31
+ horizontal: string | number;
32
+ top?: (string | number) | undefined;
33
+ bottom?: (string | number) | undefined;
34
+ } | {
35
+ vertical: string | number;
36
+ right?: (string | number) | undefined;
37
+ left?: (string | number) | undefined;
38
+ }) | undefined;
39
+ $padding?: (string | number) | ({
40
+ top?: (string | number) | undefined;
41
+ right?: (string | number) | undefined;
42
+ bottom?: (string | number) | undefined;
43
+ left?: (string | number) | undefined;
44
+ } | {
45
+ horizontal: string | number;
46
+ top?: (string | number) | undefined;
47
+ bottom?: (string | number) | undefined;
48
+ } | {
49
+ vertical: string | number;
50
+ right?: (string | number) | undefined;
51
+ left?: (string | number) | undefined;
52
+ }) | undefined;
53
+ $placeItems?: "end" | "start" | "center" | "stretch" | undefined;
54
+ } & {
55
+ $gridAutoFlow: string;
56
+ } & {
57
+ width: string | number;
58
+ height: string | number;
59
+ $isLoading?: boolean;
60
+ }, "$gridAutoFlow">;
61
+ export declare const RichMediaPreviewIframe: import("styled-components").StyledComponent<"iframe", any, {}, never>;
@@ -0,0 +1,17 @@
1
+ import styled from 'styled-components';
2
+ import { Color, ShapeRadius } from '@pushwoosh/kit-constants';
3
+ import { Vertical, toCssValue } from '@pushwoosh/kit-helpers';
4
+ export const RichMediaPreviewContainer = styled(Vertical).withConfig({
5
+ displayName: "RichMediaPreviewContainer",
6
+ componentId: "sc-1ci6l2b-0"
7
+ })(["position:relative;border:1px solid #ddd;width:", ";height:", ";border-radius:", ";background-color:", ";margin:0 auto;overflow:hidden;"], ({
8
+ width
9
+ }) => toCssValue(width), ({
10
+ height
11
+ }) => toCssValue(height), ShapeRadius.SECTION, ({
12
+ $isLoading
13
+ }) => $isLoading ? Color.FROZEN : Color.CLEAR);
14
+ export const RichMediaPreviewIframe = styled.iframe.withConfig({
15
+ displayName: "RichMediaPreviewIframe",
16
+ componentId: "sc-1ci6l2b-1"
17
+ })(["position:absolute;left:-50%;top:-50%;width:200%;height:200%;transform:scale(0.51);"]);
@@ -0,0 +1,20 @@
1
+ export type ObjectItem = {
2
+ [key: string]: any;
3
+ };
4
+ export type Replacer = {
5
+ placeholder: string;
6
+ replacer: any;
7
+ };
8
+ export type BuildRichmediaHtmlArgs = {
9
+ params: any;
10
+ content: string;
11
+ language?: string;
12
+ defaultLanguage?: string;
13
+ baseUrl?: string;
14
+ };
15
+ export type RichmediaPreviewProps = BuildRichmediaHtmlArgs & {
16
+ name: string;
17
+ width?: string | number;
18
+ height?: string | number;
19
+ isLoading: boolean;
20
+ };
@@ -0,0 +1 @@
1
+ export {};
package/index.d.ts CHANGED
@@ -38,6 +38,7 @@ export { NumberPicker } from './NumberPicker';
38
38
  export { CodeEditor } from './CodeEditor';
39
39
  export { EnhancedInput, SearchInput } from './EnhancedInput';
40
40
  export { Chip } from './Chip';
41
+ export { RichmediaPreview, useRichmediaHtml } from './RichmediaPreview';
41
42
  export { RichMessageEditor, RichMessageViewer, type DynamicContent, } from './RichMessageEditor';
42
43
  export { FrequencyCappingEdit, FrequencyCappingReadonly, type LocalCapping, } from './FrequencyCapping';
43
44
  export { SendRateEdit, SendRateReadonly, type SendRateBase, type SendRateEditProps, type SendRateReadonlyProps, } from './SendRate';
package/index.js CHANGED
@@ -38,6 +38,7 @@ export { NumberPicker } from './NumberPicker';
38
38
  export { CodeEditor } from './CodeEditor';
39
39
  export { EnhancedInput, SearchInput } from './EnhancedInput';
40
40
  export { Chip } from './Chip';
41
+ export { RichmediaPreview, useRichmediaHtml } from './RichmediaPreview';
41
42
  export { RichMessageEditor, RichMessageViewer } from './RichMessageEditor';
42
43
  export { FrequencyCappingEdit, FrequencyCappingReadonly } from './FrequencyCapping';
43
44
  export { SendRateEdit, SendRateReadonly } from './SendRate';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushwoosh/dumb-components",
3
- "version": "1.1.84",
3
+ "version": "1.1.86",
4
4
  "description": "React components to build Pushwoosh products",
5
5
  "main": "index.js",
6
6
  "module": "index.js",