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