@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.
@@ -3880,6 +3880,49 @@
3880
3880
  COMPOSE AREA
3881
3881
  ======================================== */
3882
3882
 
3883
+ /* ========================================
3884
+ EMOJI PICKER
3885
+ ======================================== */
3886
+
3887
+ .messenger-emoji-picker-container {
3888
+ padding: 0 var(--spacing-3) var(--spacing-2);
3889
+ }
3890
+
3891
+ .messenger-emoji-picker-container emoji-picker {
3892
+ width: 100%;
3893
+ height: 320px;
3894
+ border-radius: var(--radius-xl);
3895
+ border: 1px solid var(--msg-border);
3896
+ box-shadow: var(--shadow-lg);
3897
+
3898
+ --background: var(--msg-bg);
3899
+ --border-color: var(--msg-border);
3900
+ --border-radius: 12px;
3901
+ --category-font-color: var(--msg-text-secondary);
3902
+ --category-font-size: 0.7rem;
3903
+ --emoji-size: 1.35rem;
3904
+ --emoji-padding: 0.3rem;
3905
+ --input-border-color: var(--msg-border);
3906
+ --input-border-radius: 8px;
3907
+ --input-font-color: var(--msg-text);
3908
+ --input-font-size: 0.8rem;
3909
+ --input-placeholder-color: var(--msg-text-tertiary);
3910
+ --input-padding: 0.375rem 0.625rem;
3911
+ --outline-color: var(--color-primary);
3912
+ --num-columns: 8;
3913
+ --indicator-color: var(--color-primary);
3914
+ --hover-background: var(--msg-bg-hover);
3915
+ }
3916
+
3917
+ .messenger-widget.theme-dark .messenger-emoji-picker-container emoji-picker {
3918
+ --background: var(--msg-bg);
3919
+ --border-color: var(--msg-border);
3920
+ --category-font-color: var(--msg-text-secondary);
3921
+ --input-font-color: var(--msg-text);
3922
+ --input-placeholder-color: var(--msg-text-tertiary);
3923
+ --hover-background: var(--msg-bg-hover);
3924
+ }
3925
+
3883
3926
  .messenger-chat-compose {
3884
3927
  display: flex;
3885
3928
  flex-direction: column;
@@ -4411,7 +4454,14 @@
4411
4454
  margin-left: 0;
4412
4455
  }
4413
4456
 
4457
+ .messenger-mobile-close-btn {
4458
+ display: none;
4459
+ }
4460
+
4414
4461
  @media (max-width: 480px) {
4462
+ .messenger-mobile-close-btn {
4463
+ display: flex;
4464
+ }
4415
4465
  .messenger-panel {
4416
4466
  width: 100%;
4417
4467
  height: 100%;
@@ -5438,42 +5488,35 @@
5438
5488
  .messenger-changelog-list {
5439
5489
  display: flex;
5440
5490
  flex-direction: column;
5491
+ gap: var(--spacing-3);
5492
+ padding: var(--spacing-4) var(--spacing-5);
5441
5493
  }
5442
5494
 
5443
5495
  .messenger-changelog-card {
5444
5496
  display: flex;
5445
- align-items: center;
5446
- gap: var(--spacing-3);
5447
- padding: var(--spacing-4) var(--spacing-5);
5448
- border-bottom: 1px solid var(--msg-border);
5497
+ flex-direction: column;
5498
+ border: 1px solid var(--msg-border);
5499
+ border-radius: 10px;
5500
+ overflow: hidden;
5449
5501
  cursor: pointer;
5450
- transition: background var(--transition-base);
5451
- }
5452
-
5453
- .messenger-changelog-card:last-child {
5454
- border-bottom: none;
5502
+ transition: box-shadow var(--transition-base), transform var(--transition-base);
5455
5503
  }
5456
5504
 
5457
5505
  .messenger-changelog-card:hover {
5458
- background: var(--msg-bg-hover);
5459
- }
5460
-
5461
- .messenger-changelog-card:hover .messenger-changelog-arrow {
5462
- color: var(--color-primary);
5463
- transform: translateX(3px);
5506
+ box-shadow: var(--shadow-md);
5507
+ transform: translateY(-1px);
5464
5508
  }
5465
5509
 
5466
5510
  .messenger-changelog-card:active {
5467
- transform: translateY(1px);
5511
+ transform: translateY(0);
5468
5512
  transition-duration: 100ms;
5469
5513
  }
5470
5514
 
5471
5515
  .messenger-changelog-content {
5472
- flex: 1;
5473
- min-width: 0;
5474
5516
  display: flex;
5475
5517
  flex-direction: column;
5476
- gap: 3px;
5518
+ gap: var(--spacing-1);
5519
+ padding: var(--spacing-3) var(--spacing-4);
5477
5520
  }
5478
5521
 
5479
5522
  .messenger-changelog-meta {
@@ -5511,9 +5554,6 @@
5511
5554
  font-weight: var(--font-weight-semibold);
5512
5555
  color: var(--msg-text);
5513
5556
  line-height: var(--line-height-snug);
5514
- white-space: nowrap;
5515
- overflow: hidden;
5516
- text-overflow: ellipsis;
5517
5557
  }
5518
5558
 
5519
5559
  .messenger-changelog-description {
@@ -5528,26 +5568,17 @@
5528
5568
  }
5529
5569
 
5530
5570
  .messenger-changelog-thumb {
5531
- width: 64px;
5532
- height: 64px;
5533
- flex-shrink: 0;
5534
- border-radius: 8px;
5571
+ width: 100%;
5535
5572
  overflow: hidden;
5536
- border: 1px solid var(--msg-border);
5573
+ border-bottom: 1px solid var(--msg-border);
5537
5574
  }
5538
5575
 
5539
5576
  .messenger-changelog-thumb img {
5540
5577
  width: 100%;
5541
- height: 100%;
5578
+ height: 180px;
5542
5579
  display: block;
5543
5580
  object-fit: cover;
5544
5581
  }
5545
-
5546
- .messenger-changelog-arrow {
5547
- flex-shrink: 0;
5548
- color: var(--msg-text-tertiary);
5549
- transition: all var(--transition-base);
5550
- }
5551
5582
  `;
5552
5583
 
5553
5584
  const messengerStyles =
@@ -8983,8 +9014,8 @@
8983
9014
  <div class="messenger-changelog-header">
8984
9015
  <div class="messenger-changelog-header-top">
8985
9016
  <h2>Latest Updates</h2>
8986
- <button class="sdk-close-btn messenger-changelog-close-btn" aria-label="Close">
8987
- <iconify-icon icon="ph:x-duotone" width="18" height="18"></iconify-icon>
9017
+ <button class="sdk-close-btn messenger-changelog-close-btn messenger-mobile-close-btn" aria-label="Close">
9018
+ <iconify-icon icon="ph:x" width="18" height="18"></iconify-icon>
8988
9019
  </button>
8989
9020
  </div>
8990
9021
  </div>
@@ -9024,30 +9055,13 @@
9024
9055
  }
9025
9056
 
9026
9057
  _renderChangelogCard(item) {
9027
- const dateStr = this._formatDate(item.publishedAt || item.date);
9028
- const labelsHtml =
9029
- item.labels && item.labels.length > 0
9030
- ? item.labels
9031
- .map((label) => {
9032
- const bg = label.color || '#E5E7EB';
9033
- const color = this._getContrastColor(bg);
9034
- return `<span class="messenger-changelog-tag" style="background:${bg};color:${color};">${label.name}</span>`;
9035
- })
9036
- .join('')
9037
- : '';
9038
-
9039
9058
  return `
9040
9059
  <div class="messenger-changelog-card" data-changelog-id="${item.id}">
9060
+ ${item.coverImage ? `<div class="messenger-changelog-thumb"><img src="${item.coverImage}" alt="${item.title}" onerror="this.parentElement.style.display='none';" /></div>` : ''}
9041
9061
  <div class="messenger-changelog-content">
9042
- <div class="messenger-changelog-meta">
9043
- ${dateStr ? `<span class="messenger-changelog-date">${dateStr}</span>` : ''}
9044
- ${labelsHtml}
9045
- </div>
9046
9062
  <h3 class="messenger-changelog-title">${item.title}</h3>
9047
9063
  ${item.description ? `<p class="messenger-changelog-description">${this._stripHtml(item.description)}</p>` : ''}
9048
9064
  </div>
9049
- ${item.coverImage ? `<div class="messenger-changelog-thumb"><img src="${item.coverImage}" alt="${item.title}" onerror="this.style.display='none';" /></div>` : ''}
9050
- <iconify-icon icon="ph:caret-right" class="messenger-changelog-arrow" width="16" height="16"></iconify-icon>
9051
9065
  </div>
9052
9066
  `;
9053
9067
  }
@@ -9090,11 +9104,12 @@
9090
9104
  }
9091
9105
 
9092
9106
  _attachEvents() {
9093
- this.element
9094
- .querySelector('.messenger-changelog-close-btn')
9095
- .addEventListener('click', () => {
9107
+ const mobileCloseBtn = this.element.querySelector('.messenger-changelog-close-btn');
9108
+ if (mobileCloseBtn) {
9109
+ mobileCloseBtn.addEventListener('click', () => {
9096
9110
  this.state.setOpen(false);
9097
9111
  });
9112
+ }
9098
9113
 
9099
9114
  this._attachChangelogEvents();
9100
9115
  }
@@ -9138,6 +9153,8 @@
9138
9153
  this._typingIndicator = null;
9139
9154
  this._isConversationClosed = false;
9140
9155
  this._pendingAttachments = [];
9156
+ this._emojiPickerOpen = false;
9157
+ this._emojiOutsideHandler = null;
9141
9158
  }
9142
9159
 
9143
9160
  render() {
@@ -9214,11 +9231,8 @@
9214
9231
  <span class="messenger-chat-subtitle">The team can also help</span>
9215
9232
  </div>
9216
9233
  <div class="messenger-chat-header-actions">
9217
- <button class="sdk-btn-icon" aria-label="More options">
9218
- <iconify-icon icon="ph:dots-three-outline-duotone" width="20" height="20"></iconify-icon>
9219
- </button>
9220
- <button class="sdk-close-btn" aria-label="Close">
9221
- <iconify-icon icon="ph:x-duotone" width="18" height="18"></iconify-icon>
9234
+ <button class="sdk-btn-icon sdk-close-btn messenger-mobile-close-btn" aria-label="Close">
9235
+ <iconify-icon icon="ph:x" width="18" height="18"></iconify-icon>
9222
9236
  </button>
9223
9237
  </div>
9224
9238
  </div>
@@ -9258,7 +9272,7 @@
9258
9272
  <button class="sdk-btn-icon messenger-compose-attach" aria-label="Attach file">
9259
9273
  <iconify-icon icon="ph:paperclip-duotone" width="20" height="20"></iconify-icon>
9260
9274
  </button>
9261
- <button class="sdk-btn-icon" aria-label="Emoji">
9275
+ <button class="sdk-btn-icon messenger-emoji-btn" aria-label="Emoji">
9262
9276
  <iconify-icon icon="ph:smiley-duotone" width="20" height="20"></iconify-icon>
9263
9277
  </button>
9264
9278
  </div>
@@ -9495,11 +9509,12 @@
9495
9509
  this.state.setView('messages');
9496
9510
  });
9497
9511
 
9498
- this.element
9499
- .querySelector('.sdk-close-btn')
9500
- .addEventListener('click', () => {
9512
+ const mobileCloseBtn = this.element.querySelector('.messenger-mobile-close-btn');
9513
+ if (mobileCloseBtn) {
9514
+ mobileCloseBtn.addEventListener('click', () => {
9501
9515
  this.state.setOpen(false);
9502
9516
  });
9517
+ }
9503
9518
 
9504
9519
  const input = this.element.querySelector('.messenger-compose-input');
9505
9520
  const sendBtn = this.element.querySelector('.messenger-compose-send');
@@ -9527,6 +9542,14 @@
9527
9542
  });
9528
9543
  }
9529
9544
 
9545
+ const emojiBtn = this.element.querySelector('.messenger-emoji-btn');
9546
+ if (emojiBtn) {
9547
+ emojiBtn.addEventListener('click', (e) => {
9548
+ e.stopPropagation();
9549
+ this._toggleEmojiPicker();
9550
+ });
9551
+ }
9552
+
9530
9553
  const attachBtn = this.element.querySelector('.messenger-compose-attach');
9531
9554
  const fileInput = this.element.querySelector(
9532
9555
  '.messenger-compose-file-input'
@@ -9657,6 +9680,85 @@
9657
9680
  this._updateSendButtonState();
9658
9681
  }
9659
9682
 
9683
+ _loadEmojiPicker() {
9684
+ if (document.querySelector('#product7-emoji-picker-script')) {
9685
+ return Promise.resolve();
9686
+ }
9687
+ return new Promise((resolve, reject) => {
9688
+ const script = document.createElement('script');
9689
+ script.id = 'product7-emoji-picker-script';
9690
+ script.type = 'module';
9691
+ script.src =
9692
+ 'https://cdn.jsdelivr.net/npm/emoji-picker-element@1/index.js';
9693
+ script.onload = resolve;
9694
+ script.onerror = reject;
9695
+ document.head.appendChild(script);
9696
+ });
9697
+ }
9698
+
9699
+ async _toggleEmojiPicker() {
9700
+ const existing = this.element.querySelector(
9701
+ '.messenger-emoji-picker-container'
9702
+ );
9703
+ if (existing) {
9704
+ existing.remove();
9705
+ this._emojiPickerOpen = false;
9706
+ if (this._emojiOutsideHandler) {
9707
+ document.removeEventListener('click', this._emojiOutsideHandler);
9708
+ this._emojiOutsideHandler = null;
9709
+ }
9710
+ return;
9711
+ }
9712
+
9713
+ try {
9714
+ await this._loadEmojiPicker();
9715
+ } catch {
9716
+ return;
9717
+ }
9718
+
9719
+ const container = document.createElement('div');
9720
+ container.className = 'messenger-emoji-picker-container';
9721
+
9722
+ const picker = document.createElement('emoji-picker');
9723
+ container.appendChild(picker);
9724
+
9725
+ const compose = this.element.querySelector('.messenger-chat-compose');
9726
+ compose.parentNode.insertBefore(container, compose);
9727
+ this._emojiPickerOpen = true;
9728
+
9729
+ picker.addEventListener('emoji-click', (e) => {
9730
+ this._insertEmoji(e.detail.unicode);
9731
+ container.remove();
9732
+ this._emojiPickerOpen = false;
9733
+ if (this._emojiOutsideHandler) {
9734
+ document.removeEventListener('click', this._emojiOutsideHandler);
9735
+ this._emojiOutsideHandler = null;
9736
+ }
9737
+ });
9738
+
9739
+ this._emojiOutsideHandler = (e) => {
9740
+ if (!container.contains(e.target) && !e.target.closest('.messenger-emoji-btn')) {
9741
+ container.remove();
9742
+ this._emojiPickerOpen = false;
9743
+ document.removeEventListener('click', this._emojiOutsideHandler);
9744
+ this._emojiOutsideHandler = null;
9745
+ }
9746
+ };
9747
+ setTimeout(() => document.addEventListener('click', this._emojiOutsideHandler), 0);
9748
+ }
9749
+
9750
+ _insertEmoji(emoji) {
9751
+ const input = this.element.querySelector('.messenger-compose-input');
9752
+ if (!input) return;
9753
+ const start = input.selectionStart;
9754
+ const end = input.selectionEnd;
9755
+ input.value =
9756
+ input.value.slice(0, start) + emoji + input.value.slice(end);
9757
+ input.selectionStart = input.selectionEnd = start + emoji.length;
9758
+ input.focus();
9759
+ input.dispatchEvent(new Event('input'));
9760
+ }
9761
+
9660
9762
  _startTyping() {
9661
9763
  if (this._isConversationClosed) return;
9662
9764
  if (!this._isTyping && this.state.activeConversationId) {
@@ -9714,6 +9816,9 @@
9714
9816
  clearTimeout(this._typingTimeout);
9715
9817
  }
9716
9818
  this._stopTyping();
9819
+ if (this._emojiOutsideHandler) {
9820
+ document.removeEventListener('click', this._emojiOutsideHandler);
9821
+ }
9717
9822
  if (this.element && this.element.parentNode) {
9718
9823
  this.element.parentNode.removeChild(this.element);
9719
9824
  }
@@ -9995,8 +10100,8 @@
9995
10100
  <div class="messenger-help-header">
9996
10101
  <div class="messenger-help-header-top">
9997
10102
  <h2>Help</h2>
9998
- <button class="sdk-close-btn messenger-help-close-btn" aria-label="Close">
9999
- <iconify-icon icon="ph:x-duotone" width="18" height="18"></iconify-icon>
10103
+ <button class="sdk-close-btn messenger-help-close-btn messenger-mobile-close-btn" aria-label="Close">
10104
+ <iconify-icon icon="ph:x" width="18" height="18"></iconify-icon>
10000
10105
  </button>
10001
10106
  </div>
10002
10107
  <div class="messenger-help-search-wrap">
@@ -10163,11 +10268,12 @@
10163
10268
  }
10164
10269
 
10165
10270
  _attachEvents() {
10166
- this.element
10167
- .querySelector('.messenger-help-close-btn')
10168
- .addEventListener('click', () => {
10271
+ const mobileCloseBtn = this.element.querySelector('.messenger-help-close-btn');
10272
+ if (mobileCloseBtn) {
10273
+ mobileCloseBtn.addEventListener('click', () => {
10169
10274
  this.state.setOpen(false);
10170
10275
  });
10276
+ }
10171
10277
 
10172
10278
  const searchInput = this.element.querySelector(
10173
10279
  '.messenger-help-search-input'