@pushwoosh/dumb-components 1.1.165 → 1.1.167
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/Modal/components/Modal/styles.js +13 -6
- package/Modal/components/ModalConfirm/ModalConfirm.js +8 -11
- package/Modal/components/ModalContent/styles.d.ts +22 -5
- package/Modal/components/ModalContent/styles.js +16 -10
- package/Modal/components/ModalTitle/ModalTitle.js +17 -6
- package/Modal/components/ModalTitle/styles.d.ts +21 -1
- package/Modal/components/ModalTitle/styles.js +26 -5
- package/Modal/polyglot/messages_ar.js +2 -1
- package/Modal/polyglot/messages_bn.js +2 -1
- package/Modal/polyglot/messages_de.js +2 -1
- package/Modal/polyglot/messages_en.js +2 -1
- package/Modal/polyglot/messages_es.js +2 -1
- package/Modal/polyglot/messages_fr.js +2 -1
- package/Modal/polyglot/messages_he.js +2 -1
- package/Modal/polyglot/messages_hi.js +2 -1
- package/Modal/polyglot/messages_ja.js +2 -1
- package/Modal/polyglot/messages_ko.js +2 -1
- package/Modal/polyglot/messages_pt.js +2 -1
- package/Modal/polyglot/messages_ru.js +2 -1
- package/Modal/polyglot/messages_th.js +2 -1
- package/Modal/polyglot/messages_zh.js +2 -1
- package/Modal/polyglot/types.d.ts +1 -0
- package/NativeRichMediaPreview/parseNativeRichMediaConfig.d.ts +4 -1
- package/NativeRichMediaPreview/parseNativeRichMediaConfig.js +17 -8
- package/NativeRichMediaPreview/types.d.ts +12 -10
- package/NativeRichMediaPreview/views/NativeRichMediaBannerView/styles.js +1 -1
- package/NativeRichMediaPreview/views/NativeRichMediaModalView/styles.js +1 -1
- package/NativeRichMediaPreview/views/NativeRichMediaScratchcardView/NativeRichMediaScratchcardView.js +12 -10
- package/NativeRichMediaPreview/views/NativeRichMediaScratchcardView/styles.d.ts +1 -0
- package/NativeRichMediaPreview/views/NativeRichMediaScratchcardView/styles.js +11 -7
- package/package.json +1 -1
|
@@ -2,7 +2,10 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { CSSTransition } from 'react-transition-group';
|
|
3
3
|
import styled, { createGlobalStyle } from 'styled-components';
|
|
4
4
|
import { Color, ShapeRadius } from '@pushwoosh/kit-constants';
|
|
5
|
-
const
|
|
5
|
+
const ENTER_DURATION = 200;
|
|
6
|
+
const EXIT_DURATION = 150;
|
|
7
|
+
const SLIDE_DISTANCE = '16px';
|
|
8
|
+
const VIEWPORT_INSET = '56px';
|
|
6
9
|
export const LockBody = createGlobalStyle(["body{overflow:hidden;position:relative;height:100%;}"]);
|
|
7
10
|
export const ModalBox = styled.div.attrs(({
|
|
8
11
|
$zIndex
|
|
@@ -17,7 +20,7 @@ export const ModalBox = styled.div.attrs(({
|
|
|
17
20
|
export const ModalInner = styled.div.withConfig({
|
|
18
21
|
displayName: "ModalInner",
|
|
19
22
|
componentId: "sc-lejcgu-1"
|
|
20
|
-
})(["display:flex;align-items:flex-start;justify-content:center;width:
|
|
23
|
+
})(["display:flex;align-items:flex-start;justify-content:center;width:100%;height:100%;padding:", ";"], VIEWPORT_INSET);
|
|
21
24
|
function ModalBoxBase(props) {
|
|
22
25
|
const {
|
|
23
26
|
isOpen,
|
|
@@ -28,7 +31,11 @@ function ModalBoxBase(props) {
|
|
|
28
31
|
return _jsx(CSSTransition, {
|
|
29
32
|
appear: true,
|
|
30
33
|
in: isOpen,
|
|
31
|
-
timeout:
|
|
34
|
+
timeout: {
|
|
35
|
+
appear: ENTER_DURATION,
|
|
36
|
+
enter: ENTER_DURATION,
|
|
37
|
+
exit: EXIT_DURATION
|
|
38
|
+
},
|
|
32
39
|
classNames: className,
|
|
33
40
|
unmountOnExit: true,
|
|
34
41
|
nodeRef: nodeRef,
|
|
@@ -40,13 +47,13 @@ const backdropVisible = 'rgb(0 0 0 / 70%)';
|
|
|
40
47
|
export const ModalBoxTrans = styled(ModalBoxBase).withConfig({
|
|
41
48
|
displayName: "ModalBoxTrans",
|
|
42
49
|
componentId: "sc-lejcgu-2"
|
|
43
|
-
})(["&-appear,&-enter{background-color:", ";", "{opacity:0;transform:
|
|
50
|
+
})(["&-appear,&-enter{background-color:", ";", "{opacity:0;transform:translateY(", ");}}&-appear-active,&-enter-active{background-color:", ";transition:background-color ", "ms ease-out;", "{opacity:1;transform:translateY(0);transition:opacity ", "ms ease-out,transform ", "ms ease-out;}}&-appear-done,&-enter-done,&-exit{background-color:", ";", "{opacity:1;transform:translateY(0);}}&-exit-active{background-color:", ";transition:background-color ", "ms ease-in;", "{opacity:0;transform:translateY(", ");transition:opacity ", "ms ease-in,transform ", "ms ease-in;}}"], backdropHidden, ModalInner, SLIDE_DISTANCE, backdropVisible, ENTER_DURATION, ModalInner, ENTER_DURATION, ENTER_DURATION, backdropVisible, ModalInner, backdropHidden, EXIT_DURATION, ModalInner, SLIDE_DISTANCE, EXIT_DURATION, EXIT_DURATION);
|
|
44
51
|
export const ModalContainer = styled.div.withConfig({
|
|
45
52
|
displayName: "ModalContainer",
|
|
46
53
|
componentId: "sc-lejcgu-3"
|
|
47
|
-
})(["display:
|
|
54
|
+
})(["display:flex;flex-direction:column;position:relative;width:", ";max-height:calc(100vh - 2 * ", ");background-color:", ";border-radius:", ";"], ({
|
|
48
55
|
$width
|
|
49
|
-
}) => $width, Color.CLEAR, ShapeRadius.DIALOG
|
|
56
|
+
}) => $width, VIEWPORT_INSET, Color.CLEAR, ShapeRadius.DIALOG);
|
|
50
57
|
ModalBox.displayName = 'ModalBox';
|
|
51
58
|
ModalInner.displayName = 'ModalInner';
|
|
52
59
|
ModalContainer.displayName = 'ModalContainer';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useCallback } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { Horizontal } from '@pushwoosh/kit-helpers';
|
|
4
4
|
import { Banner } from '../../../Banner';
|
|
5
5
|
import { Button } from '../../../Button';
|
|
6
6
|
import { useLang } from '../../polyglot';
|
|
@@ -58,16 +58,13 @@ export function ModalConfirm(props) {
|
|
|
58
58
|
size: size,
|
|
59
59
|
isOpen: isOpen,
|
|
60
60
|
onClose: onCancel,
|
|
61
|
-
children: [
|
|
62
|
-
children:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
title: errorMessage
|
|
69
|
-
})]
|
|
70
|
-
})
|
|
61
|
+
children: [_jsxs(ModalHeader, {
|
|
62
|
+
children: [_jsx(ModalTitle, {
|
|
63
|
+
children: resolvedTitle
|
|
64
|
+
}), errorMessage && _jsx(Banner, {
|
|
65
|
+
type: "error",
|
|
66
|
+
title: errorMessage
|
|
67
|
+
})]
|
|
71
68
|
}), description && _jsx(ModalBody, {
|
|
72
69
|
children: description
|
|
73
70
|
}), _jsx(ModalFooter, {
|
|
@@ -1,5 +1,24 @@
|
|
|
1
|
+
import { UnitSize } from '@pushwoosh/kit-constants';
|
|
1
2
|
/** Top section of a {@link Modal}; typically wraps a {@link ModalTitle}. */
|
|
2
|
-
export declare const ModalHeader: import("styled-components").StyledComponent<"div", any, {
|
|
3
|
+
export declare const ModalHeader: import("styled-components").StyledComponent<"div", any, import("@pushwoosh/kit-helpers/styled-helpers").CommonBoxProps & {
|
|
4
|
+
$alignContent?: import("@pushwoosh/kit-helpers/styled-helpers").AlignContentValue | undefined;
|
|
5
|
+
$alignItems?: import("@pushwoosh/kit-helpers/styled-helpers").ItemAlignmentValue | undefined;
|
|
6
|
+
$gap?: import("@pushwoosh/kit-helpers/styled-helpers").StrNum | undefined;
|
|
7
|
+
$justifyContent?: import("@pushwoosh/kit-helpers/styled-helpers").JustifyContentValue | undefined;
|
|
8
|
+
} & {
|
|
9
|
+
$gridAutoFlow?: "row" | "column" | "dense" | "row dense" | "column dense" | undefined;
|
|
10
|
+
$justifyItems?: import("@pushwoosh/kit-helpers/styled-helpers").ItemAlignmentValue | undefined;
|
|
11
|
+
$placeItems?: import("@pushwoosh/kit-helpers/styled-helpers").ItemAlignmentValue | undefined;
|
|
12
|
+
} & {
|
|
13
|
+
$gridAutoFlow: string;
|
|
14
|
+
} & {
|
|
15
|
+
$gap: number;
|
|
16
|
+
$padding: {
|
|
17
|
+
horizontal: UnitSize;
|
|
18
|
+
top: UnitSize;
|
|
19
|
+
bottom: number;
|
|
20
|
+
};
|
|
21
|
+
}, "$gridAutoFlow" | "$padding" | "$gap">;
|
|
3
22
|
/** Groups {@link ModalBodyItem}s with hairline dividers between them, inside a {@link ModalBody}. */
|
|
4
23
|
export declare const ModalBodyGroup: import("styled-components").StyledComponent<"div", any, import("@pushwoosh/kit-helpers/styled-helpers").CommonBoxProps & {
|
|
5
24
|
$alignContent?: import("@pushwoosh/kit-helpers/styled-helpers").AlignContentValue | undefined;
|
|
@@ -13,10 +32,8 @@ export declare const ModalBodyGroup: import("styled-components").StyledComponent
|
|
|
13
32
|
} & {
|
|
14
33
|
$gridAutoFlow: string;
|
|
15
34
|
}, "$gridAutoFlow">;
|
|
16
|
-
/** A single row within a {@link ModalBodyGroup}
|
|
17
|
-
export declare const ModalBodyItem: import("styled-components").StyledComponent<"div", any, {
|
|
18
|
-
$vPadding?: boolean;
|
|
19
|
-
}, never>;
|
|
35
|
+
/** A single row within a {@link ModalBodyGroup}, divided from its siblings by hairlines. */
|
|
36
|
+
export declare const ModalBodyItem: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
20
37
|
/** Scrollable main content area of a {@link Modal}; self-pads unless it holds a {@link ModalBodyGroup}. */
|
|
21
38
|
export declare const ModalBody: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
22
39
|
/** Bottom action bar of a {@link Modal}, divided from the body; typically holds buttons. */
|
|
@@ -1,34 +1,40 @@
|
|
|
1
1
|
import styled from 'styled-components';
|
|
2
|
-
import { Color } from '@pushwoosh/kit-constants';
|
|
2
|
+
import { Color, UnitSize } from '@pushwoosh/kit-constants';
|
|
3
3
|
import { Vertical } from '@pushwoosh/kit-helpers';
|
|
4
4
|
/** Top section of a {@link Modal}; typically wraps a {@link ModalTitle}. */
|
|
5
|
-
export const ModalHeader = styled.
|
|
5
|
+
export const ModalHeader = styled(Vertical).attrs({
|
|
6
|
+
$gap: 8,
|
|
7
|
+
$padding: {
|
|
8
|
+
horizontal: UnitSize.POPUP_PADDING,
|
|
9
|
+
top: UnitSize.POPUP_PADDING,
|
|
10
|
+
bottom: 8
|
|
11
|
+
}
|
|
12
|
+
}).withConfig({
|
|
6
13
|
displayName: "ModalHeader",
|
|
7
14
|
componentId: "sc-1b5r517-0"
|
|
8
|
-
})(["
|
|
15
|
+
})([""]);
|
|
9
16
|
ModalHeader.displayName = 'ModalHeader';
|
|
10
17
|
/** Groups {@link ModalBodyItem}s with hairline dividers between them, inside a {@link ModalBody}. */
|
|
11
18
|
export const ModalBodyGroup = styled(Vertical).withConfig({
|
|
12
19
|
displayName: "ModalBodyGroup",
|
|
13
20
|
componentId: "sc-1b5r517-1"
|
|
14
|
-
})(["
|
|
21
|
+
})([""]);
|
|
15
22
|
ModalBodyGroup.displayName = 'ModalBodyGroup';
|
|
16
|
-
/** A single row within a {@link ModalBodyGroup}
|
|
23
|
+
/** A single row within a {@link ModalBodyGroup}, divided from its siblings by hairlines. */
|
|
17
24
|
export const ModalBodyItem = styled.div.withConfig({
|
|
18
25
|
displayName: "ModalBodyItem",
|
|
19
26
|
componentId: "sc-1b5r517-2"
|
|
20
|
-
})(["padding:", "
|
|
21
|
-
|
|
22
|
-
}) => $vPadding ? '24px' : 0, Color.CLEAR);
|
|
27
|
+
})(["padding:", ";&:not(:last-child){border-bottom:1px solid ", ";}", " > &:first-child{padding-top:0;}"], UnitSize.POPUP_PADDING, Color.DIVIDER, ModalBodyGroup);
|
|
28
|
+
ModalBodyItem.displayName = 'ModalBodyItem';
|
|
23
29
|
/** Scrollable main content area of a {@link Modal}; self-pads unless it holds a {@link ModalBodyGroup}. */
|
|
24
30
|
export const ModalBody = styled.div.withConfig({
|
|
25
31
|
displayName: "ModalBody",
|
|
26
32
|
componentId: "sc-1b5r517-3"
|
|
27
|
-
})(["
|
|
33
|
+
})(["min-height:0;overflow-y:auto;overscroll-behavior:contain;&:not(:has(> ", ")){padding:", ";}", " + &{padding-top:0;}"], ModalBodyGroup, UnitSize.POPUP_PADDING, ModalHeader);
|
|
28
34
|
ModalBody.displayName = 'ModalBody';
|
|
29
35
|
/** Bottom action bar of a {@link Modal}, divided from the body; typically holds buttons. */
|
|
30
36
|
export const ModalFooter = styled.div.withConfig({
|
|
31
37
|
displayName: "ModalFooter",
|
|
32
38
|
componentId: "sc-1b5r517-4"
|
|
33
|
-
})(["padding:
|
|
39
|
+
})(["padding:", ";border-top:1px solid ", ";"], UnitSize.POPUP_PADDING, Color.DIVIDER);
|
|
34
40
|
ModalFooter.displayName = 'ModalFooter';
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { CloseIcon } from '@pushwoosh/kit-icons';
|
|
3
|
-
import { ModalTitleBox } from './styles';
|
|
4
|
-
import {
|
|
3
|
+
import { ModalTitleBox, ModalTitleClose, ModalTitleText } from './styles';
|
|
4
|
+
import { Button } from '../../../Button';
|
|
5
|
+
import { useLang } from '../../polyglot';
|
|
5
6
|
/**
|
|
6
7
|
* Modal heading row with an optional close button; place inside {@link ModalHeader}.
|
|
7
8
|
*
|
|
@@ -14,12 +15,22 @@ export function ModalTitle(props) {
|
|
|
14
15
|
onClose,
|
|
15
16
|
...rest
|
|
16
17
|
} = props;
|
|
18
|
+
const lang = useLang();
|
|
17
19
|
return _jsxs(ModalTitleBox, {
|
|
18
20
|
...rest,
|
|
19
|
-
children: [
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
children: [_jsx(ModalTitleText, {
|
|
22
|
+
children: children
|
|
23
|
+
}), onClose && _jsx(ModalTitleClose, {
|
|
24
|
+
children: _jsx(Button, {
|
|
25
|
+
color: "secondary",
|
|
26
|
+
view: "ghost",
|
|
27
|
+
onClick: onClose,
|
|
28
|
+
icon: _jsx(CloseIcon, {
|
|
29
|
+
size: "medium"
|
|
30
|
+
}),
|
|
31
|
+
"aria-label": lang({
|
|
32
|
+
message: 'DUMB.MODAL.CLOSE'
|
|
33
|
+
})
|
|
23
34
|
})
|
|
24
35
|
})]
|
|
25
36
|
});
|
|
@@ -1 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
import { H3 } from '@pushwoosh/kit-typography';
|
|
2
|
+
export declare const ModalTitleBox: import("styled-components").StyledComponent<typeof H3, any, {}, never>;
|
|
3
|
+
export declare const ModalTitleText: import("styled-components").StyledComponent<"span", any, {}, never>;
|
|
4
|
+
export declare const ModalTitleClose: import("styled-components").StyledComponent<"div", any, import("@pushwoosh/kit-helpers/styled-helpers").CommonBoxProps & {
|
|
5
|
+
$alignContent?: import("@pushwoosh/kit-helpers/styled-helpers").AlignContentValue;
|
|
6
|
+
$alignItems?: import("@pushwoosh/kit-helpers/styled-helpers").ItemAlignmentValue;
|
|
7
|
+
$gap?: import("@pushwoosh/kit-helpers/styled-helpers").StrNum;
|
|
8
|
+
$justifyContent?: import("@pushwoosh/kit-helpers/styled-helpers").JustifyContentValue;
|
|
9
|
+
} & {
|
|
10
|
+
$flexDirection?: "row" | "row-reverse" | "column" | "column-reverse";
|
|
11
|
+
$flexWrap?: "nowrap" | "wrap" | "wrap-reverse";
|
|
12
|
+
} & {
|
|
13
|
+
$alignItems: string;
|
|
14
|
+
$justifyContent: string;
|
|
15
|
+
$shrink: number;
|
|
16
|
+
$width: number;
|
|
17
|
+
$height: number;
|
|
18
|
+
$margin: {
|
|
19
|
+
left: string;
|
|
20
|
+
};
|
|
21
|
+
}, "$height" | "$margin" | "$shrink" | "$width" | "$alignItems" | "$justifyContent">;
|
|
@@ -1,8 +1,29 @@
|
|
|
1
1
|
import styled from 'styled-components';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
2
|
+
import { FlexContainer } from '@pushwoosh/kit-helpers';
|
|
3
|
+
import { H3 } from '@pushwoosh/kit-typography';
|
|
4
|
+
const TITLE_GAP = '8px';
|
|
5
|
+
const CLOSE_BOX_SIZE = 24;
|
|
6
|
+
export const ModalTitleBox = styled(H3).withConfig({
|
|
5
7
|
displayName: "ModalTitleBox",
|
|
6
8
|
componentId: "sc-8qbijb-0"
|
|
7
|
-
})(["display:flex;
|
|
8
|
-
ModalTitleBox.displayName = 'ModalTitleBox';
|
|
9
|
+
})(["display:flex;align-items:center;gap:", ";"], TITLE_GAP);
|
|
10
|
+
ModalTitleBox.displayName = 'ModalTitleBox';
|
|
11
|
+
export const ModalTitleText = styled.span.withConfig({
|
|
12
|
+
displayName: "ModalTitleText",
|
|
13
|
+
componentId: "sc-8qbijb-1"
|
|
14
|
+
})(["flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:", ";"], TITLE_GAP);
|
|
15
|
+
ModalTitleText.displayName = 'ModalTitleText';
|
|
16
|
+
export const ModalTitleClose = styled(FlexContainer).attrs({
|
|
17
|
+
$alignItems: 'center',
|
|
18
|
+
$justifyContent: 'center',
|
|
19
|
+
$shrink: 0,
|
|
20
|
+
$width: CLOSE_BOX_SIZE,
|
|
21
|
+
$height: CLOSE_BOX_SIZE,
|
|
22
|
+
$margin: {
|
|
23
|
+
left: 'auto'
|
|
24
|
+
}
|
|
25
|
+
}).withConfig({
|
|
26
|
+
displayName: "ModalTitleClose",
|
|
27
|
+
componentId: "sc-8qbijb-2"
|
|
28
|
+
})([""]);
|
|
29
|
+
ModalTitleClose.displayName = 'ModalTitleClose';
|
|
@@ -2,5 +2,6 @@ export const messages = {
|
|
|
2
2
|
'DUMB.MODAL.UNEXPECTED_ERROR': 'একটি অপ্রত্যাশিত ত্রুটি ঘটেছে',
|
|
3
3
|
'DUMB.MODAL.CONFIRM_TITLE': 'ক্রিয়াটি নিশ্চিত করুন',
|
|
4
4
|
'DUMB.MODAL.CONFIRM': 'নিশ্চিত করুন',
|
|
5
|
-
'DUMB.MODAL.CANCEL': 'বাতিল করুন'
|
|
5
|
+
'DUMB.MODAL.CANCEL': 'বাতিল করুন',
|
|
6
|
+
'DUMB.MODAL.CLOSE': 'বন্ধ করুন'
|
|
6
7
|
};
|
|
@@ -2,5 +2,6 @@ export const messages = {
|
|
|
2
2
|
'DUMB.MODAL.UNEXPECTED_ERROR': 'Ein unerwarteter Fehler ist aufgetreten',
|
|
3
3
|
'DUMB.MODAL.CONFIRM_TITLE': 'Aktion bestätigen',
|
|
4
4
|
'DUMB.MODAL.CONFIRM': 'Bestätigen',
|
|
5
|
-
'DUMB.MODAL.CANCEL': 'Abbrechen'
|
|
5
|
+
'DUMB.MODAL.CANCEL': 'Abbrechen',
|
|
6
|
+
'DUMB.MODAL.CLOSE': 'Schließen'
|
|
6
7
|
};
|
|
@@ -2,5 +2,6 @@ export const messages = {
|
|
|
2
2
|
'DUMB.MODAL.UNEXPECTED_ERROR': 'Unexpected error occurred',
|
|
3
3
|
'DUMB.MODAL.CONFIRM_TITLE': 'Confirm action',
|
|
4
4
|
'DUMB.MODAL.CONFIRM': 'Confirm',
|
|
5
|
-
'DUMB.MODAL.CANCEL': 'Cancel'
|
|
5
|
+
'DUMB.MODAL.CANCEL': 'Cancel',
|
|
6
|
+
'DUMB.MODAL.CLOSE': 'Close'
|
|
6
7
|
};
|
|
@@ -2,5 +2,6 @@ export const messages = {
|
|
|
2
2
|
'DUMB.MODAL.UNEXPECTED_ERROR': 'Se produjo un error inesperado',
|
|
3
3
|
'DUMB.MODAL.CONFIRM_TITLE': 'Confirmar acción',
|
|
4
4
|
'DUMB.MODAL.CONFIRM': 'Confirmar',
|
|
5
|
-
'DUMB.MODAL.CANCEL': 'Cancelar'
|
|
5
|
+
'DUMB.MODAL.CANCEL': 'Cancelar',
|
|
6
|
+
'DUMB.MODAL.CLOSE': 'Cerrar'
|
|
6
7
|
};
|
|
@@ -2,5 +2,6 @@ export const messages = {
|
|
|
2
2
|
'DUMB.MODAL.UNEXPECTED_ERROR': 'Une erreur inattendue s’est produite',
|
|
3
3
|
'DUMB.MODAL.CONFIRM_TITLE': 'Confirmer l’action',
|
|
4
4
|
'DUMB.MODAL.CONFIRM': 'Confirmer',
|
|
5
|
-
'DUMB.MODAL.CANCEL': 'Annuler'
|
|
5
|
+
'DUMB.MODAL.CANCEL': 'Annuler',
|
|
6
|
+
'DUMB.MODAL.CLOSE': 'Fermer'
|
|
6
7
|
};
|
|
@@ -2,5 +2,6 @@ export const messages = {
|
|
|
2
2
|
'DUMB.MODAL.UNEXPECTED_ERROR': 'एक अप्रत्याशित त्रुटि हुई',
|
|
3
3
|
'DUMB.MODAL.CONFIRM_TITLE': 'कार्रवाई की पुष्टि करें',
|
|
4
4
|
'DUMB.MODAL.CONFIRM': 'पुष्टि करें',
|
|
5
|
-
'DUMB.MODAL.CANCEL': 'रद्द करें'
|
|
5
|
+
'DUMB.MODAL.CANCEL': 'रद्द करें',
|
|
6
|
+
'DUMB.MODAL.CLOSE': 'बंद करें'
|
|
6
7
|
};
|
|
@@ -2,5 +2,6 @@ export const messages = {
|
|
|
2
2
|
'DUMB.MODAL.UNEXPECTED_ERROR': 'Ocorreu um erro inesperado',
|
|
3
3
|
'DUMB.MODAL.CONFIRM_TITLE': 'Confirmar ação',
|
|
4
4
|
'DUMB.MODAL.CONFIRM': 'Confirmar',
|
|
5
|
-
'DUMB.MODAL.CANCEL': 'Cancelar'
|
|
5
|
+
'DUMB.MODAL.CANCEL': 'Cancelar',
|
|
6
|
+
'DUMB.MODAL.CLOSE': 'Fechar'
|
|
6
7
|
};
|
|
@@ -2,5 +2,6 @@ export const messages = {
|
|
|
2
2
|
'DUMB.MODAL.UNEXPECTED_ERROR': 'Произошла непредвиденная ошибка',
|
|
3
3
|
'DUMB.MODAL.CONFIRM_TITLE': 'Подтвердите действие',
|
|
4
4
|
'DUMB.MODAL.CONFIRM': 'Подтвердить',
|
|
5
|
-
'DUMB.MODAL.CANCEL': 'Отмена'
|
|
5
|
+
'DUMB.MODAL.CANCEL': 'Отмена',
|
|
6
|
+
'DUMB.MODAL.CLOSE': 'Закрыть'
|
|
6
7
|
};
|
|
@@ -2,5 +2,6 @@ export const messages = {
|
|
|
2
2
|
'DUMB.MODAL.UNEXPECTED_ERROR': 'เกิดข้อผิดพลาดที่ไม่คาดคิด',
|
|
3
3
|
'DUMB.MODAL.CONFIRM_TITLE': 'ยืนยันการดำเนินการ',
|
|
4
4
|
'DUMB.MODAL.CONFIRM': 'ยืนยัน',
|
|
5
|
-
'DUMB.MODAL.CANCEL': 'ยกเลิก'
|
|
5
|
+
'DUMB.MODAL.CANCEL': 'ยกเลิก',
|
|
6
|
+
'DUMB.MODAL.CLOSE': 'ปิด'
|
|
6
7
|
};
|
|
@@ -3,6 +3,9 @@ import { type NativeRichMediaConfig } from './types';
|
|
|
3
3
|
* Parses and validates a native rich media config from an object or a JSON
|
|
4
4
|
* string; returns `null` when the input is not a well-formed config — unknown
|
|
5
5
|
* `displayType`, missing block, empty `items`/`segments`, or any required
|
|
6
|
-
* field of the block contract absent or malformed.
|
|
6
|
+
* field of the block contract absent or malformed. Content that may be
|
|
7
|
+
* legitimately unfinished in a draft — empty text values, an empty or absent
|
|
8
|
+
* video `url`, an absent `reward` — is accepted and rendered bare, so live
|
|
9
|
+
* editor drafts preview without a placeholder.
|
|
7
10
|
*/
|
|
8
11
|
export declare function parseNativeRichMediaConfig(content: string | NativeRichMediaConfig): NativeRichMediaConfig | null;
|
|
@@ -9,7 +9,13 @@ function isFiniteNumber(value) {
|
|
|
9
9
|
return typeof value === 'number' && Number.isFinite(value);
|
|
10
10
|
}
|
|
11
11
|
function isText(value) {
|
|
12
|
-
return isObject(value) &&
|
|
12
|
+
return isObject(value) && typeof value.text === 'string' && isNonEmptyString(value.color);
|
|
13
|
+
}
|
|
14
|
+
function isFilledText(value) {
|
|
15
|
+
return isText(value) && isNonEmptyString(value.text);
|
|
16
|
+
}
|
|
17
|
+
function isOptionalString(value) {
|
|
18
|
+
return value === undefined || typeof value === 'string';
|
|
13
19
|
}
|
|
14
20
|
function isOptionalText(value) {
|
|
15
21
|
return value === undefined || isText(value);
|
|
@@ -21,7 +27,7 @@ function isAction(value) {
|
|
|
21
27
|
if (value.type === 'close') {
|
|
22
28
|
return true;
|
|
23
29
|
}
|
|
24
|
-
return value.type === 'url' &&
|
|
30
|
+
return value.type === 'url' && isOptionalString(value.url);
|
|
25
31
|
}
|
|
26
32
|
function isOptionalAction(value) {
|
|
27
33
|
return value === undefined || isAction(value);
|
|
@@ -45,7 +51,7 @@ function isReward(value) {
|
|
|
45
51
|
if (!isObject(value)) {
|
|
46
52
|
return false;
|
|
47
53
|
}
|
|
48
|
-
const hasIdentity =
|
|
54
|
+
const hasIdentity = isFilledText(value.title) || isNonEmptyString(value.code);
|
|
49
55
|
return hasIdentity && isOptionalText(value.title) && isOptionalText(value.message) && (value.button === undefined || isButton(value.button));
|
|
50
56
|
}
|
|
51
57
|
function isOptionalReward(value) {
|
|
@@ -59,18 +65,21 @@ const BLOCK_VALIDATORS = {
|
|
|
59
65
|
carousel: block => typeof block.showClose === 'boolean' && Array.isArray(block.items) && block.items.length > 0 && block.items.every(item => isObject(item) && isOptionalText(item.title) && isOptionalText(item.message) && isOptionalAction(item.action)),
|
|
60
66
|
fullscreen: block => typeof block.showClose === 'boolean' && isCover(block.cover) && isOptionalText(block.title) && isOptionalText(block.message) && isButtonArray(block.buttons),
|
|
61
67
|
modal: block => typeof block.showClose === 'boolean' && typeof block.dimBackground === 'boolean' && isNonEmptyString(block.background) && isOptionalText(block.title) && isOptionalText(block.message) && isButtonArray(block.buttons),
|
|
62
|
-
pip: block => typeof block.showClose === 'boolean' && ['bottom-right', 'bottom-left', 'top-right', 'top-left'].includes(block.position) && typeof block.loop === 'boolean' && typeof block.muted === 'boolean' &&
|
|
63
|
-
scratchcard: block => typeof block.showClose === 'boolean' && isBackground(block.background) && isFiniteNumber(block.revealThreshold) && isCover(block.cover) && (block.revealButton === undefined || isActionlessButton(block.revealButton)) && isOptionalText(block.title) && isOptionalText(block.message) &&
|
|
68
|
+
pip: block => typeof block.showClose === 'boolean' && ['bottom-right', 'bottom-left', 'top-right', 'top-left'].includes(block.position) && typeof block.loop === 'boolean' && typeof block.muted === 'boolean' && isOptionalString(block.url) && isFiniteNumber(block.width) && isFiniteNumber(block.aspectRatio) && isOptionalAction(block.action),
|
|
69
|
+
scratchcard: block => typeof block.showClose === 'boolean' && isBackground(block.background) && isFiniteNumber(block.revealThreshold) && isCover(block.cover) && (block.revealButton === undefined || isActionlessButton(block.revealButton)) && isOptionalText(block.title) && isOptionalText(block.message) && isOptionalReward(block.reward),
|
|
64
70
|
sheet: block => typeof block.showClose === 'boolean' && typeof block.dimBackground === 'boolean' && isNonEmptyString(block.background) && isOptionalText(block.title) && isOptionalText(block.message) && isButtonArray(block.buttons),
|
|
65
|
-
spinwheel: block => typeof block.showClose === 'boolean' && isBackground(block.background) && isFiniteNumber(block.winIndex) && isActionlessButton(block.spinButton) && isOptionalText(block.title) && isOptionalText(block.message) &&
|
|
71
|
+
spinwheel: block => typeof block.showClose === 'boolean' && isBackground(block.background) && isFiniteNumber(block.winIndex) && isActionlessButton(block.spinButton) && isOptionalText(block.title) && isOptionalText(block.message) && isOptionalReward(block.reward) && isOptionalText(block.loseTitle) && Array.isArray(block.segments) && block.segments.length > 0 && block.segments.every(segment => isObject(segment) && isText(segment.message) && isFiniteNumber(segment.weight) && isOptionalReward(segment.reward)),
|
|
66
72
|
stories: block => typeof block.showClose === 'boolean' && typeof block.loop === 'boolean' && Array.isArray(block.items) && block.items.length > 0 && block.items.every(item => isObject(item) && isOptionalText(item.title) && isOptionalText(item.message) && isButtonArray(item.buttons) && isFiniteNumber(item.duration)),
|
|
67
|
-
video: block => typeof block.showClose === 'boolean' && typeof block.loop === 'boolean' && typeof block.muted === 'boolean' &&
|
|
73
|
+
video: block => typeof block.showClose === 'boolean' && typeof block.loop === 'boolean' && typeof block.muted === 'boolean' && isOptionalString(block.url) && isOptionalText(block.title) && isOptionalText(block.message) && isButtonArray(block.buttons)
|
|
68
74
|
};
|
|
69
75
|
/**
|
|
70
76
|
* Parses and validates a native rich media config from an object or a JSON
|
|
71
77
|
* string; returns `null` when the input is not a well-formed config — unknown
|
|
72
78
|
* `displayType`, missing block, empty `items`/`segments`, or any required
|
|
73
|
-
* field of the block contract absent or malformed.
|
|
79
|
+
* field of the block contract absent or malformed. Content that may be
|
|
80
|
+
* legitimately unfinished in a draft — empty text values, an empty or absent
|
|
81
|
+
* video `url`, an absent `reward` — is accepted and rendered bare, so live
|
|
82
|
+
* editor drafts preview without a placeholder.
|
|
74
83
|
*/
|
|
75
84
|
export function parseNativeRichMediaConfig(content) {
|
|
76
85
|
let raw = content;
|
|
@@ -22,9 +22,11 @@ export type NativeRichMediaCover = {
|
|
|
22
22
|
/** Available actions. */
|
|
23
23
|
export type NativeRichMediaAction = {
|
|
24
24
|
type: 'close';
|
|
25
|
-
}
|
|
25
|
+
}
|
|
26
|
+
/** `url` is required by the SDK, but may be empty or absent in a draft. */
|
|
27
|
+
| {
|
|
26
28
|
type: 'url';
|
|
27
|
-
url
|
|
29
|
+
url?: string;
|
|
28
30
|
};
|
|
29
31
|
/** Button block. */
|
|
30
32
|
export type NativeRichMediaButton = {
|
|
@@ -162,8 +164,8 @@ export type NativeRichMediaVideoBlock = {
|
|
|
162
164
|
loop: boolean;
|
|
163
165
|
/** Start playback muted. */
|
|
164
166
|
muted: boolean;
|
|
165
|
-
/** Video URL. */
|
|
166
|
-
url
|
|
167
|
+
/** Video URL; required by the SDK, may be empty or absent in a draft. */
|
|
168
|
+
url?: string;
|
|
167
169
|
/** Poster image URL shown before playback. */
|
|
168
170
|
poster?: string;
|
|
169
171
|
/** Image URL shown when the video cannot be played. */
|
|
@@ -181,8 +183,8 @@ export type NativeRichMediaPipBlock = {
|
|
|
181
183
|
loop: boolean;
|
|
182
184
|
/** Start playback muted. */
|
|
183
185
|
muted: boolean;
|
|
184
|
-
/** Video URL. */
|
|
185
|
-
url
|
|
186
|
+
/** Video URL; required by the SDK, may be empty or absent in a draft. */
|
|
187
|
+
url?: string;
|
|
186
188
|
/** Poster image URL shown before playback. */
|
|
187
189
|
poster?: string;
|
|
188
190
|
/** Image URL shown when the video cannot be played. */
|
|
@@ -212,8 +214,8 @@ export type NativeRichMediaScratchcardBlock = {
|
|
|
212
214
|
title?: NativeRichMediaText;
|
|
213
215
|
/** Message. */
|
|
214
216
|
message?: NativeRichMediaText;
|
|
215
|
-
/** Reward revealed under the cover. */
|
|
216
|
-
reward
|
|
217
|
+
/** Reward revealed under the cover; required by the SDK, may be absent in a draft. */
|
|
218
|
+
reward?: NativeRichMediaReward;
|
|
217
219
|
};
|
|
218
220
|
/** Content of a `spinwheel` rich media. */
|
|
219
221
|
export type NativeRichMediaSpinwheelBlock = {
|
|
@@ -229,8 +231,8 @@ export type NativeRichMediaSpinwheelBlock = {
|
|
|
229
231
|
winIndex: number;
|
|
230
232
|
/** Spin button, including its own tap action. */
|
|
231
233
|
spinButton: Omit<NativeRichMediaButton, 'action'>;
|
|
232
|
-
/** Reward shown after a winning spin. */
|
|
233
|
-
reward
|
|
234
|
+
/** Reward shown after a winning spin; required by the SDK, may be absent in a draft. */
|
|
235
|
+
reward?: NativeRichMediaReward;
|
|
234
236
|
/** Heading shown after a losing spin. */
|
|
235
237
|
loseTitle?: NativeRichMediaText;
|
|
236
238
|
/** Wheel sectors. */
|
|
@@ -13,4 +13,4 @@ export const Card = styled.div.withConfig({
|
|
|
13
13
|
export const CloseGlyph = styled.div.withConfig({
|
|
14
14
|
displayName: "CloseGlyph",
|
|
15
15
|
componentId: "sc-1fs78cm-1"
|
|
16
|
-
})(["flex:none;width:24px;height:24px;display:flex;align-items:center;justify-content:center;color:rgba(255,255,255,0.6);font-size:", ";font-weight:", ";user-select:none;cursor:pointer;"], FontSize.SMALL, FontWeight.BOLD);
|
|
16
|
+
})(["flex:none;margin-left:auto;width:24px;height:24px;border-radius:50%;background:rgba(0,0,0,0.4);display:flex;align-items:center;justify-content:center;color:rgba(255,255,255,0.6);font-size:", ";font-weight:", ";user-select:none;cursor:pointer;"], FontSize.SMALL, FontWeight.BOLD);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Card, HintOverlay, HintText, RevealArea, RevealButtonText, RewardSlot } from './styles';
|
|
2
|
+
import { Card, HintOverlay, HintText, RevealArea, RevealButtonText, RewardSlot, TextBlock } from './styles';
|
|
3
3
|
import { NativeRichMediaCloseChip } from '../../components/NativeRichMediaCloseChip';
|
|
4
4
|
import { NativeRichMediaCoverImg } from '../../components/NativeRichMediaCoverImg';
|
|
5
5
|
import { NativeRichMediaRewardPanel } from '../../components/NativeRichMediaRewardPanel';
|
|
@@ -21,15 +21,17 @@ export function NativeRichMediaScratchcardView(props) {
|
|
|
21
21
|
const revealButton = asButtonValue(block.revealButton);
|
|
22
22
|
return _jsxs(Card, {
|
|
23
23
|
"$background": surfaceBackground(block.background, '#FFFFFF'),
|
|
24
|
-
children: [title.text &&
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
children: [(title.text || message.text) && _jsxs(TextBlock, {
|
|
25
|
+
children: [title.text && _jsx(NativeRichMediaTitle, {
|
|
26
|
+
"$color": title.color,
|
|
27
|
+
"$align": "center",
|
|
28
|
+
children: title.text
|
|
29
|
+
}), message.text && _jsx(NativeRichMediaText, {
|
|
30
|
+
"$color": message.color,
|
|
31
|
+
"$marginTop": 4,
|
|
32
|
+
"$align": "center",
|
|
33
|
+
children: message.text
|
|
34
|
+
})]
|
|
33
35
|
}), _jsxs(RevealArea, {
|
|
34
36
|
children: [_jsx(RewardSlot, {
|
|
35
37
|
children: _jsx(NativeRichMediaRewardPanel, {
|
|
@@ -4,6 +4,7 @@ export declare const Card: import("styled-components").StyledComponent<"div", an
|
|
|
4
4
|
} & {
|
|
5
5
|
$padding: string;
|
|
6
6
|
}, "$padding">;
|
|
7
|
+
export declare const TextBlock: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
7
8
|
export declare const RevealArea: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
8
9
|
export declare const RewardSlot: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
9
10
|
export declare const HintOverlay: import("styled-components").StyledComponent<"div", any, {
|
|
@@ -4,35 +4,39 @@ import { NativeRichMediaText } from '../../components/NativeRichMediaText';
|
|
|
4
4
|
import { mixHex } from '../../helpers';
|
|
5
5
|
import { Card as SharedCard } from '../shared/styles';
|
|
6
6
|
export const Card = styled(SharedCard).attrs({
|
|
7
|
-
$padding: '
|
|
7
|
+
$padding: '24px'
|
|
8
8
|
}).withConfig({
|
|
9
9
|
displayName: "Card",
|
|
10
10
|
componentId: "sc-nguevq-0"
|
|
11
11
|
})([""]);
|
|
12
|
+
export const TextBlock = styled.div.withConfig({
|
|
13
|
+
displayName: "TextBlock",
|
|
14
|
+
componentId: "sc-nguevq-1"
|
|
15
|
+
})(["margin-bottom:14px;"]);
|
|
12
16
|
export const RevealArea = styled.div.withConfig({
|
|
13
17
|
displayName: "RevealArea",
|
|
14
|
-
componentId: "sc-nguevq-
|
|
15
|
-
})(["position:relative;
|
|
18
|
+
componentId: "sc-nguevq-2"
|
|
19
|
+
})(["position:relative;height:179px;border-radius:18px;background:#F7F7F7;overflow:hidden;"]);
|
|
16
20
|
export const RewardSlot = styled.div.withConfig({
|
|
17
21
|
displayName: "RewardSlot",
|
|
18
|
-
componentId: "sc-nguevq-
|
|
22
|
+
componentId: "sc-nguevq-3"
|
|
19
23
|
})(["position:absolute;left:16px;right:16px;top:50%;transform:translateY(-50%);"]);
|
|
20
24
|
export const HintOverlay = styled.div.withConfig({
|
|
21
25
|
displayName: "HintOverlay",
|
|
22
|
-
componentId: "sc-nguevq-
|
|
26
|
+
componentId: "sc-nguevq-4"
|
|
23
27
|
})(["position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;background:", ";"], ({
|
|
24
28
|
$coverBase
|
|
25
29
|
}) => `linear-gradient(135deg, ${mixHex($coverBase, '#FFFFFF', 0.4)}, ${$coverBase} 45%, ${mixHex($coverBase, '#000000', 0.12)})`);
|
|
26
30
|
export const HintText = styled(NativeRichMediaText).withConfig({
|
|
27
31
|
displayName: "HintText",
|
|
28
|
-
componentId: "sc-nguevq-
|
|
32
|
+
componentId: "sc-nguevq-5"
|
|
29
33
|
})(["font-weight:", ";"], FontWeight.MEDIUM);
|
|
30
34
|
export const RevealButtonText = styled(NativeRichMediaText).attrs({
|
|
31
35
|
$align: 'center',
|
|
32
36
|
$marginTop: 14
|
|
33
37
|
}).withConfig({
|
|
34
38
|
displayName: "RevealButtonText",
|
|
35
|
-
componentId: "sc-nguevq-
|
|
39
|
+
componentId: "sc-nguevq-6"
|
|
36
40
|
})(["font-weight:", ";width:fit-content;margin-left:auto;margin-right:auto;background:", ";border-radius:", "px;padding:10px 16px;border:1px solid ", ";user-select:none;cursor:pointer;"], FontWeight.MEDIUM, ({
|
|
37
41
|
$background
|
|
38
42
|
}) => $background, ({
|