@coveo/atomic 3.64.1 → 3.65.1

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.
Files changed (97) hide show
  1. package/custom-elements.json +307 -173
  2. package/dist/assets/education.svg +0 -0
  3. package/dist/assets/events.svg +0 -0
  4. package/dist/assets/fulfillment_order.svg +0 -0
  5. package/dist/assets/opportunity_contact_role.svg +0 -0
  6. package/dist/assets/order_item.svg +0 -0
  7. package/dist/assets/recycle_bin.svg +0 -0
  8. package/dist/assets/store.svg +0 -0
  9. package/dist/cjs/components/commerce/atomic-commerce-search-box/atomic-commerce-search-box.cjs +108 -13
  10. package/dist/cjs/components/commerce/product-list/product-template-provider.cjs +2 -0
  11. package/dist/cjs/components/common/atomic-modal/atomic-modal.cjs +8 -1
  12. package/dist/cjs/components/common/atomic-tab-popover/atomic-tab-popover.cjs +1 -0
  13. package/dist/cjs/components/common/facets/timeframe-facet-common.cjs +2 -2
  14. package/dist/cjs/components/common/generated-answer/answer-announcement.cjs +8 -5
  15. package/dist/cjs/components/common/generated-answer/generated-answer-controller.cjs +6 -3
  16. package/dist/cjs/components/common/generated-answer/generated-content/markdown-utils.cjs +1 -0
  17. package/dist/cjs/components/common/generated-answer/render-disclaimer.cjs +6 -2
  18. package/dist/cjs/components/common/item-list/result-template-provider.cjs +1 -0
  19. package/dist/cjs/components/common/result-templates/result-template-controller.cjs +1 -0
  20. package/dist/cjs/components/common/suggestions/suggestion-manager.cjs +3 -0
  21. package/dist/cjs/components/insight/atomic-insight-facet/atomic-insight-facet.cjs +2 -2
  22. package/dist/cjs/components/insight/atomic-insight-generated-answer/atomic-insight-generated-answer.cjs +1 -0
  23. package/dist/cjs/components/insight/atomic-insight-result-attach-to-case-indicator/atomic-insight-result-attach-to-case-indicator.cjs +1 -0
  24. package/dist/cjs/components/insight/atomic-insight-user-actions-session/atomic-insight-user-actions-session.cjs +1 -0
  25. package/dist/cjs/components/insight/atomic-insight-user-actions-session/user-action.cjs +1 -0
  26. package/dist/cjs/components/search/atomic-generated-answer/atomic-generated-answer.cjs +2 -0
  27. package/dist/cjs/components/search/atomic-rating-range-facet/atomic-rating-range-facet.cjs +3 -4
  28. package/dist/cjs/components/search/atomic-search-box/atomic-search-box.cjs +107 -13
  29. package/dist/cjs/components/search/atomic-search-box-instant-results/atomic-search-box-instant-results.cjs +1 -0
  30. package/dist/cjs/global/environment.cjs +1 -1
  31. package/dist/cjs/utils/tailwind.global.tw.css.cjs +1 -1
  32. package/dist/cjs/versions.cjs +1 -1
  33. package/dist/esm/components/commerce/atomic-commerce-search-box/atomic-commerce-search-box.js +109 -14
  34. package/dist/esm/components/commerce/product-list/product-template-provider.js +2 -0
  35. package/dist/esm/components/common/atomic-modal/atomic-modal.js +9 -2
  36. package/dist/esm/components/common/atomic-tab-popover/atomic-tab-popover.js +1 -0
  37. package/dist/esm/components/common/facets/timeframe-facet-common.js +2 -2
  38. package/dist/esm/components/common/generated-answer/answer-announcement.js +8 -5
  39. package/dist/esm/components/common/generated-answer/generated-answer-controller.js +6 -3
  40. package/dist/esm/components/common/generated-answer/generated-content/markdown-utils.js +1 -0
  41. package/dist/esm/components/common/generated-answer/render-disclaimer.js +4 -3
  42. package/dist/esm/components/common/item-list/result-template-provider.js +1 -0
  43. package/dist/esm/components/common/result-templates/result-template-controller.js +1 -0
  44. package/dist/esm/components/common/suggestions/suggestion-manager.js +3 -0
  45. package/dist/esm/components/insight/atomic-insight-facet/atomic-insight-facet.js +2 -2
  46. package/dist/esm/components/insight/atomic-insight-generated-answer/atomic-insight-generated-answer.js +2 -1
  47. package/dist/esm/components/insight/atomic-insight-result-attach-to-case-indicator/atomic-insight-result-attach-to-case-indicator.js +1 -0
  48. package/dist/esm/components/insight/atomic-insight-user-actions-session/atomic-insight-user-actions-session.js +1 -0
  49. package/dist/esm/components/insight/atomic-insight-user-actions-session/user-action.js +1 -0
  50. package/dist/esm/components/search/atomic-generated-answer/atomic-generated-answer.js +3 -1
  51. package/dist/esm/components/search/atomic-rating-range-facet/atomic-rating-range-facet.js +3 -4
  52. package/dist/esm/components/search/atomic-search-box/atomic-search-box.js +109 -15
  53. package/dist/esm/components/search/atomic-search-box-instant-results/atomic-search-box-instant-results.js +1 -0
  54. package/dist/esm/global/environment.js +1 -1
  55. package/dist/esm/utils/tailwind.global.tw.css.js +1 -1
  56. package/dist/esm/versions.js +1 -1
  57. package/dist/lang/cs.json +1 -1
  58. package/dist/lang/da.json +1 -1
  59. package/dist/lang/de.json +1 -1
  60. package/dist/lang/dev.json +1 -1
  61. package/dist/lang/el.json +1 -1
  62. package/dist/lang/en.json +1 -1
  63. package/dist/lang/es.json +1 -1
  64. package/dist/lang/fi.json +1 -1
  65. package/dist/lang/fr.json +1 -1
  66. package/dist/lang/hu.json +1 -1
  67. package/dist/lang/id.json +1 -1
  68. package/dist/lang/it.json +1 -1
  69. package/dist/lang/ja.json +1 -1
  70. package/dist/lang/ko.json +1 -1
  71. package/dist/lang/nl.json +1 -1
  72. package/dist/lang/no.json +1 -1
  73. package/dist/lang/pl.json +1 -1
  74. package/dist/lang/pt-BR.json +1 -1
  75. package/dist/lang/pt.json +1 -1
  76. package/dist/lang/ru.json +1 -1
  77. package/dist/lang/sv.json +1 -1
  78. package/dist/lang/th.json +1 -1
  79. package/dist/lang/tr.json +1 -1
  80. package/dist/lang/zh-CN.json +1 -1
  81. package/dist/lang/zh-TW.json +1 -1
  82. package/dist/lang/zh.json +1 -1
  83. package/dist/types/components/commerce/atomic-commerce-search-box/atomic-commerce-search-box.d.ts +23 -6
  84. package/dist/types/components/commerce/product-list/product-template-provider.d.ts +2 -0
  85. package/dist/types/components/common/atomic-modal/atomic-modal.d.ts +6 -0
  86. package/dist/types/components/common/atomic-tab-popover/atomic-tab-popover.d.ts +1 -0
  87. package/dist/types/components/common/generated-answer/generated-content/markdown-utils.d.ts +1 -0
  88. package/dist/types/components/common/generated-answer/render-disclaimer.d.ts +3 -0
  89. package/dist/types/components/common/item-list/result-template-provider.d.ts +1 -0
  90. package/dist/types/components/common/layout/item-layout-sections.d.ts +1 -1
  91. package/dist/types/components/common/result-templates/result-template-controller.d.ts +1 -0
  92. package/dist/types/components/insight/atomic-insight-result-attach-to-case-indicator/atomic-insight-result-attach-to-case-indicator.d.ts +1 -0
  93. package/dist/types/components/insight/atomic-insight-user-actions-session/atomic-insight-user-actions-session.d.ts +1 -0
  94. package/dist/types/components/insight/atomic-insight-user-actions-session/user-action.d.ts +1 -0
  95. package/dist/types/components/search/atomic-search-box/atomic-search-box.d.ts +23 -6
  96. package/dist/types/components/search/atomic-search-box-instant-results/atomic-search-box-instant-results.d.ts +1 -0
  97. package/package.json +28 -27
@@ -1,8 +1,12 @@
1
+ import { Schema, StringValue } from "@coveo/bueno";
1
2
  import { buildSearchBox, buildStandaloneSearchBox, loadQuerySetActions } from "@coveo/headless/commerce";
2
- import { LitElement, css, html } from "lit";
3
+ import { LitElement, css, html, nothing } from "lit";
3
4
  import { customElement, property, state } from "lit/decorators.js";
4
5
  import { classMap } from "lit/directives/class-map.js";
5
6
  import { createRef, ref } from "lit/directives/ref.js";
7
+ import { when } from "lit/directives/when.js";
8
+ import { renderButton } from "../../common/button.js";
9
+ import { ValidatePropsController } from "../../common/validate-props-controller/validate-props-controller.js";
6
10
  import { booleanConverter } from "../../../converters/boolean-converter.js";
7
11
  import { bindStateToController } from "../../../decorators/bind-state.js";
8
12
  import { bindingGuard } from "../../../decorators/binding-guard.js";
@@ -226,7 +230,7 @@ class AtomicCommerceSearchBox extends LitElement {
226
230
  }
227
231
  break;
228
232
  case 'Tab':
229
- this.suggestionManager.clearSuggestions();
233
+ if ('bottom' !== this.clearRecentButtonPosition || !this.clearRecentQueriesElement) this.suggestionManager.clearSuggestions();
230
234
  break;
231
235
  default:
232
236
  if (this.suggestionManager.keyboardActiveDescendant) this.suggestionManager.updateKeyboardActiveDescendant();
@@ -291,11 +295,59 @@ class AtomicCommerceSearchBox extends LitElement {
291
295
  }
292
296
  })}`;
293
297
  }
298
+ get clearRecentQueriesElement() {
299
+ const { leftSuggestionElements, rightSuggestionElements } = this.suggestionManager;
300
+ return [
301
+ leftSuggestionElements,
302
+ rightSuggestionElements
303
+ ].flatMap((elements)=>elements.slice(0, -1)).find((element)=>'recent-query-clear' === element.key);
304
+ }
305
+ renderRecentQueriesTitle() {
306
+ return html`<div
307
+ part="recent-query-title"
308
+ class="text-neutral-dark flex min-h-10 items-center px-4 font-bold"
309
+ @mousedown=${(e)=>e.preventDefault()}
310
+ >
311
+ ${this.bindings.i18n.t('recent-searches')}
312
+ </div>`;
313
+ }
314
+ renderClearRecentQueriesButton(element) {
315
+ const deselectSuggestion = ()=>{
316
+ this.suggestionManager.updateKeyboardActiveDescendant();
317
+ this.suggestionManager.updateActiveDescendant();
318
+ };
319
+ return html`<div
320
+ class="border-neutral flex border-t"
321
+ @mousedown=${(e)=>e.preventDefault()}
322
+ @mouseenter=${deselectSuggestion}
323
+ @focusin=${deselectSuggestion}
324
+ @keydown=${(e)=>{
325
+ if ('Escape' !== e.key) return;
326
+ this.textAreaRef.value?.focus();
327
+ this.isExpanded = false;
328
+ this.suggestionManager.clearSuggestions();
329
+ }}
330
+ >
331
+ ${renderButton({
332
+ props: {
333
+ style: 'text-primary',
334
+ text: this.bindings.i18n.t('clear-recent-searches'),
335
+ part: 'recent-query-clear-button',
336
+ class: 'focus-visible:ring-ring-primary flex min-h-12 w-full items-center justify-center rounded-none px-4 focus-visible:ring-2 focus-visible:ring-inset',
337
+ onClick: (e)=>{
338
+ element.onSelect?.(e);
339
+ this.textAreaRef.value?.focus();
340
+ }
341
+ }
342
+ })(nothing)}
343
+ </div>`;
344
+ }
294
345
  renderSuggestions() {
295
346
  const part = `suggestions-wrapper ${this.suggestionManager.isDoubleList ? 'suggestions-double-list' : 'suggestions-single-list'}`;
296
347
  const isVisible = this.suggestionManager.hasSuggestions && this.isExpanded && !this.isSearchDisabledForEndUser;
297
348
  const classes = {
298
349
  'bg-background border-neutral absolute top-full left-0 z-10 flex w-full rounded-md border': true,
350
+ 'overflow-hidden': 'bottom' === this.clearRecentButtonPosition,
299
351
  hidden: !isVisible
300
352
  };
301
353
  return html`<div
@@ -306,25 +358,43 @@ class AtomicCommerceSearchBox extends LitElement {
306
358
  aria-label=${this.bindings.i18n.t(this.suggestionManager.isDoubleList ? 'search-suggestions-double-list' : 'search-suggestions-single-list')}
307
359
  aria-activedescendant=${this.suggestionManager.activeDescendant}
308
360
  >
309
- ${this.renderPanel('left', this.suggestionManager.leftSuggestionElements, (el)=>{
310
- this.suggestionManager.leftPanel = el;
311
- }, ()=>this.suggestionManager.leftPanel)}
312
- ${this.renderPanel('right', this.suggestionManager.rightSuggestionElements, (el)=>{
313
- this.suggestionManager.rightPanel = el;
314
- }, ()=>this.suggestionManager.rightPanel)}
361
+ ${this.renderPanel('left', this.suggestionManager.leftSuggestionElements, this.setLeftPanel, ()=>this.suggestionManager.leftPanel)}
362
+ ${this.renderPanel('right', this.suggestionManager.rightSuggestionElements, this.setRightPanel, ()=>this.suggestionManager.rightPanel)}
315
363
  </div>`;
316
364
  }
317
365
  renderPanel(side, elements, setRef, getRef) {
318
- if (!elements.length) return null;
366
+ let listElements = elements;
367
+ let isListNested = false;
368
+ let recentQueriesTitle;
369
+ let clearRecentQueriesButton;
370
+ switch(this.clearRecentButtonPosition){
371
+ case 'bottom':
372
+ {
373
+ isListNested = true;
374
+ const clearElement = this.clearRecentQueriesElement;
375
+ if (clearElement && elements.includes(clearElement)) {
376
+ listElements = elements.filter((element)=>element !== clearElement);
377
+ clearRecentQueriesButton = this.renderClearRecentQueriesButton(clearElement);
378
+ if (elements[0] === clearElement) recentQueriesTitle = this.renderRecentQueriesTitle();
379
+ }
380
+ break;
381
+ }
382
+ }
383
+ if (!listElements.length) return null;
384
+ const suggestions = listElements.map((suggestion, index)=>this.renderSuggestion(suggestion, index, listElements.length - 1, side));
319
385
  return html`<div
320
386
  part="suggestions suggestions-${side}"
321
- ${ref(setRef)}
387
+ ${ref(isListNested ? void 0 : setRef)}
322
388
  class="flex grow basis-1/2 flex-col"
323
389
  @mousedown=${(e)=>{
324
390
  if (e.target === getRef()) e.preventDefault();
325
391
  }}
326
392
  >
327
- ${elements.map((suggestion, index)=>this.renderSuggestion(suggestion, index, elements.length - 1, side))}
393
+ ${recentQueriesTitle}
394
+ ${when(isListNested, ()=>html`<div class="flex grow flex-col" ${ref(setRef)}>
395
+ ${suggestions}
396
+ </div>`, ()=>suggestions)}
397
+ ${clearRecentQueriesButton}
328
398
  </div>`;
329
399
  }
330
400
  renderSuggestion(item, index, lastIndex, side) {
@@ -390,10 +460,25 @@ class AtomicCommerceSearchBox extends LitElement {
390
460
  announceClearSearchBoxToScreenReader() {
391
461
  this.searchBoxAriaMessage.message = this.bindings.i18n.t('search-box-cleared');
392
462
  }
393
- constructor(...args){
394
- super(...args), this.isExpanded = false, this.textAreaRef = createRef(), this.searchBoxSuggestionEventsQueue = [], this.searchBoxAriaMessage = new AriaLiveRegionController(this, 'search-box'), this.suggestionsAriaMessage = new AriaLiveRegionController(this, 'search-suggestions', true), this.numberOfQueries = 8, this.suggestionTimeout = 400, this.suggestionDelay = 0, this.disableSearch = false, this.minimumQueryLength = 0, this.clearFilters = true, this.updateBreakpoints = once(()=>updateBreakpoints(this));
463
+ constructor(){
464
+ super(), this.isExpanded = false, this.textAreaRef = createRef(), this.setLeftPanel = (el)=>{
465
+ this.suggestionManager.leftPanel = el;
466
+ }, this.setRightPanel = (el)=>{
467
+ this.suggestionManager.rightPanel = el;
468
+ }, this.searchBoxSuggestionEventsQueue = [], this.searchBoxAriaMessage = new AriaLiveRegionController(this, 'search-box'), this.suggestionsAriaMessage = new AriaLiveRegionController(this, 'search-suggestions', true), this.numberOfQueries = 8, this.suggestionTimeout = 400, this.suggestionDelay = 0, this.disableSearch = false, this.minimumQueryLength = 0, this.clearFilters = true, this.clearRecentButtonPosition = 'top', this.updateBreakpoints = once(()=>updateBreakpoints(this));
469
+ new ValidatePropsController(this, ()=>({
470
+ clearRecentButtonPosition: this.clearRecentButtonPosition
471
+ }), AtomicCommerceSearchBox.propsSchema);
395
472
  }
396
473
  }
474
+ AtomicCommerceSearchBox.propsSchema = new Schema({
475
+ clearRecentButtonPosition: new StringValue({
476
+ constrainTo: [
477
+ 'top',
478
+ 'bottom'
479
+ ]
480
+ })
481
+ });
397
482
  AtomicCommerceSearchBox.shadowRootOptions = {
398
483
  ...LitElement.shadowRootOptions,
399
484
  delegatesFocus: true
@@ -465,6 +550,14 @@ _ts_decorate([
465
550
  converter: booleanConverter
466
551
  })
467
552
  ], AtomicCommerceSearchBox.prototype, "clearFilters", void 0);
553
+ _ts_decorate([
554
+ property({
555
+ type: String,
556
+ attribute: 'clear-recent-button-position',
557
+ reflect: true
558
+ }),
559
+ _ts_metadata("design:type", String)
560
+ ], AtomicCommerceSearchBox.prototype, "clearRecentButtonPosition", void 0);
468
561
  _ts_decorate([
469
562
  watch('redirectionUrl'),
470
563
  _ts_metadata("design:type", Function),
@@ -481,6 +574,8 @@ _ts_decorate([
481
574
  AtomicCommerceSearchBox = _ts_decorate([
482
575
  customElement('atomic-commerce-search-box'),
483
576
  bindings(),
484
- withTailwindStyles
577
+ withTailwindStyles,
578
+ _ts_metadata("design:type", Function),
579
+ _ts_metadata("design:paramtypes", [])
485
580
  ], AtomicCommerceSearchBox);
486
581
  export { AtomicCommerceSearchBox };
@@ -1,6 +1,8 @@
1
1
  import { buildProductTemplatesManager } from "@coveo/headless/commerce";
2
2
  import { TemplateProvider } from "../../common/template-provider/template-provider.js";
3
3
  import "../atomic-product-template/atomic-product-template.js";
4
+ import "../atomic-product-section-name/atomic-product-section-name.js";
5
+ import "../atomic-product-section-visual/atomic-product-section-visual.js";
4
6
  class ProductTemplateProvider extends TemplateProvider {
5
7
  makeDefaultTemplate() {
6
8
  const content = document.createDocumentFragment();
@@ -11,7 +11,8 @@ import { multiClassMap, tw } from "../../../directives/multi-class-map.js";
11
11
  import { InitializeBindingsMixin } from "../../../mixins/bindings-mixin.js";
12
12
  import { buildCustomEvent, listenOnce } from "../../../utils/event-utils.js";
13
13
  import { updateBreakpoints } from "../../../utils/replace-breakpoint-utils.js";
14
- import { once, randomID } from "../../../utils/utils.js";
14
+ import { getFocusedElement, isAncestorOf, once, randomID } from "../../../utils/utils.js";
15
+ import "../atomic-focus-trap/atomic-focus-trap.js";
15
16
  function _ts_decorate(decorators, target, key, desc) {
16
17
  var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
17
18
  if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
@@ -52,7 +53,7 @@ class AtomicModal extends InitializeBindingsMixin(LitElement) {
52
53
  role="dialog"
53
54
  aria-modal=${this.isOpen ? 'true' : 'false'}
54
55
  aria-labelledby=${this.headerId}
55
- .source=${this.source}
56
+ .source=${this.source ?? this.focusedElementBeforeOpen}
56
57
  .container=${this.container ?? this}
57
58
  ${ref(this.focusTrap)}
58
59
  .scope=${this.scope ?? this.bindings?.interfaceElement ?? document.body}
@@ -96,6 +97,8 @@ class AtomicModal extends InitializeBindingsMixin(LitElement) {
96
97
  }
97
98
  async handleModalOpen() {
98
99
  const executionId = this.createExecutionTracker();
100
+ const focusedElement = getFocusedElement();
101
+ this.focusedElementBeforeOpen = focusedElement instanceof HTMLElement && !isAncestorOf(this, focusedElement) ? focusedElement : void 0;
99
102
  if (!this.shouldRender) {
100
103
  this.shouldRender = true;
101
104
  await this.updateComplete;
@@ -272,6 +275,10 @@ _ts_decorate([
272
275
  }),
273
276
  _ts_metadata("design:type", "u" < typeof HTMLElement ? Object : HTMLElement)
274
277
  ], AtomicModal.prototype, "source", void 0);
278
+ _ts_decorate([
279
+ state(),
280
+ _ts_metadata("design:type", "u" < typeof HTMLElement ? Object : HTMLElement)
281
+ ], AtomicModal.prototype, "focusedElementBeforeOpen", void 0);
275
282
  _ts_decorate([
276
283
  errorGuard(),
277
284
  _ts_metadata("design:type", Function),
@@ -9,6 +9,7 @@ import { bindings } from "../../../decorators/bindings.js";
9
9
  import { errorGuard } from "../../../decorators/error-guard.js";
10
10
  import { withTailwindStyles } from "../../../decorators/with-tailwind-styles.js";
11
11
  import arrow_bottom_rounded from "../../../images/arrow-bottom-rounded.js";
12
+ import "../atomic-icon/atomic-icon.js";
12
13
  function _ts_decorate(decorators, target, key, desc) {
13
14
  var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
14
15
  if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
@@ -156,8 +156,8 @@ class TimeframeFacetCommon {
156
156
  label: this.props.label
157
157
  }
158
158
  })(html`<ul class="mt-3" part="values">
159
- ${children}
160
- </ul>`);
159
+ ${children}
160
+ </ul>`);
161
161
  }
162
162
  renderHeader(isCollapsed, headerFocus, onToggleCollapse) {
163
163
  return renderFacetHeader({
@@ -20,12 +20,15 @@ const getAnswerAnnouncement = (answer, i18n)=>{
20
20
  message: i18n.t('generating-answer'),
21
21
  assertive: false
22
22
  };
23
- if (answer.answer?.trim()) return {
24
- message: i18n.t('answer-generated', {
23
+ if (answer.answer?.trim()) {
24
+ const answerGenerated = i18n.t('answer-generated', {
25
25
  answer: markdownToPlainText(answer.answer)
26
- }),
27
- assertive: false
28
- };
26
+ });
27
+ return {
28
+ message: `${answerGenerated} ${i18n.t('generated-answer-disclaimer-announcement')}`,
29
+ assertive: false
30
+ };
31
+ }
29
32
  return SILENT;
30
33
  };
31
34
  const isSettledAnswer = (answer)=>Boolean(answer && !answer.isStreaming && !answer.isLoading && !answer.error && !answer.cannotAnswer && answer.answer?.trim());
@@ -39,9 +39,12 @@ class GeneratedAnswerController {
39
39
  if (isHidden) return bindings.i18n.t('generated-answer-hidden');
40
40
  if (isGenerating) return bindings.i18n.t('generating-answer');
41
41
  if (hasError || cannotAnswer) return bindings.i18n.t('answer-could-not-be-generated');
42
- if (hasNonEmptyAnswer) return bindings.i18n.t('answer-generated', {
43
- answer: markdownToPlainText(state.answer)
44
- });
42
+ if (hasNonEmptyAnswer) {
43
+ const answerGenerated = bindings.i18n.t('answer-generated', {
44
+ answer: markdownToPlainText(state.answer)
45
+ });
46
+ return `${answerGenerated} ${bindings.i18n.t('generated-answer-disclaimer-announcement')}`;
47
+ }
45
48
  return '';
46
49
  }
47
50
  isStatusAssertive() {
@@ -1,5 +1,6 @@
1
1
  import { Marked, Renderer } from "marked";
2
2
  import { parseHTML } from "../../../../utils/utils.js";
3
+ import "../../atomic-generated-answer-inline-link/atomic-generated-answer-inline-link.js";
3
4
  const toInlinePlainText = (textWithHtml)=>{
4
5
  const withoutHtmlTags = textWithHtml.replace(/<[^>]*>/g, ' ');
5
6
  const withCollapsedWhitespaces = withoutHtmlTags.replace(/\s{2,}/g, ' ');
@@ -1,10 +1,11 @@
1
1
  import { html } from "lit";
2
+ const DISCLAIMER_ID = 'generated-answer-disclaimer';
2
3
  const renderDisclaimer = ({ props })=>{
3
4
  const { i18n } = props;
4
5
  return html`
5
- <div class="flex justify-end text-neutral-dark text-xs/[1rem]">
6
+ <small id=${DISCLAIMER_ID} class="flex justify-end text-neutral-dark text-xs/[1rem]">
6
7
  <slot name="disclaimer">${i18n.t('generated-answer-disclaimer')}</slot>
7
- </div>
8
+ </small>
8
9
  `;
9
10
  };
10
- export { renderDisclaimer };
11
+ export { DISCLAIMER_ID, renderDisclaimer };
@@ -1,5 +1,6 @@
1
1
  import { buildResultTemplatesManager } from "@coveo/headless";
2
2
  import { TemplateProvider } from "../template-provider/template-provider.js";
3
+ import "../../search/atomic-result-link/atomic-result-link.js";
3
4
  class ResultTemplateProvider extends TemplateProvider {
4
5
  makeDefaultTemplate() {
5
6
  const content = document.createDocumentFragment();
@@ -1,4 +1,5 @@
1
1
  import { BaseTemplateController } from "../template-controller/base-template-controller.js";
2
+ import "../../search/atomic-result-link/atomic-result-link.js";
2
3
  class ResultTemplateController extends BaseTemplateController {
3
4
  getTemplate(conditions) {
4
5
  const baseTemplate = this.getBaseTemplate(conditions);
@@ -58,11 +58,13 @@ class SuggestionManager {
58
58
  const panelHasActiveDescendant = this.previousActiveDescendantElement && panel.contains(this.previousActiveDescendantElement);
59
59
  const newValue = panelHasActiveDescendant ? this.previousActiveDescendantElement : panel.firstElementChild;
60
60
  this.updateDescendants(newValue.id);
61
+ this.updateKeyboardActiveDescendant(newValue.id);
61
62
  }
62
63
  }
63
64
  clearSuggestions() {
64
65
  this.clearSuggestionElements();
65
66
  this.updateActiveDescendant();
67
+ this.updateKeyboardActiveDescendant();
66
68
  }
67
69
  async focusNextValue() {
68
70
  if (!this.hasSuggestions || !this.nextOrFirstValue) return;
@@ -111,6 +113,7 @@ class SuggestionManager {
111
113
  }
112
114
  async executeQuerySuggestion() {
113
115
  this.updateActiveDescendant();
116
+ this.updateKeyboardActiveDescendant();
114
117
  const settled = await Promise.allSettled(this.suggestions.map((suggestion)=>promiseTimeout(suggestion.onInput ? suggestion.onInput() : Promise.resolve(), this.ownerSearchBoxProps.getSuggestionTimeout())));
115
118
  const fulfilledSuggestions = [];
116
119
  settled.forEach((prom, j)=>{
@@ -110,8 +110,8 @@ class AtomicInsightFacet extends LitElement {
110
110
  label: this.label
111
111
  }
112
112
  })(html`<ul class="mt-3 ${'box' === this.displayValuesAs ? 'box-container' : ''}" part="values">
113
- ${children}
114
- </ul>`);
113
+ ${children}
114
+ </ul>`);
115
115
  }
116
116
  renderValues() {
117
117
  const firstNewValueIndex = getFirstNewFacetValueIndex(this.facet.state.values, this.valuesBeforeShowMore);
@@ -8,7 +8,7 @@ import { renderAnswerContent } from "../../common/generated-answer/render-answer
8
8
  import { renderCardHeader } from "../../common/generated-answer/render-card-header.js";
9
9
  import { renderCitations } from "../../common/generated-answer/render-citations.js";
10
10
  import { renderCustomNoAnswerMessage } from "../../common/generated-answer/render-custom-no-answer-message.js";
11
- import { renderDisclaimer } from "../../common/generated-answer/render-disclaimer.js";
11
+ import { DISCLAIMER_ID, renderDisclaimer } from "../../common/generated-answer/render-disclaimer.js";
12
12
  import { renderFeedbackAndCopyButtons } from "../../common/generated-answer/render-feedback-and-copy-buttons.js";
13
13
  import { ValidatePropsController } from "../../common/validate-props-controller/validate-props-controller.js";
14
14
  import { booleanConverter } from "../../../converters/boolean-converter.js";
@@ -101,6 +101,7 @@ class AtomicInsightGeneratedAnswer extends LitElement {
101
101
  class=${contentClasses}
102
102
  part="container"
103
103
  aria-label=${this.bindings.i18n.t('generated-answer-title')}
104
+ aria-describedby=${this.isAnswerVisible ? DISCLAIMER_ID : nothing}
104
105
  >
105
106
  <div part="generated-content">
106
107
  ${this.renderCardHeaderWrapper()}
@@ -8,6 +8,7 @@ import { bindings } from "../../../decorators/bindings.js";
8
8
  import { errorGuard } from "../../../decorators/error-guard.js";
9
9
  import { withTailwindStyles } from "../../../decorators/with-tailwind-styles.js";
10
10
  import attach from "../../../images/attach.js";
11
+ import "../../common/atomic-icon/atomic-icon.js";
11
12
  function _ts_decorate(decorators, target, key, desc) {
12
13
  var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
13
14
  if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
@@ -9,6 +9,7 @@ import { withTailwindStyles } from "../../../decorators/with-tailwind-styles.js"
9
9
  import flag from "../../../images/flag.js";
10
10
  import three_dots from "../../../images/three-dots.js";
11
11
  import { renderUserAction } from "./user-action.js";
12
+ import "../../common/atomic-icon/atomic-icon.js";
12
13
  function _ts_decorate(decorators, target, key, desc) {
13
14
  var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
14
15
  if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
@@ -6,6 +6,7 @@ import images_document from "../../../images/document.js";
6
6
  import point from "../../../images/point.js";
7
7
  import quickview from "../../../images/quickview.js";
8
8
  import search from "../../../images/search.js";
9
+ import "../../common/atomic-icon/atomic-icon.js";
9
10
  const icons = {
10
11
  SEARCH: search,
11
12
  CLICK: images_document,
@@ -11,7 +11,7 @@ import { renderAnswerContent } from "../../common/generated-answer/render-answer
11
11
  import { renderCardHeader } from "../../common/generated-answer/render-card-header.js";
12
12
  import { renderCitations } from "../../common/generated-answer/render-citations.js";
13
13
  import { renderCustomNoAnswerMessage } from "../../common/generated-answer/render-custom-no-answer-message.js";
14
- import { renderDisclaimer } from "../../common/generated-answer/render-disclaimer.js";
14
+ import { DISCLAIMER_ID, renderDisclaimer } from "../../common/generated-answer/render-disclaimer.js";
15
15
  import { renderFeedbackAndCopyButtons } from "../../common/generated-answer/render-feedback-and-copy-buttons.js";
16
16
  import { ValidatePropsController } from "../../common/validate-props-controller/validate-props-controller.js";
17
17
  import { arrayConverter } from "../../../converters/array-converter.js";
@@ -121,6 +121,7 @@ class AtomicGeneratedAnswer extends LitElement {
121
121
  class=${contentClasses}
122
122
  part="container"
123
123
  aria-label=${this.bindings.i18n.t('generated-answer-title')}
124
+ aria-describedby=${this.isAnswerVisible ? DISCLAIMER_ID : nothing}
124
125
  >
125
126
  <div part="generated-content">
126
127
  ${this.renderCardHeaderWrapper()}
@@ -133,6 +134,7 @@ class AtomicGeneratedAnswer extends LitElement {
133
134
  'agent-scrollable': this.areFollowUpsEnabled
134
135
  })}
135
136
  tabindex=${this.areFollowUpsEnabled ? '0' : nothing}
137
+ aria-describedby=${this.areFollowUpsEnabled ? DISCLAIMER_ID : nothing}
136
138
  >
137
139
  <article>${this.renderAnswerContent()}</article>
138
140
  </div>
@@ -194,8 +194,8 @@ class AtomicRatingRangeFacet extends LitElement {
194
194
  label: this.label
195
195
  }
196
196
  })(html`<ul class="mt-3" part="values">
197
- ${children}
198
- </ul>`);
197
+ ${children}
198
+ </ul>`);
199
199
  }
200
200
  renderValues() {
201
201
  return this.renderValuesContainer(this.valuesToRender.map((value)=>this.renderValue(value, ()=>this.facet.toggleSingleSelect(value))));
@@ -212,8 +212,7 @@ class AtomicRatingRangeFacet extends LitElement {
212
212
  }
213
213
  });
214
214
  if (!this.valuesToRender.length) return nothing;
215
- return renderFacetContainer()(html`${this.renderHeader()}
216
- ${when(!this.isCollapsed, ()=>this.renderValues())}`);
215
+ return renderFacetContainer()(html`${this.renderHeader()} ${when(!this.isCollapsed, ()=>this.renderValues())}`);
217
216
  })}`;
218
217
  }
219
218
  constructor(){