@phcdevworks/spectre-components 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +586 -107
  2. package/dist/base-B_9DJkh2.d.cts +38 -0
  3. package/dist/base-B_9DJkh2.d.ts +38 -0
  4. package/dist/button.cjs +252 -90
  5. package/dist/button.cjs.map +1 -1
  6. package/dist/button.d.cts +39 -37
  7. package/dist/button.d.ts +39 -37
  8. package/dist/button.js +252 -90
  9. package/dist/button.js.map +1 -1
  10. package/dist/checkbox.cjs +228 -67
  11. package/dist/checkbox.cjs.map +1 -1
  12. package/dist/checkbox.d.cts +21 -21
  13. package/dist/checkbox.d.ts +21 -21
  14. package/dist/checkbox.js +228 -67
  15. package/dist/checkbox.js.map +1 -1
  16. package/dist/fieldset.cjs +245 -56
  17. package/dist/fieldset.cjs.map +1 -1
  18. package/dist/fieldset.d.cts +35 -14
  19. package/dist/fieldset.d.ts +35 -14
  20. package/dist/fieldset.js +245 -56
  21. package/dist/fieldset.js.map +1 -1
  22. package/dist/form-9cZG1E9P.d.cts +10 -0
  23. package/dist/form-9cZG1E9P.d.ts +10 -0
  24. package/dist/index.cjs +647 -328
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +4 -4
  27. package/dist/index.d.ts +4 -4
  28. package/dist/index.js +647 -328
  29. package/dist/index.js.map +1 -1
  30. package/dist/input.cjs +262 -77
  31. package/dist/input.cjs.map +1 -1
  32. package/dist/input.d.cts +72 -40
  33. package/dist/input.d.ts +72 -40
  34. package/dist/input.js +262 -77
  35. package/dist/input.js.map +1 -1
  36. package/dist/label.cjs +217 -55
  37. package/dist/label.cjs.map +1 -1
  38. package/dist/label.d.cts +17 -10
  39. package/dist/label.d.ts +17 -10
  40. package/dist/label.js +217 -55
  41. package/dist/label.js.map +1 -1
  42. package/dist/{projectable-DcnBRiko.d.cts → projectable-CIfxi7dv.d.cts} +1 -1
  43. package/dist/{projectable-SzbPvXfM.d.ts → projectable-Ksv9eoIr.d.ts} +1 -1
  44. package/dist/radio.cjs +248 -67
  45. package/dist/radio.cjs.map +1 -1
  46. package/dist/radio.d.cts +23 -21
  47. package/dist/radio.d.ts +23 -21
  48. package/dist/radio.js +248 -67
  49. package/dist/radio.js.map +1 -1
  50. package/dist/select.cjs +230 -67
  51. package/dist/select.cjs.map +1 -1
  52. package/dist/select.d.cts +27 -27
  53. package/dist/select.d.ts +27 -27
  54. package/dist/select.js +230 -67
  55. package/dist/select.js.map +1 -1
  56. package/dist/textarea.cjs +256 -77
  57. package/dist/textarea.cjs.map +1 -1
  58. package/dist/textarea.d.cts +53 -32
  59. package/dist/textarea.d.ts +53 -32
  60. package/dist/textarea.js +256 -77
  61. package/dist/textarea.js.map +1 -1
  62. package/package.json +22 -12
  63. package/dist/base-DQtCQ-dP.d.cts +0 -22
  64. package/dist/base-DQtCQ-dP.d.ts +0 -22
  65. package/dist/form-iI7vV-3W.d.cts +0 -6
  66. package/dist/form-iI7vV-3W.d.ts +0 -6
package/dist/index.js CHANGED
@@ -1,28 +1,141 @@
1
+ import { getButtonClasses, getInputClasses, getInputLabelClasses } from '@phcdevworks/spectre-ui';
1
2
  import { LitElement, html, nothing } from 'lit';
2
3
  import { ifDefined } from 'lit/directives/if-defined.js';
3
- import { getButtonClasses, getInputClasses } from '@phcdevworks/spectre-ui';
4
4
  import { live } from 'lit/directives/live.js';
5
5
 
6
- // src/components/button/sp-button.ts
6
+ // src/utils/form.ts
7
+ var spectreInputSizes = ["sm", "md", "lg"];
8
+ function isInputSize(value) {
9
+ return spectreInputSizes.includes(value);
10
+ }
11
+ var spectreButtonVariants = [
12
+ "primary",
13
+ "secondary",
14
+ "ghost",
15
+ "danger",
16
+ "success",
17
+ "cta",
18
+ "accent"
19
+ ];
20
+ function isButtonVariant(value) {
21
+ return spectreButtonVariants.includes(value);
22
+ }
23
+ var spectreButtonTypes = ["button", "submit", "reset"];
24
+ function isButtonType(value) {
25
+ return spectreButtonTypes.includes(value);
26
+ }
27
+ var spectreInputTypes = [
28
+ "text",
29
+ "email",
30
+ "password",
31
+ "search",
32
+ "tel",
33
+ "url",
34
+ "number",
35
+ "date",
36
+ "datetime-local",
37
+ "month",
38
+ "time",
39
+ "week"
40
+ ];
41
+ function isInputType(value) {
42
+ return spectreInputTypes.includes(value);
43
+ }
44
+ function normalizeInt(value, fallback, min = 0) {
45
+ if (value == null || typeof value !== "number" || !Number.isInteger(value) || value < min) {
46
+ return fallback;
47
+ }
48
+ return value;
49
+ }
7
50
  var SpectreBaseElement = class extends LitElement {
8
51
  constructor() {
9
52
  super(...arguments);
10
- this.ariaLabel = null;
11
- this.ariaLabelledBy = null;
12
- this.ariaDescribedBy = null;
53
+ this._ariaLabel = null;
54
+ this._ariaLabelledBy = null;
55
+ this._ariaDescribedBy = null;
56
+ this._autocapitalize = "";
57
+ this._spellcheck = null;
58
+ this._title = "";
59
+ this._id = "";
60
+ }
61
+ get ariaLabel() {
62
+ return this._ariaLabel;
63
+ }
64
+ set ariaLabel(value) {
65
+ if (this._ariaLabel === value) {
66
+ return;
67
+ }
68
+ this._ariaLabel = value;
69
+ this._removeHostAttribute("aria-label");
70
+ this.requestUpdate();
71
+ }
72
+ get ariaLabelledBy() {
73
+ return this._ariaLabelledBy;
74
+ }
75
+ set ariaLabelledBy(value) {
76
+ if (this._ariaLabelledBy === value) {
77
+ return;
78
+ }
79
+ this._ariaLabelledBy = value;
80
+ this._removeHostAttribute("aria-labelledby");
81
+ this.requestUpdate();
82
+ }
83
+ get ariaDescribedBy() {
84
+ return this._ariaDescribedBy;
85
+ }
86
+ set ariaDescribedBy(value) {
87
+ if (this._ariaDescribedBy === value) {
88
+ return;
89
+ }
90
+ this._ariaDescribedBy = value;
91
+ this._removeHostAttribute("aria-describedby");
92
+ this.requestUpdate();
93
+ }
94
+ get autocapitalize() {
95
+ return this._autocapitalize;
96
+ }
97
+ set autocapitalize(value) {
98
+ const normalizedValue = value ?? "";
99
+ if (this._autocapitalize === normalizedValue) {
100
+ return;
101
+ }
102
+ this._autocapitalize = normalizedValue;
103
+ this._removeHostAttribute("autocapitalize");
104
+ this.requestUpdate();
105
+ }
106
+ get spellcheck() {
107
+ return this._spellcheck ?? super.spellcheck;
108
+ }
109
+ set spellcheck(value) {
110
+ if (this._spellcheck === value) {
111
+ return;
112
+ }
113
+ this._spellcheck = value ?? null;
114
+ this._removeHostAttribute("spellcheck");
115
+ this.requestUpdate();
116
+ }
117
+ get title() {
118
+ return this._title;
119
+ }
120
+ set title(value) {
121
+ const normalizedValue = value ?? "";
122
+ if (this._title === normalizedValue) {
123
+ return;
124
+ }
125
+ this._title = normalizedValue;
126
+ this._removeHostAttribute("title");
127
+ this.requestUpdate();
13
128
  }
14
129
  get id() {
15
- return this._id ?? "";
130
+ return this._id;
16
131
  }
17
132
  set id(value) {
18
- if ((this._id ?? "") === value) {
133
+ const normalizedValue = value ?? "";
134
+ if (this._id === normalizedValue) {
19
135
  return;
20
136
  }
21
- this._id = value;
22
- const host = this;
23
- if (HTMLElement.prototype.hasAttribute.call(host, "id")) {
24
- HTMLElement.prototype.removeAttribute.call(host, "id");
25
- }
137
+ this._id = normalizedValue;
138
+ this._removeHostAttribute("id");
26
139
  this.requestUpdate();
27
140
  }
28
141
  // Spectre components intentionally render in light DOM so the global
@@ -32,36 +145,121 @@ var SpectreBaseElement = class extends LitElement {
32
145
  }
33
146
  connectedCallback() {
34
147
  super.connectedCallback();
35
- const hostId = super.getAttribute("id");
36
- if (hostId !== null) {
37
- this.id = hostId;
38
- }
148
+ const proxiedAttributes = [
149
+ "id",
150
+ "title",
151
+ "autocapitalize",
152
+ "spellcheck",
153
+ "aria-label",
154
+ "aria-labelledby",
155
+ "aria-describedby"
156
+ ];
157
+ proxiedAttributes.forEach((attr) => {
158
+ const value = super.getAttribute(attr);
159
+ if (value !== null) {
160
+ this.setAttribute(attr, value);
161
+ }
162
+ });
39
163
  }
40
164
  getAttribute(qualifiedName) {
41
- if (qualifiedName === "id") {
42
- return this.id || null;
165
+ switch (qualifiedName) {
166
+ case "id":
167
+ return this.id || null;
168
+ case "title":
169
+ return this.title || null;
170
+ case "autocapitalize":
171
+ return this.autocapitalize || null;
172
+ case "spellcheck":
173
+ return this._spellcheck !== null ? String(this._spellcheck) : null;
174
+ case "aria-label":
175
+ return this.ariaLabel;
176
+ case "aria-labelledby":
177
+ return this.ariaLabelledBy;
178
+ case "aria-describedby":
179
+ return this.ariaDescribedBy;
180
+ default:
181
+ return super.getAttribute(qualifiedName);
43
182
  }
44
- return super.getAttribute(qualifiedName);
45
183
  }
46
184
  hasAttribute(qualifiedName) {
47
- if (qualifiedName === "id") {
48
- return this.id !== "";
185
+ switch (qualifiedName) {
186
+ case "id":
187
+ return this.id !== "";
188
+ case "title":
189
+ return this.title !== "";
190
+ case "autocapitalize":
191
+ return this.autocapitalize !== "";
192
+ case "spellcheck":
193
+ return this._spellcheck !== null;
194
+ case "aria-label":
195
+ return this.ariaLabel !== null;
196
+ case "aria-labelledby":
197
+ return this.ariaLabelledBy !== null;
198
+ case "aria-describedby":
199
+ return this.ariaDescribedBy !== null;
200
+ default:
201
+ return super.hasAttribute(qualifiedName);
49
202
  }
50
- return super.hasAttribute(qualifiedName);
51
203
  }
52
204
  setAttribute(qualifiedName, value) {
53
- if (qualifiedName === "id") {
54
- this.id = value;
55
- return;
205
+ switch (qualifiedName) {
206
+ case "id":
207
+ this.id = value;
208
+ break;
209
+ case "title":
210
+ this.title = value;
211
+ break;
212
+ case "autocapitalize":
213
+ this.autocapitalize = value;
214
+ break;
215
+ case "spellcheck":
216
+ this.spellcheck = value !== "false";
217
+ break;
218
+ case "aria-label":
219
+ this.ariaLabel = value;
220
+ break;
221
+ case "aria-labelledby":
222
+ this.ariaLabelledBy = value;
223
+ break;
224
+ case "aria-describedby":
225
+ this.ariaDescribedBy = value;
226
+ break;
227
+ default:
228
+ super.setAttribute(qualifiedName, value);
56
229
  }
57
- super.setAttribute(qualifiedName, value);
58
230
  }
59
231
  removeAttribute(qualifiedName) {
60
- if (qualifiedName === "id") {
61
- this.id = "";
62
- return;
232
+ switch (qualifiedName) {
233
+ case "id":
234
+ this.id = "";
235
+ break;
236
+ case "title":
237
+ this.title = "";
238
+ break;
239
+ case "autocapitalize":
240
+ this.autocapitalize = "";
241
+ break;
242
+ case "spellcheck":
243
+ this.spellcheck = null;
244
+ break;
245
+ case "aria-label":
246
+ this.ariaLabel = null;
247
+ break;
248
+ case "aria-labelledby":
249
+ this.ariaLabelledBy = null;
250
+ break;
251
+ case "aria-describedby":
252
+ this.ariaDescribedBy = null;
253
+ break;
254
+ default:
255
+ super.removeAttribute(qualifiedName);
256
+ }
257
+ }
258
+ _removeHostAttribute(name) {
259
+ const host = this;
260
+ if (HTMLElement.prototype.hasAttribute.call(host, name)) {
261
+ HTMLElement.prototype.removeAttribute.call(host, name);
63
262
  }
64
- super.removeAttribute(qualifiedName);
65
263
  }
66
264
  get forwardedAriaLabel() {
67
265
  const value = this.ariaLabel?.trim();
@@ -76,11 +274,7 @@ var SpectreBaseElement = class extends LitElement {
76
274
  return value ? value : void 0;
77
275
  }
78
276
  };
79
- SpectreBaseElement.properties = {
80
- ariaLabel: { attribute: "aria-label", type: String },
81
- ariaLabelledBy: { attribute: "aria-labelledby", type: String },
82
- ariaDescribedBy: { attribute: "aria-describedby", type: String }
83
- };
277
+ SpectreBaseElement.properties = {};
84
278
 
85
279
  // src/utils/dom.ts
86
280
  function hasMeaningfulContent(nodes) {
@@ -141,9 +335,9 @@ var SpectreProjectableElement = class extends SpectreBaseElement {
141
335
  }
142
336
  this.contentObserver = new MutationObserver((mutations) => {
143
337
  const isInternalMovement = mutations.every(
144
- (mutation) => Array.from(mutation.removedNodes).every(
338
+ (mutation) => [...mutation.removedNodes].every(
145
339
  (node) => this.isInternalNode(node) || this.contains(node)
146
- ) && Array.from(mutation.addedNodes).every((node) => this.isInternalNode(node))
340
+ ) && [...mutation.addedNodes].every((node) => this.isInternalNode(node))
147
341
  );
148
342
  if (isInternalMovement) {
149
343
  return;
@@ -159,41 +353,33 @@ var SpectreProjectableElement = class extends SpectreBaseElement {
159
353
  this.contentObserver = void 0;
160
354
  }
161
355
  };
162
- var spectreButtonVariants = [
163
- "primary",
164
- "secondary",
165
- "ghost",
166
- "danger",
167
- "success",
168
- "cta",
169
- "accent"
170
- ];
171
- var spectreButtonSizes = ["sm", "md", "lg"];
172
- var spectreButtonTypes = ["button", "submit", "reset"];
173
- function isButtonVariant(value) {
174
- return spectreButtonVariants.includes(value);
175
- }
176
- function isButtonSize(value) {
177
- return spectreButtonSizes.includes(value);
178
- }
179
- function isButtonType(value) {
180
- return spectreButtonTypes.includes(value);
181
- }
182
356
  var SpectreButtonElement = class extends SpectreProjectableElement {
183
357
  constructor() {
184
358
  super(...arguments);
185
359
  this.autofocus = false;
186
360
  this.disabled = false;
187
361
  this.fullWidth = false;
362
+ this.iconOnly = false;
188
363
  this.loading = false;
189
364
  this.loadingLabel = "Loading";
190
365
  this.pill = false;
191
366
  this.size = "md";
192
- this.title = "";
193
367
  this.type = "button";
194
368
  this.variant = "primary";
195
369
  this.value = "";
196
370
  }
371
+ get id() {
372
+ return super.id;
373
+ }
374
+ set id(value) {
375
+ super.id = value;
376
+ }
377
+ get title() {
378
+ return super.title;
379
+ }
380
+ set title(value) {
381
+ super.title = value;
382
+ }
197
383
  getContentContainer() {
198
384
  return this.querySelector("[data-sp-button-native]");
199
385
  }
@@ -205,13 +391,13 @@ var SpectreButtonElement = class extends SpectreProjectableElement {
205
391
  return el.hasAttribute("data-sp-button-native") || el.hasAttribute("data-sp-button-loading-label") || el.hasAttribute("data-sp-button-label-fallback");
206
392
  }
207
393
  willUpdate(changedProperties) {
208
- if (changedProperties.has("variant") && !isButtonVariant(this.variant)) {
394
+ if (changedProperties.has("variant") && (this.variant == null || !isButtonVariant(this.variant))) {
209
395
  this.variant = "primary";
210
396
  }
211
- if (changedProperties.has("size") && !isButtonSize(this.size)) {
397
+ if (changedProperties.has("size") && (this.size == null || !isInputSize(this.size))) {
212
398
  this.size = "md";
213
399
  }
214
- if (changedProperties.has("type") && !isButtonType(this.type)) {
400
+ if (changedProperties.has("type") && (this.type == null || !isButtonType(this.type))) {
215
401
  this.type = "button";
216
402
  }
217
403
  if (changedProperties.has("loadingLabel")) {
@@ -226,15 +412,16 @@ var SpectreButtonElement = class extends SpectreProjectableElement {
226
412
  get buttonClasses() {
227
413
  return getButtonClasses({
228
414
  disabled: this.isDisabled,
229
- fullWidth: this.fullWidth,
230
- loading: this.loading,
231
- pill: this.pill,
415
+ fullWidth: this.fullWidth ?? false,
416
+ iconOnly: this.iconOnly ?? false,
417
+ loading: this.loading ?? false,
418
+ pill: this.pill ?? false,
232
419
  size: this.size,
233
420
  variant: this.variant
234
421
  });
235
422
  }
236
423
  get isDisabled() {
237
- return this.disabled || this.loading;
424
+ return (this.disabled ?? false) || (this.loading ?? false);
238
425
  }
239
426
  get visibleLabelFallback() {
240
427
  const trimmedLabel = this.label?.trim();
@@ -248,34 +435,32 @@ var SpectreButtonElement = class extends SpectreProjectableElement {
248
435
  }
249
436
  renderButtonContent() {
250
437
  if (this.loading) {
251
- return html`<span data-sp-button-loading-label>${this.loadingLabel}</span>`;
438
+ return html`<span class="sp-label" data-sp-button-loading-label>${this.loadingLabel}</span>`;
252
439
  }
253
440
  if (this.hasProjectedContent) {
254
441
  return this.projectedContent;
255
442
  }
256
- return this.visibleLabelFallback ? html`<span data-sp-button-label-fallback>${this.visibleLabelFallback}</span>` : nothing;
443
+ return this.visibleLabelFallback ? html`<span class="sp-label" data-sp-button-label-fallback>${this.visibleLabelFallback}</span>` : nothing;
257
444
  }
258
445
  render() {
259
- return html`
260
- <button
261
- aria-busy=${this.loading ? "true" : "false"}
262
- aria-describedby=${ifDefined(this.forwardedAriaDescribedBy)}
263
- aria-label=${ifDefined(this.forwardedAriaLabel)}
264
- aria-labelledby=${ifDefined(this.forwardedAriaLabelledBy)}
265
- ?autofocus=${this.autofocus}
266
- class=${this.buttonClasses}
267
- data-sp-button-native
268
- ?disabled=${this.isDisabled}
269
- form=${ifDefined(this.form)}
270
- id=${ifDefined(this.id || void 0)}
271
- name=${ifDefined(this.name)}
272
- title=${ifDefined(this.title || void 0)}
273
- type=${this.type}
274
- value=${ifDefined(this.value)}
275
- >
276
- ${this.renderButtonContent() || nothing}
277
- </button>
278
- `;
446
+ return html`<button
447
+ aria-busy="${this.loading ? "true" : "false"}"
448
+ aria-describedby="${ifDefined(this.forwardedAriaDescribedBy)}"
449
+ aria-label="${ifDefined(this.forwardedAriaLabel)}"
450
+ aria-labelledby="${ifDefined(this.forwardedAriaLabelledBy)}"
451
+ ?autofocus="${this.autofocus}"
452
+ class="${this.buttonClasses}"
453
+ data-sp-button-native
454
+ ?disabled="${this.isDisabled}"
455
+ form="${ifDefined(this.form || void 0)}"
456
+ id="${ifDefined(this.id || void 0)}"
457
+ name="${ifDefined(this.name || void 0)}"
458
+ title="${ifDefined(this.title || void 0)}"
459
+ type="${this.type}"
460
+ value="${ifDefined(this.value)}"
461
+ >
462
+ ${this.renderButtonContent()}
463
+ </button>`;
279
464
  }
280
465
  };
281
466
  SpectreButtonElement.properties = {
@@ -283,16 +468,16 @@ SpectreButtonElement.properties = {
283
468
  disabled: { type: Boolean, reflect: true },
284
469
  form: { type: String },
285
470
  fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
471
+ iconOnly: { attribute: "icon-only", type: Boolean, reflect: true },
286
472
  label: { type: String, reflect: true },
287
473
  loading: { type: Boolean, reflect: true },
288
474
  loadingLabel: { attribute: "loading-label", type: String, reflect: true },
289
475
  name: { type: String, reflect: true },
290
476
  pill: { type: Boolean, reflect: true },
291
477
  size: { type: String, reflect: true },
292
- title: { type: String, reflect: true },
293
478
  type: { type: String, reflect: true },
294
479
  variant: { type: String, reflect: true },
295
- value: { type: String, reflect: true }
480
+ value: { type: String }
296
481
  };
297
482
  function defineSpectreButton(tagName = "sp-button") {
298
483
  const existingElement = customElements.get(tagName);
@@ -302,27 +487,6 @@ function defineSpectreButton(tagName = "sp-button") {
302
487
  customElements.define(tagName, SpectreButtonElement);
303
488
  return SpectreButtonElement;
304
489
  }
305
- var spectreInputSizes = ["sm", "md", "lg"];
306
- function isInputSize(value) {
307
- return spectreInputSizes.includes(value);
308
- }
309
- var spectreInputTypes = [
310
- "text",
311
- "email",
312
- "password",
313
- "search",
314
- "tel",
315
- "url",
316
- "number",
317
- "date",
318
- "datetime-local",
319
- "month",
320
- "time",
321
- "week"
322
- ];
323
- function isInputType(value) {
324
- return spectreInputTypes.includes(value);
325
- }
326
490
  var SpectreInputElement = class extends SpectreBaseElement {
327
491
  constructor() {
328
492
  super(...arguments);
@@ -336,41 +500,60 @@ var SpectreInputElement = class extends SpectreBaseElement {
336
500
  this.required = false;
337
501
  this.size = "md";
338
502
  this.success = false;
339
- this.title = "";
340
503
  this.type = "text";
341
504
  this.value = "";
342
505
  }
506
+ get autocapitalize() {
507
+ return super.autocapitalize;
508
+ }
509
+ set autocapitalize(value) {
510
+ super.autocapitalize = value;
511
+ }
512
+ get id() {
513
+ return super.id;
514
+ }
515
+ set id(value) {
516
+ super.id = value;
517
+ }
518
+ get spellcheck() {
519
+ return super.spellcheck;
520
+ }
521
+ set spellcheck(value) {
522
+ super.spellcheck = value;
523
+ }
524
+ get title() {
525
+ return super.title;
526
+ }
527
+ set title(value) {
528
+ super.title = value;
529
+ }
343
530
  willUpdate(changedProperties) {
344
- if (changedProperties.has("size") && !isInputSize(this.size)) {
531
+ if (changedProperties.has("size") && (this.size == null || !isInputSize(this.size))) {
345
532
  this.size = "md";
346
533
  }
347
- if (changedProperties.has("type") && !isInputType(this.type)) {
534
+ if (changedProperties.has("type") && (this.type == null || !isInputType(this.type))) {
348
535
  this.type = "text";
349
536
  }
350
537
  if (changedProperties.has("value") && this.value == null) {
351
538
  this.value = "";
352
539
  }
353
540
  if (changedProperties.has("maxlength")) {
354
- if (this.maxlength == null || !Number.isInteger(this.maxlength) || this.maxlength < 0) {
355
- this.maxlength = void 0;
356
- }
541
+ this.maxlength = normalizeInt(this.maxlength, void 0);
357
542
  }
358
543
  if (changedProperties.has("minlength")) {
359
- if (this.minlength == null || !Number.isInteger(this.minlength) || this.minlength < 0) {
360
- this.minlength = void 0;
361
- }
544
+ this.minlength = normalizeInt(this.minlength, void 0);
362
545
  }
363
546
  }
364
547
  get inputClasses() {
365
548
  return getInputClasses({
366
- fullWidth: this.fullWidth,
367
- pill: this.pill,
549
+ fullWidth: this.fullWidth ?? false,
550
+ pill: this.pill ?? false,
368
551
  size: this.size,
369
552
  state: this.isDisabled ? this.disabled ? "disabled" : "loading" : this.invalid ? "error" : this.success ? "success" : "default"
370
553
  });
371
554
  }
372
555
  get isDisabled() {
373
- return this.disabled || this.loading;
556
+ return (this.disabled ?? false) || (this.loading ?? false);
374
557
  }
375
558
  get nativeInput() {
376
559
  return this.querySelector("[data-sp-input-native]");
@@ -390,61 +573,70 @@ var SpectreInputElement = class extends SpectreBaseElement {
390
573
  this.nativeInput?.blur();
391
574
  }
392
575
  render() {
393
- return html`
394
- <input
395
- aria-busy=${this.loading ? "true" : "false"}
396
- aria-describedby=${ifDefined(this.forwardedAriaDescribedBy)}
397
- aria-invalid=${ifDefined(this.invalid ? "true" : void 0)}
398
- aria-label=${ifDefined(this.forwardedAriaLabel)}
399
- aria-labelledby=${ifDefined(this.forwardedAriaLabelledBy)}
400
- autocomplete=${ifDefined(this.autocomplete)}
401
- ?autofocus=${this.autofocus}
402
- class=${this.inputClasses}
403
- data-sp-input-native
404
- ?disabled=${this.isDisabled}
405
- form=${ifDefined(this.form)}
406
- ?readonly=${this.readonly}
407
- ?required=${this.required}
408
- id=${ifDefined(this.id || void 0)}
409
- inputmode=${ifDefined(this.inputmode)}
410
- max=${ifDefined(this.max)}
411
- maxlength=${ifDefined(this.maxlength)}
412
- min=${ifDefined(this.min)}
413
- minlength=${ifDefined(this.minlength)}
414
- name=${ifDefined(this.name)}
415
- placeholder=${ifDefined(this.placeholder)}
416
- step=${ifDefined(this.step)}
417
- title=${ifDefined(this.title || void 0)}
418
- type=${this.type}
419
- .value=${live(this.value)}
420
- @change=${this.handleChange}
421
- @input=${this.handleInput}
422
- />
423
- `;
576
+ return html`<input
577
+ aria-busy="${this.loading ? "true" : "false"}"
578
+ aria-describedby="${ifDefined(this.forwardedAriaDescribedBy)}"
579
+ aria-invalid="${ifDefined(this.invalid ? "true" : void 0)}"
580
+ aria-label="${ifDefined(this.forwardedAriaLabel)}"
581
+ aria-labelledby="${ifDefined(this.forwardedAriaLabelledBy)}"
582
+ autocapitalize="${ifDefined(this.autocapitalize || void 0)}"
583
+ autocomplete="${ifDefined(this.autocomplete || void 0)}"
584
+ ?autofocus="${this.autofocus}"
585
+ class="${this.inputClasses}"
586
+ data-sp-input-native
587
+ ?disabled="${this.isDisabled}"
588
+ enterkeyhint="${ifDefined(this.enterkeyhint || void 0)}"
589
+ form="${ifDefined(this.form || void 0)}"
590
+ ?readonly="${this.readonly}"
591
+ ?required="${this.required}"
592
+ id="${ifDefined(this.id || void 0)}"
593
+ inputmode="${ifDefined(this.inputmode || void 0)}"
594
+ list="${ifDefined(this.list || void 0)}"
595
+ max="${ifDefined(this.max || void 0)}"
596
+ maxlength="${ifDefined(this.maxlength)}"
597
+ min="${ifDefined(this.min || void 0)}"
598
+ minlength="${ifDefined(this.minlength)}"
599
+ name="${ifDefined(this.name || void 0)}"
600
+ pattern="${ifDefined(this.pattern || void 0)}"
601
+ placeholder="${ifDefined(this.placeholder || void 0)}"
602
+ spellcheck="${ifDefined(
603
+ this.spellcheck === void 0 ? void 0 : String(this.spellcheck)
604
+ )}"
605
+ step="${ifDefined(this.step || void 0)}"
606
+ title="${ifDefined(this.title || void 0)}"
607
+ type="${this.type}"
608
+ .value="${live(this.value)}"
609
+ @change="${this.handleChange}"
610
+ @input="${this.handleInput}"
611
+ />`;
424
612
  }
425
613
  };
426
614
  SpectreInputElement.properties = {
615
+ autocapitalize: { type: String, reflect: true },
427
616
  autocomplete: { type: String, reflect: true },
428
617
  autofocus: { type: Boolean, reflect: true },
429
618
  disabled: { type: Boolean, reflect: true },
619
+ enterkeyhint: { type: String, reflect: true },
430
620
  form: { type: String },
431
621
  fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
432
622
  inputmode: { type: String, reflect: true },
433
623
  invalid: { type: Boolean, reflect: true },
624
+ list: { type: String, reflect: true },
434
625
  loading: { type: Boolean, reflect: true },
435
626
  max: { type: String, reflect: true },
436
627
  maxlength: { type: Number, reflect: true },
437
628
  min: { type: String, reflect: true },
438
629
  minlength: { type: Number, reflect: true },
439
630
  name: { type: String, reflect: true },
631
+ pattern: { type: String, reflect: true },
440
632
  pill: { type: Boolean, reflect: true },
441
633
  placeholder: { type: String, reflect: true },
442
634
  readonly: { type: Boolean, reflect: true },
443
635
  required: { type: Boolean, reflect: true },
444
636
  size: { type: String, reflect: true },
637
+ spellcheck: { type: Boolean, reflect: true },
445
638
  step: { type: String, reflect: true },
446
639
  success: { type: Boolean, reflect: true },
447
- title: { type: String, reflect: true },
448
640
  type: { type: String, reflect: true },
449
641
  value: { type: String }
450
642
  };
@@ -471,42 +663,59 @@ var SpectreTextareaElement = class extends SpectreBaseElement {
471
663
  this.rows = DEFAULT_ROWS;
472
664
  this.size = "md";
473
665
  this.success = false;
474
- this.title = "";
475
666
  this.value = "";
476
667
  }
668
+ get autocapitalize() {
669
+ return super.autocapitalize;
670
+ }
671
+ set autocapitalize(value) {
672
+ super.autocapitalize = value;
673
+ }
674
+ get id() {
675
+ return super.id;
676
+ }
677
+ set id(value) {
678
+ super.id = value;
679
+ }
680
+ get spellcheck() {
681
+ return super.spellcheck;
682
+ }
683
+ set spellcheck(value) {
684
+ super.spellcheck = value;
685
+ }
686
+ get title() {
687
+ return super.title;
688
+ }
689
+ set title(value) {
690
+ super.title = value;
691
+ }
477
692
  willUpdate(changedProperties) {
478
- if (changedProperties.has("size") && !isInputSize(this.size)) {
693
+ if (changedProperties.has("size") && (this.size == null || !isInputSize(this.size))) {
479
694
  this.size = "md";
480
695
  }
481
696
  if (changedProperties.has("rows")) {
482
- if (this.rows == null || !Number.isInteger(this.rows) || this.rows < 1) {
483
- this.rows = DEFAULT_ROWS;
484
- }
697
+ this.rows = normalizeInt(this.rows, DEFAULT_ROWS, 1);
485
698
  }
486
699
  if (changedProperties.has("value") && this.value == null) {
487
700
  this.value = "";
488
701
  }
489
702
  if (changedProperties.has("maxlength")) {
490
- if (this.maxlength == null || !Number.isInteger(this.maxlength) || this.maxlength < 0) {
491
- this.maxlength = void 0;
492
- }
703
+ this.maxlength = normalizeInt(this.maxlength, void 0);
493
704
  }
494
705
  if (changedProperties.has("minlength")) {
495
- if (this.minlength == null || !Number.isInteger(this.minlength) || this.minlength < 0) {
496
- this.minlength = void 0;
497
- }
706
+ this.minlength = normalizeInt(this.minlength, void 0);
498
707
  }
499
708
  }
500
709
  get textareaClasses() {
501
710
  return getInputClasses({
502
- fullWidth: this.fullWidth,
503
- pill: this.pill,
711
+ fullWidth: this.fullWidth ?? false,
712
+ pill: this.pill ?? false,
504
713
  size: this.size,
505
714
  state: this.isDisabled ? this.disabled ? "disabled" : "loading" : this.invalid ? "error" : this.success ? "success" : "default"
506
715
  });
507
716
  }
508
717
  get isDisabled() {
509
- return this.disabled || this.loading;
718
+ return (this.disabled ?? false) || (this.loading ?? false);
510
719
  }
511
720
  get nativeTextarea() {
512
721
  return this.querySelector("[data-sp-textarea-native]");
@@ -526,40 +735,45 @@ var SpectreTextareaElement = class extends SpectreBaseElement {
526
735
  this.nativeTextarea?.blur();
527
736
  }
528
737
  render() {
529
- return html`
530
- <textarea
531
- aria-busy=${this.loading ? "true" : "false"}
532
- aria-describedby=${ifDefined(this.forwardedAriaDescribedBy)}
533
- aria-invalid=${ifDefined(this.invalid ? "true" : void 0)}
534
- aria-label=${ifDefined(this.forwardedAriaLabel)}
535
- aria-labelledby=${ifDefined(this.forwardedAriaLabelledBy)}
536
- autocomplete=${ifDefined(this.autocomplete)}
537
- ?autofocus=${this.autofocus}
538
- class=${this.textareaClasses}
539
- data-sp-textarea-native
540
- ?disabled=${this.isDisabled}
541
- form=${ifDefined(this.form)}
542
- inputmode=${ifDefined(this.inputmode)}
543
- ?readonly=${this.readonly}
544
- ?required=${this.required}
545
- id=${ifDefined(this.id || void 0)}
546
- maxlength=${ifDefined(this.maxlength)}
547
- minlength=${ifDefined(this.minlength)}
548
- name=${ifDefined(this.name)}
549
- placeholder=${ifDefined(this.placeholder)}
550
- rows=${this.rows}
551
- title=${ifDefined(this.title || void 0)}
552
- .value=${live(this.value)}
553
- @change=${this.handleChange}
554
- @input=${this.handleInput}
555
- ></textarea>
556
- `;
738
+ return html`<textarea
739
+ aria-busy="${this.loading ? "true" : "false"}"
740
+ aria-describedby="${ifDefined(this.forwardedAriaDescribedBy)}"
741
+ aria-invalid="${ifDefined(this.invalid ? "true" : void 0)}"
742
+ aria-label="${ifDefined(this.forwardedAriaLabel)}"
743
+ aria-labelledby="${ifDefined(this.forwardedAriaLabelledBy)}"
744
+ autocapitalize="${ifDefined(this.autocapitalize || void 0)}"
745
+ autocomplete="${ifDefined(this.autocomplete || void 0)}"
746
+ ?autofocus="${this.autofocus}"
747
+ class="${this.textareaClasses}"
748
+ data-sp-textarea-native
749
+ ?disabled="${this.isDisabled}"
750
+ enterkeyhint="${ifDefined(this.enterkeyhint || void 0)}"
751
+ form="${ifDefined(this.form || void 0)}"
752
+ inputmode="${ifDefined(this.inputmode || void 0)}"
753
+ ?readonly="${this.readonly}"
754
+ ?required="${this.required}"
755
+ id="${ifDefined(this.id || void 0)}"
756
+ maxlength="${ifDefined(this.maxlength)}"
757
+ minlength="${ifDefined(this.minlength)}"
758
+ name="${ifDefined(this.name || void 0)}"
759
+ placeholder="${ifDefined(this.placeholder || void 0)}"
760
+ rows="${this.rows}"
761
+ spellcheck="${ifDefined(
762
+ this.spellcheck === void 0 ? void 0 : String(this.spellcheck)
763
+ )}"
764
+ title="${ifDefined(this.title || void 0)}"
765
+ .value="${live(this.value)}"
766
+ @change="${this.handleChange}"
767
+ @input="${this.handleInput}"
768
+ ></textarea>`;
557
769
  }
558
770
  };
559
771
  SpectreTextareaElement.properties = {
772
+ autocapitalize: { type: String, reflect: true },
560
773
  autocomplete: { type: String, reflect: true },
561
774
  autofocus: { type: Boolean, reflect: true },
562
775
  disabled: { type: Boolean, reflect: true },
776
+ enterkeyhint: { type: String, reflect: true },
563
777
  form: { type: String },
564
778
  fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
565
779
  inputmode: { type: String, reflect: true },
@@ -572,10 +786,10 @@ SpectreTextareaElement.properties = {
572
786
  placeholder: { type: String, reflect: true },
573
787
  readonly: { type: Boolean, reflect: true },
574
788
  required: { type: Boolean, reflect: true },
575
- rows: { type: Number },
789
+ rows: { type: Number, reflect: true },
576
790
  size: { type: String, reflect: true },
791
+ spellcheck: { type: Boolean, reflect: true },
577
792
  success: { type: Boolean, reflect: true },
578
- title: { type: String, reflect: true },
579
793
  value: { type: String }
580
794
  };
581
795
  function defineSpectreTextarea(tagName = "sp-textarea") {
@@ -598,9 +812,20 @@ var SpectreSelectElement = class extends SpectreProjectableElement {
598
812
  this.required = false;
599
813
  this.size = "md";
600
814
  this.success = false;
601
- this.title = "";
602
815
  this.value = "";
603
816
  }
817
+ get id() {
818
+ return super.id;
819
+ }
820
+ set id(value) {
821
+ super.id = value;
822
+ }
823
+ get title() {
824
+ return super.title;
825
+ }
826
+ set title(value) {
827
+ super.title = value;
828
+ }
604
829
  getContentContainer() {
605
830
  return this.querySelector("[data-sp-select-native]");
606
831
  }
@@ -612,7 +837,7 @@ var SpectreSelectElement = class extends SpectreProjectableElement {
612
837
  return el.hasAttribute("data-sp-select-native");
613
838
  }
614
839
  willUpdate(changedProperties) {
615
- if (changedProperties.has("size") && !isInputSize(this.size)) {
840
+ if (changedProperties.has("size") && (this.size == null || !isInputSize(this.size))) {
616
841
  this.size = "md";
617
842
  }
618
843
  if (changedProperties.has("value") && this.value == null) {
@@ -625,8 +850,12 @@ var SpectreSelectElement = class extends SpectreProjectableElement {
625
850
  if (!nativeSelect) {
626
851
  return;
627
852
  }
628
- if (this.value !== "" && nativeSelect.value !== this.value) {
629
- nativeSelect.value = this.value;
853
+ const valueChanged = changedProperties.has("value");
854
+ const oldValue = changedProperties.get("value");
855
+ if (valueChanged && this.value !== void 0 && (this.value !== "" || oldValue !== void 0 || this.hasAttribute("value"))) {
856
+ if (nativeSelect.value !== this.value) {
857
+ nativeSelect.value = this.value;
858
+ }
630
859
  }
631
860
  if (this.value === "" && !this.hasAttribute("value")) {
632
861
  const nativeValue = nativeSelect.value ?? "";
@@ -641,14 +870,14 @@ var SpectreSelectElement = class extends SpectreProjectableElement {
641
870
  }
642
871
  get selectClasses() {
643
872
  return getInputClasses({
644
- fullWidth: this.fullWidth,
645
- pill: this.pill,
873
+ fullWidth: this.fullWidth ?? false,
874
+ pill: this.pill ?? false,
646
875
  size: this.size,
647
876
  state: this.isDisabled ? this.disabled ? "disabled" : "loading" : this.invalid ? "error" : this.success ? "success" : "default"
648
877
  });
649
878
  }
650
879
  get isDisabled() {
651
- return this.disabled || this.loading;
880
+ return (this.disabled ?? false) || (this.loading ?? false);
652
881
  }
653
882
  handleInput(event) {
654
883
  const select = event.currentTarget;
@@ -665,30 +894,28 @@ var SpectreSelectElement = class extends SpectreProjectableElement {
665
894
  this.getContentContainer()?.blur();
666
895
  }
667
896
  render() {
668
- return html`
669
- <select
670
- aria-busy=${this.loading ? "true" : "false"}
671
- aria-describedby=${ifDefined(this.forwardedAriaDescribedBy)}
672
- aria-invalid=${ifDefined(this.invalid ? "true" : void 0)}
673
- aria-label=${ifDefined(this.forwardedAriaLabel)}
674
- aria-labelledby=${ifDefined(this.forwardedAriaLabelledBy)}
675
- autocomplete=${ifDefined(this.autocomplete)}
676
- ?autofocus=${this.autofocus}
677
- class=${this.selectClasses}
678
- data-sp-select-native
679
- ?disabled=${this.isDisabled}
680
- form=${ifDefined(this.form)}
681
- id=${ifDefined(this.id || void 0)}
682
- name=${ifDefined(this.name)}
683
- ?required=${this.required}
684
- title=${ifDefined(this.title || void 0)}
685
- .value=${live(this.value)}
686
- @change=${this.handleChange}
687
- @input=${this.handleInput}
688
- >
689
- ${this.hasProjectedContent ? this.projectedContent : nothing}
690
- </select>
691
- `;
897
+ return html`<select
898
+ aria-busy="${this.loading ? "true" : "false"}"
899
+ aria-describedby="${ifDefined(this.forwardedAriaDescribedBy)}"
900
+ aria-invalid="${ifDefined(this.invalid ? "true" : void 0)}"
901
+ aria-label="${ifDefined(this.forwardedAriaLabel)}"
902
+ aria-labelledby="${ifDefined(this.forwardedAriaLabelledBy)}"
903
+ autocomplete="${ifDefined(this.autocomplete || void 0)}"
904
+ ?autofocus="${this.autofocus}"
905
+ class="${this.selectClasses}"
906
+ data-sp-select-native
907
+ ?disabled="${this.isDisabled}"
908
+ form="${ifDefined(this.form || void 0)}"
909
+ id="${ifDefined(this.id || void 0)}"
910
+ name="${ifDefined(this.name || void 0)}"
911
+ ?required="${this.required}"
912
+ title="${ifDefined(this.title || void 0)}"
913
+ .value="${live(this.value)}"
914
+ @change="${this.handleChange}"
915
+ @input="${this.handleInput}"
916
+ >
917
+ ${this.hasProjectedContent ? this.projectedContent : nothing}
918
+ </select>`;
692
919
  }
693
920
  };
694
921
  SpectreSelectElement.properties = {
@@ -704,7 +931,6 @@ SpectreSelectElement.properties = {
704
931
  required: { type: Boolean, reflect: true },
705
932
  size: { type: String, reflect: true },
706
933
  success: { type: Boolean, reflect: true },
707
- title: { type: String, reflect: true },
708
934
  value: { type: String }
709
935
  };
710
936
  function defineSpectreSelect(tagName = "sp-select") {
@@ -725,9 +951,20 @@ var SpectreCheckboxElement = class extends SpectreProjectableElement {
725
951
  this.loading = false;
726
952
  this.required = false;
727
953
  this.success = false;
728
- this.title = "";
729
954
  this.value = "on";
730
955
  }
956
+ get id() {
957
+ return super.id;
958
+ }
959
+ set id(value) {
960
+ super.id = value;
961
+ }
962
+ get title() {
963
+ return super.title;
964
+ }
965
+ set title(value) {
966
+ super.title = value;
967
+ }
731
968
  getContentContainer() {
732
969
  return this.querySelector("[data-sp-checkbox-label]");
733
970
  }
@@ -747,7 +984,7 @@ var SpectreCheckboxElement = class extends SpectreProjectableElement {
747
984
  return this.querySelector("[data-sp-checkbox-native]");
748
985
  }
749
986
  get isDisabled() {
750
- return this.disabled || this.loading;
987
+ return (this.disabled ?? false) || (this.loading ?? false);
751
988
  }
752
989
  get visibleLabelFallback() {
753
990
  const trimmedLabel = this.label?.trim();
@@ -768,33 +1005,34 @@ var SpectreCheckboxElement = class extends SpectreProjectableElement {
768
1005
  this.nativeInput?.blur();
769
1006
  }
770
1007
  render() {
771
- const labelContent = this.hasProjectedContent ? this.projectedContent : this.visibleLabelFallback ? html`<span class='sp-label' data-sp-checkbox-label-fallback>${this.visibleLabelFallback}</span>` : nothing;
772
- return html`
773
- <label data-sp-checkbox-label>
774
- <input
775
- aria-busy=${this.loading ? "true" : "false"}
776
- aria-describedby=${ifDefined(this.forwardedAriaDescribedBy)}
777
- aria-invalid=${ifDefined(this.invalid ? "true" : void 0)}
778
- aria-label=${ifDefined(this.forwardedAriaLabel)}
779
- aria-labelledby=${ifDefined(this.forwardedAriaLabelledBy)}
780
- ?autofocus=${this.autofocus}
781
- data-sp-checkbox-native
782
- .checked=${live(this.checked)}
783
- ?disabled=${this.isDisabled}
784
- form=${ifDefined(this.form)}
785
- id=${ifDefined(this.id || void 0)}
786
- name=${ifDefined(this.name)}
787
- ?required=${this.required}
788
- title=${ifDefined(this.title || void 0)}
789
- type='checkbox'
790
- value=${ifDefined(this.value || void 0)}
791
- @change=${this.handleChange}
792
- @input=${this.handleInput}
793
- />
794
- <span class="sp-checkbox-indicator" data-sp-checkbox-indicator></span>
795
- ${labelContent}
796
- </label>
797
- `;
1008
+ const labelContent = this.hasProjectedContent ? this.projectedContent : this.visibleLabelFallback ? html`<span
1009
+ class="${getInputLabelClasses({ disabled: this.isDisabled })}"
1010
+ data-sp-checkbox-label-fallback
1011
+ >${this.visibleLabelFallback}</span>` : nothing;
1012
+ return html`<label data-sp-checkbox-label>
1013
+ <input
1014
+ aria-busy="${this.loading ? "true" : "false"}"
1015
+ aria-describedby="${ifDefined(this.forwardedAriaDescribedBy)}"
1016
+ aria-invalid="${ifDefined(this.invalid ? "true" : void 0)}"
1017
+ aria-label="${ifDefined(this.forwardedAriaLabel)}"
1018
+ aria-labelledby="${ifDefined(this.forwardedAriaLabelledBy)}"
1019
+ ?autofocus="${this.autofocus}"
1020
+ data-sp-checkbox-native
1021
+ .checked="${live(this.checked)}"
1022
+ ?disabled="${this.isDisabled}"
1023
+ form="${ifDefined(this.form || void 0)}"
1024
+ id="${ifDefined(this.id || void 0)}"
1025
+ name="${ifDefined(this.name || void 0)}"
1026
+ ?required="${this.required}"
1027
+ title="${ifDefined(this.title || void 0)}"
1028
+ type="checkbox"
1029
+ value="${ifDefined(this.value)}"
1030
+ @change="${this.handleChange}"
1031
+ @input="${this.handleInput}"
1032
+ />
1033
+ <span class="sp-checkbox-indicator" data-sp-checkbox-indicator></span>
1034
+ ${labelContent}
1035
+ </label>`;
798
1036
  }
799
1037
  };
800
1038
  SpectreCheckboxElement.properties = {
@@ -808,7 +1046,6 @@ SpectreCheckboxElement.properties = {
808
1046
  name: { type: String, reflect: true },
809
1047
  required: { type: Boolean, reflect: true },
810
1048
  success: { type: Boolean, reflect: true },
811
- title: { type: String, reflect: true },
812
1049
  value: { type: String }
813
1050
  };
814
1051
  function defineSpectreCheckbox(tagName = "sp-checkbox") {
@@ -829,9 +1066,20 @@ var SpectreRadioElement = class extends SpectreProjectableElement {
829
1066
  this.loading = false;
830
1067
  this.required = false;
831
1068
  this.success = false;
832
- this.title = "";
833
1069
  this.value = "on";
834
1070
  }
1071
+ get id() {
1072
+ return super.id;
1073
+ }
1074
+ set id(value) {
1075
+ super.id = value;
1076
+ }
1077
+ get title() {
1078
+ return super.title;
1079
+ }
1080
+ set title(value) {
1081
+ super.title = value;
1082
+ }
835
1083
  getContentContainer() {
836
1084
  return this.querySelector("[data-sp-radio-label]");
837
1085
  }
@@ -851,7 +1099,7 @@ var SpectreRadioElement = class extends SpectreProjectableElement {
851
1099
  return this.querySelector("[data-sp-radio-native]");
852
1100
  }
853
1101
  get isDisabled() {
854
- return this.disabled || this.loading;
1102
+ return (this.disabled ?? false) || (this.loading ?? false);
855
1103
  }
856
1104
  get visibleLabelFallback() {
857
1105
  const trimmedLabel = this.label?.trim();
@@ -865,6 +1113,26 @@ var SpectreRadioElement = class extends SpectreProjectableElement {
865
1113
  const input = event.currentTarget;
866
1114
  this.checked = input.checked;
867
1115
  }
1116
+ updated(changedProperties) {
1117
+ super.updated(changedProperties);
1118
+ if ((changedProperties.has("checked") || changedProperties.has("name")) && this.checked && this.name) {
1119
+ this.syncGroup();
1120
+ }
1121
+ }
1122
+ syncGroup() {
1123
+ if (!this.name || !this.checked) {
1124
+ return;
1125
+ }
1126
+ const root = this.getRootNode();
1127
+ const radios = root.querySelectorAll(
1128
+ `sp-radio[name="${this.name}"]`
1129
+ );
1130
+ radios.forEach((radio) => {
1131
+ if (radio !== this && radio.checked) {
1132
+ radio.checked = false;
1133
+ }
1134
+ });
1135
+ }
868
1136
  focus(options) {
869
1137
  this.nativeInput?.focus(options);
870
1138
  }
@@ -872,33 +1140,34 @@ var SpectreRadioElement = class extends SpectreProjectableElement {
872
1140
  this.nativeInput?.blur();
873
1141
  }
874
1142
  render() {
875
- const labelContent = this.hasProjectedContent ? this.projectedContent : this.visibleLabelFallback ? html`<span class='sp-label' data-sp-radio-label-fallback>${this.visibleLabelFallback}</span>` : nothing;
876
- return html`
877
- <label data-sp-radio-label>
878
- <input
879
- aria-busy=${this.loading ? "true" : "false"}
880
- aria-describedby=${ifDefined(this.forwardedAriaDescribedBy)}
881
- aria-invalid=${ifDefined(this.invalid ? "true" : void 0)}
882
- aria-label=${ifDefined(this.forwardedAriaLabel)}
883
- aria-labelledby=${ifDefined(this.forwardedAriaLabelledBy)}
884
- ?autofocus=${this.autofocus}
885
- data-sp-radio-native
886
- .checked=${live(this.checked)}
887
- ?disabled=${this.isDisabled}
888
- form=${ifDefined(this.form)}
889
- id=${ifDefined(this.id || void 0)}
890
- name=${ifDefined(this.name)}
891
- ?required=${this.required}
892
- title=${ifDefined(this.title || void 0)}
893
- type='radio'
894
- value=${ifDefined(this.value || void 0)}
895
- @change=${this.handleChange}
896
- @input=${this.handleInput}
897
- />
898
- <span class="sp-radio-indicator" data-sp-radio-indicator></span>
899
- ${labelContent}
900
- </label>
901
- `;
1143
+ const labelContent = this.hasProjectedContent ? this.projectedContent : this.visibleLabelFallback ? html`<span
1144
+ class="${getInputLabelClasses({ disabled: this.isDisabled })}"
1145
+ data-sp-radio-label-fallback
1146
+ >${this.visibleLabelFallback}</span>` : nothing;
1147
+ return html`<label data-sp-radio-label>
1148
+ <input
1149
+ aria-busy="${this.loading ? "true" : "false"}"
1150
+ aria-describedby="${ifDefined(this.forwardedAriaDescribedBy)}"
1151
+ aria-invalid="${ifDefined(this.invalid ? "true" : void 0)}"
1152
+ aria-label="${ifDefined(this.forwardedAriaLabel)}"
1153
+ aria-labelledby="${ifDefined(this.forwardedAriaLabelledBy)}"
1154
+ ?autofocus="${this.autofocus}"
1155
+ data-sp-radio-native
1156
+ .checked="${live(this.checked)}"
1157
+ ?disabled="${this.isDisabled}"
1158
+ form="${ifDefined(this.form || void 0)}"
1159
+ id="${ifDefined(this.id || void 0)}"
1160
+ name="${ifDefined(this.name || void 0)}"
1161
+ ?required="${this.required}"
1162
+ title="${ifDefined(this.title || void 0)}"
1163
+ type="radio"
1164
+ value="${ifDefined(this.value)}"
1165
+ @change="${this.handleChange}"
1166
+ @input="${this.handleInput}"
1167
+ />
1168
+ <span class="sp-radio-indicator" data-sp-radio-indicator></span>
1169
+ ${labelContent}
1170
+ </label>`;
902
1171
  }
903
1172
  };
904
1173
  SpectreRadioElement.properties = {
@@ -912,7 +1181,6 @@ SpectreRadioElement.properties = {
912
1181
  name: { type: String, reflect: true },
913
1182
  required: { type: Boolean, reflect: true },
914
1183
  success: { type: Boolean, reflect: true },
915
- title: { type: String, reflect: true },
916
1184
  value: { type: String }
917
1185
  };
918
1186
  function defineSpectreRadio(tagName = "sp-radio") {
@@ -926,7 +1194,22 @@ function defineSpectreRadio(tagName = "sp-radio") {
926
1194
  var SpectreLabelElement = class extends SpectreProjectableElement {
927
1195
  constructor() {
928
1196
  super(...arguments);
929
- this.title = "";
1197
+ this.disabled = false;
1198
+ }
1199
+ get isDisabled() {
1200
+ return this.disabled ?? false;
1201
+ }
1202
+ get id() {
1203
+ return super.id;
1204
+ }
1205
+ set id(value) {
1206
+ super.id = value;
1207
+ }
1208
+ get title() {
1209
+ return super.title;
1210
+ }
1211
+ set title(value) {
1212
+ super.title = value;
930
1213
  }
931
1214
  getContentContainer() {
932
1215
  return this.querySelector("[data-sp-label-native]");
@@ -945,26 +1228,23 @@ var SpectreLabelElement = class extends SpectreProjectableElement {
945
1228
  this.getContentContainer()?.blur();
946
1229
  }
947
1230
  render() {
948
- return html`
949
- <label
950
- aria-describedby=${ifDefined(this.forwardedAriaDescribedBy)}
951
- aria-label=${ifDefined(this.forwardedAriaLabel)}
952
- aria-labelledby=${ifDefined(this.forwardedAriaLabelledBy)}
953
- class='sp-label'
954
- data-sp-label-native
955
- for=${ifDefined(this.htmlFor)}
956
- id=${ifDefined(this.id || void 0)}
957
- tabindex='-1'
958
- title=${ifDefined(this.title || void 0)}
959
- >
960
- ${this.hasProjectedContent ? this.projectedContent : nothing}
961
- </label>
962
- `;
1231
+ return html`<label
1232
+ aria-describedby="${ifDefined(this.forwardedAriaDescribedBy)}"
1233
+ aria-label="${ifDefined(this.forwardedAriaLabel)}"
1234
+ aria-labelledby="${ifDefined(this.forwardedAriaLabelledBy)}"
1235
+ class="${getInputLabelClasses({ disabled: this.isDisabled })}"
1236
+ data-sp-label-native
1237
+ for="${ifDefined(this.htmlFor || void 0)}"
1238
+ id="${ifDefined(this.id || void 0)}"
1239
+ title="${ifDefined(this.title || void 0)}"
1240
+ >
1241
+ ${this.hasProjectedContent ? this.projectedContent : nothing}
1242
+ </label>`;
963
1243
  }
964
1244
  };
965
1245
  SpectreLabelElement.properties = {
966
- htmlFor: { attribute: "for", type: String, reflect: true },
967
- title: { type: String, reflect: true }
1246
+ disabled: { type: Boolean, reflect: true },
1247
+ htmlFor: { attribute: "for", type: String, reflect: true }
968
1248
  };
969
1249
  function defineSpectreLabel(tagName = "sp-label") {
970
1250
  const existingElement = customElements.get(tagName);
@@ -978,8 +1258,28 @@ var SpectreFieldsetElement = class extends SpectreProjectableElement {
978
1258
  constructor() {
979
1259
  super(...arguments);
980
1260
  this.disabled = false;
981
- this.legend = "";
982
- this.title = "";
1261
+ this.invalid = false;
1262
+ this.loading = false;
1263
+ this.success = false;
1264
+ }
1265
+ get id() {
1266
+ return super.id;
1267
+ }
1268
+ set id(value) {
1269
+ super.id = value;
1270
+ }
1271
+ get title() {
1272
+ return super.title;
1273
+ }
1274
+ set title(value) {
1275
+ super.title = value;
1276
+ }
1277
+ get visibleLegend() {
1278
+ const trimmedLegend = this.legend?.trim();
1279
+ return trimmedLegend ? trimmedLegend : void 0;
1280
+ }
1281
+ get isDisabled() {
1282
+ return (this.disabled ?? false) || (this.loading ?? false);
983
1283
  }
984
1284
  getContentContainer() {
985
1285
  return this.querySelector("[data-sp-fieldset-native]");
@@ -991,6 +1291,20 @@ var SpectreFieldsetElement = class extends SpectreProjectableElement {
991
1291
  const el = node;
992
1292
  return el.hasAttribute("data-sp-fieldset-native") || el.hasAttribute("data-sp-fieldset-legend");
993
1293
  }
1294
+ willUpdate(changedProperties) {
1295
+ if (changedProperties.has("disabled") && this.disabled == null) {
1296
+ this.disabled = false;
1297
+ }
1298
+ if (changedProperties.has("invalid") && this.invalid == null) {
1299
+ this.invalid = false;
1300
+ }
1301
+ if (changedProperties.has("loading") && this.loading == null) {
1302
+ this.loading = false;
1303
+ }
1304
+ if (changedProperties.has("success") && this.success == null) {
1305
+ this.success = false;
1306
+ }
1307
+ }
994
1308
  focus(options) {
995
1309
  this.getContentContainer()?.focus(options);
996
1310
  }
@@ -998,30 +1312,35 @@ var SpectreFieldsetElement = class extends SpectreProjectableElement {
998
1312
  this.getContentContainer()?.blur();
999
1313
  }
1000
1314
  render() {
1001
- return html`
1002
- <fieldset
1003
- aria-describedby=${ifDefined(this.forwardedAriaDescribedBy)}
1004
- aria-label=${ifDefined(this.forwardedAriaLabel)}
1005
- aria-labelledby=${ifDefined(this.forwardedAriaLabelledBy)}
1006
- data-sp-fieldset-native
1007
- ?disabled=${this.disabled}
1008
- form=${ifDefined(this.form)}
1009
- id=${ifDefined(this.id || void 0)}
1010
- name=${ifDefined(this.name)}
1011
- title=${ifDefined(this.title || void 0)}
1012
- >
1013
- ${this.legend ? html`<legend class='sp-label' data-sp-fieldset-legend>${this.legend}</legend>` : nothing}
1014
- ${this.hasProjectedContent ? this.projectedContent : nothing}
1015
- </fieldset>
1016
- `;
1315
+ return html`<fieldset
1316
+ aria-busy="${this.loading ? "true" : "false"}"
1317
+ aria-describedby="${ifDefined(this.forwardedAriaDescribedBy)}"
1318
+ aria-invalid="${ifDefined(this.invalid ? "true" : void 0)}"
1319
+ aria-label="${ifDefined(this.forwardedAriaLabel)}"
1320
+ aria-labelledby="${ifDefined(this.forwardedAriaLabelledBy)}"
1321
+ data-sp-fieldset-native
1322
+ ?disabled="${this.isDisabled}"
1323
+ form="${ifDefined(this.form || void 0)}"
1324
+ id="${ifDefined(this.id || void 0)}"
1325
+ name="${ifDefined(this.name || void 0)}"
1326
+ title="${ifDefined(this.title || void 0)}"
1327
+ >
1328
+ ${this.visibleLegend ? html`<legend
1329
+ class="${getInputLabelClasses({ disabled: this.isDisabled })}"
1330
+ data-sp-fieldset-legend
1331
+ >${this.visibleLegend}</legend>` : nothing}
1332
+ ${this.hasProjectedContent ? this.projectedContent : nothing}
1333
+ </fieldset>`;
1017
1334
  }
1018
1335
  };
1019
1336
  SpectreFieldsetElement.properties = {
1020
1337
  disabled: { type: Boolean, reflect: true },
1021
1338
  form: { type: String },
1339
+ invalid: { type: Boolean, reflect: true },
1022
1340
  legend: { type: String, reflect: true },
1341
+ loading: { type: Boolean, reflect: true },
1023
1342
  name: { type: String, reflect: true },
1024
- title: { type: String, reflect: true }
1343
+ success: { type: Boolean, reflect: true }
1025
1344
  };
1026
1345
  function defineSpectreFieldset(tagName = "sp-fieldset") {
1027
1346
  const existingElement = customElements.get(tagName);
@@ -1044,6 +1363,6 @@ function defineSpectreComponents() {
1044
1363
  defineSpectreFieldset();
1045
1364
  }
1046
1365
 
1047
- export { SpectreButtonElement, SpectreCheckboxElement, SpectreFieldsetElement, SpectreInputElement, SpectreLabelElement, SpectreRadioElement, SpectreSelectElement, SpectreTextareaElement, defineSpectreButton, defineSpectreCheckbox, defineSpectreComponents, defineSpectreFieldset, defineSpectreInput, defineSpectreLabel, defineSpectreRadio, defineSpectreSelect, defineSpectreTextarea, spectreButtonSizes, spectreButtonTypes, spectreButtonVariants, spectreInputSizes, spectreInputTypes };
1366
+ export { SpectreButtonElement, SpectreCheckboxElement, SpectreFieldsetElement, SpectreInputElement, SpectreLabelElement, SpectreRadioElement, SpectreSelectElement, SpectreTextareaElement, defineSpectreButton, defineSpectreCheckbox, defineSpectreComponents, defineSpectreFieldset, defineSpectreInput, defineSpectreLabel, defineSpectreRadio, defineSpectreSelect, defineSpectreTextarea, spectreInputSizes as spectreButtonSizes, spectreButtonTypes, spectreButtonVariants, spectreInputSizes, spectreInputTypes };
1048
1367
  //# sourceMappingURL=index.js.map
1049
1368
  //# sourceMappingURL=index.js.map