kemet-ui 0.2.0 → 1.1.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 (87) hide show
  1. package/custom-elements.json +6323 -831
  2. package/dist/components/kemet-accordion/kemet-accordion-panel.js +178 -0
  3. package/dist/components/kemet-accordion/kemet-accordion.js +139 -0
  4. package/dist/components/kemet-badge/kemet-badge.js +102 -0
  5. package/dist/components/kemet-button/kemet-button.js +230 -0
  6. package/dist/components/kemet-carousel/kemet-carousel-current.js +36 -0
  7. package/dist/components/kemet-carousel/kemet-carousel-first.js +47 -0
  8. package/dist/components/kemet-carousel/kemet-carousel-last.js +47 -0
  9. package/dist/components/{kemet-carousel-link.js → kemet-carousel/kemet-carousel-link.js} +7 -2
  10. package/dist/components/{kemet-carousel-next.js → kemet-carousel/kemet-carousel-next.js} +3 -2
  11. package/dist/components/{kemet-carousel-prev.js → kemet-carousel/kemet-carousel-prev.js} +2 -1
  12. package/dist/components/kemet-carousel/kemet-carousel-slide.js +51 -0
  13. package/dist/components/kemet-carousel/kemet-carousel-total.js +36 -0
  14. package/dist/components/kemet-carousel/kemet-carousel.js +492 -0
  15. package/dist/components/kemet-checkbox/kemet-checkbox.js +298 -0
  16. package/dist/components/kemet-combo/kemet-combo.js +207 -0
  17. package/dist/components/kemet-count/kemet-count.js +112 -0
  18. package/dist/components/{kemet-draggable.js → kemet-draggable/kemet-draggable.js} +19 -6
  19. package/dist/components/{kemet-drawer.js → kemet-drawer/kemet-drawer.js} +38 -15
  20. package/dist/components/{kemet-drawer.styles.js → kemet-drawer/kemet-drawer.styles.js} +6 -0
  21. package/dist/components/kemet-field/kemet-field.js +233 -0
  22. package/dist/components/{kemet-flipcard-trigger.js → kemet-flipcard/kemet-flipcard-trigger.js} +4 -5
  23. package/dist/components/{kemet-flipcard.js → kemet-flipcard/kemet-flipcard.js} +26 -3
  24. package/dist/components/{kemet-icon.js → kemet-icon/kemet-icon.js} +19 -3
  25. package/dist/components/kemet-input/kemet-input.js +650 -0
  26. package/dist/components/kemet-modal/kemet-modal-close.js +38 -0
  27. package/dist/components/kemet-modal/kemet-modal.js +140 -0
  28. package/dist/components/{kemet-modal.styles.js → kemet-modal/kemet-modal.styles.js} +14 -2
  29. package/dist/components/{kemet-popover-close.js → kemet-popover/kemet-popover-close.js} +1 -1
  30. package/dist/components/{kemet-popover.effects.styles.js → kemet-popover/kemet-popover.effects.styles.js} +0 -0
  31. package/dist/components/{kemet-popover.js → kemet-popover/kemet-popover.js} +75 -12
  32. package/dist/components/{kemet-popover.tooltip.styles.js → kemet-popover/kemet-popover.tooltip.styles.js} +0 -0
  33. package/dist/components/kemet-radio/kemet-radio.js +214 -0
  34. package/dist/components/kemet-radio/kemet-radios.js +218 -0
  35. package/dist/components/{kemet-rotator.js → kemet-rotator/kemet-rotator.js} +23 -4
  36. package/dist/components/{kemet-scroll-link.js → kemet-scroll-link/kemet-scroll-link.js} +21 -2
  37. package/dist/components/{kemet-scroll-nav.js → kemet-scroll-nav/kemet-scroll-nav.js} +25 -2
  38. package/dist/components/{kemet-scroll-snap-paginator.js → kemet-scroll-snap/kemet-scroll-snap-paginator.js} +68 -26
  39. package/dist/components/{kemet-scroll-snap-slide.js → kemet-scroll-snap/kemet-scroll-snap-slide.js} +23 -13
  40. package/dist/components/{kemet-scroll-snap.js → kemet-scroll-snap/kemet-scroll-snap.js} +31 -16
  41. package/dist/components/kemet-select/kemet-option.js +45 -0
  42. package/dist/components/kemet-select/kemet-select.js +365 -0
  43. package/dist/components/{kemet-svg.js → kemet-svgs/kemet-svg.js} +18 -2
  44. package/dist/components/{kemet-svgs.js → kemet-svgs/kemet-svgs.js} +7 -3
  45. package/dist/components/{kemet-tab-panel.js → kemet-tabs/kemet-tab-panel.js} +15 -1
  46. package/dist/components/{kemet-tab.js → kemet-tabs/kemet-tab.js} +48 -1
  47. package/dist/components/kemet-tabs/kemet-tabs.js +556 -0
  48. package/dist/components/kemet-tabs/kemet-tabs.styles.js +200 -0
  49. package/dist/components/kemet-textarea/kemet-textarea.js +395 -0
  50. package/dist/components/kemet-toggle/kemet-toggle.js +225 -0
  51. package/dist/kemet-components.cjs +7251 -2465
  52. package/dist/kemet-components.js +7237 -2440
  53. package/dist/kemet-components.min.js +1641 -355
  54. package/dist/styles/components/_config.scss +4 -0
  55. package/dist/styles/components/accordion.scss +9 -0
  56. package/dist/styles/{scss/components → components}/drawer.scss +2 -2
  57. package/dist/styles/components/modal.scss +8 -0
  58. package/dist/styles/components/scrollsnap.scss +11 -0
  59. package/dist/styles/core/_config.scss +354 -0
  60. package/dist/styles/{scss/core → core}/_helpers.scss +113 -2
  61. package/dist/styles/{scss/core → core}/attributes.scss +16 -0
  62. package/dist/styles/core/base.scss +38 -0
  63. package/dist/styles/{scss/core → core}/layout.scss +6 -5
  64. package/dist/styles/kemet.components.css +12 -339
  65. package/dist/styles/kemet.components.css.map +1 -1
  66. package/dist/styles/{scss/kemet.components.scss → kemet.components.scss} +0 -3
  67. package/dist/styles/kemet.core.css +2371 -503
  68. package/dist/styles/kemet.core.css.map +1 -1
  69. package/dist/styles/kemet.core.scss +3 -0
  70. package/dist/utilities/controllers/forms.js +121 -0
  71. package/package.json +37 -57
  72. package/dist/components/kemet-accordion.js +0 -106
  73. package/dist/components/kemet-carousel-slide.js +0 -83
  74. package/dist/components/kemet-carousel.js +0 -236
  75. package/dist/components/kemet-modal-close.js +0 -19
  76. package/dist/components/kemet-modal.js +0 -75
  77. package/dist/components/kemet-ratio.js +0 -61
  78. package/dist/components/kemet-tabs.js +0 -350
  79. package/dist/styles/scss/components/_config.scss +0 -29
  80. package/dist/styles/scss/components/accordion.scss +0 -58
  81. package/dist/styles/scss/components/carousel.scss +0 -64
  82. package/dist/styles/scss/components/flipcard.scss +0 -14
  83. package/dist/styles/scss/components/modal.scss +0 -12
  84. package/dist/styles/scss/components/scrollsnap.scss +0 -68
  85. package/dist/styles/scss/components/tabs.scss +0 -73
  86. package/dist/styles/scss/core/_config.scss +0 -197
  87. package/dist/styles/scss/kemet.core.scss +0 -4
@@ -0,0 +1,492 @@
1
+ import { html, css, LitElement } from 'lit';
2
+
3
+ export default class KemetCarousel extends LitElement {
4
+ static get styles() {
5
+ return css`
6
+ :host,
7
+ *,
8
+ *::before,
9
+ *::after {
10
+ box-sizing: border-box;
11
+ }
12
+
13
+ :host {
14
+ position: relative;
15
+ display: grid;
16
+ grid-template-columns: minmax(0, 1fr);
17
+ align-items: center;
18
+ width: var(--kemet-carousel-width, 100%);
19
+ height: var(--kemet-carousel-height, auto);
20
+ overflow: visible;
21
+ }
22
+
23
+ :host([arrows]) {
24
+ grid-template-columns: auto minmax(0, 1fr) auto;
25
+ }
26
+
27
+ .toolbar {
28
+ display: flex;
29
+ gap: var(--kemet-carousel-toolbar-gap, 1rem);
30
+ align-items: center;
31
+ justify-content: var(--kemet-carousel-toolbar-justify-content, center);
32
+ line-height: 1;
33
+ padding: var(--kemet-carousel-toolbar-padding, 1rem);
34
+ }
35
+
36
+ :host([inner]) .toolbar {
37
+ width: var(--kemet-carousel-toolbar-inner-width, 100%);
38
+ position: absolute;
39
+ bottom: var(--kemet-carousel-toolbar-inner-bottom, 0);
40
+ top: var(--kemet-carousel-toolbar-inner-top, auto);
41
+ color: var(--kemet-carousel-toolbar-inner-color, var(--kemet-color-white));
42
+ background-color: var(--kemet-carousel-toolbar-inner-background-color, rgba(0, 0, 0, 0.4));
43
+ }
44
+
45
+ .slides {
46
+ overflow: hidden;
47
+ position: relative;
48
+ padding: 1rem 0;
49
+ border: var(--kemet-carousel-slides-border, 1px solid var(--kemet-color-gray1));
50
+ }
51
+
52
+ .slider {
53
+ display: flex;
54
+ flex-wrap: nowrap;
55
+ transition: transform var(--kemet-carousel-transition-speed, 300ms) ease;
56
+ }
57
+
58
+ ::slotted([slot='next']),
59
+ ::slotted([slot='prev']) {
60
+ opacity: var(--kemet-carousel-arrows-opacity, 0.25);
61
+ transition: opacity var(--kemet-carousel-arrows-transition-speed, 300ms) ease-in-out;
62
+ }
63
+
64
+ :host(:hover) ::slotted([slot='next']),
65
+ :host(:hover) ::slotted([slot='prev']) {
66
+ opacity: var(--kemet-carousel-arrows-opacity-hover, 1);
67
+ }
68
+ `;
69
+ }
70
+
71
+ static get properties() {
72
+ return {
73
+ /**
74
+ * The current slide index.
75
+ */
76
+ index: {
77
+ type: Number,
78
+ reflect: true,
79
+ },
80
+ /**
81
+ * The total amount of slides
82
+ */
83
+ total: {
84
+ type: Number,
85
+ },
86
+ /**
87
+ * The width of the slider
88
+ */
89
+ sliderWidth: {
90
+ type: String,
91
+ },
92
+ /**
93
+ * The X position of the slider
94
+ */
95
+ sliderTranslateX: {
96
+ type: String,
97
+ },
98
+ /**
99
+ * Displays the toolbar inside the carousel container
100
+ */
101
+ inner: {
102
+ type: Boolean,
103
+ reflect: true,
104
+ },
105
+ /**
106
+ * Determines whether or not to display arrows
107
+ */
108
+ arrows: {
109
+ type: Boolean,
110
+ reflect: true,
111
+ },
112
+ /**
113
+ * Default options for the carousel
114
+ */
115
+ options: {
116
+ type: Object,
117
+ },
118
+ /**
119
+ * Options are different breakpoints for the carousel. Is mobile first.
120
+ */
121
+ breakpoints: {
122
+ type: Object,
123
+ },
124
+ };
125
+ }
126
+
127
+ constructor() {
128
+ super();
129
+
130
+ // managed properties
131
+ this.index = 0;
132
+ this.total = 0;
133
+ this.sliderWidth = 'auto';
134
+ this.sliderTranslateX = '0';
135
+ this.inner = false;
136
+ this.arrows = false;
137
+ this.options = {
138
+ perView: 1,
139
+ perMove: 1,
140
+ gap: 12,
141
+ slideshow: 0,
142
+ rewind: true,
143
+ center: false,
144
+ };
145
+ this.breakpoints = {
146
+ 768: {
147
+ perView: 2,
148
+ gap: 24,
149
+ rewind: false,
150
+ },
151
+ 1280: {
152
+ perView: 2.5,
153
+ center: true,
154
+ },
155
+ };
156
+
157
+ // bindings
158
+ this.addEventListener('kemet-carousel-first', this.handleFirst.bind(this));
159
+ this.addEventListener('kemet-carousel-last', this.handleLast.bind(this));
160
+ this.addEventListener('kemet-carousel-next', this.handleNext.bind(this));
161
+ this.addEventListener('kemet-carousel-prev', this.handlePrev.bind(this));
162
+ this.addEventListener('kemet-carousel-link', this.handleLink.bind(this));
163
+ }
164
+
165
+ firstUpdated() {
166
+ // standard properties
167
+ this.slides = [];
168
+ this.links = [];
169
+
170
+ // elements
171
+ this.containerElement = this.shadowRoot.querySelector('[part="container"]');
172
+ this.slidesElement = this.shadowRoot.querySelector('[part="slides"]');
173
+ this.sliderElement = this.shadowRoot.querySelector('[part="slider"]');
174
+ this.toolbarElement = this.shadowRoot.querySelector('[part="toolbar"]');
175
+ this.toolbarSlotElement = this.querySelector('[slot="toolbar"]');
176
+ this.informationElement = this.querySelector('kemet-carousel-information');
177
+
178
+ // events
179
+ window.addEventListener('resize', () => {
180
+ this.setSlideSize();
181
+ this.setToolbarSize();
182
+ this.updateIndex(this.index);
183
+ });
184
+
185
+ this.sliderElement.addEventListener('transitionend', this.handleTransitionEnd.bind(this));
186
+
187
+ // methods
188
+ this.swipeMove = (event) => {
189
+ event.preventDefault();
190
+
191
+ const pageX = event.touches ? event.touches[0].pageX : event.pageX;
192
+ const currentSlide = this.slides[this.index];
193
+
194
+ this.sliderTranslateX = `${pageX - this.startX - currentSlide.offsetLeft}px`;
195
+ };
196
+
197
+ this.handleSlideShow = () => {
198
+ if (this.getOption('slideshow') > 0) {
199
+ this.updateIndex(this.index + 1);
200
+ clearTimeout(this.handleSlideShow);
201
+ }
202
+ };
203
+
204
+ // setup
205
+ this.setSlideSize();
206
+ this.goToSlide(this.index);
207
+ }
208
+
209
+ updated(prevProps) {
210
+ this.setSlideSize();
211
+ this.setToolbarSize();
212
+
213
+ if (prevProps.has('index')) {
214
+ this.updateIndex(this.index);
215
+ setTimeout(this.handleSlideShow, this.getOption('slideshow') * 1000);
216
+ }
217
+ }
218
+
219
+ render() {
220
+ return html`
221
+ <slot name="prev" @slotchange=${this.handleArrows}></slot>
222
+ <div class="container" part="container">
223
+ <section
224
+ class="slides"
225
+ part="slides"
226
+ @mousedown=${this.swipeStart}
227
+ @mouseup=${this.swipeEnd}
228
+ @touchstart=${this.swipeStart}
229
+ @touchend=${this.swipeEnd}
230
+ @mouseleave=${this.swipeLeave}
231
+ >
232
+ <div class="slider" part="slider" style="width:${this.sliderWidth}; transform:translateX(${this.sliderTranslateX});">
233
+ <slot name="slides" @slotchange="${this.handleSlotChange}"></slot>
234
+ </div>
235
+ </section>
236
+ ${this.makeToolbar()}
237
+ </div>
238
+ <slot name="next" @slotchange=${this.handleArrows}></slot>
239
+ `;
240
+ }
241
+
242
+ swipeStart(event) {
243
+ this.startX = event.touches ? event.touches[0].pageX : event.pageX;
244
+
245
+ this.addEventListener('mousemove', this.swipeMove);
246
+ this.addEventListener('touchmove', this.swipeMove);
247
+ }
248
+
249
+ swipeEnd(event) {
250
+ this.updateIndex(this.swipeUpdate(event));
251
+ this.removeEventListener('mousemove', this.swipeMove, false);
252
+ this.removeEventListener('touchmove', this.swipeMove, false);
253
+ }
254
+
255
+ swipeUpdate(event) {
256
+ const pageX = event.changedTouches ? event.changedTouches[0].pageX : event.pageX;
257
+ const direction = this.startX > pageX ? 'right' : 'left';
258
+ const threshold = this.slidesElement.offsetWidth / 3;
259
+ const diff = this.startX - pageX;
260
+ const shouldUpdate = Math.abs(diff) > threshold;
261
+
262
+ let { index } = this;
263
+
264
+ if (shouldUpdate && direction === 'right') {
265
+ index = this.index >= this.slides.length - 1 ? this.index : this.index + 1;
266
+ }
267
+
268
+ if (shouldUpdate && direction === 'left') {
269
+ index = this.index < 1 ? 0 : this.index - 1;
270
+ }
271
+
272
+ return index;
273
+ }
274
+
275
+ swipeLeave() {
276
+ this.updateIndex(this.index);
277
+ this.removeEventListener('mousemove', this.swipeMove, false);
278
+ this.removeEventListener('touchmove', this.swipeMove, false);
279
+ }
280
+
281
+ setSlideSize() {
282
+ this.slideWidth = this.containerElement.offsetWidth / this.getOption('perView');
283
+
284
+ this.slides.forEach((slide) => {
285
+ slide.style.marginLeft = `${this.getOption('gap') / 2}px`;
286
+ slide.style.marginRight = `${this.getOption('gap') / 2}px`;
287
+ slide.style.width = `${this.slideWidth - this.getOption('gap')}px`;
288
+ });
289
+
290
+ this.sliderWidth = `${this.slideWidth * this.slides.length}px`;
291
+ }
292
+
293
+ setToolbarSize() {
294
+ if (this.inner && this.toolbarElement) {
295
+ const width = this.slidesElement.offsetWidth;
296
+ this.toolbarElement.style.width = `${width}px`;
297
+ }
298
+ }
299
+
300
+ makeToolbar() {
301
+ if (this.toolbarSlotElement) {
302
+ return html`
303
+ <section class="toolbar" part="toolbar">
304
+ <slot name="toolbar"></slot>
305
+ </section>
306
+ `;
307
+ }
308
+
309
+ return null;
310
+ }
311
+
312
+ handleSlotChange() {
313
+ const slides = this.querySelectorAll('kemet-carousel-slide');
314
+ const links = this.querySelectorAll('kemet-carousel-link');
315
+
316
+ // handle slides
317
+ slides.forEach((slide) => {
318
+ this.slides.push(slide);
319
+ });
320
+
321
+ this.updateInformation();
322
+ this.total = slides.length;
323
+ slides[this.index].selected = true;
324
+
325
+ // handle links
326
+ links.forEach((link) => {
327
+ this.links.push(link);
328
+ });
329
+ }
330
+
331
+ handleArrows() {
332
+ this.arrows = true;
333
+ }
334
+
335
+ handleFirst() {
336
+ this.updateIndex(0);
337
+ }
338
+
339
+ handleLast() {
340
+ this.updateIndex(this.slides.length - 1);
341
+ }
342
+
343
+ handleNext() {
344
+ let newIndex = this.index + this.getOption('perMove');
345
+
346
+ if (newIndex >= this.slides.length) {
347
+ if (this.getOption('rewind')) {
348
+ newIndex = 0;
349
+ } else {
350
+ newIndex = this.index;
351
+ }
352
+ }
353
+
354
+ this.updateIndex(newIndex);
355
+ }
356
+
357
+ handlePrev() {
358
+ let newIndex = this.index - this.getOption('perMove');
359
+
360
+ // send them to the last slide
361
+ if (newIndex < 0) {
362
+ if (this.getOption('rewind')) {
363
+ newIndex = this.slides.length - 1;
364
+ } else {
365
+ newIndex = this.index;
366
+ }
367
+ }
368
+
369
+ this.updateIndex(newIndex);
370
+ }
371
+
372
+ updateIndex(newIndex) {
373
+ let currentSlide = this.slides[this.index];
374
+ let currentLink = this.links[newIndex];
375
+
376
+ // remove selected from all links
377
+ this.links.forEach((link) => {
378
+ link.selected = false;
379
+ });
380
+
381
+ // if current link is invalid assume it's the first link
382
+ if (!currentLink) {
383
+ [currentLink] = this.links;
384
+ }
385
+
386
+ // add selected to current link
387
+ if (currentLink) {
388
+ currentLink.selected = true;
389
+ }
390
+
391
+ if (currentSlide) {
392
+ currentSlide.setAttribute('aria-hidden', 'true');
393
+
394
+ // correct for invalid indexes
395
+ if (newIndex > -1 && newIndex < this.slides.length) {
396
+ this.index = newIndex;
397
+ } else {
398
+ // eslint-disable-next-line no-console
399
+ console.warn('An invalid index number was entered. The kemet-carousel has been reset to the first slide.');
400
+ this.index = 0;
401
+ }
402
+
403
+ // move
404
+ this.goToSlide(this.index);
405
+
406
+ // update new slide
407
+ currentSlide = this.slides[this.index];
408
+ currentSlide.setAttribute('aria-hidden', 'false');
409
+
410
+ this.slides.forEach((slide) => {
411
+ slide.selected = false;
412
+ });
413
+
414
+ currentSlide.selected = true;
415
+
416
+ // notify consumers of slide change
417
+
418
+ /**
419
+ * Fires with the a slide has begun to change
420
+ */
421
+ this.dispatchEvent(new CustomEvent('kemet-carousel-change-start', {
422
+ bubbles: true,
423
+ composed: true,
424
+ detail: this,
425
+ }));
426
+
427
+ // update information element
428
+ this.updateInformation();
429
+ }
430
+ }
431
+
432
+ updateInformation() {
433
+ this.informationSlot = this.slides[this.index].querySelector('[slot="information"]');
434
+
435
+ if (this.informationElement) {
436
+ if (this.informationSlot) {
437
+ this.informationElement.innerHTML = this.informationSlot.outerHTML;
438
+ } else {
439
+ this.informationElement.innerHTML = '';
440
+ }
441
+ }
442
+ }
443
+
444
+ goToSlide(index) {
445
+ if (this.getOption('center') === true) {
446
+ const slidesCenter = this.slidesElement.offsetWidth / 2;
447
+ const slideX = this.slideWidth * index;
448
+ this.sliderTranslateX = `${slideX - (slideX - slidesCenter) - this.slideWidth / 2 - slideX}px`;
449
+ } else {
450
+ this.sliderTranslateX = `${(this.slideWidth * index) * -1}px`;
451
+ }
452
+ }
453
+
454
+ handleTransitionEnd() {
455
+ const currentElement = this.querySelector('kemet-carousel-current');
456
+
457
+ if (currentElement) {
458
+ currentElement.current = this.index + 1;
459
+ }
460
+
461
+ /**
462
+ * Fires when a slide has changed and finished animating
463
+ */
464
+ this.dispatchEvent(new CustomEvent('kemet-carousel-change-finished', {
465
+ bubbles: true,
466
+ composed: true,
467
+ detail: this,
468
+ }));
469
+ }
470
+
471
+ handleLink(event) {
472
+ this.updateIndex(event.detail.slide);
473
+ }
474
+
475
+ getOption(option) {
476
+ const breakpoints = Object.keys(this.breakpoints);
477
+ let value = this.options[option];
478
+
479
+ breakpoints.forEach((breakpoint) => {
480
+ if (window.matchMedia(`(min-width: ${breakpoint}px)`).matches && this.breakpoints[breakpoint][option] !== undefined) {
481
+ value = this.breakpoints[breakpoint][option];
482
+ }
483
+
484
+ return value;
485
+ });
486
+
487
+ return value;
488
+ }
489
+ }
490
+
491
+ // eslint-disable-next-line no-unused-expressions
492
+ customElements.get('kemet-carousel') || customElements.define('kemet-carousel', KemetCarousel);