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