@phcdevworks/spectre-components 0.0.1

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 (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +177 -0
  3. package/dist/button.cjs +288 -0
  4. package/dist/button.cjs.map +1 -0
  5. package/dist/button.d.cts +142 -0
  6. package/dist/button.d.ts +142 -0
  7. package/dist/button.js +282 -0
  8. package/dist/button.js.map +1 -0
  9. package/dist/checkbox.cjs +158 -0
  10. package/dist/checkbox.cjs.map +1 -0
  11. package/dist/checkbox.d.cts +98 -0
  12. package/dist/checkbox.d.ts +98 -0
  13. package/dist/checkbox.js +155 -0
  14. package/dist/checkbox.js.map +1 -0
  15. package/dist/fieldset.cjs +179 -0
  16. package/dist/fieldset.cjs.map +1 -0
  17. package/dist/fieldset.d.cts +63 -0
  18. package/dist/fieldset.d.ts +63 -0
  19. package/dist/fieldset.js +176 -0
  20. package/dist/fieldset.js.map +1 -0
  21. package/dist/index.cjs +1600 -0
  22. package/dist/index.cjs.map +1 -0
  23. package/dist/index.d.cts +14 -0
  24. package/dist/index.d.ts +14 -0
  25. package/dist/index.js +1576 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/input.cjs +235 -0
  28. package/dist/input.cjs.map +1 -0
  29. package/dist/input.d.cts +175 -0
  30. package/dist/input.d.ts +175 -0
  31. package/dist/input.js +230 -0
  32. package/dist/input.js.map +1 -0
  33. package/dist/label.cjs +156 -0
  34. package/dist/label.cjs.map +1 -0
  35. package/dist/label.d.cts +39 -0
  36. package/dist/label.d.ts +39 -0
  37. package/dist/label.js +153 -0
  38. package/dist/label.js.map +1 -0
  39. package/dist/radio.cjs +158 -0
  40. package/dist/radio.cjs.map +1 -0
  41. package/dist/radio.d.cts +98 -0
  42. package/dist/radio.d.ts +98 -0
  43. package/dist/radio.js +155 -0
  44. package/dist/radio.js.map +1 -0
  45. package/dist/select.cjs +272 -0
  46. package/dist/select.cjs.map +1 -0
  47. package/dist/select.d.cts +130 -0
  48. package/dist/select.d.ts +130 -0
  49. package/dist/select.js +268 -0
  50. package/dist/select.js.map +1 -0
  51. package/dist/textarea.cjs +423 -0
  52. package/dist/textarea.cjs.map +1 -0
  53. package/dist/textarea.d.cts +156 -0
  54. package/dist/textarea.d.ts +156 -0
  55. package/dist/textarea.js +420 -0
  56. package/dist/textarea.js.map +1 -0
  57. package/package.json +124 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,1600 @@
1
+ 'use strict';
2
+
3
+ var lit = require('lit');
4
+ var ifDefined_js = require('lit/directives/if-defined.js');
5
+ var spectreUi = require('@phcdevworks/spectre-ui');
6
+ var live_js = require('lit/directives/live.js');
7
+
8
+ // src/components/button/sp-button.ts
9
+ var spectreButtonVariants = [
10
+ "primary",
11
+ "secondary",
12
+ "ghost",
13
+ "danger",
14
+ "success",
15
+ "cta",
16
+ "accent"
17
+ ];
18
+ var spectreButtonSizes = ["sm", "md", "lg"];
19
+ var spectreButtonTypes = ["button", "submit", "reset"];
20
+ function isButtonVariant(value) {
21
+ return spectreButtonVariants.includes(value);
22
+ }
23
+ function isButtonSize(value) {
24
+ return spectreButtonSizes.includes(value);
25
+ }
26
+ function isButtonType(value) {
27
+ return spectreButtonTypes.includes(value);
28
+ }
29
+ function hasMeaningfulContent(nodes) {
30
+ return nodes.some((node) => {
31
+ if (node.nodeType === Node.ELEMENT_NODE) {
32
+ return true;
33
+ }
34
+ if (node.nodeType === Node.TEXT_NODE) {
35
+ return (node.textContent?.trim().length ?? 0) > 0;
36
+ }
37
+ return false;
38
+ });
39
+ }
40
+ var SpectreButtonElement = class extends lit.LitElement {
41
+ constructor() {
42
+ super(...arguments);
43
+ this.ariaLabel = null;
44
+ this.ariaLabelledBy = null;
45
+ this.ariaDescribedBy = null;
46
+ this.autofocus = false;
47
+ this.disabled = false;
48
+ this.fullWidth = false;
49
+ this.loading = false;
50
+ this.loadingLabel = "Loading";
51
+ this.pill = false;
52
+ this.size = "md";
53
+ this.title = "";
54
+ this.type = "button";
55
+ this.variant = "primary";
56
+ // Native slot projection is a Shadow DOM feature, so in light DOM we keep
57
+ // host-provided content reactive by tracking and reusing the host nodes.
58
+ this.projectedContent = [];
59
+ }
60
+ get id() {
61
+ return this._id ?? "";
62
+ }
63
+ set id(value) {
64
+ if ((this._id ?? "") === value) {
65
+ return;
66
+ }
67
+ this._id = value;
68
+ const host = this;
69
+ if (HTMLElement.prototype.hasAttribute.call(host, "id")) {
70
+ HTMLElement.prototype.removeAttribute.call(host, "id");
71
+ }
72
+ this.requestUpdate();
73
+ }
74
+ createRenderRoot() {
75
+ return this;
76
+ }
77
+ connectedCallback() {
78
+ super.connectedCallback();
79
+ const hostId = super.getAttribute("id");
80
+ if (hostId !== null) {
81
+ this.id = hostId;
82
+ }
83
+ this.syncProjectedContent();
84
+ this.startContentObserver();
85
+ }
86
+ getAttribute(qualifiedName) {
87
+ if (qualifiedName === "id") {
88
+ return this.id || null;
89
+ }
90
+ return super.getAttribute(qualifiedName);
91
+ }
92
+ hasAttribute(qualifiedName) {
93
+ if (qualifiedName === "id") {
94
+ return this.id !== "";
95
+ }
96
+ return super.hasAttribute(qualifiedName);
97
+ }
98
+ setAttribute(qualifiedName, value) {
99
+ if (qualifiedName === "id") {
100
+ this.id = value;
101
+ return;
102
+ }
103
+ super.setAttribute(qualifiedName, value);
104
+ }
105
+ removeAttribute(qualifiedName) {
106
+ if (qualifiedName === "id") {
107
+ this.id = "";
108
+ return;
109
+ }
110
+ super.removeAttribute(qualifiedName);
111
+ }
112
+ disconnectedCallback() {
113
+ this.stopContentObserver();
114
+ super.disconnectedCallback();
115
+ }
116
+ willUpdate(changedProperties) {
117
+ if (changedProperties.has("variant") && !isButtonVariant(this.variant)) {
118
+ this.variant = "primary";
119
+ }
120
+ if (changedProperties.has("size") && !isButtonSize(this.size)) {
121
+ this.size = "md";
122
+ }
123
+ if (changedProperties.has("type") && !isButtonType(this.type)) {
124
+ this.type = "button";
125
+ }
126
+ if (changedProperties.has("loadingLabel")) {
127
+ if (this.loadingLabel == null || this.loadingLabel.trim() === "") {
128
+ this.loadingLabel = "Loading";
129
+ }
130
+ }
131
+ }
132
+ update(changedProperties) {
133
+ this.stopContentObserver();
134
+ super.update(changedProperties);
135
+ this.startContentObserver();
136
+ }
137
+ get buttonClasses() {
138
+ return spectreUi.getButtonClasses({
139
+ disabled: this.isDisabled,
140
+ fullWidth: this.fullWidth,
141
+ loading: this.loading,
142
+ pill: this.pill,
143
+ size: this.size,
144
+ variant: this.variant
145
+ });
146
+ }
147
+ get isDisabled() {
148
+ return this.disabled || this.loading;
149
+ }
150
+ get hasProjectedContent() {
151
+ return hasMeaningfulContent(this.projectedContent);
152
+ }
153
+ get visibleLabelFallback() {
154
+ const trimmedLabel = this.label?.trim();
155
+ return trimmedLabel ? trimmedLabel : void 0;
156
+ }
157
+ get forwardedAriaLabel() {
158
+ const ariaLabel = this.ariaLabel?.trim();
159
+ return ariaLabel ? ariaLabel : void 0;
160
+ }
161
+ get forwardedAriaLabelledBy() {
162
+ const ariaLabelledBy = this.ariaLabelledBy?.trim();
163
+ return ariaLabelledBy ? ariaLabelledBy : void 0;
164
+ }
165
+ get forwardedAriaDescribedBy() {
166
+ const ariaDescribedBy = this.ariaDescribedBy?.trim();
167
+ return ariaDescribedBy ? ariaDescribedBy : void 0;
168
+ }
169
+ startContentObserver() {
170
+ if (this.contentObserver) {
171
+ return;
172
+ }
173
+ this.contentObserver = new MutationObserver((mutations) => {
174
+ const isInternalMovement = mutations.every((mutation) => {
175
+ return Array.from(mutation.removedNodes).every(
176
+ (node) => this.isInternalButtonNode(node) || this.contains(node)
177
+ ) && Array.from(mutation.addedNodes).every((node) => this.isInternalButtonNode(node));
178
+ });
179
+ if (isInternalMovement) {
180
+ return;
181
+ }
182
+ if (this.syncProjectedContent()) {
183
+ this.requestUpdate();
184
+ }
185
+ });
186
+ this.contentObserver.observe(this, {
187
+ childList: true
188
+ });
189
+ }
190
+ stopContentObserver() {
191
+ this.contentObserver?.disconnect();
192
+ this.contentObserver = void 0;
193
+ }
194
+ syncProjectedContent() {
195
+ const nextProjectedContent = [];
196
+ Array.from(this.childNodes).forEach((node) => {
197
+ if (this.isInternalButtonNode(node)) {
198
+ this.projectedContent.forEach((pNode) => {
199
+ if (pNode.parentNode !== this && this.contains(pNode)) {
200
+ nextProjectedContent.push(pNode);
201
+ }
202
+ });
203
+ } else {
204
+ nextProjectedContent.push(node);
205
+ }
206
+ });
207
+ const hasChanged = nextProjectedContent.length !== this.projectedContent.length || nextProjectedContent.some((node, index) => node !== this.projectedContent[index]);
208
+ if (hasChanged) {
209
+ this.projectedContent = nextProjectedContent;
210
+ }
211
+ return hasChanged;
212
+ }
213
+ isInternalButtonNode(node) {
214
+ return node.nodeType === Node.ELEMENT_NODE && node.hasAttribute("data-sp-button-native");
215
+ }
216
+ get nativeButton() {
217
+ return this.querySelector("[data-sp-button-native]");
218
+ }
219
+ focus(options) {
220
+ this.nativeButton?.focus(options);
221
+ }
222
+ blur() {
223
+ this.nativeButton?.blur();
224
+ }
225
+ renderButtonContent() {
226
+ if (this.loading) {
227
+ return this.loadingLabel;
228
+ }
229
+ if (this.hasProjectedContent) {
230
+ return this.projectedContent;
231
+ }
232
+ return this.visibleLabelFallback ?? "";
233
+ }
234
+ render() {
235
+ return lit.html`
236
+ <button
237
+ aria-busy=${this.loading ? "true" : "false"}
238
+ aria-describedby=${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}
239
+ aria-label=${ifDefined_js.ifDefined(this.forwardedAriaLabel)}
240
+ aria-labelledby=${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}
241
+ ?autofocus=${this.autofocus}
242
+ class=${this.buttonClasses}
243
+ data-sp-button-native
244
+ ?disabled=${this.isDisabled}
245
+ id=${ifDefined_js.ifDefined(this.id || void 0)}
246
+ name=${ifDefined_js.ifDefined(this.name)}
247
+ title=${ifDefined_js.ifDefined(this.title || void 0)}
248
+ type=${this.type}
249
+ value=${ifDefined_js.ifDefined(this.value)}
250
+ >
251
+ ${this.renderButtonContent() || lit.nothing}
252
+ </button>
253
+ `;
254
+ }
255
+ };
256
+ SpectreButtonElement.properties = {
257
+ ariaLabel: { attribute: "aria-label", type: String },
258
+ ariaLabelledBy: { attribute: "aria-labelledby", type: String },
259
+ ariaDescribedBy: { attribute: "aria-describedby", type: String },
260
+ autofocus: { type: Boolean, reflect: true },
261
+ disabled: { type: Boolean, reflect: true },
262
+ fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
263
+ label: { type: String, reflect: true },
264
+ loading: { type: Boolean, reflect: true },
265
+ loadingLabel: { attribute: "loading-label", type: String, reflect: true },
266
+ name: { type: String, reflect: true },
267
+ pill: { type: Boolean, reflect: true },
268
+ size: { type: String, reflect: true },
269
+ title: { type: String, reflect: true },
270
+ type: { type: String, reflect: true },
271
+ variant: { type: String, reflect: true },
272
+ value: { type: String, reflect: true }
273
+ };
274
+ function defineSpectreButton(tagName = "sp-button") {
275
+ const existingElement = customElements.get(tagName);
276
+ if (existingElement) {
277
+ return existingElement;
278
+ }
279
+ customElements.define(tagName, SpectreButtonElement);
280
+ return SpectreButtonElement;
281
+ }
282
+ var spectreInputTypes = [
283
+ "text",
284
+ "email",
285
+ "password",
286
+ "search",
287
+ "tel",
288
+ "url",
289
+ "number",
290
+ "date",
291
+ "datetime-local",
292
+ "month",
293
+ "time",
294
+ "week"
295
+ ];
296
+ var spectreInputSizes = ["sm", "md", "lg"];
297
+ function isInputType(value) {
298
+ return spectreInputTypes.includes(value);
299
+ }
300
+ function isInputSize(value) {
301
+ return spectreInputSizes.includes(value);
302
+ }
303
+ var SpectreInputElement = class extends lit.LitElement {
304
+ constructor() {
305
+ super(...arguments);
306
+ this.ariaLabel = null;
307
+ this.ariaLabelledBy = null;
308
+ this.ariaDescribedBy = null;
309
+ this.autofocus = false;
310
+ this.disabled = false;
311
+ this.fullWidth = false;
312
+ this.invalid = false;
313
+ this.loading = false;
314
+ this.pill = false;
315
+ this.readonly = false;
316
+ this.required = false;
317
+ this.size = "md";
318
+ this.success = false;
319
+ this.title = "";
320
+ this.type = "text";
321
+ this.value = "";
322
+ }
323
+ get id() {
324
+ return this._id ?? "";
325
+ }
326
+ set id(value) {
327
+ if ((this._id ?? "") === value) {
328
+ return;
329
+ }
330
+ this._id = value;
331
+ const host = this;
332
+ if (HTMLElement.prototype.hasAttribute.call(host, "id")) {
333
+ HTMLElement.prototype.removeAttribute.call(host, "id");
334
+ }
335
+ this.requestUpdate();
336
+ }
337
+ createRenderRoot() {
338
+ return this;
339
+ }
340
+ connectedCallback() {
341
+ super.connectedCallback();
342
+ const hostId = super.getAttribute("id");
343
+ if (hostId !== null) {
344
+ this.id = hostId;
345
+ }
346
+ }
347
+ getAttribute(qualifiedName) {
348
+ if (qualifiedName === "id") {
349
+ return this.id || null;
350
+ }
351
+ return super.getAttribute(qualifiedName);
352
+ }
353
+ hasAttribute(qualifiedName) {
354
+ if (qualifiedName === "id") {
355
+ return this.id !== "";
356
+ }
357
+ return super.hasAttribute(qualifiedName);
358
+ }
359
+ setAttribute(qualifiedName, value) {
360
+ if (qualifiedName === "id") {
361
+ this.id = value;
362
+ return;
363
+ }
364
+ super.setAttribute(qualifiedName, value);
365
+ }
366
+ removeAttribute(qualifiedName) {
367
+ if (qualifiedName === "id") {
368
+ this.id = "";
369
+ return;
370
+ }
371
+ super.removeAttribute(qualifiedName);
372
+ }
373
+ willUpdate(changedProperties) {
374
+ if (changedProperties.has("size") && !isInputSize(this.size)) {
375
+ this.size = "md";
376
+ }
377
+ if (changedProperties.has("type") && !isInputType(this.type)) {
378
+ this.type = "text";
379
+ }
380
+ if (changedProperties.has("value") && this.value == null) {
381
+ this.value = "";
382
+ }
383
+ if (changedProperties.has("maxlength")) {
384
+ if (this.maxlength == null || !Number.isInteger(this.maxlength) || this.maxlength < 0) {
385
+ this.maxlength = void 0;
386
+ }
387
+ }
388
+ if (changedProperties.has("minlength")) {
389
+ if (this.minlength == null || !Number.isInteger(this.minlength) || this.minlength < 0) {
390
+ this.minlength = void 0;
391
+ }
392
+ }
393
+ }
394
+ get inputClasses() {
395
+ return spectreUi.getInputClasses({
396
+ fullWidth: this.fullWidth,
397
+ pill: this.pill,
398
+ size: this.size,
399
+ state: this.isDisabled ? this.disabled ? "disabled" : "loading" : this.invalid ? "error" : this.success ? "success" : "default"
400
+ });
401
+ }
402
+ get isDisabled() {
403
+ return this.disabled || this.loading;
404
+ }
405
+ get nativeInput() {
406
+ return this.querySelector("[data-sp-input-native]");
407
+ }
408
+ get forwardedAriaLabel() {
409
+ const ariaLabel = this.ariaLabel?.trim();
410
+ return ariaLabel ? ariaLabel : void 0;
411
+ }
412
+ get forwardedAriaLabelledBy() {
413
+ const ariaLabelledBy = this.ariaLabelledBy?.trim();
414
+ return ariaLabelledBy ? ariaLabelledBy : void 0;
415
+ }
416
+ get forwardedAriaDescribedBy() {
417
+ const ariaDescribedBy = this.ariaDescribedBy?.trim();
418
+ return ariaDescribedBy ? ariaDescribedBy : void 0;
419
+ }
420
+ handleInput(event) {
421
+ const input = event.currentTarget;
422
+ this.value = input.value;
423
+ }
424
+ handleChange(event) {
425
+ const input = event.currentTarget;
426
+ this.value = input.value;
427
+ }
428
+ focus(options) {
429
+ this.nativeInput?.focus(options);
430
+ }
431
+ blur() {
432
+ this.nativeInput?.blur();
433
+ }
434
+ render() {
435
+ return lit.html`
436
+ <input
437
+ aria-busy=${this.loading ? "true" : "false"}
438
+ aria-describedby=${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}
439
+ aria-invalid=${ifDefined_js.ifDefined(this.invalid ? "true" : void 0)}
440
+ aria-label=${ifDefined_js.ifDefined(this.forwardedAriaLabel)}
441
+ aria-labelledby=${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}
442
+ autocomplete=${ifDefined_js.ifDefined(this.autocomplete)}
443
+ ?autofocus=${this.autofocus}
444
+ class=${this.inputClasses}
445
+ data-sp-input-native
446
+ ?disabled=${this.isDisabled}
447
+ ?readonly=${this.readonly}
448
+ ?required=${this.required}
449
+ id=${ifDefined_js.ifDefined(this.id || void 0)}
450
+ inputmode=${ifDefined_js.ifDefined(this.inputmode)}
451
+ max=${ifDefined_js.ifDefined(this.max)}
452
+ maxlength=${ifDefined_js.ifDefined(this.maxlength)}
453
+ min=${ifDefined_js.ifDefined(this.min)}
454
+ minlength=${ifDefined_js.ifDefined(this.minlength)}
455
+ name=${ifDefined_js.ifDefined(this.name)}
456
+ placeholder=${ifDefined_js.ifDefined(this.placeholder)}
457
+ step=${ifDefined_js.ifDefined(this.step)}
458
+ title=${ifDefined_js.ifDefined(this.title || void 0)}
459
+ type=${this.type}
460
+ .value=${live_js.live(this.value)}
461
+ @change=${this.handleChange}
462
+ @input=${this.handleInput}
463
+ />
464
+ `;
465
+ }
466
+ };
467
+ SpectreInputElement.properties = {
468
+ ariaLabel: { attribute: "aria-label", type: String },
469
+ ariaLabelledBy: { attribute: "aria-labelledby", type: String },
470
+ ariaDescribedBy: { attribute: "aria-describedby", type: String },
471
+ autocomplete: { type: String },
472
+ autofocus: { type: Boolean, reflect: true },
473
+ disabled: { type: Boolean, reflect: true },
474
+ fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
475
+ inputmode: { type: String },
476
+ invalid: { type: Boolean, reflect: true },
477
+ loading: { type: Boolean, reflect: true },
478
+ max: { type: String },
479
+ maxlength: { type: Number },
480
+ min: { type: String },
481
+ minlength: { type: Number },
482
+ name: { type: String },
483
+ pill: { type: Boolean, reflect: true },
484
+ placeholder: { type: String },
485
+ readonly: { type: Boolean, reflect: true },
486
+ required: { type: Boolean, reflect: true },
487
+ size: { type: String, reflect: true },
488
+ step: { type: String },
489
+ success: { type: Boolean, reflect: true },
490
+ title: { type: String, reflect: true },
491
+ type: { type: String, reflect: true },
492
+ value: { type: String }
493
+ };
494
+ function defineSpectreInput(tagName = "sp-input") {
495
+ const existingElement = customElements.get(tagName);
496
+ if (existingElement) {
497
+ return existingElement;
498
+ }
499
+ customElements.define(tagName, SpectreInputElement);
500
+ return SpectreInputElement;
501
+ }
502
+ var DEFAULT_ROWS = 2;
503
+ var SpectreTextareaElement = class extends lit.LitElement {
504
+ constructor() {
505
+ super(...arguments);
506
+ this.ariaLabel = null;
507
+ this.ariaLabelledBy = null;
508
+ this.ariaDescribedBy = null;
509
+ this.autofocus = false;
510
+ this.disabled = false;
511
+ this.fullWidth = false;
512
+ this.invalid = false;
513
+ this.loading = false;
514
+ this.pill = false;
515
+ this.readonly = false;
516
+ this.required = false;
517
+ this.rows = DEFAULT_ROWS;
518
+ this.size = "md";
519
+ this.success = false;
520
+ this.title = "";
521
+ this.value = "";
522
+ }
523
+ get id() {
524
+ return this._id ?? "";
525
+ }
526
+ set id(value) {
527
+ if ((this._id ?? "") === value) {
528
+ return;
529
+ }
530
+ this._id = value;
531
+ const host = this;
532
+ if (HTMLElement.prototype.hasAttribute.call(host, "id")) {
533
+ HTMLElement.prototype.removeAttribute.call(host, "id");
534
+ }
535
+ this.requestUpdate();
536
+ }
537
+ createRenderRoot() {
538
+ return this;
539
+ }
540
+ connectedCallback() {
541
+ super.connectedCallback();
542
+ const hostId = super.getAttribute("id");
543
+ if (hostId !== null) {
544
+ this.id = hostId;
545
+ }
546
+ }
547
+ getAttribute(qualifiedName) {
548
+ if (qualifiedName === "id") {
549
+ return this.id || null;
550
+ }
551
+ return super.getAttribute(qualifiedName);
552
+ }
553
+ hasAttribute(qualifiedName) {
554
+ if (qualifiedName === "id") {
555
+ return this.id !== "";
556
+ }
557
+ return super.hasAttribute(qualifiedName);
558
+ }
559
+ setAttribute(qualifiedName, value) {
560
+ if (qualifiedName === "id") {
561
+ this.id = value;
562
+ return;
563
+ }
564
+ super.setAttribute(qualifiedName, value);
565
+ }
566
+ removeAttribute(qualifiedName) {
567
+ if (qualifiedName === "id") {
568
+ this.id = "";
569
+ return;
570
+ }
571
+ super.removeAttribute(qualifiedName);
572
+ }
573
+ willUpdate(changedProperties) {
574
+ if (changedProperties.has("size") && !isInputSize(this.size)) {
575
+ this.size = "md";
576
+ }
577
+ if (changedProperties.has("rows")) {
578
+ if (this.rows == null || !Number.isInteger(this.rows) || this.rows < 1) {
579
+ this.rows = DEFAULT_ROWS;
580
+ }
581
+ }
582
+ if (changedProperties.has("value") && this.value == null) {
583
+ this.value = "";
584
+ }
585
+ if (changedProperties.has("maxlength")) {
586
+ if (this.maxlength == null || !Number.isInteger(this.maxlength) || this.maxlength < 0) {
587
+ this.maxlength = void 0;
588
+ }
589
+ }
590
+ if (changedProperties.has("minlength")) {
591
+ if (this.minlength == null || !Number.isInteger(this.minlength) || this.minlength < 0) {
592
+ this.minlength = void 0;
593
+ }
594
+ }
595
+ }
596
+ get textareaClasses() {
597
+ return spectreUi.getInputClasses({
598
+ fullWidth: this.fullWidth,
599
+ pill: this.pill,
600
+ size: this.size,
601
+ state: this.isDisabled ? this.disabled ? "disabled" : "loading" : this.invalid ? "error" : this.success ? "success" : "default"
602
+ });
603
+ }
604
+ get isDisabled() {
605
+ return this.disabled || this.loading;
606
+ }
607
+ get nativeTextarea() {
608
+ return this.querySelector("[data-sp-textarea-native]");
609
+ }
610
+ get forwardedAriaLabel() {
611
+ const ariaLabel = this.ariaLabel?.trim();
612
+ return ariaLabel ? ariaLabel : void 0;
613
+ }
614
+ get forwardedAriaLabelledBy() {
615
+ const ariaLabelledBy = this.ariaLabelledBy?.trim();
616
+ return ariaLabelledBy ? ariaLabelledBy : void 0;
617
+ }
618
+ get forwardedAriaDescribedBy() {
619
+ const ariaDescribedBy = this.ariaDescribedBy?.trim();
620
+ return ariaDescribedBy ? ariaDescribedBy : void 0;
621
+ }
622
+ handleInput(event) {
623
+ const textarea = event.currentTarget;
624
+ this.value = textarea.value;
625
+ }
626
+ handleChange(event) {
627
+ const textarea = event.currentTarget;
628
+ this.value = textarea.value;
629
+ }
630
+ focus(options) {
631
+ this.nativeTextarea?.focus(options);
632
+ }
633
+ blur() {
634
+ this.nativeTextarea?.blur();
635
+ }
636
+ render() {
637
+ return lit.html`
638
+ <textarea
639
+ aria-busy=${this.loading ? "true" : "false"}
640
+ aria-describedby=${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}
641
+ aria-invalid=${ifDefined_js.ifDefined(this.invalid ? "true" : void 0)}
642
+ aria-label=${ifDefined_js.ifDefined(this.forwardedAriaLabel)}
643
+ aria-labelledby=${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}
644
+ autocomplete=${ifDefined_js.ifDefined(this.autocomplete)}
645
+ ?autofocus=${this.autofocus}
646
+ class=${this.textareaClasses}
647
+ data-sp-textarea-native
648
+ ?disabled=${this.isDisabled}
649
+ inputmode=${ifDefined_js.ifDefined(this.inputmode)}
650
+ ?readonly=${this.readonly}
651
+ ?required=${this.required}
652
+ id=${ifDefined_js.ifDefined(this.id || void 0)}
653
+ maxlength=${ifDefined_js.ifDefined(this.maxlength)}
654
+ minlength=${ifDefined_js.ifDefined(this.minlength)}
655
+ name=${ifDefined_js.ifDefined(this.name)}
656
+ placeholder=${ifDefined_js.ifDefined(this.placeholder)}
657
+ rows=${this.rows}
658
+ title=${ifDefined_js.ifDefined(this.title || void 0)}
659
+ .value=${live_js.live(this.value)}
660
+ @change=${this.handleChange}
661
+ @input=${this.handleInput}
662
+ ></textarea>
663
+ `;
664
+ }
665
+ };
666
+ SpectreTextareaElement.properties = {
667
+ ariaLabel: { attribute: "aria-label", type: String },
668
+ ariaLabelledBy: { attribute: "aria-labelledby", type: String },
669
+ ariaDescribedBy: { attribute: "aria-describedby", type: String },
670
+ autocomplete: { type: String },
671
+ autofocus: { type: Boolean, reflect: true },
672
+ disabled: { type: Boolean, reflect: true },
673
+ fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
674
+ inputmode: { type: String },
675
+ invalid: { type: Boolean, reflect: true },
676
+ loading: { type: Boolean, reflect: true },
677
+ maxlength: { type: Number },
678
+ minlength: { type: Number },
679
+ name: { type: String },
680
+ pill: { type: Boolean, reflect: true },
681
+ placeholder: { type: String },
682
+ readonly: { type: Boolean, reflect: true },
683
+ required: { type: Boolean, reflect: true },
684
+ rows: { type: Number },
685
+ size: { type: String, reflect: true },
686
+ success: { type: Boolean, reflect: true },
687
+ title: { type: String, reflect: true },
688
+ value: { type: String }
689
+ };
690
+ function defineSpectreTextarea(tagName = "sp-textarea") {
691
+ const existingElement = customElements.get(tagName);
692
+ if (existingElement) {
693
+ return existingElement;
694
+ }
695
+ customElements.define(tagName, SpectreTextareaElement);
696
+ return SpectreTextareaElement;
697
+ }
698
+ var spectreSelectSizes = ["sm", "md", "lg"];
699
+ function isSelectSize(value) {
700
+ return spectreSelectSizes.includes(value);
701
+ }
702
+ function isSelectableContent(node) {
703
+ if (node.nodeType === Node.ELEMENT_NODE) {
704
+ const tagName = node.tagName;
705
+ return tagName === "OPTION" || tagName === "OPTGROUP";
706
+ }
707
+ if (node.nodeType === Node.TEXT_NODE) {
708
+ return (node.textContent?.trim().length ?? 0) > 0;
709
+ }
710
+ return false;
711
+ }
712
+ var SpectreSelectElement = class extends lit.LitElement {
713
+ constructor() {
714
+ super(...arguments);
715
+ this.ariaLabel = null;
716
+ this.ariaLabelledBy = null;
717
+ this.ariaDescribedBy = null;
718
+ this.autofocus = false;
719
+ this.disabled = false;
720
+ this.fullWidth = false;
721
+ this.invalid = false;
722
+ this.loading = false;
723
+ this.pill = false;
724
+ this.required = false;
725
+ this.size = "md";
726
+ this.success = false;
727
+ this.title = "";
728
+ this.value = "";
729
+ this.projectedOptions = [];
730
+ }
731
+ get id() {
732
+ return this._id ?? "";
733
+ }
734
+ set id(value) {
735
+ if ((this._id ?? "") === value) {
736
+ return;
737
+ }
738
+ this._id = value;
739
+ const host = this;
740
+ if (HTMLElement.prototype.hasAttribute.call(host, "id")) {
741
+ HTMLElement.prototype.removeAttribute.call(host, "id");
742
+ }
743
+ this.requestUpdate();
744
+ }
745
+ createRenderRoot() {
746
+ return this;
747
+ }
748
+ connectedCallback() {
749
+ super.connectedCallback();
750
+ const hostId = super.getAttribute("id");
751
+ if (hostId !== null) {
752
+ this.id = hostId;
753
+ }
754
+ this.syncProjectedOptions();
755
+ this.startContentObserver();
756
+ }
757
+ disconnectedCallback() {
758
+ this.stopContentObserver();
759
+ super.disconnectedCallback();
760
+ }
761
+ getAttribute(qualifiedName) {
762
+ if (qualifiedName === "id") {
763
+ return this.id || null;
764
+ }
765
+ return super.getAttribute(qualifiedName);
766
+ }
767
+ hasAttribute(qualifiedName) {
768
+ if (qualifiedName === "id") {
769
+ return this.id !== "";
770
+ }
771
+ return super.hasAttribute(qualifiedName);
772
+ }
773
+ setAttribute(qualifiedName, value) {
774
+ if (qualifiedName === "id") {
775
+ this.id = value;
776
+ return;
777
+ }
778
+ super.setAttribute(qualifiedName, value);
779
+ }
780
+ removeAttribute(qualifiedName) {
781
+ if (qualifiedName === "id") {
782
+ this.id = "";
783
+ return;
784
+ }
785
+ super.removeAttribute(qualifiedName);
786
+ }
787
+ willUpdate(changedProperties) {
788
+ if (changedProperties.has("size") && !isSelectSize(this.size)) {
789
+ this.size = "md";
790
+ }
791
+ if (changedProperties.has("value") && this.value == null) {
792
+ this.value = "";
793
+ }
794
+ }
795
+ update(changedProperties) {
796
+ this.stopContentObserver();
797
+ super.update(changedProperties);
798
+ this.startContentObserver();
799
+ }
800
+ updated(changedProperties) {
801
+ super.updated(changedProperties);
802
+ const nativeSelect = this.nativeSelect;
803
+ if (!nativeSelect) {
804
+ return;
805
+ }
806
+ if (this.value !== "" && nativeSelect.value !== this.value) {
807
+ nativeSelect.value = this.value;
808
+ return;
809
+ }
810
+ if (this.value === "" && !this.hasAttribute("value")) {
811
+ const nativeValue = nativeSelect.value ?? "";
812
+ if (nativeValue !== "") {
813
+ this.value = nativeValue;
814
+ }
815
+ }
816
+ }
817
+ get selectClasses() {
818
+ return spectreUi.getInputClasses({
819
+ fullWidth: this.fullWidth,
820
+ pill: this.pill,
821
+ size: this.size,
822
+ state: this.isDisabled ? this.disabled ? "disabled" : "loading" : this.invalid ? "error" : this.success ? "success" : "default"
823
+ });
824
+ }
825
+ get isDisabled() {
826
+ return this.disabled || this.loading;
827
+ }
828
+ get nativeSelect() {
829
+ return this.querySelector("[data-sp-select-native]");
830
+ }
831
+ get forwardedAriaLabel() {
832
+ const ariaLabel = this.ariaLabel?.trim();
833
+ return ariaLabel ? ariaLabel : void 0;
834
+ }
835
+ get forwardedAriaLabelledBy() {
836
+ const ariaLabelledBy = this.ariaLabelledBy?.trim();
837
+ return ariaLabelledBy ? ariaLabelledBy : void 0;
838
+ }
839
+ get forwardedAriaDescribedBy() {
840
+ const ariaDescribedBy = this.ariaDescribedBy?.trim();
841
+ return ariaDescribedBy ? ariaDescribedBy : void 0;
842
+ }
843
+ startContentObserver() {
844
+ if (this.contentObserver) {
845
+ return;
846
+ }
847
+ this.contentObserver = new MutationObserver((mutations) => {
848
+ const isInternalMovement = mutations.every((mutation) => {
849
+ return Array.from(mutation.removedNodes).every(
850
+ (node) => this.isInternalSelectNode(node) || this.contains(node)
851
+ ) && Array.from(mutation.addedNodes).every((node) => this.isInternalSelectNode(node));
852
+ });
853
+ if (isInternalMovement) {
854
+ return;
855
+ }
856
+ if (this.syncProjectedOptions()) {
857
+ this.requestUpdate();
858
+ }
859
+ });
860
+ this.contentObserver.observe(this, {
861
+ childList: true
862
+ });
863
+ }
864
+ stopContentObserver() {
865
+ this.contentObserver?.disconnect();
866
+ this.contentObserver = void 0;
867
+ }
868
+ syncProjectedOptions() {
869
+ const nextProjectedOptions = [];
870
+ Array.from(this.childNodes).forEach((node) => {
871
+ if (this.isInternalSelectNode(node)) {
872
+ this.projectedOptions.forEach((projectedNode) => {
873
+ if (projectedNode.parentNode !== this && this.contains(projectedNode)) {
874
+ nextProjectedOptions.push(projectedNode);
875
+ }
876
+ });
877
+ return;
878
+ }
879
+ if (isSelectableContent(node)) {
880
+ nextProjectedOptions.push(node);
881
+ }
882
+ });
883
+ const hasChanged = nextProjectedOptions.length !== this.projectedOptions.length || nextProjectedOptions.some((node, index) => node !== this.projectedOptions[index]);
884
+ if (hasChanged) {
885
+ this.projectedOptions = nextProjectedOptions;
886
+ }
887
+ return hasChanged;
888
+ }
889
+ isInternalSelectNode(node) {
890
+ return node.nodeType === Node.ELEMENT_NODE && node.hasAttribute("data-sp-select-native");
891
+ }
892
+ handleInput(event) {
893
+ const select = event.currentTarget;
894
+ this.value = select.value;
895
+ }
896
+ handleChange(event) {
897
+ const select = event.currentTarget;
898
+ this.value = select.value;
899
+ }
900
+ focus(options) {
901
+ this.nativeSelect?.focus(options);
902
+ }
903
+ blur() {
904
+ this.nativeSelect?.blur();
905
+ }
906
+ render() {
907
+ return lit.html`
908
+ <select
909
+ aria-busy=${this.loading ? "true" : "false"}
910
+ aria-describedby=${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}
911
+ aria-invalid=${ifDefined_js.ifDefined(this.invalid ? "true" : void 0)}
912
+ aria-label=${ifDefined_js.ifDefined(this.forwardedAriaLabel)}
913
+ aria-labelledby=${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}
914
+ ?autofocus=${this.autofocus}
915
+ class=${this.selectClasses}
916
+ data-sp-select-native
917
+ ?disabled=${this.isDisabled}
918
+ id=${ifDefined_js.ifDefined(this.id || void 0)}
919
+ name=${ifDefined_js.ifDefined(this.name)}
920
+ ?required=${this.required}
921
+ title=${ifDefined_js.ifDefined(this.title || void 0)}
922
+ .value=${live_js.live(this.value)}
923
+ @change=${this.handleChange}
924
+ @input=${this.handleInput}
925
+ >
926
+ ${this.projectedOptions.length > 0 ? this.projectedOptions : lit.nothing}
927
+ </select>
928
+ `;
929
+ }
930
+ };
931
+ SpectreSelectElement.properties = {
932
+ ariaLabel: { attribute: "aria-label", type: String },
933
+ ariaLabelledBy: { attribute: "aria-labelledby", type: String },
934
+ ariaDescribedBy: { attribute: "aria-describedby", type: String },
935
+ autofocus: { type: Boolean, reflect: true },
936
+ disabled: { type: Boolean, reflect: true },
937
+ fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
938
+ invalid: { type: Boolean, reflect: true },
939
+ loading: { type: Boolean, reflect: true },
940
+ name: { type: String },
941
+ pill: { type: Boolean, reflect: true },
942
+ required: { type: Boolean, reflect: true },
943
+ size: { type: String, reflect: true },
944
+ success: { type: Boolean, reflect: true },
945
+ title: { type: String, reflect: true },
946
+ value: { type: String }
947
+ };
948
+ function defineSpectreSelect(tagName = "sp-select") {
949
+ const existingElement = customElements.get(tagName);
950
+ if (existingElement) {
951
+ return existingElement;
952
+ }
953
+ customElements.define(tagName, SpectreSelectElement);
954
+ return SpectreSelectElement;
955
+ }
956
+ var SpectreCheckboxElement = class extends lit.LitElement {
957
+ constructor() {
958
+ super(...arguments);
959
+ this.ariaLabel = null;
960
+ this.ariaLabelledBy = null;
961
+ this.ariaDescribedBy = null;
962
+ this.autofocus = false;
963
+ this.checked = false;
964
+ this.disabled = false;
965
+ this.invalid = false;
966
+ this.label = "";
967
+ this.required = false;
968
+ this.title = "";
969
+ this.value = "on";
970
+ }
971
+ get id() {
972
+ return this._id ?? "";
973
+ }
974
+ set id(value) {
975
+ if ((this._id ?? "") === value) {
976
+ return;
977
+ }
978
+ this._id = value;
979
+ const host = this;
980
+ if (HTMLElement.prototype.hasAttribute.call(host, "id")) {
981
+ HTMLElement.prototype.removeAttribute.call(host, "id");
982
+ }
983
+ this.requestUpdate();
984
+ }
985
+ createRenderRoot() {
986
+ return this;
987
+ }
988
+ connectedCallback() {
989
+ super.connectedCallback();
990
+ const hostId = super.getAttribute("id");
991
+ if (hostId !== null) {
992
+ this.id = hostId;
993
+ }
994
+ }
995
+ getAttribute(qualifiedName) {
996
+ if (qualifiedName === "id") {
997
+ return this.id || null;
998
+ }
999
+ return super.getAttribute(qualifiedName);
1000
+ }
1001
+ hasAttribute(qualifiedName) {
1002
+ if (qualifiedName === "id") {
1003
+ return this.id !== "";
1004
+ }
1005
+ return super.hasAttribute(qualifiedName);
1006
+ }
1007
+ setAttribute(qualifiedName, value) {
1008
+ if (qualifiedName === "id") {
1009
+ this.id = value;
1010
+ return;
1011
+ }
1012
+ super.setAttribute(qualifiedName, value);
1013
+ }
1014
+ removeAttribute(qualifiedName) {
1015
+ if (qualifiedName === "id") {
1016
+ this.id = "";
1017
+ return;
1018
+ }
1019
+ super.removeAttribute(qualifiedName);
1020
+ }
1021
+ willUpdate(changedProperties) {
1022
+ if (changedProperties.has("value") && this.value == null) {
1023
+ this.value = "on";
1024
+ }
1025
+ }
1026
+ get nativeInput() {
1027
+ return this.querySelector("[data-sp-checkbox-native]");
1028
+ }
1029
+ get forwardedAriaLabel() {
1030
+ const value = this.ariaLabel?.trim();
1031
+ return value ? value : void 0;
1032
+ }
1033
+ get forwardedAriaLabelledBy() {
1034
+ const value = this.ariaLabelledBy?.trim();
1035
+ return value ? value : void 0;
1036
+ }
1037
+ get forwardedAriaDescribedBy() {
1038
+ const value = this.ariaDescribedBy?.trim();
1039
+ return value ? value : void 0;
1040
+ }
1041
+ handleInput(event) {
1042
+ const input = event.currentTarget;
1043
+ this.checked = input.checked;
1044
+ }
1045
+ handleChange(event) {
1046
+ const input = event.currentTarget;
1047
+ this.checked = input.checked;
1048
+ }
1049
+ focus(options) {
1050
+ this.nativeInput?.focus(options);
1051
+ }
1052
+ blur() {
1053
+ this.nativeInput?.blur();
1054
+ }
1055
+ render() {
1056
+ return lit.html`
1057
+ <label>
1058
+ <input
1059
+ aria-describedby=${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}
1060
+ aria-invalid=${ifDefined_js.ifDefined(this.invalid ? "true" : void 0)}
1061
+ aria-label=${ifDefined_js.ifDefined(this.forwardedAriaLabel)}
1062
+ aria-labelledby=${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}
1063
+ ?autofocus=${this.autofocus}
1064
+ data-sp-checkbox-native
1065
+ ?checked=${this.checked}
1066
+ ?disabled=${this.disabled}
1067
+ id=${ifDefined_js.ifDefined(this.id || void 0)}
1068
+ name=${ifDefined_js.ifDefined(this.name)}
1069
+ ?required=${this.required}
1070
+ title=${ifDefined_js.ifDefined(this.title || void 0)}
1071
+ type='checkbox'
1072
+ value=${ifDefined_js.ifDefined(this.value || void 0)}
1073
+ @change=${this.handleChange}
1074
+ @input=${this.handleInput}
1075
+ />
1076
+ <span class='sp-label'>${this.label}</span>
1077
+ </label>
1078
+ `;
1079
+ }
1080
+ };
1081
+ SpectreCheckboxElement.properties = {
1082
+ ariaLabel: { attribute: "aria-label", type: String },
1083
+ ariaLabelledBy: { attribute: "aria-labelledby", type: String },
1084
+ ariaDescribedBy: { attribute: "aria-describedby", type: String },
1085
+ autofocus: { type: Boolean, reflect: true },
1086
+ checked: { type: Boolean, reflect: true },
1087
+ disabled: { type: Boolean, reflect: true },
1088
+ invalid: { type: Boolean, reflect: true },
1089
+ label: { type: String, reflect: true },
1090
+ name: { type: String },
1091
+ required: { type: Boolean, reflect: true },
1092
+ title: { type: String, reflect: true },
1093
+ value: { type: String }
1094
+ };
1095
+ function defineSpectreCheckbox(tagName = "sp-checkbox") {
1096
+ const existingElement = customElements.get(tagName);
1097
+ if (existingElement) {
1098
+ return existingElement;
1099
+ }
1100
+ customElements.define(tagName, SpectreCheckboxElement);
1101
+ return SpectreCheckboxElement;
1102
+ }
1103
+ var SpectreRadioElement = class extends lit.LitElement {
1104
+ constructor() {
1105
+ super(...arguments);
1106
+ this.ariaLabel = null;
1107
+ this.ariaLabelledBy = null;
1108
+ this.ariaDescribedBy = null;
1109
+ this.autofocus = false;
1110
+ this.checked = false;
1111
+ this.disabled = false;
1112
+ this.invalid = false;
1113
+ this.label = "";
1114
+ this.required = false;
1115
+ this.title = "";
1116
+ this.value = "on";
1117
+ }
1118
+ get id() {
1119
+ return this._id ?? "";
1120
+ }
1121
+ set id(value) {
1122
+ if ((this._id ?? "") === value) {
1123
+ return;
1124
+ }
1125
+ this._id = value;
1126
+ const host = this;
1127
+ if (HTMLElement.prototype.hasAttribute.call(host, "id")) {
1128
+ HTMLElement.prototype.removeAttribute.call(host, "id");
1129
+ }
1130
+ this.requestUpdate();
1131
+ }
1132
+ createRenderRoot() {
1133
+ return this;
1134
+ }
1135
+ connectedCallback() {
1136
+ super.connectedCallback();
1137
+ const hostId = super.getAttribute("id");
1138
+ if (hostId !== null) {
1139
+ this.id = hostId;
1140
+ }
1141
+ }
1142
+ getAttribute(qualifiedName) {
1143
+ if (qualifiedName === "id") {
1144
+ return this.id || null;
1145
+ }
1146
+ return super.getAttribute(qualifiedName);
1147
+ }
1148
+ hasAttribute(qualifiedName) {
1149
+ if (qualifiedName === "id") {
1150
+ return this.id !== "";
1151
+ }
1152
+ return super.hasAttribute(qualifiedName);
1153
+ }
1154
+ setAttribute(qualifiedName, value) {
1155
+ if (qualifiedName === "id") {
1156
+ this.id = value;
1157
+ return;
1158
+ }
1159
+ super.setAttribute(qualifiedName, value);
1160
+ }
1161
+ removeAttribute(qualifiedName) {
1162
+ if (qualifiedName === "id") {
1163
+ this.id = "";
1164
+ return;
1165
+ }
1166
+ super.removeAttribute(qualifiedName);
1167
+ }
1168
+ willUpdate(changedProperties) {
1169
+ if (changedProperties.has("value") && this.value == null) {
1170
+ this.value = "on";
1171
+ }
1172
+ }
1173
+ get nativeInput() {
1174
+ return this.querySelector("[data-sp-radio-native]");
1175
+ }
1176
+ get forwardedAriaLabel() {
1177
+ const value = this.ariaLabel?.trim();
1178
+ return value ? value : void 0;
1179
+ }
1180
+ get forwardedAriaLabelledBy() {
1181
+ const value = this.ariaLabelledBy?.trim();
1182
+ return value ? value : void 0;
1183
+ }
1184
+ get forwardedAriaDescribedBy() {
1185
+ const value = this.ariaDescribedBy?.trim();
1186
+ return value ? value : void 0;
1187
+ }
1188
+ handleInput(event) {
1189
+ const input = event.currentTarget;
1190
+ this.checked = input.checked;
1191
+ }
1192
+ handleChange(event) {
1193
+ const input = event.currentTarget;
1194
+ this.checked = input.checked;
1195
+ }
1196
+ focus(options) {
1197
+ this.nativeInput?.focus(options);
1198
+ }
1199
+ blur() {
1200
+ this.nativeInput?.blur();
1201
+ }
1202
+ render() {
1203
+ return lit.html`
1204
+ <label>
1205
+ <input
1206
+ aria-describedby=${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}
1207
+ aria-invalid=${ifDefined_js.ifDefined(this.invalid ? "true" : void 0)}
1208
+ aria-label=${ifDefined_js.ifDefined(this.forwardedAriaLabel)}
1209
+ aria-labelledby=${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}
1210
+ ?autofocus=${this.autofocus}
1211
+ data-sp-radio-native
1212
+ ?checked=${this.checked}
1213
+ ?disabled=${this.disabled}
1214
+ id=${ifDefined_js.ifDefined(this.id || void 0)}
1215
+ name=${ifDefined_js.ifDefined(this.name)}
1216
+ ?required=${this.required}
1217
+ title=${ifDefined_js.ifDefined(this.title || void 0)}
1218
+ type='radio'
1219
+ value=${ifDefined_js.ifDefined(this.value || void 0)}
1220
+ @change=${this.handleChange}
1221
+ @input=${this.handleInput}
1222
+ />
1223
+ <span class='sp-label'>${this.label}</span>
1224
+ </label>
1225
+ `;
1226
+ }
1227
+ };
1228
+ SpectreRadioElement.properties = {
1229
+ ariaLabel: { attribute: "aria-label", type: String },
1230
+ ariaLabelledBy: { attribute: "aria-labelledby", type: String },
1231
+ ariaDescribedBy: { attribute: "aria-describedby", type: String },
1232
+ autofocus: { type: Boolean, reflect: true },
1233
+ checked: { type: Boolean, reflect: true },
1234
+ disabled: { type: Boolean, reflect: true },
1235
+ invalid: { type: Boolean, reflect: true },
1236
+ label: { type: String, reflect: true },
1237
+ name: { type: String },
1238
+ required: { type: Boolean, reflect: true },
1239
+ title: { type: String, reflect: true },
1240
+ value: { type: String }
1241
+ };
1242
+ function defineSpectreRadio(tagName = "sp-radio") {
1243
+ const existingElement = customElements.get(tagName);
1244
+ if (existingElement) {
1245
+ return existingElement;
1246
+ }
1247
+ customElements.define(tagName, SpectreRadioElement);
1248
+ return SpectreRadioElement;
1249
+ }
1250
+ var SpectreLabelElement = class extends lit.LitElement {
1251
+ constructor() {
1252
+ super(...arguments);
1253
+ this.projectedContent = [];
1254
+ }
1255
+ get id() {
1256
+ return this._id ?? "";
1257
+ }
1258
+ set id(value) {
1259
+ if ((this._id ?? "") === value) {
1260
+ return;
1261
+ }
1262
+ this._id = value;
1263
+ const host = this;
1264
+ if (HTMLElement.prototype.hasAttribute.call(host, "id")) {
1265
+ HTMLElement.prototype.removeAttribute.call(host, "id");
1266
+ }
1267
+ this.requestUpdate();
1268
+ }
1269
+ createRenderRoot() {
1270
+ return this;
1271
+ }
1272
+ connectedCallback() {
1273
+ super.connectedCallback();
1274
+ const hostId = super.getAttribute("id");
1275
+ if (hostId !== null) {
1276
+ this.id = hostId;
1277
+ }
1278
+ this.syncProjectedContent();
1279
+ this.startContentObserver();
1280
+ }
1281
+ disconnectedCallback() {
1282
+ this.stopContentObserver();
1283
+ super.disconnectedCallback();
1284
+ }
1285
+ getAttribute(qualifiedName) {
1286
+ if (qualifiedName === "id") {
1287
+ return this.id || null;
1288
+ }
1289
+ return super.getAttribute(qualifiedName);
1290
+ }
1291
+ hasAttribute(qualifiedName) {
1292
+ if (qualifiedName === "id") {
1293
+ return this.id !== "";
1294
+ }
1295
+ return super.hasAttribute(qualifiedName);
1296
+ }
1297
+ setAttribute(qualifiedName, value) {
1298
+ if (qualifiedName === "id") {
1299
+ this.id = value;
1300
+ return;
1301
+ }
1302
+ super.setAttribute(qualifiedName, value);
1303
+ }
1304
+ removeAttribute(qualifiedName) {
1305
+ if (qualifiedName === "id") {
1306
+ this.id = "";
1307
+ return;
1308
+ }
1309
+ super.removeAttribute(qualifiedName);
1310
+ }
1311
+ update(changedProperties) {
1312
+ this.stopContentObserver();
1313
+ super.update(changedProperties);
1314
+ this.startContentObserver();
1315
+ }
1316
+ get nativeLabel() {
1317
+ return this.querySelector("[data-sp-label-native]");
1318
+ }
1319
+ startContentObserver() {
1320
+ if (this.contentObserver) {
1321
+ return;
1322
+ }
1323
+ this.contentObserver = new MutationObserver((mutations) => {
1324
+ const isInternalMovement = mutations.every((mutation) => {
1325
+ return Array.from(mutation.removedNodes).every(
1326
+ (node) => this.isInternalLabelNode(node) || this.contains(node)
1327
+ ) && Array.from(mutation.addedNodes).every((node) => this.isInternalLabelNode(node));
1328
+ });
1329
+ if (isInternalMovement) {
1330
+ return;
1331
+ }
1332
+ if (this.syncProjectedContent()) {
1333
+ this.requestUpdate();
1334
+ }
1335
+ });
1336
+ this.contentObserver.observe(this, { childList: true });
1337
+ }
1338
+ stopContentObserver() {
1339
+ this.contentObserver?.disconnect();
1340
+ this.contentObserver = void 0;
1341
+ }
1342
+ syncProjectedContent() {
1343
+ const nextProjectedContent = [];
1344
+ Array.from(this.childNodes).forEach((node) => {
1345
+ if (this.isInternalLabelNode(node)) {
1346
+ this.projectedContent.forEach((projectedNode) => {
1347
+ if (projectedNode.parentNode !== this && this.contains(projectedNode)) {
1348
+ nextProjectedContent.push(projectedNode);
1349
+ }
1350
+ });
1351
+ return;
1352
+ }
1353
+ nextProjectedContent.push(node);
1354
+ });
1355
+ if (nextProjectedContent.length === this.projectedContent.length && nextProjectedContent.every((node, index) => node === this.projectedContent[index])) {
1356
+ return false;
1357
+ }
1358
+ this.projectedContent = nextProjectedContent;
1359
+ return true;
1360
+ }
1361
+ isInternalLabelNode(node) {
1362
+ return node === this.nativeLabel;
1363
+ }
1364
+ focus(options) {
1365
+ this.nativeLabel?.focus(options);
1366
+ }
1367
+ blur() {
1368
+ this.nativeLabel?.blur();
1369
+ }
1370
+ render() {
1371
+ return lit.html`
1372
+ <label
1373
+ class='sp-label'
1374
+ data-sp-label-native
1375
+ for=${ifDefined_js.ifDefined(this.htmlFor)}
1376
+ id=${ifDefined_js.ifDefined(this.id || void 0)}
1377
+ tabindex='-1'
1378
+ >
1379
+ ${this.projectedContent.length > 0 ? this.projectedContent : lit.nothing}
1380
+ </label>
1381
+ `;
1382
+ }
1383
+ };
1384
+ SpectreLabelElement.properties = {
1385
+ htmlFor: { attribute: "for", type: String }
1386
+ };
1387
+ function defineSpectreLabel(tagName = "sp-label") {
1388
+ const existingElement = customElements.get(tagName);
1389
+ if (existingElement) {
1390
+ return existingElement;
1391
+ }
1392
+ customElements.define(tagName, SpectreLabelElement);
1393
+ return SpectreLabelElement;
1394
+ }
1395
+ var SpectreFieldsetElement = class extends lit.LitElement {
1396
+ constructor() {
1397
+ super(...arguments);
1398
+ this.ariaLabel = null;
1399
+ this.ariaLabelledBy = null;
1400
+ this.ariaDescribedBy = null;
1401
+ this.disabled = false;
1402
+ this.legend = "";
1403
+ this.projectedContent = [];
1404
+ }
1405
+ get id() {
1406
+ return this._id ?? "";
1407
+ }
1408
+ set id(value) {
1409
+ if ((this._id ?? "") === value) {
1410
+ return;
1411
+ }
1412
+ this._id = value;
1413
+ const host = this;
1414
+ if (HTMLElement.prototype.hasAttribute.call(host, "id")) {
1415
+ HTMLElement.prototype.removeAttribute.call(host, "id");
1416
+ }
1417
+ this.requestUpdate();
1418
+ }
1419
+ createRenderRoot() {
1420
+ return this;
1421
+ }
1422
+ connectedCallback() {
1423
+ super.connectedCallback();
1424
+ const hostId = super.getAttribute("id");
1425
+ if (hostId !== null) {
1426
+ this.id = hostId;
1427
+ }
1428
+ this.syncProjectedContent();
1429
+ this.startContentObserver();
1430
+ }
1431
+ disconnectedCallback() {
1432
+ this.stopContentObserver();
1433
+ super.disconnectedCallback();
1434
+ }
1435
+ getAttribute(qualifiedName) {
1436
+ if (qualifiedName === "id") {
1437
+ return this.id || null;
1438
+ }
1439
+ return super.getAttribute(qualifiedName);
1440
+ }
1441
+ hasAttribute(qualifiedName) {
1442
+ if (qualifiedName === "id") {
1443
+ return this.id !== "";
1444
+ }
1445
+ return super.hasAttribute(qualifiedName);
1446
+ }
1447
+ setAttribute(qualifiedName, value) {
1448
+ if (qualifiedName === "id") {
1449
+ this.id = value;
1450
+ return;
1451
+ }
1452
+ super.setAttribute(qualifiedName, value);
1453
+ }
1454
+ removeAttribute(qualifiedName) {
1455
+ if (qualifiedName === "id") {
1456
+ this.id = "";
1457
+ return;
1458
+ }
1459
+ super.removeAttribute(qualifiedName);
1460
+ }
1461
+ update(changedProperties) {
1462
+ this.stopContentObserver();
1463
+ super.update(changedProperties);
1464
+ this.startContentObserver();
1465
+ }
1466
+ get nativeFieldset() {
1467
+ return this.querySelector("[data-sp-fieldset-native]");
1468
+ }
1469
+ get forwardedAriaLabel() {
1470
+ const value = this.ariaLabel?.trim();
1471
+ return value ? value : void 0;
1472
+ }
1473
+ get forwardedAriaLabelledBy() {
1474
+ const value = this.ariaLabelledBy?.trim();
1475
+ return value ? value : void 0;
1476
+ }
1477
+ get forwardedAriaDescribedBy() {
1478
+ const value = this.ariaDescribedBy?.trim();
1479
+ return value ? value : void 0;
1480
+ }
1481
+ startContentObserver() {
1482
+ if (this.contentObserver) {
1483
+ return;
1484
+ }
1485
+ this.contentObserver = new MutationObserver((mutations) => {
1486
+ const isInternalMovement = mutations.every((mutation) => {
1487
+ return Array.from(mutation.removedNodes).every(
1488
+ (node) => this.isInternalFieldsetNode(node) || this.contains(node)
1489
+ ) && Array.from(mutation.addedNodes).every((node) => this.isInternalFieldsetNode(node));
1490
+ });
1491
+ if (isInternalMovement) {
1492
+ return;
1493
+ }
1494
+ if (this.syncProjectedContent()) {
1495
+ this.requestUpdate();
1496
+ }
1497
+ });
1498
+ this.contentObserver.observe(this, { childList: true });
1499
+ }
1500
+ stopContentObserver() {
1501
+ this.contentObserver?.disconnect();
1502
+ this.contentObserver = void 0;
1503
+ }
1504
+ syncProjectedContent() {
1505
+ const nextProjectedContent = [];
1506
+ Array.from(this.childNodes).forEach((node) => {
1507
+ if (this.isInternalFieldsetNode(node)) {
1508
+ this.projectedContent.forEach((projectedNode) => {
1509
+ if (projectedNode.parentNode !== this && this.contains(projectedNode)) {
1510
+ nextProjectedContent.push(projectedNode);
1511
+ }
1512
+ });
1513
+ return;
1514
+ }
1515
+ nextProjectedContent.push(node);
1516
+ });
1517
+ if (nextProjectedContent.length === this.projectedContent.length && nextProjectedContent.every((node, index) => node === this.projectedContent[index])) {
1518
+ return false;
1519
+ }
1520
+ this.projectedContent = nextProjectedContent;
1521
+ return true;
1522
+ }
1523
+ isInternalFieldsetNode(node) {
1524
+ return node === this.nativeFieldset;
1525
+ }
1526
+ focus(options) {
1527
+ this.nativeFieldset?.focus(options);
1528
+ }
1529
+ blur() {
1530
+ this.nativeFieldset?.blur();
1531
+ }
1532
+ render() {
1533
+ return lit.html`
1534
+ <fieldset
1535
+ aria-describedby=${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}
1536
+ aria-label=${ifDefined_js.ifDefined(this.forwardedAriaLabel)}
1537
+ aria-labelledby=${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}
1538
+ data-sp-fieldset-native
1539
+ ?disabled=${this.disabled}
1540
+ id=${ifDefined_js.ifDefined(this.id || void 0)}
1541
+ >
1542
+ ${this.legend ? lit.html`<legend class='sp-label'>${this.legend}</legend>` : lit.nothing}
1543
+ ${this.projectedContent.length > 0 ? this.projectedContent : lit.nothing}
1544
+ </fieldset>
1545
+ `;
1546
+ }
1547
+ };
1548
+ SpectreFieldsetElement.properties = {
1549
+ ariaLabel: { attribute: "aria-label", type: String },
1550
+ ariaLabelledBy: { attribute: "aria-labelledby", type: String },
1551
+ ariaDescribedBy: { attribute: "aria-describedby", type: String },
1552
+ disabled: { type: Boolean, reflect: true },
1553
+ legend: { type: String, reflect: true }
1554
+ };
1555
+ function defineSpectreFieldset(tagName = "sp-fieldset") {
1556
+ const existingElement = customElements.get(tagName);
1557
+ if (existingElement) {
1558
+ return existingElement;
1559
+ }
1560
+ customElements.define(tagName, SpectreFieldsetElement);
1561
+ return SpectreFieldsetElement;
1562
+ }
1563
+
1564
+ // src/index.ts
1565
+ function defineSpectreComponents() {
1566
+ defineSpectreButton();
1567
+ defineSpectreInput();
1568
+ defineSpectreTextarea();
1569
+ defineSpectreSelect();
1570
+ defineSpectreCheckbox();
1571
+ defineSpectreRadio();
1572
+ defineSpectreLabel();
1573
+ defineSpectreFieldset();
1574
+ }
1575
+
1576
+ exports.SpectreButtonElement = SpectreButtonElement;
1577
+ exports.SpectreCheckboxElement = SpectreCheckboxElement;
1578
+ exports.SpectreFieldsetElement = SpectreFieldsetElement;
1579
+ exports.SpectreInputElement = SpectreInputElement;
1580
+ exports.SpectreLabelElement = SpectreLabelElement;
1581
+ exports.SpectreRadioElement = SpectreRadioElement;
1582
+ exports.SpectreSelectElement = SpectreSelectElement;
1583
+ exports.SpectreTextareaElement = SpectreTextareaElement;
1584
+ exports.defineSpectreButton = defineSpectreButton;
1585
+ exports.defineSpectreCheckbox = defineSpectreCheckbox;
1586
+ exports.defineSpectreComponents = defineSpectreComponents;
1587
+ exports.defineSpectreFieldset = defineSpectreFieldset;
1588
+ exports.defineSpectreInput = defineSpectreInput;
1589
+ exports.defineSpectreLabel = defineSpectreLabel;
1590
+ exports.defineSpectreRadio = defineSpectreRadio;
1591
+ exports.defineSpectreSelect = defineSpectreSelect;
1592
+ exports.defineSpectreTextarea = defineSpectreTextarea;
1593
+ exports.spectreButtonSizes = spectreButtonSizes;
1594
+ exports.spectreButtonTypes = spectreButtonTypes;
1595
+ exports.spectreButtonVariants = spectreButtonVariants;
1596
+ exports.spectreInputSizes = spectreInputSizes;
1597
+ exports.spectreInputTypes = spectreInputTypes;
1598
+ exports.spectreSelectSizes = spectreSelectSizes;
1599
+ //# sourceMappingURL=index.cjs.map
1600
+ //# sourceMappingURL=index.cjs.map