@product7/product7-js 0.1.6 → 0.1.8
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/dist/product7-js.js +177 -71
- package/dist/product7-js.js.map +1 -1
- package/dist/product7-js.min.js +1 -1
- package/dist/product7-js.min.js.map +1 -1
- package/package.json +1 -1
- package/src/styles/messenger-components.js +43 -0
- package/src/styles/messenger-core.js +7 -0
- package/src/styles/messenger-views.js +15 -34
- package/src/widgets/messenger/views/ChangelogView.js +7 -23
- package/src/widgets/messenger/views/ChatView.js +99 -9
- package/src/widgets/messenger/views/HelpView.js +6 -5
- package/types/index.d.ts +1 -0
package/package.json
CHANGED
|
@@ -253,6 +253,49 @@ export const messengerComponentsStyles = `
|
|
|
253
253
|
COMPOSE AREA
|
|
254
254
|
======================================== */
|
|
255
255
|
|
|
256
|
+
/* ========================================
|
|
257
|
+
EMOJI PICKER
|
|
258
|
+
======================================== */
|
|
259
|
+
|
|
260
|
+
.messenger-emoji-picker-container {
|
|
261
|
+
padding: 0 var(--spacing-3) var(--spacing-2);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.messenger-emoji-picker-container emoji-picker {
|
|
265
|
+
width: 100%;
|
|
266
|
+
height: 320px;
|
|
267
|
+
border-radius: var(--radius-xl);
|
|
268
|
+
border: 1px solid var(--msg-border);
|
|
269
|
+
box-shadow: var(--shadow-lg);
|
|
270
|
+
|
|
271
|
+
--background: var(--msg-bg);
|
|
272
|
+
--border-color: var(--msg-border);
|
|
273
|
+
--border-radius: 12px;
|
|
274
|
+
--category-font-color: var(--msg-text-secondary);
|
|
275
|
+
--category-font-size: 0.7rem;
|
|
276
|
+
--emoji-size: 1.35rem;
|
|
277
|
+
--emoji-padding: 0.3rem;
|
|
278
|
+
--input-border-color: var(--msg-border);
|
|
279
|
+
--input-border-radius: 8px;
|
|
280
|
+
--input-font-color: var(--msg-text);
|
|
281
|
+
--input-font-size: 0.8rem;
|
|
282
|
+
--input-placeholder-color: var(--msg-text-tertiary);
|
|
283
|
+
--input-padding: 0.375rem 0.625rem;
|
|
284
|
+
--outline-color: var(--color-primary);
|
|
285
|
+
--num-columns: 8;
|
|
286
|
+
--indicator-color: var(--color-primary);
|
|
287
|
+
--hover-background: var(--msg-bg-hover);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.messenger-widget.theme-dark .messenger-emoji-picker-container emoji-picker {
|
|
291
|
+
--background: var(--msg-bg);
|
|
292
|
+
--border-color: var(--msg-border);
|
|
293
|
+
--category-font-color: var(--msg-text-secondary);
|
|
294
|
+
--input-font-color: var(--msg-text);
|
|
295
|
+
--input-placeholder-color: var(--msg-text-tertiary);
|
|
296
|
+
--hover-background: var(--msg-bg-hover);
|
|
297
|
+
}
|
|
298
|
+
|
|
256
299
|
.messenger-chat-compose {
|
|
257
300
|
display: flex;
|
|
258
301
|
flex-direction: column;
|
|
@@ -154,7 +154,14 @@ export const messengerCoreStyles = `
|
|
|
154
154
|
margin-left: 0;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
.messenger-mobile-close-btn {
|
|
158
|
+
display: none;
|
|
159
|
+
}
|
|
160
|
+
|
|
157
161
|
@media (max-width: 480px) {
|
|
162
|
+
.messenger-mobile-close-btn {
|
|
163
|
+
display: flex;
|
|
164
|
+
}
|
|
158
165
|
.messenger-panel {
|
|
159
166
|
width: 100%;
|
|
160
167
|
height: 100%;
|
|
@@ -777,42 +777,35 @@ export const messengerViewsStyles = `
|
|
|
777
777
|
.messenger-changelog-list {
|
|
778
778
|
display: flex;
|
|
779
779
|
flex-direction: column;
|
|
780
|
+
gap: var(--spacing-3);
|
|
781
|
+
padding: var(--spacing-4) var(--spacing-5);
|
|
780
782
|
}
|
|
781
783
|
|
|
782
784
|
.messenger-changelog-card {
|
|
783
785
|
display: flex;
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
786
|
+
flex-direction: column;
|
|
787
|
+
border: 1px solid var(--msg-border);
|
|
788
|
+
border-radius: 10px;
|
|
789
|
+
overflow: hidden;
|
|
788
790
|
cursor: pointer;
|
|
789
|
-
transition:
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
.messenger-changelog-card:last-child {
|
|
793
|
-
border-bottom: none;
|
|
791
|
+
transition: box-shadow var(--transition-base), transform var(--transition-base);
|
|
794
792
|
}
|
|
795
793
|
|
|
796
794
|
.messenger-changelog-card:hover {
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
.messenger-changelog-card:hover .messenger-changelog-arrow {
|
|
801
|
-
color: var(--color-primary);
|
|
802
|
-
transform: translateX(3px);
|
|
795
|
+
box-shadow: var(--shadow-md);
|
|
796
|
+
transform: translateY(-1px);
|
|
803
797
|
}
|
|
804
798
|
|
|
805
799
|
.messenger-changelog-card:active {
|
|
806
|
-
transform: translateY(
|
|
800
|
+
transform: translateY(0);
|
|
807
801
|
transition-duration: 100ms;
|
|
808
802
|
}
|
|
809
803
|
|
|
810
804
|
.messenger-changelog-content {
|
|
811
|
-
flex: 1;
|
|
812
|
-
min-width: 0;
|
|
813
805
|
display: flex;
|
|
814
806
|
flex-direction: column;
|
|
815
|
-
gap:
|
|
807
|
+
gap: var(--spacing-1);
|
|
808
|
+
padding: var(--spacing-3) var(--spacing-4);
|
|
816
809
|
}
|
|
817
810
|
|
|
818
811
|
.messenger-changelog-meta {
|
|
@@ -850,9 +843,6 @@ export const messengerViewsStyles = `
|
|
|
850
843
|
font-weight: var(--font-weight-semibold);
|
|
851
844
|
color: var(--msg-text);
|
|
852
845
|
line-height: var(--line-height-snug);
|
|
853
|
-
white-space: nowrap;
|
|
854
|
-
overflow: hidden;
|
|
855
|
-
text-overflow: ellipsis;
|
|
856
846
|
}
|
|
857
847
|
|
|
858
848
|
.messenger-changelog-description {
|
|
@@ -867,24 +857,15 @@ export const messengerViewsStyles = `
|
|
|
867
857
|
}
|
|
868
858
|
|
|
869
859
|
.messenger-changelog-thumb {
|
|
870
|
-
width:
|
|
871
|
-
height: 64px;
|
|
872
|
-
flex-shrink: 0;
|
|
873
|
-
border-radius: 8px;
|
|
860
|
+
width: 100%;
|
|
874
861
|
overflow: hidden;
|
|
875
|
-
border: 1px solid var(--msg-border);
|
|
862
|
+
border-bottom: 1px solid var(--msg-border);
|
|
876
863
|
}
|
|
877
864
|
|
|
878
865
|
.messenger-changelog-thumb img {
|
|
879
866
|
width: 100%;
|
|
880
|
-
height:
|
|
867
|
+
height: 180px;
|
|
881
868
|
display: block;
|
|
882
869
|
object-fit: cover;
|
|
883
870
|
}
|
|
884
|
-
|
|
885
|
-
.messenger-changelog-arrow {
|
|
886
|
-
flex-shrink: 0;
|
|
887
|
-
color: var(--msg-text-tertiary);
|
|
888
|
-
transition: all var(--transition-base);
|
|
889
|
-
}
|
|
890
871
|
`;
|
|
@@ -29,8 +29,8 @@ export class ChangelogView {
|
|
|
29
29
|
<div class="messenger-changelog-header">
|
|
30
30
|
<div class="messenger-changelog-header-top">
|
|
31
31
|
<h2>Latest Updates</h2>
|
|
32
|
-
<button class="sdk-close-btn messenger-changelog-close-btn" aria-label="Close">
|
|
33
|
-
<iconify-icon icon="ph:x
|
|
32
|
+
<button class="sdk-close-btn messenger-changelog-close-btn messenger-mobile-close-btn" aria-label="Close">
|
|
33
|
+
<iconify-icon icon="ph:x" width="18" height="18"></iconify-icon>
|
|
34
34
|
</button>
|
|
35
35
|
</div>
|
|
36
36
|
</div>
|
|
@@ -70,30 +70,13 @@ export class ChangelogView {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
_renderChangelogCard(item) {
|
|
73
|
-
const dateStr = this._formatDate(item.publishedAt || item.date);
|
|
74
|
-
const labelsHtml =
|
|
75
|
-
item.labels && item.labels.length > 0
|
|
76
|
-
? item.labels
|
|
77
|
-
.map((label) => {
|
|
78
|
-
const bg = label.color || '#E5E7EB';
|
|
79
|
-
const color = this._getContrastColor(bg);
|
|
80
|
-
return `<span class="messenger-changelog-tag" style="background:${bg};color:${color};">${label.name}</span>`;
|
|
81
|
-
})
|
|
82
|
-
.join('')
|
|
83
|
-
: '';
|
|
84
|
-
|
|
85
73
|
return `
|
|
86
74
|
<div class="messenger-changelog-card" data-changelog-id="${item.id}">
|
|
75
|
+
${item.coverImage ? `<div class="messenger-changelog-thumb"><img src="${item.coverImage}" alt="${item.title}" onerror="this.parentElement.style.display='none';" /></div>` : ''}
|
|
87
76
|
<div class="messenger-changelog-content">
|
|
88
|
-
<div class="messenger-changelog-meta">
|
|
89
|
-
${dateStr ? `<span class="messenger-changelog-date">${dateStr}</span>` : ''}
|
|
90
|
-
${labelsHtml}
|
|
91
|
-
</div>
|
|
92
77
|
<h3 class="messenger-changelog-title">${item.title}</h3>
|
|
93
78
|
${item.description ? `<p class="messenger-changelog-description">${this._stripHtml(item.description)}</p>` : ''}
|
|
94
79
|
</div>
|
|
95
|
-
${item.coverImage ? `<div class="messenger-changelog-thumb"><img src="${item.coverImage}" alt="${item.title}" onerror="this.style.display='none';" /></div>` : ''}
|
|
96
|
-
<iconify-icon icon="ph:caret-right" class="messenger-changelog-arrow" width="16" height="16"></iconify-icon>
|
|
97
80
|
</div>
|
|
98
81
|
`;
|
|
99
82
|
}
|
|
@@ -136,11 +119,12 @@ export class ChangelogView {
|
|
|
136
119
|
}
|
|
137
120
|
|
|
138
121
|
_attachEvents() {
|
|
139
|
-
this.element
|
|
140
|
-
|
|
141
|
-
.addEventListener('click', () => {
|
|
122
|
+
const mobileCloseBtn = this.element.querySelector('.messenger-changelog-close-btn');
|
|
123
|
+
if (mobileCloseBtn) {
|
|
124
|
+
mobileCloseBtn.addEventListener('click', () => {
|
|
142
125
|
this.state.setOpen(false);
|
|
143
126
|
});
|
|
127
|
+
}
|
|
144
128
|
|
|
145
129
|
this._attachChangelogEvents();
|
|
146
130
|
}
|
|
@@ -9,6 +9,8 @@ export class ChatView {
|
|
|
9
9
|
this._typingIndicator = null;
|
|
10
10
|
this._isConversationClosed = false;
|
|
11
11
|
this._pendingAttachments = [];
|
|
12
|
+
this._emojiPickerOpen = false;
|
|
13
|
+
this._emojiOutsideHandler = null;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
render() {
|
|
@@ -85,11 +87,8 @@ export class ChatView {
|
|
|
85
87
|
<span class="messenger-chat-subtitle">The team can also help</span>
|
|
86
88
|
</div>
|
|
87
89
|
<div class="messenger-chat-header-actions">
|
|
88
|
-
<button class="sdk-btn-icon" aria-label="
|
|
89
|
-
<iconify-icon icon="ph:
|
|
90
|
-
</button>
|
|
91
|
-
<button class="sdk-close-btn" aria-label="Close">
|
|
92
|
-
<iconify-icon icon="ph:x-duotone" width="18" height="18"></iconify-icon>
|
|
90
|
+
<button class="sdk-btn-icon sdk-close-btn messenger-mobile-close-btn" aria-label="Close">
|
|
91
|
+
<iconify-icon icon="ph:x" width="18" height="18"></iconify-icon>
|
|
93
92
|
</button>
|
|
94
93
|
</div>
|
|
95
94
|
</div>
|
|
@@ -129,7 +128,7 @@ export class ChatView {
|
|
|
129
128
|
<button class="sdk-btn-icon messenger-compose-attach" aria-label="Attach file">
|
|
130
129
|
<iconify-icon icon="ph:paperclip-duotone" width="20" height="20"></iconify-icon>
|
|
131
130
|
</button>
|
|
132
|
-
<button class="sdk-btn-icon" aria-label="Emoji">
|
|
131
|
+
<button class="sdk-btn-icon messenger-emoji-btn" aria-label="Emoji">
|
|
133
132
|
<iconify-icon icon="ph:smiley-duotone" width="20" height="20"></iconify-icon>
|
|
134
133
|
</button>
|
|
135
134
|
</div>
|
|
@@ -366,11 +365,12 @@ export class ChatView {
|
|
|
366
365
|
this.state.setView('messages');
|
|
367
366
|
});
|
|
368
367
|
|
|
369
|
-
this.element
|
|
370
|
-
|
|
371
|
-
.addEventListener('click', () => {
|
|
368
|
+
const mobileCloseBtn = this.element.querySelector('.messenger-mobile-close-btn');
|
|
369
|
+
if (mobileCloseBtn) {
|
|
370
|
+
mobileCloseBtn.addEventListener('click', () => {
|
|
372
371
|
this.state.setOpen(false);
|
|
373
372
|
});
|
|
373
|
+
}
|
|
374
374
|
|
|
375
375
|
const input = this.element.querySelector('.messenger-compose-input');
|
|
376
376
|
const sendBtn = this.element.querySelector('.messenger-compose-send');
|
|
@@ -398,6 +398,14 @@ export class ChatView {
|
|
|
398
398
|
});
|
|
399
399
|
}
|
|
400
400
|
|
|
401
|
+
const emojiBtn = this.element.querySelector('.messenger-emoji-btn');
|
|
402
|
+
if (emojiBtn) {
|
|
403
|
+
emojiBtn.addEventListener('click', (e) => {
|
|
404
|
+
e.stopPropagation();
|
|
405
|
+
this._toggleEmojiPicker();
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
|
|
401
409
|
const attachBtn = this.element.querySelector('.messenger-compose-attach');
|
|
402
410
|
const fileInput = this.element.querySelector(
|
|
403
411
|
'.messenger-compose-file-input'
|
|
@@ -528,6 +536,85 @@ export class ChatView {
|
|
|
528
536
|
this._updateSendButtonState();
|
|
529
537
|
}
|
|
530
538
|
|
|
539
|
+
_loadEmojiPicker() {
|
|
540
|
+
if (document.querySelector('#product7-emoji-picker-script')) {
|
|
541
|
+
return Promise.resolve();
|
|
542
|
+
}
|
|
543
|
+
return new Promise((resolve, reject) => {
|
|
544
|
+
const script = document.createElement('script');
|
|
545
|
+
script.id = 'product7-emoji-picker-script';
|
|
546
|
+
script.type = 'module';
|
|
547
|
+
script.src =
|
|
548
|
+
'https://cdn.jsdelivr.net/npm/emoji-picker-element@1/index.js';
|
|
549
|
+
script.onload = resolve;
|
|
550
|
+
script.onerror = reject;
|
|
551
|
+
document.head.appendChild(script);
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
async _toggleEmojiPicker() {
|
|
556
|
+
const existing = this.element.querySelector(
|
|
557
|
+
'.messenger-emoji-picker-container'
|
|
558
|
+
);
|
|
559
|
+
if (existing) {
|
|
560
|
+
existing.remove();
|
|
561
|
+
this._emojiPickerOpen = false;
|
|
562
|
+
if (this._emojiOutsideHandler) {
|
|
563
|
+
document.removeEventListener('click', this._emojiOutsideHandler);
|
|
564
|
+
this._emojiOutsideHandler = null;
|
|
565
|
+
}
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
try {
|
|
570
|
+
await this._loadEmojiPicker();
|
|
571
|
+
} catch {
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
const container = document.createElement('div');
|
|
576
|
+
container.className = 'messenger-emoji-picker-container';
|
|
577
|
+
|
|
578
|
+
const picker = document.createElement('emoji-picker');
|
|
579
|
+
container.appendChild(picker);
|
|
580
|
+
|
|
581
|
+
const compose = this.element.querySelector('.messenger-chat-compose');
|
|
582
|
+
compose.parentNode.insertBefore(container, compose);
|
|
583
|
+
this._emojiPickerOpen = true;
|
|
584
|
+
|
|
585
|
+
picker.addEventListener('emoji-click', (e) => {
|
|
586
|
+
this._insertEmoji(e.detail.unicode);
|
|
587
|
+
container.remove();
|
|
588
|
+
this._emojiPickerOpen = false;
|
|
589
|
+
if (this._emojiOutsideHandler) {
|
|
590
|
+
document.removeEventListener('click', this._emojiOutsideHandler);
|
|
591
|
+
this._emojiOutsideHandler = null;
|
|
592
|
+
}
|
|
593
|
+
});
|
|
594
|
+
|
|
595
|
+
this._emojiOutsideHandler = (e) => {
|
|
596
|
+
if (!container.contains(e.target) && !e.target.closest('.messenger-emoji-btn')) {
|
|
597
|
+
container.remove();
|
|
598
|
+
this._emojiPickerOpen = false;
|
|
599
|
+
document.removeEventListener('click', this._emojiOutsideHandler);
|
|
600
|
+
this._emojiOutsideHandler = null;
|
|
601
|
+
}
|
|
602
|
+
};
|
|
603
|
+
setTimeout(() => document.addEventListener('click', this._emojiOutsideHandler), 0);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
_insertEmoji(emoji) {
|
|
607
|
+
const input = this.element.querySelector('.messenger-compose-input');
|
|
608
|
+
if (!input) return;
|
|
609
|
+
const start = input.selectionStart;
|
|
610
|
+
const end = input.selectionEnd;
|
|
611
|
+
input.value =
|
|
612
|
+
input.value.slice(0, start) + emoji + input.value.slice(end);
|
|
613
|
+
input.selectionStart = input.selectionEnd = start + emoji.length;
|
|
614
|
+
input.focus();
|
|
615
|
+
input.dispatchEvent(new Event('input'));
|
|
616
|
+
}
|
|
617
|
+
|
|
531
618
|
_startTyping() {
|
|
532
619
|
if (this._isConversationClosed) return;
|
|
533
620
|
if (!this._isTyping && this.state.activeConversationId) {
|
|
@@ -585,6 +672,9 @@ export class ChatView {
|
|
|
585
672
|
clearTimeout(this._typingTimeout);
|
|
586
673
|
}
|
|
587
674
|
this._stopTyping();
|
|
675
|
+
if (this._emojiOutsideHandler) {
|
|
676
|
+
document.removeEventListener('click', this._emojiOutsideHandler);
|
|
677
|
+
}
|
|
588
678
|
if (this.element && this.element.parentNode) {
|
|
589
679
|
this.element.parentNode.removeChild(this.element);
|
|
590
680
|
}
|
|
@@ -28,8 +28,8 @@ export class HelpView {
|
|
|
28
28
|
<div class="messenger-help-header">
|
|
29
29
|
<div class="messenger-help-header-top">
|
|
30
30
|
<h2>Help</h2>
|
|
31
|
-
<button class="sdk-close-btn messenger-help-close-btn" aria-label="Close">
|
|
32
|
-
<iconify-icon icon="ph:x
|
|
31
|
+
<button class="sdk-close-btn messenger-help-close-btn messenger-mobile-close-btn" aria-label="Close">
|
|
32
|
+
<iconify-icon icon="ph:x" width="18" height="18"></iconify-icon>
|
|
33
33
|
</button>
|
|
34
34
|
</div>
|
|
35
35
|
<div class="messenger-help-search-wrap">
|
|
@@ -196,11 +196,12 @@ export class HelpView {
|
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
_attachEvents() {
|
|
199
|
-
this.element
|
|
200
|
-
|
|
201
|
-
.addEventListener('click', () => {
|
|
199
|
+
const mobileCloseBtn = this.element.querySelector('.messenger-help-close-btn');
|
|
200
|
+
if (mobileCloseBtn) {
|
|
201
|
+
mobileCloseBtn.addEventListener('click', () => {
|
|
202
202
|
this.state.setOpen(false);
|
|
203
203
|
});
|
|
204
|
+
}
|
|
204
205
|
|
|
205
206
|
const searchInput = this.element.querySelector(
|
|
206
207
|
'.messenger-help-search-input'
|