@product7/feedback-sdk 1.5.4 → 1.5.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.
@@ -1695,7 +1695,7 @@
1695
1695
  backgroundColor: options.backgroundColor || '#ffffff',
1696
1696
  textColor: options.textColor || '#1F2937',
1697
1697
  autoShow: false,
1698
- showBackdrop: true,
1698
+ showBackdrop: false,
1699
1699
  customStyles: {},
1700
1700
  suppressAfterSubmission: true,
1701
1701
  suppressionDays: BaseWidget.DEFAULT_COOLDOWN_DAYS,
@@ -2035,10 +2035,16 @@
2035
2035
  _getPanelHTML() {
2036
2036
  return `
2037
2037
  <div class="feedback-panel-content">
2038
- <div class="feedback-panel-header">
2039
- <h3>Send Feedback</h3>
2040
- <button class="sdk-close-btn" type="button" aria-label="Close">&times;</button>
2041
- </div>
2038
+ <div class="feedback-panel-header">
2039
+ <h3>Send Feedback</h3>
2040
+ <button class="sdk-close-btn" type="button" aria-label="Close">
2041
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="18" height="18">
2042
+ <rect width="256" height="256" fill="none"/>
2043
+ <line x1="200" y1="56" x2="56" y2="200" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
2044
+ <line x1="200" y1="200" x2="56" y2="56" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
2045
+ </svg>
2046
+ </button>
2047
+ </div>
2042
2048
  <div class="feedback-panel-body">
2043
2049
  <form class="feedback-form">
2044
2050
  <div class="sdk-form-group">
@@ -2420,7 +2426,7 @@
2420
2426
  this.modalElement.className = 'changelog-modal';
2421
2427
  this.modalElement.innerHTML = `
2422
2428
  <div class="changelog-modal-container">
2423
- <button class="changelog-modal-close" type="button" aria-label="Close">&times;</button>
2429
+ <button class="changelog-modal-close" type="button" aria-label="Close"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><line x1="200" y1="56" x2="56" y2="200" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="200" y1="200" x2="56" y2="56" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/></svg></button>
2424
2430
  <div class="changelog-modal-content">
2425
2431
  <div class="changelog-loading">
2426
2432
  <div class="sdk-spinner"></div>
@@ -2567,8 +2573,13 @@
2567
2573
  <div class="changelog-list-modal-container">
2568
2574
  <div class="changelog-list-modal-header">
2569
2575
  <h2>${this.options.title || "What's New"} 🎉</h2>
2570
- <button class="changelog-list-modal-close" type="button" aria-label="Close">&times;</button>
2571
- </div>
2576
+ <button class="changelog-list-modal-close" type="button" aria-label="Close">
2577
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="18" height="18">
2578
+ <rect width="256" height="256" fill="none"/>
2579
+ <line x1="200" y1="56" x2="56" y2="200" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
2580
+ <line x1="200" y1="200" x2="56" y2="56" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
2581
+ </svg>
2582
+ </button></div>
2572
2583
  <div class="changelog-list-modal-body">
2573
2584
  <div class="changelog-loading">
2574
2585
  <div class="sdk-spinner"></div>
@@ -4000,12 +4011,7 @@
4000
4011
  }
4001
4012
 
4002
4013
  _getMessagesIcon() {
4003
- return `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 256 256">
4004
- <circle cx="128" cy="128" r="12"/>
4005
- <circle cx="84" cy="128" r="12"/>
4006
- <circle cx="172" cy="128" r="12"/>
4007
- <path d="M79.93,211.11a96,96,0,1,0-35-35h0L32.42,213.46a8,8,0,0,0,10.12,10.12l37.39-12.47Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
4008
- </svg>`;
4014
+ return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><path d="M71.58,144,32,176V48a8,8,0,0,1,8-8H168a8,8,0,0,1,8,8v88a8,8,0,0,1-8,8Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M80,144v40a8,8,0,0,0,8,8h96.42L224,224V96a8,8,0,0,0-8-8H176" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/></svg>`;
4009
4015
  }
4010
4016
 
4011
4017
  _getHelpIcon() {
@@ -4432,10 +4438,12 @@
4432
4438
  <div class="messenger-compose-attachments-preview"></div>
4433
4439
 
4434
4440
  <div class="messenger-chat-compose">
4435
- <button class="sdk-btn-icon messenger-compose-attach" aria-label="Attach file">
4436
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="16" height="16" fill="none"/><path d="M160,80,76.69,164.69a16,16,0,0,0,22.63,22.62L198.63,86.63a32,32,0,0,0-45.26-45.26L54.06,142.06a48,48,0,0,0,67.88,67.88L204,128" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/></svg>
4437
- </button>
4438
- <div class="messenger-compose-input-wrapper">
4441
+ <button class="sdk-btn-icon messenger-compose-attach" aria-label="Attach file">
4442
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="20" height="20">
4443
+ <rect width="256" height="256" fill="none"/>
4444
+ <path d="M160,80,76.69,164.69a16,16,0,0,0,22.63,22.62L198.63,86.63a32,32,0,0,0-45.26-45.26L54.06,142.06a48,48,0,0,0,67.88,67.88L204,128" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
4445
+ </svg>
4446
+ </button> <div class="messenger-compose-input-wrapper">
4439
4447
  <textarea class="messenger-compose-input" placeholder="${placeholder}" rows="1"></textarea>
4440
4448
  </div>
4441
4449
  <button class="messenger-compose-send" aria-label="Send" disabled>
@@ -4962,11 +4970,13 @@
4962
4970
  this.element.innerHTML = `
4963
4971
  <div class="messenger-conversations-header">
4964
4972
  <h2>Messages</h2>
4965
- <button class="sdk-close-btn" aria-label="Close">
4966
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="#000000" viewBox="0 0 256 256">
4967
- <path d="M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z"></path>
4968
- </svg>
4969
- </button>
4973
+ <button class="sdk-close-btn" aria-label="Close">
4974
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="18" height="18">
4975
+ <rect width="256" height="256" fill="none"/>
4976
+ <line x1="200" y1="56" x2="56" y2="200" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
4977
+ <line x1="200" y1="200" x2="56" y2="56" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
4978
+ </svg>
4979
+ </button>
4970
4980
  </div>
4971
4981
 
4972
4982
  <div class="messenger-conversations-body">
@@ -6728,6 +6738,25 @@
6728
6738
  description: options.description || null,
6729
6739
  lowLabel: options.lowLabel || null,
6730
6740
  highLabel: options.highLabel || null,
6741
+ ratingScale: options.ratingScale || options.scale || null,
6742
+ showFeedbackInput:
6743
+ typeof options.showFeedbackInput === 'boolean'
6744
+ ? options.showFeedbackInput
6745
+ : null,
6746
+ showSubmitButton:
6747
+ typeof options.showSubmitButton === 'boolean'
6748
+ ? options.showSubmitButton
6749
+ : null,
6750
+ autoSubmitOnSelect:
6751
+ typeof options.autoSubmitOnSelect === 'boolean'
6752
+ ? options.autoSubmitOnSelect
6753
+ : null,
6754
+ showTitle:
6755
+ typeof options.showTitle === 'boolean' ? options.showTitle : null,
6756
+ showDescription:
6757
+ typeof options.showDescription === 'boolean'
6758
+ ? options.showDescription
6759
+ : null,
6731
6760
  customQuestions: options.customQuestions || [],
6732
6761
  pages: Array.isArray(options.pages) ? options.pages : [],
6733
6762
  respondentId: options.respondentId || null,
@@ -6742,6 +6771,7 @@
6742
6771
  customAnswers: {},
6743
6772
  pageAnswers: {},
6744
6773
  currentPageIndex: 0,
6774
+ isSubmitting: false,
6745
6775
  isVisible: false,
6746
6776
  };
6747
6777
  }
@@ -6777,6 +6807,10 @@
6777
6807
  const config = this._getSurveyConfig();
6778
6808
  const isMultiPage = this._isMultiPageSurvey();
6779
6809
  const isLastPage = this._isLastPage();
6810
+ const showFeedbackInput = this._shouldShowFeedbackInput();
6811
+ const showActions = this._shouldShowActions();
6812
+ const showTitle = this._shouldShowTitle(config);
6813
+ const showDescription = this._shouldShowDescription(config);
6780
6814
  const pageProgress = isMultiPage
6781
6815
  ? `Page ${this.surveyState.currentPageIndex + 1} of ${this.surveyOptions.pages.length}`
6782
6816
  : '';
@@ -6796,21 +6830,33 @@
6796
6830
  }
6797
6831
 
6798
6832
  this.surveyElement = document.createElement('div');
6799
- this.surveyElement.className = `feedback-survey feedback-survey-${this.surveyOptions.position}`;
6833
+ this.surveyElement.className = `feedback-survey feedback-survey-${this.surveyOptions.position}${
6834
+ showDescription && !showTitle
6835
+ ? ' feedback-survey-description-primary'
6836
+ : ''
6837
+ }`;
6800
6838
 
6801
6839
  this.surveyElement.innerHTML = `
6802
- <button class="feedback-survey-close">&times;</button>
6803
- <h3 class="feedback-survey-title">${config.title}</h3>
6804
- <p class="feedback-survey-description">${config.description}</p>
6840
+ <button class="feedback-survey-close"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><line x1="200" y1="56" x2="56" y2="200" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="200" y1="200" x2="56" y2="56" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/></svg></button>
6841
+ ${showTitle ? `<h3 class="feedback-survey-title">${config.title}</h3>` : ''}
6842
+ ${showDescription ? `<p class="feedback-survey-description">${config.description}</p>` : ''}
6805
6843
  ${isMultiPage ? `<div class="feedback-survey-progress">${pageProgress}</div>` : ''}
6806
6844
  <div class="feedback-survey-content">${config.html}</div>
6807
- <div class="feedback-survey-feedback">
6845
+ ${
6846
+ showFeedbackInput
6847
+ ? `<div class="feedback-survey-feedback">
6808
6848
  <textarea class="feedback-survey-textarea" placeholder="Any additional feedback? (optional)">${this.surveyState.feedback || ''}</textarea>
6809
- </div>
6810
- <div class="feedback-survey-actions">
6849
+ </div>`
6850
+ : ''
6851
+ }
6852
+ ${
6853
+ showActions
6854
+ ? `<div class="feedback-survey-actions">
6811
6855
  ${backButton}
6812
6856
  <button class="feedback-survey-submit">${submitLabel}</button>
6813
- </div>
6857
+ </div>`
6858
+ : ''
6859
+ }
6814
6860
  `;
6815
6861
 
6816
6862
  document.body.appendChild(this.surveyElement);
@@ -6830,37 +6876,62 @@
6830
6876
  return this._getCurrentPageConfig();
6831
6877
  }
6832
6878
 
6879
+ const npsScale = this._getNPSScale();
6880
+ const npsUsesSegmentedScale = npsScale.values.length <= 7;
6881
+ const npsContainerClass = npsUsesSegmentedScale
6882
+ ? 'feedback-survey-ces feedback-survey-rating-scale'
6883
+ : 'feedback-survey-nps';
6884
+ const npsButtonClass = npsUsesSegmentedScale
6885
+ ? 'feedback-survey-nps-btn feedback-survey-ces-btn feedback-survey-rating-scale-btn'
6886
+ : 'feedback-survey-nps-btn';
6887
+ const npsLowLabel =
6888
+ this.surveyOptions.lowLabel ||
6889
+ (npsScale.start === 0 ? 'Not likely' : 'Strongly Disagree');
6890
+ const npsHighLabel =
6891
+ this.surveyOptions.highLabel ||
6892
+ (npsScale.start === 0 ? 'Very likely' : 'Strongly Agree');
6893
+ const npsPrompt =
6894
+ this.surveyOptions.description ||
6895
+ this.surveyOptions.title ||
6896
+ 'How likely are you to recommend us?';
6897
+ const csatPrompt =
6898
+ this.surveyOptions.description ||
6899
+ this.surveyOptions.title ||
6900
+ 'How satisfied are you?';
6901
+ const cesPrompt =
6902
+ this.surveyOptions.description ||
6903
+ this.surveyOptions.title ||
6904
+ 'How easy was it?';
6905
+
6833
6906
  const configs = {
6834
6907
  nps: {
6835
- title:
6836
- this.surveyOptions.title || 'How likely are you to recommend us?',
6837
- description:
6838
- this.surveyOptions.description ||
6839
- 'On a scale of 0-10, how likely are you to recommend our product to a friend or colleague?',
6908
+ title: this.surveyOptions.title || '',
6909
+ description: npsPrompt,
6840
6910
  html: `
6841
- <div class="feedback-survey-nps">
6842
- ${[...Array(11).keys()]
6911
+ <div class="${npsContainerClass}">
6912
+ ${npsScale.values
6843
6913
  .map(
6844
6914
  (n) => `
6845
- <button class="feedback-survey-nps-btn" data-score="${n}">${n}</button>
6915
+ <button class="${npsButtonClass}" data-score="${n}">${n}</button>
6846
6916
  `
6847
6917
  )
6848
6918
  .join('')}
6849
6919
  </div>
6850
- <div class="feedback-survey-labels">
6851
- <span>${this.surveyOptions.lowLabel || 'Not likely'}</span>
6852
- <span>${this.surveyOptions.highLabel || 'Very likely'}</span>
6853
- </div>
6920
+ ${this._renderScaleLabels(npsLowLabel, npsHighLabel)}
6854
6921
  `,
6855
6922
  },
6856
6923
  csat: {
6857
- title: this.surveyOptions.title || 'How satisfied are you?',
6858
- description:
6859
- this.surveyOptions.description ||
6860
- 'How would you rate your overall satisfaction with our product?',
6924
+ title: this.surveyOptions.title || '',
6925
+ description: csatPrompt,
6861
6926
  html: `
6862
6927
  <div class="feedback-survey-csat">
6863
- ${['😞', '😕', '😐', '🙂', '😄']
6928
+ ${[
6929
+ '\uD83D\uDE1E',
6930
+ '\uD83D\uDE15',
6931
+ '\uD83D\uDE10',
6932
+ '\uD83D\uDE42',
6933
+ '\uD83D\uDE04',
6934
+ ]
6864
6935
  .map(
6865
6936
  (emoji, i) => `
6866
6937
  <button class="feedback-survey-csat-btn" data-score="${i + 1}">${emoji}</button>
@@ -6868,17 +6939,15 @@
6868
6939
  )
6869
6940
  .join('')}
6870
6941
  </div>
6871
- <div class="feedback-survey-labels">
6872
- <span>${this.surveyOptions.lowLabel || 'Very dissatisfied'}</span>
6873
- <span>${this.surveyOptions.highLabel || 'Very satisfied'}</span>
6874
- </div>
6942
+ ${this._renderScaleLabels(
6943
+ this.surveyOptions.lowLabel || 'Very dissatisfied',
6944
+ this.surveyOptions.highLabel || 'Very satisfied'
6945
+ )}
6875
6946
  `,
6876
6947
  },
6877
6948
  ces: {
6878
- title: this.surveyOptions.title || 'How easy was it?',
6879
- description:
6880
- this.surveyOptions.description ||
6881
- 'How easy was it to accomplish your task today?',
6949
+ title: this.surveyOptions.title || '',
6950
+ description: cesPrompt,
6882
6951
  html: `
6883
6952
  <div class="feedback-survey-ces">
6884
6953
  ${['Very Difficult', 'Difficult', 'Neutral', 'Easy', 'Very Easy']
@@ -6903,6 +6972,91 @@
6903
6972
  return configs[this.surveyOptions.surveyType] || configs.nps;
6904
6973
  }
6905
6974
 
6975
+ _getNPSScale() {
6976
+ const rawScale = Number(this.surveyOptions.ratingScale);
6977
+ const scale = Number.isFinite(rawScale) && rawScale >= 2 ? rawScale : 5;
6978
+ const start = scale === 11 ? 0 : 1;
6979
+ return {
6980
+ scale,
6981
+ start,
6982
+ values: Array.from({ length: scale }, (_, index) => start + index),
6983
+ };
6984
+ }
6985
+
6986
+ _renderScaleLabels(lowLabel, highLabel) {
6987
+ const low = lowLabel || '';
6988
+ const high = highLabel || '';
6989
+ if (!low && !high) {
6990
+ return '';
6991
+ }
6992
+ return `
6993
+ <div class="feedback-survey-labels">
6994
+ <span>${low}</span>
6995
+ <span>${high}</span>
6996
+ </div>
6997
+ `;
6998
+ }
6999
+
7000
+ _isRatingSurveyType(type = this.surveyOptions.surveyType) {
7001
+ return type === 'nps' || type === 'csat' || type === 'ces';
7002
+ }
7003
+
7004
+ _shouldShowTitle(config) {
7005
+ if (!config || !config.title) {
7006
+ return false;
7007
+ }
7008
+ if (typeof this.surveyOptions.showTitle === 'boolean') {
7009
+ return this.surveyOptions.showTitle;
7010
+ }
7011
+ if (!this._isMultiPageSurvey() && this._isRatingSurveyType()) {
7012
+ return !config.description;
7013
+ }
7014
+ return true;
7015
+ }
7016
+
7017
+ _shouldShowDescription(config) {
7018
+ if (typeof this.surveyOptions.showDescription === 'boolean') {
7019
+ return this.surveyOptions.showDescription;
7020
+ }
7021
+ if (!this._isMultiPageSurvey() && this._isRatingSurveyType()) {
7022
+ return Boolean(config && (config.description || config.title));
7023
+ }
7024
+ return Boolean(config && config.description);
7025
+ }
7026
+
7027
+ _shouldShowFeedbackInput() {
7028
+ if (this._isMultiPageSurvey()) {
7029
+ return false;
7030
+ }
7031
+ if (typeof this.surveyOptions.showFeedbackInput === 'boolean') {
7032
+ return this.surveyOptions.showFeedbackInput;
7033
+ }
7034
+ return false;
7035
+ }
7036
+
7037
+ _shouldAutoSubmitOnSelect() {
7038
+ if (typeof this.surveyOptions.autoSubmitOnSelect === 'boolean') {
7039
+ return this.surveyOptions.autoSubmitOnSelect;
7040
+ }
7041
+ if (this._isMultiPageSurvey()) {
7042
+ return false;
7043
+ }
7044
+ if (this.surveyOptions.showSubmitButton === true) {
7045
+ return false;
7046
+ }
7047
+ return this._isRatingSurveyType() && !this._shouldShowFeedbackInput();
7048
+ }
7049
+
7050
+ _shouldShowActions() {
7051
+ if (this._isMultiPageSurvey()) {
7052
+ return true;
7053
+ }
7054
+ if (typeof this.surveyOptions.showSubmitButton === 'boolean') {
7055
+ return this.surveyOptions.showSubmitButton;
7056
+ }
7057
+ return !this._shouldAutoSubmitOnSelect();
7058
+ }
7059
+
6906
7060
  _isMultiPageSurvey() {
6907
7061
  return (
6908
7062
  Array.isArray(this.surveyOptions.pages) &&
@@ -6917,7 +7071,9 @@
6917
7071
 
6918
7072
  _isLastPage() {
6919
7073
  if (!this._isMultiPageSurvey()) return true;
6920
- return this.surveyState.currentPageIndex >= this.surveyOptions.pages.length - 1;
7074
+ return (
7075
+ this.surveyState.currentPageIndex >= this.surveyOptions.pages.length - 1
7076
+ );
6921
7077
  }
6922
7078
 
6923
7079
  _getCurrentPageConfig() {
@@ -6928,10 +7084,7 @@
6928
7084
 
6929
7085
  return {
6930
7086
  title: page.title || this.surveyOptions.title || 'Quick Feedback',
6931
- description:
6932
- page.description ||
6933
- this.surveyOptions.description ||
6934
- 'Help us improve by answering this question.',
7087
+ description: page.description || this.surveyOptions.description || '',
6935
7088
  html: this._renderSurveyPage(page),
6936
7089
  };
6937
7090
  }
@@ -6939,9 +7092,7 @@
6939
7092
  _getFallbackSurveyConfig() {
6940
7093
  return {
6941
7094
  title: this.surveyOptions.title || 'Quick Feedback',
6942
- description:
6943
- this.surveyOptions.description ||
6944
- 'Help us improve by answering a few questions.',
7095
+ description: this.surveyOptions.description || '',
6945
7096
  html: this._renderCustomQuestions(),
6946
7097
  };
6947
7098
  }
@@ -6963,24 +7114,48 @@
6963
7114
  const pageId = page.id || `page_${this.surveyState.currentPageIndex}`;
6964
7115
  const config = page.ratingConfig || page.rating_config || {};
6965
7116
  const scale = Number(config.scale) || 5;
6966
- const ratingType = config.survey_type || this.surveyOptions.surveyType || 'csat';
7117
+ const ratingType =
7118
+ config.survey_type || this.surveyOptions.surveyType || 'csat';
6967
7119
  const pageAnswer = this.surveyState.pageAnswers[pageId] || {};
6968
7120
  const currentRating = pageAnswer.rating;
6969
-
6970
- const labels = `
6971
- <div class="feedback-survey-labels">
6972
- <span>${config.low_label || this.surveyOptions.lowLabel || ''}</span>
6973
- <span>${config.high_label || this.surveyOptions.highLabel || ''}</span>
6974
- </div>
6975
- `;
6976
-
6977
- if (scale === 11 || ratingType === 'nps') {
7121
+ const defaultLowLabel =
7122
+ ratingType === 'nps'
7123
+ ? scale === 11
7124
+ ? 'Not likely'
7125
+ : 'Strongly Disagree'
7126
+ : '';
7127
+ const defaultHighLabel =
7128
+ ratingType === 'nps'
7129
+ ? scale === 11
7130
+ ? 'Very likely'
7131
+ : 'Strongly Agree'
7132
+ : '';
7133
+ const lowLabel =
7134
+ config.low_label || this.surveyOptions.lowLabel || defaultLowLabel;
7135
+ const highLabel =
7136
+ config.high_label || this.surveyOptions.highLabel || defaultHighLabel;
7137
+ const labels = this._renderScaleLabels(lowLabel, highLabel);
7138
+
7139
+ if (ratingType === 'nps') {
7140
+ const npsScale = Number.isFinite(scale) && scale >= 2 ? scale : 5;
7141
+ const start = npsScale === 11 ? 0 : 1;
7142
+ const values = Array.from(
7143
+ { length: npsScale },
7144
+ (_, index) => start + index
7145
+ );
7146
+ const usesSegmentedScale = values.length <= 7;
7147
+ const containerClass = usesSegmentedScale
7148
+ ? 'feedback-survey-ces feedback-survey-rating-scale'
7149
+ : 'feedback-survey-nps';
7150
+ const buttonClass = usesSegmentedScale
7151
+ ? 'feedback-survey-page-rating-btn feedback-survey-nps-btn feedback-survey-ces-btn feedback-survey-rating-scale-btn'
7152
+ : 'feedback-survey-page-rating-btn feedback-survey-nps-btn';
6978
7153
  return `
6979
- <div class="feedback-survey-nps" data-page-id="${pageId}">
6980
- ${[...Array(11).keys()]
7154
+ <div class="${containerClass}" data-page-id="${pageId}">
7155
+ ${values
6981
7156
  .map((n) => {
6982
7157
  const selected = currentRating === n ? ' selected' : '';
6983
- return `<button class="feedback-survey-page-rating-btn feedback-survey-nps-btn${selected}" data-page-id="${pageId}" data-score="${n}">${n}</button>`;
7158
+ return `<button class="${buttonClass}${selected}" data-page-id="${pageId}" data-score="${n}">${n}</button>`;
6984
7159
  })
6985
7160
  .join('')}
6986
7161
  </div>
@@ -7011,12 +7186,12 @@
7011
7186
  }
7012
7187
 
7013
7188
  return `
7014
- <div class="feedback-survey-ces" data-page-id="${pageId}">
7189
+ <div class="feedback-survey-ces feedback-survey-rating-scale" data-page-id="${pageId}">
7015
7190
  ${[...Array(scale).keys()]
7016
7191
  .map((i) => {
7017
7192
  const score = i + 1;
7018
7193
  const selected = currentRating === score ? ' selected' : '';
7019
- return `<button class="feedback-survey-page-rating-btn feedback-survey-ces-btn${selected}" data-page-id="${pageId}" data-score="${score}">${score}</button>`;
7194
+ return `<button class="feedback-survey-page-rating-btn feedback-survey-ces-btn feedback-survey-rating-scale-btn${selected}" data-page-id="${pageId}" data-score="${score}">${score}</button>`;
7020
7195
  })
7021
7196
  .join('')}
7022
7197
  </div>
@@ -7026,9 +7201,11 @@
7026
7201
 
7027
7202
  _renderMultipleChoicePage(page) {
7028
7203
  const pageId = page.id || `page_${this.surveyState.currentPageIndex}`;
7029
- const config = page.multipleChoiceConfig || page.multiple_choice_config || {};
7204
+ const config =
7205
+ page.multipleChoiceConfig || page.multiple_choice_config || {};
7030
7206
  const options = Array.isArray(config.options) ? config.options : [];
7031
- const allowMultiple = config.allow_multiple === true || config.multiple === true;
7207
+ const allowMultiple =
7208
+ config.allow_multiple === true || config.multiple === true;
7032
7209
  const pageAnswer = this.surveyState.pageAnswers[pageId] || {};
7033
7210
  const selectedValues = Array.isArray(pageAnswer.values)
7034
7211
  ? pageAnswer.values
@@ -7133,7 +7310,9 @@
7133
7310
  const submitBtn = this.surveyElement.querySelector(
7134
7311
  '.feedback-survey-submit'
7135
7312
  );
7136
- submitBtn.addEventListener('click', () => this._handleSubmit());
7313
+ if (submitBtn) {
7314
+ submitBtn.addEventListener('click', () => this._handleSubmit());
7315
+ }
7137
7316
 
7138
7317
  const backBtn = this.surveyElement.querySelector('.feedback-survey-back');
7139
7318
  if (backBtn) {
@@ -7143,9 +7322,11 @@
7143
7322
  const textarea = this.surveyElement.querySelector(
7144
7323
  '.feedback-survey-textarea'
7145
7324
  );
7146
- textarea.addEventListener('input', (e) => {
7147
- this.surveyState.feedback = e.target.value;
7148
- });
7325
+ if (textarea) {
7326
+ textarea.addEventListener('input', (e) => {
7327
+ this.surveyState.feedback = e.target.value;
7328
+ });
7329
+ }
7149
7330
 
7150
7331
  this._attachTypeSpecificEvents();
7151
7332
 
@@ -7317,6 +7498,7 @@
7317
7498
  btn.classList.remove('selected');
7318
7499
  }
7319
7500
  });
7501
+ this._maybeAutoSubmit();
7320
7502
  }
7321
7503
 
7322
7504
  _selectCSAT(score) {
@@ -7331,6 +7513,7 @@
7331
7513
  btn.classList.remove('selected');
7332
7514
  }
7333
7515
  });
7516
+ this._maybeAutoSubmit();
7334
7517
  }
7335
7518
 
7336
7519
  _selectCES(score) {
@@ -7345,6 +7528,14 @@
7345
7528
  btn.classList.remove('selected');
7346
7529
  }
7347
7530
  });
7531
+ this._maybeAutoSubmit();
7532
+ }
7533
+
7534
+ _maybeAutoSubmit() {
7535
+ if (!this._shouldAutoSubmitOnSelect()) {
7536
+ return;
7537
+ }
7538
+ this._handleSubmit();
7348
7539
  }
7349
7540
 
7350
7541
  _selectFrequency(freq) {
@@ -7362,6 +7553,9 @@
7362
7553
 
7363
7554
  async _handleSubmit() {
7364
7555
  const type = this.surveyOptions.surveyType;
7556
+ if (this.surveyState.isSubmitting) {
7557
+ return;
7558
+ }
7365
7559
 
7366
7560
  if (this._isMultiPageSurvey()) {
7367
7561
  if (!this._validateCurrentPage()) {
@@ -7369,7 +7563,10 @@
7369
7563
  }
7370
7564
 
7371
7565
  const nextPageIndex = this._getNextPageIndex();
7372
- if (nextPageIndex !== -1 && nextPageIndex !== this.surveyState.currentPageIndex) {
7566
+ if (
7567
+ nextPageIndex !== -1 &&
7568
+ nextPageIndex !== this.surveyState.currentPageIndex
7569
+ ) {
7373
7570
  this.surveyState.currentPageIndex = nextPageIndex;
7374
7571
  this._renderSurvey();
7375
7572
  return;
@@ -7385,6 +7582,8 @@
7385
7582
  return;
7386
7583
  }
7387
7584
 
7585
+ this.surveyState.isSubmitting = true;
7586
+
7388
7587
  const respondent = this._getRespondentContext();
7389
7588
  const normalizedPageAnswers = this._normalizePageAnswersForSubmit();
7390
7589
  const mergedAnswers = {
@@ -7411,16 +7610,18 @@
7411
7610
  timestamp: new Date().toISOString(),
7412
7611
  };
7413
7612
 
7414
- if (this.surveyOptions.onSubmit) {
7415
- this.surveyOptions.onSubmit(response);
7416
- }
7417
-
7418
7613
  try {
7614
+ if (this.surveyOptions.onSubmit) {
7615
+ this.surveyOptions.onSubmit(response);
7616
+ }
7617
+
7419
7618
  const surveyId =
7420
7619
  this.surveyOptions.surveyId || `local_${type}_${Date.now()}`;
7421
7620
  await this.apiService.submitSurveyResponse(surveyId, responseData);
7422
7621
  } catch (error) {
7423
7622
  console.error('[SurveyWidget] Failed to submit survey:', error);
7623
+ } finally {
7624
+ this.surveyState.isSubmitting = false;
7424
7625
  }
7425
7626
 
7426
7627
  this.sdk.eventBus.emit('survey:submitted', { widget: this, response });
@@ -7528,7 +7729,8 @@
7528
7729
  }
7529
7730
 
7530
7731
  for (const page of this.surveyOptions.pages) {
7531
- const pageId = page.id || `page_${this.surveyOptions.pages.indexOf(page)}`;
7732
+ const pageId =
7733
+ page.id || `page_${this.surveyOptions.pages.indexOf(page)}`;
7532
7734
  const answer = this.surveyState.pageAnswers[pageId];
7533
7735
  if (answer && typeof answer.rating === 'number') {
7534
7736
  return answer.rating;
@@ -7540,7 +7742,9 @@
7540
7742
 
7541
7743
  _normalizePageAnswersForSubmit() {
7542
7744
  const output = {};
7543
- for (const [pageId, answer] of Object.entries(this.surveyState.pageAnswers)) {
7745
+ for (const [pageId, answer] of Object.entries(
7746
+ this.surveyState.pageAnswers
7747
+ )) {
7544
7748
  if (answer == null) continue;
7545
7749
  if (Array.isArray(answer.values) && answer.values.length > 0) {
7546
7750
  output[pageId] = answer.values;
@@ -7567,8 +7771,7 @@
7567
7771
  ? this.sdk.getUserContext() || {}
7568
7772
  : {};
7569
7773
  const apiUserContext =
7570
- this.apiService &&
7571
- typeof this.apiService.getUserContext === 'function'
7774
+ this.apiService && typeof this.apiService.getUserContext === 'function'
7572
7775
  ? this.apiService.getUserContext() || {}
7573
7776
  : {};
7574
7777
  const localUserContext = this.options.userContext || {};
@@ -7616,7 +7819,15 @@
7616
7819
  const submitBtn = this.surveyElement.querySelector(
7617
7820
  '.feedback-survey-submit'
7618
7821
  );
7619
- submitBtn.parentNode.insertBefore(error, submitBtn);
7822
+ const actions = this.surveyElement.querySelector(
7823
+ '.feedback-survey-actions'
7824
+ );
7825
+ const anchor = submitBtn || actions;
7826
+ if (anchor && anchor.parentNode) {
7827
+ anchor.parentNode.insertBefore(error, anchor);
7828
+ } else {
7829
+ this.surveyElement.appendChild(error);
7830
+ }
7620
7831
 
7621
7832
  setTimeout(() => error.remove(), 3000);
7622
7833
  }
@@ -7679,6 +7890,7 @@
7679
7890
  customAnswers: {},
7680
7891
  pageAnswers: {},
7681
7892
  currentPageIndex: 0,
7893
+ isSubmitting: false,
7682
7894
  isVisible: false,
7683
7895
  };
7684
7896
  }
@@ -7940,6 +8152,16 @@
7940
8152
  description: surveyConfig.description,
7941
8153
  lowLabel: surveyConfig.lowLabel || surveyConfig.low_label,
7942
8154
  highLabel: surveyConfig.highLabel || surveyConfig.high_label,
8155
+ ratingScale: surveyConfig.ratingScale ?? surveyConfig.rating_scale,
8156
+ showFeedbackInput:
8157
+ surveyConfig.showFeedbackInput ?? surveyConfig.show_feedback_input,
8158
+ showSubmitButton:
8159
+ surveyConfig.showSubmitButton ?? surveyConfig.show_submit_button,
8160
+ autoSubmitOnSelect:
8161
+ surveyConfig.autoSubmitOnSelect ?? surveyConfig.auto_submit_on_select,
8162
+ showTitle: surveyConfig.showTitle ?? surveyConfig.show_title,
8163
+ showDescription:
8164
+ surveyConfig.showDescription ?? surveyConfig.show_description,
7943
8165
  customQuestions: surveyConfig.customQuestions || surveyConfig.questions,
7944
8166
  pages: surveyConfig.pages,
7945
8167
  ...displayOptions,
@@ -7966,13 +8188,20 @@
7966
8188
 
7967
8189
  const surveyWidget = this.createWidget('survey', {
7968
8190
  surveyId: normalizedOptions.surveyId,
7969
- surveyType: normalizedOptions.surveyType || normalizedOptions.type || 'nps',
8191
+ surveyType:
8192
+ normalizedOptions.surveyType || normalizedOptions.type || 'nps',
7970
8193
  position: normalizedOptions.position || 'bottom-right',
7971
8194
  theme: normalizedOptions.theme || this.config.theme || 'light',
7972
8195
  title: normalizedOptions.title,
7973
8196
  description: normalizedOptions.description,
7974
8197
  lowLabel: normalizedOptions.lowLabel,
7975
8198
  highLabel: normalizedOptions.highLabel,
8199
+ ratingScale: normalizedOptions.ratingScale ?? normalizedOptions.scale,
8200
+ showFeedbackInput: normalizedOptions.showFeedbackInput,
8201
+ showSubmitButton: normalizedOptions.showSubmitButton,
8202
+ autoSubmitOnSelect: normalizedOptions.autoSubmitOnSelect,
8203
+ showTitle: normalizedOptions.showTitle,
8204
+ showDescription: normalizedOptions.showDescription,
7976
8205
  customQuestions: normalizedOptions.customQuestions,
7977
8206
  pages: normalizedOptions.pages,
7978
8207
  respondentId: normalizedOptions.respondentId,
@@ -7988,7 +8217,10 @@
7988
8217
  }
7989
8218
 
7990
8219
  _isSurveyEligible(survey = {}) {
7991
- const shouldShow = this._getSurveyField(survey, ['shouldShow', 'should_show']);
8220
+ const shouldShow = this._getSurveyField(survey, [
8221
+ 'shouldShow',
8222
+ 'should_show',
8223
+ ]);
7992
8224
  if (typeof shouldShow === 'boolean') {
7993
8225
  return shouldShow;
7994
8226
  }
@@ -8010,7 +8242,10 @@
8010
8242
  return eligible;
8011
8243
  }
8012
8244
 
8013
- const isAnswered = this._getSurveyField(survey, ['isAnswered', 'is_answered']);
8245
+ const isAnswered = this._getSurveyField(survey, [
8246
+ 'isAnswered',
8247
+ 'is_answered',
8248
+ ]);
8014
8249
  if (typeof isAnswered === 'boolean') {
8015
8250
  return !isAnswered;
8016
8251
  }
@@ -8045,7 +8280,10 @@
8045
8280
  return eligibilityReason;
8046
8281
  }
8047
8282
 
8048
- const isAnswered = this._getSurveyField(survey, ['isAnswered', 'is_answered']);
8283
+ const isAnswered = this._getSurveyField(survey, [
8284
+ 'isAnswered',
8285
+ 'is_answered',
8286
+ ]);
8049
8287
  if (isAnswered === true) {
8050
8288
  return 'already_answered';
8051
8289
  }
@@ -8054,17 +8292,16 @@
8054
8292
  }
8055
8293
 
8056
8294
  _normalizeSurveyConfig(survey = {}) {
8057
- const firstPage = Array.isArray(survey.pages) && survey.pages.length > 0
8058
- ? survey.pages[0]
8059
- : null;
8295
+ const firstPage =
8296
+ Array.isArray(survey.pages) && survey.pages.length > 0
8297
+ ? survey.pages[0]
8298
+ : null;
8060
8299
  const ratingConfig = firstPage
8061
8300
  ? firstPage.rating_config || firstPage.ratingConfig || {}
8062
8301
  : {};
8063
8302
 
8064
8303
  const inferredType =
8065
- survey.type ||
8066
- this._inferSurveyTypeFromPage(firstPage) ||
8067
- 'nps';
8304
+ survey.type || this._inferSurveyTypeFromPage(firstPage) || 'nps';
8068
8305
 
8069
8306
  return {
8070
8307
  ...survey,
@@ -8078,22 +8315,27 @@
8078
8315
  survey.reason ||
8079
8316
  (survey.eligibility ? survey.eligibility.reason : undefined),
8080
8317
  title:
8081
- survey.title ||
8082
- survey.name ||
8083
- (firstPage ? firstPage.title : null),
8318
+ survey.title || survey.name || (firstPage ? firstPage.title : null),
8084
8319
  description:
8085
- survey.description ||
8086
- (firstPage ? firstPage.description : null),
8320
+ survey.description || (firstPage ? firstPage.description : null),
8087
8321
  lowLabel:
8088
- survey.lowLabel ||
8089
- survey.low_label ||
8090
- ratingConfig.low_label ||
8091
- null,
8322
+ survey.lowLabel || survey.low_label || ratingConfig.low_label || null,
8092
8323
  highLabel:
8093
8324
  survey.highLabel ||
8094
8325
  survey.high_label ||
8095
8326
  ratingConfig.high_label ||
8096
8327
  null,
8328
+ ratingScale:
8329
+ survey.ratingScale ?? survey.rating_scale ?? ratingConfig.scale ?? null,
8330
+ showFeedbackInput:
8331
+ survey.showFeedbackInput ?? survey.show_feedback_input ?? null,
8332
+ showSubmitButton:
8333
+ survey.showSubmitButton ?? survey.show_submit_button ?? null,
8334
+ autoSubmitOnSelect:
8335
+ survey.autoSubmitOnSelect ?? survey.auto_submit_on_select ?? null,
8336
+ showTitle: survey.showTitle ?? survey.show_title ?? null,
8337
+ showDescription:
8338
+ survey.showDescription ?? survey.show_description ?? null,
8097
8339
  customQuestions: survey.customQuestions || survey.questions || [],
8098
8340
  pages: this._normalizeSurveyPages(survey.pages || []),
8099
8341
  };
@@ -8106,17 +8348,17 @@
8106
8348
 
8107
8349
  return pages
8108
8350
  .map((page, index) => ({
8109
- id: page.id || `page_${index}`,
8110
- type: page.type || 'rating',
8111
- title: page.title || '',
8112
- description: page.description || '',
8113
- required: page.required !== false,
8114
- position: page.position ?? index,
8115
- ratingConfig: page.ratingConfig || page.rating_config || null,
8116
- multipleChoiceConfig:
8117
- page.multipleChoiceConfig || page.multiple_choice_config || null,
8118
- linkConfig: page.linkConfig || page.link_config || null,
8119
- afterThisPage: page.afterThisPage || page.after_this_page || null,
8351
+ id: page.id || `page_${index}`,
8352
+ type: page.type || 'rating',
8353
+ title: page.title || '',
8354
+ description: page.description || '',
8355
+ required: page.required !== false,
8356
+ position: page.position ?? index,
8357
+ ratingConfig: page.ratingConfig || page.rating_config || null,
8358
+ multipleChoiceConfig:
8359
+ page.multipleChoiceConfig || page.multiple_choice_config || null,
8360
+ linkConfig: page.linkConfig || page.link_config || null,
8361
+ afterThisPage: page.afterThisPage || page.after_this_page || null,
8120
8362
  }))
8121
8363
  .sort((a, b) => a.position - b.position);
8122
8364
  }
@@ -8632,8 +8874,8 @@
8632
8874
  width: 100%;
8633
8875
  max-width: 580px;
8634
8876
  max-height: 90vh;
8635
- background: #DBEAFE;
8636
- border-radius: var(--radius-4xl);
8877
+ background: var(--color-primary-light);
8878
+ border-radius: 10px;
8637
8879
  overflow: hidden;
8638
8880
  box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px, rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
8639
8881
  transform: scale(0.95) translateY(20px);
@@ -8650,28 +8892,30 @@
8650
8892
  position: absolute;
8651
8893
  top: var(--spacing-4);
8652
8894
  right: var(--spacing-4);
8653
- background: rgba(255, 255, 255, 0.9);
8895
+ background: none;
8654
8896
  border: none;
8655
- font-size: 24px;
8656
8897
  cursor: pointer;
8657
8898
  color: var(--color-neutral-500);
8658
8899
  padding: 0;
8659
- width: 36px;
8660
- height: 36px;
8900
+ width: 20px;
8901
+ height: 20px;
8661
8902
  display: flex;
8662
8903
  align-items: center;
8663
8904
  justify-content: center;
8664
- border-radius: var(--radius-full);
8905
+ border-radius: 8px;
8665
8906
  transition: all var(--transition-base);
8666
8907
  line-height: 1;
8667
8908
  z-index: 10;
8668
- box-shadow: var(--shadow-md);
8669
8909
  }
8670
8910
 
8671
8911
  .changelog-modal-close:hover {
8672
- background: var(--color-white);
8912
+ background: var(--color-neutral-100);
8673
8913
  color: var(--color-neutral-900);
8674
- transform: scale(1.05);
8914
+ }
8915
+
8916
+ .changelog-modal-close svg {
8917
+ width: 18px;
8918
+ height: 18px;
8675
8919
  }
8676
8920
 
8677
8921
  .changelog-modal-content {
@@ -8725,7 +8969,7 @@
8725
8969
  height: auto;
8726
8970
  display: block;
8727
8971
  object-fit: cover;
8728
- border-radius: var(--radius-xl);
8972
+ border-radius: 8px;
8729
8973
  border: 2px solid var(--color-primary);
8730
8974
  box-shadow: 0 4px 20px rgba(21, 94, 239, 0.2);
8731
8975
  }
@@ -8738,7 +8982,7 @@
8738
8982
  .changelog-popup-title {
8739
8983
  margin: 0 0 var(--spacing-3);
8740
8984
  font-size: var(--font-size-xl);
8741
- font-weight: var(--font-weight-bold);
8985
+ font-weight: var(--font-weight-semibold);
8742
8986
  line-height: var(--line-height-snug);
8743
8987
  color: var(--color-neutral-900);
8744
8988
  }
@@ -8756,11 +9000,11 @@
8756
9000
  justify-content: center;
8757
9001
  padding: var(--spacing-3) var(--spacing-8);
8758
9002
  font-size: var(--font-size-base);
8759
- font-weight: var(--font-weight-semibold);
9003
+ font-weight: var(--font-weight-medium);
8760
9004
  color: var(--color-white);
8761
9005
  background: var(--color-primary);
8762
9006
  border: 1px solid var(--color-primary);
8763
- border-radius: var(--radius-md);
9007
+ border-radius: 8px;
8764
9008
  cursor: pointer;
8765
9009
  transition: all var(--transition-base);
8766
9010
  font-family: inherit;
@@ -8823,7 +9067,7 @@
8823
9067
  font-weight: var(--font-weight-medium);
8824
9068
  cursor: pointer;
8825
9069
  padding: var(--spacing-2) var(--spacing-3);
8826
- border-radius: var(--radius-md);
9070
+ border-radius: 8px;
8827
9071
  transition: all var(--transition-base);
8828
9072
  font-family: inherit;
8829
9073
  }
@@ -8869,7 +9113,7 @@
8869
9113
  max-width: 460px;
8870
9114
  max-height: 85vh;
8871
9115
  background: var(--color-white);
8872
- border-radius: var(--radius-2xl);
9116
+ border-radius: 10px;
8873
9117
  overflow: hidden;
8874
9118
  box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px, rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
8875
9119
  transform: scale(0.95) translateY(20px);
@@ -8896,7 +9140,7 @@
8896
9140
 
8897
9141
  .changelog-list-modal-header h2 {
8898
9142
  margin: 0;
8899
- font-size: var(--font-size-lg);
9143
+ font-size: var(--font-size-md);
8900
9144
  font-weight: var(--font-weight-semibold);
8901
9145
  color: var(--color-text-primary);
8902
9146
  }
@@ -8906,16 +9150,21 @@
8906
9150
  border: none;
8907
9151
  cursor: pointer;
8908
9152
  color: var(--color-neutral-500);
8909
- padding: var(--spacing-1);
8910
- width: 28px;
8911
- height: 28px;
9153
+ padding: 0;
9154
+ width: 20px;
9155
+ height: 20px;
8912
9156
  display: flex;
8913
9157
  align-items: center;
8914
9158
  justify-content: center;
8915
- border-radius: var(--radius-md);
9159
+ border-radius: 8px;
8916
9160
  transition: all var(--transition-base);
8917
9161
  }
8918
9162
 
9163
+ .changelog-list-modal-close svg {
9164
+ width: 18px;
9165
+ height: 18px;
9166
+ }
9167
+
8919
9168
  .changelog-list-modal-close:hover {
8920
9169
  background: var(--color-neutral-100);
8921
9170
  color: var(--color-neutral-900);
@@ -8955,7 +9204,7 @@
8955
9204
  .changelog-list-item-image {
8956
9205
  width: 100%;
8957
9206
  margin-bottom: var(--spacing-2);
8958
- border-radius: var(--radius-md);
9207
+ border-radius: 8px;
8959
9208
  overflow: hidden;
8960
9209
  border: 1px solid var(--color-border);
8961
9210
  }
@@ -9042,7 +9291,7 @@
9042
9291
 
9043
9292
  .changelog-modal-container {
9044
9293
  max-width: 100%;
9045
- border-radius: var(--radius-3xl);
9294
+ border-radius: 10px;
9046
9295
  }
9047
9296
 
9048
9297
  .changelog-popup-image {
@@ -9054,7 +9303,7 @@
9054
9303
  }
9055
9304
 
9056
9305
  .changelog-popup-title {
9057
- font-size: var(--font-size-xl);
9306
+ font-size: var(--font-size-lg);
9058
9307
  }
9059
9308
 
9060
9309
  .changelog-popup-description {
@@ -9078,7 +9327,7 @@
9078
9327
  .changelog-list-modal-container {
9079
9328
  max-width: 100%;
9080
9329
  max-height: 90vh;
9081
- border-radius: var(--radius-2xl);
9330
+ border-radius: 10px;
9082
9331
  }
9083
9332
 
9084
9333
  .changelog-list-item {
@@ -9097,7 +9346,7 @@
9097
9346
  align-items: center;
9098
9347
  justify-content: center;
9099
9348
  gap: var(--spacing-2);
9100
- border-radius: var(--radius-md);
9349
+ border-radius: 8px;
9101
9350
  border: none;
9102
9351
  font-size: var(--font-size-md);
9103
9352
  font-weight: var(--font-weight-medium);
@@ -9121,7 +9370,7 @@
9121
9370
  background: var(--color-primary);
9122
9371
  color: var(--color-white);
9123
9372
  border: 1px solid var(--color-primary);
9124
- border-radius: var(--radius-md);
9373
+ border-radius: 8px;
9125
9374
  font-size: var(--font-size-base);
9126
9375
  font-weight: var(--font-weight-medium);
9127
9376
  height: 44px;
@@ -9188,7 +9437,7 @@
9188
9437
  height: 36px;
9189
9438
  border: none;
9190
9439
  background: none;
9191
- border-radius: var(--radius-md);
9440
+ border-radius: 8px;
9192
9441
  cursor: pointer;
9193
9442
  color: var(--color-text-secondary);
9194
9443
  transition: all var(--transition-base);
@@ -9203,7 +9452,7 @@
9203
9452
  .sdk-input {
9204
9453
  width: 100%;
9205
9454
  height: 44px;
9206
- border-radius: var(--radius-md);
9455
+ border-radius: 8px;
9207
9456
  border: 1px solid var(--color-border);
9208
9457
  padding: 10px 14px;
9209
9458
  font-size: var(--font-size-md);
@@ -9234,7 +9483,7 @@
9234
9483
  width: 100%;
9235
9484
  min-height: 120px;
9236
9485
  resize: vertical;
9237
- border-radius: var(--radius-md);
9486
+ border-radius: 8px;
9238
9487
  border: 1px solid var(--color-border);
9239
9488
  padding: 10px 14px;
9240
9489
  font-size: var(--font-size-md);
@@ -9259,7 +9508,7 @@
9259
9508
  .sdk-select {
9260
9509
  width: 100%;
9261
9510
  height: 44px;
9262
- border-radius: var(--radius-md);
9511
+ border-radius: 8px;
9263
9512
  border: 1px solid var(--color-border);
9264
9513
  padding: 10px 14px;
9265
9514
  font-size: var(--font-size-md);
@@ -9297,7 +9546,7 @@
9297
9546
 
9298
9547
  .sdk-card {
9299
9548
  background: var(--color-white);
9300
- border-radius: var(--radius-xl);
9549
+ border-radius: 10px;
9301
9550
  box-shadow: var(--shadow-base);
9302
9551
  overflow: hidden;
9303
9552
  }
@@ -9358,7 +9607,7 @@
9358
9607
  max-width: 580px;
9359
9608
  max-height: 90vh;
9360
9609
  background: var(--color-white);
9361
- border-radius: var(--radius-4xl);
9610
+ border-radius: 10px;
9362
9611
  overflow: hidden;
9363
9612
  box-shadow: var(--shadow-2xl);
9364
9613
  transform: scale(0.95) translateY(20px);
@@ -9394,15 +9643,18 @@
9394
9643
  .sdk-close-btn {
9395
9644
  background: none;
9396
9645
  border: none;
9397
- padding: var(--spacing-2);
9646
+ padding: 0;
9398
9647
  cursor: pointer;
9399
9648
  color: var(--color-neutral-500);
9400
9649
  display: flex;
9401
9650
  align-items: center;
9402
9651
  justify-content: center;
9403
- border-radius: var(--radius-md);
9652
+ width: 20px;
9653
+ height: 20px;
9654
+ border-radius: 8px;
9404
9655
  transition: all var(--transition-base);
9405
9656
  line-height: 1;
9657
+ flex-shrink: 0;
9406
9658
  }
9407
9659
 
9408
9660
  .sdk-close-btn:hover {
@@ -9410,6 +9662,11 @@
9410
9662
  color: var(--color-neutral-900);
9411
9663
  }
9412
9664
 
9665
+ .sdk-close-btn svg {
9666
+ width: 18px;
9667
+ height: 18px;
9668
+ }
9669
+
9413
9670
  .sdk-avatar {
9414
9671
  display: flex;
9415
9672
  align-items: center;
@@ -9496,7 +9753,7 @@
9496
9753
  right: var(--spacing-6);
9497
9754
  z-index: var(--z-notification);
9498
9755
  background: var(--color-white);
9499
- border-radius: var(--radius-xl);
9756
+ border-radius: 10px;
9500
9757
  box-shadow: var(--shadow-lg);
9501
9758
  min-width: 320px;
9502
9759
  animation: slideInRight 0.3s cubic-bezier(0.4, 0, 0.2, 1);
@@ -9586,7 +9843,7 @@
9586
9843
 
9587
9844
  .sdk-modal-container {
9588
9845
  max-width: 100%;
9589
- border-radius: var(--spacing-5);
9846
+ border-radius: 10px;
9590
9847
  }
9591
9848
 
9592
9849
  .sdk-notification {
@@ -9846,7 +10103,7 @@
9846
10103
  height: 100%;
9847
10104
  display: flex;
9848
10105
  flex-direction: column;
9849
- border-radius: var(--radius-2xl);
10106
+ border-radius: 10px;
9850
10107
  }
9851
10108
 
9852
10109
  .feedback-panel-header {
@@ -10215,6 +10472,17 @@
10215
10472
  display: none;
10216
10473
  }
10217
10474
 
10475
+ .messenger-compose-attach {
10476
+ width: 28px;
10477
+ height: 28px;
10478
+ flex-shrink: 0;
10479
+ }
10480
+
10481
+ .messenger-compose-attach svg {
10482
+ width: 20px;
10483
+ height: 20px;
10484
+ }
10485
+
10218
10486
  /* ========================================
10219
10487
  TYPING INDICATOR
10220
10488
  ======================================== */
@@ -10244,17 +10512,9 @@
10244
10512
  animation: messenger-typing-bounce 1.4s infinite ease-in-out;
10245
10513
  }
10246
10514
 
10247
- .messenger-typing-dots span:nth-child(1) {
10248
- animation-delay: -0.32s;
10249
- }
10250
-
10251
- .messenger-typing-dots span:nth-child(2) {
10252
- animation-delay: -0.16s;
10253
- }
10254
-
10255
- .messenger-typing-dots span:nth-child(3) {
10256
- animation-delay: 0s;
10257
- }
10515
+ .messenger-typing-dots span:nth-child(1) { animation-delay: -0.32s; }
10516
+ .messenger-typing-dots span:nth-child(2) { animation-delay: -0.16s; }
10517
+ .messenger-typing-dots span:nth-child(3) { animation-delay: 0s; }
10258
10518
 
10259
10519
  .messenger-typing-text {
10260
10520
  font-size: var(--font-size-xs);
@@ -10272,12 +10532,12 @@
10272
10532
 
10273
10533
  .messenger-nav-tabs {
10274
10534
  display: flex;
10275
- padding: var(--spacing-1) var(--spacing-2);
10535
+ padding: var(--spacing-1) var(--spacing-2) 0;
10276
10536
  gap: var(--spacing-1);
10277
10537
  }
10278
10538
 
10279
10539
  .messenger-nav-footer {
10280
- padding: var(--spacing-1) var(--spacing-2);
10540
+ padding: 2px var(--spacing-2) var(--spacing-2);
10281
10541
  text-align: center;
10282
10542
  }
10283
10543
 
@@ -10309,12 +10569,12 @@
10309
10569
  display: flex;
10310
10570
  flex-direction: column;
10311
10571
  align-items: center;
10312
- gap: 4px;
10313
- padding: var(--spacing-2) var(--spacing-1);
10572
+ gap: 2px;
10573
+ padding: var(--spacing-1) var(--spacing-1);
10314
10574
  background: none;
10315
10575
  border: none;
10316
10576
  cursor: pointer;
10317
- border-radius: var(--radius-md);
10577
+ border-radius: 8px;
10318
10578
  transition: all var(--transition-base);
10319
10579
  position: relative;
10320
10580
  }
@@ -10326,10 +10586,21 @@
10326
10586
  .messenger-nav-icon {
10327
10587
  color: var(--color-text-secondary);
10328
10588
  transition: color var(--transition-base);
10589
+ display: flex;
10590
+ align-items: center;
10591
+ justify-content: center;
10592
+ width: 20px;
10593
+ height: 20px;
10594
+ }
10595
+
10596
+ .messenger-nav-icon svg {
10597
+ width: 20px;
10598
+ height: 20px;
10599
+ display: block;
10329
10600
  }
10330
10601
 
10331
10602
  .messenger-nav-label {
10332
- font-size: var(--font-size-base);
10603
+ font-size: var(--font-size-xs);
10333
10604
  font-weight: var(--font-weight-medium);
10334
10605
  color: var(--color-text-secondary);
10335
10606
  transition: color var(--transition-base);
@@ -10381,7 +10652,7 @@
10381
10652
 
10382
10653
  .messenger-prechat-card {
10383
10654
  background: var(--color-white);
10384
- border-radius: var(--radius-2xl);
10655
+ border-radius: 10px;
10385
10656
  padding: var(--spacing-6);
10386
10657
  width: 100%;
10387
10658
  max-width: 360px;
@@ -11472,10 +11743,11 @@
11472
11743
  .feedback-survey {
11473
11744
  position: fixed;
11474
11745
  z-index: var(--z-modal);
11475
- background: var(--color-white);
11476
- border-radius: var(--radius-2xl);
11477
- box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px, rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
11478
- padding: var(--spacing-6);
11746
+ background: var(--color-neutral-50);
11747
+ border: 1px solid var(--color-neutral-300);
11748
+ border-radius: 10px;
11749
+ box-shadow: var(--shadow-lg);
11750
+ padding: var(--spacing-8);
11479
11751
  min-width: 320px;
11480
11752
  max-width: 400px;
11481
11753
  font-family: inherit;
@@ -11495,56 +11767,77 @@
11495
11767
  top: 50%;
11496
11768
  left: 50%;
11497
11769
  transform: translate(-50%, -50%);
11770
+ width: min(680px, calc(100vw - 24px));
11771
+ max-width: 680px;
11498
11772
  }
11499
11773
 
11500
11774
  .feedback-survey-bottom {
11501
11775
  bottom: 0;
11502
11776
  left: 0;
11503
11777
  right: 0;
11504
- border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
11778
+ border-radius: 10px 10px 0 0;
11505
11779
  max-width: none;
11506
11780
  }
11507
11781
 
11508
11782
  .feedback-survey-close {
11509
11783
  position: absolute;
11510
- top: var(--spacing-3);
11511
- right: var(--spacing-3);
11784
+ top: var(--spacing-4);
11785
+ right: var(--spacing-4);
11512
11786
  background: none;
11513
11787
  border: none;
11514
11788
  cursor: pointer;
11515
11789
  color: var(--color-neutral-500);
11516
11790
  padding: 0;
11517
- width: 28px;
11518
- height: 28px;
11791
+ width: 20px;
11792
+ height: 20px;
11519
11793
  display: flex;
11520
11794
  align-items: center;
11521
11795
  justify-content: center;
11522
- border-radius: var(--radius-md);
11796
+ border-radius: 8px;
11523
11797
  transition: all var(--transition-base);
11524
11798
  }
11525
11799
 
11800
+ .feedback-survey-close svg {
11801
+ width: 18px;
11802
+ height: 18px;
11803
+ }
11804
+
11526
11805
  .feedback-survey-close:hover {
11527
11806
  background: var(--color-neutral-100);
11528
11807
  color: var(--color-neutral-900);
11529
11808
  }
11530
11809
 
11810
+ .feedback-survey-close:focus-visible {
11811
+ outline: none;
11812
+ box-shadow: 0 0 0 3px var(--color-primary-light);
11813
+ }
11814
+
11531
11815
  .feedback-survey-title {
11532
11816
  margin: 0 0 var(--spacing-2) 0;
11533
11817
  font-size: var(--font-size-xl);
11534
- font-weight: var(--font-weight-bold);
11535
- padding-right: var(--spacing-6);
11818
+ font-weight: var(--font-weight-semibold);
11819
+ line-height: var(--line-height-snug);
11820
+ padding-right: var(--spacing-12);
11536
11821
  color: var(--color-text-primary);
11537
11822
  }
11538
11823
 
11539
11824
  .feedback-survey-description {
11540
11825
  color: var(--color-text-secondary);
11541
- margin: 0 0 var(--spacing-5) 0;
11542
- font-size: var(--font-size-base);
11826
+ margin: 0 0 var(--spacing-4) 0;
11827
+ font-size: var(--font-size-md);
11543
11828
  line-height: var(--line-height-relaxed);
11544
11829
  }
11545
11830
 
11831
+ .feedback-survey-description-primary .feedback-survey-description {
11832
+ color: var(--color-text-primary);
11833
+ font-size: var(--font-size-lg);
11834
+ font-weight: var(--font-weight-semibold);
11835
+ line-height: var(--line-height-snug);
11836
+ padding-right: var(--spacing-12);
11837
+ }
11838
+
11546
11839
  .feedback-survey-content {
11547
- margin-bottom: var(--spacing-4);
11840
+ margin-bottom: var(--spacing-3);
11548
11841
  }
11549
11842
 
11550
11843
  /* ========================================
@@ -11561,7 +11854,7 @@
11561
11854
  width: 28px;
11562
11855
  height: 36px;
11563
11856
  border: 1px solid var(--color-border);
11564
- border-radius: var(--radius-md);
11857
+ border-radius: 8px;
11565
11858
  background: var(--color-surface);
11566
11859
  cursor: pointer;
11567
11860
  font-size: var(--font-size-sm);
@@ -11572,8 +11865,8 @@
11572
11865
  }
11573
11866
 
11574
11867
  .feedback-survey-nps-btn:hover {
11575
- border-color: var(--color-primary);
11576
- background: var(--color-white);
11868
+ background: var(--color-neutral-100);
11869
+ border-color: var(--color-border);
11577
11870
  }
11578
11871
 
11579
11872
  .feedback-survey-nps-btn.selected {
@@ -11596,7 +11889,7 @@
11596
11889
  background: none;
11597
11890
  border: none;
11598
11891
  cursor: pointer;
11599
- font-size: 36px;
11892
+ font-size: 28px;
11600
11893
  transition: transform var(--transition-fast);
11601
11894
  padding: var(--spacing-2);
11602
11895
  }
@@ -11635,8 +11928,8 @@
11635
11928
  }
11636
11929
 
11637
11930
  .feedback-survey-ces-btn:hover {
11638
- border-color: var(--color-primary);
11639
- background: var(--color-white);
11931
+ background: var(--color-neutral-100);
11932
+ border-color: var(--color-border);
11640
11933
  }
11641
11934
 
11642
11935
  .feedback-survey-ces-btn.selected {
@@ -11645,6 +11938,56 @@
11645
11938
  color: var(--color-white);
11646
11939
  }
11647
11940
 
11941
+ .feedback-survey-rating-scale {
11942
+ display: flex;
11943
+ gap: 0;
11944
+ border: 1px solid var(--color-neutral-300);
11945
+ border-radius: 8px;
11946
+ overflow: hidden;
11947
+ background: var(--color-white);
11948
+ }
11949
+
11950
+ .feedback-survey-rating-scale-btn {
11951
+ flex: 1;
11952
+ width: auto;
11953
+ height: auto;
11954
+ min-height: 64px;
11955
+ padding: 0;
11956
+ border: 0;
11957
+ border-right: 1px solid var(--color-neutral-300);
11958
+ border-radius: 0;
11959
+ background: var(--color-white);
11960
+ cursor: pointer;
11961
+ font-size: clamp(16px, 3vw, 22px);
11962
+ font-weight: var(--font-weight-medium);
11963
+ color: var(--color-black);
11964
+ transition:
11965
+ background var(--transition-fast),
11966
+ color var(--transition-fast),
11967
+ box-shadow var(--transition-fast);
11968
+ position: relative;
11969
+ }
11970
+
11971
+ .feedback-survey-rating-scale-btn:last-child {
11972
+ border-right: none;
11973
+ }
11974
+
11975
+ .feedback-survey-rating-scale-btn:hover {
11976
+ background: var(--color-neutral-100);
11977
+ }
11978
+
11979
+ .feedback-survey-rating-scale-btn:focus-visible {
11980
+ outline: none;
11981
+ z-index: 1;
11982
+ box-shadow: inset 0 0 0 3px var(--color-primary);
11983
+ }
11984
+
11985
+ .feedback-survey-rating-scale-btn.selected {
11986
+ background: var(--color-primary-light);
11987
+ color: var(--color-primary-active);
11988
+ box-shadow: inset 0 0 0 2px var(--color-primary);
11989
+ }
11990
+
11648
11991
  .feedback-survey-labels {
11649
11992
  display: flex;
11650
11993
  justify-content: space-between;
@@ -11653,6 +11996,14 @@
11653
11996
  color: var(--color-text-tertiary);
11654
11997
  }
11655
11998
 
11999
+ .feedback-survey-rating-scale + .feedback-survey-labels {
12000
+ margin-top: var(--spacing-3);
12001
+ padding: 0 var(--spacing-1);
12002
+ font-size: var(--font-size-sm);
12003
+ font-weight: var(--font-weight-normal);
12004
+ color: var(--color-text-tertiary);
12005
+ }
12006
+
11656
12007
  /* ========================================
11657
12008
  FREQUENCY
11658
12009
  ======================================== */
@@ -11677,8 +12028,8 @@
11677
12028
  }
11678
12029
 
11679
12030
  .feedback-survey-freq-btn:hover {
11680
- border-color: var(--color-primary);
11681
- background: var(--color-white);
12031
+ background: var(--color-neutral-100);
12032
+ border-color: var(--color-border);
11682
12033
  }
11683
12034
 
11684
12035
  .feedback-survey-freq-btn.selected {
@@ -11835,7 +12186,7 @@
11835
12186
  border: 1px solid var(--color-primary);
11836
12187
  border-radius: var(--radius-md);
11837
12188
  font-size: var(--font-size-base);
11838
- font-weight: var(--font-weight-semibold);
12189
+ font-weight: var(--font-weight-medium);
11839
12190
  cursor: pointer;
11840
12191
  font-family: inherit;
11841
12192
  transition: all var(--transition-base);
@@ -11861,7 +12212,7 @@
11861
12212
  color: var(--color-white);
11862
12213
  padding: var(--spacing-3) var(--spacing-5);
11863
12214
  border-radius: var(--radius-xl);
11864
- font-size: var(--font-size-base);
12215
+ font-size: var(--font-size-sm);
11865
12216
  font-weight: var(--font-weight-medium);
11866
12217
  z-index: var(--z-notification);
11867
12218
  box-shadow: var(--shadow-lg);
@@ -11881,6 +12232,7 @@
11881
12232
  @media (max-width: 768px) {
11882
12233
  .feedback-survey {
11883
12234
  min-width: 300px;
12235
+ padding: var(--spacing-6);
11884
12236
  }
11885
12237
 
11886
12238
  .feedback-survey-bottom {
@@ -11894,7 +12246,24 @@
11894
12246
  }
11895
12247
 
11896
12248
  .feedback-survey-csat-btn {
11897
- font-size: 32px;
12249
+ font-size: 24px;
12250
+ }
12251
+
12252
+ .feedback-survey-title {
12253
+ font-size: var(--font-size-lg);
12254
+ }
12255
+
12256
+ .feedback-survey-description-primary .feedback-survey-description {
12257
+ font-size: var(--font-size-md);
12258
+ }
12259
+
12260
+ .feedback-survey-rating-scale-btn {
12261
+ min-height: 52px;
12262
+ font-size: clamp(14px, 6vw, 18px);
12263
+ }
12264
+
12265
+ .feedback-survey-rating-scale + .feedback-survey-labels {
12266
+ font-size: var(--font-size-xs);
11898
12267
  }
11899
12268
  }
11900
12269
  `;