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.
- package/README.md +1 -1
- package/custom-elements.json +3355 -3272
- package/dist/{constants-W9QKPlZP.d.ts → constants-CHvA2ed5.d.ts} +13 -0
- package/dist/elements/accordion/index.d.ts +1 -0
- package/dist/elements/accordion/index.js +5 -1
- package/dist/elements/accordion/index.js.map +1 -1
- package/dist/elements/accordion-panel/index.d.ts +1 -0
- package/dist/elements/accordion-panel/index.js +5 -1
- package/dist/elements/accordion-panel/index.js.map +1 -1
- package/dist/elements/alert/index.d.ts +2 -1
- package/dist/elements/alert/index.js +5 -1
- package/dist/elements/alert/index.js.map +1 -1
- package/dist/elements/avatar/index.d.ts +2 -1
- package/dist/elements/avatar/index.js +5 -1
- package/dist/elements/avatar/index.js.map +1 -1
- package/dist/elements/avatars/index.d.ts +1 -0
- package/dist/elements/avatars/index.js +5 -1
- package/dist/elements/avatars/index.js.map +1 -1
- package/dist/elements/badge/index.d.ts +2 -1
- package/dist/elements/badge/index.js +5 -1
- package/dist/elements/badge/index.js.map +1 -1
- package/dist/elements/button/index.d.ts +2 -1
- package/dist/elements/button/index.js +5 -1
- package/dist/elements/button/index.js.map +1 -1
- package/dist/elements/card/index.d.ts +2 -1
- package/dist/elements/card/index.js +5 -1
- package/dist/elements/card/index.js.map +1 -1
- package/dist/elements/checkbox/index.d.ts +2 -1
- package/dist/elements/checkbox/index.js +7 -1
- package/dist/elements/checkbox/index.js.map +1 -1
- package/dist/elements/combo/index.d.ts +1 -1
- package/dist/elements/combo/index.js +5 -1
- package/dist/elements/combo/index.js.map +1 -1
- package/dist/elements/count/index.d.ts +1 -1
- package/dist/elements/count/index.js +28 -1
- package/dist/elements/count/index.js.map +1 -1
- package/dist/elements/dialog/index.d.ts +2 -1
- package/dist/elements/dialog/index.js +5 -1
- package/dist/elements/dialog/index.js.map +1 -1
- package/dist/elements/dialog-close/index.d.ts +1 -0
- package/dist/elements/dialog-close/index.js +5 -1
- package/dist/elements/dialog-close/index.js.map +1 -1
- package/dist/elements/drawer/effects.js +1 -1
- package/dist/elements/drawer/effects.js.map +1 -1
- package/dist/elements/drawer/index.d.ts +1 -0
- package/dist/elements/drawer/index.js +6 -2
- package/dist/elements/drawer/index.js.map +1 -1
- package/dist/elements/fab/index.d.ts +2 -1
- package/dist/elements/fab/index.js +5 -1
- package/dist/elements/fab/index.js.map +1 -1
- package/dist/elements/field/index.d.ts +1 -1
- package/dist/elements/field/index.js +5 -1
- package/dist/elements/field/index.js.map +1 -1
- package/dist/elements/flipcard/index.d.ts +2 -1
- package/dist/elements/flipcard/index.js +5 -1
- package/dist/elements/flipcard/index.js.map +1 -1
- package/dist/elements/flipcard-trigger/index.d.ts +1 -0
- package/dist/elements/flipcard-trigger/index.js +5 -1
- package/dist/elements/flipcard-trigger/index.js.map +1 -1
- package/dist/elements/icon/index.d.ts +2 -1
- package/dist/elements/icon/index.js +8 -2
- package/dist/elements/icon/index.js.map +1 -1
- package/dist/elements/input/index.d.ts +1 -1
- package/dist/elements/input/index.js +9 -3
- package/dist/elements/input/index.js.map +1 -1
- package/dist/elements/input/styles.css.js +2 -2
- package/dist/elements/input/styles.css.js.map +1 -1
- package/dist/elements/input-combo/index.d.ts +2 -1
- package/dist/elements/input-combo/index.js +7 -1
- package/dist/elements/input-combo/index.js.map +1 -1
- package/dist/elements/input-file/index.d.ts +1 -1
- package/dist/elements/input-file/index.js +39 -249
- package/dist/elements/input-file/index.js.map +1 -1
- package/dist/elements/input-file/styles.css.js +8 -8
- package/dist/elements/input-file/styles.css.js.map +1 -1
- package/dist/elements/input-files/index.d.ts +1 -1
- package/dist/elements/input-files/index.js +29 -237
- package/dist/elements/input-files/index.js.map +1 -1
- package/dist/elements/input-files/styles.css.js +2 -2
- package/dist/elements/input-files/styles.css.js.map +1 -1
- package/dist/elements/input-otp/index.d.ts +1 -0
- package/dist/elements/input-otp/index.js +5 -1
- package/dist/elements/input-otp/index.js.map +1 -1
- package/dist/elements/loader/index.d.ts +1 -0
- package/dist/elements/loader/index.js +5 -1
- package/dist/elements/loader/index.js.map +1 -1
- package/dist/elements/password/index.d.ts +2 -2
- package/dist/elements/password/index.js +24 -234
- package/dist/elements/password/index.js.map +1 -1
- package/dist/elements/radio/index.d.ts +1 -0
- package/dist/elements/radio/index.js +7 -1
- package/dist/elements/radio/index.js.map +1 -1
- package/dist/elements/radios/index.d.ts +2 -1
- package/dist/elements/radios/index.js +5 -1
- package/dist/elements/radios/index.js.map +1 -1
- package/dist/elements/rotator/index.d.ts +1 -0
- package/dist/elements/rotator/index.js +7 -2
- package/dist/elements/rotator/index.js.map +1 -1
- package/dist/elements/select/index.d.ts +2 -1
- package/dist/elements/select/index.js +28 -25
- package/dist/elements/select/index.js.map +1 -1
- package/dist/elements/select-option/index.d.ts +1 -0
- package/dist/elements/select-option/index.js +7 -1
- package/dist/elements/select-option/index.js.map +1 -1
- package/dist/elements/sortable/index.d.ts +1 -0
- package/dist/elements/sortable/index.js +7 -1
- package/dist/elements/sortable/index.js.map +1 -1
- package/dist/elements/sortable-item/index.d.ts +1 -0
- package/dist/elements/sortable-item/index.js +5 -1
- package/dist/elements/sortable-item/index.js.map +1 -1
- package/dist/elements/tab/index.d.ts +1 -1
- package/dist/elements/tab/index.js +18 -228
- package/dist/elements/tab/index.js.map +1 -1
- package/dist/elements/tab-panel/index.d.ts +1 -0
- package/dist/elements/tab-panel/index.js +5 -1
- package/dist/elements/tab-panel/index.js.map +1 -1
- package/dist/elements/tabs/index.d.ts +3 -2
- package/dist/elements/tabs/index.js +44 -246
- package/dist/elements/tabs/index.js.map +1 -1
- package/dist/elements/textarea/index.d.ts +1 -1
- package/dist/elements/textarea/index.js +9 -3
- package/dist/elements/textarea/index.js.map +1 -1
- package/dist/elements/textarea/styles.css.js +2 -2
- package/dist/elements/textarea/styles.css.js.map +1 -1
- package/dist/elements/timer/index.d.ts +1 -0
- package/dist/elements/timer/index.js +11 -7
- package/dist/elements/timer/index.js.map +1 -1
- package/dist/elements/timer-display/index.d.ts +1 -1
- package/dist/elements/timer-display/index.js +19 -16
- package/dist/elements/timer-display/index.js.map +1 -1
- package/dist/elements/toggle/index.d.ts +1 -0
- package/dist/elements/toggle/index.js +5 -1
- package/dist/elements/toggle/index.js.map +1 -1
- package/dist/elements/tracker/index.d.ts +1 -2
- package/dist/elements/tracker/index.js +10 -19
- package/dist/elements/tracker/index.js.map +1 -1
- package/dist/elements/tracker-step/index.d.ts +1 -2
- package/dist/elements/tracker-step/index.js +46 -240
- package/dist/elements/tracker-step/index.js.map +1 -1
- package/dist/elements/typewriter/index.d.ts +1 -0
- package/dist/elements/typewriter/index.js +7 -1
- package/dist/elements/typewriter/index.js.map +1 -1
- package/dist/{index-h1DTXXCf.d.ts → index-n43o0UmE.d.ts} +13 -7
- package/dist/wrappers/react.d.ts +2 -2
- package/dist/wrappers/react.js +489 -491
- package/dist/wrappers/react.js.map +1 -1
- 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-
|
|
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
|
|
14
|
-
|
|
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/
|
|
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
|
|
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
|
|
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
|
|
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
|
|
171
|
+
return html`<kemet-icon name=${this.icon} size=${this.iconSize}></kemet-icon>`;
|
|
382
172
|
}
|
|
383
|
-
return
|
|
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 = [
|
|
221
|
+
KemetPassword.styles = [styles_css_default];
|
|
432
222
|
__decorateClass([
|
|
433
|
-
|
|
223
|
+
property({ type: Array })
|
|
434
224
|
], KemetPassword.prototype, "rules", 2);
|
|
435
225
|
__decorateClass([
|
|
436
|
-
|
|
226
|
+
property({ type: Boolean, reflect: true })
|
|
437
227
|
], KemetPassword.prototype, "show", 2);
|
|
438
228
|
__decorateClass([
|
|
439
|
-
|
|
229
|
+
property({ type: String })
|
|
440
230
|
], KemetPassword.prototype, "value", 2);
|
|
441
231
|
__decorateClass([
|
|
442
|
-
|
|
232
|
+
property({ type: String })
|
|
443
233
|
], KemetPassword.prototype, "message", 2);
|
|
444
234
|
__decorateClass([
|
|
445
|
-
|
|
235
|
+
property({ type: String })
|
|
446
236
|
], KemetPassword.prototype, "strength", 2);
|
|
447
237
|
__decorateClass([
|
|
448
|
-
|
|
238
|
+
property({ type: String })
|
|
449
239
|
], KemetPassword.prototype, "icon", 2);
|
|
450
240
|
__decorateClass([
|
|
451
|
-
|
|
241
|
+
property({ type: Number })
|
|
452
242
|
], KemetPassword.prototype, "iconSize", 2);
|
|
453
243
|
__decorateClass([
|
|
454
|
-
|
|
244
|
+
state()
|
|
455
245
|
], KemetPassword.prototype, "appearance", 2);
|
|
456
246
|
__decorateClass([
|
|
457
|
-
|
|
247
|
+
state()
|
|
458
248
|
], KemetPassword.prototype, "field", 2);
|
|
459
249
|
__decorateClass([
|
|
460
|
-
|
|
250
|
+
state()
|
|
461
251
|
], KemetPassword.prototype, "input", 2);
|
|
462
252
|
KemetPassword = __decorateClass([
|
|
463
|
-
|
|
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":";;;;;;;;;;;;AAAA,SAAS,QAAAA,OAAM,cAAAC,mBAA6C;AAC5D,SAAS,iBAAAC,gBAAe,YAAAC,WAAU,SAAAC,cAAa;;;ACDxC,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,MAA0B,kBAA6B;AAChE,SAAS,eAAe,UAAU,aAAa;AAC/C,SAAS,wBAAwB;;;ACFjC,SAAS,WAAW;AAEpB,IAAO,qBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ADIf,IAAM,kBAAkB,uBAAO;AAC/B,IAAM,kBAAkB,uBAAO;AAG/B,IAAI;AACJ,IAAM,YAAY,oBAAI,IAAgC;AAGtD,IAAM,0BAA0B;AAChC,IAAM,eAAkC,CAAC;AACzC,IAAI,iBAAiB;AAErB,SAAS,aAAa,UAAsB;AAC1C,MAAI,iBAAiB,yBAAyB;AAC5C;AACA,aAAS;AAAA,EACX,OAAO;AACL,iBAAa,KAAK,QAAQ;AAAA,EAC5B;AACF;AAEA,SAAS,kBAAkB;AACzB;AACA,MAAI,aAAa,SAAS,GAAG;AAC3B,UAAM,cAAc,aAAa,MAAM;AACvC,QAAI,aAAa;AACf;AACA,kBAAY;AAAA,IACd;AAAA,EACF;AACF;AA4BA,IAAqB,YAArB,cAAuC,WAAW;AAAA,EAAlD;AAAA;AAIE,gBAAe;AAGf,mBAAkB;AAGlB,kBAAiB;AAGjB,gBAAe;AASf,eAAc;AAId,SAAQ,MAA8C;AAItD,SAAQ,MAAc;AAGtB;AAAA,SAAQ,YAAqB;AAAA;AAAA,EAE7B,oBAAoB;AAClB,UAAM,kBAAkB;AAExB,SAAK,UAAU;AACf,QAAI,CAAC,KAAK,KAAK;AACb,WAAK,YAAY;AACjB,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AAAA,EAEA,UAAU;AACR,SAAK,UAAU;AACf,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,eAAe;AACb,cAAU,MAAM,sBAAsB;AAAA,MACpC,SAAS;AAAA,MACT,UAAU;AAAA,MACV,QAAQ;AAAA,QACN,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AACD,SAAK,MAAM;AAAA,EACb;AAAA,EAEA,SAAS;AAEP,QAAI,KAAK,KAAK;AACZ,aAAO,KAAK;AAAA,IACd;AAGA,QAAI,CAAC,KAAK,WAAW;AACnB,WAAK,YAAY;AACjB,WAAK,QAAQ;AAAA,IACf;AAEA,WAAO,8BAA8B,KAAK,IAAI,aAAa,KAAK,IAAI;AAAA,EACtE;AAAA;AAAA,EAGO,WAAW;AAChB,SAAK,YAAY;AACjB,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,MAAM,UAAU;AACd,QAAI,CAAC,KAAK,UAAW;AAErB,QAAI,eAAe,UAAU,IAAI,GAAG,KAAK,MAAM,IAAI,KAAK,IAAI,EAAE;AAE9D,QAAI,CAAC,cAAc;AACjB,qBAAe,KAAK,YAAY;AAChC,gBAAU,IAAI,GAAG,KAAK,MAAM,IAAI,KAAK,IAAI,IAAI,YAAY;AAAA,IAC3D;AAEA,UAAM,MAAM,MAAM;AAElB,QAAI,QAAQ,iBAAiB;AAC3B,gBAAU,OAAO,GAAG,KAAK,MAAM,IAAI,KAAK,IAAI,EAAE;AAAA,IAChD;AAEA,QAAI,iBAAiB,GAAG,GAAG;AACzB,WAAK,MAAM;AAAA,IACb,WAAW,eAAe,eAAe;AAEvC,WAAK,MAAM,IAAI,UAAU,IAAI;AAAA,IAC/B;AAAA,EACF;AAAA,EAEQ,YAAY;AAClB,YAAQ,KAAK,SAAS;AAAA,MACpB,KAAK;AACH,aAAK,UAAU,KAAK,WAAW;AAC/B,aAAK,MAAM,mDAAmD,KAAK,OAAO;AAC1E;AAAA,MACF,KAAK;AACH,aAAK,UAAU,KAAK,WAAW;AAC/B,aAAK,MAAM,qCAAqC,KAAK,OAAO;AAC5D;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,MAAc,cAAkC;AAC9C,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,mBAAa,YAAY;AACvB,YAAI;AACJ,YAAI,WAAmB,GAAG,KAAK,GAAG,IAAI,KAAK,MAAM,IAAI,KAAK,IAAI;AAE9D,gBAAQ,KAAK,SAAS;AAAA,UACpB,KAAK;AACH,uBAAW,GAAG,KAAK,GAAG,IAAI,KAAK,MAAM,IAAI,KAAK,IAAI;AAClD;AAAA,UACF,KAAK;AACH,uBAAW,GAAG,KAAK,GAAG,IAAI,KAAK,IAAI;AACnC;AAAA,QACJ;AAEA,YAAI;AACF,qBAAW,MAAM,MAAM,QAAQ;AAC/B,cAAI,CAAC,SAAS,IAAI;AAChB,4BAAgB;AAChB,oBAAQ,SAAS,WAAW,MAAM,kBAAkB,eAAe;AACnE;AAAA,UACF;AAAA,QACF,QAAQ;AACN,0BAAgB;AAChB,kBAAQ,eAAe;AACvB;AAAA,QACF;AAEA,YAAI;AACF,gBAAM,MAAM,SAAS,cAAc,KAAK;AACxC,cAAI,YAAY,MAAM,SAAS,KAAK;AAEpC,gBAAM,MAAM,IAAI;AAChB,cAAI,KAAK,SAAS,YAAY,MAAM,OAAO;AACzC,4BAAgB;AAChB,oBAAQ,eAAe;AACvB;AAAA,UACF;AAEA,cAAI,CAAC,OAAQ,UAAS,IAAI,UAAU;AACpC,gBAAM,MAAM,OAAO,gBAAgB,IAAI,WAAW,WAAW;AAE7D,gBAAM,QAAQ,IAAI,KAAK,cAAc,KAAK;AAC1C,cAAI,CAAC,OAAO;AACV,4BAAgB;AAChB,oBAAQ,eAAe;AACvB;AAAA,UACF;AAEA,gBAAM,KAAK,IAAI,KAAK;AACpB,gBAAM,aAAa,SAAS,GAAG,KAAK,IAAI,IAAI;AAC5C,gBAAM,aAAa,UAAU,GAAG,KAAK,IAAI,IAAI;AAE7C,0BAAgB;AAChB,kBAAQ,SAAS,UAAU,KAAK,CAAC;AAAA,QACnC,QAAQ;AACN,0BAAgB;AAChB,kBAAQ,eAAe;AAAA,QACzB;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEQ,aAAa;AACnB,QAAI,KAAK,KAAK;AACZ,YAAM,MAAM,KAAK;AACjB,UAAI,aAAa,SAAS,GAAG,KAAK,IAAI,IAAI;AAC1C,UAAI,aAAa,UAAU,GAAG,KAAK,IAAI,IAAI;AAAA,IAC7C;AAAA,EACF;AACF;AA7LqB,UACZ,SAAS,CAAC,kBAAM;AAGvB;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAHP,UAInB;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GANP,UAOnB;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GATP,UAUnB;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAZP,UAanB;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAfP,UAgBnB;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAlBtB,UAmBnB;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GArBtB,UAsBnB;AAIQ;AAAA,EADP,MAAM;AAAA,GAzBY,UA0BX;AAIA;AAAA,EADP,MAAM;AAAA,GA7BY,UA8BX;AA9BW,YAArB;AAAA,EADC,cAAc,YAAY;AAAA,GACN;;;AEhErB,SAAS,OAAAC,YAAW;AAEpB,IAAOC,sBAAQD;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;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AJ6Cf,IAAqB,gBAArB,cAA2CE,YAAW;AAAA,EAAtD;AAAA;AAIE,iBAA4B;AAAA,MAC1B,EAAE,SAAS,cAAc,SAAS,6BAA6B;AAAA,MAC/D,EAAE,SAAS,0BAA0B,SAAS,0BAA0B;AAAA,MACxE,EAAE,SAAS,eAAe,SAAS,4BAA4B;AAAA,IACjE;AAGA,gBAAgB;AAMhB,mBAAkB;AAMlB,gBAAe;AAGf,oBAAmB;AAAA;AAAA,EAWnB,eAAe;AAEb,SAAK,QAAQ,KAAK,QAAQ,aAAa;AACvC,SAAK,QAAQ,KAAK,MAAM,cAAc,gBAAgB;AAGtD,SAAK,OAAO,iBAAiB,qBAAqB,KAAK,YAAY,KAAK,IAAI,CAAC;AAAA,EAC/E;AAAA,EAEA,SAAS;AACP,WAAOC;AAAA;AAAA,sBAEW,KAAK,QAAQ;AAAA,kBACjB,KAAK,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAOH,KAAK,OAAO;AAAA;AAAA,YAE5B,KAAK,UAAU,CAAC;AAAA;AAAA;AAAA;AAAA,EAI1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAiC;AAC/B,QAAI,KAAK,OAAO;AACd,aAAO,KAAK,MAAM,IAAI,CAAC,SAAS;AAC9B,cAAM,SAAS,IAAI,OAAO,KAAK,OAAO;AACtC,cAAM,gBAAgB,OAAO,KAAK,KAAK,MAAM,KAAK;AAClD,aAAK,gBAAgB;AACrB,eAAOA,YAAW,KAAK,cAAc,aAAa,CAAC,IAAI,KAAK,OAAO;AAAA,MACrE,CAAC;AAAA,IACH;AAEA,WAAO,CAAC;AAAA,EACV;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,cAAc,eAAwC;AACpD,QAAI,eAAe;AACjB,aAAOA,yBAAwB,KAAK,IAAI,SAAS,KAAK,QAAQ;AAAA,IAChE;AAEA,WAAOA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAY,OAAc;AACxB,SAAK,QAAS,MAAsB,OAAO;AAC3C,SAAK,YAAY;AACjB,SAAK,WAAW;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc;AAIZ,eAAW,MAAM;AACf,YAAM,aAAa,KAAK,MAAM;AAC9B,YAAM,WAAW,KAAK,MAAM,OAAO,UAAQ,KAAK,aAAa,EAAE;AAC/D,YAAM,qBAAqB,KAAK,MAAO,WAAW,aAAc,GAAG,IAAI;AAEvE,UAAI,sBAAsB,MAAM;AAC9B,aAAK,WAAW;AAChB,aAAK;AAAA,MACP;AAEA,UAAI,qBAAqB,QAAQ,sBAAsB,MAAM;AAC3D,aAAK,WAAW;AAChB,aAAK;AAAA,MACP;AAEA,UAAI,qBAAqB,MAAM;AAC7B,aAAK,WAAW;AAChB,aAAK;AAAA,MACP;AAEA,gBAAU,MAAM,kCAAkC;AAAA,QAChD,YAAY,KAAK;AAAA,QACjB,uBAAuB,KAAK;AAAA,QAC5B,SAAS;AAAA,MACX,CAAC;AAAA,IACH,GAAG,CAAC;AAAA,EACN;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa;AACX,SAAK,OAAO,KAAK,MAAM,SAAS;AAAA,EAClC;AACF;AAvJqB,cACZ,SAAS,CAACC,mBAAM;AAGvB;AAAA,EADCC,UAAS,EAAE,MAAM,MAAM,CAAC;AAAA,GAHN,cAInB;AAOA;AAAA,EADCA,UAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAVvB,cAWnB;AAGA;AAAA,EADCA,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAbP,cAcnB;AAGA;AAAA,EADCA,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAhBP,cAiBnB;AAGA;AAAA,EADCA,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAnBP,cAoBnB;AAGA;AAAA,EADCA,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAtBP,cAuBnB;AAGA;AAAA,EADCA,UAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAzBP,cA0BnB;AAGA;AAAA,EADCC,OAAM;AAAA,GA5BY,cA6BnB;AAGA;AAAA,EADCA,OAAM;AAAA,GA/BY,cAgCnB;AAGA;AAAA,EADCA,OAAM;AAAA,GAlCY,cAmCnB;AAnCmB,gBAArB;AAAA,EADCC,eAAc,gBAAgB;AAAA,GACV;","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
|
-
|
|
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-
|
|
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
|
-
|
|
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":"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","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.
|