@pushwoosh/dumb-components 1.1.231 → 1.1.233
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/InboxPreview/styles.js +2 -2
- package/NativeRichMediaPreview/NativeRichMediaPreview.d.ts +0 -30
- package/NativeRichMediaPreview/NativeRichMediaPreview.js +36 -9
- package/NativeRichMediaPreview/components/NativeRichMediaThemeChip/NativeRichMediaThemeChip.d.ts +3 -0
- package/NativeRichMediaPreview/components/NativeRichMediaThemeChip/NativeRichMediaThemeChip.js +25 -0
- package/NativeRichMediaPreview/components/NativeRichMediaThemeChip/index.d.ts +1 -0
- package/NativeRichMediaPreview/components/NativeRichMediaThemeChip/index.js +1 -0
- package/NativeRichMediaPreview/components/NativeRichMediaThemeChip/styles.d.ts +8 -0
- package/NativeRichMediaPreview/components/NativeRichMediaThemeChip/styles.js +7 -0
- package/NativeRichMediaPreview/components/NativeRichMediaThemeChip/types.d.ts +8 -0
- package/NativeRichMediaPreview/components/NativeRichMediaThemeChip/types.js +1 -0
- package/NativeRichMediaPreview/icons/MoonIcon.svg +3 -0
- package/NativeRichMediaPreview/icons/SunIcon.svg +4 -0
- package/NativeRichMediaPreview/icons/index.d.ts +2 -0
- package/NativeRichMediaPreview/icons/index.js +3 -1
- package/NativeRichMediaPreview/index.d.ts +2 -1
- package/NativeRichMediaPreview/index.js +2 -1
- package/NativeRichMediaPreview/mergeNativeDarkOverlay.d.ts +3 -0
- package/NativeRichMediaPreview/mergeNativeDarkOverlay.js +89 -0
- package/NativeRichMediaPreview/polyglot/messages_ar.js +2 -1
- package/NativeRichMediaPreview/polyglot/messages_bn.js +2 -1
- package/NativeRichMediaPreview/polyglot/messages_de.js +2 -1
- package/NativeRichMediaPreview/polyglot/messages_en.js +2 -1
- package/NativeRichMediaPreview/polyglot/messages_es.js +2 -1
- package/NativeRichMediaPreview/polyglot/messages_fr.js +2 -1
- package/NativeRichMediaPreview/polyglot/messages_he.js +2 -1
- package/NativeRichMediaPreview/polyglot/messages_hi.js +2 -1
- package/NativeRichMediaPreview/polyglot/messages_ja.js +2 -1
- package/NativeRichMediaPreview/polyglot/messages_ko.js +2 -1
- package/NativeRichMediaPreview/polyglot/messages_pt.js +2 -1
- package/NativeRichMediaPreview/polyglot/messages_ru.js +2 -1
- package/NativeRichMediaPreview/polyglot/messages_th.js +2 -1
- package/NativeRichMediaPreview/polyglot/messages_zh.js +2 -1
- package/NativeRichMediaPreview/polyglot/types.d.ts +1 -0
- package/NativeRichMediaPreview/types.d.ts +26 -0
- package/index.d.ts +1 -1
- package/package.json +1 -1
package/InboxPreview/styles.js
CHANGED
|
@@ -5,14 +5,14 @@ import { Text } from '@pushwoosh/kit-typography';
|
|
|
5
5
|
export const HeroImage = styled.img.withConfig({
|
|
6
6
|
displayName: "HeroImage",
|
|
7
7
|
componentId: "sc-1rsolhm-0"
|
|
8
|
-
})(["display:block;width:100%;aspect-ratio:
|
|
8
|
+
})(["display:block;width:100%;aspect-ratio:2 / 1;object-fit:cover;border-radius:", ";"], ShapeRadius.SECTION);
|
|
9
9
|
export const EmptyHero = styled(Vertical).attrs({
|
|
10
10
|
$borderRadius: ShapeRadius.SECTION,
|
|
11
11
|
$shrink: 0
|
|
12
12
|
}).withConfig({
|
|
13
13
|
displayName: "EmptyHero",
|
|
14
14
|
componentId: "sc-1rsolhm-1"
|
|
15
|
-
})(["aspect-ratio:
|
|
15
|
+
})(["aspect-ratio:2 / 1;border:1px dashed ", ";background:", ";"], Color.BRIGHT, Color.BRIGHT_LIGHT_HOVER);
|
|
16
16
|
export const ClampText = styled(Text).withConfig({
|
|
17
17
|
displayName: "ClampText",
|
|
18
18
|
componentId: "sc-1rsolhm-2"
|
|
@@ -1,33 +1,3 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
2
|
import type { NativeRichMediaPreviewProps } from './types';
|
|
3
|
-
/**
|
|
4
|
-
* Preview of a native rich media (modal, banner, stories, spinwheel, …)
|
|
5
|
-
* rendered from its JSON config; lays out with plain CSS in the real pixels
|
|
6
|
-
* of the given width/height box, with no fidelity to any phone's pt-metrics
|
|
7
|
-
* since this is a preview and devices vary. Content flows inside a scrollable
|
|
8
|
-
* layer above a static backdrop (the dim overlay or, for
|
|
9
|
-
* `fullscreen`/`video`/`stories`, the full-bleed background image or poster):
|
|
10
|
-
* content taller than the box scrolls, shorter content aligns per display
|
|
11
|
-
* type while the backdrop stays put. Pass `scale` to lay the content out on a
|
|
12
|
-
* larger (or smaller) reference viewport and scale the whole preview to fill
|
|
13
|
-
* the box — the way to cram a phone-sized layout into a small preview box
|
|
14
|
-
* while keeping its proportions. Shows an invalid-config placeholder when the
|
|
15
|
-
* config cannot be parsed or misses required contract fields.
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* <NativeRichMediaPreview
|
|
19
|
-
* width={304}
|
|
20
|
-
* height={659}
|
|
21
|
-
* content={{
|
|
22
|
-
* displayType: 'modal',
|
|
23
|
-
* modal: {
|
|
24
|
-
* showClose: true,
|
|
25
|
-
* dimBackground: true,
|
|
26
|
-
* background: '#FFFFFFFF',
|
|
27
|
-
* title: { text: 'Hi', color: '#4B5057FF' },
|
|
28
|
-
* buttons: [],
|
|
29
|
-
* },
|
|
30
|
-
* }}
|
|
31
|
-
* />
|
|
32
|
-
*/
|
|
33
3
|
export declare function NativeRichMediaPreview(props: NativeRichMediaPreviewProps): ReactElement;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo } from 'react';
|
|
2
|
+
import { useMemo, useState } from 'react';
|
|
3
3
|
import { Color } from '@pushwoosh/kit-constants';
|
|
4
4
|
import { Spinner } from '../Spinner';
|
|
5
5
|
import { NativeRichMediaCloseChip } from './components/NativeRichMediaCloseChip';
|
|
6
6
|
import { NativeRichMediaCoverImg } from './components/NativeRichMediaCoverImg';
|
|
7
7
|
import { NativeRichMediaDim } from './components/NativeRichMediaDim';
|
|
8
8
|
import { NativeRichMediaMuteChip } from './components/NativeRichMediaMuteChip';
|
|
9
|
+
import { NativeRichMediaThemeChip } from './components/NativeRichMediaThemeChip';
|
|
9
10
|
import { EDGE_INSET, clampIndex } from './helpers';
|
|
11
|
+
import { mergeNativeDarkOverlay } from './mergeNativeDarkOverlay';
|
|
10
12
|
import { parseNativeRichMediaConfig } from './parseNativeRichMediaConfig';
|
|
11
13
|
import { resolveLocalization } from './resolveLocalization';
|
|
12
14
|
import { BackdropLayer, ContentFlow, PreviewHost, ScaleViewport, ScrollLayer, SpinnerLayer } from './styles';
|
|
@@ -180,6 +182,17 @@ function renderConfig(config, activeIndex) {
|
|
|
180
182
|
* }}
|
|
181
183
|
* />
|
|
182
184
|
*/
|
|
185
|
+
function parseDarkVariant(content, withThemeToggle) {
|
|
186
|
+
if (!withThemeToggle) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
const merged = mergeNativeDarkOverlay(content);
|
|
190
|
+
// The merge hands back `content` itself, untouched, whenever there is nothing to apply.
|
|
191
|
+
if (merged === content) {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
return parseNativeRichMediaConfig(merged);
|
|
195
|
+
}
|
|
183
196
|
export function NativeRichMediaPreview(props) {
|
|
184
197
|
const {
|
|
185
198
|
content,
|
|
@@ -190,15 +203,25 @@ export function NativeRichMediaPreview(props) {
|
|
|
190
203
|
scale = 1,
|
|
191
204
|
activeIndex = 0,
|
|
192
205
|
isLoading = false,
|
|
193
|
-
withBackground = true
|
|
206
|
+
withBackground = true,
|
|
207
|
+
withThemeToggle = false
|
|
194
208
|
} = props;
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
209
|
+
const [theme, setTheme] = useState('light');
|
|
210
|
+
const {
|
|
211
|
+
config,
|
|
212
|
+
isDarkRendered,
|
|
213
|
+
canToggleDark
|
|
214
|
+
} = useMemo(() => {
|
|
215
|
+
const lightParsed = parseNativeRichMediaConfig(content);
|
|
216
|
+
const darkParsed = parseDarkVariant(content, withThemeToggle);
|
|
217
|
+
const themed = theme === 'dark' && darkParsed ? darkParsed : lightParsed;
|
|
218
|
+
const resolved = themed ? parseNativeRichMediaConfig(resolveLocalization(themed, localization, language)) : null;
|
|
219
|
+
return {
|
|
220
|
+
config: resolved,
|
|
221
|
+
isDarkRendered: Boolean(resolved) && theme === 'dark' && darkParsed !== null,
|
|
222
|
+
canToggleDark: darkParsed !== null
|
|
223
|
+
};
|
|
224
|
+
}, [content, localization, language, theme, withThemeToggle]);
|
|
202
225
|
const shouldDim = !isLoading && dimsScreen(config);
|
|
203
226
|
return _jsxs(PreviewHost, {
|
|
204
227
|
...LIGHT_ISLAND_PROPS,
|
|
@@ -215,6 +238,10 @@ export function NativeRichMediaPreview(props) {
|
|
|
215
238
|
children: renderConfig(config, activeIndex)
|
|
216
239
|
})
|
|
217
240
|
}, config.displayType), !isLoading && config && renderChrome(config)]
|
|
241
|
+
}), !isLoading && config && withThemeToggle && _jsx(NativeRichMediaThemeChip, {
|
|
242
|
+
theme: isDarkRendered ? 'dark' : 'light',
|
|
243
|
+
disabled: !canToggleDark,
|
|
244
|
+
onToggle: () => setTheme(theme === 'dark' ? 'light' : 'dark')
|
|
218
245
|
}), isLoading && _jsx(SpinnerLayer, {
|
|
219
246
|
children: _jsx(Spinner, {
|
|
220
247
|
size: "medium",
|
package/NativeRichMediaPreview/components/NativeRichMediaThemeChip/NativeRichMediaThemeChip.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { ThemeToggleChip } from './styles';
|
|
3
|
+
import { MoonIcon, SunIcon } from '../../icons';
|
|
4
|
+
import { useLang } from '../../polyglot';
|
|
5
|
+
export function NativeRichMediaThemeChip(props) {
|
|
6
|
+
const {
|
|
7
|
+
theme,
|
|
8
|
+
disabled,
|
|
9
|
+
onToggle
|
|
10
|
+
} = props;
|
|
11
|
+
const lang = useLang();
|
|
12
|
+
return _jsx(ThemeToggleChip, {
|
|
13
|
+
as: "button",
|
|
14
|
+
type: "button",
|
|
15
|
+
"$bottom": 8,
|
|
16
|
+
"$right": 8,
|
|
17
|
+
disabled: disabled,
|
|
18
|
+
"aria-label": lang({
|
|
19
|
+
message: 'DUMB.NATIVE_RICH_MEDIA_PREVIEW.TOGGLE_THEME'
|
|
20
|
+
}),
|
|
21
|
+
"aria-pressed": theme === 'dark',
|
|
22
|
+
onClick: onToggle,
|
|
23
|
+
children: theme === 'dark' ? _jsx(MoonIcon, {}) : _jsx(SunIcon, {})
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { NativeRichMediaThemeChip } from './NativeRichMediaThemeChip';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { NativeRichMediaThemeChip } from './NativeRichMediaThemeChip';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** `Chip` is a `div`; rendered `as="button"` it needs the UA button chrome stripped or it fights `border-radius: 50%`. */
|
|
2
|
+
export declare const ThemeToggleChip: import("styled-components").StyledComponent<"div", any, {
|
|
3
|
+
$small?: boolean;
|
|
4
|
+
$top?: number;
|
|
5
|
+
$right?: number;
|
|
6
|
+
$bottom?: number;
|
|
7
|
+
$left?: number;
|
|
8
|
+
}, never>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
import { Chip } from '../NativeRichMediaCloseChip';
|
|
3
|
+
/** `Chip` is a `div`; rendered `as="button"` it needs the UA button chrome stripped or it fights `border-radius: 50%`. */
|
|
4
|
+
export const ThemeToggleChip = styled(Chip).withConfig({
|
|
5
|
+
displayName: "ThemeToggleChip",
|
|
6
|
+
componentId: "sc-e7nbqw-0"
|
|
7
|
+
})(["border:none;padding:0;appearance:none;font:inherit;&:disabled{cursor:default;opacity:0.4;}"]);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type NativeRichMediaThemeChipProps = {
|
|
2
|
+
/** Theme actually rendered right now — may lag a click while an overlay applies, or fall back to light. */
|
|
3
|
+
theme: 'light' | 'dark';
|
|
4
|
+
/** Disable when the current content has no dark overlay to switch to. */
|
|
5
|
+
disabled: boolean;
|
|
6
|
+
/** Flip to the other theme. */
|
|
7
|
+
onToggle: () => void;
|
|
8
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none">
|
|
2
|
+
<circle cx="12" cy="12" r="4.5" fill="#fff"/>
|
|
3
|
+
<path d="M12 2v2.5M12 19.5V22M4.22 4.22l1.77 1.77M18.01 18.01l1.77 1.77M2 12h2.5M19.5 12H22M4.22 19.78l1.77-1.77M18.01 5.99l1.77-1.77" stroke="#fff" stroke-width="2" stroke-linecap="round"/>
|
|
4
|
+
</svg>
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { default as CopyIcon } from './CopyIcon.svg';
|
|
2
2
|
export { default as ExpandIcon } from './ExpandIcon.svg';
|
|
3
|
+
export { default as MoonIcon } from './MoonIcon.svg';
|
|
3
4
|
export { default as MutedIcon } from './MutedIcon.svg';
|
|
4
5
|
export { default as ScribbleIcon } from './ScribbleIcon.svg';
|
|
5
6
|
export { default as SoundIcon } from './SoundIcon.svg';
|
|
7
|
+
export { default as SunIcon } from './SunIcon.svg';
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { default as CopyIcon } from './CopyIcon.svg';
|
|
2
2
|
export { default as ExpandIcon } from './ExpandIcon.svg';
|
|
3
|
+
export { default as MoonIcon } from './MoonIcon.svg';
|
|
3
4
|
export { default as MutedIcon } from './MutedIcon.svg';
|
|
4
5
|
export { default as ScribbleIcon } from './ScribbleIcon.svg';
|
|
5
|
-
export { default as SoundIcon } from './SoundIcon.svg';
|
|
6
|
+
export { default as SoundIcon } from './SoundIcon.svg';
|
|
7
|
+
export { default as SunIcon } from './SunIcon.svg';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export type { NativeRichMediaConfig, NativeRichMediaDisplayType, NativeRichMediaText, NativeRichMediaBorder, NativeRichMediaCover, NativeRichMediaAction, NativeRichMediaButton, NativeRichMediaReward, NativeRichMediaModalBlock, NativeRichMediaSheetBlock, NativeRichMediaCarouselBlock, NativeRichMediaStoriesBlock, NativeRichMediaBannerBlock, NativeRichMediaFullscreenBlock, NativeRichMediaVideoBlock, NativeRichMediaPipBlock, NativeRichMediaScratchcardBlock, NativeRichMediaSpinwheelBlock, NativeRichMediaPreviewProps, NativeRichMediaLocalization, } from './types';
|
|
1
|
+
export type { NativeRichMediaConfig, NativeRichMediaDisplayType, NativeRichMediaDarkOverlay, NativeRichMediaText, NativeRichMediaBorder, NativeRichMediaCover, NativeRichMediaAction, NativeRichMediaButton, NativeRichMediaReward, NativeRichMediaModalBlock, NativeRichMediaSheetBlock, NativeRichMediaCarouselBlock, NativeRichMediaStoriesBlock, NativeRichMediaBannerBlock, NativeRichMediaFullscreenBlock, NativeRichMediaVideoBlock, NativeRichMediaPipBlock, NativeRichMediaScratchcardBlock, NativeRichMediaSpinwheelBlock, NativeRichMediaPreviewProps, NativeRichMediaLocalization, } from './types';
|
|
2
2
|
export { NATIVE_RICH_MEDIA_DISPLAY_TYPES, EDITABLE_NATIVE_RICH_MEDIA_DISPLAY_TYPES } from './types';
|
|
3
3
|
export { parseNativeRichMediaConfig } from './parseNativeRichMediaConfig';
|
|
4
4
|
export { parseLocalizationParams } from './parseLocalizationParams';
|
|
5
5
|
export { NativeRichMediaPreview } from './NativeRichMediaPreview';
|
|
6
|
+
export { mergeNativeDarkOverlay } from './mergeNativeDarkOverlay';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { NATIVE_RICH_MEDIA_DISPLAY_TYPES, EDITABLE_NATIVE_RICH_MEDIA_DISPLAY_TYPES } from './types';
|
|
2
2
|
export { parseNativeRichMediaConfig } from './parseNativeRichMediaConfig';
|
|
3
3
|
export { parseLocalizationParams } from './parseLocalizationParams';
|
|
4
|
-
export { NativeRichMediaPreview } from './NativeRichMediaPreview';
|
|
4
|
+
export { NativeRichMediaPreview } from './NativeRichMediaPreview';
|
|
5
|
+
export { mergeNativeDarkOverlay } from './mergeNativeDarkOverlay';
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { NativeRichMediaConfig } from './types';
|
|
2
|
+
/** Applies a config's `dark` overlay onto its display block ahead of strict parsing, since the light block may only become valid once the overlay lands; any break returns the input untouched. */
|
|
3
|
+
export declare function mergeNativeDarkOverlay(content: string | NativeRichMediaConfig): string | NativeRichMediaConfig;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { isObject } from './helpers';
|
|
2
|
+
/** Leaves a theme may replace: everything else is content, not appearance. */
|
|
3
|
+
const VISUAL_LEAF_KEYS = new Set(['background', 'color', 'image', 'poster', 'fallback']);
|
|
4
|
+
/** The only arrays that merge; both sides must line up element for element. */
|
|
5
|
+
const POSITIONAL_ARRAY_KEYS = new Set(['buttons', 'items']);
|
|
6
|
+
function overlayOnto(light, dark) {
|
|
7
|
+
const merged = {
|
|
8
|
+
...light
|
|
9
|
+
};
|
|
10
|
+
for (const key of Object.keys(dark)) {
|
|
11
|
+
const darkValue = dark[key];
|
|
12
|
+
const lightValue = light[key];
|
|
13
|
+
if (darkValue === null || darkValue === undefined) {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (POSITIONAL_ARRAY_KEYS.has(key)) {
|
|
17
|
+
if (!Array.isArray(darkValue) || !Array.isArray(lightValue)) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
if (darkValue.length !== lightValue.length) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
const items = [];
|
|
24
|
+
for (let i = 0; i < darkValue.length; i += 1) {
|
|
25
|
+
const darkItem = darkValue[i];
|
|
26
|
+
const lightItem = lightValue[i];
|
|
27
|
+
if (!isObject(darkItem) || !isObject(lightItem)) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const mergedItem = overlayOnto(lightItem, darkItem);
|
|
31
|
+
if (!mergedItem) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
items.push(mergedItem);
|
|
35
|
+
}
|
|
36
|
+
merged[key] = items;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (isObject(lightValue)) {
|
|
40
|
+
if (isObject(darkValue)) {
|
|
41
|
+
const mergedChild = overlayOnto(lightValue, darkValue);
|
|
42
|
+
if (!mergedChild) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
merged[key] = mergedChild;
|
|
46
|
+
}
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (VISUAL_LEAF_KEYS.has(key)) {
|
|
50
|
+
merged[key] = Array.isArray(darkValue) ? [...darkValue] : darkValue;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return merged;
|
|
54
|
+
}
|
|
55
|
+
/** Applies a config's `dark` overlay onto its display block ahead of strict parsing, since the light block may only become valid once the overlay lands; any break returns the input untouched. */
|
|
56
|
+
export function mergeNativeDarkOverlay(content) {
|
|
57
|
+
let raw = content;
|
|
58
|
+
if (typeof content === 'string') {
|
|
59
|
+
try {
|
|
60
|
+
raw = JSON.parse(content);
|
|
61
|
+
} catch {
|
|
62
|
+
return content;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (!isObject(raw)) {
|
|
66
|
+
return content;
|
|
67
|
+
}
|
|
68
|
+
const displayType = raw.displayType;
|
|
69
|
+
if (typeof displayType !== 'string') {
|
|
70
|
+
return content;
|
|
71
|
+
}
|
|
72
|
+
const block = raw[displayType];
|
|
73
|
+
if (!isObject(block)) {
|
|
74
|
+
return content;
|
|
75
|
+
}
|
|
76
|
+
const overlay = block.dark;
|
|
77
|
+
if (!isObject(overlay)) {
|
|
78
|
+
return content;
|
|
79
|
+
}
|
|
80
|
+
const merged = overlayOnto(block, overlay);
|
|
81
|
+
if (!merged) {
|
|
82
|
+
return content;
|
|
83
|
+
}
|
|
84
|
+
delete merged.dark;
|
|
85
|
+
return {
|
|
86
|
+
...raw,
|
|
87
|
+
[displayType]: merged
|
|
88
|
+
};
|
|
89
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const messages = {
|
|
2
2
|
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.INVALID_CONFIG': 'تكوين rich media غير صالح',
|
|
3
|
-
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'اكشط هنا'
|
|
3
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'اكشط هنا',
|
|
4
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.TOGGLE_THEME': 'تبديل الوضع الفاتح والداكن'
|
|
4
5
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const messages = {
|
|
2
2
|
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.INVALID_CONFIG': 'অবৈধ rich media কনফিগারেশন',
|
|
3
|
-
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'এখানে ঘষুন'
|
|
3
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'এখানে ঘষুন',
|
|
4
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.TOGGLE_THEME': 'হালকা এবং গাঢ় থিমের মধ্যে পরিবর্তন করুন'
|
|
4
5
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const messages = {
|
|
2
2
|
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.INVALID_CONFIG': 'Ungültige Rich-Media-Konfiguration',
|
|
3
|
-
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'Hier freirubbeln'
|
|
3
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'Hier freirubbeln',
|
|
4
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.TOGGLE_THEME': 'Zwischen hellem und dunklem Design wechseln'
|
|
4
5
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const messages = {
|
|
2
2
|
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.INVALID_CONFIG': 'Invalid rich media config',
|
|
3
|
-
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'Scratch here'
|
|
3
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'Scratch here',
|
|
4
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.TOGGLE_THEME': 'Switch light and dark'
|
|
4
5
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const messages = {
|
|
2
2
|
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.INVALID_CONFIG': 'Configuración de rich media no válida',
|
|
3
|
-
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'Rasca aquí'
|
|
3
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'Rasca aquí',
|
|
4
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.TOGGLE_THEME': 'Cambiar entre claro y oscuro'
|
|
4
5
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const messages = {
|
|
2
2
|
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.INVALID_CONFIG': 'Configuration rich media non valide',
|
|
3
|
-
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'Grattez ici'
|
|
3
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'Grattez ici',
|
|
4
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.TOGGLE_THEME': 'Basculer entre clair et sombre'
|
|
4
5
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const messages = {
|
|
2
2
|
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.INVALID_CONFIG': 'תצורת rich media לא חוקית',
|
|
3
|
-
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'גרדו כאן'
|
|
3
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'גרדו כאן',
|
|
4
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.TOGGLE_THEME': 'החלף בין ערכת נושא בהירה לכהה'
|
|
4
5
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const messages = {
|
|
2
2
|
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.INVALID_CONFIG': 'अमान्य rich media कॉन्फ़िगरेशन',
|
|
3
|
-
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'यहाँ खरोंचें'
|
|
3
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'यहाँ खरोंचें',
|
|
4
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.TOGGLE_THEME': 'लाइट और डार्क थीम के बीच स्विच करें'
|
|
4
5
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const messages = {
|
|
2
2
|
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.INVALID_CONFIG': 'リッチメディア設定が無効です',
|
|
3
|
-
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'ここを削ってください'
|
|
3
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'ここを削ってください',
|
|
4
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.TOGGLE_THEME': 'ライトとダークを切り替える'
|
|
4
5
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const messages = {
|
|
2
2
|
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.INVALID_CONFIG': '리치 미디어 구성이 잘못되었습니다',
|
|
3
|
-
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': '여기를 긁어보세요'
|
|
3
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': '여기를 긁어보세요',
|
|
4
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.TOGGLE_THEME': '라이트와 다크 테마 전환'
|
|
4
5
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const messages = {
|
|
2
2
|
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.INVALID_CONFIG': 'Configuração de rich media inválida',
|
|
3
|
-
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'Raspe aqui'
|
|
3
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'Raspe aqui',
|
|
4
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.TOGGLE_THEME': 'Alternar entre claro e escuro'
|
|
4
5
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const messages = {
|
|
2
2
|
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.INVALID_CONFIG': 'Некорректная конфигурация rich media',
|
|
3
|
-
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'Сотрите здесь'
|
|
3
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'Сотрите здесь',
|
|
4
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.TOGGLE_THEME': 'Переключить светлую и тёмную тему'
|
|
4
5
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const messages = {
|
|
2
2
|
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.INVALID_CONFIG': 'การกำหนดค่า rich media ไม่ถูกต้อง',
|
|
3
|
-
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'ขูดที่นี่'
|
|
3
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': 'ขูดที่นี่',
|
|
4
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.TOGGLE_THEME': 'สลับธีมสว่างและมืด'
|
|
4
5
|
};
|
|
@@ -2,4 +2,5 @@ import type { NoParams } from '../../polyglot';
|
|
|
2
2
|
export type NativeRichMediaPreviewMessages = {
|
|
3
3
|
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.INVALID_CONFIG': NoParams;
|
|
4
4
|
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.SCRATCH_HERE': NoParams;
|
|
5
|
+
'DUMB.NATIVE_RICH_MEDIA_PREVIEW.TOGGLE_THEME': NoParams;
|
|
5
6
|
};
|
|
@@ -50,6 +50,10 @@ export type NativeRichMediaReward = {
|
|
|
50
50
|
/** Confirmation button, including its own tap action. */
|
|
51
51
|
button?: NativeRichMediaButton;
|
|
52
52
|
};
|
|
53
|
+
/** Sparse dark overlay over a display block: visual leaves replace, objects merge recursively, `buttons`/`items` positionally; typed loosely because the shape is checked at merge time. */
|
|
54
|
+
export type NativeRichMediaDarkOverlay = {
|
|
55
|
+
[key: string]: string | string[] | NativeRichMediaDarkOverlay | NativeRichMediaDarkOverlay[] | undefined;
|
|
56
|
+
};
|
|
53
57
|
/** Content of a `banner` rich media. */
|
|
54
58
|
export type NativeRichMediaBannerBlock = {
|
|
55
59
|
/** Show a close (✕) chip. */
|
|
@@ -68,6 +72,8 @@ export type NativeRichMediaBannerBlock = {
|
|
|
68
72
|
action: NativeRichMediaAction;
|
|
69
73
|
/** Auto-dismiss timeout in seconds; omit to keep the banner until closed. */
|
|
70
74
|
autoDismiss?: number;
|
|
75
|
+
/** Dark-theme overlay merged over this block when the dark variant is shown. */
|
|
76
|
+
dark?: NativeRichMediaDarkOverlay;
|
|
71
77
|
};
|
|
72
78
|
/** Content of a `carousel` rich media. */
|
|
73
79
|
export type NativeRichMediaCarouselBlock = {
|
|
@@ -84,6 +90,8 @@ export type NativeRichMediaCarouselBlock = {
|
|
|
84
90
|
/** Tap action of the card. */
|
|
85
91
|
action?: NativeRichMediaAction;
|
|
86
92
|
}>;
|
|
93
|
+
/** Dark-theme overlay merged over this block when the dark variant is shown. */
|
|
94
|
+
dark?: NativeRichMediaDarkOverlay;
|
|
87
95
|
};
|
|
88
96
|
/** Content of a `modal` rich media. */
|
|
89
97
|
export type NativeRichMediaModalBlock = {
|
|
@@ -101,6 +109,8 @@ export type NativeRichMediaModalBlock = {
|
|
|
101
109
|
message?: NativeRichMediaText;
|
|
102
110
|
/** Action buttons under the message. */
|
|
103
111
|
buttons: Array<NativeRichMediaButton>;
|
|
112
|
+
/** Dark-theme overlay merged over this block when the dark variant is shown. */
|
|
113
|
+
dark?: NativeRichMediaDarkOverlay;
|
|
104
114
|
};
|
|
105
115
|
/** Content of a `sheet` rich media. */
|
|
106
116
|
export type NativeRichMediaSheetBlock = {
|
|
@@ -118,6 +128,8 @@ export type NativeRichMediaSheetBlock = {
|
|
|
118
128
|
message?: NativeRichMediaText;
|
|
119
129
|
/** Action buttons under the message. */
|
|
120
130
|
buttons: Array<NativeRichMediaButton>;
|
|
131
|
+
/** Dark-theme overlay merged over this block when the dark variant is shown. */
|
|
132
|
+
dark?: NativeRichMediaDarkOverlay;
|
|
121
133
|
};
|
|
122
134
|
/** Content of a `stories` rich media. */
|
|
123
135
|
export type NativeRichMediaStoriesBlock = {
|
|
@@ -138,6 +150,8 @@ export type NativeRichMediaStoriesBlock = {
|
|
|
138
150
|
/** Slide duration in seconds (SDK: default 5, max 30). */
|
|
139
151
|
duration: number;
|
|
140
152
|
}>;
|
|
153
|
+
/** Dark-theme overlay merged over this block when the dark variant is shown. */
|
|
154
|
+
dark?: NativeRichMediaDarkOverlay;
|
|
141
155
|
};
|
|
142
156
|
/** Content of a `fullscreen` rich media. */
|
|
143
157
|
export type NativeRichMediaFullscreenBlock = {
|
|
@@ -151,6 +165,8 @@ export type NativeRichMediaFullscreenBlock = {
|
|
|
151
165
|
message?: NativeRichMediaText;
|
|
152
166
|
/** Action buttons at the bottom. */
|
|
153
167
|
buttons: Array<NativeRichMediaButton>;
|
|
168
|
+
/** Dark-theme overlay merged over this block when the dark variant is shown. */
|
|
169
|
+
dark?: NativeRichMediaDarkOverlay;
|
|
154
170
|
};
|
|
155
171
|
/** Content of a `video` rich media. */
|
|
156
172
|
export type NativeRichMediaVideoBlock = {
|
|
@@ -172,6 +188,8 @@ export type NativeRichMediaVideoBlock = {
|
|
|
172
188
|
fallback?: string;
|
|
173
189
|
/** Action buttons at the bottom. */
|
|
174
190
|
buttons: Array<NativeRichMediaButton>;
|
|
191
|
+
/** Dark-theme overlay merged over this block when the dark variant is shown. */
|
|
192
|
+
dark?: NativeRichMediaDarkOverlay;
|
|
175
193
|
};
|
|
176
194
|
/** Content of a `pip` (picture-in-picture) rich media. */
|
|
177
195
|
export type NativeRichMediaPipBlock = {
|
|
@@ -197,6 +215,8 @@ export type NativeRichMediaPipBlock = {
|
|
|
197
215
|
borderRadius?: number;
|
|
198
216
|
/** Tap action of the pip window itself. */
|
|
199
217
|
action?: NativeRichMediaAction;
|
|
218
|
+
/** Dark-theme overlay merged over this block when the dark variant is shown. */
|
|
219
|
+
dark?: NativeRichMediaDarkOverlay;
|
|
200
220
|
};
|
|
201
221
|
/** Content of a `scratchcard` rich media. */
|
|
202
222
|
export type NativeRichMediaScratchcardBlock = {
|
|
@@ -216,6 +236,8 @@ export type NativeRichMediaScratchcardBlock = {
|
|
|
216
236
|
message?: NativeRichMediaText;
|
|
217
237
|
/** Reward revealed under the cover; required by the SDK, may be absent in a draft. */
|
|
218
238
|
reward?: NativeRichMediaReward;
|
|
239
|
+
/** Dark-theme overlay merged over this block when the dark variant is shown. */
|
|
240
|
+
dark?: NativeRichMediaDarkOverlay;
|
|
219
241
|
};
|
|
220
242
|
/** Content of a `spinwheel` rich media. */
|
|
221
243
|
export type NativeRichMediaSpinwheelBlock = {
|
|
@@ -246,6 +268,8 @@ export type NativeRichMediaSpinwheelBlock = {
|
|
|
246
268
|
/** Reward granted when the wheel stops on this sector. */
|
|
247
269
|
reward?: NativeRichMediaReward;
|
|
248
270
|
}>;
|
|
271
|
+
/** Dark-theme overlay merged over this block when the dark variant is shown. */
|
|
272
|
+
dark?: NativeRichMediaDarkOverlay;
|
|
249
273
|
};
|
|
250
274
|
/** Native rich media config: a display type and the matching content block. */
|
|
251
275
|
export type NativeRichMediaConfig = {
|
|
@@ -315,4 +339,6 @@ export type NativeRichMediaPreviewProps = {
|
|
|
315
339
|
isLoading?: boolean;
|
|
316
340
|
/** Render the container chrome — white backdrop and border (default `true`). Set `false` for a transparent preview over the consumer's own background. */
|
|
317
341
|
withBackground?: boolean;
|
|
342
|
+
/** Show a chip that switches the preview between the light and dark variants (default `false`). The preview always opens light. */
|
|
343
|
+
withThemeToggle?: boolean;
|
|
318
344
|
};
|
package/index.d.ts
CHANGED
|
@@ -50,7 +50,7 @@ export { Chip, type ChipProps, type ChipVariant } from './Chip';
|
|
|
50
50
|
export { RichmediaPreview, useRichmediaHtml } from './RichmediaPreview';
|
|
51
51
|
export { SandboxedHtmlFrame, type SandboxedHtmlFrameProps, type IsolatedSandboxedHtmlFrameProps, type InspectableSandboxedHtmlFrameProps, } from './SandboxedHtmlFrame';
|
|
52
52
|
export { NativeRichMediaPreview, parseNativeRichMediaConfig, parseLocalizationParams, NATIVE_RICH_MEDIA_DISPLAY_TYPES, EDITABLE_NATIVE_RICH_MEDIA_DISPLAY_TYPES, } from './NativeRichMediaPreview';
|
|
53
|
-
export type { NativeRichMediaConfig, NativeRichMediaDisplayType, NativeRichMediaText, NativeRichMediaBorder, NativeRichMediaCover, NativeRichMediaAction, NativeRichMediaButton, NativeRichMediaReward, NativeRichMediaModalBlock, NativeRichMediaSheetBlock, NativeRichMediaCarouselBlock, NativeRichMediaStoriesBlock, NativeRichMediaBannerBlock, NativeRichMediaFullscreenBlock, NativeRichMediaVideoBlock, NativeRichMediaPipBlock, NativeRichMediaScratchcardBlock, NativeRichMediaSpinwheelBlock, NativeRichMediaPreviewProps, NativeRichMediaLocalization, } from './NativeRichMediaPreview';
|
|
53
|
+
export type { NativeRichMediaConfig, NativeRichMediaDisplayType, NativeRichMediaText, NativeRichMediaBorder, NativeRichMediaCover, NativeRichMediaAction, NativeRichMediaButton, NativeRichMediaReward, NativeRichMediaDarkOverlay, NativeRichMediaModalBlock, NativeRichMediaSheetBlock, NativeRichMediaCarouselBlock, NativeRichMediaStoriesBlock, NativeRichMediaBannerBlock, NativeRichMediaFullscreenBlock, NativeRichMediaVideoBlock, NativeRichMediaPipBlock, NativeRichMediaScratchcardBlock, NativeRichMediaSpinwheelBlock, NativeRichMediaPreviewProps, NativeRichMediaLocalization, } from './NativeRichMediaPreview';
|
|
54
54
|
export { RichMessageEditor, RichMessageViewer, type DynamicContent, } from './RichMessageEditor';
|
|
55
55
|
export { FrequencyCappingEdit, FrequencyCappingReadonly, FrequencyCappingInApps, CappingCountingMode, CountingMode, type CountingModeProps, type LocalCapping, type CappingInAppBase, } from './FrequencyCapping';
|
|
56
56
|
export { SendRateEdit, SendRateReadonly, type SendRateBase, type SendRateEditProps, type SendRateReadonlyProps, } from './SendRate';
|