@pushwoosh/websdk-common 6.18.0 → 6.19.0

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.
@@ -0,0 +1,546 @@
1
+ /** The sending pipeline and the editor keep at most this many carousel slides. */
2
+ export const INBOX_MAX_CAROUSEL_SLIDES = 5;
3
+ /** Layouts a cell can draw; anything else falls back to the heuristic. */
4
+ export const INBOX_KNOWN_LAYOUTS = ['classic', 'captioned', 'banner', 'carousel'];
5
+ /** Prefix of the widget's CSS custom properties: `--pw-inbox-<name>`, a public API customers override from their CSS. */
6
+ export const INBOX_WIDGET_STYLE_PREFIX = 'pw-inbox';
7
+ /** Month labels of the absolute message dates. */
8
+ export const INBOX_MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'];
9
+ /** Appearance values exposed as CSS custom properties, with their formatting. */
10
+ export const INBOX_WIDGET_STYLE_VARIABLES = [{
11
+ name: 'widgetWidth',
12
+ type: 'size'
13
+ }, {
14
+ name: 'borderRadius',
15
+ type: 'size'
16
+ }, {
17
+ name: 'zIndex',
18
+ type: 'number'
19
+ }, {
20
+ name: 'fontFamily',
21
+ type: 'string'
22
+ }, {
23
+ name: 'bgColor',
24
+ type: 'color'
25
+ }, {
26
+ name: 'textColor',
27
+ type: 'color'
28
+ }, {
29
+ name: 'arrowBorderColor',
30
+ type: 'color'
31
+ }, {
32
+ name: 'borderColor',
33
+ type: 'color'
34
+ }, {
35
+ name: 'badgeBgColor',
36
+ type: 'color'
37
+ }, {
38
+ name: 'badgeTextColor',
39
+ type: 'color'
40
+ }, {
41
+ name: 'timeTextColor',
42
+ type: 'color'
43
+ }, {
44
+ name: 'messageTitleColor',
45
+ type: 'color'
46
+ }, {
47
+ name: 'emptyInboxTitleColor',
48
+ type: 'color'
49
+ }, {
50
+ name: 'emptyInboxTextColor',
51
+ type: 'color'
52
+ }, {
53
+ name: 'unreadDotColor',
54
+ type: 'color'
55
+ }, {
56
+ name: 'avatarBgColor',
57
+ type: 'color'
58
+ }, {
59
+ name: 'avatarTextColor',
60
+ type: 'color'
61
+ }, {
62
+ name: 'avatarSize',
63
+ type: 'size'
64
+ }, {
65
+ name: 'mediaRadius',
66
+ type: 'size'
67
+ }, {
68
+ name: 'slideCaptionColor',
69
+ type: 'color'
70
+ }, {
71
+ name: 'slideScrimColor',
72
+ type: 'color'
73
+ }, {
74
+ name: 'pagerDotActiveColor',
75
+ type: 'color'
76
+ }, {
77
+ name: 'pagerDotColor',
78
+ type: 'color'
79
+ }];
80
+ /** Default appearance of the web inbox widget. */
81
+ export const INBOX_WIDGET_DEFAULT_APPEARANCE = {
82
+ title: 'Inbox',
83
+ bgColor: '#ffffff',
84
+ textColor: '#333333',
85
+ fontFamily: 'inherit',
86
+ borderRadius: 4,
87
+ borderColor: 'transparent',
88
+ badgeBgColor: '#ff4c00',
89
+ badgeTextColor: '#ffffff',
90
+ widgetWidth: 350,
91
+ zIndex: 100,
92
+ messageTitleColor: '#7a7a7a',
93
+ timeTextColor: '#c4c4c4',
94
+ emptyInboxTitle: 'You\'re all caught up',
95
+ emptyInboxTitleColor: '#333333',
96
+ emptyInboxText: 'There are no new messages. Stay tuned!',
97
+ emptyInboxTextColor: '#7a7a7a',
98
+ emptyInboxIconUrl: 'https://pushon.pushwoosh.com/static/icon-empty-inbox.png',
99
+ arrowBorderColor: 'rgba(0,0,0,.1)',
100
+ legacyClassicCell: false,
101
+ unreadDotColor: '#00a2ff',
102
+ avatarBgColor: '#c4c8cc',
103
+ avatarTextColor: '#4b5057',
104
+ avatarSize: 52,
105
+ mediaRadius: 8,
106
+ slideCaptionColor: '#ffffff',
107
+ slideScrimColor: 'rgba(0,0,0,.45)',
108
+ pagerDotActiveColor: '#00a2ff',
109
+ pagerDotColor: '#ebf0f5'
110
+ };
111
+ /** Stylesheet of the web inbox widget and its trigger badge; class names and custom properties are public API. */
112
+ export const INBOX_WIDGET_CSS = `
113
+ .pw-inbox-trigger {
114
+ position: relative;
115
+ cursor: pointer;
116
+ }
117
+
118
+ .pw-inbox-trigger:after {
119
+ content: attr(data-pw-count);
120
+ display: block;
121
+ position: absolute;
122
+ right: 0;
123
+ top: 0;
124
+ background: var(--pw-inbox-badgeBgColor, #ff4c00);
125
+ border-radius: 8px;
126
+ color: var(--pw-inbox-badgeTextColor, #ffffff);
127
+ font-size: 10px;
128
+ font-weight: normal;
129
+ line-height: 16px;
130
+ width: 16px;
131
+ padding: 0 2px;
132
+ box-sizing: border-box;
133
+ text-align: center;
134
+ }
135
+
136
+ .pw-inbox-trigger.pw-empty:after {
137
+ display: none;
138
+ }
139
+
140
+ .pw-inbox-widget * {
141
+ position: static;
142
+ box-sizing: border-box;
143
+ font-size: 1em;
144
+ outline: none;
145
+ font-family: var(--pw-inbox-fontFamily, inherit);
146
+ }
147
+ .pw-inbox-widget {
148
+ font-size: 14px;
149
+ position: absolute;
150
+ top: 0;
151
+ left: -1000px;
152
+ background: var(--pw-inbox-bgColor, #ffffff);
153
+ border: solid 1px var(--pw-inbox-borderColor, transparent);
154
+ border-radius: var(--pw-inbox-borderRadius, 4px);
155
+ width: var(--pw-inbox-widgetWidth, 350px);
156
+ box-shadow: 0 1px 4px 0 rgba(0,0,0,.25);
157
+ z-index: var(--pw-inbox-zIndex, 100);
158
+ opacity: 0;
159
+ transition: opacity .6s ease;
160
+ transition-delay: 100ms;
161
+ }
162
+ .pw-inbox-widget.pw-open {
163
+ opacity: 1;
164
+ transition-delay: 0ms;
165
+ }
166
+ .pw-inbox-widget.pw-inbox-widget--inset {
167
+ top: auto;
168
+ left: auto;
169
+ display: none;
170
+ }
171
+ .pw-inbox-widget.pw-inbox-widget--inset.pw-open {
172
+ display: block;
173
+ }
174
+ .pw-inbox-widget.pw-inbox-widget--inset.pw-bottom {
175
+ top: 100%;
176
+ left: 50%;
177
+ transform: translateX(-50%);
178
+ }
179
+ .pw-inbox-widget.pw-inbox-widget--inset.pw-top {
180
+ bottom: 100%;
181
+ left: 50%;
182
+ transform: translateX(-50%);
183
+ }
184
+ .pw-inbox-widget.pw-inbox-widget--inset.pw-right {
185
+ left: 100%;
186
+ top: 50%;
187
+ transform: translateY(-50%);
188
+ }
189
+ .pw-inbox-widget.pw-inbox-widget--inset.pw-left {
190
+ right: 100%;
191
+ top: 50%;
192
+ transform: translateY(-50%);
193
+ }
194
+ .pw-inbox-widget.pw-inbox-widget--empty {
195
+ max-height: none;
196
+ }
197
+ .pw-inbox-widget .pw-inbox__arrow {
198
+ display: block;
199
+ width: 0;
200
+ height: 0;
201
+ border-width: 10px;
202
+ border-style: solid;
203
+ border-color: transparent;
204
+ position: absolute;
205
+ }
206
+ .pw-inbox-widget .pw-inbox__arrow:before {
207
+ content: "";
208
+ display: block;
209
+ width: 0;
210
+ height: 0;
211
+ border-width: 10px;
212
+ border-style: solid;
213
+ border-color: transparent;
214
+ position: absolute;
215
+ }
216
+ .pw-inbox-widget.pw-top {
217
+ margin-top: -12px;
218
+ }
219
+ .pw-inbox-widget.pw-top .pw-inbox__arrow {
220
+ border-top-color: var(--pw-inbox-arrowBorderColor, rgba(0,0,0,.1));
221
+ bottom: -21px;
222
+ left: 50%;
223
+ transform: translateX(-50%);
224
+ }
225
+ .pw-inbox-widget.pw-top .pw-inbox__arrow:before {
226
+ border-top-color: var(--pw-inbox-bgColor, #ffffff);
227
+ top: -11px;
228
+ left: -10px;
229
+ }
230
+ .pw-inbox-widget.pw-bottom {
231
+ margin-top: 12px;
232
+ }
233
+ .pw-inbox-widget.pw-bottom .pw-inbox__arrow {
234
+ border-bottom-color: var(--pw-inbox-arrowBorderColor, rgba(0,0,0,.1));
235
+ top: -21px;
236
+ left: 50%;
237
+ transform: translateX(-50%);
238
+ }
239
+ .pw-inbox-widget.pw-bottom .pw-inbox__arrow:before {
240
+ border-bottom-color: var(--pw-inbox-bgColor, #ffffff);
241
+ bottom: -11px;
242
+ left: -10px;
243
+ }
244
+ .pw-inbox-widget.pw-left {
245
+ margin-left: -12px;
246
+ }
247
+ .pw-inbox-widget.pw-left .pw-inbox__arrow {
248
+ border-left-color: var(--pw-inbox-arrowBorderColor, rgba(0,0,0,.1));
249
+ right: -21px;
250
+ top: 50%;
251
+ transform: translateY(-50%);
252
+ }
253
+ .pw-inbox-widget.pw-left .pw-inbox__arrow:before {
254
+ border-left-color: var(--pw-inbox-bgColor, #ffffff);
255
+ left: -11px;
256
+ top: -10px;
257
+ }
258
+ .pw-inbox-widget.pw-right {
259
+ margin-left: 12px;
260
+ }
261
+ .pw-inbox-widget.pw-right .pw-inbox__arrow {
262
+ border-right-color: var(--pw-inbox-arrowBorderColor, rgba(0,0,0,.1));
263
+ left: -21px;
264
+ top: 50%;
265
+ transform: translateY(-50%);
266
+ }
267
+ .pw-inbox-widget.pw-right .pw-inbox__arrow:before {
268
+ border-right-color: var(--pw-inbox-bgColor, #ffffff);
269
+ right: -11px;
270
+ top: -10px;
271
+ }
272
+ .pw-inbox_inner {
273
+ overflow: hidden;
274
+ display: flex;
275
+ flex-direction: column;
276
+ height: 100%;
277
+ }
278
+ .pw-inbox_title {
279
+ color: var(--pw-inbox-textColor, #333333);
280
+ margin: 0;
281
+ padding: 28px 32px 12px;
282
+ font-size: 24px;
283
+ font-weight: 500;
284
+ line-height: 1.1;
285
+ text-align: left;
286
+ flex: 0 0 66px;
287
+ }
288
+ .pw-inbox_list {
289
+ overflow-x: hidden;
290
+ overflow-y: auto;
291
+ min-width: 200px;
292
+ max-height: 300px;
293
+ padding: 0;
294
+ margin: 0;
295
+ list-style: none;
296
+ position: relative;
297
+ flex: 1 1 auto;
298
+ }
299
+
300
+ .pw-inbox_item {
301
+ position: relative;
302
+ padding: 8px 32px;
303
+ margin: 0;
304
+ text-align: left;
305
+ }
306
+ .pw-inbox_item-inner {
307
+ display: flex;
308
+ cursor: pointer;
309
+ }
310
+ .pw-inbox_icon {
311
+ flex: 0 0 auto;
312
+ width: var(--pw-inbox-avatarSize, 52px);
313
+ height: var(--pw-inbox-avatarSize, 52px);
314
+ margin-right: 14px;
315
+ overflow: hidden;
316
+ border-radius: var(--pw-inbox-mediaRadius, 8px);
317
+ background: var(--pw-inbox-avatarBgColor, #c4c8cc);
318
+ display: flex;
319
+ align-items: center;
320
+ justify-content: center;
321
+ }
322
+ .pw-inbox_message-image {
323
+ width: 100%;
324
+ height: 100%;
325
+ object-fit: cover;
326
+ display: block;
327
+ }
328
+ .pw-inbox_icon-initial {
329
+ color: var(--pw-inbox-avatarTextColor, #4b5057);
330
+ font-size: 22px;
331
+ line-height: 1;
332
+ font-weight: 700;
333
+ }
334
+ .pw-inbox_content {
335
+ flex: 1 1 auto;
336
+ min-width: 0;
337
+ }
338
+ .pw-inbox_item-title {
339
+ color: var(--pw-inbox-messageTitleColor, #7a7a7a);
340
+ font-size: 14px;
341
+ line-height: 20px;
342
+ margin-bottom: 4px;
343
+ display: flex;
344
+ align-items: center;
345
+ gap: 6px;
346
+ overflow: hidden;
347
+ text-overflow: ellipsis;
348
+ white-space: nowrap;
349
+ }
350
+ .pw-inbox_unread-dot {
351
+ flex: 0 0 auto;
352
+ width: 6px;
353
+ height: 6px;
354
+ border-radius: 50%;
355
+ background: var(--pw-inbox-unreadDotColor, #00a2ff);
356
+ }
357
+ .pw-inbox_item-body {
358
+ color: var(--pw-inbox-textColor, #333333);
359
+ font-size: 14px;
360
+ line-height: 20px;
361
+ margin-bottom: 4px;
362
+ display: -webkit-box;
363
+ -webkit-line-clamp: 2;
364
+ -webkit-box-orient: vertical;
365
+ overflow: hidden;
366
+ }
367
+ .pw-inbox_item-time {
368
+ color: var(--pw-inbox-timeTextColor, #c4c4c4);
369
+ font-size: 12px;
370
+ line-height: 17px;
371
+ }
372
+ .pw-inbox_item-remove {
373
+ position: absolute;
374
+ z-index: 2;
375
+ top: 8px;
376
+ right: 8px;
377
+ display: none;
378
+ width: 10px;
379
+ height: 10px;
380
+ background: transparent url('https://cdn.pushwoosh.com/webpush/img/iconClose.svg') 50% no-repeat;
381
+ cursor: pointer;
382
+ }
383
+ .pw-inbox_item:hover .pw-inbox_item-remove {
384
+ display: block;
385
+ }
386
+
387
+ .pw-inbox_item.pw-new .pw-inbox_item-title {
388
+ color: var(--pw-inbox-textColor, #333333);
389
+ font-weight: 700;
390
+ }
391
+
392
+ .pw-inbox_item.pw-new .pw-inbox_item-body {
393
+ font-weight: 700;
394
+ }
395
+
396
+ .pw-inbox_list--empty {
397
+ padding: 50px 16px;
398
+ text-align: center;
399
+ max-height: 100%;
400
+ overflow: auto;
401
+ }
402
+
403
+ .pw-inbox_list--empty .pw-inbox_list-icon {
404
+ text-align: center;
405
+ margin-bottom: 30px;
406
+ }
407
+ .pw-inbox_list--empty .pw-inbox_list-icon img {
408
+ max-width: 100%;
409
+ }
410
+
411
+ .pw-inbox_list--empty .pw-inbox_list-title {
412
+ font-size: 28px;
413
+ line-height: 36px;
414
+ color: var(--pw-inbox-emptyInboxTitleColor, #333333);
415
+ margin-bottom: 20px;
416
+ }
417
+
418
+ .pw-inbox_list--empty .ipw-inbox_list-body {
419
+ font-size: 14px;
420
+ line-height: 18px;
421
+ color: var(--pw-inbox-emptyInboxTextColor, #7a7a7a);
422
+ }
423
+
424
+ /* Cell layouts: banner, captioned and carousel stack their media above the
425
+ texts, so the flex row of the classic cell becomes a column. */
426
+ .pw-inbox_item--banner,
427
+ .pw-inbox_item--captioned,
428
+ .pw-inbox_item--carousel {
429
+ flex-direction: column;
430
+ gap: 12px;
431
+ }
432
+
433
+ .pw-inbox_media {
434
+ position: relative;
435
+ width: 100%;
436
+ }
437
+ .pw-inbox_hero {
438
+ display: block;
439
+ width: 100%;
440
+ max-width: 100%;
441
+ aspect-ratio: 2 / 1;
442
+ object-fit: cover;
443
+ border-radius: var(--pw-inbox-mediaRadius, 8px);
444
+ }
445
+
446
+ .pw-inbox_slide {
447
+ position: relative;
448
+ display: block;
449
+ cursor: pointer;
450
+ }
451
+ .pw-inbox_slide-caption {
452
+ position: absolute;
453
+ left: 0;
454
+ right: 0;
455
+ bottom: 0;
456
+ padding: 14px 10px 6px;
457
+ color: var(--pw-inbox-slideCaptionColor, #ffffff);
458
+ font-size: 14px;
459
+ line-height: 20px;
460
+ border-radius: 0 0 var(--pw-inbox-mediaRadius, 8px) var(--pw-inbox-mediaRadius, 8px);
461
+ background: linear-gradient(transparent, var(--pw-inbox-slideScrimColor, rgba(0,0,0,.45)));
462
+ display: -webkit-box;
463
+ -webkit-line-clamp: 2;
464
+ -webkit-box-orient: vertical;
465
+ overflow: hidden;
466
+ }
467
+
468
+ .pw-inbox_pager {
469
+ position: absolute;
470
+ left: 0;
471
+ right: 0;
472
+ bottom: 8px;
473
+ display: flex;
474
+ align-items: center;
475
+ justify-content: center;
476
+ gap: 6px;
477
+ }
478
+ .pw-inbox_dot {
479
+ width: 6px;
480
+ height: 6px;
481
+ padding: 0;
482
+ border: none;
483
+ border-radius: 50%;
484
+ background: var(--pw-inbox-pagerDotColor, #ebf0f5);
485
+ cursor: pointer;
486
+ }
487
+ .pw-inbox_dot.pw-active {
488
+ background: var(--pw-inbox-pagerDotActiveColor, #00a2ff);
489
+ }
490
+
491
+ /* \`legacyClassicCell\` restores the pre-3.75 classic cell. Scoped to classic on
492
+ purpose: the three new layouts have no older look to go back to. */
493
+ .pw-inbox-widget--legacy-cell .pw-inbox_item--classic .pw-inbox_icon {
494
+ display: block;
495
+ flex: 0 0 40px;
496
+ width: auto;
497
+ height: auto;
498
+ margin-right: 0;
499
+ border-radius: 0;
500
+ background: none;
501
+ }
502
+ .pw-inbox-widget--legacy-cell .pw-inbox_item--classic .pw-inbox_message-image {
503
+ width: 28px;
504
+ height: auto;
505
+ object-fit: fill;
506
+ }
507
+ .pw-inbox-widget--legacy-cell .pw-inbox_item--classic .pw-inbox_content {
508
+ flex: 0 1 100%;
509
+ }
510
+ .pw-inbox-widget--legacy-cell .pw-inbox_item--classic .pw-inbox_item-title {
511
+ display: block;
512
+ overflow: visible;
513
+ text-overflow: clip;
514
+ white-space: normal;
515
+ }
516
+ .pw-inbox-widget--legacy-cell .pw-inbox_item--classic .pw-inbox_unread-dot {
517
+ display: none;
518
+ }
519
+ .pw-inbox-widget--legacy-cell .pw-inbox_item--classic .pw-inbox_item-body {
520
+ display: block;
521
+ overflow: visible;
522
+ }
523
+
524
+ .pw-inbox-widget.pw-inbox-widget--preview {
525
+ position: relative;
526
+ top: auto;
527
+ left: auto;
528
+ max-width: 100%;
529
+ opacity: 1;
530
+ transition: none;
531
+ }
532
+ .pw-inbox-widget--preview .pw-inbox__arrow {
533
+ display: none;
534
+ }
535
+ .pw-inbox-widget--cell .pw-inbox_item {
536
+ padding: 16px;
537
+ }
538
+ .pw-inbox_icon--placeholder {
539
+ border: 1px dashed #00a2ff;
540
+ background: #80b7ff33;
541
+ }
542
+ .pw-inbox_hero--placeholder {
543
+ border: 1px dashed #00a2ff;
544
+ background: #80b7ff33;
545
+ }
546
+ `;
@@ -0,0 +1,30 @@
1
+ import { type InboxCellContent, type InboxLayout, type InboxSlide, type InboxWidgetAppearance, type InboxWidgetStyleType } from './types';
2
+ /** Picks the content to render: explicit `content` wins, otherwise the `language` entry of `localizedContent` with default/en/first fallbacks. */
3
+ export declare function pickInboxLocalizedContent(content?: InboxCellContent | null, localizedContent?: Record<string, InboxCellContent>, language?: string): InboxCellContent | null;
4
+ /** Slides a cell draws: the ones with an image, at most {@link INBOX_MAX_CAROUSEL_SLIDES}. */
5
+ export declare function getInboxValidSlides(slides?: InboxSlide[] | null): InboxSlide[];
6
+ /** Hero image of the banner/captioned layouts: the banner, with the icon standing in when none was sent. */
7
+ export declare function getInboxHeroUrl(content: InboxCellContent): string;
8
+ /** Resolves the layout a cell draws: the requested one when it can render, the heuristic for unknown ones, classic otherwise. */
9
+ export declare function resolveInboxLayout(content: InboxCellContent): InboxLayout;
10
+ /** True when the content has nothing to render yet, so a preview shows the layout placeholder. */
11
+ export declare function isInboxContentEmpty(content: InboxCellContent): boolean;
12
+ /** The layout whose placeholder an empty preview shows: the requested one when known, else classic. */
13
+ export declare function getInboxEmptyLayout(content: InboxCellContent): InboxLayout;
14
+ /** Title/body pair of the mobile cells: in classic the body stands in for a missing title, as the mobile SDKs draw it. */
15
+ export declare function getInboxMobileTexts(content: InboxCellContent, layout: InboxLayout): {
16
+ title: string;
17
+ body: string;
18
+ };
19
+ /** The colored initial a classic cell shows when there is no icon. */
20
+ export declare function getInboxIconInitial(content: InboxCellContent): string;
21
+ /** Date label of a web widget message: relative within a day of `now`, then `D Mon YYYY, H:mm` in local time. */
22
+ export declare function formatInboxMessageTime(sendDate: string, now?: number): string;
23
+ /** Newest first. */
24
+ export declare function compareInboxBySendDate(one: string, two: string): number;
25
+ /** Full appearance from a partial one; the arrow border follows a visible widget border unless set explicitly. */
26
+ export declare function resolveInboxWidgetAppearance(appearance?: Partial<InboxWidgetAppearance> | null): InboxWidgetAppearance;
27
+ /** One appearance value as its CSS custom property value; `null` leaves it unset so the stylesheet default applies. */
28
+ export declare function formatInboxStyleValue(type: InboxWidgetStyleType, value: unknown): string | null;
29
+ /** The `--pw-inbox-*` custom properties of an appearance, ready for a `style` object or `setProperty`. */
30
+ export declare function inboxWidgetStyleVariables(appearance: InboxWidgetAppearance): Record<string, string>;