@product7/product7-js 0.1.6 → 0.1.7

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;
@@ -9138,6 +9181,8 @@
9138
9181
  this._typingIndicator = null;
9139
9182
  this._isConversationClosed = false;
9140
9183
  this._pendingAttachments = [];
9184
+ this._emojiPickerOpen = false;
9185
+ this._emojiOutsideHandler = null;
9141
9186
  }
9142
9187
 
9143
9188
  render() {
@@ -9258,7 +9303,7 @@
9258
9303
  <button class="sdk-btn-icon messenger-compose-attach" aria-label="Attach file">
9259
9304
  <iconify-icon icon="ph:paperclip-duotone" width="20" height="20"></iconify-icon>
9260
9305
  </button>
9261
- <button class="sdk-btn-icon" aria-label="Emoji">
9306
+ <button class="sdk-btn-icon messenger-emoji-btn" aria-label="Emoji">
9262
9307
  <iconify-icon icon="ph:smiley-duotone" width="20" height="20"></iconify-icon>
9263
9308
  </button>
9264
9309
  </div>
@@ -9527,6 +9572,14 @@
9527
9572
  });
9528
9573
  }
9529
9574
 
9575
+ const emojiBtn = this.element.querySelector('.messenger-emoji-btn');
9576
+ if (emojiBtn) {
9577
+ emojiBtn.addEventListener('click', (e) => {
9578
+ e.stopPropagation();
9579
+ this._toggleEmojiPicker();
9580
+ });
9581
+ }
9582
+
9530
9583
  const attachBtn = this.element.querySelector('.messenger-compose-attach');
9531
9584
  const fileInput = this.element.querySelector(
9532
9585
  '.messenger-compose-file-input'
@@ -9657,6 +9710,85 @@
9657
9710
  this._updateSendButtonState();
9658
9711
  }
9659
9712
 
9713
+ _loadEmojiPicker() {
9714
+ if (document.querySelector('#product7-emoji-picker-script')) {
9715
+ return Promise.resolve();
9716
+ }
9717
+ return new Promise((resolve, reject) => {
9718
+ const script = document.createElement('script');
9719
+ script.id = 'product7-emoji-picker-script';
9720
+ script.type = 'module';
9721
+ script.src =
9722
+ 'https://cdn.jsdelivr.net/npm/emoji-picker-element@1/index.js';
9723
+ script.onload = resolve;
9724
+ script.onerror = reject;
9725
+ document.head.appendChild(script);
9726
+ });
9727
+ }
9728
+
9729
+ async _toggleEmojiPicker() {
9730
+ const existing = this.element.querySelector(
9731
+ '.messenger-emoji-picker-container'
9732
+ );
9733
+ if (existing) {
9734
+ existing.remove();
9735
+ this._emojiPickerOpen = false;
9736
+ if (this._emojiOutsideHandler) {
9737
+ document.removeEventListener('click', this._emojiOutsideHandler);
9738
+ this._emojiOutsideHandler = null;
9739
+ }
9740
+ return;
9741
+ }
9742
+
9743
+ try {
9744
+ await this._loadEmojiPicker();
9745
+ } catch {
9746
+ return;
9747
+ }
9748
+
9749
+ const container = document.createElement('div');
9750
+ container.className = 'messenger-emoji-picker-container';
9751
+
9752
+ const picker = document.createElement('emoji-picker');
9753
+ container.appendChild(picker);
9754
+
9755
+ const compose = this.element.querySelector('.messenger-chat-compose');
9756
+ compose.parentNode.insertBefore(container, compose);
9757
+ this._emojiPickerOpen = true;
9758
+
9759
+ picker.addEventListener('emoji-click', (e) => {
9760
+ this._insertEmoji(e.detail.unicode);
9761
+ container.remove();
9762
+ this._emojiPickerOpen = false;
9763
+ if (this._emojiOutsideHandler) {
9764
+ document.removeEventListener('click', this._emojiOutsideHandler);
9765
+ this._emojiOutsideHandler = null;
9766
+ }
9767
+ });
9768
+
9769
+ this._emojiOutsideHandler = (e) => {
9770
+ if (!container.contains(e.target) && !e.target.closest('.messenger-emoji-btn')) {
9771
+ container.remove();
9772
+ this._emojiPickerOpen = false;
9773
+ document.removeEventListener('click', this._emojiOutsideHandler);
9774
+ this._emojiOutsideHandler = null;
9775
+ }
9776
+ };
9777
+ setTimeout(() => document.addEventListener('click', this._emojiOutsideHandler), 0);
9778
+ }
9779
+
9780
+ _insertEmoji(emoji) {
9781
+ const input = this.element.querySelector('.messenger-compose-input');
9782
+ if (!input) return;
9783
+ const start = input.selectionStart;
9784
+ const end = input.selectionEnd;
9785
+ input.value =
9786
+ input.value.slice(0, start) + emoji + input.value.slice(end);
9787
+ input.selectionStart = input.selectionEnd = start + emoji.length;
9788
+ input.focus();
9789
+ input.dispatchEvent(new Event('input'));
9790
+ }
9791
+
9660
9792
  _startTyping() {
9661
9793
  if (this._isConversationClosed) return;
9662
9794
  if (!this._isTyping && this.state.activeConversationId) {
@@ -9714,6 +9846,9 @@
9714
9846
  clearTimeout(this._typingTimeout);
9715
9847
  }
9716
9848
  this._stopTyping();
9849
+ if (this._emojiOutsideHandler) {
9850
+ document.removeEventListener('click', this._emojiOutsideHandler);
9851
+ }
9717
9852
  if (this.element && this.element.parentNode) {
9718
9853
  this.element.parentNode.removeChild(this.element);
9719
9854
  }