@coveo/atomic 3.59.2 → 3.59.4

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 (28) hide show
  1. package/custom-elements.json +536 -81
  2. package/dist/cjs/components/commerce/atomic-commerce-search-box/atomic-commerce-search-box.cjs +1 -0
  3. package/dist/cjs/components/insight/atomic-insight-search-box/atomic-insight-search-box.cjs +1 -0
  4. package/dist/cjs/components/insight/atomic-insight-tab/atomic-insight-tab.cjs +66 -22
  5. package/dist/cjs/components/insight/atomic-insight-tabs/atomic-insight-tabs.cjs +3 -1
  6. package/dist/cjs/components/ipx/atomic-ipx-tab/atomic-ipx-tab.cjs +66 -30
  7. package/dist/cjs/components/ipx/atomic-ipx-tabs/atomic-ipx-tabs.cjs +3 -1
  8. package/dist/cjs/components/search/atomic-search-box/atomic-search-box.cjs +1 -0
  9. package/dist/cjs/generated/dayjs-locales-data.cjs +6 -6
  10. package/dist/cjs/global/environment.cjs +1 -1
  11. package/dist/cjs/utils/hidden-state-controller.cjs +63 -0
  12. package/dist/cjs/versions.cjs +1 -1
  13. package/dist/esm/components/commerce/atomic-commerce-search-box/atomic-commerce-search-box.js +1 -0
  14. package/dist/esm/components/insight/atomic-insight-search-box/atomic-insight-search-box.js +1 -0
  15. package/dist/esm/components/insight/atomic-insight-tab/atomic-insight-tab.js +51 -20
  16. package/dist/esm/components/insight/atomic-insight-tabs/atomic-insight-tabs.js +3 -1
  17. package/dist/esm/components/ipx/atomic-ipx-tab/atomic-ipx-tab.js +52 -29
  18. package/dist/esm/components/ipx/atomic-ipx-tabs/atomic-ipx-tabs.js +3 -1
  19. package/dist/esm/components/search/atomic-search-box/atomic-search-box.js +1 -0
  20. package/dist/esm/generated/dayjs-locales-data.js +6 -6
  21. package/dist/esm/global/environment.js +1 -1
  22. package/dist/esm/utils/hidden-state-controller.js +29 -0
  23. package/dist/esm/versions.js +1 -1
  24. package/dist/types/components/insight/atomic-insight-smart-snippet-feedback-modal/atomic-insight-smart-snippet-feedback-modal.d.ts +0 -2
  25. package/dist/types/components/insight/atomic-insight-tab/atomic-insight-tab.d.ts +5 -0
  26. package/dist/types/components/insight/atomic-insight-user-actions-modal/atomic-insight-user-actions-modal.d.ts +0 -2
  27. package/dist/types/components/ipx/atomic-ipx-tab/atomic-ipx-tab.d.ts +6 -1
  28. package/package.json +13 -13
@@ -226,6 +226,7 @@ class AtomicCommerceSearchBox extends external_lit_namespaceObject.LitElement {
226
226
  if (!e.shiftKey) this.onSubmit();
227
227
  break;
228
228
  case 'Escape':
229
+ this.isExpanded = false;
229
230
  this.suggestionManager.clearSuggestions();
230
231
  break;
231
232
  case 'ArrowDown':
@@ -123,6 +123,7 @@ class AtomicInsightSearchBox extends external_lit_namespaceObject.LitElement {
123
123
  if (!e.shiftKey) this.onSubmit();
124
124
  break;
125
125
  case 'Escape':
126
+ this.isExpanded = false;
126
127
  this.suggestionManager.clearSuggestions();
127
128
  break;
128
129
  case 'ArrowDown':
@@ -30,7 +30,6 @@ const insight_namespaceObject = require("@coveo/headless/insight");
30
30
  const external_lit_namespaceObject = require("lit");
31
31
  const decorators_js_namespaceObject = require("lit/decorators.js");
32
32
  const when_js_namespaceObject = require("lit/directives/when.js");
33
- const button_cjs_namespaceObject = require("../../common/button.cjs");
34
33
  const store_cjs_namespaceObject = require("../../common/interface/store.cjs");
35
34
  const tab_common_cjs_namespaceObject = require("../../common/tabs/tab-common.cjs");
36
35
  const bind_state_cjs_namespaceObject = require("../../../decorators/bind-state.cjs");
@@ -49,6 +48,17 @@ function _ts_metadata(k, v) {
49
48
  if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
50
49
  }
51
50
  class AtomicInsightTab extends external_lit_namespaceObject.LitElement {
51
+ connectedCallback() {
52
+ super.connectedCallback();
53
+ this.addEventListener('click', this.handleClick);
54
+ this.addEventListener('keydown', this.handleKeydown);
55
+ this.updateHostAttributes();
56
+ }
57
+ disconnectedCallback() {
58
+ super.disconnectedCallback();
59
+ this.removeEventListener('click', this.handleClick);
60
+ this.removeEventListener('keydown', this.handleKeydown);
61
+ }
52
62
  initialize() {
53
63
  this.tab = (0, insight_namespaceObject.buildTab)(this.bindings.engine, {
54
64
  options: {
@@ -64,46 +74,80 @@ class AtomicInsightTab extends external_lit_namespaceObject.LitElement {
64
74
  });
65
75
  }
66
76
  select() {
67
- this.tab.select();
77
+ this.tab?.select();
68
78
  }
69
79
  updated() {
70
- if (this.tabState) this.active = this.tabState.isActive;
80
+ if (this.tabState) {
81
+ this.active = this.tabState.isActive;
82
+ this.updateHostAttributes();
83
+ }
71
84
  (0, tab_common_cjs_namespaceObject.dispatchTabLoaded)(this);
72
85
  }
86
+ updateHostAttributes() {
87
+ this.setAttribute('role', 'tab');
88
+ this.setAttribute('aria-selected', this.active ? 'true' : 'false');
89
+ this.tabIndex = this.active ? 0 : -1;
90
+ }
73
91
  render() {
74
- return (0, external_lit_namespaceObject.html)`${(0, when_js_namespaceObject.when)(this.isAppLoaded, ()=>(0, button_cjs_namespaceObject.renderButton)({
75
- props: {
76
- style: 'text-transparent',
77
- part: 'tab',
78
- class: this.tabState.isActive ? 'active' : '',
79
- ariaLabel: this.bindings.i18n.t('tab-search', {
80
- label: this.label
81
- }),
82
- title: this.label,
83
- ariaPressed: this.tabState.isActive ? 'true' : 'false',
84
- onClick: ()=>{
85
- this.tab.select();
86
- }
87
- }
88
- })((0, external_lit_namespaceObject.html)`${this.label}`))}`;
92
+ return (0, external_lit_namespaceObject.html)`<span part="tab" title=${this.label}
93
+ >${(0, when_js_namespaceObject.when)(this.isAppLoaded, ()=>this.label)}</span
94
+ >`;
89
95
  }
90
96
  constructor(...args){
91
- super(...args), this.label = 'no-label', this.active = false, this.isAppLoaded = false, this.tabId = (0, utils_cjs_namespaceObject.randomID)('insight-tab');
97
+ super(...args), this.label = 'no-label', this.active = false, this.isAppLoaded = false, this.tabId = (0, utils_cjs_namespaceObject.randomID)('insight-tab'), this.handleClick = ()=>{
98
+ this.tab?.select();
99
+ }, this.handleKeydown = (event)=>{
100
+ if ('Enter' === event.key || ' ' === event.key) {
101
+ event.preventDefault();
102
+ this.tab?.select();
103
+ return;
104
+ }
105
+ const tablist = this.closest('[role="tablist"]');
106
+ if (!tablist) return;
107
+ const tabs = Array.from(tablist.querySelectorAll('[role="tab"]'));
108
+ const currentIndex = tabs.indexOf(this);
109
+ if (-1 === currentIndex) return;
110
+ let nextIndex = null;
111
+ if ('ArrowRight' === event.key) nextIndex = (currentIndex + 1) % tabs.length;
112
+ else if ('ArrowLeft' === event.key) nextIndex = (currentIndex - 1 + tabs.length) % tabs.length;
113
+ else if ('Home' === event.key) nextIndex = 0;
114
+ else if ('End' === event.key) nextIndex = tabs.length - 1;
115
+ if (null !== nextIndex) {
116
+ event.preventDefault();
117
+ tabs.forEach((tab, index)=>{
118
+ tab.tabIndex = index === nextIndex ? 0 : -1;
119
+ });
120
+ tabs[nextIndex].focus();
121
+ }
122
+ };
92
123
  }
93
124
  }
94
125
  AtomicInsightTab.styles = (0, external_lit_namespaceObject.css)`
95
126
  @reference '../../../utils/tailwind.global.tw.css';
96
- .active::after {
97
- @apply bg-primary absolute bottom-0 block h-1 w-full rounded;
98
- content: '';
127
+
128
+ :host {
129
+ display: flex;
130
+ @apply cursor-pointer;
131
+ @apply focus-visible:outline-none;
99
132
  }
100
133
 
101
134
  [part='tab'] {
102
135
  @apply relative mt-1 mr-6 pb-3 font-semibold;
136
+ @apply text-on-background;
103
137
  max-width: 150px;
104
138
  text-overflow: ellipsis;
105
139
  overflow: hidden;
106
140
  }
141
+
142
+ :host(:hover) [part='tab'],
143
+ :host(:focus-visible) [part='tab'] {
144
+ @apply text-primary;
145
+ }
146
+
147
+ :host([active]) [part='tab']::after {
148
+ @apply bg-primary absolute bottom-0 block h-1 w-full rounded;
149
+ content: '';
150
+ }
107
151
  `;
108
152
  _ts_decorate([
109
153
  (0, decorators_js_namespaceObject.property)({
@@ -46,7 +46,9 @@ class AtomicInsightTabs extends (0, light_dom_cjs_namespaceObject.LightDomMixin)
46
46
  initialize() {}
47
47
  render() {
48
48
  return (0, external_lit_namespaceObject.html)`<atomic-tab-bar
49
- >${this.renderDefaultSlotContent()}</atomic-tab-bar
49
+ ><div role="tablist" style="display:flex;flex-direction:row;width:100%">
50
+ ${this.renderDefaultSlotContent()}
51
+ </div></atomic-tab-bar
50
52
  >`;
51
53
  }
52
54
  }
@@ -30,7 +30,6 @@ const headless_namespaceObject = require("@coveo/headless");
30
30
  const external_lit_namespaceObject = require("lit");
31
31
  const decorators_js_namespaceObject = require("lit/decorators.js");
32
32
  const when_js_namespaceObject = require("lit/directives/when.js");
33
- const button_cjs_namespaceObject = require("../../common/button.cjs");
34
33
  const store_cjs_namespaceObject = require("../../common/interface/store.cjs");
35
34
  const tab_common_cjs_namespaceObject = require("../../common/tabs/tab-common.cjs");
36
35
  const bind_state_cjs_namespaceObject = require("../../../decorators/bind-state.cjs");
@@ -46,6 +45,17 @@ function _ts_metadata(k, v) {
46
45
  if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
47
46
  }
48
47
  class AtomicIpxTab extends external_lit_namespaceObject.LitElement {
48
+ connectedCallback() {
49
+ super.connectedCallback();
50
+ this.addEventListener('click', this.handleClick);
51
+ this.addEventListener('keydown', this.handleKeydown);
52
+ this.updateHostAttributes();
53
+ }
54
+ disconnectedCallback() {
55
+ super.disconnectedCallback();
56
+ this.removeEventListener('click', this.handleClick);
57
+ this.removeEventListener('keydown', this.handleKeydown);
58
+ }
49
59
  initialize() {
50
60
  this.tab = (0, headless_namespaceObject.buildTab)(this.bindings.engine, {
51
61
  options: {
@@ -61,54 +71,80 @@ class AtomicIpxTab extends external_lit_namespaceObject.LitElement {
61
71
  });
62
72
  }
63
73
  select() {
64
- this.tab.select();
74
+ this.tab?.select();
65
75
  }
66
76
  updated() {
67
- if (this.tabState) this.active = this.tabState.isActive;
77
+ if (this.tabState) {
78
+ this.active = this.tabState.isActive;
79
+ this.updateHostAttributes();
80
+ }
68
81
  (0, tab_common_cjs_namespaceObject.dispatchTabLoaded)(this);
69
82
  }
83
+ updateHostAttributes() {
84
+ this.setAttribute('role', 'tab');
85
+ this.setAttribute('aria-selected', this.active ? 'true' : 'false');
86
+ this.tabIndex = this.active ? 0 : -1;
87
+ }
70
88
  render() {
71
- return (0, when_js_namespaceObject.when)(this.isAppLoaded, ()=>{
72
- const buttonClasses = [
73
- 'relative',
74
- 'pb-3',
75
- 'mt-1',
76
- 'mr-6',
77
- 'font-semibold'
78
- ];
79
- if (this.tabState.isActive) buttonClasses.push('active');
80
- return (0, button_cjs_namespaceObject.renderButton)({
81
- props: {
82
- style: 'text-transparent',
83
- part: 'tab',
84
- class: buttonClasses.join(' '),
85
- ariaLabel: this.bindings.i18n.t('tab-search', {
86
- label: this.label
87
- }),
88
- title: this.label,
89
- ariaPressed: this.tabState.isActive ? 'true' : 'false',
90
- onClick: ()=>this.tab.select()
91
- }
92
- })((0, external_lit_namespaceObject.html)`${this.label}`);
93
- }, ()=>external_lit_namespaceObject.nothing);
89
+ return (0, external_lit_namespaceObject.html)`<span part="tab" title=${this.label}
90
+ >${(0, when_js_namespaceObject.when)(this.isAppLoaded, ()=>this.label)}</span
91
+ >`;
94
92
  }
95
93
  constructor(...args){
96
- super(...args), this.label = 'no-label', this.active = false, this.isAppLoaded = false;
94
+ super(...args), this.label = 'no-label', this.active = false, this.isAppLoaded = false, this.handleClick = ()=>{
95
+ this.tab?.select();
96
+ }, this.handleKeydown = (event)=>{
97
+ if ('Enter' === event.key || ' ' === event.key) {
98
+ event.preventDefault();
99
+ this.tab?.select();
100
+ return;
101
+ }
102
+ const tablist = this.closest('[role="tablist"]');
103
+ if (!tablist) return;
104
+ const tabs = Array.from(tablist.querySelectorAll('[role="tab"]'));
105
+ const currentIndex = tabs.indexOf(this);
106
+ if (-1 === currentIndex) return;
107
+ let nextIndex = null;
108
+ if ('ArrowRight' === event.key) nextIndex = (currentIndex + 1) % tabs.length;
109
+ else if ('ArrowLeft' === event.key) nextIndex = (currentIndex - 1 + tabs.length) % tabs.length;
110
+ else if ('Home' === event.key) nextIndex = 0;
111
+ else if ('End' === event.key) nextIndex = tabs.length - 1;
112
+ if (null !== nextIndex) {
113
+ event.preventDefault();
114
+ tabs.forEach((tab, index)=>{
115
+ tab.tabIndex = index === nextIndex ? 0 : -1;
116
+ });
117
+ tabs[nextIndex].focus();
118
+ }
119
+ };
97
120
  }
98
121
  }
99
122
  AtomicIpxTab.styles = (0, external_lit_namespaceObject.css)`
100
123
  @reference '../../../utils/tailwind.global.tw.css';
101
124
 
102
- .active::after {
103
- @apply bg-primary absolute bottom-0 block h-1 w-full rounded;
104
- content: '';
125
+ :host {
126
+ display: flex;
127
+ @apply cursor-pointer;
128
+ @apply focus-visible:outline-none;
105
129
  }
106
130
 
107
131
  [part='tab'] {
132
+ @apply relative mt-1 mr-6 pb-3 font-semibold;
133
+ @apply text-on-background;
108
134
  max-width: 150px;
109
135
  text-overflow: ellipsis;
110
136
  overflow: hidden;
111
137
  }
138
+
139
+ :host(:hover) [part='tab'],
140
+ :host(:focus-visible) [part='tab'] {
141
+ @apply text-primary;
142
+ }
143
+
144
+ :host([active]) [part='tab']::after {
145
+ @apply bg-primary absolute bottom-0 block h-1 w-full rounded;
146
+ content: '';
147
+ }
112
148
  `;
113
149
  _ts_decorate([
114
150
  (0, decorators_js_namespaceObject.property)({
@@ -45,7 +45,9 @@ class AtomicIpxTabs extends (0, light_dom_cjs_namespaceObject.LightDomMixin)((0,
45
45
  initialize() {}
46
46
  render() {
47
47
  return (0, external_lit_namespaceObject.html)`<atomic-tab-bar
48
- >${this.renderDefaultSlotContent()}</atomic-tab-bar
48
+ ><div role="tablist" style="display:flex;flex-direction:row;width:100%">
49
+ ${this.renderDefaultSlotContent()}
50
+ </div></atomic-tab-bar
49
51
  >`;
50
52
  }
51
53
  }
@@ -229,6 +229,7 @@ class AtomicSearchBox extends external_lit_namespaceObject.LitElement {
229
229
  if (!e.shiftKey) this.onSubmit();
230
230
  break;
231
231
  case 'Escape':
232
+ this.isExpanded = false;
232
233
  this.suggestionManager.clearSuggestions();
233
234
  break;
234
235
  case 'ArrowDown':
@@ -53,11 +53,11 @@ const locales = {
53
53
  cy: ()=>import("dayjs/locale/cy"),
54
54
  da: ()=>import("dayjs/locale/da"),
55
55
  'de-AT': ()=>import("dayjs/locale/de-at"),
56
- 'de-CH': ()=>import("dayjs/locale/de-ch"),
57
56
  de: ()=>import("dayjs/locale/de"),
57
+ 'de-CH': ()=>import("dayjs/locale/de-ch"),
58
58
  dv: ()=>import("dayjs/locale/dv"),
59
- el: ()=>import("dayjs/locale/el"),
60
59
  'en-AU': ()=>import("dayjs/locale/en-au"),
60
+ el: ()=>import("dayjs/locale/el"),
61
61
  'en-CA': ()=>import("dayjs/locale/en-ca"),
62
62
  'en-GB': ()=>import("dayjs/locale/en-gb"),
63
63
  'en-IE': ()=>import("dayjs/locale/en-ie"),
@@ -83,9 +83,9 @@ const locales = {
83
83
  fr: ()=>import("dayjs/locale/fr"),
84
84
  fy: ()=>import("dayjs/locale/fy"),
85
85
  ga: ()=>import("dayjs/locale/ga"),
86
- gd: ()=>import("dayjs/locale/gd"),
87
86
  gl: ()=>import("dayjs/locale/gl"),
88
87
  'gom-LATN': ()=>import("dayjs/locale/gom-latn"),
88
+ gd: ()=>import("dayjs/locale/gd"),
89
89
  gu: ()=>import("dayjs/locale/gu"),
90
90
  he: ()=>import("dayjs/locale/he"),
91
91
  hi: ()=>import("dayjs/locale/hi"),
@@ -150,14 +150,14 @@ const locales = {
150
150
  te: ()=>import("dayjs/locale/te"),
151
151
  tet: ()=>import("dayjs/locale/tet"),
152
152
  tg: ()=>import("dayjs/locale/tg"),
153
- th: ()=>import("dayjs/locale/th"),
154
153
  tk: ()=>import("dayjs/locale/tk"),
154
+ th: ()=>import("dayjs/locale/th"),
155
155
  'tl-PH': ()=>import("dayjs/locale/tl-ph"),
156
- tlh: ()=>import("dayjs/locale/tlh"),
157
156
  tr: ()=>import("dayjs/locale/tr"),
158
- tzl: ()=>import("dayjs/locale/tzl"),
157
+ tlh: ()=>import("dayjs/locale/tlh"),
159
158
  'tzm-LATN': ()=>import("dayjs/locale/tzm-latn"),
160
159
  tzm: ()=>import("dayjs/locale/tzm"),
160
+ tzl: ()=>import("dayjs/locale/tzl"),
161
161
  'ug-CN': ()=>import("dayjs/locale/ug-cn"),
162
162
  uk: ()=>import("dayjs/locale/uk"),
163
163
  ur: ()=>import("dayjs/locale/ur"),
@@ -33,7 +33,7 @@ function getWindow() {
33
33
  }
34
34
  function getAtomicEnvironment(headlessVersion) {
35
35
  return {
36
- version: "3.59.2",
36
+ version: "3.59.4",
37
37
  headlessVersion
38
38
  };
39
39
  }
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ HiddenStateController: ()=>HiddenStateController
28
+ });
29
+ const shadowSheet = new CSSStyleSheet();
30
+ shadowSheet.replaceSync(':host(:state(empty)) { display: none }');
31
+ const lightSheet = new CSSStyleSheet();
32
+ lightSheet.replaceSync(':state(empty) { display: none }');
33
+ class HiddenStateController {
34
+ hostConnected() {
35
+ const root = this.host.shadowRoot;
36
+ if (root) {
37
+ if (!root.adoptedStyleSheets.includes(shadowSheet)) root.adoptedStyleSheets.push(shadowSheet);
38
+ } else {
39
+ const parentRoot = this.host.getRootNode();
40
+ if (!parentRoot.adoptedStyleSheets.includes(lightSheet)) parentRoot.adoptedStyleSheets.push(lightSheet);
41
+ }
42
+ }
43
+ set isEmpty(value) {
44
+ if (value) this.internals.states.add('empty');
45
+ else this.internals.states.delete('empty');
46
+ }
47
+ get isEmpty() {
48
+ return this.internals.states.has('empty');
49
+ }
50
+ constructor(host){
51
+ this.host = host;
52
+ this.internals = host.attachInternals();
53
+ this.internals.states.add('empty');
54
+ host.addController(this);
55
+ }
56
+ }
57
+ exports.HiddenStateController = __webpack_exports__.HiddenStateController;
58
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
59
+ "HiddenStateController"
60
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
61
+ Object.defineProperty(exports, '__esModule', {
62
+ value: true
63
+ });
@@ -28,7 +28,7 @@ __webpack_require__.d(__webpack_exports__, {
28
28
  headlessVersion: ()=>package_json_namespaceObject.version
29
29
  });
30
30
  const package_json_namespaceObject = require("@coveo/headless/package.json");
31
- const atomicVersion = "3.59.2";
31
+ const atomicVersion = "3.59.4";
32
32
  exports.atomicVersion = __webpack_exports__.atomicVersion;
33
33
  exports.headlessVersion = __webpack_exports__.headlessVersion;
34
34
  for(var __rspack_i in __webpack_exports__)if (-1 === [
@@ -198,6 +198,7 @@ class AtomicCommerceSearchBox extends LitElement {
198
198
  if (!e.shiftKey) this.onSubmit();
199
199
  break;
200
200
  case 'Escape':
201
+ this.isExpanded = false;
201
202
  this.suggestionManager.clearSuggestions();
202
203
  break;
203
204
  case 'ArrowDown':
@@ -84,6 +84,7 @@ class AtomicInsightSearchBox extends LitElement {
84
84
  if (!e.shiftKey) this.onSubmit();
85
85
  break;
86
86
  case 'Escape':
87
+ this.isExpanded = false;
87
88
  this.suggestionManager.clearSuggestions();
88
89
  break;
89
90
  case 'ArrowDown':
@@ -2,7 +2,6 @@ import { buildTab } from "@coveo/headless/insight";
2
2
  import { LitElement, css, html } from "lit";
3
3
  import { customElement, property, state } from "lit/decorators.js";
4
4
  import { when } from "lit/directives/when.js";
5
- import { renderButton } from "../../common/button.js";
6
5
  import { createAppLoadedListener } from "../../common/interface/store.js";
7
6
  import { dispatchTabLoaded } from "../../common/tabs/tab-common.js";
8
7
  import { bindStateToController } from "../../../decorators/bind-state.js";
@@ -21,6 +20,17 @@ function _ts_metadata(k, v) {
21
20
  if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
22
21
  }
23
22
  class AtomicInsightTab extends LitElement {
23
+ connectedCallback() {
24
+ super.connectedCallback();
25
+ this.addEventListener('click', this.handleClick);
26
+ this.addEventListener('keydown', this.handleKeydown);
27
+ this.updateHostAttributes();
28
+ }
29
+ disconnectedCallback() {
30
+ super.disconnectedCallback();
31
+ this.removeEventListener('click', this.handleClick);
32
+ this.removeEventListener('keydown', this.handleKeydown);
33
+ }
24
34
  initialize() {
25
35
  this.tab = buildTab(this.bindings.engine, {
26
36
  options: {
@@ -36,34 +46,55 @@ class AtomicInsightTab extends LitElement {
36
46
  });
37
47
  }
38
48
  select() {
39
- this.tab.select();
49
+ this.tab?.select();
40
50
  }
41
51
  updated() {
42
- if (this.tabState) this.active = this.tabState.isActive;
52
+ if (this.tabState) {
53
+ this.active = this.tabState.isActive;
54
+ this.updateHostAttributes();
55
+ }
43
56
  dispatchTabLoaded(this);
44
57
  }
58
+ updateHostAttributes() {
59
+ this.setAttribute('role', 'tab');
60
+ this.setAttribute('aria-selected', this.active ? 'true' : 'false');
61
+ this.tabIndex = this.active ? 0 : -1;
62
+ }
45
63
  render() {
46
- return html`${when(this.isAppLoaded, ()=>renderButton({
47
- props: {
48
- style: 'text-transparent',
49
- part: 'tab',
50
- class: this.tabState.isActive ? 'active' : '',
51
- ariaLabel: this.bindings.i18n.t('tab-search', {
52
- label: this.label
53
- }),
54
- title: this.label,
55
- ariaPressed: this.tabState.isActive ? 'true' : 'false',
56
- onClick: ()=>{
57
- this.tab.select();
58
- }
59
- }
60
- })(html`${this.label}`))}`;
64
+ return html`<span part="tab" title=${this.label}
65
+ >${when(this.isAppLoaded, ()=>this.label)}</span
66
+ >`;
61
67
  }
62
68
  constructor(...args){
63
- super(...args), this.label = 'no-label', this.active = false, this.isAppLoaded = false, this.tabId = randomID('insight-tab');
69
+ super(...args), this.label = 'no-label', this.active = false, this.isAppLoaded = false, this.tabId = randomID('insight-tab'), this.handleClick = ()=>{
70
+ this.tab?.select();
71
+ }, this.handleKeydown = (event)=>{
72
+ if ('Enter' === event.key || ' ' === event.key) {
73
+ event.preventDefault();
74
+ this.tab?.select();
75
+ return;
76
+ }
77
+ const tablist = this.closest('[role="tablist"]');
78
+ if (!tablist) return;
79
+ const tabs = Array.from(tablist.querySelectorAll('[role="tab"]'));
80
+ const currentIndex = tabs.indexOf(this);
81
+ if (-1 === currentIndex) return;
82
+ let nextIndex = null;
83
+ if ('ArrowRight' === event.key) nextIndex = (currentIndex + 1) % tabs.length;
84
+ else if ('ArrowLeft' === event.key) nextIndex = (currentIndex - 1 + tabs.length) % tabs.length;
85
+ else if ('Home' === event.key) nextIndex = 0;
86
+ else if ('End' === event.key) nextIndex = tabs.length - 1;
87
+ if (null !== nextIndex) {
88
+ event.preventDefault();
89
+ tabs.forEach((tab, index)=>{
90
+ tab.tabIndex = index === nextIndex ? 0 : -1;
91
+ });
92
+ tabs[nextIndex].focus();
93
+ }
94
+ };
64
95
  }
65
96
  }
66
- AtomicInsightTab.styles = css`/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,::backdrop,:after,:before{--tw-font-weight:initial}}}.active:after{background-color:var(--atomic-primary);border-radius:var(--atomic-border-radius);bottom:calc(var(--spacing,.25rem)*0);content:"";display:block;height:calc(var(--spacing,.25rem)*1);position:absolute;width:100%}[part=tab]{margin-right:calc(var(--spacing,.25rem)*6);margin-top:calc(var(--spacing,.25rem)*1);padding-bottom:calc(var(--spacing,.25rem)*3);--tw-font-weight:var(--font-weight-semibold,600);font-weight:var(--font-weight-semibold,600);max-width:150px;overflow:hidden;position:relative;text-overflow:ellipsis}@property --tw-font-weight{syntax:"*";inherits:false}`;
97
+ AtomicInsightTab.styles = css`/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,::backdrop,:after,:before{--tw-font-weight:initial}}}:host{cursor:pointer;display:flex}:host:focus-visible{--tw-outline-style:none;outline-style:none}[part=tab]{margin-right:calc(var(--spacing,.25rem)*6);margin-top:calc(var(--spacing,.25rem)*1);padding-bottom:calc(var(--spacing,.25rem)*3);--tw-font-weight:var(--font-weight-semibold,600);color:var(--atomic-on-background);font-weight:var(--font-weight-semibold,600);max-width:150px;overflow:hidden;position:relative;text-overflow:ellipsis}:host(:focus-visible) [part=tab],:host(:hover) [part=tab]{color:var(--atomic-primary)}:host([active]) [part=tab]:after{background-color:var(--atomic-primary);border-radius:var(--atomic-border-radius);bottom:calc(var(--spacing,.25rem)*0);content:"";display:block;height:calc(var(--spacing,.25rem)*1);position:absolute;width:100%}@property --tw-font-weight{syntax:"*";inherits:false}`;
67
98
  _ts_decorate([
68
99
  property({
69
100
  type: String,
@@ -18,7 +18,9 @@ class AtomicInsightTabs extends LightDomMixin(SlotsForNoShadowDOMMixin(LitElemen
18
18
  initialize() {}
19
19
  render() {
20
20
  return html`<atomic-tab-bar
21
- >${this.renderDefaultSlotContent()}</atomic-tab-bar
21
+ ><div role="tablist" style="display:flex;flex-direction:row;width:100%">
22
+ ${this.renderDefaultSlotContent()}
23
+ </div></atomic-tab-bar
22
24
  >`;
23
25
  }
24
26
  }