kemet-ui 5.0.0 → 5.0.2

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 (147) hide show
  1. package/README.md +1 -1
  2. package/custom-elements.json +3355 -3272
  3. package/dist/{constants-W9QKPlZP.d.ts → constants-CHvA2ed5.d.ts} +13 -0
  4. package/dist/elements/accordion/index.d.ts +1 -0
  5. package/dist/elements/accordion/index.js +5 -1
  6. package/dist/elements/accordion/index.js.map +1 -1
  7. package/dist/elements/accordion-panel/index.d.ts +1 -0
  8. package/dist/elements/accordion-panel/index.js +5 -1
  9. package/dist/elements/accordion-panel/index.js.map +1 -1
  10. package/dist/elements/alert/index.d.ts +2 -1
  11. package/dist/elements/alert/index.js +5 -1
  12. package/dist/elements/alert/index.js.map +1 -1
  13. package/dist/elements/avatar/index.d.ts +2 -1
  14. package/dist/elements/avatar/index.js +5 -1
  15. package/dist/elements/avatar/index.js.map +1 -1
  16. package/dist/elements/avatars/index.d.ts +1 -0
  17. package/dist/elements/avatars/index.js +5 -1
  18. package/dist/elements/avatars/index.js.map +1 -1
  19. package/dist/elements/badge/index.d.ts +2 -1
  20. package/dist/elements/badge/index.js +5 -1
  21. package/dist/elements/badge/index.js.map +1 -1
  22. package/dist/elements/button/index.d.ts +2 -1
  23. package/dist/elements/button/index.js +5 -1
  24. package/dist/elements/button/index.js.map +1 -1
  25. package/dist/elements/card/index.d.ts +2 -1
  26. package/dist/elements/card/index.js +5 -1
  27. package/dist/elements/card/index.js.map +1 -1
  28. package/dist/elements/checkbox/index.d.ts +2 -1
  29. package/dist/elements/checkbox/index.js +7 -1
  30. package/dist/elements/checkbox/index.js.map +1 -1
  31. package/dist/elements/combo/index.d.ts +1 -1
  32. package/dist/elements/combo/index.js +5 -1
  33. package/dist/elements/combo/index.js.map +1 -1
  34. package/dist/elements/count/index.d.ts +1 -1
  35. package/dist/elements/count/index.js +28 -1
  36. package/dist/elements/count/index.js.map +1 -1
  37. package/dist/elements/dialog/index.d.ts +2 -1
  38. package/dist/elements/dialog/index.js +5 -1
  39. package/dist/elements/dialog/index.js.map +1 -1
  40. package/dist/elements/dialog-close/index.d.ts +1 -0
  41. package/dist/elements/dialog-close/index.js +5 -1
  42. package/dist/elements/dialog-close/index.js.map +1 -1
  43. package/dist/elements/drawer/effects.js +1 -1
  44. package/dist/elements/drawer/effects.js.map +1 -1
  45. package/dist/elements/drawer/index.d.ts +1 -0
  46. package/dist/elements/drawer/index.js +6 -2
  47. package/dist/elements/drawer/index.js.map +1 -1
  48. package/dist/elements/fab/index.d.ts +2 -1
  49. package/dist/elements/fab/index.js +5 -1
  50. package/dist/elements/fab/index.js.map +1 -1
  51. package/dist/elements/field/index.d.ts +1 -1
  52. package/dist/elements/field/index.js +5 -1
  53. package/dist/elements/field/index.js.map +1 -1
  54. package/dist/elements/flipcard/index.d.ts +2 -1
  55. package/dist/elements/flipcard/index.js +5 -1
  56. package/dist/elements/flipcard/index.js.map +1 -1
  57. package/dist/elements/flipcard-trigger/index.d.ts +1 -0
  58. package/dist/elements/flipcard-trigger/index.js +5 -1
  59. package/dist/elements/flipcard-trigger/index.js.map +1 -1
  60. package/dist/elements/icon/index.d.ts +2 -1
  61. package/dist/elements/icon/index.js +8 -2
  62. package/dist/elements/icon/index.js.map +1 -1
  63. package/dist/elements/input/index.d.ts +1 -1
  64. package/dist/elements/input/index.js +9 -3
  65. package/dist/elements/input/index.js.map +1 -1
  66. package/dist/elements/input/styles.css.js +2 -2
  67. package/dist/elements/input/styles.css.js.map +1 -1
  68. package/dist/elements/input-combo/index.d.ts +2 -1
  69. package/dist/elements/input-combo/index.js +7 -1
  70. package/dist/elements/input-combo/index.js.map +1 -1
  71. package/dist/elements/input-file/index.d.ts +1 -1
  72. package/dist/elements/input-file/index.js +39 -249
  73. package/dist/elements/input-file/index.js.map +1 -1
  74. package/dist/elements/input-file/styles.css.js +8 -8
  75. package/dist/elements/input-file/styles.css.js.map +1 -1
  76. package/dist/elements/input-files/index.d.ts +1 -1
  77. package/dist/elements/input-files/index.js +29 -237
  78. package/dist/elements/input-files/index.js.map +1 -1
  79. package/dist/elements/input-files/styles.css.js +2 -2
  80. package/dist/elements/input-files/styles.css.js.map +1 -1
  81. package/dist/elements/input-otp/index.d.ts +1 -0
  82. package/dist/elements/input-otp/index.js +5 -1
  83. package/dist/elements/input-otp/index.js.map +1 -1
  84. package/dist/elements/loader/index.d.ts +1 -0
  85. package/dist/elements/loader/index.js +5 -1
  86. package/dist/elements/loader/index.js.map +1 -1
  87. package/dist/elements/password/index.d.ts +2 -2
  88. package/dist/elements/password/index.js +24 -234
  89. package/dist/elements/password/index.js.map +1 -1
  90. package/dist/elements/radio/index.d.ts +1 -0
  91. package/dist/elements/radio/index.js +7 -1
  92. package/dist/elements/radio/index.js.map +1 -1
  93. package/dist/elements/radios/index.d.ts +2 -1
  94. package/dist/elements/radios/index.js +5 -1
  95. package/dist/elements/radios/index.js.map +1 -1
  96. package/dist/elements/rotator/index.d.ts +1 -0
  97. package/dist/elements/rotator/index.js +7 -2
  98. package/dist/elements/rotator/index.js.map +1 -1
  99. package/dist/elements/select/index.d.ts +2 -1
  100. package/dist/elements/select/index.js +28 -25
  101. package/dist/elements/select/index.js.map +1 -1
  102. package/dist/elements/select-option/index.d.ts +1 -0
  103. package/dist/elements/select-option/index.js +7 -1
  104. package/dist/elements/select-option/index.js.map +1 -1
  105. package/dist/elements/sortable/index.d.ts +1 -0
  106. package/dist/elements/sortable/index.js +7 -1
  107. package/dist/elements/sortable/index.js.map +1 -1
  108. package/dist/elements/sortable-item/index.d.ts +1 -0
  109. package/dist/elements/sortable-item/index.js +5 -1
  110. package/dist/elements/sortable-item/index.js.map +1 -1
  111. package/dist/elements/tab/index.d.ts +1 -1
  112. package/dist/elements/tab/index.js +18 -228
  113. package/dist/elements/tab/index.js.map +1 -1
  114. package/dist/elements/tab-panel/index.d.ts +1 -0
  115. package/dist/elements/tab-panel/index.js +5 -1
  116. package/dist/elements/tab-panel/index.js.map +1 -1
  117. package/dist/elements/tabs/index.d.ts +3 -2
  118. package/dist/elements/tabs/index.js +44 -246
  119. package/dist/elements/tabs/index.js.map +1 -1
  120. package/dist/elements/textarea/index.d.ts +1 -1
  121. package/dist/elements/textarea/index.js +9 -3
  122. package/dist/elements/textarea/index.js.map +1 -1
  123. package/dist/elements/textarea/styles.css.js +2 -2
  124. package/dist/elements/textarea/styles.css.js.map +1 -1
  125. package/dist/elements/timer/index.d.ts +1 -0
  126. package/dist/elements/timer/index.js +11 -7
  127. package/dist/elements/timer/index.js.map +1 -1
  128. package/dist/elements/timer-display/index.d.ts +1 -1
  129. package/dist/elements/timer-display/index.js +19 -16
  130. package/dist/elements/timer-display/index.js.map +1 -1
  131. package/dist/elements/toggle/index.d.ts +1 -0
  132. package/dist/elements/toggle/index.js +5 -1
  133. package/dist/elements/toggle/index.js.map +1 -1
  134. package/dist/elements/tracker/index.d.ts +1 -2
  135. package/dist/elements/tracker/index.js +10 -19
  136. package/dist/elements/tracker/index.js.map +1 -1
  137. package/dist/elements/tracker-step/index.d.ts +1 -2
  138. package/dist/elements/tracker-step/index.js +46 -240
  139. package/dist/elements/tracker-step/index.js.map +1 -1
  140. package/dist/elements/typewriter/index.d.ts +1 -0
  141. package/dist/elements/typewriter/index.js +7 -1
  142. package/dist/elements/typewriter/index.js.map +1 -1
  143. package/dist/{index-h1DTXXCf.d.ts → index-n43o0UmE.d.ts} +13 -7
  144. package/dist/wrappers/react.d.ts +2 -2
  145. package/dist/wrappers/react.js +489 -491
  146. package/dist/wrappers/react.js.map +1 -1
  147. package/package.json +2 -3
@@ -1,7 +1,6 @@
1
1
  import * as lit from 'lit';
2
2
  import { LitElement, TemplateResult } from 'lit';
3
- import { E as EnumAppearances, H as HTMLKemetFieldElement, c as HTMLKemetInputElement, f as HTMLKemetTextareaElement } from '../../constants-W9QKPlZP.js';
4
- import '../icon/index.js';
3
+ import { E as EnumAppearances, H as HTMLKemetFieldElement, c as HTMLKemetInputElement, f as HTMLKemetTextareaElement } from '../../constants-CHvA2ed5.js';
5
4
  import 'lit-html';
6
5
  import '../../form-controller-3q581XcZ.js';
7
6
 
@@ -21,6 +20,7 @@ interface InterfacePasswordStrengthChangeDetails {
21
20
  *
22
21
  * @tagname kemet-password
23
22
  * @summary Gauges the strength of a password entered by the user.
23
+ * @ssrsafe yes
24
24
  *
25
25
  * @prop {array} rules - An array of objects containing the rules the password must meet.
26
26
  * @prop {boolean} show - Controls the display of the component.
@@ -10,8 +10,12 @@ var __decorateClass = (decorators, target, key, kind) => {
10
10
  };
11
11
 
12
12
  // src/elements/password/index.ts
13
- import { html as html2, LitElement as LitElement2 } from "lit";
14
- import { customElement as customElement2, property as property2, state as state2 } from "lit/decorators.js";
13
+ import { html, LitElement } from "lit";
14
+
15
+ // src/utilities/decorators.ts
16
+ import { property, state, query, queryAll } from "lit/decorators.js";
17
+ import { customElement as litCustomElement } from "lit/decorators.js";
18
+ var customElement = (tagName) => (classOrDescriptor) => typeof customElements !== "undefined" && !customElements.get(tagName) ? litCustomElement(tagName)(classOrDescriptor) : classOrDescriptor;
15
19
 
16
20
  // src/utilities/events.ts
17
21
  var emitEvent = (element, name, detail, bubbles = true, composed = true) => {
@@ -20,223 +24,9 @@ var emitEvent = (element, name, detail, bubbles = true, composed = true) => {
20
24
  );
21
25
  };
22
26
 
23
- // src/elements/icon/index.ts
24
- import { html, LitElement } from "lit";
25
- import { customElement, property, state } from "lit/decorators.js";
26
- import { isTemplateResult } from "lit/directive-helpers.js";
27
-
28
- // src/elements/icon/styles.css.ts
27
+ // src/elements/password/styles.css.ts
29
28
  import { css } from "lit";
30
29
  var styles_css_default = css`:host {
31
- display: inline-flex;
32
- align-items: center;
33
- justify-content: center;
34
- color: inherit;
35
- }
36
- `;
37
-
38
- // src/elements/icon/index.ts
39
- var CACHEABLE_ERROR = /* @__PURE__ */ Symbol();
40
- var RETRYABLE_ERROR = /* @__PURE__ */ Symbol();
41
- var parser;
42
- var iconCache = /* @__PURE__ */ new Map();
43
- var MAX_CONCURRENT_REQUESTS = 10;
44
- var requestQueue = [];
45
- var activeRequests = 0;
46
- function queueRequest(callback) {
47
- if (activeRequests < MAX_CONCURRENT_REQUESTS) {
48
- activeRequests++;
49
- callback();
50
- } else {
51
- requestQueue.push(callback);
52
- }
53
- }
54
- function requestComplete() {
55
- activeRequests--;
56
- if (requestQueue.length > 0) {
57
- const nextRequest = requestQueue.shift();
58
- if (nextRequest) {
59
- activeRequests++;
60
- nextRequest();
61
- }
62
- }
63
- }
64
- var KemetIcon = class extends LitElement {
65
- constructor() {
66
- super(...arguments);
67
- this.name = "house";
68
- this.library = "bootstrap";
69
- this.family = "regular";
70
- this.size = 16;
71
- this.dom = "initializing";
72
- this.svg = null;
73
- this.url = "https://unpkg.com/bootstrap-icons@latest/icons";
74
- /** @internal */
75
- this.isVisible = false;
76
- }
77
- connectedCallback() {
78
- super.connectedCallback();
79
- this.updateUrl();
80
- if (!this.svg) {
81
- this.isVisible = true;
82
- this.setIcon();
83
- }
84
- }
85
- updated() {
86
- this.updateUrl();
87
- this.updateSize();
88
- }
89
- firstUpdated() {
90
- emitEvent(this, "kemet-icon-mounted", {
91
- bubbles: true,
92
- composed: true,
93
- detail: {
94
- element: this
95
- }
96
- });
97
- this.dom = "mounted";
98
- }
99
- render() {
100
- if (this.svg) {
101
- return this.svg;
102
- }
103
- if (!this.isVisible) {
104
- this.isVisible = true;
105
- this.setIcon();
106
- }
107
- return html`<svg part="svg" width="${this.size}" height="${this.size}" viewBox="0 0 16 16"></svg>`;
108
- }
109
- /** Public method to force icon loading */
110
- loadIcon() {
111
- this.isVisible = true;
112
- this.setIcon();
113
- }
114
- async setIcon() {
115
- if (!this.isVisible) return;
116
- let iconResolver = iconCache.get(`${this.family}/${this.name}`);
117
- if (!iconResolver) {
118
- iconResolver = this.resolveIcon();
119
- iconCache.set(`${this.family}/${this.name}`, iconResolver);
120
- }
121
- const svg = await iconResolver;
122
- if (svg === RETRYABLE_ERROR) {
123
- iconCache.delete(`${this.family}/${this.name}`);
124
- }
125
- if (isTemplateResult(svg)) {
126
- this.svg = svg;
127
- } else if (svg instanceof SVGSVGElement) {
128
- this.svg = svg.cloneNode(true);
129
- }
130
- }
131
- updateUrl() {
132
- switch (this.library) {
133
- case "fontawesome" /* FONTAWESOME */:
134
- this.version = this.version || "7.3.1";
135
- this.url = `https://unpkg.com/@fortawesome/fontawesome-free@${this.version}/svgs`;
136
- break;
137
- case "bootstrap" /* BOOTSTRAP */:
138
- this.version = this.version || "1.11.3";
139
- this.url = `https://unpkg.com/bootstrap-icons@${this.version}/icons`;
140
- break;
141
- }
142
- }
143
- async resolveIcon() {
144
- return new Promise((resolve) => {
145
- queueRequest(async () => {
146
- let fileData;
147
- let fetchURL = `${this.url}/${this.family}/${this.name}.svg`;
148
- switch (this.library) {
149
- case "fontawesome" /* FONTAWESOME */:
150
- fetchURL = `${this.url}/${this.family}/${this.name}.svg`;
151
- break;
152
- case "bootstrap" /* BOOTSTRAP */:
153
- fetchURL = `${this.url}/${this.name}.svg`;
154
- break;
155
- }
156
- try {
157
- fileData = await fetch(fetchURL);
158
- if (!fileData.ok) {
159
- requestComplete();
160
- resolve(fileData.status === 410 ? CACHEABLE_ERROR : RETRYABLE_ERROR);
161
- return;
162
- }
163
- } catch {
164
- requestComplete();
165
- resolve(RETRYABLE_ERROR);
166
- return;
167
- }
168
- try {
169
- const div = document.createElement("div");
170
- div.innerHTML = await fileData.text();
171
- const svg = div.firstElementChild;
172
- if (svg?.tagName?.toLowerCase() !== "svg") {
173
- requestComplete();
174
- resolve(CACHEABLE_ERROR);
175
- return;
176
- }
177
- if (!parser) parser = new DOMParser();
178
- const doc = parser.parseFromString(svg.outerHTML, "text/html");
179
- const svgEl = doc.body.querySelector("svg");
180
- if (!svgEl) {
181
- requestComplete();
182
- resolve(CACHEABLE_ERROR);
183
- return;
184
- }
185
- svgEl.part.add("svg");
186
- svgEl.setAttribute("width", `${this.size}px`);
187
- svgEl.setAttribute("height", `${this.size}px`);
188
- requestComplete();
189
- resolve(document.adoptNode(svgEl));
190
- } catch {
191
- requestComplete();
192
- resolve(CACHEABLE_ERROR);
193
- }
194
- });
195
- });
196
- }
197
- updateSize() {
198
- if (this.svg) {
199
- const svg = this.svg;
200
- svg.setAttribute("width", `${this.size}px`);
201
- svg.setAttribute("height", `${this.size}px`);
202
- }
203
- }
204
- };
205
- KemetIcon.styles = [styles_css_default];
206
- __decorateClass([
207
- property({ type: String })
208
- ], KemetIcon.prototype, "name", 2);
209
- __decorateClass([
210
- property({ type: String })
211
- ], KemetIcon.prototype, "library", 2);
212
- __decorateClass([
213
- property({ type: String })
214
- ], KemetIcon.prototype, "family", 2);
215
- __decorateClass([
216
- property({ type: Number })
217
- ], KemetIcon.prototype, "size", 2);
218
- __decorateClass([
219
- property({ type: String })
220
- ], KemetIcon.prototype, "version", 2);
221
- __decorateClass([
222
- property({ type: String, reflect: true })
223
- ], KemetIcon.prototype, "polarity", 2);
224
- __decorateClass([
225
- property({ type: String, reflect: true })
226
- ], KemetIcon.prototype, "dom", 2);
227
- __decorateClass([
228
- state()
229
- ], KemetIcon.prototype, "svg", 2);
230
- __decorateClass([
231
- state()
232
- ], KemetIcon.prototype, "url", 2);
233
- KemetIcon = __decorateClass([
234
- customElement("kemet-icon")
235
- ], KemetIcon);
236
-
237
- // src/elements/password/styles.css.ts
238
- import { css as css2 } from "lit";
239
- var styles_css_default2 = css2`:host {
240
30
  color: inherit;
241
31
  display: none;
242
32
  }
@@ -318,7 +108,7 @@ p {
318
108
  `;
319
109
 
320
110
  // src/elements/password/index.ts
321
- var KemetPassword = class extends LitElement2 {
111
+ var KemetPassword = class extends LitElement {
322
112
  constructor() {
323
113
  super(...arguments);
324
114
  this.rules = [
@@ -337,7 +127,7 @@ var KemetPassword = class extends LitElement2 {
337
127
  this.input?.addEventListener("kemet-input-input", this.handleInput.bind(this));
338
128
  }
339
129
  render() {
340
- return html2`
130
+ return html`
341
131
  <div role="alert" aria-live="assertive">
342
132
  <div class="${this.strength}" part="strength">
343
133
  <span>${this.strength}</span>
@@ -365,7 +155,7 @@ var KemetPassword = class extends LitElement2 {
365
155
  const regExp = new RegExp(rule.pattern);
366
156
  const meetsCriteria = regExp.test(this.input.value);
367
157
  rule.meetsCriteria = meetsCriteria;
368
- return html2`<li>${this.makeCheckIcon(meetsCriteria)} ${rule.message}</li>`;
158
+ return html`<li>${this.makeCheckIcon(meetsCriteria)} ${rule.message}</li>`;
369
159
  });
370
160
  }
371
161
  return [];
@@ -378,9 +168,9 @@ var KemetPassword = class extends LitElement2 {
378
168
  */
379
169
  makeCheckIcon(meetsCriteria) {
380
170
  if (meetsCriteria) {
381
- return html2`<kemet-icon name=${this.icon} size=${this.iconSize}></kemet-icon>`;
171
+ return html`<kemet-icon name=${this.icon} size=${this.iconSize}></kemet-icon>`;
382
172
  }
383
- return html2``;
173
+ return html``;
384
174
  }
385
175
  /**
386
176
  * Handles the kemet-input-input event
@@ -428,39 +218,39 @@ var KemetPassword = class extends LitElement2 {
428
218
  this.show = this.value.length > 0;
429
219
  }
430
220
  };
431
- KemetPassword.styles = [styles_css_default2];
221
+ KemetPassword.styles = [styles_css_default];
432
222
  __decorateClass([
433
- property2({ type: Array })
223
+ property({ type: Array })
434
224
  ], KemetPassword.prototype, "rules", 2);
435
225
  __decorateClass([
436
- property2({ type: Boolean, reflect: true })
226
+ property({ type: Boolean, reflect: true })
437
227
  ], KemetPassword.prototype, "show", 2);
438
228
  __decorateClass([
439
- property2({ type: String })
229
+ property({ type: String })
440
230
  ], KemetPassword.prototype, "value", 2);
441
231
  __decorateClass([
442
- property2({ type: String })
232
+ property({ type: String })
443
233
  ], KemetPassword.prototype, "message", 2);
444
234
  __decorateClass([
445
- property2({ type: String })
235
+ property({ type: String })
446
236
  ], KemetPassword.prototype, "strength", 2);
447
237
  __decorateClass([
448
- property2({ type: String })
238
+ property({ type: String })
449
239
  ], KemetPassword.prototype, "icon", 2);
450
240
  __decorateClass([
451
- property2({ type: Number })
241
+ property({ type: Number })
452
242
  ], KemetPassword.prototype, "iconSize", 2);
453
243
  __decorateClass([
454
- state2()
244
+ state()
455
245
  ], KemetPassword.prototype, "appearance", 2);
456
246
  __decorateClass([
457
- state2()
247
+ state()
458
248
  ], KemetPassword.prototype, "field", 2);
459
249
  __decorateClass([
460
- state2()
250
+ state()
461
251
  ], KemetPassword.prototype, "input", 2);
462
252
  KemetPassword = __decorateClass([
463
- customElement2("kemet-password")
253
+ customElement("kemet-password")
464
254
  ], KemetPassword);
465
255
  export {
466
256
  KemetPassword as default
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/elements/password/index.ts","../../../src/utilities/events.ts","../../../src/elements/icon/index.ts","../../../src/elements/icon/styles.css.ts","../../../src/elements/password/styles.css.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS, TemplateResult } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { emitEvent } from '../../utilities/events';\nimport { EnumAppearances } from '../../utilities/constants';\nimport HTMLKemetFieldElement from '../field';\nimport HTMLKemetInputElement from '../input';\nimport HTMLKemetTextareaElement from '../textarea';\nimport '../icon';\nimport styles from './styles.css.ts';\n\ninterface InterfaceOptions {\n pattern: string;\n message: string;\n meetsCriteria?: boolean;\n}\n\nexport interface InterfacePasswordStrengthChangeDetails {\n appearance: EnumAppearances;\n meetsPasswordCriteria: boolean;\n element: KemetPassword;\n}\n\n/**\n * @since 1.2.0\n * @status stable\n *\n * @tagname kemet-password\n * @summary Gauges the strength of a password entered by the user.\n *\n * @prop {array} rules - An array of objects containing the rules the password must meet.\n * @prop {boolean} show - Controls the display of the component.\n * @prop {string} value - The value of the input component.\n * @prop {string} message - A message that is above the rules.\n * @prop {string} strength - The strength of the password. Weak | Better | Strong.\n * @prop {string} icon\n * @prop {number} iconSize\n *\n * @event kemet-password-strength-change - Fires when there's a change in strength.\n *\n * @csspart strength - Indicates password strength.\n * @csspart indicator - The strength indicator bars.\n * @csspart message - A message to display to the user.\n * @csspart rules - A description of rules to follow.\n *\n */\n\n@customElement('kemet-password')\nexport default class KemetPassword extends LitElement {\n static styles = [styles];\n\n @property({ type: Array })\n rules: InterfaceOptions[] = [\n { pattern: '(?=.{8,}$)', message: 'At least 8 characters long' },\n { pattern: '(?=.*[a-z])(?=.*[A-Z])', message: 'Uppercase and lowercase' },\n { pattern: '(?=.*[0-9])', message: 'At least one number (0-9)' },\n ];\n\n @property({ type: Boolean, reflect: true })\n show: boolean = false;\n\n @property({ type: String })\n value!: string;\n\n @property({ type: String })\n message: string = 'Please make sure you meet all the requirements.';\n\n @property({ type: String })\n strength!: string;\n\n @property({ type: String })\n icon: string = 'check2';\n\n @property({ type: Number })\n iconSize: number = 18;\n\n @state()\n appearance?: EnumAppearances;\n\n @state()\n field!: HTMLKemetFieldElement;\n\n @state()\n input!: HTMLKemetInputElement | HTMLKemetTextareaElement;\n\n firstUpdated() {\n // elements\n this.field = this.closest('kemet-field') as HTMLKemetFieldElement;\n this.input = this.field.querySelector('[slot=\"input\"]') as HTMLKemetInputElement | HTMLKemetTextareaElement;\n\n // events listeners\n this.input?.addEventListener('kemet-input-input', this.handleInput.bind(this));\n }\n\n render() {\n return html`\n <div role=\"alert\" aria-live=\"assertive\">\n <div class=\"${this.strength}\" part=\"strength\">\n <span>${this.strength}</span>\n <ul part=\"indicator\">\n <li></li>\n <li></li>\n <li></li>\n </ul>\n </div>\n <p part=\"message\">${this.message}</p>\n <ul part=\"rules\">\n ${this.makeRules()}\n </ul>\n </div>\n `;\n }\n\n /**\n * Makes the list of rules\n * @private\n * @returns {TemplateResult<1>[]} the criteria rules\n */\n makeRules(): TemplateResult<1>[] {\n if (this.input) {\n return this.rules.map((rule) => {\n const regExp = new RegExp(rule.pattern);\n const meetsCriteria = regExp.test(this.input.value);\n rule.meetsCriteria = meetsCriteria;\n return html`<li>${this.makeCheckIcon(meetsCriteria)} ${rule.message}</li>`;\n });\n }\n\n return [];\n }\n\n /**\n * Makes the check icon if the criteria has been met\n * @param {boolean} meetsCriteria\n * @private\n * @returns {TemplateResult} an icon component\n */\n makeCheckIcon(meetsCriteria: boolean): TemplateResult {\n if (meetsCriteria) {\n return html`<kemet-icon name=${this.icon} size=${this.iconSize}></kemet-icon>`;\n }\n\n return html``;\n }\n\n /**\n * Handles the kemet-input-input event\n * @param {*} event\n * @private\n */\n handleInput(event: Event) {\n this.value = (event as CustomEvent).detail.value;\n this.setStrength();\n this.visibility();\n }\n\n /**\n * Determines the strength of the password\n * @private\n */\n setStrength() {\n // We use a setTimeout here because makeRules adds the meetsCriteria\n // property to the rules. We need that to be set by render() before\n // setting the Strength because the percentage calc is based on it\n setTimeout(() => {\n const totalRules = this.rules.length;\n const metRules = this.rules.filter(rule => rule.meetsCriteria).length;\n const metRulesPercentage = Math.round((metRules / totalRules) * 100) / 100;\n\n if (metRulesPercentage <= 0.33) {\n this.strength = 'weak';\n this.appearance = EnumAppearances.Error;\n }\n\n if (metRulesPercentage > 0.33 && metRulesPercentage <= 0.67) {\n this.strength = 'better';\n this.appearance = EnumAppearances.Error;\n }\n\n if (metRulesPercentage > 0.67) {\n this.strength = 'strong';\n this.appearance = EnumAppearances.Success;\n }\n\n emitEvent(this, 'kemet-password-strength-change', {\n appearance: this.appearance,\n meetsPasswordCriteria: this.appearance === EnumAppearances.Success,\n element: this,\n });\n }, 1);\n }\n\n /**\n * Determines whether to show or hide the component\n * @private\n */\n visibility() {\n this.show = this.value.length > 0;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kemet-password': KemetPassword\n }\n}\n","export const emitEvent = (element, name, detail, bubbles = true, composed = true) => {\n element.dispatchEvent(\n new CustomEvent(name, { bubbles, composed, detail }),\n );\n};\n","import { html, HTMLTemplateResult, LitElement, unsafeCSS } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { isTemplateResult } from 'lit/directive-helpers.js';\nimport { emitEvent } from '../../utilities/events';\nimport styles from './styles.css.ts';\n\nconst CACHEABLE_ERROR = Symbol();\nconst RETRYABLE_ERROR = Symbol();\ntype SVGResult = HTMLTemplateResult | SVGSVGElement | typeof RETRYABLE_ERROR | typeof CACHEABLE_ERROR;\n\nlet parser: DOMParser;\nconst iconCache = new Map<string, Promise<SVGResult>>();\n\n// Request queue with concurrency limit\nconst MAX_CONCURRENT_REQUESTS = 10;\nconst requestQueue: Array<() => void> = [];\nlet activeRequests = 0;\n\nfunction queueRequest(callback: () => void) {\n if (activeRequests < MAX_CONCURRENT_REQUESTS) {\n activeRequests++;\n callback();\n } else {\n requestQueue.push(callback);\n }\n}\n\nfunction requestComplete() {\n activeRequests--;\n if (requestQueue.length > 0) {\n const nextRequest = requestQueue.shift();\n if (nextRequest) {\n activeRequests++;\n nextRequest();\n }\n }\n}\n\nexport enum EnumLibrary {\n FONTAWESOME = 'fontawesome',\n BOOTSTRAP = 'bootstrap',\n}\n\n/**\n * @since 5.0.0\n * @status stable\n *\n * @tagname kemet-icon\n * @summary An element that represents an icon from a predefined set of open sourced icons.\n *\n * @prop {string} name - The name of the icon to reference.\n * @prop {string} library - The library of icons to use. Values include: (bootstrap | fontawesome)\n * @prop {string} family - The family of icons to use. The family is relative to the library being used. Font awesome values include: (regular | solid | brand)\n * @prop {string} version - The version of the icon library to use. Use latest to grab the most recent version.\n * @prop {number} size - The width and height of the icon in pixels.\n * @prop {'light' | 'dark'} polarity - Determines if the component has a dark or light background\n * @prop {string} dom - The status of dom initalization.\n *\n * @fires kemet-icon-mounted - Fired when the icon is mounted to the DOM\n * @detail {HTMLElement} element - The icon element\n *\n */\n\n@customElement('kemet-icon')\nexport default class KemetIcon extends LitElement {\n static styles = [styles];\n\n @property({ type: String })\n name: string = 'house';\n\n @property({ type: String })\n library: string = 'bootstrap';\n\n @property({ type: String })\n family: string = 'regular';\n\n @property({ type: Number })\n size: number = 16;\n\n @property({ type: String })\n version?: string;\n\n @property({ type: String, reflect: true })\n polarity?: 'light' | 'dark';\n\n @property({ type: String, reflect: true })\n dom: string = 'initializing';\n\n /** @internal */\n @state()\n private svg: SVGElement | HTMLTemplateResult | null = null;\n\n /** @internal */\n @state()\n private url: string = 'https://unpkg.com/bootstrap-icons@latest/icons';\n\n /** @internal */\n private isVisible: boolean = false;\n\n connectedCallback() {\n super.connectedCallback();\n // Load icon when connected to DOM\n this.updateUrl();\n if (!this.svg) {\n this.isVisible = true;\n this.setIcon();\n }\n }\n\n updated() {\n this.updateUrl();\n this.updateSize();\n }\n\n firstUpdated() {\n emitEvent(this, 'kemet-icon-mounted', {\n bubbles: true,\n composed: true,\n detail: {\n element: this,\n },\n });\n this.dom = 'mounted';\n }\n\n render() {\n // Return the svg if it's loaded, otherwise show placeholder\n if (this.svg) {\n return this.svg;\n }\n\n // If not loaded, trigger loading\n if (!this.isVisible) {\n this.isVisible = true;\n this.setIcon();\n }\n\n return html`<svg part=\"svg\" width=\"${this.size}\" height=\"${this.size}\" viewBox=\"0 0 16 16\"></svg>`;\n }\n\n /** Public method to force icon loading */\n public loadIcon() {\n this.isVisible = true;\n this.setIcon();\n }\n\n async setIcon() {\n if (!this.isVisible) return;\n\n let iconResolver = iconCache.get(`${this.family}/${this.name}`);\n\n if (!iconResolver) {\n iconResolver = this.resolveIcon();\n iconCache.set(`${this.family}/${this.name}`, iconResolver);\n }\n\n const svg = await iconResolver;\n\n if (svg === RETRYABLE_ERROR) {\n iconCache.delete(`${this.family}/${this.name}`);\n }\n\n if (isTemplateResult(svg)) {\n this.svg = svg;\n } else if (svg instanceof SVGSVGElement) {\n // Clone the SVG so each icon instance gets its own copy\n this.svg = svg.cloneNode(true) as SVGSVGElement;\n }\n }\n\n private updateUrl() {\n switch (this.library) {\n case EnumLibrary.FONTAWESOME:\n this.version = this.version || '7.3.1';\n this.url = `https://unpkg.com/@fortawesome/fontawesome-free@${this.version}/svgs`;\n break;\n case EnumLibrary.BOOTSTRAP:\n this.version = this.version || '1.11.3';\n this.url = `https://unpkg.com/bootstrap-icons@${this.version}/icons`;\n break;\n }\n }\n\n private async resolveIcon(): Promise<SVGResult> {\n return new Promise((resolve) => {\n queueRequest(async () => {\n let fileData: Response;\n let fetchURL: string = `${this.url}/${this.family}/${this.name}.svg`;\n\n switch (this.library) {\n case EnumLibrary.FONTAWESOME:\n fetchURL = `${this.url}/${this.family}/${this.name}.svg`;\n break;\n case EnumLibrary.BOOTSTRAP:\n fetchURL = `${this.url}/${this.name}.svg`;\n break;\n }\n\n try {\n fileData = await fetch(fetchURL);\n if (!fileData.ok) {\n requestComplete();\n resolve(fileData.status === 410 ? CACHEABLE_ERROR : RETRYABLE_ERROR);\n return;\n }\n } catch {\n requestComplete();\n resolve(RETRYABLE_ERROR);\n return;\n }\n\n try {\n const div = document.createElement('div');\n div.innerHTML = await fileData.text();\n\n const svg = div.firstElementChild;\n if (svg?.tagName?.toLowerCase() !== 'svg') {\n requestComplete();\n resolve(CACHEABLE_ERROR);\n return;\n }\n\n if (!parser) parser = new DOMParser();\n const doc = parser.parseFromString(svg.outerHTML, 'text/html');\n\n const svgEl = doc.body.querySelector('svg');\n if (!svgEl) {\n requestComplete();\n resolve(CACHEABLE_ERROR);\n return;\n }\n\n svgEl.part.add('svg');\n svgEl.setAttribute('width', `${this.size}px`);\n svgEl.setAttribute('height', `${this.size}px`);\n\n requestComplete();\n resolve(document.adoptNode(svgEl));\n } catch {\n requestComplete();\n resolve(CACHEABLE_ERROR);\n }\n });\n });\n }\n\n private updateSize() {\n if (this.svg) {\n const svg = this.svg as SVGElement;\n svg.setAttribute('width', `${this.size}px`);\n svg.setAttribute('height', `${this.size}px`);\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kemet-icon': KemetIcon\n }\n}\n","import { css } from 'lit';\n\nexport default css`:host {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: inherit;\n}\n`;\n","import { css } from 'lit';\n\nexport default css`:host {\n color: inherit;\n display: none;\n}\n\n:host([show]) {\n display: block;\n}\n\np {\n margin: 1.6rem 0;\n}\n\n[part=strength] {\n display: grid;\n align-items: center;\n grid-template-columns: 1fr auto;\n line-height: 1;\n margin-top: 0.8rem;\n}\n\n[part=strength] > span {\n text-transform: capitalize;\n}\n\n.weak {\n color: var(--kemet-color-font-error);\n}\n\n.better {\n color: var(--kemet-color-font-warning);\n}\n\n.strong {\n color: var(--kemet-color-font-success);\n}\n\n[part=indicator] {\n display: flex;\n gap: 0.4rem;\n margin: 0;\n list-style: none;\n}\n\n[part=indicator] li {\n width: 1.6rem;\n height: 0.2rem;\n}\n\n.weak [part=indicator] li:nth-child(1) {\n background-color: var(--kemet-color-font-error);\n}\n\n.better [part=indicator] li:nth-child(1),\n.better [part=indicator] li:nth-child(2) {\n background-color: var(--kemet-color-font-warning);\n}\n\n.strong [part=indicator] li {\n background-color: var(--kemet-color-font-success);\n}\n\n[part=rules] {\n color: inherit;\n line-height: 1.5;\n list-style: none;\n font-size: 90%;\n padding-left: 2rem;\n}\n\n[part=rules] li {\n position: relative;\n}\n\n[part=rules] kemet-icon {\n color: var(--kemet-color-font-success);\n position: absolute;\n left: -2rem;\n}\n`;\n"],"mappings":"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","names":["html","LitElement","customElement","property","state","css","styles_css_default","LitElement","html","styles_css_default","property","state","customElement"]}
1
+ {"version":3,"sources":["../../../src/elements/password/index.ts","../../../src/utilities/decorators.ts","../../../src/utilities/events.ts","../../../src/elements/password/styles.css.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS, TemplateResult } from 'lit';\nimport { customElement, property, state } from '../../utilities/decorators';\nimport { emitEvent } from '../../utilities/events';\nimport { EnumAppearances } from '../../utilities/constants';\nimport HTMLKemetFieldElement from '../field';\nimport HTMLKemetInputElement from '../input';\nimport HTMLKemetTextareaElement from '../textarea';\nimport styles from './styles.css.ts';\n\ninterface InterfaceOptions {\n pattern: string;\n message: string;\n meetsCriteria?: boolean;\n}\n\nexport interface InterfacePasswordStrengthChangeDetails {\n appearance: EnumAppearances;\n meetsPasswordCriteria: boolean;\n element: KemetPassword;\n}\n\n/**\n * @since 1.2.0\n * @status stable\n *\n * @tagname kemet-password\n * @summary Gauges the strength of a password entered by the user.\n * @ssrsafe yes\n *\n * @prop {array} rules - An array of objects containing the rules the password must meet.\n * @prop {boolean} show - Controls the display of the component.\n * @prop {string} value - The value of the input component.\n * @prop {string} message - A message that is above the rules.\n * @prop {string} strength - The strength of the password. Weak | Better | Strong.\n * @prop {string} icon\n * @prop {number} iconSize\n *\n * @event kemet-password-strength-change - Fires when there's a change in strength.\n *\n * @csspart strength - Indicates password strength.\n * @csspart indicator - The strength indicator bars.\n * @csspart message - A message to display to the user.\n * @csspart rules - A description of rules to follow.\n *\n */\n\n@customElement('kemet-password')\nexport default class KemetPassword extends LitElement {\n static styles = [styles];\n\n @property({ type: Array })\n rules: InterfaceOptions[] = [\n { pattern: '(?=.{8,}$)', message: 'At least 8 characters long' },\n { pattern: '(?=.*[a-z])(?=.*[A-Z])', message: 'Uppercase and lowercase' },\n { pattern: '(?=.*[0-9])', message: 'At least one number (0-9)' },\n ];\n\n @property({ type: Boolean, reflect: true })\n show: boolean = false;\n\n @property({ type: String })\n value!: string;\n\n @property({ type: String })\n message: string = 'Please make sure you meet all the requirements.';\n\n @property({ type: String })\n strength!: string;\n\n @property({ type: String })\n icon: string = 'check2';\n\n @property({ type: Number })\n iconSize: number = 18;\n\n @state()\n appearance?: EnumAppearances;\n\n @state()\n field!: HTMLKemetFieldElement;\n\n @state()\n input!: HTMLKemetInputElement | HTMLKemetTextareaElement;\n\n firstUpdated() {\n // elements\n this.field = this.closest('kemet-field') as HTMLKemetFieldElement;\n this.input = this.field.querySelector('[slot=\"input\"]') as HTMLKemetInputElement | HTMLKemetTextareaElement;\n\n // events listeners\n this.input?.addEventListener('kemet-input-input', this.handleInput.bind(this));\n }\n\n render() {\n return html`\n <div role=\"alert\" aria-live=\"assertive\">\n <div class=\"${this.strength}\" part=\"strength\">\n <span>${this.strength}</span>\n <ul part=\"indicator\">\n <li></li>\n <li></li>\n <li></li>\n </ul>\n </div>\n <p part=\"message\">${this.message}</p>\n <ul part=\"rules\">\n ${this.makeRules()}\n </ul>\n </div>\n `;\n }\n\n /**\n * Makes the list of rules\n * @private\n * @returns {TemplateResult<1>[]} the criteria rules\n */\n makeRules(): TemplateResult<1>[] {\n if (this.input) {\n return this.rules.map((rule) => {\n const regExp = new RegExp(rule.pattern);\n const meetsCriteria = regExp.test(this.input.value);\n rule.meetsCriteria = meetsCriteria;\n return html`<li>${this.makeCheckIcon(meetsCriteria)} ${rule.message}</li>`;\n });\n }\n\n return [];\n }\n\n /**\n * Makes the check icon if the criteria has been met\n * @param {boolean} meetsCriteria\n * @private\n * @returns {TemplateResult} an icon component\n */\n makeCheckIcon(meetsCriteria: boolean): TemplateResult {\n if (meetsCriteria) {\n return html`<kemet-icon name=${this.icon} size=${this.iconSize}></kemet-icon>`;\n }\n\n return html``;\n }\n\n /**\n * Handles the kemet-input-input event\n * @param {*} event\n * @private\n */\n handleInput(event: Event) {\n this.value = (event as CustomEvent).detail.value;\n this.setStrength();\n this.visibility();\n }\n\n /**\n * Determines the strength of the password\n * @private\n */\n setStrength() {\n // We use a setTimeout here because makeRules adds the meetsCriteria\n // property to the rules. We need that to be set by render() before\n // setting the Strength because the percentage calc is based on it\n setTimeout(() => {\n const totalRules = this.rules.length;\n const metRules = this.rules.filter(rule => rule.meetsCriteria).length;\n const metRulesPercentage = Math.round((metRules / totalRules) * 100) / 100;\n\n if (metRulesPercentage <= 0.33) {\n this.strength = 'weak';\n this.appearance = EnumAppearances.Error;\n }\n\n if (metRulesPercentage > 0.33 && metRulesPercentage <= 0.67) {\n this.strength = 'better';\n this.appearance = EnumAppearances.Error;\n }\n\n if (metRulesPercentage > 0.67) {\n this.strength = 'strong';\n this.appearance = EnumAppearances.Success;\n }\n\n emitEvent(this, 'kemet-password-strength-change', {\n appearance: this.appearance,\n meetsPasswordCriteria: this.appearance === EnumAppearances.Success,\n element: this,\n });\n }, 1);\n }\n\n /**\n * Determines whether to show or hide the component\n * @private\n */\n visibility() {\n this.show = this.value.length > 0;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kemet-password': KemetPassword\n }\n}\n","export { property, state, query, queryAll } from 'lit/decorators.js';\nimport { customElement as litCustomElement } from 'lit/decorators.js';\n\n/**\n * A drop-in replacement for lit's `customElement` decorator that is safe under\n * hot-module-replacement / live-reload environments where the module may be\n * re-evaluated.\n */\nexport const customElement = (tagName: string) => (classOrDescriptor: any) =>\n typeof customElements !== 'undefined' && !customElements.get(tagName)\n ? litCustomElement(tagName)(classOrDescriptor)\n : classOrDescriptor;\n","export const emitEvent = (element, name, detail, bubbles = true, composed = true) => {\n element.dispatchEvent(\n new CustomEvent(name, { bubbles, composed, detail }),\n );\n};\n","import { css } from 'lit';\n\nexport default css`:host {\n color: inherit;\n display: none;\n}\n\n:host([show]) {\n display: block;\n}\n\np {\n margin: 1.6rem 0;\n}\n\n[part=strength] {\n display: grid;\n align-items: center;\n grid-template-columns: 1fr auto;\n line-height: 1;\n margin-top: 0.8rem;\n}\n\n[part=strength] > span {\n text-transform: capitalize;\n}\n\n.weak {\n color: var(--kemet-color-font-error);\n}\n\n.better {\n color: var(--kemet-color-font-warning);\n}\n\n.strong {\n color: var(--kemet-color-font-success);\n}\n\n[part=indicator] {\n display: flex;\n gap: 0.4rem;\n margin: 0;\n list-style: none;\n}\n\n[part=indicator] li {\n width: 1.6rem;\n height: 0.2rem;\n}\n\n.weak [part=indicator] li:nth-child(1) {\n background-color: var(--kemet-color-font-error);\n}\n\n.better [part=indicator] li:nth-child(1),\n.better [part=indicator] li:nth-child(2) {\n background-color: var(--kemet-color-font-warning);\n}\n\n.strong [part=indicator] li {\n background-color: var(--kemet-color-font-success);\n}\n\n[part=rules] {\n color: inherit;\n line-height: 1.5;\n list-style: none;\n font-size: 90%;\n padding-left: 2rem;\n}\n\n[part=rules] li {\n position: relative;\n}\n\n[part=rules] kemet-icon {\n color: var(--kemet-color-font-success);\n position: absolute;\n left: -2rem;\n}\n`;\n"],"mappings":"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","names":[]}
@@ -8,6 +8,7 @@ import { LitElement } from 'lit';
8
8
  *
9
9
  * @tagname kemet-radio
10
10
  * @summary An enhanced radio button.
11
+ * @ssrsafe yes
11
12
  *
12
13
  * @prop {string} label - The text next to the radio button
13
14
  * @prop {boolean} checked - Determines whether or not the button is checked
@@ -11,7 +11,13 @@ var __decorateClass = (decorators, target, key, kind) => {
11
11
 
12
12
  // src/elements/radio/index.ts
13
13
  import { html, LitElement } from "lit";
14
- import { customElement, property, state } from "lit/decorators.js";
14
+
15
+ // src/utilities/decorators.ts
16
+ import { property, state, query, queryAll } from "lit/decorators.js";
17
+ import { customElement as litCustomElement } from "lit/decorators.js";
18
+ var customElement = (tagName) => (classOrDescriptor) => typeof customElements !== "undefined" && !customElements.get(tagName) ? litCustomElement(tagName)(classOrDescriptor) : classOrDescriptor;
19
+
20
+ // src/elements/radio/index.ts
15
21
  import { ifDefined } from "lit/directives/if-defined.js";
16
22
  import { live } from "lit/directives/live.js";
17
23
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/elements/radio/index.ts","../../../src/utilities/events.ts","../../../src/elements/radio/styles.css.ts"],"sourcesContent":["import { html, LitElement } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { live } from 'lit/directives/live.js';\nimport { emitEvent } from '../../utilities/events';\nimport HTMLKemetRadiosElements from '../radios';\nimport styles from './styles.css.ts'\n\n/**\n * @since 1.0.0\n * @status stable\n *\n * @tagname kemet-radio\n * @summary An enhanced radio button.\n *\n * @prop {string} label - The text next to the radio button\n * @prop {boolean} checked - Determines whether or not the button is checked\n * @prop {string} name - The name of the field\n * @prop {string} value - The value of the radio button\n * @prop {boolean} disabled - Determines if the button should be disabled\n * @prop {boolean} focused - Is true when the button is focused on\n * @prop {boolean} filled - Displayed the button as a filled button\n * @prop {'light' | 'dark'} polarity - Determines if the component has a dark or light background\n * @prop {string} dom - The status of dom initalization.\n *\n * @csspart label - The label that contains the radio button.\n * @csspart button - The radio button.\n * @csspart text - The text next to the radio button.\n * @csspart dot - The circle that fills the radio button.\n *\n * @cssproperty --kemet-radio-size - The size of the radio button.\n * @cssproperty --kemet-radio-border - The outer border of the radio button.\n * @cssproperty --kemet-radio-dot-color - The color of the radio button's dot.\n * @cssproperty --kemet-radio-dot-border-width - The border width of the radio button's dot.\n * @cssproperty --kemet-radio-dot-border-color - The border color of the radio button's dot.\n * @cssproperty --kemet-radio-dot-color-filled - The filled color of the radio button.\n * @cssproperty --kemet-radio-dot-ring-color - The ring color of the radio button's dot.\n *\n * @event kemet-radio-focus - Fires when the checkbox receives focus\n * @event kemet-radio-blur - Fires when the checkbox loses focus\n *\n * @fires kemet-radio-mounted - Fired when the radio is mounted to the DOM\n * @detail {HTMLElement} element - The radio element\n *\n */\n\n@customElement('kemet-radio')\nexport default class KemetRadio extends LitElement {\n static styles = [styles];\n\n @property({ type: String })\n label: string = '';\n\n @property({ type: Boolean, reflect: true })\n checked: boolean = false;\n\n @property({ type: String })\n name: string = '';\n\n @property({ type: String })\n value: string = '';\n\n @property({ type: Boolean, reflect: true })\n disabled: boolean = false;\n\n @property({ type: Boolean, reflect: true })\n focused: boolean = false;\n\n @property({ type: Boolean, reflect: true })\n filled: boolean = false;\n\n @property({ type: String, reflect: true })\n polarity?: 'light' | 'dark';\n\n @property({ type: String, reflect: true })\n dom: string = 'initializing';\n\n @state()\n input: HTMLInputElement = undefined as any;\n\n firstUpdated() {\n const radiosElement = this.closest('kemet-radios') as HTMLKemetRadiosElements;\n\n this.name = radiosElement.name || 'radio-button';\n this.input = this.shadowRoot?.querySelector('input') as HTMLInputElement;\n this.setAttribute('role', 'radio');\n\n if (this.checked) {\n this.setAttribute('aria-checked', 'true');\n } else {\n this.setAttribute('aria-checked', 'false');\n }\n\n emitEvent(this, 'kemet-radio-mounted', {\n bubbles: true,\n composed: true,\n detail: {\n element: this,\n },\n });\n this.dom = 'mounted';\n }\n\n render() {\n return html`\n <label part=\"label\">\n <input\n type=\"radio\"\n name=${ifDefined(this.name)}\n .value=${this.value}\n .checked=${live(this.checked)}\n .disabled=${this.disabled}\n @blur=${() => this.handleBlur()}\n @focus=${() => this.handleFocus()}\n />\n <button part=\"button\" aria-label=${this.label}>${this.makeDot()}</button>\n <span part=\"text\">${this.label}</span>\n </label>\n `;\n }\n\n /**\n * Simulates a click on the input element.\n * @public\n * @method click\n * @returns {void}\n */\n click() {\n this.input.click();\n }\n\n /**\n * Calls blur on the input element.\n * @public\n * @method blur\n * @returns {void}\n */\n blur(): void {\n this.input.blur();\n }\n\n /**\n * Calls focus on the input element.\n * @public\n * @method focus\n * @returns {void}\n */\n focus(): void {\n this.input.focus();\n }\n\n handleBlur() {\n this.focused = false;\n emitEvent(this, 'kemet-radio-blur', { element: this });\n }\n\n handleFocus() {\n this.focused = true;\n emitEvent(this, 'kemet-radio-focus', { element: this });\n }\n\n makeDot() {\n if (this.checked) {\n return html`\n <span part=\"dot\"></span>\n `;\n }\n\n return null;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kemet-radio': KemetRadio\n }\n}\n","export const emitEvent = (element, name, detail, bubbles = true, composed = true) => {\n element.dispatchEvent(\n new CustomEvent(name, { bubbles, composed, detail }),\n );\n};\n","import { css } from 'lit';\n\nexport default css`:host {\n --kemet-radio-size: 18px;\n --kemet-radio-border: 1px solid var(--kemet-color-font-active);\n --kemet-radio-dot-color: var(--kemet-color-font-active);\n --kemet-radio-dot-border: none;\n --kemet-radio-dot-border-width: 3px;\n --kemet-radio-dot-ring-color: var(--kemet-color-font-inverse-base);\n --kemet-radio-dot-color-filled: var(--kemet-color-font-inverse-base);\n --kemet-radio-dot-border-width: 4px;\n --kemet-radio-dot-border-color: var(--kemet-color-font-active);\n\n display: inline-block;\n}\n\n:host([disabled]) {\n opacity: 0.5;\n}\n\nlabel {\n cursor: pointer;\n display: inline-flex;\n gap: 0.5rem;\n align-items: center;\n margin-right: 0.5rem;\n}\n\ninput {\n cursor: pointer;\n margin: 0;\n padding: 0;\n width: var(--kemet-radio-size);\n height: var(--kemet-radio-size);\n position: absolute;\n opacity: 0;\n}\n\nbutton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--kemet-radio-size);\n height: var(--kemet-radio-size);\n padding: 0;\n border-radius: var(--kemet-border-radius-circle);\n background: none;\n border: var(--kemet-radio-border);\n}\n\n[part=dot] {\n display: inline-flex;\n border-radius: var(--kemet-border-radius-circle);\n width: calc(var(--kemet-radio-size) - 2px);\n height: calc(var(--kemet-radio-size) - 2px);\n background: var(--kemet-radio-dot-color);\n border: var(--kemet-radio-dot-border);\n box-shadow: inset 0px 0px 0px var(--kemet-radio-dot-border-width) var(--kemet-radio-dot-ring-color);\n}\n\n:host([filled]) [part=dot] {\n background: var(--kemet-radio-dot-color-filled);\n box-shadow: inset 0px 0px 0px var(--kemet-radio-dot-border-width) var(--kemet-radio-dot-border-color);\n}\n`;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/elements/radio/index.ts","../../../src/utilities/decorators.ts","../../../src/utilities/events.ts","../../../src/elements/radio/styles.css.ts"],"sourcesContent":["import { html, LitElement } from 'lit';\nimport { customElement, property, state } from '../../utilities/decorators';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { live } from 'lit/directives/live.js';\nimport { emitEvent } from '../../utilities/events';\nimport HTMLKemetRadiosElements from '../radios';\nimport styles from './styles.css.ts'\n\n/**\n * @since 1.0.0\n * @status stable\n *\n * @tagname kemet-radio\n * @summary An enhanced radio button.\n * @ssrsafe yes\n *\n * @prop {string} label - The text next to the radio button\n * @prop {boolean} checked - Determines whether or not the button is checked\n * @prop {string} name - The name of the field\n * @prop {string} value - The value of the radio button\n * @prop {boolean} disabled - Determines if the button should be disabled\n * @prop {boolean} focused - Is true when the button is focused on\n * @prop {boolean} filled - Displayed the button as a filled button\n * @prop {'light' | 'dark'} polarity - Determines if the component has a dark or light background\n * @prop {string} dom - The status of dom initalization.\n *\n * @csspart label - The label that contains the radio button.\n * @csspart button - The radio button.\n * @csspart text - The text next to the radio button.\n * @csspart dot - The circle that fills the radio button.\n *\n * @cssproperty --kemet-radio-size - The size of the radio button.\n * @cssproperty --kemet-radio-border - The outer border of the radio button.\n * @cssproperty --kemet-radio-dot-color - The color of the radio button's dot.\n * @cssproperty --kemet-radio-dot-border-width - The border width of the radio button's dot.\n * @cssproperty --kemet-radio-dot-border-color - The border color of the radio button's dot.\n * @cssproperty --kemet-radio-dot-color-filled - The filled color of the radio button.\n * @cssproperty --kemet-radio-dot-ring-color - The ring color of the radio button's dot.\n *\n * @event kemet-radio-focus - Fires when the checkbox receives focus\n * @event kemet-radio-blur - Fires when the checkbox loses focus\n *\n * @fires kemet-radio-mounted - Fired when the radio is mounted to the DOM\n * @detail {HTMLElement} element - The radio element\n *\n */\n\n@customElement('kemet-radio')\nexport default class KemetRadio extends LitElement {\n static styles = [styles];\n\n @property({ type: String })\n label: string = '';\n\n @property({ type: Boolean, reflect: true })\n checked: boolean = false;\n\n @property({ type: String })\n name: string = '';\n\n @property({ type: String })\n value: string = '';\n\n @property({ type: Boolean, reflect: true })\n disabled: boolean = false;\n\n @property({ type: Boolean, reflect: true })\n focused: boolean = false;\n\n @property({ type: Boolean, reflect: true })\n filled: boolean = false;\n\n @property({ type: String, reflect: true })\n polarity?: 'light' | 'dark';\n\n @property({ type: String, reflect: true })\n dom: string = 'initializing';\n\n @state()\n input: HTMLInputElement = undefined as any;\n\n firstUpdated() {\n const radiosElement = this.closest('kemet-radios') as HTMLKemetRadiosElements;\n\n this.name = radiosElement.name || 'radio-button';\n this.input = this.shadowRoot?.querySelector('input') as HTMLInputElement;\n this.setAttribute('role', 'radio');\n\n if (this.checked) {\n this.setAttribute('aria-checked', 'true');\n } else {\n this.setAttribute('aria-checked', 'false');\n }\n\n emitEvent(this, 'kemet-radio-mounted', {\n bubbles: true,\n composed: true,\n detail: {\n element: this,\n },\n });\n this.dom = 'mounted';\n }\n\n render() {\n return html`\n <label part=\"label\">\n <input\n type=\"radio\"\n name=${ifDefined(this.name)}\n .value=${this.value}\n .checked=${live(this.checked)}\n .disabled=${this.disabled}\n @blur=${() => this.handleBlur()}\n @focus=${() => this.handleFocus()}\n />\n <button part=\"button\" aria-label=${this.label}>${this.makeDot()}</button>\n <span part=\"text\">${this.label}</span>\n </label>\n `;\n }\n\n /**\n * Simulates a click on the input element.\n * @public\n * @method click\n * @returns {void}\n */\n click() {\n this.input.click();\n }\n\n /**\n * Calls blur on the input element.\n * @public\n * @method blur\n * @returns {void}\n */\n blur(): void {\n this.input.blur();\n }\n\n /**\n * Calls focus on the input element.\n * @public\n * @method focus\n * @returns {void}\n */\n focus(): void {\n this.input.focus();\n }\n\n handleBlur() {\n this.focused = false;\n emitEvent(this, 'kemet-radio-blur', { element: this });\n }\n\n handleFocus() {\n this.focused = true;\n emitEvent(this, 'kemet-radio-focus', { element: this });\n }\n\n makeDot() {\n if (this.checked) {\n return html`\n <span part=\"dot\"></span>\n `;\n }\n\n return null;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kemet-radio': KemetRadio\n }\n}\n","export { property, state, query, queryAll } from 'lit/decorators.js';\nimport { customElement as litCustomElement } from 'lit/decorators.js';\n\n/**\n * A drop-in replacement for lit's `customElement` decorator that is safe under\n * hot-module-replacement / live-reload environments where the module may be\n * re-evaluated.\n */\nexport const customElement = (tagName: string) => (classOrDescriptor: any) =>\n typeof customElements !== 'undefined' && !customElements.get(tagName)\n ? litCustomElement(tagName)(classOrDescriptor)\n : classOrDescriptor;\n","export const emitEvent = (element, name, detail, bubbles = true, composed = true) => {\n element.dispatchEvent(\n new CustomEvent(name, { bubbles, composed, detail }),\n );\n};\n","import { css } from 'lit';\n\nexport default css`:host {\n --kemet-radio-size: 18px;\n --kemet-radio-border: 1px solid var(--kemet-color-font-active);\n --kemet-radio-dot-color: var(--kemet-color-font-active);\n --kemet-radio-dot-border: none;\n --kemet-radio-dot-border-width: 3px;\n --kemet-radio-dot-ring-color: var(--kemet-color-font-inverse-base);\n --kemet-radio-dot-color-filled: var(--kemet-color-font-inverse-base);\n --kemet-radio-dot-border-width: 4px;\n --kemet-radio-dot-border-color: var(--kemet-color-font-active);\n\n display: inline-block;\n}\n\n:host([disabled]) {\n opacity: 0.5;\n}\n\nlabel {\n cursor: pointer;\n display: inline-flex;\n gap: 0.5rem;\n align-items: center;\n margin-right: 0.5rem;\n}\n\ninput {\n cursor: pointer;\n margin: 0;\n padding: 0;\n width: var(--kemet-radio-size);\n height: var(--kemet-radio-size);\n position: absolute;\n opacity: 0;\n}\n\nbutton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--kemet-radio-size);\n height: var(--kemet-radio-size);\n padding: 0;\n border-radius: var(--kemet-border-radius-circle);\n background: none;\n border: var(--kemet-radio-border);\n}\n\n[part=dot] {\n display: inline-flex;\n border-radius: var(--kemet-border-radius-circle);\n width: calc(var(--kemet-radio-size) - 2px);\n height: calc(var(--kemet-radio-size) - 2px);\n background: var(--kemet-radio-dot-color);\n border: var(--kemet-radio-dot-border);\n box-shadow: inset 0px 0px 0px var(--kemet-radio-dot-border-width) var(--kemet-radio-dot-ring-color);\n}\n\n:host([filled]) [part=dot] {\n background: var(--kemet-radio-dot-color-filled);\n box-shadow: inset 0px 0px 0px var(--kemet-radio-dot-border-width) var(--kemet-radio-dot-border-color);\n}\n`;\n"],"mappings":"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","names":[]}
@@ -2,7 +2,7 @@ import * as lit_html from 'lit-html';
2
2
  import * as lit from 'lit';
3
3
  import { LitElement } from 'lit';
4
4
  import { F as FormSubmitController } from '../../form-controller-3q581XcZ.js';
5
- import { g as EnumAxis, E as EnumAppearances } from '../../constants-W9QKPlZP.js';
5
+ import { g as EnumAxis, E as EnumAppearances } from '../../constants-CHvA2ed5.js';
6
6
  import KemetRadio from '../radio/index.js';
7
7
 
8
8
  /**
@@ -11,6 +11,7 @@ import KemetRadio from '../radio/index.js';
11
11
  *
12
12
  * @tagname kemet-radios
13
13
  * @summary A group of radio buttons.
14
+ * @ssrsafe yes
14
15
  *
15
16
  * @prop {string} legend - The legend text for the fieldset
16
17
  * @prop {TypeAxis} axis - The direction of the button's layout
@@ -11,7 +11,11 @@ var __decorateClass = (decorators, target, key, kind) => {
11
11
 
12
12
  // src/elements/radios/index.ts
13
13
  import { html, LitElement } from "lit";
14
- import { customElement, property, state } from "lit/decorators.js";
14
+
15
+ // src/utilities/decorators.ts
16
+ import { property, state, query, queryAll } from "lit/decorators.js";
17
+ import { customElement as litCustomElement } from "lit/decorators.js";
18
+ var customElement = (tagName) => (classOrDescriptor) => typeof customElements !== "undefined" && !customElements.get(tagName) ? litCustomElement(tagName)(classOrDescriptor) : classOrDescriptor;
15
19
 
16
20
  // src/utilities/form-controller.ts
17
21
  var FormSubmitController = class {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/elements/radios/index.ts","../../../src/utilities/form-controller.ts","../../../src/utilities/events.ts","../../../src/elements/radios/styles.css.ts"],"sourcesContent":["import { html, LitElement } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { FormSubmitController } from '../../utilities/form-controller';\nimport { emitEvent } from '../../utilities/events';\nimport { EnumAxis, EnumAppearances } from '../../utilities/constants';\nimport type HTMLKemetRadioElement from '../radio';\nimport styles from './styles.css.ts'\n\n\n/**\n * @since 1.0.0\n * @status stable\n *\n * @tagname kemet-radios\n * @summary A group of radio buttons.\n *\n * @prop {string} legend - The legend text for the fieldset\n * @prop {TypeAxis} axis - The direction of the button's layout\n * @prop {string} value - The value of the selected radio button\n * @prop {string} name - The name of the radio button set\n * @prop {EnumAppearances} appearance - The appearance of the radio button set\n * @prop {string} message - Validation message for the user\n * @prop {boolean} required - Determines whether the radio button set is required\n * @prop {'light' | 'dark'} polarity - Determines if the component has a dark or light background\n * @prop {string} dom - The status of dom initalization.\n *\n * @csspart fieldset - The fieldset element.\n * @csspart legend - The legend element.\n *\n * @event kemet-radios-change - Fires when the state of the checkbox changes\n *\n * @fires kemet-radios-mounted - Fired when the radios is mounted to the DOM\n * @detail {HTMLElement} element - The radios element\n *\n */\n\n@customElement('kemet-radios')\nexport default class KemetRadios extends LitElement {\n formSubmitController: FormSubmitController;\n\n static styles = [styles];\n\n @property({ type: String })\n legend: string = '';\n\n @property({ type: String, reflect: true })\n axis: EnumAxis = EnumAxis.Horizontal;\n\n @property({ type: String })\n value!: string;\n\n @property({ type: String })\n name: string = 'radios';\n\n @property({ type: String, reflect: true })\n appearance: EnumAppearances = EnumAppearances.Neutral;\n\n @property({ type: String })\n message!: string;\n\n @property({ type: Boolean })\n required!: boolean;\n\n @property({ type: String, reflect: true })\n polarity?: 'light' | 'dark';\n\n @property({ type: String, reflect: true })\n dom: string = 'initializing';\n\n @state()\n radios!: NodeListOf<HTMLKemetRadioElement>;\n\n constructor() {\n super();\n\n /** @internal */\n this.formSubmitController = new FormSubmitController(this);\n }\n\n firstUpdated() {\n this.radios = this.querySelectorAll('kemet-radio');\n this.setAttribute('role', 'radiogroup');\n\n emitEvent(this, 'kemet-radios-mounted', {\n bubbles: true,\n composed: true,\n detail: {\n element: this,\n },\n });\n this.dom = 'mounted';\n }\n\n render() {\n return html`\n <fieldset part=\"fieldset\">\n ${this.legend !== '' ? html`<legend part=\"legend\">${this.legend}</legend>` : null}\n <slot @click=${(event: MouseEvent) => this.handleClick(event)} @keydown=${(event: KeyboardEvent) => this.handleKeyDown(event)} @slotchange=${() => this.handleSlotChange()}></slot>\n </fieldset>\n ${this.makeMessage()}\n `;\n }\n\n handleClick(event: MouseEvent) {\n const target = event.target as HTMLKemetRadioElement;\n\n this.radios.forEach((radio) => {\n radio.checked = false;\n radio.tabIndex = radio === target ? 0 : -1;\n radio.setAttribute('aria-checked', 'false');\n });\n\n if (!target.disabled) {\n target.checked = true;\n target.setAttribute('aria-checked', 'true');\n this.value = target.value;\n this.appearance = EnumAppearances.Neutral;\n\n emitEvent(this, 'kemet-radios-change', this);\n }\n }\n\n handleKeyDown(event: KeyboardEvent) {\n const radios = Array.from(this.radios);\n const arrowKeys = ['ArrowUp', 'ArrowRight', 'ArrowDown', 'ArrowLeft'];\n const forwardKeys = ['ArrowRight', 'ArrowDown'];\n const shift: number = forwardKeys.includes(event.key) ? 1 : -1;\n const checkedIndex: number | HTMLKemetRadioElement = radios.findIndex((radio: HTMLKemetRadioElement) => radio.checked) ?? radios[0];\n\n let index: number;\n\n if (typeof checkedIndex === 'number') {\n index = checkedIndex + shift;\n } else {\n index = shift;\n }\n\n if (arrowKeys.includes(event.key)) {\n if (index < 0) {\n index = radios.length - 1;\n }\n\n if (index > radios.length - 1) {\n index = 0;\n }\n\n this.radios.forEach((radio) => {\n radio.checked = false;\n radio.tabIndex = -1;\n });\n\n const radio = this.radios[index];\n if (radio) {\n radio.focus();\n radio.checked = true;\n radio.tabIndex = 0;\n }\n }\n }\n\n handleSlotChange() {\n const radios = Array.from(this.radios);\n const checkedRadio = radios.find((radio: HTMLKemetRadioElement) => radio.checked) as HTMLKemetRadioElement;\n\n this.radios.forEach((radio: HTMLKemetRadioElement) => {\n radio.tabIndex = -1;\n radio.input.tabIndex = -1;\n });\n\n if (checkedRadio) {\n checkedRadio.tabIndex = 0;\n }\n }\n\n makeMessage() {\n if (this.appearance === 'error' || this.appearance === 'warning') {\n return html`<span part=\"message\">${this.message}</span>`;\n }\n\n return null;\n }\n\n checkValidity() {\n if (this.required) {\n return !!this.value;\n }\n\n return true;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kemet-radios': KemetRadios\n }\n}\n","export class FormSubmitController {\n host: any;\n form: HTMLFormElement | null | undefined;\n options: {\n form: (input: any) => HTMLFormElement | null | undefined;\n name: (input: any) => string;\n value: (input: any) => any;\n disabled: (input: any) => boolean;\n };\n\n constructor(host: any, options: Partial<{\n form: (input: any) => HTMLFormElement | null | undefined;\n name: (input: any) => string;\n value: (input: any) => any;\n disabled: (input: any) => boolean;\n }> = {}) {\n (this.host = host).addController(this);\n\n this.options = {\n form: (input: any) => input.closest('form'),\n name: (input: any) => input.name,\n value: (input: any) => input.value,\n disabled: (input: any) => input.disabled,\n ...options,\n };\n\n this.handleFormData = this.handleFormData.bind(this);\n this.handleFormSubmit = this.handleFormSubmit.bind(this);\n }\n\n hostConnected() {\n this.form = this.options.form(this.host);\n\n if (this.form) {\n this.form.addEventListener('formdata', this.handleFormData);\n this.form.addEventListener('submit', this.handleFormSubmit);\n }\n }\n\n hostDisconnected() {\n if (this.form) {\n this.form.removeEventListener('formdata', this.handleFormData);\n this.form.removeEventListener('submit', this.handleFormSubmit);\n this.form = undefined;\n }\n }\n\n handleFormData(event: FormDataEvent) {\n const disabled = this.options.disabled(this.host);\n const name = this.options.name(this.host);\n const value = this.options.value(this.host);\n\n if (!disabled && typeof name === 'string' && typeof value !== 'undefined') {\n // TODO recreate a scenario where value will be an array\n // if (Array.isArray(value)) {\n // value.forEach((val) => {\n // event.formData?.append(name, val.toString());\n // });\n // } else {\n // event.formData?.append(name, value.toString());\n // }\n event.formData?.append(name, value.toString());\n }\n }\n\n handleFormSubmit(event: SubmitEvent) {\n event.preventDefault();\n event.stopImmediatePropagation();\n\n const disabled = this.options.disabled(this.host);\n this.form = this.options.form(this.host);\n\n if (this.form && !disabled) {\n const components = this.form.querySelectorAll('kemet-input, kemet-textarea, kemet-select, kemet-checkbox, kemet-radios');\n\n components.forEach((component: any) => {\n if (component.checkValidity) {\n component.checkValidity();\n\n if (!component.checkValidity()) {\n component.status = 'error';\n component.invalid = true;\n\n component.dispatchEvent(\n new CustomEvent('kemet-input-status', {\n bubbles: true,\n composed: true,\n detail: {\n status: 'error',\n validity: component.validity ? component.validity : {},\n element: component,\n },\n }),\n );\n }\n\n if (component.checkLimitValidity && !component.checkLimitValidity()) {\n component.status = 'error';\n component.invalid = true;\n\n component.dispatchEvent(\n new CustomEvent('kemet-input-status', {\n bubbles: true,\n composed: true,\n detail: {\n status: 'error',\n validity: { passedLimit: true },\n element: component,\n },\n }),\n );\n }\n }\n });\n }\n }\n\n submit() {\n const button = document.createElement('button');\n\n if (this.form) {\n button.type = 'submit';\n button.style.position = 'absolute';\n button.style.width = '0';\n button.style.height = '0';\n button.style.clip = 'rect(0 0 0 0)';\n button.style.clipPath = 'inset(50%)';\n button.style.overflow = 'hidden';\n button.style.whiteSpace = 'nowrap';\n this.form.append(button);\n button.click();\n button.remove();\n }\n }\n}\n","export const emitEvent = (element, name, detail, bubbles = true, composed = true) => {\n element.dispatchEvent(\n new CustomEvent(name, { bubbles, composed, detail }),\n );\n};\n","import { css } from 'lit';\n\nexport default css`:host {\n display: block;\n}\n\nfieldset {\n border: 0;\n margin: 0;\n padding: 0;\n display: flex;\n gap: 0.5rem;\n}\n\nlegend {\n margin-bottom: 1rem;\n}\n\n:host([axis=vertical]) fieldset {\n flex-direction: column;\n}\n\n[part=message] {\n display: block;\n margin-top: 0.5rem;\n}\n\n:host([appearance=error]) [part=message] {\n color: var(--kemet-color-font-error);\n}\n\n:host([appearance=warning]) [part=message] {\n color: var(--kemet-color-font-warning);\n}\n`;\n"],"mappings":"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","names":["radio"]}
1
+ {"version":3,"sources":["../../../src/elements/radios/index.ts","../../../src/utilities/decorators.ts","../../../src/utilities/form-controller.ts","../../../src/utilities/events.ts","../../../src/elements/radios/styles.css.ts"],"sourcesContent":["import { html, LitElement } from 'lit';\nimport { customElement, property, state } from '../../utilities/decorators';\nimport { FormSubmitController } from '../../utilities/form-controller';\nimport { emitEvent } from '../../utilities/events';\nimport { EnumAxis, EnumAppearances } from '../../utilities/constants';\nimport type HTMLKemetRadioElement from '../radio';\nimport styles from './styles.css.ts'\n\n\n/**\n * @since 1.0.0\n * @status stable\n *\n * @tagname kemet-radios\n * @summary A group of radio buttons.\n * @ssrsafe yes\n *\n * @prop {string} legend - The legend text for the fieldset\n * @prop {TypeAxis} axis - The direction of the button's layout\n * @prop {string} value - The value of the selected radio button\n * @prop {string} name - The name of the radio button set\n * @prop {EnumAppearances} appearance - The appearance of the radio button set\n * @prop {string} message - Validation message for the user\n * @prop {boolean} required - Determines whether the radio button set is required\n * @prop {'light' | 'dark'} polarity - Determines if the component has a dark or light background\n * @prop {string} dom - The status of dom initalization.\n *\n * @csspart fieldset - The fieldset element.\n * @csspart legend - The legend element.\n *\n * @event kemet-radios-change - Fires when the state of the checkbox changes\n *\n * @fires kemet-radios-mounted - Fired when the radios is mounted to the DOM\n * @detail {HTMLElement} element - The radios element\n *\n */\n\n@customElement('kemet-radios')\nexport default class KemetRadios extends LitElement {\n formSubmitController: FormSubmitController;\n\n static styles = [styles];\n\n @property({ type: String })\n legend: string = '';\n\n @property({ type: String, reflect: true })\n axis: EnumAxis = EnumAxis.Horizontal;\n\n @property({ type: String })\n value!: string;\n\n @property({ type: String })\n name: string = 'radios';\n\n @property({ type: String, reflect: true })\n appearance: EnumAppearances = EnumAppearances.Neutral;\n\n @property({ type: String })\n message!: string;\n\n @property({ type: Boolean })\n required!: boolean;\n\n @property({ type: String, reflect: true })\n polarity?: 'light' | 'dark';\n\n @property({ type: String, reflect: true })\n dom: string = 'initializing';\n\n @state()\n radios!: NodeListOf<HTMLKemetRadioElement>;\n\n constructor() {\n super();\n\n /** @internal */\n this.formSubmitController = new FormSubmitController(this);\n }\n\n firstUpdated() {\n this.radios = this.querySelectorAll('kemet-radio');\n this.setAttribute('role', 'radiogroup');\n\n emitEvent(this, 'kemet-radios-mounted', {\n bubbles: true,\n composed: true,\n detail: {\n element: this,\n },\n });\n this.dom = 'mounted';\n }\n\n render() {\n return html`\n <fieldset part=\"fieldset\">\n ${this.legend !== '' ? html`<legend part=\"legend\">${this.legend}</legend>` : null}\n <slot @click=${(event: MouseEvent) => this.handleClick(event)} @keydown=${(event: KeyboardEvent) => this.handleKeyDown(event)} @slotchange=${() => this.handleSlotChange()}></slot>\n </fieldset>\n ${this.makeMessage()}\n `;\n }\n\n handleClick(event: MouseEvent) {\n const target = event.target as HTMLKemetRadioElement;\n\n this.radios.forEach((radio) => {\n radio.checked = false;\n radio.tabIndex = radio === target ? 0 : -1;\n radio.setAttribute('aria-checked', 'false');\n });\n\n if (!target.disabled) {\n target.checked = true;\n target.setAttribute('aria-checked', 'true');\n this.value = target.value;\n this.appearance = EnumAppearances.Neutral;\n\n emitEvent(this, 'kemet-radios-change', this);\n }\n }\n\n handleKeyDown(event: KeyboardEvent) {\n const radios = Array.from(this.radios);\n const arrowKeys = ['ArrowUp', 'ArrowRight', 'ArrowDown', 'ArrowLeft'];\n const forwardKeys = ['ArrowRight', 'ArrowDown'];\n const shift: number = forwardKeys.includes(event.key) ? 1 : -1;\n const checkedIndex: number | HTMLKemetRadioElement = radios.findIndex((radio: HTMLKemetRadioElement) => radio.checked) ?? radios[0];\n\n let index: number;\n\n if (typeof checkedIndex === 'number') {\n index = checkedIndex + shift;\n } else {\n index = shift;\n }\n\n if (arrowKeys.includes(event.key)) {\n if (index < 0) {\n index = radios.length - 1;\n }\n\n if (index > radios.length - 1) {\n index = 0;\n }\n\n this.radios.forEach((radio) => {\n radio.checked = false;\n radio.tabIndex = -1;\n });\n\n const radio = this.radios[index];\n if (radio) {\n radio.focus();\n radio.checked = true;\n radio.tabIndex = 0;\n }\n }\n }\n\n handleSlotChange() {\n const radios = Array.from(this.radios);\n const checkedRadio = radios.find((radio: HTMLKemetRadioElement) => radio.checked) as HTMLKemetRadioElement;\n\n this.radios.forEach((radio: HTMLKemetRadioElement) => {\n radio.tabIndex = -1;\n radio.input.tabIndex = -1;\n });\n\n if (checkedRadio) {\n checkedRadio.tabIndex = 0;\n }\n }\n\n makeMessage() {\n if (this.appearance === 'error' || this.appearance === 'warning') {\n return html`<span part=\"message\">${this.message}</span>`;\n }\n\n return null;\n }\n\n checkValidity() {\n if (this.required) {\n return !!this.value;\n }\n\n return true;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kemet-radios': KemetRadios\n }\n}\n","export { property, state, query, queryAll } from 'lit/decorators.js';\nimport { customElement as litCustomElement } from 'lit/decorators.js';\n\n/**\n * A drop-in replacement for lit's `customElement` decorator that is safe under\n * hot-module-replacement / live-reload environments where the module may be\n * re-evaluated.\n */\nexport const customElement = (tagName: string) => (classOrDescriptor: any) =>\n typeof customElements !== 'undefined' && !customElements.get(tagName)\n ? litCustomElement(tagName)(classOrDescriptor)\n : classOrDescriptor;\n","export class FormSubmitController {\n host: any;\n form: HTMLFormElement | null | undefined;\n options: {\n form: (input: any) => HTMLFormElement | null | undefined;\n name: (input: any) => string;\n value: (input: any) => any;\n disabled: (input: any) => boolean;\n };\n\n constructor(host: any, options: Partial<{\n form: (input: any) => HTMLFormElement | null | undefined;\n name: (input: any) => string;\n value: (input: any) => any;\n disabled: (input: any) => boolean;\n }> = {}) {\n (this.host = host).addController(this);\n\n this.options = {\n form: (input: any) => input.closest('form'),\n name: (input: any) => input.name,\n value: (input: any) => input.value,\n disabled: (input: any) => input.disabled,\n ...options,\n };\n\n this.handleFormData = this.handleFormData.bind(this);\n this.handleFormSubmit = this.handleFormSubmit.bind(this);\n }\n\n hostConnected() {\n this.form = this.options.form(this.host);\n\n if (this.form) {\n this.form.addEventListener('formdata', this.handleFormData);\n this.form.addEventListener('submit', this.handleFormSubmit);\n }\n }\n\n hostDisconnected() {\n if (this.form) {\n this.form.removeEventListener('formdata', this.handleFormData);\n this.form.removeEventListener('submit', this.handleFormSubmit);\n this.form = undefined;\n }\n }\n\n handleFormData(event: FormDataEvent) {\n const disabled = this.options.disabled(this.host);\n const name = this.options.name(this.host);\n const value = this.options.value(this.host);\n\n if (!disabled && typeof name === 'string' && typeof value !== 'undefined') {\n // TODO recreate a scenario where value will be an array\n // if (Array.isArray(value)) {\n // value.forEach((val) => {\n // event.formData?.append(name, val.toString());\n // });\n // } else {\n // event.formData?.append(name, value.toString());\n // }\n event.formData?.append(name, value.toString());\n }\n }\n\n handleFormSubmit(event: SubmitEvent) {\n event.preventDefault();\n event.stopImmediatePropagation();\n\n const disabled = this.options.disabled(this.host);\n this.form = this.options.form(this.host);\n\n if (this.form && !disabled) {\n const components = this.form.querySelectorAll('kemet-input, kemet-textarea, kemet-select, kemet-checkbox, kemet-radios');\n\n components.forEach((component: any) => {\n if (component.checkValidity) {\n component.checkValidity();\n\n if (!component.checkValidity()) {\n component.status = 'error';\n component.invalid = true;\n\n component.dispatchEvent(\n new CustomEvent('kemet-input-status', {\n bubbles: true,\n composed: true,\n detail: {\n status: 'error',\n validity: component.validity ? component.validity : {},\n element: component,\n },\n }),\n );\n }\n\n if (component.checkLimitValidity && !component.checkLimitValidity()) {\n component.status = 'error';\n component.invalid = true;\n\n component.dispatchEvent(\n new CustomEvent('kemet-input-status', {\n bubbles: true,\n composed: true,\n detail: {\n status: 'error',\n validity: { passedLimit: true },\n element: component,\n },\n }),\n );\n }\n }\n });\n }\n }\n\n submit() {\n const button = document.createElement('button');\n\n if (this.form) {\n button.type = 'submit';\n button.style.position = 'absolute';\n button.style.width = '0';\n button.style.height = '0';\n button.style.clip = 'rect(0 0 0 0)';\n button.style.clipPath = 'inset(50%)';\n button.style.overflow = 'hidden';\n button.style.whiteSpace = 'nowrap';\n this.form.append(button);\n button.click();\n button.remove();\n }\n }\n}\n","export const emitEvent = (element, name, detail, bubbles = true, composed = true) => {\n element.dispatchEvent(\n new CustomEvent(name, { bubbles, composed, detail }),\n );\n};\n","import { css } from 'lit';\n\nexport default css`:host {\n display: block;\n}\n\nfieldset {\n border: 0;\n margin: 0;\n padding: 0;\n display: flex;\n gap: 0.5rem;\n}\n\nlegend {\n margin-bottom: 1rem;\n}\n\n:host([axis=vertical]) fieldset {\n flex-direction: column;\n}\n\n[part=message] {\n display: block;\n margin-top: 0.5rem;\n}\n\n:host([appearance=error]) [part=message] {\n color: var(--kemet-color-font-error);\n}\n\n:host([appearance=warning]) [part=message] {\n color: var(--kemet-color-font-warning);\n}\n`;\n"],"mappings":";;;;;;;;;;;;AAAA,SAAS,MAAM,kBAAkB;;;ACAjC,SAAS,UAAU,OAAO,OAAO,gBAAgB;AACjD,SAAS,iBAAiB,wBAAwB;AAO3C,IAAM,gBAAgB,CAAC,YAAoB,CAAC,sBACjD,OAAO,mBAAmB,eAAe,CAAC,eAAe,IAAI,OAAO,IAChE,iBAAiB,OAAO,EAAE,iBAAiB,IAC3C;;;ACXC,IAAM,uBAAN,MAA2B;AAAA,EAUhC,YAAY,MAAW,UAKlB,CAAC,GAAG;AACP,KAAC,KAAK,OAAO,MAAM,cAAc,IAAI;AAErC,SAAK,UAAU;AAAA,MACb,MAAM,CAAC,UAAe,MAAM,QAAQ,MAAM;AAAA,MAC1C,MAAM,CAAC,UAAe,MAAM;AAAA,MAC5B,OAAO,CAAC,UAAe,MAAM;AAAA,MAC7B,UAAU,CAAC,UAAe,MAAM;AAAA,MAChC,GAAG;AAAA,IACL;AAEA,SAAK,iBAAiB,KAAK,eAAe,KAAK,IAAI;AACnD,SAAK,mBAAmB,KAAK,iBAAiB,KAAK,IAAI;AAAA,EACzD;AAAA,EAEA,gBAAgB;AACd,SAAK,OAAO,KAAK,QAAQ,KAAK,KAAK,IAAI;AAEvC,QAAI,KAAK,MAAM;AACb,WAAK,KAAK,iBAAiB,YAAY,KAAK,cAAc;AAC1D,WAAK,KAAK,iBAAiB,UAAU,KAAK,gBAAgB;AAAA,IAC5D;AAAA,EACF;AAAA,EAEA,mBAAmB;AACjB,QAAI,KAAK,MAAM;AACb,WAAK,KAAK,oBAAoB,YAAY,KAAK,cAAc;AAC7D,WAAK,KAAK,oBAAoB,UAAU,KAAK,gBAAgB;AAC7D,WAAK,OAAO;AAAA,IACd;AAAA,EACF;AAAA,EAEA,eAAe,OAAsB;AACnC,UAAM,WAAW,KAAK,QAAQ,SAAS,KAAK,IAAI;AAChD,UAAM,OAAO,KAAK,QAAQ,KAAK,KAAK,IAAI;AACxC,UAAM,QAAQ,KAAK,QAAQ,MAAM,KAAK,IAAI;AAE1C,QAAI,CAAC,YAAY,OAAO,SAAS,YAAY,OAAO,UAAU,aAAa;AASzE,YAAM,UAAU,OAAO,MAAM,MAAM,SAAS,CAAC;AAAA,IAC/C;AAAA,EACF;AAAA,EAEA,iBAAiB,OAAoB;AACnC,UAAM,eAAe;AACrB,UAAM,yBAAyB;AAE/B,UAAM,WAAW,KAAK,QAAQ,SAAS,KAAK,IAAI;AAChD,SAAK,OAAO,KAAK,QAAQ,KAAK,KAAK,IAAI;AAEvC,QAAI,KAAK,QAAQ,CAAC,UAAU;AAC1B,YAAM,aAAa,KAAK,KAAK,iBAAiB,yEAAyE;AAEvH,iBAAW,QAAQ,CAAC,cAAmB;AACrC,YAAI,UAAU,eAAe;AAC3B,oBAAU,cAAc;AAExB,cAAI,CAAC,UAAU,cAAc,GAAG;AAC9B,sBAAU,SAAS;AACnB,sBAAU,UAAU;AAEpB,sBAAU;AAAA,cACR,IAAI,YAAY,sBAAsB;AAAA,gBACpC,SAAS;AAAA,gBACT,UAAU;AAAA,gBACV,QAAQ;AAAA,kBACN,QAAQ;AAAA,kBACR,UAAU,UAAU,WAAW,UAAU,WAAW,CAAC;AAAA,kBACrD,SAAS;AAAA,gBACX;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAEA,cAAI,UAAU,sBAAsB,CAAC,UAAU,mBAAmB,GAAG;AACnE,sBAAU,SAAS;AACnB,sBAAU,UAAU;AAEpB,sBAAU;AAAA,cACR,IAAI,YAAY,sBAAsB;AAAA,gBACpC,SAAS;AAAA,gBACT,UAAU;AAAA,gBACV,QAAQ;AAAA,kBACN,QAAQ;AAAA,kBACR,UAAU,EAAE,aAAa,KAAK;AAAA,kBAC9B,SAAS;AAAA,gBACX;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,SAAS;AACP,UAAM,SAAS,SAAS,cAAc,QAAQ;AAE9C,QAAI,KAAK,MAAM;AACb,aAAO,OAAO;AACd,aAAO,MAAM,WAAW;AACxB,aAAO,MAAM,QAAQ;AACrB,aAAO,MAAM,SAAS;AACtB,aAAO,MAAM,OAAO;AACpB,aAAO,MAAM,WAAW;AACxB,aAAO,MAAM,WAAW;AACxB,aAAO,MAAM,aAAa;AAC1B,WAAK,KAAK,OAAO,MAAM;AACvB,aAAO,MAAM;AACb,aAAO,OAAO;AAAA,IAChB;AAAA,EACF;AACF;;;ACtIO,IAAM,YAAY,CAAC,SAAS,MAAM,QAAQ,UAAU,MAAM,WAAW,SAAS;AACnF,UAAQ;AAAA,IACN,IAAI,YAAY,MAAM,EAAE,SAAS,UAAU,OAAO,CAAC;AAAA,EACrD;AACF;;;ACJA,SAAS,WAAW;AAEpB,IAAO,qBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AJoCf,IAAqB,cAArB,cAAyC,WAAW;AAAA,EAmClD,cAAc;AACZ,UAAM;AA9BR,kBAAiB;AAGjB;AAMA,gBAAe;AAGf;AAYA,eAAc;AASZ,SAAK,uBAAuB,IAAI,qBAAqB,IAAI;AAAA,EAC3D;AAAA,EAEA,eAAe;AACb,SAAK,SAAS,KAAK,iBAAiB,aAAa;AACjD,SAAK,aAAa,QAAQ,YAAY;AAEtC,cAAU,MAAM,wBAAwB;AAAA,MACtC,SAAS;AAAA,MACT,UAAU;AAAA,MACV,QAAQ;AAAA,QACN,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AACD,SAAK,MAAM;AAAA,EACb;AAAA,EAEA,SAAS;AACP,WAAO;AAAA;AAAA,UAED,KAAK,WAAW,KAAK,6BAA6B,KAAK,MAAM,cAAc,IAAI;AAAA,uBAClE,CAAC,UAAsB,KAAK,YAAY,KAAK,CAAC,aAAa,CAAC,UAAyB,KAAK,cAAc,KAAK,CAAC,gBAAgB,MAAM,KAAK,iBAAiB,CAAC;AAAA;AAAA,QAE1K,KAAK,YAAY,CAAC;AAAA;AAAA,EAExB;AAAA,EAEA,YAAY,OAAmB;AAC7B,UAAM,SAAS,MAAM;AAErB,SAAK,OAAO,QAAQ,CAAC,UAAU;AAC7B,YAAM,UAAU;AAChB,YAAM,WAAW,UAAU,SAAS,IAAI;AACxC,YAAM,aAAa,gBAAgB,OAAO;AAAA,IAC5C,CAAC;AAED,QAAI,CAAC,OAAO,UAAU;AACpB,aAAO,UAAU;AACjB,aAAO,aAAa,gBAAgB,MAAM;AAC1C,WAAK,QAAQ,OAAO;AACpB,WAAK;AAEL,gBAAU,MAAM,uBAAuB,IAAI;AAAA,IAC7C;AAAA,EACF;AAAA,EAEA,cAAc,OAAsB;AAClC,UAAM,SAAS,MAAM,KAAK,KAAK,MAAM;AACrC,UAAM,YAAY,CAAC,WAAW,cAAc,aAAa,WAAW;AACpE,UAAM,cAAc,CAAC,cAAc,WAAW;AAC9C,UAAM,QAAgB,YAAY,SAAS,MAAM,GAAG,IAAI,IAAI;AAC5D,UAAM,eAA+C,OAAO,UAAU,CAAC,UAAiC,MAAM,OAAO,KAAK,OAAO,CAAC;AAElI,QAAI;AAEJ,QAAI,OAAO,iBAAiB,UAAU;AACpC,cAAQ,eAAe;AAAA,IACzB,OAAO;AACL,cAAQ;AAAA,IACV;AAEA,QAAI,UAAU,SAAS,MAAM,GAAG,GAAG;AACjC,UAAI,QAAQ,GAAG;AACb,gBAAQ,OAAO,SAAS;AAAA,MAC1B;AAEA,UAAI,QAAQ,OAAO,SAAS,GAAG;AAC7B,gBAAQ;AAAA,MACV;AAEA,WAAK,OAAO,QAAQ,CAACA,WAAU;AAC7B,QAAAA,OAAM,UAAU;AAChB,QAAAA,OAAM,WAAW;AAAA,MACnB,CAAC;AAED,YAAM,QAAQ,KAAK,OAAO,KAAK;AAC/B,UAAI,OAAO;AACT,cAAM,MAAM;AACZ,cAAM,UAAU;AAChB,cAAM,WAAW;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,mBAAmB;AACjB,UAAM,SAAS,MAAM,KAAK,KAAK,MAAM;AACrC,UAAM,eAAe,OAAO,KAAK,CAAC,UAAiC,MAAM,OAAO;AAEhF,SAAK,OAAO,QAAQ,CAAC,UAAiC;AACpD,YAAM,WAAW;AACjB,YAAM,MAAM,WAAW;AAAA,IACzB,CAAC;AAED,QAAI,cAAc;AAChB,mBAAa,WAAW;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,cAAc;AACZ,QAAI,KAAK,eAAe,WAAW,KAAK,eAAe,WAAW;AAChE,aAAO,4BAA4B,KAAK,OAAO;AAAA,IACjD;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,gBAAgB;AACd,QAAI,KAAK,UAAU;AACjB,aAAO,CAAC,CAAC,KAAK;AAAA,IAChB;AAEA,WAAO;AAAA,EACT;AACF;AAxJqB,YAGZ,SAAS,CAAC,kBAAM;AAGvB;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GALP,YAMnB;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GARtB,YASnB;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAXP,YAYnB;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAdP,YAenB;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAjBtB,YAkBnB;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GApBP,YAqBnB;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,CAAC;AAAA,GAvBR,YAwBnB;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GA1BtB,YA2BnB;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GA7BtB,YA8BnB;AAGA;AAAA,EADC,MAAM;AAAA,GAhCY,YAiCnB;AAjCmB,cAArB;AAAA,EADC,cAAc,cAAc;AAAA,GACR;","names":["radio"]}
@@ -12,6 +12,7 @@ declare enum EnumEffects {
12
12
  *
13
13
  * @tagname kemet-rotator
14
14
  * @summary A component that rotates through an array of text.
15
+ * @ssrsafe yes
15
16
  *
16
17
  * @prop {number} activeSlide - The index number for the current slide.
17
18
  * @prop {array} messages - Text in the rotator. Supports HTML.