kemet-ui 1.0.0 → 1.2.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 (77) hide show
  1. package/custom-elements.json +1605 -225
  2. package/dist/components/{kemet-accordion-panel.js → kemet-accordion/kemet-accordion-panel.js} +0 -0
  3. package/dist/components/{kemet-accordion.js → kemet-accordion/kemet-accordion.js} +0 -0
  4. package/dist/components/{kemet-badge.js → kemet-badge/kemet-badge.js} +0 -0
  5. package/dist/components/{kemet-button.js → kemet-button/kemet-button.js} +0 -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/kemet-carousel-link.js +59 -0
  10. package/dist/components/kemet-carousel/kemet-carousel-next.js +47 -0
  11. package/dist/components/kemet-carousel/kemet-carousel-prev.js +47 -0
  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.js → kemet-checkbox/kemet-checkbox.js} +0 -0
  16. package/dist/components/{kemet-combo.js → kemet-combo/kemet-combo.js} +0 -0
  17. package/dist/components/{kemet-count.js → kemet-count/kemet-count.js} +0 -0
  18. package/dist/components/{kemet-draggable.js → kemet-draggable/kemet-draggable.js} +0 -0
  19. package/dist/components/{kemet-drawer.js → kemet-drawer/kemet-drawer.js} +0 -0
  20. package/dist/components/{kemet-drawer.styles.js → kemet-drawer/kemet-drawer.styles.js} +0 -0
  21. package/dist/components/kemet-fab/kemet-fab.js +209 -0
  22. package/dist/components/{kemet-field.js → kemet-field/kemet-field.js} +0 -0
  23. package/dist/components/{kemet-flipcard-trigger.js → kemet-flipcard/kemet-flipcard-trigger.js} +0 -0
  24. package/dist/components/{kemet-flipcard.js → kemet-flipcard/kemet-flipcard.js} +0 -0
  25. package/dist/components/{kemet-icon.js → kemet-icon/kemet-icon.js} +0 -0
  26. package/dist/components/{kemet-input.js → kemet-input/kemet-input.js} +15 -4
  27. package/dist/components/{kemet-modal-close.js → kemet-modal/kemet-modal-close.js} +0 -0
  28. package/dist/components/{kemet-modal.js → kemet-modal/kemet-modal.js} +0 -0
  29. package/dist/components/{kemet-modal.styles.js → kemet-modal/kemet-modal.styles.js} +0 -0
  30. package/dist/components/kemet-password/kemet-password.js +278 -0
  31. package/dist/components/{kemet-popover-close.js → kemet-popover/kemet-popover-close.js} +0 -0
  32. package/dist/components/{kemet-popover.effects.styles.js → kemet-popover/kemet-popover.effects.styles.js} +0 -0
  33. package/dist/components/{kemet-popover.js → kemet-popover/kemet-popover.js} +0 -0
  34. package/dist/components/{kemet-popover.tooltip.styles.js → kemet-popover/kemet-popover.tooltip.styles.js} +0 -0
  35. package/dist/components/{kemet-radio.js → kemet-radio/kemet-radio.js} +0 -0
  36. package/dist/components/{kemet-radios.js → kemet-radio/kemet-radios.js} +0 -0
  37. package/dist/components/{kemet-rotator.js → kemet-rotator/kemet-rotator.js} +0 -0
  38. package/dist/components/{kemet-scroll-link.js → kemet-scroll-link/kemet-scroll-link.js} +0 -0
  39. package/dist/components/{kemet-scroll-nav.js → kemet-scroll-nav/kemet-scroll-nav.js} +0 -0
  40. package/dist/components/{kemet-scroll-snap-paginator.js → kemet-scroll-snap/kemet-scroll-snap-paginator.js} +0 -0
  41. package/dist/components/{kemet-scroll-snap-slide.js → kemet-scroll-snap/kemet-scroll-snap-slide.js} +0 -0
  42. package/dist/components/{kemet-scroll-snap.js → kemet-scroll-snap/kemet-scroll-snap.js} +0 -0
  43. package/dist/components/{kemet-option.js → kemet-select/kemet-option.js} +0 -0
  44. package/dist/components/{kemet-select.js → kemet-select/kemet-select.js} +0 -0
  45. package/dist/components/{kemet-svg.js → kemet-svgs/kemet-svg.js} +0 -0
  46. package/dist/components/{kemet-svgs.js → kemet-svgs/kemet-svgs.js} +0 -0
  47. package/dist/components/{kemet-tab-panel.js → kemet-tabs/kemet-tab-panel.js} +0 -0
  48. package/dist/components/{kemet-tab.js → kemet-tabs/kemet-tab.js} +0 -0
  49. package/dist/components/{kemet-tabs.js → kemet-tabs/kemet-tabs.js} +0 -0
  50. package/dist/components/{kemet-tabs.styles.js → kemet-tabs/kemet-tabs.styles.js} +0 -0
  51. package/dist/components/{kemet-textarea.js → kemet-textarea/kemet-textarea.js} +0 -0
  52. package/dist/components/{kemet-toggle.js → kemet-toggle/kemet-toggle.js} +0 -0
  53. package/dist/components/kemet-tracker/kemet-tracker-step.js +239 -0
  54. package/dist/components/kemet-tracker/kemet-tracker.js +76 -0
  55. package/dist/kemet-components.cjs +1809 -140
  56. package/dist/kemet-components.js +1805 -141
  57. package/dist/kemet-components.min.js +574 -87
  58. package/dist/styles/components/_config.scss +4 -0
  59. package/dist/styles/{scss/components → components}/accordion.scss +0 -0
  60. package/dist/styles/{scss/components → components}/drawer.scss +2 -2
  61. package/dist/styles/{scss/components → components}/modal.scss +0 -0
  62. package/dist/styles/{scss/components → components}/scrollsnap.scss +0 -0
  63. package/dist/styles/{scss/core → core}/_config.scss +22 -22
  64. package/dist/styles/{scss/core → core}/_helpers.scss +7 -3
  65. package/dist/styles/{scss/core → core}/attributes.scss +0 -0
  66. package/dist/styles/{scss/core → core}/base.scss +0 -0
  67. package/dist/styles/{scss/core → core}/layout.scss +0 -0
  68. package/dist/styles/kemet.components.css +1 -80
  69. package/dist/styles/kemet.components.css.map +1 -1
  70. package/dist/styles/{scss/kemet.components.scss → kemet.components.scss} +0 -1
  71. package/dist/styles/kemet.core.css +1 -1
  72. package/dist/styles/kemet.core.css.map +1 -1
  73. package/dist/styles/{scss/kemet.core.scss → kemet.core.scss} +0 -0
  74. package/dist/utilities/controllers/forms.js +123 -0
  75. package/package.json +5 -3
  76. package/dist/styles/scss/components/_config.scss +0 -4
  77. package/dist/styles/scss/components/carousel.scss +0 -64
@@ -463,6 +463,107 @@ class KemetAccordion extends s$1 {
463
463
  // eslint-disable-next-line no-unused-expressions
464
464
  customElements.get('kemet-accordion') || customElements.define('kemet-accordion', KemetAccordion);
465
465
 
466
+ class KemetBadge extends s$1 {
467
+ static get styles() {
468
+ return [
469
+ r$3`
470
+ :host {
471
+ display: inline-flex;
472
+ align-items: center;
473
+ justify-content: center;
474
+ padding: var(--kemet-badge-padding, 10px);
475
+ line-height: 1;
476
+ color: var(--kemet-color-white);
477
+ }
478
+
479
+ :host([status='primary']) {
480
+ background-color: var(--kemet-color-primary);
481
+ }
482
+
483
+ :host([status='success']) {
484
+ background-color: var(--kemet-color-success);
485
+ }
486
+
487
+ :host([status='standard']) {
488
+ background-color: var(--kemet-color-gray6);
489
+ }
490
+
491
+ :host([status='warning']) {
492
+ background-color: var(--kemet-color-warning);
493
+ }
494
+
495
+ :host([status='error']) {
496
+ background-color: var(--kemet-color-error);
497
+ }
498
+
499
+ :host([circle]) {
500
+ border-radius: 50%;
501
+ }
502
+
503
+ :host([pill]) {
504
+ border-radius: 99rem;
505
+ }
506
+ `,
507
+ ];
508
+ }
509
+
510
+ static get properties() {
511
+ return {
512
+ /**
513
+ * The status of the badge
514
+ */
515
+ status: {
516
+ type: String,
517
+ reflect: true,
518
+ },
519
+ /**
520
+ * Displays the badge in a circle
521
+ */
522
+ circle: {
523
+ type: Boolean,
524
+ reflect: true,
525
+ },
526
+ /**
527
+ * Rounds the corners on the badge
528
+ */
529
+ pill: {
530
+ type: Boolean,
531
+ reflect: true,
532
+ },
533
+ /**
534
+ * Padding on the badge as a circle
535
+ */
536
+ circlePadding: {
537
+ type: Number,
538
+ attribute: 'circle-padding',
539
+ },
540
+ };
541
+ }
542
+
543
+ constructor() {
544
+ super();
545
+
546
+ this.status = 'primary';
547
+ this.pill = false;
548
+ this.circle = false;
549
+ this.circlePadding = 0;
550
+ }
551
+
552
+ render() {
553
+ return $`<slot @slotchange=${() => this.handleSlotChange()}></slot>`;
554
+ }
555
+
556
+ handleSlotChange() {
557
+ if (this.circle) {
558
+ this.style.height = `${this.offsetWidth + this.circlePadding}px`;
559
+ this.style.width = `${this.offsetWidth + this.circlePadding}px`;
560
+ }
561
+ }
562
+ }
563
+
564
+ // eslint-disable-next-line no-unused-expressions
565
+ customElements.get('kemet-badge') || customElements.define('kemet-badge', KemetBadge);
566
+
466
567
  class FormSubmitController {
467
568
  host;
468
569
  form;
@@ -508,10 +609,10 @@ class FormSubmitController {
508
609
  if (!disabled && typeof name === 'string' && typeof value !== 'undefined') {
509
610
  if (Array.isArray(value)) {
510
611
  value.forEach((val) => {
511
- event.formData.append(name, val.toString());
612
+ event.formData?.append(name, val.toString());
512
613
  });
513
614
  } else {
514
- event.formData.append(name, value.toString());
615
+ event.formData?.append(name, value.toString());
515
616
  }
516
617
  }
517
618
  }
@@ -520,6 +621,8 @@ class FormSubmitController {
520
621
  const disabled = this.options.disabled(this.host);
521
622
  const checkValidity = this.options.checkValidity;
522
623
 
624
+ this.form = this.options.form(this.host);
625
+
523
626
  if (this.form && !this.form.noValidate && !disabled && !checkValidity(this.host)) {
524
627
  event.preventDefault();
525
628
  event.stopImmediatePropagation();
@@ -812,106 +915,858 @@ class KemetButton extends s$1 {
812
915
  // eslint-disable-next-line no-unused-expressions
813
916
  customElements.get('kemet-button') || customElements.define('kemet-button', KemetButton);
814
917
 
815
- class KemetBadge extends s$1 {
918
+ class KemetCarouselCurrent extends s$1 {
816
919
  static get styles() {
817
920
  return [
818
921
  r$3`
819
922
  :host {
820
- display: inline-flex;
821
- align-items: center;
822
- justify-content: center;
823
- padding: var(--kemet-badge-padding, 10px);
824
- line-height: 1;
825
- color: var(--kemet-color-white);
923
+ display: inline-block;
924
+ }
925
+ `,
926
+ ];
927
+ }
928
+
929
+ static get properties() {
930
+ return {
931
+ current: {
932
+ type: Number,
933
+ },
934
+ };
935
+ }
936
+
937
+ firstUpdated() {
938
+ this.carousel = this.closest('kemet-carousel');
939
+ }
940
+
941
+ updated() {
942
+ this.current = this.carousel.index + 1;
943
+ }
944
+
945
+ render() {
946
+ return $`${this.current}`;
947
+ }
948
+ }
949
+
950
+ // eslint-disable-next-line no-unused-expressions
951
+ customElements.get('kemet-carousel-current') || customElements.define('kemet-carousel-current', KemetCarouselCurrent);
952
+
953
+ class KemetCarouselFirst extends s$1 {
954
+ static get styles() {
955
+ return [
956
+ r$3`
957
+ :host {
958
+ cursor: pointer;
959
+ }
960
+
961
+ :host([disabled]) {
962
+ cursor: not-allowed;
963
+ }
964
+ `,
965
+ ];
966
+ }
967
+
968
+ static get properties() {
969
+ return {
970
+ disabled: {
971
+ type: Boolean,
972
+ reflect: true,
973
+ },
974
+ };
975
+ }
976
+
977
+ render() {
978
+ return $`
979
+ <span tabindex="0" @keyup=${() => this.first()} @click=${() => this.first()}>
980
+ <slot></slot>
981
+ </span>
982
+ `;
983
+ }
984
+
985
+ first() {
986
+ if (!this.disabled) {
987
+ this.dispatchEvent(new CustomEvent('kemet-carousel-first', {
988
+ bubbles: true,
989
+ composed: true,
990
+ detail: this,
991
+ }));
992
+ }
993
+ }
994
+ }
995
+
996
+ // eslint-disable-next-line no-unused-expressions
997
+ customElements.get('kemet-carousel-first') || customElements.define('kemet-carousel-first', KemetCarouselFirst);
998
+
999
+ class KemetCarouselLast extends s$1 {
1000
+ static get styles() {
1001
+ return [
1002
+ r$3`
1003
+ :host {
1004
+ cursor: pointer;
1005
+ }
1006
+
1007
+ :host([disabled]) {
1008
+ cursor: not-allowed;
1009
+ }
1010
+ `,
1011
+ ];
1012
+ }
1013
+
1014
+ static get properties() {
1015
+ return {
1016
+ disabled: {
1017
+ type: Boolean,
1018
+ reflect: true,
1019
+ },
1020
+ };
1021
+ }
1022
+
1023
+ render() {
1024
+ return $`
1025
+ <span tabindex="0" @keyup=${() => this.last()} @click=${() => this.last()}>
1026
+ <slot></slot>
1027
+ </span>
1028
+ `;
1029
+ }
1030
+
1031
+ last() {
1032
+ if (!this.disabled) {
1033
+ this.dispatchEvent(new CustomEvent('kemet-carousel-last', {
1034
+ bubbles: true,
1035
+ composed: true,
1036
+ detail: this,
1037
+ }));
1038
+ }
1039
+ }
1040
+ }
1041
+
1042
+ // eslint-disable-next-line no-unused-expressions
1043
+ customElements.get('kemet-carousel-last') || customElements.define('kemet-carousel-last', KemetCarouselLast);
1044
+
1045
+ class KemetCarouselLink extends s$1 {
1046
+ static get properties() {
1047
+ return {
1048
+ slide: {
1049
+ type: Number,
1050
+ reflect: true,
1051
+ },
1052
+ selected: {
1053
+ type: Boolean,
1054
+ reflect: true,
1055
+ },
1056
+ disabled: {
1057
+ type: Boolean,
1058
+ reflect: true,
1059
+ },
1060
+ };
1061
+ }
1062
+
1063
+ static get styles() {
1064
+ return [
1065
+ r$3`
1066
+ :host([selected]) {
1067
+ color: var(--kemet-carousel-link-selected-color, var(--kemet-color-primary));
826
1068
  }
827
1069
 
828
- :host([status='primary']) {
829
- background-color: var(--kemet-color-primary);
830
- }
1070
+ :host(:not([selected])) {
1071
+ cursor: pointer;
1072
+ }
1073
+
1074
+ :host([disabled]) {
1075
+ cursor: not-allowed;
1076
+ }
1077
+ `,
1078
+ ];
1079
+ }
1080
+
1081
+ render() {
1082
+ return $`
1083
+ <span tabindex="0" @keyup=${() => this.changed()} @click=${() => this.changed()}>
1084
+ <slot></slot>
1085
+ </span>
1086
+ `;
1087
+ }
1088
+
1089
+ changed() {
1090
+ if (!this.disabled) {
1091
+ this.dispatchEvent(new CustomEvent('kemet-carousel-link', {
1092
+ bubbles: true,
1093
+ composed: true,
1094
+ detail: this,
1095
+ }));
1096
+ }
1097
+ }
1098
+ }
1099
+
1100
+ // eslint-disable-next-line no-unused-expressions
1101
+ customElements.get('kemet-carousel-link') || customElements.define('kemet-carousel-link', KemetCarouselLink);
1102
+
1103
+ class KemetCarouselNext extends s$1 {
1104
+ static get styles() {
1105
+ return [
1106
+ r$3`
1107
+ :host {
1108
+ cursor: pointer;
1109
+ }
1110
+
1111
+ :host([disabled]) {
1112
+ cursor: not-allowed;
1113
+ }
1114
+ `,
1115
+ ];
1116
+ }
1117
+
1118
+ static get properties() {
1119
+ return {
1120
+ disabled: {
1121
+ type: Boolean,
1122
+ reflect: true,
1123
+ },
1124
+ };
1125
+ }
1126
+
1127
+ render() {
1128
+ return $`
1129
+ <span tabindex="0" @keyup=${() => this.next()} @click=${() => this.next()}>
1130
+ <slot></slot>
1131
+ </span>
1132
+ `;
1133
+ }
1134
+
1135
+ next() {
1136
+ if (!this.disabled) {
1137
+ this.dispatchEvent(new CustomEvent('kemet-carousel-next', {
1138
+ bubbles: true,
1139
+ composed: true,
1140
+ detail: this,
1141
+ }));
1142
+ }
1143
+ }
1144
+ }
1145
+
1146
+ // eslint-disable-next-line no-unused-expressions
1147
+ customElements.get('kemet-carousel-next') || customElements.define('kemet-carousel-next', KemetCarouselNext);
1148
+
1149
+ class KemetCarouselPrev extends s$1 {
1150
+ static get styles() {
1151
+ return [
1152
+ r$3`
1153
+ :host {
1154
+ cursor: pointer;
1155
+ }
1156
+
1157
+ :host([disabled]) {
1158
+ cursor: not-allowed;
1159
+ }
1160
+ `,
1161
+ ];
1162
+ }
1163
+
1164
+ static get properties() {
1165
+ return {
1166
+ disabled: {
1167
+ type: Boolean,
1168
+ reflect: true,
1169
+ },
1170
+ };
1171
+ }
1172
+
1173
+ render() {
1174
+ return $`
1175
+ <span tabindex="0" @keyup=${() => this.prev()} @click=${() => this.prev()}>
1176
+ <slot></slot>
1177
+ </span>
1178
+ `;
1179
+ }
1180
+
1181
+ prev() {
1182
+ if (!this.disabled) {
1183
+ this.dispatchEvent(new CustomEvent('kemet-carousel-prev', {
1184
+ bubbles: true,
1185
+ composed: true,
1186
+ detail: this,
1187
+ }));
1188
+ }
1189
+ }
1190
+ }
1191
+
1192
+ // eslint-disable-next-line no-unused-expressions
1193
+ customElements.get('kemet-carousel-prev') || customElements.define('kemet-carousel-prev', KemetCarouselPrev);
1194
+
1195
+ class KemetCarouselSlide extends s$1 {
1196
+ static get styles() {
1197
+ return [
1198
+ r$3`
1199
+ :host,
1200
+ :host *,
1201
+ :host *::before,
1202
+ *::after {
1203
+ box-sizing: border-box;
1204
+ }
1205
+
1206
+ :host {
1207
+ flex: 0 0 auto;
1208
+ }
1209
+ `,
1210
+ ];
1211
+ }
1212
+
1213
+ static get properties() {
1214
+ return {
1215
+ /**
1216
+ * Determines if the slide is selected
1217
+ */
1218
+ selected: {
1219
+ type: Boolean,
1220
+ reflect: true,
1221
+ },
1222
+ 'aria-hidden': {
1223
+ type: String,
1224
+ reflect: true,
1225
+ },
1226
+ };
1227
+ }
1228
+
1229
+ constructor() {
1230
+ super();
1231
+ this.selected = false;
1232
+ this['aria-hidden'] = 'true';
1233
+ }
1234
+
1235
+ render() {
1236
+ return $`
1237
+ <slot></slot>
1238
+ `;
1239
+ }
1240
+ }
1241
+
1242
+ // eslint-disable-next-line no-unused-expressions
1243
+ customElements.get('kemet-carousel-slide') || customElements.define('kemet-carousel-slide', KemetCarouselSlide);
1244
+
1245
+ class KemetCarouselTotal extends s$1 {
1246
+ static get styles() {
1247
+ return [
1248
+ r$3`
1249
+ :host {
1250
+ display: inline-block;
1251
+ }
1252
+ `,
1253
+ ];
1254
+ }
1255
+
1256
+ static get properties() {
1257
+ return {
1258
+ total: {
1259
+ type: Number,
1260
+ },
1261
+ };
1262
+ }
1263
+
1264
+ firstUpdated() {
1265
+ this.carousel = this.closest('kemet-carousel');
1266
+ }
1267
+
1268
+ updated() {
1269
+ this.total = this.carousel.total;
1270
+ }
1271
+
1272
+ render() {
1273
+ return $`${this.total}`;
1274
+ }
1275
+ }
1276
+
1277
+ // eslint-disable-next-line no-unused-expressions
1278
+ customElements.get('kemet-carousel-total') || customElements.define('kemet-carousel-total', KemetCarouselTotal);
1279
+
1280
+ class KemetCarousel extends s$1 {
1281
+ static get styles() {
1282
+ return r$3`
1283
+ :host,
1284
+ *,
1285
+ *::before,
1286
+ *::after {
1287
+ box-sizing: border-box;
1288
+ }
1289
+
1290
+ :host {
1291
+ position: relative;
1292
+ display: grid;
1293
+ grid-template-columns: minmax(0, 1fr);
1294
+ align-items: center;
1295
+ width: var(--kemet-carousel-width, 100%);
1296
+ height: var(--kemet-carousel-height, auto);
1297
+ overflow: visible;
1298
+ }
1299
+
1300
+ :host([arrows]) {
1301
+ grid-template-columns: auto minmax(0, 1fr) auto;
1302
+ }
1303
+
1304
+ .toolbar {
1305
+ display: flex;
1306
+ gap: var(--kemet-carousel-toolbar-gap, 1rem);
1307
+ align-items: center;
1308
+ justify-content: var(--kemet-carousel-toolbar-justify-content, center);
1309
+ line-height: 1;
1310
+ padding: var(--kemet-carousel-toolbar-padding, 1rem);
1311
+ }
1312
+
1313
+ :host([inner]) .toolbar {
1314
+ width: var(--kemet-carousel-toolbar-inner-width, 100%);
1315
+ position: absolute;
1316
+ bottom: var(--kemet-carousel-toolbar-inner-bottom, 0);
1317
+ top: var(--kemet-carousel-toolbar-inner-top, auto);
1318
+ color: var(--kemet-carousel-toolbar-inner-color, var(--kemet-color-white));
1319
+ background-color: var(--kemet-carousel-toolbar-inner-background-color, rgba(0, 0, 0, 0.4));
1320
+ }
1321
+
1322
+ .slides {
1323
+ overflow: hidden;
1324
+ position: relative;
1325
+ padding: 1rem 0;
1326
+ border: var(--kemet-carousel-slides-border, 1px solid var(--kemet-color-gray1));
1327
+ }
1328
+
1329
+ .slider {
1330
+ display: flex;
1331
+ flex-wrap: nowrap;
1332
+ transition: transform var(--kemet-carousel-transition-speed, 300ms) ease;
1333
+ }
1334
+
1335
+ ::slotted([slot='next']),
1336
+ ::slotted([slot='prev']) {
1337
+ opacity: var(--kemet-carousel-arrows-opacity, 0.25);
1338
+ transition: opacity var(--kemet-carousel-arrows-transition-speed, 300ms) ease-in-out;
1339
+ }
1340
+
1341
+ :host(:hover) ::slotted([slot='next']),
1342
+ :host(:hover) ::slotted([slot='prev']) {
1343
+ opacity: var(--kemet-carousel-arrows-opacity-hover, 1);
1344
+ }
1345
+ `;
1346
+ }
1347
+
1348
+ static get properties() {
1349
+ return {
1350
+ /**
1351
+ * The current slide index.
1352
+ */
1353
+ index: {
1354
+ type: Number,
1355
+ reflect: true,
1356
+ },
1357
+ /**
1358
+ * The total amount of slides
1359
+ */
1360
+ total: {
1361
+ type: Number,
1362
+ },
1363
+ /**
1364
+ * The width of the slider
1365
+ */
1366
+ sliderWidth: {
1367
+ type: String,
1368
+ },
1369
+ /**
1370
+ * The X position of the slider
1371
+ */
1372
+ sliderTranslateX: {
1373
+ type: String,
1374
+ },
1375
+ /**
1376
+ * Displays the toolbar inside the carousel container
1377
+ */
1378
+ inner: {
1379
+ type: Boolean,
1380
+ reflect: true,
1381
+ },
1382
+ /**
1383
+ * Determines whether or not to display arrows
1384
+ */
1385
+ arrows: {
1386
+ type: Boolean,
1387
+ reflect: true,
1388
+ },
1389
+ /**
1390
+ * Default options for the carousel
1391
+ */
1392
+ options: {
1393
+ type: Object,
1394
+ },
1395
+ /**
1396
+ * Options are different breakpoints for the carousel. Is mobile first.
1397
+ */
1398
+ breakpoints: {
1399
+ type: Object,
1400
+ },
1401
+ };
1402
+ }
1403
+
1404
+ constructor() {
1405
+ super();
1406
+
1407
+ // managed properties
1408
+ this.index = 0;
1409
+ this.total = 0;
1410
+ this.sliderWidth = 'auto';
1411
+ this.sliderTranslateX = '0';
1412
+ this.inner = false;
1413
+ this.arrows = false;
1414
+ this.options = {
1415
+ perView: 1,
1416
+ perMove: 1,
1417
+ gap: 12,
1418
+ slideshow: 0,
1419
+ rewind: true,
1420
+ center: false,
1421
+ };
1422
+ this.breakpoints = {
1423
+ 768: {
1424
+ perView: 2,
1425
+ gap: 24,
1426
+ rewind: false,
1427
+ },
1428
+ 1280: {
1429
+ perView: 2.5,
1430
+ center: true,
1431
+ },
1432
+ };
1433
+
1434
+ // bindings
1435
+ this.addEventListener('kemet-carousel-first', this.handleFirst.bind(this));
1436
+ this.addEventListener('kemet-carousel-last', this.handleLast.bind(this));
1437
+ this.addEventListener('kemet-carousel-next', this.handleNext.bind(this));
1438
+ this.addEventListener('kemet-carousel-prev', this.handlePrev.bind(this));
1439
+ this.addEventListener('kemet-carousel-link', this.handleLink.bind(this));
1440
+ }
1441
+
1442
+ firstUpdated() {
1443
+ // standard properties
1444
+ this.slides = [];
1445
+ this.links = [];
1446
+
1447
+ // elements
1448
+ this.containerElement = this.shadowRoot.querySelector('[part="container"]');
1449
+ this.slidesElement = this.shadowRoot.querySelector('[part="slides"]');
1450
+ this.sliderElement = this.shadowRoot.querySelector('[part="slider"]');
1451
+ this.toolbarElement = this.shadowRoot.querySelector('[part="toolbar"]');
1452
+ this.toolbarSlotElement = this.querySelector('[slot="toolbar"]');
1453
+ this.informationElement = this.querySelector('kemet-carousel-information');
1454
+
1455
+ // events
1456
+ window.addEventListener('resize', () => {
1457
+ this.setSlideSize();
1458
+ this.setToolbarSize();
1459
+ this.updateIndex(this.index);
1460
+ });
1461
+
1462
+ this.sliderElement.addEventListener('transitionend', this.handleTransitionEnd.bind(this));
1463
+
1464
+ // methods
1465
+ this.swipeMove = (event) => {
1466
+ event.preventDefault();
1467
+
1468
+ const pageX = event.touches ? event.touches[0].pageX : event.pageX;
1469
+ const currentSlide = this.slides[this.index];
1470
+
1471
+ this.sliderTranslateX = `${pageX - this.startX - currentSlide.offsetLeft}px`;
1472
+ };
1473
+
1474
+ this.handleSlideShow = () => {
1475
+ if (this.getOption('slideshow') > 0) {
1476
+ this.updateIndex(this.index + 1);
1477
+ clearTimeout(this.handleSlideShow);
1478
+ }
1479
+ };
1480
+
1481
+ // setup
1482
+ this.setSlideSize();
1483
+ this.goToSlide(this.index);
1484
+ }
1485
+
1486
+ updated(prevProps) {
1487
+ this.setSlideSize();
1488
+ this.setToolbarSize();
1489
+
1490
+ if (prevProps.has('index')) {
1491
+ this.updateIndex(this.index);
1492
+ setTimeout(this.handleSlideShow, this.getOption('slideshow') * 1000);
1493
+ }
1494
+ }
1495
+
1496
+ render() {
1497
+ return $`
1498
+ <slot name="prev" @slotchange=${this.handleArrows}></slot>
1499
+ <div class="container" part="container">
1500
+ <section
1501
+ class="slides"
1502
+ part="slides"
1503
+ @mousedown=${this.swipeStart}
1504
+ @mouseup=${this.swipeEnd}
1505
+ @touchstart=${this.swipeStart}
1506
+ @touchend=${this.swipeEnd}
1507
+ @mouseleave=${this.swipeLeave}
1508
+ >
1509
+ <div class="slider" part="slider" style="width:${this.sliderWidth}; transform:translateX(${this.sliderTranslateX});">
1510
+ <slot name="slides" @slotchange="${this.handleSlotChange}"></slot>
1511
+ </div>
1512
+ </section>
1513
+ ${this.makeToolbar()}
1514
+ </div>
1515
+ <slot name="next" @slotchange=${this.handleArrows}></slot>
1516
+ `;
1517
+ }
1518
+
1519
+ swipeStart(event) {
1520
+ this.startX = event.touches ? event.touches[0].pageX : event.pageX;
1521
+
1522
+ this.addEventListener('mousemove', this.swipeMove);
1523
+ this.addEventListener('touchmove', this.swipeMove);
1524
+ }
1525
+
1526
+ swipeEnd(event) {
1527
+ this.updateIndex(this.swipeUpdate(event));
1528
+ this.removeEventListener('mousemove', this.swipeMove, false);
1529
+ this.removeEventListener('touchmove', this.swipeMove, false);
1530
+ }
1531
+
1532
+ swipeUpdate(event) {
1533
+ const pageX = event.changedTouches ? event.changedTouches[0].pageX : event.pageX;
1534
+ const direction = this.startX > pageX ? 'right' : 'left';
1535
+ const threshold = this.slidesElement.offsetWidth / 3;
1536
+ const diff = this.startX - pageX;
1537
+ const shouldUpdate = Math.abs(diff) > threshold;
1538
+
1539
+ let { index } = this;
1540
+
1541
+ if (shouldUpdate && direction === 'right') {
1542
+ index = this.index >= this.slides.length - 1 ? this.index : this.index + 1;
1543
+ }
1544
+
1545
+ if (shouldUpdate && direction === 'left') {
1546
+ index = this.index < 1 ? 0 : this.index - 1;
1547
+ }
1548
+
1549
+ return index;
1550
+ }
1551
+
1552
+ swipeLeave() {
1553
+ this.updateIndex(this.index);
1554
+ this.removeEventListener('mousemove', this.swipeMove, false);
1555
+ this.removeEventListener('touchmove', this.swipeMove, false);
1556
+ }
1557
+
1558
+ setSlideSize() {
1559
+ this.slideWidth = this.containerElement.offsetWidth / this.getOption('perView');
1560
+
1561
+ this.slides.forEach((slide) => {
1562
+ slide.style.marginLeft = `${this.getOption('gap') / 2}px`;
1563
+ slide.style.marginRight = `${this.getOption('gap') / 2}px`;
1564
+ slide.style.width = `${this.slideWidth - this.getOption('gap')}px`;
1565
+ });
1566
+
1567
+ this.sliderWidth = `${this.slideWidth * this.slides.length}px`;
1568
+ }
1569
+
1570
+ setToolbarSize() {
1571
+ if (this.inner && this.toolbarElement) {
1572
+ const width = this.slidesElement.offsetWidth;
1573
+ this.toolbarElement.style.width = `${width}px`;
1574
+ }
1575
+ }
1576
+
1577
+ makeToolbar() {
1578
+ if (this.toolbarSlotElement) {
1579
+ return $`
1580
+ <section class="toolbar" part="toolbar">
1581
+ <slot name="toolbar"></slot>
1582
+ </section>
1583
+ `;
1584
+ }
1585
+
1586
+ return null;
1587
+ }
1588
+
1589
+ handleSlotChange() {
1590
+ const slides = this.querySelectorAll('kemet-carousel-slide');
1591
+ const links = this.querySelectorAll('kemet-carousel-link');
1592
+
1593
+ // handle slides
1594
+ slides.forEach((slide) => {
1595
+ this.slides.push(slide);
1596
+ });
1597
+
1598
+ this.updateInformation();
1599
+ this.total = slides.length;
1600
+ slides[this.index].selected = true;
1601
+
1602
+ // handle links
1603
+ links.forEach((link) => {
1604
+ this.links.push(link);
1605
+ });
1606
+ }
1607
+
1608
+ handleArrows() {
1609
+ this.arrows = true;
1610
+ }
1611
+
1612
+ handleFirst() {
1613
+ this.updateIndex(0);
1614
+ }
1615
+
1616
+ handleLast() {
1617
+ this.updateIndex(this.slides.length - 1);
1618
+ }
1619
+
1620
+ handleNext() {
1621
+ let newIndex = this.index + this.getOption('perMove');
1622
+
1623
+ if (newIndex >= this.slides.length) {
1624
+ if (this.getOption('rewind')) {
1625
+ newIndex = 0;
1626
+ } else {
1627
+ newIndex = this.index;
1628
+ }
1629
+ }
1630
+
1631
+ this.updateIndex(newIndex);
1632
+ }
1633
+
1634
+ handlePrev() {
1635
+ let newIndex = this.index - this.getOption('perMove');
1636
+
1637
+ // send them to the last slide
1638
+ if (newIndex < 0) {
1639
+ if (this.getOption('rewind')) {
1640
+ newIndex = this.slides.length - 1;
1641
+ } else {
1642
+ newIndex = this.index;
1643
+ }
1644
+ }
1645
+
1646
+ this.updateIndex(newIndex);
1647
+ }
831
1648
 
832
- :host([status='success']) {
833
- background-color: var(--kemet-color-success);
834
- }
1649
+ updateIndex(newIndex) {
1650
+ let currentSlide = this.slides[this.index];
1651
+ let currentLink = this.links[newIndex];
835
1652
 
836
- :host([status='standard']) {
837
- background-color: var(--kemet-color-gray6);
838
- }
1653
+ // remove selected from all links
1654
+ this.links.forEach((link) => {
1655
+ link.selected = false;
1656
+ });
839
1657
 
840
- :host([status='warning']) {
841
- background-color: var(--kemet-color-warning);
842
- }
1658
+ // if current link is invalid assume it's the first link
1659
+ if (!currentLink) {
1660
+ [currentLink] = this.links;
1661
+ }
843
1662
 
844
- :host([status='error']) {
845
- background-color: var(--kemet-color-error);
846
- }
1663
+ // add selected to current link
1664
+ if (currentLink) {
1665
+ currentLink.selected = true;
1666
+ }
847
1667
 
848
- :host([circle]) {
849
- border-radius: 50%;
850
- }
1668
+ if (currentSlide) {
1669
+ currentSlide.setAttribute('aria-hidden', 'true');
851
1670
 
852
- :host([pill]) {
853
- border-radius: 99rem;
854
- }
855
- `,
856
- ];
857
- }
1671
+ // correct for invalid indexes
1672
+ if (newIndex > -1 && newIndex < this.slides.length) {
1673
+ this.index = newIndex;
1674
+ } else {
1675
+ // eslint-disable-next-line no-console
1676
+ console.warn('An invalid index number was entered. The kemet-carousel has been reset to the first slide.');
1677
+ this.index = 0;
1678
+ }
1679
+
1680
+ // move
1681
+ this.goToSlide(this.index);
1682
+
1683
+ // update new slide
1684
+ currentSlide = this.slides[this.index];
1685
+ currentSlide.setAttribute('aria-hidden', 'false');
1686
+
1687
+ this.slides.forEach((slide) => {
1688
+ slide.selected = false;
1689
+ });
1690
+
1691
+ currentSlide.selected = true;
1692
+
1693
+ // notify consumers of slide change
858
1694
 
859
- static get properties() {
860
- return {
861
- /**
862
- * The status of the badge
863
- */
864
- status: {
865
- type: String,
866
- reflect: true,
867
- },
868
- /**
869
- * Displays the badge in a circle
870
- */
871
- circle: {
872
- type: Boolean,
873
- reflect: true,
874
- },
875
- /**
876
- * Rounds the corners on the badge
877
- */
878
- pill: {
879
- type: Boolean,
880
- reflect: true,
881
- },
882
1695
  /**
883
- * Padding on the badge as a circle
1696
+ * Fires with the a slide has begun to change
884
1697
  */
885
- circlePadding: {
886
- type: Number,
887
- attribute: 'circle-padding',
888
- },
889
- };
1698
+ this.dispatchEvent(new CustomEvent('kemet-carousel-change-start', {
1699
+ bubbles: true,
1700
+ composed: true,
1701
+ detail: this,
1702
+ }));
1703
+
1704
+ // update information element
1705
+ this.updateInformation();
1706
+ }
890
1707
  }
891
1708
 
892
- constructor() {
893
- super();
1709
+ updateInformation() {
1710
+ this.informationSlot = this.slides[this.index].querySelector('[slot="information"]');
894
1711
 
895
- this.status = 'primary';
896
- this.pill = false;
897
- this.circle = false;
898
- this.circlePadding = 0;
1712
+ if (this.informationElement) {
1713
+ if (this.informationSlot) {
1714
+ this.informationElement.innerHTML = this.informationSlot.outerHTML;
1715
+ } else {
1716
+ this.informationElement.innerHTML = '';
1717
+ }
1718
+ }
899
1719
  }
900
1720
 
901
- render() {
902
- return $`<slot @slotchange=${() => this.handleSlotChange()}></slot>`;
1721
+ goToSlide(index) {
1722
+ if (this.getOption('center') === true) {
1723
+ const slidesCenter = this.slidesElement.offsetWidth / 2;
1724
+ const slideX = this.slideWidth * index;
1725
+ this.sliderTranslateX = `${slideX - (slideX - slidesCenter) - this.slideWidth / 2 - slideX}px`;
1726
+ } else {
1727
+ this.sliderTranslateX = `${(this.slideWidth * index) * -1}px`;
1728
+ }
903
1729
  }
904
1730
 
905
- handleSlotChange() {
906
- if (this.circle) {
907
- this.style.height = `${this.offsetWidth + this.circlePadding}px`;
908
- this.style.width = `${this.offsetWidth + this.circlePadding}px`;
1731
+ handleTransitionEnd() {
1732
+ const currentElement = this.querySelector('kemet-carousel-current');
1733
+
1734
+ if (currentElement) {
1735
+ currentElement.current = this.index + 1;
909
1736
  }
1737
+
1738
+ /**
1739
+ * Fires when a slide has changed and finished animating
1740
+ */
1741
+ this.dispatchEvent(new CustomEvent('kemet-carousel-change-finished', {
1742
+ bubbles: true,
1743
+ composed: true,
1744
+ detail: this,
1745
+ }));
1746
+ }
1747
+
1748
+ handleLink(event) {
1749
+ this.updateIndex(event.detail.slide);
1750
+ }
1751
+
1752
+ getOption(option) {
1753
+ const breakpoints = Object.keys(this.breakpoints);
1754
+ let value = this.options[option];
1755
+
1756
+ breakpoints.forEach((breakpoint) => {
1757
+ if (window.matchMedia(`(min-width: ${breakpoint}px)`).matches && this.breakpoints[breakpoint][option] !== undefined) {
1758
+ value = this.breakpoints[breakpoint][option];
1759
+ }
1760
+
1761
+ return value;
1762
+ });
1763
+
1764
+ return value;
910
1765
  }
911
1766
  }
912
1767
 
913
1768
  // eslint-disable-next-line no-unused-expressions
914
- customElements.get('kemet-badge') || customElements.define('kemet-badge', KemetBadge);
1769
+ customElements.get('kemet-carousel') || customElements.define('kemet-carousel', KemetCarousel);
915
1770
 
916
1771
  /**
917
1772
  * @license
@@ -2091,26 +2946,234 @@ class KemetDrawer extends s$1 {
2091
2946
  }
2092
2947
  }
2093
2948
 
2094
- render() {
2095
- return $`
2096
- <section class="off-canvas" part="container">
2097
- <nav class="off-canvas__nav" part="drawer" title="Drawer">
2098
- <slot name="navigation"></slot>
2099
- </nav>
2100
- <div class="off-canvas__pusher" part="pusher">
2101
- <main class="off-canvas__content" part="content">
2102
- <div class="off-canvas__wrapper" part="wrapper">
2103
- <slot name="content"></slot>
2104
- </div>
2105
- </main>
2106
- </div>
2107
- </section>
2108
- `;
2949
+ render() {
2950
+ return $`
2951
+ <section class="off-canvas" part="container">
2952
+ <nav class="off-canvas__nav" part="drawer" title="Drawer">
2953
+ <slot name="navigation"></slot>
2954
+ </nav>
2955
+ <div class="off-canvas__pusher" part="pusher">
2956
+ <main class="off-canvas__content" part="content">
2957
+ <div class="off-canvas__wrapper" part="wrapper">
2958
+ <slot name="content"></slot>
2959
+ </div>
2960
+ </main>
2961
+ </div>
2962
+ </section>
2963
+ `;
2964
+ }
2965
+ }
2966
+
2967
+ // eslint-disable-next-line no-unused-expressions
2968
+ customElements.get('kemet-drawer') || customElements.define('kemet-drawer', KemetDrawer);
2969
+
2970
+ class KemetFAB extends s$1 {
2971
+ static get styles() {
2972
+ return [
2973
+ r$3`
2974
+ :host {
2975
+ --kemet-fab-size: 50px;
2976
+
2977
+ display: inline-block;
2978
+ position: relative;
2979
+ }
2980
+
2981
+ button {
2982
+ color: var(--kemet-fab-color, var(--kemet-color-white));
2983
+ font-size: inherit;
2984
+ display: inline-flex;
2985
+ padding: 0;
2986
+ position: relative;
2987
+ min-height: var(--kemet-fab-size);
2988
+ min-width: var(--kemet-fab-size);
2989
+ max-width: var(--kemet-fab-size);
2990
+ align-items: center;
2991
+ justify-content: flex-start;
2992
+ transition: all 0.4s ease;
2993
+ border: none;
2994
+ background-color: var(--kemet-fab-background-color, var(--kemet-color-primary));
2995
+ }
2996
+
2997
+ :host([outlined]) button {
2998
+ color: var(--kemet-fab-outlined-color, var(--kemet-color-primary));
2999
+ border: var(--kemet-fab-outlined-border, 1px solid var(--kemet-color-primary));
3000
+ background-color: transparent;
3001
+ }
3002
+
3003
+ :host([pill]) button {
3004
+ border-radius: var(--kemet-fab-pill-radius, 10rem);
3005
+ }
3006
+
3007
+ button::before {
3008
+ content: '';
3009
+ position: absolute;
3010
+ top: 0;
3011
+ left: 0;
3012
+ right: 0;
3013
+ bottom: 0;
3014
+ z-index: -1;
3015
+ width: 100%;
3016
+ height: 100%;
3017
+ transition: background-color 0.3s ease-in-out;
3018
+ background-color: var(--kemet-fab-background-color, var(--kemet-color-primary));
3019
+ }
3020
+
3021
+ :host([pill]) button::before {
3022
+ border-radius: var(--kemet-fab-pill-radius, 10rem);
3023
+ }
3024
+
3025
+ :host([outlined]) button::before {
3026
+ border: var(--kemet-fab-outline-border, 1px solid var(--kemet-color-primary));
3027
+ background-color: transparent;
3028
+ }
3029
+
3030
+ :host([expanded]) button {
3031
+ max-width: 99rem;
3032
+ padding: 0 1.35rem 0 0.25rem;
3033
+ }
3034
+
3035
+ :host([disabled]) button {
3036
+ opacity: 0.5;
3037
+ cursor: not-allowed;
3038
+ }
3039
+
3040
+ .icon {
3041
+ width: var(--kemet-fab-size);
3042
+ height: var(--kemet-fab-size);
3043
+ display: flex;
3044
+ flex: 0 0 auto;
3045
+ align-items: center;
3046
+ justify-content: center;
3047
+ }
3048
+
3049
+ .text {
3050
+ color: var(--kemet-fab-color, var(--kemet-color-white));
3051
+ z-index: 1;
3052
+ white-space: nowrap;
3053
+ pointer-events: none;
3054
+ opacity: 0;
3055
+ transition: opacity 0.2s ease-in-out;
3056
+ }
3057
+
3058
+ :host([outlined]) .text {
3059
+ color: var(--kemet-fab-outlined-color, var(--kemet-color-primary));
3060
+ }
3061
+
3062
+ :host([expanded]) .text {
3063
+ opacity: 1;
3064
+ }
3065
+ `,
3066
+ ];
3067
+ }
3068
+
3069
+ static get properties() {
3070
+ return {
3071
+ /**
3072
+ * The expanded state of the button
3073
+ */
3074
+ expanded: {
3075
+ type: Boolean,
3076
+ reflect: true,
3077
+ },
3078
+ /**
3079
+ * Outline style for a button
3080
+ */
3081
+ outlined: {
3082
+ type: Boolean,
3083
+ reflect: true,
3084
+ },
3085
+ /**
3086
+ * Determines whether not a button is disabled
3087
+ */
3088
+ disabled: {
3089
+ type: Boolean,
3090
+ reflect: true,
3091
+ },
3092
+ /**
3093
+ * Displays the fab with rounded corners
3094
+ */
3095
+ pill: {
3096
+ type: Boolean,
3097
+ reflect: true,
3098
+ },
3099
+ /**
3100
+ * The distance, in pixels, where the fab should automatically expand
3101
+ */
3102
+ expandPoint: {
3103
+ type: Number,
3104
+ attribute: 'expand-point',
3105
+ },
3106
+ /**
3107
+ * The distance, in pixels, where the fab should automatically collapse
3108
+ */
3109
+ collapsePoint: {
3110
+ type: Number,
3111
+ attribute: 'collapse-point',
3112
+ },
3113
+ };
3114
+ }
3115
+
3116
+ constructor() {
3117
+ super();
3118
+
3119
+ this.outlined = false;
3120
+ this.disabled = false;
3121
+ this.expanded = false;
3122
+ }
3123
+
3124
+ firstUpdated() {
3125
+ // events
3126
+ window.addEventListener('scroll', this.handleScroll.bind(this));
3127
+ this.addEventListener('mouseover', this.handleMouseOver.bind(this));
3128
+ this.addEventListener('mouseout', this.handleMouseOut.bind(this));
3129
+ }
3130
+
3131
+ render() {
3132
+ return $`
3133
+ <button class="button" part="button" ?disabled=${this.disabled} aria-disabled=${this.disabled ? 'true' : 'false'}>
3134
+ <span class="icon" part="icon">
3135
+ <slot name="icon"></slot>
3136
+ </span>
3137
+ <span class="text" part="text">
3138
+ <slot></slot>
3139
+ </span>
3140
+ </button>
3141
+ `;
3142
+ }
3143
+
3144
+ handleMouseOver() {
3145
+ if (!this.disabled) {
3146
+ this.expanded = true;
3147
+ }
3148
+ }
3149
+
3150
+ handleMouseOut() {
3151
+ if (!this.disabled) {
3152
+ this.expanded = false;
3153
+ }
3154
+ }
3155
+
3156
+ handleScroll() {
3157
+ if (window.scrollY > this.expandPoint) {
3158
+ this.expanded = true;
3159
+ }
3160
+
3161
+ if (window.scrollY < this.expandPoint) {
3162
+ this.expanded = false;
3163
+ }
3164
+
3165
+ if (window.scrollY > this.collapsePoint) {
3166
+ this.expanded = false;
3167
+ }
3168
+
3169
+ if (window.scrollY < this.collapsePoint) {
3170
+ this.expanded = true;
3171
+ }
2109
3172
  }
2110
3173
  }
2111
3174
 
2112
3175
  // eslint-disable-next-line no-unused-expressions
2113
- customElements.get('kemet-drawer') || customElements.define('kemet-drawer', KemetDrawer);
3176
+ customElements.get('kemet-fab') || customElements.define('kemet-fab', KemetFAB);
2114
3177
 
2115
3178
  class KemetField extends s$1 {
2116
3179
  static get styles() {
@@ -2893,6 +3956,13 @@ class KemetInput extends s$1 {
2893
3956
  inputType: {
2894
3957
  type: String,
2895
3958
  },
3959
+ /**
3960
+ * Determines if the input is focused
3961
+ */
3962
+ focused: {
3963
+ type: Boolean,
3964
+ reflect: true,
3965
+ },
2896
3966
  };
2897
3967
  }
2898
3968
 
@@ -2907,6 +3977,7 @@ class KemetInput extends s$1 {
2907
3977
  this.iconSize = 20;
2908
3978
  this.validateOnBlur = false;
2909
3979
  this.isPasswordVisible = false;
3980
+ this.focused = false;
2910
3981
 
2911
3982
  /**
2912
3983
  * Used only for form reactive controller
@@ -2920,6 +3991,10 @@ class KemetInput extends s$1 {
2920
3991
  this.field = this.closest('kemet-field');
2921
3992
  this.form = this.closest('form');
2922
3993
  this.slug = this.field ? this.field.slug : 'input';
3994
+
3995
+ if (this.field) {
3996
+ this.field.addEventListener('fmc-password-status', event => this.handleStatus(event));
3997
+ }
2923
3998
  }
2924
3999
 
2925
4000
  render() {
@@ -3034,7 +4109,7 @@ class KemetInput extends s$1 {
3034
4109
  * @private
3035
4110
  */
3036
4111
  handleFocus() {
3037
- this.hasFocus = true;
4112
+ this.focused = true;
3038
4113
 
3039
4114
  /**
3040
4115
  * Fires when the input receives and loses focus
@@ -3058,7 +4133,7 @@ class KemetInput extends s$1 {
3058
4133
  this.validity = this.input.validity;
3059
4134
  }
3060
4135
 
3061
- this.hasFocus = false;
4136
+ this.focused = false;
3062
4137
 
3063
4138
  /**
3064
4139
  * Fires when the input receives and loses focus
@@ -3108,8 +4183,7 @@ class KemetInput extends s$1 {
3108
4183
  * Handles when the input receives input
3109
4184
  * @private
3110
4185
  */
3111
- handleInput(e) {
3112
- this.inputType = e.inputType;
4186
+ handleInput() {
3113
4187
  this.value = this.input.value;
3114
4188
 
3115
4189
  /**
@@ -3600,66 +4674,343 @@ class KemetModal extends s$1 {
3600
4674
  this.focusableElements[0].focus();
3601
4675
  }, 100);
3602
4676
 
3603
- /**
3604
- * Fires when the modal opens
3605
- */
3606
- this.dispatchEvent(
3607
- new CustomEvent('kemet-modal-opened', {
3608
- bubbles: true,
3609
- composed: true,
3610
- detail: this,
3611
- }),
3612
- );
3613
- }
4677
+ /**
4678
+ * Fires when the modal opens
4679
+ */
4680
+ this.dispatchEvent(
4681
+ new CustomEvent('kemet-modal-opened', {
4682
+ bubbles: true,
4683
+ composed: true,
4684
+ detail: this,
4685
+ }),
4686
+ );
4687
+ }
4688
+
4689
+ if (prevProps.get('opened') && this.opened === false) {
4690
+ /**
4691
+ * Fires when the modal closes
4692
+ */
4693
+ this.dispatchEvent(
4694
+ new CustomEvent('kemet-modal-closed', {
4695
+ bubbles: true,
4696
+ composed: true,
4697
+ detail: this,
4698
+ }),
4699
+ );
4700
+ }
4701
+
4702
+ this.isMobile();
4703
+ }
4704
+
4705
+ render() {
4706
+ return $`
4707
+ <div class="content" part="content">
4708
+ <slot></slot>
4709
+ </div>
4710
+ <div class="overlay" part="overlay"></div>
4711
+ `;
4712
+ }
4713
+
4714
+ isMobile() {
4715
+ const mediaQuery = window.matchMedia(`(max-width: ${this.breakpoint})`);
4716
+ this.mobile = mediaQuery.matches;
4717
+ }
4718
+
4719
+ handleFocusableDown(event) {
4720
+ const firstFocusable = this.focusableElements[0];
4721
+ const lastFocusable = this.focusableElements[this.focusableElements.length - 1];
4722
+
4723
+ if (event.key === 'Tab') {
4724
+ if (event.shiftKey && document.activeElement === firstFocusable) {
4725
+ event.preventDefault();
4726
+ lastFocusable.focus();
4727
+ } else if (!event.shiftKey && document.activeElement === lastFocusable) {
4728
+ event.preventDefault();
4729
+ firstFocusable.focus();
4730
+ }
4731
+ }
4732
+ }
4733
+ }
4734
+
4735
+ // eslint-disable-next-line no-unused-expressions
4736
+ customElements.get('kemet-modal') || customElements.define('kemet-modal', KemetModal);
4737
+
4738
+ class KemetPassword extends s$1 {
4739
+ static get styles() {
4740
+ return [
4741
+ r$3`
4742
+ :host {
4743
+ color: inherit;
4744
+ display: none;
4745
+ }
4746
+
4747
+ :host([show]) {
4748
+ display: block;
4749
+ }
4750
+
4751
+ p {
4752
+ margin: 1.6rem 0;
4753
+ }
4754
+
4755
+ .status {
4756
+ display: grid;
4757
+ align-items: center;
4758
+ grid-template-columns: 1fr auto;
4759
+ line-height: 1;
4760
+ margin-top: 0.8rem;
4761
+ }
4762
+
4763
+ .status > span {
4764
+ text-transform: capitalize;
4765
+ }
4766
+
4767
+ .status--weak,
4768
+ .status--better {
4769
+ color: var(--kemet-color-error);
4770
+ }
4771
+
4772
+ .status--strong {
4773
+ color: var(--kemet-color-success);
4774
+ }
4775
+
4776
+ .indicator {
4777
+ display: flex;
4778
+ gap: 0.4rem;
4779
+ margin: 0;
4780
+ list-style: none;
4781
+ }
4782
+
4783
+ .indicator li {
4784
+ width: 1.6rem;
4785
+ height: 0.2rem;
4786
+ background-color: var(--fds-color--gray2);
4787
+ }
4788
+
4789
+ .status--weak .indicator li:nth-child(1) {
4790
+ background-color: var(--kemet-color-error);
4791
+ }
4792
+
4793
+ .status--better .indicator li:nth-child(1),
4794
+ .status--better .indicator li:nth-child(2) {
4795
+ background-color: var(--kemet-color-error);
4796
+ }
4797
+
4798
+ .status--strong .indicator li {
4799
+ background-color: var(--kemet-color-success);
4800
+ }
4801
+
4802
+ .rules {
4803
+ color: var(--kemet-color-primary);
4804
+ list-style: none;
4805
+ font-size: 90%;
4806
+ padding-left: 2rem;
4807
+ }
4808
+
4809
+ .rules li {
4810
+ position: relative;
4811
+ }
4812
+
4813
+ .rules kemet-icon {
4814
+ color: var(--kemet-color-success);
4815
+ position: absolute;
4816
+ left: -2.4rem;
4817
+ }
4818
+ `,
4819
+ ];
4820
+ }
4821
+
4822
+ static get properties() {
4823
+ return {
4824
+ /**
4825
+ * An array of objects containing the rules the password must meet
4826
+ */
4827
+ rules: {
4828
+ type: Array,
4829
+ },
4830
+ /**
4831
+ * Controls the display of the component
4832
+ */
4833
+ show: {
4834
+ type: Boolean,
4835
+ reflect: true,
4836
+ },
4837
+ /**
4838
+ * The value of the input component
4839
+ */
4840
+ value: {
4841
+ type: String,
4842
+ },
4843
+ /**
4844
+ * A message that is above the rules
4845
+ */
4846
+ message: {
4847
+ type: String,
4848
+ },
4849
+ /**
4850
+ * The strength of the password. Weak | Better | Strong
4851
+ */
4852
+ strength: {
4853
+ type: String,
4854
+ },
4855
+ icon: {
4856
+ type: String,
4857
+ },
4858
+ iconSize: {
4859
+ type: Number,
4860
+ },
4861
+ };
4862
+ }
4863
+
4864
+ constructor() {
4865
+ super();
4866
+
4867
+ // managed properties
4868
+ this.rules = [
4869
+ { pattern: '(?=.{8,}$)', message: 'At least 8 characters long' },
4870
+ { pattern: '(?=.*[a-z])(?=.*[A-Z])', message: 'Uppercase and lowercase' },
4871
+ { pattern: '(?=.*[0-9])', message: 'At least one number (0-9)' },
4872
+ ];
4873
+ this.message = 'Please make sure you meet all the requirements.';
4874
+ this.icon = 'check2';
4875
+ this.iconSize = 16;
4876
+ }
4877
+
4878
+ firstUpdated() {
4879
+ // standard properties
4880
+ this.field = this.closest('kemet-field');
4881
+ this.input = this.field.querySelector('[slot="input"]');
4882
+
4883
+ // managed properties
4884
+ this.slug = this.field.slug;
4885
+
4886
+ // events listeners
4887
+ this.input.addEventListener('kemet-input-input', this.handleInput.bind(this));
4888
+ }
4889
+
4890
+ render() {
4891
+ return $`
4892
+ <div role="alert" aria-live="assertive">
4893
+ <div class="status status--${this.strength}" part="status">
4894
+ <span>${this.strength}</span>
4895
+ <ul class="indicator" part="indicator">
4896
+ <li></li>
4897
+ <li></li>
4898
+ <li></li>
4899
+ </ul>
4900
+ </div>
4901
+ <p class="message" part="message">${this.message}</p>
4902
+ <ul class="rules" part="rules">
4903
+ ${this.makeRules()}
4904
+ </ul>
4905
+ </div>
4906
+ `;
4907
+ }
4908
+
4909
+ /**
4910
+ * Makes the list of rules
4911
+ * @private
4912
+ * @returns {templateResults} the criteria rules
4913
+ */
4914
+ makeRules() {
4915
+ if (this.input) {
4916
+ const rules = this.rules.map((rule, index) => {
4917
+ const regExp = new RegExp(rule.pattern);
4918
+ const meetsCriteria = regExp.test(this.input.value);
4919
+ this.rules[index].meetsCriteria = meetsCriteria;
4920
+ return $`<li>${this.makeCheckIcon(meetsCriteria)} ${rule.message}</li>`;
4921
+ });
4922
+
4923
+ return rules;
4924
+ }
4925
+
4926
+ return null;
4927
+ }
4928
+
4929
+ /**
4930
+ * Makes the check icon if the criteria has been met
4931
+ * @param {boolean} meetsCriteria
4932
+ * @private
4933
+ * @returns {templateResults} an icon component
4934
+ */
4935
+ makeCheckIcon(meetsCriteria) {
4936
+ if (meetsCriteria) {
4937
+ return $`<kemet-icon icon=${this.icon} size=${this.iconSize}></kemet-icon>`;
4938
+ }
4939
+
4940
+ return null;
4941
+ }
4942
+
4943
+ /**
4944
+ * Handles the kemet-input-input event
4945
+ * @param {*} event
4946
+ * @private
4947
+ */
4948
+ handleInput(event) {
4949
+ this.value = event.detail;
4950
+ this.setStrength();
4951
+ this.visibility();
4952
+ }
4953
+
4954
+ /**
4955
+ * Determines the strength of the password
4956
+ * @private
4957
+ */
4958
+ setStrength() {
4959
+ // We use a setTimeout here because makeRules adds the meetsCriteria
4960
+ // property to the rules. We need that to be set by render() before
4961
+ // setting the Strength because the percentage calc is based on it
4962
+ setTimeout(() => {
4963
+ const totalRules = this.rules.length;
4964
+ const metRules = this.rules.filter(rule => rule.meetsCriteria).length;
4965
+ const metRulesPercentage = Math.round((metRules / totalRules) * 100) / 100;
4966
+
4967
+ if (metRulesPercentage <= 0.33) {
4968
+ this.strength = 'weak';
4969
+ this.status = 'error';
4970
+ }
4971
+
4972
+ if (metRulesPercentage > 0.33 && metRulesPercentage <= 0.67) {
4973
+ this.strength = 'better';
4974
+ this.status = 'error';
4975
+ }
4976
+
4977
+ if (metRulesPercentage > 0.67) {
4978
+ this.strength = 'strong';
4979
+ this.status = 'success';
4980
+ }
3614
4981
 
3615
- if (prevProps.get('opened') && this.opened === false) {
3616
4982
  /**
3617
- * Fires when the modal closes
4983
+ * Fires when there's a change in status.
3618
4984
  */
3619
4985
  this.dispatchEvent(
3620
- new CustomEvent('kemet-modal-closed', {
4986
+ new CustomEvent('kemet-password-status', {
3621
4987
  bubbles: true,
3622
4988
  composed: true,
3623
- detail: this,
4989
+ detail: {
4990
+ status: this.status,
4991
+ validity: { meetsPasswordCriteria: this.status === 'success' },
4992
+ element: this,
4993
+ },
3624
4994
  }),
3625
4995
  );
3626
- }
3627
-
3628
- this.isMobile();
3629
- }
3630
-
3631
- render() {
3632
- return $`
3633
- <div class="content" part="content">
3634
- <slot></slot>
3635
- </div>
3636
- <div class="overlay" part="overlay"></div>
3637
- `;
3638
- }
3639
-
3640
- isMobile() {
3641
- const mediaQuery = window.matchMedia(`(max-width: ${this.breakpoint})`);
3642
- this.mobile = mediaQuery.matches;
4996
+ }, 1);
3643
4997
  }
3644
4998
 
3645
- handleFocusableDown(event) {
3646
- const firstFocusable = this.focusableElements[0];
3647
- const lastFocusable = this.focusableElements[this.focusableElements.length - 1];
3648
-
3649
- if (event.key === 'Tab') {
3650
- if (event.shiftKey && document.activeElement === firstFocusable) {
3651
- event.preventDefault();
3652
- lastFocusable.focus();
3653
- } else if (!event.shiftKey && document.activeElement === lastFocusable) {
3654
- event.preventDefault();
3655
- firstFocusable.focus();
3656
- }
4999
+ /**
5000
+ * Determines whether to show or hide the component
5001
+ * @private
5002
+ */
5003
+ visibility() {
5004
+ if (this.value.length > 0) {
5005
+ this.show = true;
5006
+ } else {
5007
+ this.show = false;
3657
5008
  }
3658
5009
  }
3659
5010
  }
3660
5011
 
3661
5012
  // eslint-disable-next-line no-unused-expressions
3662
- customElements.get('kemet-modal') || customElements.define('kemet-modal', KemetModal);
5013
+ customElements.get('kemet-password') || customElements.define('kemet-password', KemetPassword);
3663
5014
 
3664
5015
  const keyCodes$1 = {
3665
5016
  ENTER: 13,
@@ -7903,6 +9254,324 @@ class KemetToggle extends s$1 {
7903
9254
  // eslint-disable-next-line no-unused-expressions
7904
9255
  customElements.get('kemet-toggle') || customElements.define('kemet-toggle', KemetToggle);
7905
9256
 
9257
+ class KemetTrackerStep extends s$1 {
9258
+ static get styles() {
9259
+ return [
9260
+ r$3`
9261
+ :host {
9262
+ --kemet-tracker-step-dot-size: 50px;
9263
+ --kemet-tracker-step-dot-size-mobile: 25px;
9264
+ --kemet-tracker-step-dot-gap: 4px;
9265
+ --kemet-tracker-step-standard-line-weight: 1px;
9266
+ --kemet-tracker-step-completed-line-weight: 3px;
9267
+ --kemet-tracker-step-dot-transition: all 300ms ease-in-out;
9268
+
9269
+ position: relative;
9270
+ width: 100%;
9271
+ text-align: center;
9272
+ }
9273
+
9274
+ .dot {
9275
+ font-size: var(--kemet-tracker-step-dot-font-size, 90%);
9276
+ color: var(--kemet-tracker-step-dot-color, var(--kemet-color-primary));
9277
+ display: flex;
9278
+ align-items: center;
9279
+ justify-content: center;
9280
+ margin: 0 auto;
9281
+ position: relative;
9282
+ z-index: 1;
9283
+ width: var(--kemet-tracker-step-dot-size);
9284
+ height: var(--kemet-tracker-step-dot-size);
9285
+ border-radius: 100%;
9286
+ transition: var(--kemet-tracker-step-dot-transition);
9287
+ background-color: var(--kemet-tracker-step-dot-background-color, var(--kemet-color-white));
9288
+ }
9289
+
9290
+ .dot::after {
9291
+ content: "";
9292
+ width: unset;
9293
+ height: unset;
9294
+ position: absolute;
9295
+ top: var(--kemet-tracker-step-dot-gap);
9296
+ left: var(--kemet-tracker-step-dot-gap);
9297
+ right: var(--kemet-tracker-step-dot-gap);
9298
+ bottom: var(--kemet-tracker-step-dot-gap);
9299
+ z-index: -1;
9300
+ border-radius: 100%;
9301
+ transition: var(--kemet-tracker-step-dot-transition);
9302
+ border: var(--kemet-tracker-step-dot-border, 1px solid var(--kemet-color-primary));
9303
+ background-color: var(--kemet-tracker-step-dot-fill-color, transparent);
9304
+ }
9305
+
9306
+ :host([completed]) .dot {
9307
+ color: var(--kemet-tracker-step-completed-color, var(--kemet-color-white));
9308
+ }
9309
+
9310
+ :host([completed]) .dot::after {
9311
+ border: 0;
9312
+ background-color: var(--kemet-tracker-step-completed-fill-color, var(--kemet-color-success));
9313
+ }
9314
+
9315
+ :host([current]) .dot.animate {
9316
+ color: var(--kemet-tracker-step-current-color, var(--kemet-color-white));
9317
+ }
9318
+
9319
+ :host([current]) .dot.animate::after {
9320
+ border: 0;
9321
+ background-color: var(--kemet-tracker-step-current-fill-color, var(--kemet-color-primary));
9322
+ }
9323
+
9324
+ :host([mobile]) .dot {
9325
+ width: var(--kemet-tracker-step-dot-size-mobile);
9326
+ height: var(--kemet-tracker-step-dot-size-mobile);
9327
+ }
9328
+
9329
+ .line {
9330
+ display: block;
9331
+ position: absolute;
9332
+ left: 50%;
9333
+ right: 0;
9334
+ bottom: 0;
9335
+ width: 100%;
9336
+
9337
+ /* standard */
9338
+ top: calc((var(--kemet-tracker-step-dot-size) - var(--kemet-tracker-step-standard-line-weight)) / 2);
9339
+ height: var(--kemet-tracker-step-standard-line-weight);
9340
+ background-color: var(--kemet-tracker-step-line-color, var(--kemet-color-primary));
9341
+ }
9342
+
9343
+ .line.completed {
9344
+ width: 100%;
9345
+ transform: scaleX(0);
9346
+ transform-origin: left center;
9347
+ top: calc((var(--kemet-tracker-step-dot-size) - var(--kemet-tracker-step-completed-line-weight)) / 2);
9348
+ height: var(--kemet-tracker-step-completed-line-weight);
9349
+ background-color: var(--kemet-tracker-step-completed-line-color, var(--kemet-color-primary));
9350
+ animation-name: grow;
9351
+ animation-delay: 1s;
9352
+ animation-duration: 600ms;
9353
+ animation-fill-mode: forwards;
9354
+ }
9355
+
9356
+ :host([mobile]) .line {
9357
+ top: calc((var(--kemet-tracker-step-dot-size-mobile) - var(--kemet-tracker-step-standard-line-weight)) / 2);
9358
+ }
9359
+
9360
+ :host([mobile]) .line.completed {
9361
+ top: calc((var(--kemet-tracker-step-dot-size-mobile) - var(--kemet-tracker-step-completed-line-weight)) / 2);
9362
+ }
9363
+
9364
+ @keyframes grow {
9365
+ from { transform: scaleX(0); }
9366
+ to { transform: scaleX(1); }
9367
+ }
9368
+ `,
9369
+ ];
9370
+ }
9371
+
9372
+ static get properties() {
9373
+ return {
9374
+ /**
9375
+ * The current step number
9376
+ */
9377
+ step: {
9378
+ type: Number,
9379
+ },
9380
+ /**
9381
+ * Determines whether or not a step renders as complete
9382
+ */
9383
+ completed: {
9384
+ type: Boolean,
9385
+ reflect: true,
9386
+ },
9387
+ /**
9388
+ * Determines whether or not a step renders as the current step
9389
+ */
9390
+ current: {
9391
+ type: Boolean,
9392
+ reflect: true,
9393
+ },
9394
+ /**
9395
+ * Is automatically added to the last step
9396
+ */
9397
+ last: {
9398
+ type: Boolean,
9399
+ reflect: true,
9400
+ },
9401
+ /**
9402
+ * Determines if a step should render as mobile
9403
+ */
9404
+ mobile: {
9405
+ type: Boolean,
9406
+ reflect: true,
9407
+ },
9408
+ /**
9409
+ * Hides the label inside of a dot
9410
+ */
9411
+ hideDotContent: {
9412
+ type: Boolean,
9413
+ reflect: true,
9414
+ attribute: 'hide-dot-content',
9415
+ },
9416
+ /**
9417
+ * The icon size for the completed check mark
9418
+ */
9419
+ completedSize: {
9420
+ type: Number,
9421
+ },
9422
+ };
9423
+ }
9424
+
9425
+ constructor() {
9426
+ super();
9427
+ this.completedSize = 16;
9428
+ }
9429
+
9430
+ firstUpdated() {
9431
+ this.tracker = this.closest('kemet-tracker');
9432
+ }
9433
+
9434
+ render() {
9435
+ return $`
9436
+ ${this.makeLine()}
9437
+ ${this.makeCompletedLine()}
9438
+ <div class="dot" part="dot">${this.makeDotContent()}</div>
9439
+ ${this.makeSlotContent()}
9440
+ `;
9441
+ }
9442
+
9443
+ makeLine() {
9444
+ if (!this.last) {
9445
+ return $`<div class="line" part="line"></div>`;
9446
+ }
9447
+
9448
+ return null;
9449
+ }
9450
+
9451
+ makeCompletedLine() {
9452
+ if (this.completed && !this.last) {
9453
+ return $`<div class="line completed" part="completed-line" @animationend=${() => this.handleCompletedLineEnd()}></div>`;
9454
+ }
9455
+
9456
+ return null;
9457
+ }
9458
+
9459
+ makeDotContent() {
9460
+ if (this.completed && !this.mobile && !this.hideDotContent) {
9461
+ return $`
9462
+ <kemet-icon icon="check2" size=${this.completedSize}></kemet-icon>
9463
+ `;
9464
+ }
9465
+
9466
+ if (!this.mobile && !this.hideDotContent) {
9467
+ return $`
9468
+ <span>${this.step}/${this.tracker?.total}</span>
9469
+ `;
9470
+ }
9471
+
9472
+ return null;
9473
+ }
9474
+
9475
+ makeSlotContent() {
9476
+ if (!this.mobile) {
9477
+ return $`<slot></slot>`;
9478
+ }
9479
+
9480
+ return null;
9481
+ }
9482
+
9483
+ handleCompletedLineEnd() {
9484
+ const currentDot = this.tracker.querySelector('[current]').shadowRoot.querySelector('.dot');
9485
+
9486
+ if (currentDot) {
9487
+ currentDot.classList.add('animate');
9488
+ }
9489
+ }
9490
+ }
9491
+
9492
+ // eslint-disable-next-line no-unused-expressions
9493
+ customElements.get('kemet-tracker-step') || customElements.define('kemet-tracker-step', KemetTrackerStep);
9494
+
9495
+ class KemetTracker extends s$1 {
9496
+ static get styles() {
9497
+ return [
9498
+ r$3`
9499
+ :host {
9500
+ display: flex;
9501
+ justify-content: center;
9502
+ align-items: flex-start;
9503
+ }
9504
+ `,
9505
+ ];
9506
+ }
9507
+
9508
+ static get properties() {
9509
+ return {
9510
+ /**
9511
+ * The total number of steps
9512
+ */
9513
+ total: {
9514
+ type: Number,
9515
+ },
9516
+ /**
9517
+ * The point at which the tracker goes from mobile to standard
9518
+ */
9519
+ breakpoint: {
9520
+ type: String,
9521
+ },
9522
+ };
9523
+ }
9524
+
9525
+ constructor() {
9526
+ super();
9527
+ this.breakpoint = '767px';
9528
+ }
9529
+
9530
+ firstUpdated() {
9531
+ // elements
9532
+ this.steps = this.querySelectorAll('kemet-tracker-step');
9533
+
9534
+ // methods exe
9535
+ this.isMobile();
9536
+
9537
+ // events
9538
+ window.addEventListener('resize', () => {
9539
+ this.isMobile();
9540
+ });
9541
+ }
9542
+
9543
+ render() {
9544
+ return $`<slot @slotchange=${() => this.handleSlotChange()}></slot>`;
9545
+ }
9546
+
9547
+ handleSlotChange() {
9548
+ this.total = this.steps.length;
9549
+
9550
+ this.steps.forEach((step, index) => {
9551
+ step.step = index + 1;
9552
+ if (step.step === this.total) {
9553
+ step.last = true;
9554
+ }
9555
+ });
9556
+ }
9557
+
9558
+ isMobile() {
9559
+ const mediaQuery = window.matchMedia(`(max-width: ${this.breakpoint})`);
9560
+
9561
+ this.steps.forEach((step) => {
9562
+ step.mobile = mediaQuery.matches;
9563
+ });
9564
+ }
9565
+ }
9566
+
9567
+ // eslint-disable-next-line no-unused-expressions
9568
+ customElements.get('kemet-tracker') || customElements.define('kemet-tracker', KemetTracker);
9569
+
9570
+ exports.KemetCarouselCurrent = KemetCarouselCurrent;
9571
+ exports.KemetCarouselFirst = KemetCarouselFirst;
9572
+ exports.KemetCarouselLast = KemetCarouselLast;
9573
+ exports.KemetCarouselPrev = KemetCarouselPrev;
9574
+ exports.KemetCarouselTotal = KemetCarouselTotal;
7906
9575
  exports.customTooltip = customTooltip;
7907
9576
  exports.fade = fade;
7908
9577
  exports.fall = fall;