kemet-ui 0.2.0 → 1.0.0

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 (66) hide show
  1. package/custom-elements.json +5546 -855
  2. package/dist/components/kemet-accordion-panel.js +178 -0
  3. package/dist/components/kemet-accordion.js +105 -72
  4. package/dist/components/kemet-badge.js +102 -0
  5. package/dist/components/kemet-button.js +230 -0
  6. package/dist/components/kemet-checkbox.js +298 -0
  7. package/dist/components/kemet-combo.js +207 -0
  8. package/dist/components/kemet-count.js +112 -0
  9. package/dist/components/kemet-draggable.js +19 -6
  10. package/dist/components/kemet-drawer.js +38 -15
  11. package/dist/components/kemet-drawer.styles.js +6 -0
  12. package/dist/components/kemet-field.js +233 -0
  13. package/dist/components/kemet-flipcard-trigger.js +4 -5
  14. package/dist/components/kemet-flipcard.js +26 -3
  15. package/dist/components/kemet-icon.js +19 -3
  16. package/dist/components/kemet-input.js +650 -0
  17. package/dist/components/kemet-modal-close.js +23 -4
  18. package/dist/components/kemet-modal.js +78 -13
  19. package/dist/components/kemet-modal.styles.js +14 -2
  20. package/dist/components/kemet-option.js +45 -0
  21. package/dist/components/kemet-popover-close.js +1 -1
  22. package/dist/components/kemet-popover.js +75 -12
  23. package/dist/components/kemet-radio.js +214 -0
  24. package/dist/components/kemet-radios.js +218 -0
  25. package/dist/components/kemet-rotator.js +23 -4
  26. package/dist/components/kemet-scroll-link.js +21 -2
  27. package/dist/components/kemet-scroll-nav.js +25 -2
  28. package/dist/components/kemet-scroll-snap-paginator.js +68 -26
  29. package/dist/components/kemet-scroll-snap-slide.js +23 -13
  30. package/dist/components/kemet-scroll-snap.js +31 -16
  31. package/dist/components/kemet-select.js +365 -0
  32. package/dist/components/kemet-svg.js +18 -2
  33. package/dist/components/kemet-svgs.js +7 -3
  34. package/dist/components/kemet-tab-panel.js +15 -1
  35. package/dist/components/kemet-tab.js +48 -1
  36. package/dist/components/kemet-tabs.js +289 -83
  37. package/dist/components/kemet-tabs.styles.js +200 -0
  38. package/dist/components/kemet-textarea.js +395 -0
  39. package/dist/components/kemet-toggle.js +225 -0
  40. package/dist/kemet-components.cjs +5128 -1200
  41. package/dist/kemet-components.js +5117 -1173
  42. package/dist/kemet-components.min.js +1536 -421
  43. package/dist/styles/kemet.components.css +12 -260
  44. package/dist/styles/kemet.components.css.map +1 -1
  45. package/dist/styles/kemet.core.css +2371 -503
  46. package/dist/styles/kemet.core.css.map +1 -1
  47. package/dist/styles/scss/components/_config.scss +0 -25
  48. package/dist/styles/scss/components/accordion.scss +4 -53
  49. package/dist/styles/scss/components/modal.scss +5 -9
  50. package/dist/styles/scss/components/scrollsnap.scss +0 -57
  51. package/dist/styles/scss/core/_config.scss +160 -3
  52. package/dist/styles/scss/core/_helpers.scss +109 -2
  53. package/dist/styles/scss/core/attributes.scss +16 -0
  54. package/dist/styles/scss/core/base.scss +38 -0
  55. package/dist/styles/scss/core/layout.scss +6 -5
  56. package/dist/styles/scss/kemet.components.scss +0 -2
  57. package/dist/styles/scss/kemet.core.scss +1 -2
  58. package/package.json +34 -56
  59. package/dist/components/kemet-carousel-link.js +0 -54
  60. package/dist/components/kemet-carousel-next.js +0 -46
  61. package/dist/components/kemet-carousel-prev.js +0 -46
  62. package/dist/components/kemet-carousel-slide.js +0 -83
  63. package/dist/components/kemet-carousel.js +0 -236
  64. package/dist/components/kemet-ratio.js +0 -61
  65. package/dist/styles/scss/components/flipcard.scss +0 -14
  66. package/dist/styles/scss/components/tabs.scss +0 -73
@@ -1,55 +1,89 @@
1
1
  /* eslint-disable no-lonely-if */
2
2
  /* eslint-disable no-case-declarations */
3
- import { LitElement, html, css } from 'lit';
3
+ import { LitElement, html } from 'lit';
4
+ import { stylesKemetTabs } from './kemet-tabs.styles.js';
4
5
 
5
- export class KemetTabs extends LitElement {
6
+ export default class KemetTabs extends LitElement {
6
7
  static get styles() {
7
- return [
8
- css`
9
- :host {
10
- display: block;
11
- overflow: hidden;
12
- }
13
-
14
- ::slotted([slot='links']) {
15
- overflow: auto;
16
- }
17
-
18
- ::slotted([slot='panels']) {
19
- display: flex;
20
- }
21
-
22
- :host([panel-effect='slide']) #panels {
23
- transition: transform var(--kemet-tabs-transition-speed, 0.5s) linear;
24
- }
25
-
26
- :host([panel-effect='fade']) ::slotted([slot='panels']) {
27
- flex-flow: row nowrap;
28
- }
29
- `,
30
- ];
8
+ return [stylesKemetTabs];
31
9
  }
32
10
 
33
11
  static get properties() {
34
12
  return {
13
+ /**
14
+ * The selected tab by name
15
+ */
35
16
  selected: {
36
17
  type: String,
37
18
  reflect: true,
38
19
  },
20
+ /**
21
+ * The selected tab by index
22
+ */
39
23
  selectedIndex: {
40
24
  type: Number,
41
25
  },
26
+ /**
27
+ * Positions the current panel
28
+ */
42
29
  panelPosition: {
43
30
  type: Number,
44
31
  },
32
+ /**
33
+ * The transition effect for panels
34
+ */
45
35
  panelEffect: {
46
36
  type: String,
47
37
  reflect: true,
48
38
  attribute: 'panel-effect',
49
39
  },
40
+ /**
41
+ * Determines whether or not to enable swipe behavior
42
+ */
50
43
  swipe: {
51
44
  type: Boolean,
52
45
  },
46
+ /**
47
+ * Places the tabs to the top, right, bottom, or left
48
+ */
49
+ placement: {
50
+ type: String,
51
+ reflect: true,
52
+ },
53
+ /**
54
+ * Determines whether or not to show a divider line
55
+ */
56
+ divider: {
57
+ type: Boolean,
58
+ },
59
+ /**
60
+ * Spacing alignment of the tabs
61
+ */
62
+ tabsAlign: {
63
+ type: String,
64
+ reflect: true,
65
+ attribute: 'tabs-align',
66
+ },
67
+ /**
68
+ * An object that contains information about the ink
69
+ */
70
+ ink: {
71
+ type: Object,
72
+ },
73
+ /**
74
+ * Determines whether or not to hide the ink
75
+ */
76
+ hideInk: {
77
+ type: Boolean,
78
+ attribute: 'hide-ink',
79
+ },
80
+ /**
81
+ * Is true when the space of the tabs is larger than it's container
82
+ */
83
+ overflow: {
84
+ type: Boolean,
85
+ reflect: true,
86
+ },
53
87
  };
54
88
  }
55
89
 
@@ -60,58 +94,57 @@ export class KemetTabs extends LitElement {
60
94
  this.selectedIndex = 0;
61
95
  this.panelPosition = 0;
62
96
  this.panelEffect = 'none';
97
+ this.placement = 'top';
98
+ this.tabsAlign = 'center';
99
+ this.hideInk = false;
100
+
101
+ this.addEventListener('kemet-tab-selected', this.tabSelectedChange.bind(this));
102
+ this.addEventListener('kemet-tab-close', this.handleTabClose.bind(this));
103
+ window.addEventListener('resize', this.handleResize.bind(this));
104
+ }
63
105
 
106
+ firstUpdated() {
64
107
  // standard properties
65
108
  this.tabs = [];
66
109
  this.panels = [];
67
110
  this.xDown = null;
68
111
  this.yDown = null;
69
112
 
70
- this.keyCodes = {
71
- ENTER: 13,
72
- SPACE: 32,
73
- HOME: 36,
74
- END: 35,
75
- RIGHT: 39,
76
- LEFT: 37,
77
- };
78
-
79
- this.addEventListener('kemet-tab-selected', this.tabSelectedChange.bind(this));
80
- window.addEventListener('resize', this.handleResize.bind(this));
113
+ this.links = this.shadowRoot.getElementById('links');
81
114
  }
82
115
 
83
116
  render() {
84
117
  return html`
85
- <slot name="links"></slot>
86
- <section id="panels" part="panels" style="transform: translateX(${this.panelPosition}px)">
87
- <slot name="panels"></slot>
118
+ ${this.makeLeftArrow()}
119
+ ${this.makeRightArrow()}
120
+ <div id="links" part="links">
121
+ <div part='tablist' role="tablist">
122
+ <slot name="tab" @slotchange=${() => this.handleLinksSlotChange()}></slot>
123
+ </div>
124
+ ${this.makeInk('links')}
125
+ </div>
126
+ ${this.makeInk('host')}
127
+ ${this.makeDivider()}
128
+ <section id="panels" part="panels" style="transform:translateX(${this.panelPosition}px);">
129
+ <div>
130
+ <slot name="panel" @slotchange=${() => this.handlePanelsSlotChange()}></slot>
131
+ </div>
88
132
  </section>
89
133
  `;
90
134
  }
91
135
 
92
- firstUpdated() {
93
- this.init();
94
- }
95
-
96
136
  updated() {
97
- this.selectTab();
98
- this.selectPanel();
99
137
  this.determineFade();
100
138
  }
101
139
 
102
- init() {
140
+ handleLinksSlotChange() {
103
141
  const tabs = this.querySelectorAll('kemet-tab');
104
- const panels = this.querySelectorAll('kemet-tab-panel');
105
- const panelElement = this.shadowRoot.getElementById('panels');
106
- const index = {
107
- tabs: 0,
108
- panels: 0,
109
- };
142
+ let index = 0;
110
143
 
111
144
  tabs.forEach((tab) => {
112
145
  // give each tab an index to select by if link/panel is not used
113
- tab.index = index.tabs;
114
- index.tabs += 1;
146
+ tab.index = index;
147
+ index += 1;
115
148
 
116
149
  // store the list of tabs
117
150
  this.tabs = this.tabs.concat(tab);
@@ -120,17 +153,30 @@ export class KemetTabs extends LitElement {
120
153
  tab.addEventListener('keydown', event => this.handleTabKeydown(event));
121
154
  });
122
155
 
156
+ // default to the first tab/panel selected
157
+ if (this.tabs.length > 0) this.tabs[0].selected = true;
158
+
159
+ setTimeout(() => {
160
+ this.selectTab();
161
+ }, 1);
162
+ this.determineOverflow();
163
+ }
164
+
165
+ handlePanelsSlotChange() {
166
+ const panels = this.querySelectorAll('kemet-tab-panel');
167
+ const panelElement = this.shadowRoot.getElementById('panels');
168
+ let index = 0;
169
+
123
170
  panels.forEach((panel) => {
124
171
  // give each panel an index to select by if link/panel is not used
125
- panel.index = index.panels;
126
- index.panels += 1;
172
+ panel.index = index;
173
+ index += 1;
127
174
 
128
175
  // store the list of panels
129
176
  this.panels = this.panels.concat(panel);
130
177
  });
131
178
 
132
179
  // default to the first tab/panel selected
133
- if (this.tabs.length > 0) this.tabs[0].selected = true;
134
180
  if (this.panels.length > 0) this.panels[0].selected = true;
135
181
 
136
182
  // add swipe support
@@ -138,9 +184,105 @@ export class KemetTabs extends LitElement {
138
184
  panelElement.addEventListener('touchstart', event => this.handleTouchStart(event), false);
139
185
  panelElement.addEventListener('touchmove', event => this.handleTouchMove(event), false);
140
186
  }
187
+
188
+ this.selectPanel();
189
+ }
190
+
191
+ handleLeftArrow() {
192
+ const selectedElement = this.tabs.find(tab => tab.selected) || this.tabs[0];
193
+ const previousElement = selectedElement.previousElementSibling;
194
+ const selectedIndex = this.tabs.findIndex(tab => tab.selected);
195
+
196
+ if (this.selected) {
197
+ this.selected = previousElement ? previousElement.link : selectedElement.link;
198
+ } else {
199
+ this.selectedIndex = selectedIndex > 0 ? selectedIndex - 1 : 0;
200
+ }
201
+
202
+ if (previousElement) {
203
+ this.links.scrollLeft = previousElement.offsetLeft - 20;
204
+ }
205
+
206
+ this.selectTab();
207
+ this.selectPanel();
208
+ }
209
+
210
+ handleRightArrow() {
211
+ const selectedElement = this.tabs.find(tab => tab.selected) || this.tabs[this.tabs.length - 1];
212
+ const nextElement = selectedElement.nextElementSibling;
213
+ const selectedIndex = this.tabs.findIndex(tab => tab.selected);
214
+
215
+ if (this.selected) {
216
+ this.selected = nextElement ? nextElement.link : selectedElement.link;
217
+ } else {
218
+ this.selectedIndex = selectedIndex < this.tabs.length - 1
219
+ ? selectedIndex + 1
220
+ : this.tabs.length - 1;
221
+ }
222
+
223
+ if (nextElement) {
224
+ this.links.scrollLeft = nextElement.offsetLeft - 20;
225
+ }
226
+
227
+ this.selectTab();
228
+ this.selectPanel();
229
+ }
230
+
231
+ handleTabClose(event) {
232
+ const tab = event.detail;
233
+ const panel = this.panels[tab.index];
234
+
235
+ this.selected = this.tabs[0].link;
236
+ this.selectedIndex = 0;
237
+
238
+ panel.remove();
239
+ tab.remove();
240
+ }
241
+
242
+ makeInk(location) {
243
+ if (this.hideInk) {
244
+ return null;
245
+ }
246
+
247
+ if ((this.placement === 'top' || this.placement === 'bottom') && this.ink && location === 'links') {
248
+ return html`<div part="ink" style="width:${this.ink.width}; transform:translateX(${this.ink.positionX})"></div>`;
249
+ }
250
+
251
+ if ((this.placement === 'left' || this.placement === 'right') && this.ink && location === 'host') {
252
+ return html`<div part="ink" style="height:${this.ink.height}; transform:translateY(${this.ink.positionY})"></div>`;
253
+ }
254
+
255
+ return null;
256
+ }
257
+
258
+ makeDivider() {
259
+ if (this.divider) {
260
+ return html`<div part="divider"></div>`;
261
+ }
262
+
263
+ return null;
264
+ }
265
+
266
+ makeLeftArrow() {
267
+ if (this.overflow) {
268
+ return html`<kemet-icon icon='chevron-left' size="20" @click=${() => this.handleLeftArrow()}></kemet-icon>`;
269
+ }
270
+
271
+ return null;
272
+ }
273
+
274
+ makeRightArrow() {
275
+ if (this.overflow) {
276
+ return html`<kemet-icon icon='chevron-right' size="20" @click=${() => this.handleRightArrow()}></kemet-icon>`;
277
+ }
278
+
279
+ return null;
141
280
  }
142
281
 
143
282
  selectTab() {
283
+ const marginLeft = this.links ? parseInt(window.getComputedStyle(this.links).marginLeft.replace('px', ''), 10) : 0;
284
+ const overflowOffset = this.overflow ? marginLeft : 0;
285
+
144
286
  // if the user uses the selected attribute select by it
145
287
  if (this.selected) {
146
288
  this.tabs.forEach((tab) => {
@@ -149,6 +291,15 @@ export class KemetTabs extends LitElement {
149
291
  if (tabName === this.selected) {
150
292
  tab.selected = true;
151
293
  this.selected = tabName;
294
+
295
+ this.ink = {
296
+ width: `${tab.offsetWidth}px`,
297
+ height: `${tab.offsetHeight}px`,
298
+ positionX: `${tab.offsetLeft - overflowOffset}px`,
299
+ positionY: `${tab.offsetTop}px`,
300
+ };
301
+
302
+ this.links.scrollLeft = tab.offsetLeft - overflowOffset;
152
303
  } else {
153
304
  tab.selected = false;
154
305
  }
@@ -159,6 +310,15 @@ export class KemetTabs extends LitElement {
159
310
  this.tabs.forEach((tab) => {
160
311
  if (this.selectedIndex === tab.index) {
161
312
  tab.selected = true;
313
+
314
+ this.ink = {
315
+ width: `${tab.offsetWidth}px`,
316
+ height: `${tab.offsetHeight}px`,
317
+ positionX: `${tab.offsetLeft - overflowOffset}px`,
318
+ positionY: `${tab.offsetTop}px`,
319
+ };
320
+
321
+ this.links.scrollLeft = tab.offsetLeft - overflowOffset;
162
322
  } else {
163
323
  tab.selected = false;
164
324
  }
@@ -176,6 +336,10 @@ export class KemetTabs extends LitElement {
176
336
  panel.classList.add('push');
177
337
  }
178
338
 
339
+ if (this.placement === 'left' || this.placement === 'right') {
340
+ panel.classList.add('vertical');
341
+ }
342
+
179
343
  if (panelName === this.selected) {
180
344
  panel.selected = true;
181
345
  this.animatePanel(panelName, null);
@@ -191,6 +355,10 @@ export class KemetTabs extends LitElement {
191
355
  panel.classList.add('push');
192
356
  }
193
357
 
358
+ if (this.placement === 'left' || this.placement === 'right') {
359
+ panel.classList.add('vertical');
360
+ }
361
+
194
362
  if (this.selectedIndex === panel.index) {
195
363
  panel.selected = true;
196
364
  this.animatePanel(null, panel.index);
@@ -220,6 +388,8 @@ export class KemetTabs extends LitElement {
220
388
  this.selectedIndex = event.detail.index;
221
389
  }
222
390
 
391
+ this.selectTab();
392
+ this.selectPanel();
223
393
  this.dispatchTabChange();
224
394
  }
225
395
 
@@ -230,11 +400,45 @@ export class KemetTabs extends LitElement {
230
400
  });
231
401
  }
232
402
 
233
- handleResize() {
234
- if (this.selected) {
235
- this.animatePanel(this.selected, null);
403
+ determineOverflow() {
404
+ const tabsContainerWidth = this.offsetWidth;
405
+ const tabElements = this.querySelectorAll('kemet-tab');
406
+
407
+ let totalTabsWidth = 0;
408
+
409
+ tabElements.forEach((tab) => {
410
+ totalTabsWidth += tab.offsetWidth;
411
+ });
412
+
413
+ if (totalTabsWidth > tabsContainerWidth && (this.placement === 'top' || this.placement === 'bottom')) {
414
+ this.overflow = true;
236
415
  } else {
237
- this.animatePanel(null, this.selectedIndex);
416
+ this.overflow = false;
417
+ }
418
+ }
419
+
420
+ handleResize() {
421
+ if (this.tabs && this.panels) {
422
+ const marginLeft = this.links ? parseInt(window.getComputedStyle(this.links).marginLeft.replace('px', ''), 10) : 0;
423
+ const overflowOffset = this.overflow ? marginLeft : 0;
424
+ const selectedElement = this.tabs.find(tab => tab.selected);
425
+
426
+ if (selectedElement) {
427
+ this.ink = {
428
+ width: `${selectedElement.offsetWidth}px`,
429
+ height: `${selectedElement.offsetHeight}px`,
430
+ positionX: `${selectedElement.offsetLeft - overflowOffset}px`,
431
+ positionY: `${selectedElement.offsetTop}px`,
432
+ };
433
+ }
434
+
435
+ this.determineOverflow();
436
+
437
+ if (this.selected) {
438
+ this.animatePanel(this.selected, null);
439
+ } else {
440
+ this.animatePanel(null, this.selectedIndex);
441
+ }
238
442
  }
239
443
  }
240
444
 
@@ -243,20 +447,20 @@ export class KemetTabs extends LitElement {
243
447
  const selectedPanel = this.querySelector(`[panel="${panelName}"]`);
244
448
  if (selectedPanel) this.panelPosition = selectedPanel.offsetLeft * -1;
245
449
  } else {
246
- this.panelPosition = this.panels[panelIndex].offsetLeft * -1;
450
+ if (this.panels[panelIndex]) this.panelPosition = this.panels[panelIndex].offsetLeft * -1;
247
451
  }
248
452
  }
249
453
 
250
454
  handleTabKeydown(event) {
251
455
  if (this.selected) {
252
- switch (event.keyCode) {
253
- case this.keyCodes.HOME:
456
+ switch (event.key) {
457
+ case 'Home':
254
458
  this.selected = this.tabs[0].getAttribute('link');
255
459
  break;
256
- case this.keyCodes.END:
460
+ case 'End':
257
461
  this.selected = this.tabs[this.tabs.length - 1].getAttribute('link');
258
462
  break;
259
- case this.keyCodes.RIGHT:
463
+ case 'ArrowRight':
260
464
  const nextLinkElement = this.querySelector('kemet-tab[selected]').nextElementSibling;
261
465
  const nextLink = nextLinkElement ? nextLinkElement.getAttribute('link') : false;
262
466
 
@@ -264,7 +468,7 @@ export class KemetTabs extends LitElement {
264
468
  this.selected = nextLink;
265
469
  }
266
470
  break;
267
- case this.keyCodes.LEFT:
471
+ case 'ArrowLeft':
268
472
  const previousLinkElement = this.querySelector('kemet-tab[selected]').previousElementSibling;
269
473
  const previousLink = previousLinkElement ? previousLinkElement.getAttribute('link') : false;
270
474
 
@@ -275,23 +479,23 @@ export class KemetTabs extends LitElement {
275
479
  default: break;
276
480
  }
277
481
 
278
- this.querySelector(`[link=${this.selected}]`).focus();
482
+ this.tabs.find(tab => tab.link === this.selected).focus();
279
483
  } else {
280
- switch (event.keyCode) {
281
- case this.keyCodes.HOME:
484
+ switch (event.key) {
485
+ case 'Home':
282
486
  this.selectedIndex = 0;
283
487
  break;
284
- case this.keyCodes.END:
488
+ case 'End':
285
489
  this.selectedIndex = this.tabs.length - 1;
286
490
  break;
287
- case this.keyCodes.RIGHT:
491
+ case 'ArrowRight':
288
492
  if (this.selectedIndex < this.tabs.length - 1) {
289
493
  this.selectedIndex += 1;
290
494
  } else {
291
495
  this.selectedIndex = this.tabs.length - 1;
292
496
  }
293
497
  break;
294
- case this.keyCodes.LEFT:
498
+ case 'ArrowLeft':
295
499
  if (this.selectedIndex < 1) {
296
500
  this.selectedIndex = 0;
297
501
  } else {
@@ -319,27 +523,28 @@ export class KemetTabs extends LitElement {
319
523
  const yUp = event.touches[0].clientY;
320
524
  const xDiff = this.xDown - xUp;
321
525
  const yDiff = this.yDown - yUp;
526
+ const nextElement = this.querySelector('kemet-tab-panel[selected]').nextElementSibling;
527
+ const next = nextElement ? nextElement.getAttribute('panel') : false;
528
+ const previousElement = this.querySelector('kemet-tab-panel[selected]').previousElementSibling;
529
+ const previous = previousElement ? previousElement.getAttribute('panel') : false;
322
530
 
323
531
  if (Math.abs(xDiff) > Math.abs(yDiff)) {
324
532
  if (xDiff > 0) {
325
533
  if (this.selected) {
326
- const nextElement = this.querySelector('kemet-tab-panel[selected]').nextElementSibling;
327
- const next = nextElement ? nextElement.getAttribute('panel') : false;
328
-
329
534
  if (next) this.selected = next;
330
535
  } else {
331
- this.selectedIndex += 1;
536
+ if (this.selectedIndex < this.tabs.length) this.selectedIndex += 1;
332
537
  }
333
538
  } else {
334
539
  if (this.selected) {
335
- const previousElement = this.querySelector('kemet-tab-panel[selected]').previousElementSibling;
336
- const previous = previousElement ? previousElement.getAttribute('panel') : false;
337
-
338
540
  if (previous) this.selected = previous;
339
541
  } else {
340
- this.selectedIndex -= 1;
542
+ if (this.selectedIndex > 0) this.selectedIndex -= 1;
341
543
  }
342
544
  }
545
+
546
+ this.selectTab();
547
+ this.selectPanel();
343
548
  }
344
549
 
345
550
  this.xDown = null;
@@ -347,4 +552,5 @@ export class KemetTabs extends LitElement {
347
552
  }
348
553
  }
349
554
 
350
- window.customElements.define('kemet-tabs', KemetTabs);
555
+ // eslint-disable-next-line no-unused-expressions
556
+ customElements.get('kemet-tabs') || customElements.define('kemet-tabs', KemetTabs);