@product7/feedback-sdk 1.5.3 → 1.5.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.
@@ -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">
@@ -5150,6 +5160,17 @@
5150
5160
  this.options = options;
5151
5161
  this.element = null;
5152
5162
  this._unsubscribe = null;
5163
+
5164
+ this._avatarColors = [
5165
+ { bg: '#EF4444', text: '#FFFFFF' },
5166
+ { bg: '#F97316', text: '#FFFFFF' },
5167
+ { bg: '#F59E0B', text: '#FFFFFF' },
5168
+ { bg: '#10B981', text: '#FFFFFF' },
5169
+ { bg: '#06B6D4', text: '#FFFFFF' },
5170
+ { bg: '#3B82F6', text: '#FFFFFF' },
5171
+ { bg: '#8B5CF6', text: '#FFFFFF' },
5172
+ { bg: '#EC4899', text: '#FFFFFF' },
5173
+ ];
5153
5174
  }
5154
5175
 
5155
5176
  render() {
@@ -5175,8 +5196,10 @@
5175
5196
  <div class="messenger-help-header-top">
5176
5197
  <h2>Help</h2>
5177
5198
  <button class="sdk-close-btn" aria-label="Close">
5178
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256">
5179
- <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>
5199
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="18" height="18">
5200
+ <rect width="256" height="256" fill="none"/>
5201
+ <line x1="200" y1="56" x2="56" y2="200" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
5202
+ <line x1="200" y1="200" x2="56" y2="56" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
5180
5203
  </svg>
5181
5204
  </button>
5182
5205
  </div>
@@ -5204,7 +5227,7 @@
5204
5227
  const collections = this.state.helpArticles || [];
5205
5228
  const searchQuery = (this.state.helpSearchQuery || '').toLowerCase();
5206
5229
 
5207
- const filteredCollections = searchQuery
5230
+ const filtered = searchQuery
5208
5231
  ? collections.filter(
5209
5232
  (c) =>
5210
5233
  c.title.toLowerCase().includes(searchQuery) ||
@@ -5212,41 +5235,119 @@
5212
5235
  )
5213
5236
  : collections;
5214
5237
 
5215
- const headerEl = this.element.querySelector(
5216
- '.messenger-help-collections-header'
5217
- );
5218
- if (headerEl) {
5219
- headerEl.textContent = `${filteredCollections.length} collections`;
5220
- }
5221
-
5222
- if (filteredCollections.length === 0) {
5238
+ if (filtered.length === 0) {
5223
5239
  collectionsContainer.innerHTML = this._renderEmptyState();
5224
5240
  return;
5225
5241
  }
5226
5242
 
5227
- collectionsContainer.innerHTML = filteredCollections
5228
- .map((collection) => this._renderCollectionItem(collection))
5243
+ collectionsContainer.innerHTML = filtered
5244
+ .map((c) => this._renderCollectionItem(c))
5229
5245
  .join('');
5230
5246
 
5247
+ // Resolve Phosphor icons async after render
5248
+ filtered.forEach((c) => {
5249
+ if (c.icon && !c.icon.startsWith('<svg')) {
5250
+ const item = collectionsContainer.querySelector(
5251
+ `[data-collection-id="${c.id}"] .messenger-help-collection-icon`
5252
+ );
5253
+ if (item) this._resolvePhosphorIcon(item, c.icon);
5254
+ }
5255
+ });
5256
+
5231
5257
  this._attachCollectionEvents();
5232
5258
  }
5233
5259
 
5234
5260
  _renderCollectionItem(collection) {
5235
- const articleCount = collection.articleCount || 0;
5261
+ const count = collection.article_count || collection.articleCount || 0;
5262
+ const icon = this._renderIcon(collection.icon);
5263
+ const avatar = this._renderAuthorAvatar(collection);
5264
+
5236
5265
  return `
5237
5266
  <div class="messenger-help-collection" data-collection-id="${collection.id}">
5238
- <div class="messenger-help-collection-content">
5267
+ <div class="messenger-help-collection-header">
5268
+ <div class="messenger-help-collection-icon">${icon}</div>
5239
5269
  <h3 class="messenger-help-collection-title">${collection.title}</h3>
5240
- <p class="messenger-help-collection-desc">${collection.description || ''}</p>
5241
- <span class="messenger-help-collection-count">${articleCount} articles</span>
5242
5270
  </div>
5243
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="#000000" viewBox="0 0 256 256" class="messenger-help-collection-arrow">
5244
- <path d="M181.66,133.66l-80,80a8,8,0,0,1-11.32-11.32L164.69,128,90.34,53.66a8,8,0,0,1,11.32-11.32l80,80A8,8,0,0,1,181.66,133.66Z"></path>
5245
- </svg>
5271
+ ${
5272
+ collection.description
5273
+ ? `<p class="messenger-help-collection-desc">${collection.description}</p>`
5274
+ : ''
5275
+ }
5276
+ <div class="messenger-help-collection-footer">
5277
+ ${avatar}
5278
+ <span>${count} ${count === 1 ? 'article' : 'articles'}</span>
5279
+ </div>
5246
5280
  </div>
5247
5281
  `;
5248
5282
  }
5249
5283
 
5284
+ _renderIcon(icon) {
5285
+ if (!icon) return this._getFolderIcon();
5286
+ if (icon.startsWith('<svg')) return icon;
5287
+ // Iconify string — render placeholder, then fetch async
5288
+ return this._getFolderIcon();
5289
+ }
5290
+
5291
+ async _resolvePhosphorIcon(el, iconStr) {
5292
+ // iconStr e.g. "ph:house-line-duotone"
5293
+ const [set, name] = iconStr.split(':');
5294
+ if (!set || !name) return;
5295
+ try {
5296
+ const res = await fetch(`https://api.iconify.design/${set}/${name}.svg`);
5297
+ if (!res.ok) return;
5298
+ const svg = await res.text();
5299
+ if (svg && svg.startsWith('<svg')) {
5300
+ el.innerHTML = svg;
5301
+ const s = el.querySelector('svg');
5302
+ if (s) {
5303
+ s.setAttribute('width', '16');
5304
+ s.setAttribute('height', '16');
5305
+ }
5306
+ }
5307
+ } catch (e) {
5308
+ // keep fallback folder icon
5309
+ }
5310
+ }
5311
+
5312
+ _getFolderIcon() {
5313
+ return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="20" height="20">
5314
+ <rect width="256" height="256" fill="none"/>
5315
+ <path d="M216,208H40a8,8,0,0,1-8-8V64a8,8,0,0,1,8-8H93.33a8,8,0,0,1,4.8,1.6l27.74,20.8a8,8,0,0,0,4.8,1.6H216a8,8,0,0,1,8,8V200A8,8,0,0,1,216,208Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
5316
+ </svg>`;
5317
+ }
5318
+
5319
+ _renderAuthorAvatar(collection) {
5320
+ const author = collection.author;
5321
+ if (!author) return '';
5322
+
5323
+ if (author.picture) {
5324
+ return `<img class="messenger-help-author-avatar" src="${author.picture}" alt="${author.name}" />`;
5325
+ }
5326
+
5327
+ const color = this._getAvatarColor(collection.id);
5328
+ const initials = this._getInitials(author.name);
5329
+ return `
5330
+ <div class="messenger-help-author-avatar messenger-help-author-initials"
5331
+ style="background:${color.bg};color:${color.text}">
5332
+ ${initials}
5333
+ </div>
5334
+ `;
5335
+ }
5336
+
5337
+ _getAvatarColor(id) {
5338
+ const hash = id.split('').reduce((acc, ch) => acc + ch.charCodeAt(0), 0);
5339
+ return this._avatarColors[hash % this._avatarColors.length];
5340
+ }
5341
+
5342
+ _getInitials(name) {
5343
+ return name
5344
+ .split(' ')
5345
+ .map((n) => n[0])
5346
+ .join('')
5347
+ .toUpperCase()
5348
+ .slice(0, 2);
5349
+ }
5350
+
5250
5351
  _renderEmptyState() {
5251
5352
  const isSearching = this.state.helpSearchQuery;
5252
5353
 
@@ -5317,9 +5418,7 @@
5317
5418
  }
5318
5419
 
5319
5420
  destroy() {
5320
- if (this._unsubscribe) {
5321
- this._unsubscribe();
5322
- }
5421
+ if (this._unsubscribe) this._unsubscribe();
5323
5422
  if (this.element && this.element.parentNode) {
5324
5423
  this.element.parentNode.removeChild(this.element);
5325
5424
  }
@@ -6728,6 +6827,25 @@
6728
6827
  description: options.description || null,
6729
6828
  lowLabel: options.lowLabel || null,
6730
6829
  highLabel: options.highLabel || null,
6830
+ ratingScale: options.ratingScale || options.scale || null,
6831
+ showFeedbackInput:
6832
+ typeof options.showFeedbackInput === 'boolean'
6833
+ ? options.showFeedbackInput
6834
+ : null,
6835
+ showSubmitButton:
6836
+ typeof options.showSubmitButton === 'boolean'
6837
+ ? options.showSubmitButton
6838
+ : null,
6839
+ autoSubmitOnSelect:
6840
+ typeof options.autoSubmitOnSelect === 'boolean'
6841
+ ? options.autoSubmitOnSelect
6842
+ : null,
6843
+ showTitle:
6844
+ typeof options.showTitle === 'boolean' ? options.showTitle : null,
6845
+ showDescription:
6846
+ typeof options.showDescription === 'boolean'
6847
+ ? options.showDescription
6848
+ : null,
6731
6849
  customQuestions: options.customQuestions || [],
6732
6850
  pages: Array.isArray(options.pages) ? options.pages : [],
6733
6851
  respondentId: options.respondentId || null,
@@ -6742,6 +6860,7 @@
6742
6860
  customAnswers: {},
6743
6861
  pageAnswers: {},
6744
6862
  currentPageIndex: 0,
6863
+ isSubmitting: false,
6745
6864
  isVisible: false,
6746
6865
  };
6747
6866
  }
@@ -6777,6 +6896,10 @@
6777
6896
  const config = this._getSurveyConfig();
6778
6897
  const isMultiPage = this._isMultiPageSurvey();
6779
6898
  const isLastPage = this._isLastPage();
6899
+ const showFeedbackInput = this._shouldShowFeedbackInput();
6900
+ const showActions = this._shouldShowActions();
6901
+ const showTitle = this._shouldShowTitle(config);
6902
+ const showDescription = this._shouldShowDescription(config);
6780
6903
  const pageProgress = isMultiPage
6781
6904
  ? `Page ${this.surveyState.currentPageIndex + 1} of ${this.surveyOptions.pages.length}`
6782
6905
  : '';
@@ -6796,21 +6919,33 @@
6796
6919
  }
6797
6920
 
6798
6921
  this.surveyElement = document.createElement('div');
6799
- this.surveyElement.className = `feedback-survey feedback-survey-${this.surveyOptions.position}`;
6922
+ this.surveyElement.className = `feedback-survey feedback-survey-${this.surveyOptions.position}${
6923
+ showDescription && !showTitle
6924
+ ? ' feedback-survey-description-primary'
6925
+ : ''
6926
+ }`;
6800
6927
 
6801
6928
  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>
6929
+ <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>
6930
+ ${showTitle ? `<h3 class="feedback-survey-title">${config.title}</h3>` : ''}
6931
+ ${showDescription ? `<p class="feedback-survey-description">${config.description}</p>` : ''}
6805
6932
  ${isMultiPage ? `<div class="feedback-survey-progress">${pageProgress}</div>` : ''}
6806
6933
  <div class="feedback-survey-content">${config.html}</div>
6807
- <div class="feedback-survey-feedback">
6934
+ ${
6935
+ showFeedbackInput
6936
+ ? `<div class="feedback-survey-feedback">
6808
6937
  <textarea class="feedback-survey-textarea" placeholder="Any additional feedback? (optional)">${this.surveyState.feedback || ''}</textarea>
6809
- </div>
6810
- <div class="feedback-survey-actions">
6938
+ </div>`
6939
+ : ''
6940
+ }
6941
+ ${
6942
+ showActions
6943
+ ? `<div class="feedback-survey-actions">
6811
6944
  ${backButton}
6812
6945
  <button class="feedback-survey-submit">${submitLabel}</button>
6813
- </div>
6946
+ </div>`
6947
+ : ''
6948
+ }
6814
6949
  `;
6815
6950
 
6816
6951
  document.body.appendChild(this.surveyElement);
@@ -6830,37 +6965,62 @@
6830
6965
  return this._getCurrentPageConfig();
6831
6966
  }
6832
6967
 
6968
+ const npsScale = this._getNPSScale();
6969
+ const npsUsesSegmentedScale = npsScale.values.length <= 7;
6970
+ const npsContainerClass = npsUsesSegmentedScale
6971
+ ? 'feedback-survey-ces feedback-survey-rating-scale'
6972
+ : 'feedback-survey-nps';
6973
+ const npsButtonClass = npsUsesSegmentedScale
6974
+ ? 'feedback-survey-nps-btn feedback-survey-ces-btn feedback-survey-rating-scale-btn'
6975
+ : 'feedback-survey-nps-btn';
6976
+ const npsLowLabel =
6977
+ this.surveyOptions.lowLabel ||
6978
+ (npsScale.start === 0 ? 'Not likely' : 'Strongly Disagree');
6979
+ const npsHighLabel =
6980
+ this.surveyOptions.highLabel ||
6981
+ (npsScale.start === 0 ? 'Very likely' : 'Strongly Agree');
6982
+ const npsPrompt =
6983
+ this.surveyOptions.description ||
6984
+ this.surveyOptions.title ||
6985
+ 'How likely are you to recommend us?';
6986
+ const csatPrompt =
6987
+ this.surveyOptions.description ||
6988
+ this.surveyOptions.title ||
6989
+ 'How satisfied are you?';
6990
+ const cesPrompt =
6991
+ this.surveyOptions.description ||
6992
+ this.surveyOptions.title ||
6993
+ 'How easy was it?';
6994
+
6833
6995
  const configs = {
6834
6996
  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?',
6997
+ title: this.surveyOptions.title || '',
6998
+ description: npsPrompt,
6840
6999
  html: `
6841
- <div class="feedback-survey-nps">
6842
- ${[...Array(11).keys()]
7000
+ <div class="${npsContainerClass}">
7001
+ ${npsScale.values
6843
7002
  .map(
6844
7003
  (n) => `
6845
- <button class="feedback-survey-nps-btn" data-score="${n}">${n}</button>
7004
+ <button class="${npsButtonClass}" data-score="${n}">${n}</button>
6846
7005
  `
6847
7006
  )
6848
7007
  .join('')}
6849
7008
  </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>
7009
+ ${this._renderScaleLabels(npsLowLabel, npsHighLabel)}
6854
7010
  `,
6855
7011
  },
6856
7012
  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?',
7013
+ title: this.surveyOptions.title || '',
7014
+ description: csatPrompt,
6861
7015
  html: `
6862
7016
  <div class="feedback-survey-csat">
6863
- ${['😞', '😕', '😐', '🙂', '😄']
7017
+ ${[
7018
+ '\uD83D\uDE1E',
7019
+ '\uD83D\uDE15',
7020
+ '\uD83D\uDE10',
7021
+ '\uD83D\uDE42',
7022
+ '\uD83D\uDE04',
7023
+ ]
6864
7024
  .map(
6865
7025
  (emoji, i) => `
6866
7026
  <button class="feedback-survey-csat-btn" data-score="${i + 1}">${emoji}</button>
@@ -6868,17 +7028,15 @@
6868
7028
  )
6869
7029
  .join('')}
6870
7030
  </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>
7031
+ ${this._renderScaleLabels(
7032
+ this.surveyOptions.lowLabel || 'Very dissatisfied',
7033
+ this.surveyOptions.highLabel || 'Very satisfied'
7034
+ )}
6875
7035
  `,
6876
7036
  },
6877
7037
  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?',
7038
+ title: this.surveyOptions.title || '',
7039
+ description: cesPrompt,
6882
7040
  html: `
6883
7041
  <div class="feedback-survey-ces">
6884
7042
  ${['Very Difficult', 'Difficult', 'Neutral', 'Easy', 'Very Easy']
@@ -6903,6 +7061,91 @@
6903
7061
  return configs[this.surveyOptions.surveyType] || configs.nps;
6904
7062
  }
6905
7063
 
7064
+ _getNPSScale() {
7065
+ const rawScale = Number(this.surveyOptions.ratingScale);
7066
+ const scale = Number.isFinite(rawScale) && rawScale >= 2 ? rawScale : 5;
7067
+ const start = scale === 11 ? 0 : 1;
7068
+ return {
7069
+ scale,
7070
+ start,
7071
+ values: Array.from({ length: scale }, (_, index) => start + index),
7072
+ };
7073
+ }
7074
+
7075
+ _renderScaleLabels(lowLabel, highLabel) {
7076
+ const low = lowLabel || '';
7077
+ const high = highLabel || '';
7078
+ if (!low && !high) {
7079
+ return '';
7080
+ }
7081
+ return `
7082
+ <div class="feedback-survey-labels">
7083
+ <span>${low}</span>
7084
+ <span>${high}</span>
7085
+ </div>
7086
+ `;
7087
+ }
7088
+
7089
+ _isRatingSurveyType(type = this.surveyOptions.surveyType) {
7090
+ return type === 'nps' || type === 'csat' || type === 'ces';
7091
+ }
7092
+
7093
+ _shouldShowTitle(config) {
7094
+ if (!config || !config.title) {
7095
+ return false;
7096
+ }
7097
+ if (typeof this.surveyOptions.showTitle === 'boolean') {
7098
+ return this.surveyOptions.showTitle;
7099
+ }
7100
+ if (!this._isMultiPageSurvey() && this._isRatingSurveyType()) {
7101
+ return !config.description;
7102
+ }
7103
+ return true;
7104
+ }
7105
+
7106
+ _shouldShowDescription(config) {
7107
+ if (typeof this.surveyOptions.showDescription === 'boolean') {
7108
+ return this.surveyOptions.showDescription;
7109
+ }
7110
+ if (!this._isMultiPageSurvey() && this._isRatingSurveyType()) {
7111
+ return Boolean(config && (config.description || config.title));
7112
+ }
7113
+ return Boolean(config && config.description);
7114
+ }
7115
+
7116
+ _shouldShowFeedbackInput() {
7117
+ if (this._isMultiPageSurvey()) {
7118
+ return false;
7119
+ }
7120
+ if (typeof this.surveyOptions.showFeedbackInput === 'boolean') {
7121
+ return this.surveyOptions.showFeedbackInput;
7122
+ }
7123
+ return false;
7124
+ }
7125
+
7126
+ _shouldAutoSubmitOnSelect() {
7127
+ if (typeof this.surveyOptions.autoSubmitOnSelect === 'boolean') {
7128
+ return this.surveyOptions.autoSubmitOnSelect;
7129
+ }
7130
+ if (this._isMultiPageSurvey()) {
7131
+ return false;
7132
+ }
7133
+ if (this.surveyOptions.showSubmitButton === true) {
7134
+ return false;
7135
+ }
7136
+ return this._isRatingSurveyType() && !this._shouldShowFeedbackInput();
7137
+ }
7138
+
7139
+ _shouldShowActions() {
7140
+ if (this._isMultiPageSurvey()) {
7141
+ return true;
7142
+ }
7143
+ if (typeof this.surveyOptions.showSubmitButton === 'boolean') {
7144
+ return this.surveyOptions.showSubmitButton;
7145
+ }
7146
+ return !this._shouldAutoSubmitOnSelect();
7147
+ }
7148
+
6906
7149
  _isMultiPageSurvey() {
6907
7150
  return (
6908
7151
  Array.isArray(this.surveyOptions.pages) &&
@@ -6917,7 +7160,9 @@
6917
7160
 
6918
7161
  _isLastPage() {
6919
7162
  if (!this._isMultiPageSurvey()) return true;
6920
- return this.surveyState.currentPageIndex >= this.surveyOptions.pages.length - 1;
7163
+ return (
7164
+ this.surveyState.currentPageIndex >= this.surveyOptions.pages.length - 1
7165
+ );
6921
7166
  }
6922
7167
 
6923
7168
  _getCurrentPageConfig() {
@@ -6928,10 +7173,7 @@
6928
7173
 
6929
7174
  return {
6930
7175
  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.',
7176
+ description: page.description || this.surveyOptions.description || '',
6935
7177
  html: this._renderSurveyPage(page),
6936
7178
  };
6937
7179
  }
@@ -6939,9 +7181,7 @@
6939
7181
  _getFallbackSurveyConfig() {
6940
7182
  return {
6941
7183
  title: this.surveyOptions.title || 'Quick Feedback',
6942
- description:
6943
- this.surveyOptions.description ||
6944
- 'Help us improve by answering a few questions.',
7184
+ description: this.surveyOptions.description || '',
6945
7185
  html: this._renderCustomQuestions(),
6946
7186
  };
6947
7187
  }
@@ -6963,24 +7203,48 @@
6963
7203
  const pageId = page.id || `page_${this.surveyState.currentPageIndex}`;
6964
7204
  const config = page.ratingConfig || page.rating_config || {};
6965
7205
  const scale = Number(config.scale) || 5;
6966
- const ratingType = config.survey_type || this.surveyOptions.surveyType || 'csat';
7206
+ const ratingType =
7207
+ config.survey_type || this.surveyOptions.surveyType || 'csat';
6967
7208
  const pageAnswer = this.surveyState.pageAnswers[pageId] || {};
6968
7209
  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') {
7210
+ const defaultLowLabel =
7211
+ ratingType === 'nps'
7212
+ ? scale === 11
7213
+ ? 'Not likely'
7214
+ : 'Strongly Disagree'
7215
+ : '';
7216
+ const defaultHighLabel =
7217
+ ratingType === 'nps'
7218
+ ? scale === 11
7219
+ ? 'Very likely'
7220
+ : 'Strongly Agree'
7221
+ : '';
7222
+ const lowLabel =
7223
+ config.low_label || this.surveyOptions.lowLabel || defaultLowLabel;
7224
+ const highLabel =
7225
+ config.high_label || this.surveyOptions.highLabel || defaultHighLabel;
7226
+ const labels = this._renderScaleLabels(lowLabel, highLabel);
7227
+
7228
+ if (ratingType === 'nps') {
7229
+ const npsScale = Number.isFinite(scale) && scale >= 2 ? scale : 5;
7230
+ const start = npsScale === 11 ? 0 : 1;
7231
+ const values = Array.from(
7232
+ { length: npsScale },
7233
+ (_, index) => start + index
7234
+ );
7235
+ const usesSegmentedScale = values.length <= 7;
7236
+ const containerClass = usesSegmentedScale
7237
+ ? 'feedback-survey-ces feedback-survey-rating-scale'
7238
+ : 'feedback-survey-nps';
7239
+ const buttonClass = usesSegmentedScale
7240
+ ? 'feedback-survey-page-rating-btn feedback-survey-nps-btn feedback-survey-ces-btn feedback-survey-rating-scale-btn'
7241
+ : 'feedback-survey-page-rating-btn feedback-survey-nps-btn';
6978
7242
  return `
6979
- <div class="feedback-survey-nps" data-page-id="${pageId}">
6980
- ${[...Array(11).keys()]
7243
+ <div class="${containerClass}" data-page-id="${pageId}">
7244
+ ${values
6981
7245
  .map((n) => {
6982
7246
  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>`;
7247
+ return `<button class="${buttonClass}${selected}" data-page-id="${pageId}" data-score="${n}">${n}</button>`;
6984
7248
  })
6985
7249
  .join('')}
6986
7250
  </div>
@@ -6989,7 +7253,13 @@
6989
7253
  }
6990
7254
 
6991
7255
  if (ratingType === 'emoji' && scale === 5) {
6992
- const emojis = [':(', ':/', ':|', ':)', ':D'];
7256
+ const emojis = [
7257
+ '\uD83D\uDE1E',
7258
+ '\uD83D\uDE15',
7259
+ '\uD83D\uDE10',
7260
+ '\uD83D\uDE42',
7261
+ '\uD83D\uDE04',
7262
+ ];
6993
7263
  return `
6994
7264
  <div class="feedback-survey-csat" data-page-id="${pageId}">
6995
7265
  ${emojis
@@ -7005,12 +7275,12 @@
7005
7275
  }
7006
7276
 
7007
7277
  return `
7008
- <div class="feedback-survey-ces" data-page-id="${pageId}">
7278
+ <div class="feedback-survey-ces feedback-survey-rating-scale" data-page-id="${pageId}">
7009
7279
  ${[...Array(scale).keys()]
7010
7280
  .map((i) => {
7011
7281
  const score = i + 1;
7012
7282
  const selected = currentRating === score ? ' selected' : '';
7013
- return `<button class="feedback-survey-page-rating-btn feedback-survey-ces-btn${selected}" data-page-id="${pageId}" data-score="${score}">${score}</button>`;
7283
+ 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>`;
7014
7284
  })
7015
7285
  .join('')}
7016
7286
  </div>
@@ -7020,9 +7290,11 @@
7020
7290
 
7021
7291
  _renderMultipleChoicePage(page) {
7022
7292
  const pageId = page.id || `page_${this.surveyState.currentPageIndex}`;
7023
- const config = page.multipleChoiceConfig || page.multiple_choice_config || {};
7293
+ const config =
7294
+ page.multipleChoiceConfig || page.multiple_choice_config || {};
7024
7295
  const options = Array.isArray(config.options) ? config.options : [];
7025
- const allowMultiple = config.allow_multiple === true || config.multiple === true;
7296
+ const allowMultiple =
7297
+ config.allow_multiple === true || config.multiple === true;
7026
7298
  const pageAnswer = this.surveyState.pageAnswers[pageId] || {};
7027
7299
  const selectedValues = Array.isArray(pageAnswer.values)
7028
7300
  ? pageAnswer.values
@@ -7127,7 +7399,9 @@
7127
7399
  const submitBtn = this.surveyElement.querySelector(
7128
7400
  '.feedback-survey-submit'
7129
7401
  );
7130
- submitBtn.addEventListener('click', () => this._handleSubmit());
7402
+ if (submitBtn) {
7403
+ submitBtn.addEventListener('click', () => this._handleSubmit());
7404
+ }
7131
7405
 
7132
7406
  const backBtn = this.surveyElement.querySelector('.feedback-survey-back');
7133
7407
  if (backBtn) {
@@ -7137,9 +7411,11 @@
7137
7411
  const textarea = this.surveyElement.querySelector(
7138
7412
  '.feedback-survey-textarea'
7139
7413
  );
7140
- textarea.addEventListener('input', (e) => {
7141
- this.surveyState.feedback = e.target.value;
7142
- });
7414
+ if (textarea) {
7415
+ textarea.addEventListener('input', (e) => {
7416
+ this.surveyState.feedback = e.target.value;
7417
+ });
7418
+ }
7143
7419
 
7144
7420
  this._attachTypeSpecificEvents();
7145
7421
 
@@ -7311,6 +7587,7 @@
7311
7587
  btn.classList.remove('selected');
7312
7588
  }
7313
7589
  });
7590
+ this._maybeAutoSubmit();
7314
7591
  }
7315
7592
 
7316
7593
  _selectCSAT(score) {
@@ -7325,6 +7602,7 @@
7325
7602
  btn.classList.remove('selected');
7326
7603
  }
7327
7604
  });
7605
+ this._maybeAutoSubmit();
7328
7606
  }
7329
7607
 
7330
7608
  _selectCES(score) {
@@ -7339,6 +7617,14 @@
7339
7617
  btn.classList.remove('selected');
7340
7618
  }
7341
7619
  });
7620
+ this._maybeAutoSubmit();
7621
+ }
7622
+
7623
+ _maybeAutoSubmit() {
7624
+ if (!this._shouldAutoSubmitOnSelect()) {
7625
+ return;
7626
+ }
7627
+ this._handleSubmit();
7342
7628
  }
7343
7629
 
7344
7630
  _selectFrequency(freq) {
@@ -7356,6 +7642,9 @@
7356
7642
 
7357
7643
  async _handleSubmit() {
7358
7644
  const type = this.surveyOptions.surveyType;
7645
+ if (this.surveyState.isSubmitting) {
7646
+ return;
7647
+ }
7359
7648
 
7360
7649
  if (this._isMultiPageSurvey()) {
7361
7650
  if (!this._validateCurrentPage()) {
@@ -7363,7 +7652,10 @@
7363
7652
  }
7364
7653
 
7365
7654
  const nextPageIndex = this._getNextPageIndex();
7366
- if (nextPageIndex !== -1 && nextPageIndex !== this.surveyState.currentPageIndex) {
7655
+ if (
7656
+ nextPageIndex !== -1 &&
7657
+ nextPageIndex !== this.surveyState.currentPageIndex
7658
+ ) {
7367
7659
  this.surveyState.currentPageIndex = nextPageIndex;
7368
7660
  this._renderSurvey();
7369
7661
  return;
@@ -7379,6 +7671,8 @@
7379
7671
  return;
7380
7672
  }
7381
7673
 
7674
+ this.surveyState.isSubmitting = true;
7675
+
7382
7676
  const respondent = this._getRespondentContext();
7383
7677
  const normalizedPageAnswers = this._normalizePageAnswersForSubmit();
7384
7678
  const mergedAnswers = {
@@ -7405,16 +7699,18 @@
7405
7699
  timestamp: new Date().toISOString(),
7406
7700
  };
7407
7701
 
7408
- if (this.surveyOptions.onSubmit) {
7409
- this.surveyOptions.onSubmit(response);
7410
- }
7411
-
7412
7702
  try {
7703
+ if (this.surveyOptions.onSubmit) {
7704
+ this.surveyOptions.onSubmit(response);
7705
+ }
7706
+
7413
7707
  const surveyId =
7414
7708
  this.surveyOptions.surveyId || `local_${type}_${Date.now()}`;
7415
7709
  await this.apiService.submitSurveyResponse(surveyId, responseData);
7416
7710
  } catch (error) {
7417
7711
  console.error('[SurveyWidget] Failed to submit survey:', error);
7712
+ } finally {
7713
+ this.surveyState.isSubmitting = false;
7418
7714
  }
7419
7715
 
7420
7716
  this.sdk.eventBus.emit('survey:submitted', { widget: this, response });
@@ -7522,7 +7818,8 @@
7522
7818
  }
7523
7819
 
7524
7820
  for (const page of this.surveyOptions.pages) {
7525
- const pageId = page.id || `page_${this.surveyOptions.pages.indexOf(page)}`;
7821
+ const pageId =
7822
+ page.id || `page_${this.surveyOptions.pages.indexOf(page)}`;
7526
7823
  const answer = this.surveyState.pageAnswers[pageId];
7527
7824
  if (answer && typeof answer.rating === 'number') {
7528
7825
  return answer.rating;
@@ -7534,7 +7831,9 @@
7534
7831
 
7535
7832
  _normalizePageAnswersForSubmit() {
7536
7833
  const output = {};
7537
- for (const [pageId, answer] of Object.entries(this.surveyState.pageAnswers)) {
7834
+ for (const [pageId, answer] of Object.entries(
7835
+ this.surveyState.pageAnswers
7836
+ )) {
7538
7837
  if (answer == null) continue;
7539
7838
  if (Array.isArray(answer.values) && answer.values.length > 0) {
7540
7839
  output[pageId] = answer.values;
@@ -7561,8 +7860,7 @@
7561
7860
  ? this.sdk.getUserContext() || {}
7562
7861
  : {};
7563
7862
  const apiUserContext =
7564
- this.apiService &&
7565
- typeof this.apiService.getUserContext === 'function'
7863
+ this.apiService && typeof this.apiService.getUserContext === 'function'
7566
7864
  ? this.apiService.getUserContext() || {}
7567
7865
  : {};
7568
7866
  const localUserContext = this.options.userContext || {};
@@ -7610,7 +7908,15 @@
7610
7908
  const submitBtn = this.surveyElement.querySelector(
7611
7909
  '.feedback-survey-submit'
7612
7910
  );
7613
- submitBtn.parentNode.insertBefore(error, submitBtn);
7911
+ const actions = this.surveyElement.querySelector(
7912
+ '.feedback-survey-actions'
7913
+ );
7914
+ const anchor = submitBtn || actions;
7915
+ if (anchor && anchor.parentNode) {
7916
+ anchor.parentNode.insertBefore(error, anchor);
7917
+ } else {
7918
+ this.surveyElement.appendChild(error);
7919
+ }
7614
7920
 
7615
7921
  setTimeout(() => error.remove(), 3000);
7616
7922
  }
@@ -7673,6 +7979,7 @@
7673
7979
  customAnswers: {},
7674
7980
  pageAnswers: {},
7675
7981
  currentPageIndex: 0,
7982
+ isSubmitting: false,
7676
7983
  isVisible: false,
7677
7984
  };
7678
7985
  }
@@ -7934,6 +8241,16 @@
7934
8241
  description: surveyConfig.description,
7935
8242
  lowLabel: surveyConfig.lowLabel || surveyConfig.low_label,
7936
8243
  highLabel: surveyConfig.highLabel || surveyConfig.high_label,
8244
+ ratingScale: surveyConfig.ratingScale ?? surveyConfig.rating_scale,
8245
+ showFeedbackInput:
8246
+ surveyConfig.showFeedbackInput ?? surveyConfig.show_feedback_input,
8247
+ showSubmitButton:
8248
+ surveyConfig.showSubmitButton ?? surveyConfig.show_submit_button,
8249
+ autoSubmitOnSelect:
8250
+ surveyConfig.autoSubmitOnSelect ?? surveyConfig.auto_submit_on_select,
8251
+ showTitle: surveyConfig.showTitle ?? surveyConfig.show_title,
8252
+ showDescription:
8253
+ surveyConfig.showDescription ?? surveyConfig.show_description,
7937
8254
  customQuestions: surveyConfig.customQuestions || surveyConfig.questions,
7938
8255
  pages: surveyConfig.pages,
7939
8256
  ...displayOptions,
@@ -7960,13 +8277,20 @@
7960
8277
 
7961
8278
  const surveyWidget = this.createWidget('survey', {
7962
8279
  surveyId: normalizedOptions.surveyId,
7963
- surveyType: normalizedOptions.surveyType || normalizedOptions.type || 'nps',
8280
+ surveyType:
8281
+ normalizedOptions.surveyType || normalizedOptions.type || 'nps',
7964
8282
  position: normalizedOptions.position || 'bottom-right',
7965
8283
  theme: normalizedOptions.theme || this.config.theme || 'light',
7966
8284
  title: normalizedOptions.title,
7967
8285
  description: normalizedOptions.description,
7968
8286
  lowLabel: normalizedOptions.lowLabel,
7969
8287
  highLabel: normalizedOptions.highLabel,
8288
+ ratingScale: normalizedOptions.ratingScale ?? normalizedOptions.scale,
8289
+ showFeedbackInput: normalizedOptions.showFeedbackInput,
8290
+ showSubmitButton: normalizedOptions.showSubmitButton,
8291
+ autoSubmitOnSelect: normalizedOptions.autoSubmitOnSelect,
8292
+ showTitle: normalizedOptions.showTitle,
8293
+ showDescription: normalizedOptions.showDescription,
7970
8294
  customQuestions: normalizedOptions.customQuestions,
7971
8295
  pages: normalizedOptions.pages,
7972
8296
  respondentId: normalizedOptions.respondentId,
@@ -7982,7 +8306,10 @@
7982
8306
  }
7983
8307
 
7984
8308
  _isSurveyEligible(survey = {}) {
7985
- const shouldShow = this._getSurveyField(survey, ['shouldShow', 'should_show']);
8309
+ const shouldShow = this._getSurveyField(survey, [
8310
+ 'shouldShow',
8311
+ 'should_show',
8312
+ ]);
7986
8313
  if (typeof shouldShow === 'boolean') {
7987
8314
  return shouldShow;
7988
8315
  }
@@ -8004,7 +8331,10 @@
8004
8331
  return eligible;
8005
8332
  }
8006
8333
 
8007
- const isAnswered = this._getSurveyField(survey, ['isAnswered', 'is_answered']);
8334
+ const isAnswered = this._getSurveyField(survey, [
8335
+ 'isAnswered',
8336
+ 'is_answered',
8337
+ ]);
8008
8338
  if (typeof isAnswered === 'boolean') {
8009
8339
  return !isAnswered;
8010
8340
  }
@@ -8039,7 +8369,10 @@
8039
8369
  return eligibilityReason;
8040
8370
  }
8041
8371
 
8042
- const isAnswered = this._getSurveyField(survey, ['isAnswered', 'is_answered']);
8372
+ const isAnswered = this._getSurveyField(survey, [
8373
+ 'isAnswered',
8374
+ 'is_answered',
8375
+ ]);
8043
8376
  if (isAnswered === true) {
8044
8377
  return 'already_answered';
8045
8378
  }
@@ -8048,17 +8381,16 @@
8048
8381
  }
8049
8382
 
8050
8383
  _normalizeSurveyConfig(survey = {}) {
8051
- const firstPage = Array.isArray(survey.pages) && survey.pages.length > 0
8052
- ? survey.pages[0]
8053
- : null;
8384
+ const firstPage =
8385
+ Array.isArray(survey.pages) && survey.pages.length > 0
8386
+ ? survey.pages[0]
8387
+ : null;
8054
8388
  const ratingConfig = firstPage
8055
8389
  ? firstPage.rating_config || firstPage.ratingConfig || {}
8056
8390
  : {};
8057
8391
 
8058
8392
  const inferredType =
8059
- survey.type ||
8060
- this._inferSurveyTypeFromPage(firstPage) ||
8061
- 'nps';
8393
+ survey.type || this._inferSurveyTypeFromPage(firstPage) || 'nps';
8062
8394
 
8063
8395
  return {
8064
8396
  ...survey,
@@ -8072,22 +8404,27 @@
8072
8404
  survey.reason ||
8073
8405
  (survey.eligibility ? survey.eligibility.reason : undefined),
8074
8406
  title:
8075
- survey.title ||
8076
- survey.name ||
8077
- (firstPage ? firstPage.title : null),
8407
+ survey.title || survey.name || (firstPage ? firstPage.title : null),
8078
8408
  description:
8079
- survey.description ||
8080
- (firstPage ? firstPage.description : null),
8409
+ survey.description || (firstPage ? firstPage.description : null),
8081
8410
  lowLabel:
8082
- survey.lowLabel ||
8083
- survey.low_label ||
8084
- ratingConfig.low_label ||
8085
- null,
8411
+ survey.lowLabel || survey.low_label || ratingConfig.low_label || null,
8086
8412
  highLabel:
8087
8413
  survey.highLabel ||
8088
8414
  survey.high_label ||
8089
8415
  ratingConfig.high_label ||
8090
8416
  null,
8417
+ ratingScale:
8418
+ survey.ratingScale ?? survey.rating_scale ?? ratingConfig.scale ?? null,
8419
+ showFeedbackInput:
8420
+ survey.showFeedbackInput ?? survey.show_feedback_input ?? null,
8421
+ showSubmitButton:
8422
+ survey.showSubmitButton ?? survey.show_submit_button ?? null,
8423
+ autoSubmitOnSelect:
8424
+ survey.autoSubmitOnSelect ?? survey.auto_submit_on_select ?? null,
8425
+ showTitle: survey.showTitle ?? survey.show_title ?? null,
8426
+ showDescription:
8427
+ survey.showDescription ?? survey.show_description ?? null,
8091
8428
  customQuestions: survey.customQuestions || survey.questions || [],
8092
8429
  pages: this._normalizeSurveyPages(survey.pages || []),
8093
8430
  };
@@ -8100,17 +8437,17 @@
8100
8437
 
8101
8438
  return pages
8102
8439
  .map((page, index) => ({
8103
- id: page.id || `page_${index}`,
8104
- type: page.type || 'rating',
8105
- title: page.title || '',
8106
- description: page.description || '',
8107
- required: page.required !== false,
8108
- position: page.position ?? index,
8109
- ratingConfig: page.ratingConfig || page.rating_config || null,
8110
- multipleChoiceConfig:
8111
- page.multipleChoiceConfig || page.multiple_choice_config || null,
8112
- linkConfig: page.linkConfig || page.link_config || null,
8113
- afterThisPage: page.afterThisPage || page.after_this_page || null,
8440
+ id: page.id || `page_${index}`,
8441
+ type: page.type || 'rating',
8442
+ title: page.title || '',
8443
+ description: page.description || '',
8444
+ required: page.required !== false,
8445
+ position: page.position ?? index,
8446
+ ratingConfig: page.ratingConfig || page.rating_config || null,
8447
+ multipleChoiceConfig:
8448
+ page.multipleChoiceConfig || page.multiple_choice_config || null,
8449
+ linkConfig: page.linkConfig || page.link_config || null,
8450
+ afterThisPage: page.afterThisPage || page.after_this_page || null,
8114
8451
  }))
8115
8452
  .sort((a, b) => a.position - b.position);
8116
8453
  }
@@ -8626,8 +8963,8 @@
8626
8963
  width: 100%;
8627
8964
  max-width: 580px;
8628
8965
  max-height: 90vh;
8629
- background: #DBEAFE;
8630
- border-radius: var(--radius-4xl);
8966
+ background: var(--color-primary-light);
8967
+ border-radius: 10px;
8631
8968
  overflow: hidden;
8632
8969
  box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px, rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
8633
8970
  transform: scale(0.95) translateY(20px);
@@ -8644,28 +8981,30 @@
8644
8981
  position: absolute;
8645
8982
  top: var(--spacing-4);
8646
8983
  right: var(--spacing-4);
8647
- background: rgba(255, 255, 255, 0.9);
8984
+ background: none;
8648
8985
  border: none;
8649
- font-size: 24px;
8650
8986
  cursor: pointer;
8651
8987
  color: var(--color-neutral-500);
8652
8988
  padding: 0;
8653
- width: 36px;
8654
- height: 36px;
8989
+ width: 20px;
8990
+ height: 20px;
8655
8991
  display: flex;
8656
8992
  align-items: center;
8657
8993
  justify-content: center;
8658
- border-radius: var(--radius-full);
8994
+ border-radius: 8px;
8659
8995
  transition: all var(--transition-base);
8660
8996
  line-height: 1;
8661
8997
  z-index: 10;
8662
- box-shadow: var(--shadow-md);
8663
8998
  }
8664
8999
 
8665
9000
  .changelog-modal-close:hover {
8666
- background: var(--color-white);
9001
+ background: var(--color-neutral-100);
8667
9002
  color: var(--color-neutral-900);
8668
- transform: scale(1.05);
9003
+ }
9004
+
9005
+ .changelog-modal-close svg {
9006
+ width: 18px;
9007
+ height: 18px;
8669
9008
  }
8670
9009
 
8671
9010
  .changelog-modal-content {
@@ -8719,7 +9058,7 @@
8719
9058
  height: auto;
8720
9059
  display: block;
8721
9060
  object-fit: cover;
8722
- border-radius: var(--radius-xl);
9061
+ border-radius: 8px;
8723
9062
  border: 2px solid var(--color-primary);
8724
9063
  box-shadow: 0 4px 20px rgba(21, 94, 239, 0.2);
8725
9064
  }
@@ -8732,7 +9071,7 @@
8732
9071
  .changelog-popup-title {
8733
9072
  margin: 0 0 var(--spacing-3);
8734
9073
  font-size: var(--font-size-xl);
8735
- font-weight: var(--font-weight-bold);
9074
+ font-weight: var(--font-weight-semibold);
8736
9075
  line-height: var(--line-height-snug);
8737
9076
  color: var(--color-neutral-900);
8738
9077
  }
@@ -8750,11 +9089,11 @@
8750
9089
  justify-content: center;
8751
9090
  padding: var(--spacing-3) var(--spacing-8);
8752
9091
  font-size: var(--font-size-base);
8753
- font-weight: var(--font-weight-semibold);
9092
+ font-weight: var(--font-weight-medium);
8754
9093
  color: var(--color-white);
8755
9094
  background: var(--color-primary);
8756
9095
  border: 1px solid var(--color-primary);
8757
- border-radius: var(--radius-md);
9096
+ border-radius: 8px;
8758
9097
  cursor: pointer;
8759
9098
  transition: all var(--transition-base);
8760
9099
  font-family: inherit;
@@ -8817,7 +9156,7 @@
8817
9156
  font-weight: var(--font-weight-medium);
8818
9157
  cursor: pointer;
8819
9158
  padding: var(--spacing-2) var(--spacing-3);
8820
- border-radius: var(--radius-md);
9159
+ border-radius: 8px;
8821
9160
  transition: all var(--transition-base);
8822
9161
  font-family: inherit;
8823
9162
  }
@@ -8863,7 +9202,7 @@
8863
9202
  max-width: 460px;
8864
9203
  max-height: 85vh;
8865
9204
  background: var(--color-white);
8866
- border-radius: var(--radius-2xl);
9205
+ border-radius: 10px;
8867
9206
  overflow: hidden;
8868
9207
  box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px, rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
8869
9208
  transform: scale(0.95) translateY(20px);
@@ -8890,7 +9229,7 @@
8890
9229
 
8891
9230
  .changelog-list-modal-header h2 {
8892
9231
  margin: 0;
8893
- font-size: var(--font-size-lg);
9232
+ font-size: var(--font-size-md);
8894
9233
  font-weight: var(--font-weight-semibold);
8895
9234
  color: var(--color-text-primary);
8896
9235
  }
@@ -8900,16 +9239,21 @@
8900
9239
  border: none;
8901
9240
  cursor: pointer;
8902
9241
  color: var(--color-neutral-500);
8903
- padding: var(--spacing-1);
8904
- width: 28px;
8905
- height: 28px;
9242
+ padding: 0;
9243
+ width: 20px;
9244
+ height: 20px;
8906
9245
  display: flex;
8907
9246
  align-items: center;
8908
9247
  justify-content: center;
8909
- border-radius: var(--radius-md);
9248
+ border-radius: 8px;
8910
9249
  transition: all var(--transition-base);
8911
9250
  }
8912
9251
 
9252
+ .changelog-list-modal-close svg {
9253
+ width: 18px;
9254
+ height: 18px;
9255
+ }
9256
+
8913
9257
  .changelog-list-modal-close:hover {
8914
9258
  background: var(--color-neutral-100);
8915
9259
  color: var(--color-neutral-900);
@@ -8949,7 +9293,7 @@
8949
9293
  .changelog-list-item-image {
8950
9294
  width: 100%;
8951
9295
  margin-bottom: var(--spacing-2);
8952
- border-radius: var(--radius-md);
9296
+ border-radius: 8px;
8953
9297
  overflow: hidden;
8954
9298
  border: 1px solid var(--color-border);
8955
9299
  }
@@ -9036,7 +9380,7 @@
9036
9380
 
9037
9381
  .changelog-modal-container {
9038
9382
  max-width: 100%;
9039
- border-radius: var(--radius-3xl);
9383
+ border-radius: 10px;
9040
9384
  }
9041
9385
 
9042
9386
  .changelog-popup-image {
@@ -9048,7 +9392,7 @@
9048
9392
  }
9049
9393
 
9050
9394
  .changelog-popup-title {
9051
- font-size: var(--font-size-xl);
9395
+ font-size: var(--font-size-lg);
9052
9396
  }
9053
9397
 
9054
9398
  .changelog-popup-description {
@@ -9072,7 +9416,7 @@
9072
9416
  .changelog-list-modal-container {
9073
9417
  max-width: 100%;
9074
9418
  max-height: 90vh;
9075
- border-radius: var(--radius-2xl);
9419
+ border-radius: 10px;
9076
9420
  }
9077
9421
 
9078
9422
  .changelog-list-item {
@@ -9091,7 +9435,7 @@
9091
9435
  align-items: center;
9092
9436
  justify-content: center;
9093
9437
  gap: var(--spacing-2);
9094
- border-radius: var(--radius-md);
9438
+ border-radius: 8px;
9095
9439
  border: none;
9096
9440
  font-size: var(--font-size-md);
9097
9441
  font-weight: var(--font-weight-medium);
@@ -9115,7 +9459,7 @@
9115
9459
  background: var(--color-primary);
9116
9460
  color: var(--color-white);
9117
9461
  border: 1px solid var(--color-primary);
9118
- border-radius: var(--radius-md);
9462
+ border-radius: 8px;
9119
9463
  font-size: var(--font-size-base);
9120
9464
  font-weight: var(--font-weight-medium);
9121
9465
  height: 44px;
@@ -9182,7 +9526,7 @@
9182
9526
  height: 36px;
9183
9527
  border: none;
9184
9528
  background: none;
9185
- border-radius: var(--radius-md);
9529
+ border-radius: 8px;
9186
9530
  cursor: pointer;
9187
9531
  color: var(--color-text-secondary);
9188
9532
  transition: all var(--transition-base);
@@ -9197,7 +9541,7 @@
9197
9541
  .sdk-input {
9198
9542
  width: 100%;
9199
9543
  height: 44px;
9200
- border-radius: var(--radius-md);
9544
+ border-radius: 8px;
9201
9545
  border: 1px solid var(--color-border);
9202
9546
  padding: 10px 14px;
9203
9547
  font-size: var(--font-size-md);
@@ -9228,7 +9572,7 @@
9228
9572
  width: 100%;
9229
9573
  min-height: 120px;
9230
9574
  resize: vertical;
9231
- border-radius: var(--radius-md);
9575
+ border-radius: 8px;
9232
9576
  border: 1px solid var(--color-border);
9233
9577
  padding: 10px 14px;
9234
9578
  font-size: var(--font-size-md);
@@ -9253,7 +9597,7 @@
9253
9597
  .sdk-select {
9254
9598
  width: 100%;
9255
9599
  height: 44px;
9256
- border-radius: var(--radius-md);
9600
+ border-radius: 8px;
9257
9601
  border: 1px solid var(--color-border);
9258
9602
  padding: 10px 14px;
9259
9603
  font-size: var(--font-size-md);
@@ -9291,7 +9635,7 @@
9291
9635
 
9292
9636
  .sdk-card {
9293
9637
  background: var(--color-white);
9294
- border-radius: var(--radius-xl);
9638
+ border-radius: 10px;
9295
9639
  box-shadow: var(--shadow-base);
9296
9640
  overflow: hidden;
9297
9641
  }
@@ -9352,7 +9696,7 @@
9352
9696
  max-width: 580px;
9353
9697
  max-height: 90vh;
9354
9698
  background: var(--color-white);
9355
- border-radius: var(--radius-4xl);
9699
+ border-radius: 10px;
9356
9700
  overflow: hidden;
9357
9701
  box-shadow: var(--shadow-2xl);
9358
9702
  transform: scale(0.95) translateY(20px);
@@ -9388,15 +9732,18 @@
9388
9732
  .sdk-close-btn {
9389
9733
  background: none;
9390
9734
  border: none;
9391
- padding: var(--spacing-2);
9735
+ padding: 0;
9392
9736
  cursor: pointer;
9393
9737
  color: var(--color-neutral-500);
9394
9738
  display: flex;
9395
9739
  align-items: center;
9396
9740
  justify-content: center;
9397
- border-radius: var(--radius-md);
9741
+ width: 20px;
9742
+ height: 20px;
9743
+ border-radius: 8px;
9398
9744
  transition: all var(--transition-base);
9399
9745
  line-height: 1;
9746
+ flex-shrink: 0;
9400
9747
  }
9401
9748
 
9402
9749
  .sdk-close-btn:hover {
@@ -9404,6 +9751,11 @@
9404
9751
  color: var(--color-neutral-900);
9405
9752
  }
9406
9753
 
9754
+ .sdk-close-btn svg {
9755
+ width: 18px;
9756
+ height: 18px;
9757
+ }
9758
+
9407
9759
  .sdk-avatar {
9408
9760
  display: flex;
9409
9761
  align-items: center;
@@ -9490,7 +9842,7 @@
9490
9842
  right: var(--spacing-6);
9491
9843
  z-index: var(--z-notification);
9492
9844
  background: var(--color-white);
9493
- border-radius: var(--radius-xl);
9845
+ border-radius: 10px;
9494
9846
  box-shadow: var(--shadow-lg);
9495
9847
  min-width: 320px;
9496
9848
  animation: slideInRight 0.3s cubic-bezier(0.4, 0, 0.2, 1);
@@ -9580,7 +9932,7 @@
9580
9932
 
9581
9933
  .sdk-modal-container {
9582
9934
  max-width: 100%;
9583
- border-radius: var(--spacing-5);
9935
+ border-radius: 10px;
9584
9936
  }
9585
9937
 
9586
9938
  .sdk-notification {
@@ -9840,7 +10192,7 @@
9840
10192
  height: 100%;
9841
10193
  display: flex;
9842
10194
  flex-direction: column;
9843
- border-radius: var(--radius-2xl);
10195
+ border-radius: 10px;
9844
10196
  }
9845
10197
 
9846
10198
  .feedback-panel-header {
@@ -10209,6 +10561,17 @@
10209
10561
  display: none;
10210
10562
  }
10211
10563
 
10564
+ .messenger-compose-attach {
10565
+ width: 28px;
10566
+ height: 28px;
10567
+ flex-shrink: 0;
10568
+ }
10569
+
10570
+ .messenger-compose-attach svg {
10571
+ width: 20px;
10572
+ height: 20px;
10573
+ }
10574
+
10212
10575
  /* ========================================
10213
10576
  TYPING INDICATOR
10214
10577
  ======================================== */
@@ -10238,17 +10601,9 @@
10238
10601
  animation: messenger-typing-bounce 1.4s infinite ease-in-out;
10239
10602
  }
10240
10603
 
10241
- .messenger-typing-dots span:nth-child(1) {
10242
- animation-delay: -0.32s;
10243
- }
10244
-
10245
- .messenger-typing-dots span:nth-child(2) {
10246
- animation-delay: -0.16s;
10247
- }
10248
-
10249
- .messenger-typing-dots span:nth-child(3) {
10250
- animation-delay: 0s;
10251
- }
10604
+ .messenger-typing-dots span:nth-child(1) { animation-delay: -0.32s; }
10605
+ .messenger-typing-dots span:nth-child(2) { animation-delay: -0.16s; }
10606
+ .messenger-typing-dots span:nth-child(3) { animation-delay: 0s; }
10252
10607
 
10253
10608
  .messenger-typing-text {
10254
10609
  font-size: var(--font-size-xs);
@@ -10266,12 +10621,12 @@
10266
10621
 
10267
10622
  .messenger-nav-tabs {
10268
10623
  display: flex;
10269
- padding: var(--spacing-1) var(--spacing-2);
10624
+ padding: var(--spacing-1) var(--spacing-2) 0;
10270
10625
  gap: var(--spacing-1);
10271
10626
  }
10272
10627
 
10273
10628
  .messenger-nav-footer {
10274
- padding: var(--spacing-1) var(--spacing-2);
10629
+ padding: 2px var(--spacing-2) var(--spacing-2);
10275
10630
  text-align: center;
10276
10631
  }
10277
10632
 
@@ -10303,12 +10658,12 @@
10303
10658
  display: flex;
10304
10659
  flex-direction: column;
10305
10660
  align-items: center;
10306
- gap: 4px;
10307
- padding: var(--spacing-2) var(--spacing-1);
10661
+ gap: 2px;
10662
+ padding: var(--spacing-1) var(--spacing-1);
10308
10663
  background: none;
10309
10664
  border: none;
10310
10665
  cursor: pointer;
10311
- border-radius: var(--radius-md);
10666
+ border-radius: 8px;
10312
10667
  transition: all var(--transition-base);
10313
10668
  position: relative;
10314
10669
  }
@@ -10320,10 +10675,21 @@
10320
10675
  .messenger-nav-icon {
10321
10676
  color: var(--color-text-secondary);
10322
10677
  transition: color var(--transition-base);
10678
+ display: flex;
10679
+ align-items: center;
10680
+ justify-content: center;
10681
+ width: 20px;
10682
+ height: 20px;
10683
+ }
10684
+
10685
+ .messenger-nav-icon svg {
10686
+ width: 20px;
10687
+ height: 20px;
10688
+ display: block;
10323
10689
  }
10324
10690
 
10325
10691
  .messenger-nav-label {
10326
- font-size: var(--font-size-base);
10692
+ font-size: var(--font-size-xs);
10327
10693
  font-weight: var(--font-weight-medium);
10328
10694
  color: var(--color-text-secondary);
10329
10695
  transition: color var(--transition-base);
@@ -10375,7 +10741,7 @@
10375
10741
 
10376
10742
  .messenger-prechat-card {
10377
10743
  background: var(--color-white);
10378
- border-radius: var(--radius-2xl);
10744
+ border-radius: 10px;
10379
10745
  padding: var(--spacing-6);
10380
10746
  width: 100%;
10381
10747
  max-width: 360px;
@@ -11466,10 +11832,11 @@
11466
11832
  .feedback-survey {
11467
11833
  position: fixed;
11468
11834
  z-index: var(--z-modal);
11469
- background: var(--color-white);
11470
- border-radius: var(--radius-2xl);
11471
- box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px, rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
11472
- padding: var(--spacing-6);
11835
+ background: var(--color-neutral-50);
11836
+ border: 1px solid var(--color-neutral-300);
11837
+ border-radius: 10px;
11838
+ box-shadow: var(--shadow-lg);
11839
+ padding: var(--spacing-8);
11473
11840
  min-width: 320px;
11474
11841
  max-width: 400px;
11475
11842
  font-family: inherit;
@@ -11489,56 +11856,77 @@
11489
11856
  top: 50%;
11490
11857
  left: 50%;
11491
11858
  transform: translate(-50%, -50%);
11859
+ width: min(680px, calc(100vw - 24px));
11860
+ max-width: 680px;
11492
11861
  }
11493
11862
 
11494
11863
  .feedback-survey-bottom {
11495
11864
  bottom: 0;
11496
11865
  left: 0;
11497
11866
  right: 0;
11498
- border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
11867
+ border-radius: 10px 10px 0 0;
11499
11868
  max-width: none;
11500
11869
  }
11501
11870
 
11502
11871
  .feedback-survey-close {
11503
11872
  position: absolute;
11504
- top: var(--spacing-3);
11505
- right: var(--spacing-3);
11873
+ top: var(--spacing-4);
11874
+ right: var(--spacing-4);
11506
11875
  background: none;
11507
11876
  border: none;
11508
11877
  cursor: pointer;
11509
11878
  color: var(--color-neutral-500);
11510
11879
  padding: 0;
11511
- width: 28px;
11512
- height: 28px;
11880
+ width: 20px;
11881
+ height: 20px;
11513
11882
  display: flex;
11514
11883
  align-items: center;
11515
11884
  justify-content: center;
11516
- border-radius: var(--radius-md);
11885
+ border-radius: 8px;
11517
11886
  transition: all var(--transition-base);
11518
11887
  }
11519
11888
 
11889
+ .feedback-survey-close svg {
11890
+ width: 18px;
11891
+ height: 18px;
11892
+ }
11893
+
11520
11894
  .feedback-survey-close:hover {
11521
11895
  background: var(--color-neutral-100);
11522
11896
  color: var(--color-neutral-900);
11523
11897
  }
11524
11898
 
11899
+ .feedback-survey-close:focus-visible {
11900
+ outline: none;
11901
+ box-shadow: 0 0 0 3px var(--color-primary-light);
11902
+ }
11903
+
11525
11904
  .feedback-survey-title {
11526
11905
  margin: 0 0 var(--spacing-2) 0;
11527
11906
  font-size: var(--font-size-xl);
11528
- font-weight: var(--font-weight-bold);
11529
- padding-right: var(--spacing-6);
11907
+ font-weight: var(--font-weight-semibold);
11908
+ line-height: var(--line-height-snug);
11909
+ padding-right: var(--spacing-12);
11530
11910
  color: var(--color-text-primary);
11531
11911
  }
11532
11912
 
11533
11913
  .feedback-survey-description {
11534
11914
  color: var(--color-text-secondary);
11535
- margin: 0 0 var(--spacing-5) 0;
11536
- font-size: var(--font-size-base);
11915
+ margin: 0 0 var(--spacing-4) 0;
11916
+ font-size: var(--font-size-md);
11537
11917
  line-height: var(--line-height-relaxed);
11538
11918
  }
11539
11919
 
11920
+ .feedback-survey-description-primary .feedback-survey-description {
11921
+ color: var(--color-text-primary);
11922
+ font-size: var(--font-size-lg);
11923
+ font-weight: var(--font-weight-semibold);
11924
+ line-height: var(--line-height-snug);
11925
+ padding-right: var(--spacing-12);
11926
+ }
11927
+
11540
11928
  .feedback-survey-content {
11541
- margin-bottom: var(--spacing-4);
11929
+ margin-bottom: var(--spacing-3);
11542
11930
  }
11543
11931
 
11544
11932
  /* ========================================
@@ -11555,7 +11943,7 @@
11555
11943
  width: 28px;
11556
11944
  height: 36px;
11557
11945
  border: 1px solid var(--color-border);
11558
- border-radius: var(--radius-md);
11946
+ border-radius: 8px;
11559
11947
  background: var(--color-surface);
11560
11948
  cursor: pointer;
11561
11949
  font-size: var(--font-size-sm);
@@ -11566,8 +11954,8 @@
11566
11954
  }
11567
11955
 
11568
11956
  .feedback-survey-nps-btn:hover {
11569
- border-color: var(--color-primary);
11570
- background: var(--color-white);
11957
+ background: var(--color-neutral-100);
11958
+ border-color: var(--color-border);
11571
11959
  }
11572
11960
 
11573
11961
  .feedback-survey-nps-btn.selected {
@@ -11590,7 +11978,7 @@
11590
11978
  background: none;
11591
11979
  border: none;
11592
11980
  cursor: pointer;
11593
- font-size: 36px;
11981
+ font-size: 28px;
11594
11982
  transition: transform var(--transition-fast);
11595
11983
  padding: var(--spacing-2);
11596
11984
  }
@@ -11629,8 +12017,8 @@
11629
12017
  }
11630
12018
 
11631
12019
  .feedback-survey-ces-btn:hover {
11632
- border-color: var(--color-primary);
11633
- background: var(--color-white);
12020
+ background: var(--color-neutral-100);
12021
+ border-color: var(--color-border);
11634
12022
  }
11635
12023
 
11636
12024
  .feedback-survey-ces-btn.selected {
@@ -11639,6 +12027,56 @@
11639
12027
  color: var(--color-white);
11640
12028
  }
11641
12029
 
12030
+ .feedback-survey-rating-scale {
12031
+ display: flex;
12032
+ gap: 0;
12033
+ border: 1px solid var(--color-neutral-300);
12034
+ border-radius: 8px;
12035
+ overflow: hidden;
12036
+ background: var(--color-white);
12037
+ }
12038
+
12039
+ .feedback-survey-rating-scale-btn {
12040
+ flex: 1;
12041
+ width: auto;
12042
+ height: auto;
12043
+ min-height: 64px;
12044
+ padding: 0;
12045
+ border: 0;
12046
+ border-right: 1px solid var(--color-neutral-300);
12047
+ border-radius: 0;
12048
+ background: var(--color-white);
12049
+ cursor: pointer;
12050
+ font-size: clamp(16px, 3vw, 22px);
12051
+ font-weight: var(--font-weight-medium);
12052
+ color: var(--color-black);
12053
+ transition:
12054
+ background var(--transition-fast),
12055
+ color var(--transition-fast),
12056
+ box-shadow var(--transition-fast);
12057
+ position: relative;
12058
+ }
12059
+
12060
+ .feedback-survey-rating-scale-btn:last-child {
12061
+ border-right: none;
12062
+ }
12063
+
12064
+ .feedback-survey-rating-scale-btn:hover {
12065
+ background: var(--color-neutral-100);
12066
+ }
12067
+
12068
+ .feedback-survey-rating-scale-btn:focus-visible {
12069
+ outline: none;
12070
+ z-index: 1;
12071
+ box-shadow: inset 0 0 0 3px var(--color-primary);
12072
+ }
12073
+
12074
+ .feedback-survey-rating-scale-btn.selected {
12075
+ background: var(--color-primary-light);
12076
+ color: var(--color-primary-active);
12077
+ box-shadow: inset 0 0 0 2px var(--color-primary);
12078
+ }
12079
+
11642
12080
  .feedback-survey-labels {
11643
12081
  display: flex;
11644
12082
  justify-content: space-between;
@@ -11647,6 +12085,14 @@
11647
12085
  color: var(--color-text-tertiary);
11648
12086
  }
11649
12087
 
12088
+ .feedback-survey-rating-scale + .feedback-survey-labels {
12089
+ margin-top: var(--spacing-3);
12090
+ padding: 0 var(--spacing-1);
12091
+ font-size: var(--font-size-sm);
12092
+ font-weight: var(--font-weight-normal);
12093
+ color: var(--color-text-tertiary);
12094
+ }
12095
+
11650
12096
  /* ========================================
11651
12097
  FREQUENCY
11652
12098
  ======================================== */
@@ -11671,8 +12117,8 @@
11671
12117
  }
11672
12118
 
11673
12119
  .feedback-survey-freq-btn:hover {
11674
- border-color: var(--color-primary);
11675
- background: var(--color-white);
12120
+ background: var(--color-neutral-100);
12121
+ border-color: var(--color-border);
11676
12122
  }
11677
12123
 
11678
12124
  .feedback-survey-freq-btn.selected {
@@ -11829,7 +12275,7 @@
11829
12275
  border: 1px solid var(--color-primary);
11830
12276
  border-radius: var(--radius-md);
11831
12277
  font-size: var(--font-size-base);
11832
- font-weight: var(--font-weight-semibold);
12278
+ font-weight: var(--font-weight-medium);
11833
12279
  cursor: pointer;
11834
12280
  font-family: inherit;
11835
12281
  transition: all var(--transition-base);
@@ -11855,7 +12301,7 @@
11855
12301
  color: var(--color-white);
11856
12302
  padding: var(--spacing-3) var(--spacing-5);
11857
12303
  border-radius: var(--radius-xl);
11858
- font-size: var(--font-size-base);
12304
+ font-size: var(--font-size-sm);
11859
12305
  font-weight: var(--font-weight-medium);
11860
12306
  z-index: var(--z-notification);
11861
12307
  box-shadow: var(--shadow-lg);
@@ -11875,6 +12321,7 @@
11875
12321
  @media (max-width: 768px) {
11876
12322
  .feedback-survey {
11877
12323
  min-width: 300px;
12324
+ padding: var(--spacing-6);
11878
12325
  }
11879
12326
 
11880
12327
  .feedback-survey-bottom {
@@ -11888,7 +12335,24 @@
11888
12335
  }
11889
12336
 
11890
12337
  .feedback-survey-csat-btn {
11891
- font-size: 32px;
12338
+ font-size: 24px;
12339
+ }
12340
+
12341
+ .feedback-survey-title {
12342
+ font-size: var(--font-size-lg);
12343
+ }
12344
+
12345
+ .feedback-survey-description-primary .feedback-survey-description {
12346
+ font-size: var(--font-size-md);
12347
+ }
12348
+
12349
+ .feedback-survey-rating-scale-btn {
12350
+ min-height: 52px;
12351
+ font-size: clamp(14px, 6vw, 18px);
12352
+ }
12353
+
12354
+ .feedback-survey-rating-scale + .feedback-survey-labels {
12355
+ font-size: var(--font-size-xs);
11892
12356
  }
11893
12357
  }
11894
12358
  `;