@phcdevworks/spectre-components 1.5.0 → 1.6.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 (146) hide show
  1. package/README.md +118 -2
  2. package/dist/alert.cjs +10 -3
  3. package/dist/alert.cjs.map +1 -1
  4. package/dist/alert.d.cts +4 -5
  5. package/dist/alert.d.ts +4 -5
  6. package/dist/alert.js +10 -3
  7. package/dist/alert.js.map +1 -1
  8. package/dist/avatar.cjs +11 -3
  9. package/dist/avatar.cjs.map +1 -1
  10. package/dist/avatar.d.cts +4 -5
  11. package/dist/avatar.d.ts +4 -5
  12. package/dist/avatar.js +11 -3
  13. package/dist/avatar.js.map +1 -1
  14. package/dist/badge.cjs +11 -3
  15. package/dist/badge.cjs.map +1 -1
  16. package/dist/badge.d.cts +4 -5
  17. package/dist/badge.d.ts +4 -5
  18. package/dist/badge.js +11 -3
  19. package/dist/badge.js.map +1 -1
  20. package/dist/{base-BRQ7QAAr.d.cts → base-D0s95V2v.d.cts} +2 -0
  21. package/dist/{base-BRQ7QAAr.d.ts → base-D0s95V2v.d.ts} +2 -0
  22. package/dist/button.cjs +14 -5
  23. package/dist/button.cjs.map +1 -1
  24. package/dist/button.d.cts +4 -5
  25. package/dist/button.d.ts +4 -5
  26. package/dist/button.js +14 -5
  27. package/dist/button.js.map +1 -1
  28. package/dist/card.cjs +11 -3
  29. package/dist/card.cjs.map +1 -1
  30. package/dist/card.d.cts +4 -5
  31. package/dist/card.d.ts +4 -5
  32. package/dist/card.js +11 -3
  33. package/dist/card.js.map +1 -1
  34. package/dist/checkbox.cjs +16 -5
  35. package/dist/checkbox.cjs.map +1 -1
  36. package/dist/checkbox.d.cts +2 -3
  37. package/dist/checkbox.d.ts +2 -3
  38. package/dist/checkbox.js +17 -6
  39. package/dist/checkbox.js.map +1 -1
  40. package/dist/container.cjs +421 -0
  41. package/dist/container.cjs.map +1 -0
  42. package/dist/container.d.cts +37 -0
  43. package/dist/container.d.ts +37 -0
  44. package/dist/container.js +417 -0
  45. package/dist/container.js.map +1 -0
  46. package/dist/fieldset.cjs +16 -7
  47. package/dist/fieldset.cjs.map +1 -1
  48. package/dist/fieldset.d.cts +2 -3
  49. package/dist/fieldset.d.ts +2 -3
  50. package/dist/fieldset.js +18 -9
  51. package/dist/fieldset.js.map +1 -1
  52. package/dist/{form-BumNzIay.d.cts → form-8KZeQRgr.d.cts} +13 -1
  53. package/dist/{form-BumNzIay.d.ts → form-8KZeQRgr.d.ts} +13 -1
  54. package/dist/grid.cjs +437 -0
  55. package/dist/grid.cjs.map +1 -0
  56. package/dist/grid.d.cts +42 -0
  57. package/dist/grid.d.ts +42 -0
  58. package/dist/grid.js +432 -0
  59. package/dist/grid.js.map +1 -0
  60. package/dist/icon-box.cjs +11 -3
  61. package/dist/icon-box.cjs.map +1 -1
  62. package/dist/icon-box.d.cts +4 -5
  63. package/dist/icon-box.d.ts +4 -5
  64. package/dist/icon-box.js +11 -3
  65. package/dist/icon-box.js.map +1 -1
  66. package/dist/index.cjs +362 -66
  67. package/dist/index.cjs.map +1 -1
  68. package/dist/index.d.cts +7 -3
  69. package/dist/index.d.ts +7 -3
  70. package/dist/index.js +350 -68
  71. package/dist/index.js.map +1 -1
  72. package/dist/input.cjs +10 -3
  73. package/dist/input.cjs.map +1 -1
  74. package/dist/input.d.cts +3 -4
  75. package/dist/input.d.ts +3 -4
  76. package/dist/input.js +10 -3
  77. package/dist/input.js.map +1 -1
  78. package/dist/label.cjs +17 -2
  79. package/dist/label.cjs.map +1 -1
  80. package/dist/label.d.cts +9 -3
  81. package/dist/label.d.ts +9 -3
  82. package/dist/label.js +18 -3
  83. package/dist/label.js.map +1 -1
  84. package/dist/pricing-card.cjs +11 -3
  85. package/dist/pricing-card.cjs.map +1 -1
  86. package/dist/pricing-card.d.cts +2 -3
  87. package/dist/pricing-card.d.ts +2 -3
  88. package/dist/pricing-card.js +11 -3
  89. package/dist/pricing-card.js.map +1 -1
  90. package/dist/{projectable-D6IDeKfr.d.ts → projectable-D9YCo9NY.d.ts} +1 -1
  91. package/dist/{projectable-Bx-IVk0w.d.cts → projectable-DLOn6eaW.d.cts} +1 -1
  92. package/dist/radio.cjs +16 -5
  93. package/dist/radio.cjs.map +1 -1
  94. package/dist/radio.d.cts +2 -3
  95. package/dist/radio.d.ts +2 -3
  96. package/dist/radio.js +17 -6
  97. package/dist/radio.js.map +1 -1
  98. package/dist/rating.cjs +19 -5
  99. package/dist/rating.cjs.map +1 -1
  100. package/dist/rating.d.cts +3 -4
  101. package/dist/rating.d.ts +3 -4
  102. package/dist/rating.js +19 -5
  103. package/dist/rating.js.map +1 -1
  104. package/dist/section.cjs +400 -0
  105. package/dist/section.cjs.map +1 -0
  106. package/dist/section.d.cts +25 -0
  107. package/dist/section.d.ts +25 -0
  108. package/dist/section.js +397 -0
  109. package/dist/section.js.map +1 -0
  110. package/dist/select.cjs +14 -5
  111. package/dist/select.cjs.map +1 -1
  112. package/dist/select.d.cts +3 -4
  113. package/dist/select.d.ts +3 -4
  114. package/dist/select.js +15 -6
  115. package/dist/select.js.map +1 -1
  116. package/dist/spinner.cjs +10 -0
  117. package/dist/spinner.cjs.map +1 -1
  118. package/dist/spinner.d.cts +3 -3
  119. package/dist/spinner.d.ts +3 -3
  120. package/dist/spinner.js +10 -0
  121. package/dist/spinner.js.map +1 -1
  122. package/dist/stack.cjs +443 -0
  123. package/dist/stack.cjs.map +1 -0
  124. package/dist/stack.d.cts +48 -0
  125. package/dist/stack.d.ts +48 -0
  126. package/dist/stack.js +437 -0
  127. package/dist/stack.js.map +1 -0
  128. package/dist/tag.cjs +11 -3
  129. package/dist/tag.cjs.map +1 -1
  130. package/dist/tag.d.cts +4 -5
  131. package/dist/tag.d.ts +4 -5
  132. package/dist/tag.js +11 -3
  133. package/dist/tag.js.map +1 -1
  134. package/dist/testimonial.cjs +11 -3
  135. package/dist/testimonial.cjs.map +1 -1
  136. package/dist/testimonial.d.cts +4 -5
  137. package/dist/testimonial.d.ts +4 -5
  138. package/dist/testimonial.js +11 -3
  139. package/dist/testimonial.js.map +1 -1
  140. package/dist/textarea.cjs +14 -5
  141. package/dist/textarea.cjs.map +1 -1
  142. package/dist/textarea.d.cts +2 -3
  143. package/dist/textarea.d.ts +2 -3
  144. package/dist/textarea.js +15 -6
  145. package/dist/textarea.js.map +1 -1
  146. package/package.json +41 -16
package/dist/index.cjs CHANGED
@@ -144,6 +144,34 @@ var spectreAvatarShapes = ["circle", "square"];
144
144
  function isAvatarShape(value) {
145
145
  return spectreAvatarShapes.includes(value);
146
146
  }
147
+ var spectreContainerMaxWidths = ["prose"];
148
+ function isContainerMaxWidth(value) {
149
+ return spectreContainerMaxWidths.includes(
150
+ value
151
+ );
152
+ }
153
+ var spectreGridColumns = [1, 2, 3, 4, 6, 12];
154
+ function isGridColumns(value) {
155
+ return spectreGridColumns.includes(value);
156
+ }
157
+ var spectreGridGaps = ["sm", "md", "lg"];
158
+ function isGridGap(value) {
159
+ return spectreGridGaps.includes(value);
160
+ }
161
+ var spectreStackDirections = ["vertical", "horizontal"];
162
+ function isStackDirection(value) {
163
+ return spectreStackDirections.includes(
164
+ value
165
+ );
166
+ }
167
+ var spectreStackBases = ["sidebar"];
168
+ function isStackBasis(value) {
169
+ return spectreStackBases.includes(value);
170
+ }
171
+ var spectreStackAligns = ["center", "stretch"];
172
+ function isStackAlign(value) {
173
+ return spectreStackAligns.includes(value);
174
+ }
147
175
  function normalizeInt(value, fallback, min = 0) {
148
176
  if (value == null || typeof value !== "number" || !Number.isInteger(value) || value < min) {
149
177
  return fallback;
@@ -400,6 +428,16 @@ var SpectreBaseElement = class extends lit.LitElement {
400
428
  const value = this.ariaDescribedBy?.trim();
401
429
  return value ? value : void 0;
402
430
  }
431
+ // Subclasses that expose `disabled`/`loading` properties get this disabled
432
+ // calculation for free instead of redeclaring it per component.
433
+ get isDisabled() {
434
+ const self = this;
435
+ return (self.disabled ?? false) || (self.loading ?? false);
436
+ }
437
+ // Subclasses get this for free instead of redeclaring it per component.
438
+ get hasForwardedLabel() {
439
+ return Boolean(this.forwardedAriaLabel || this.forwardedAriaLabelledBy);
440
+ }
403
441
  };
404
442
  SpectreBaseElement.properties = {};
405
443
 
@@ -567,9 +605,6 @@ var SpectreButtonElement = class extends SpectreProjectableElement {
567
605
  variant: this.variant
568
606
  });
569
607
  }
570
- get isDisabled() {
571
- return (this.disabled ?? false) || (this.loading ?? false);
572
- }
573
608
  get visibleLabelFallback() {
574
609
  const trimmedLabel = this.label?.trim();
575
610
  return trimmedLabel ? trimmedLabel : void 0;
@@ -585,7 +620,8 @@ var SpectreButtonElement = class extends SpectreProjectableElement {
585
620
  return lit.html`<span
586
621
  class="${spectreUi.getInputLabelClasses({ disabled: this.isDisabled })}"
587
622
  data-sp-button-loading-label
588
- >${this.loadingLabel}</span>`;
623
+ >${this.loadingLabel}</span
624
+ >`;
589
625
  }
590
626
  if (this.hasProjectedContent) {
591
627
  return this.projectedContent;
@@ -593,7 +629,8 @@ var SpectreButtonElement = class extends SpectreProjectableElement {
593
629
  return this.visibleLabelFallback ? lit.html`<span
594
630
  class="${spectreUi.getInputLabelClasses({ disabled: this.isDisabled })}"
595
631
  data-sp-button-label-fallback
596
- >${this.visibleLabelFallback}</span>` : lit.nothing;
632
+ >${this.visibleLabelFallback}</span
633
+ >` : lit.nothing;
597
634
  }
598
635
  render() {
599
636
  return lit.html`<button
@@ -733,9 +770,6 @@ var SpectreInputElement = class extends SpectreBaseElement {
733
770
  state: this.isDisabled ? this.disabled ? "disabled" : "loading" : this.invalid ? "error" : this.success ? "success" : "default"
734
771
  });
735
772
  }
736
- get isDisabled() {
737
- return (this.disabled ?? false) || (this.loading ?? false);
738
- }
739
773
  get nativeInput() {
740
774
  return this.querySelector("[data-sp-input-native]");
741
775
  }
@@ -912,16 +946,15 @@ var SpectreTextareaElement = class extends SpectreBaseElement {
912
946
  }
913
947
  }
914
948
  get textareaClasses() {
915
- return spectreUi.getInputClasses({
949
+ return spectreUi.getTextareaClasses({
916
950
  fullWidth: this.fullWidth ?? false,
917
951
  pill: this.pill ?? false,
918
952
  size: this.size,
919
- state: this.isDisabled ? this.disabled ? "disabled" : "loading" : this.invalid ? "error" : this.success ? "success" : "default"
953
+ disabled: this.disabled ?? false,
954
+ loading: this.loading ?? false,
955
+ state: this.invalid ? "invalid" : this.success ? "success" : "default"
920
956
  });
921
957
  }
922
- get isDisabled() {
923
- return (this.disabled ?? false) || (this.loading ?? false);
924
- }
925
958
  get nativeTextarea() {
926
959
  return this.querySelector("[data-sp-textarea-native]");
927
960
  }
@@ -1107,16 +1140,15 @@ var SpectreSelectElement = class extends SpectreProjectableElement {
1107
1140
  }
1108
1141
  }
1109
1142
  get selectClasses() {
1110
- return spectreUi.getInputClasses({
1143
+ return spectreUi.getSelectClasses({
1111
1144
  fullWidth: this.fullWidth ?? false,
1112
1145
  pill: this.pill ?? false,
1113
1146
  size: this.size,
1114
- state: this.isDisabled ? this.disabled ? "disabled" : "loading" : this.invalid ? "error" : this.success ? "success" : "default"
1147
+ disabled: this.disabled ?? false,
1148
+ loading: this.loading ?? false,
1149
+ state: this.invalid ? "invalid" : this.success ? "success" : "default"
1115
1150
  });
1116
1151
  }
1117
- get isDisabled() {
1118
- return (this.disabled ?? false) || (this.loading ?? false);
1119
- }
1120
1152
  handleInput(event) {
1121
1153
  const select = event.currentTarget;
1122
1154
  this.value = select.value;
@@ -1245,9 +1277,6 @@ var SpectreCheckboxElement = class extends SpectreProjectableElement {
1245
1277
  get nativeInput() {
1246
1278
  return this.querySelector("[data-sp-checkbox-native]");
1247
1279
  }
1248
- get isDisabled() {
1249
- return (this.disabled ?? false) || (this.loading ?? false);
1250
- }
1251
1280
  get visibleLabelFallback() {
1252
1281
  const trimmedLabel = this.label?.trim();
1253
1282
  return trimmedLabel ? trimmedLabel : void 0;
@@ -1270,7 +1299,8 @@ var SpectreCheckboxElement = class extends SpectreProjectableElement {
1270
1299
  const labelContent = this.hasProjectedContent ? this.projectedContent : this.visibleLabelFallback ? lit.html`<span
1271
1300
  class="${spectreUi.getInputLabelClasses({ disabled: this.isDisabled })}"
1272
1301
  data-sp-checkbox-label-fallback
1273
- >${this.visibleLabelFallback}</span>` : lit.nothing;
1302
+ >${this.visibleLabelFallback}</span
1303
+ >` : lit.nothing;
1274
1304
  return lit.html`<label data-sp-checkbox-label>
1275
1305
  <input
1276
1306
  aria-busy="${this.loading ? "true" : "false"}"
@@ -1292,7 +1322,10 @@ var SpectreCheckboxElement = class extends SpectreProjectableElement {
1292
1322
  @change="${this.handleChange}"
1293
1323
  @input="${this.handleInput}"
1294
1324
  />
1295
- <span class="sp-checkbox-indicator" data-sp-checkbox-indicator></span>
1325
+ <span
1326
+ class="${spectreUi.getCheckboxClasses({ checked: this.checked ?? false, disabled: this.isDisabled })}"
1327
+ data-sp-checkbox-indicator
1328
+ ></span>
1296
1329
  ${labelContent}
1297
1330
  </label>`;
1298
1331
  }
@@ -1382,9 +1415,6 @@ var SpectreRadioElement = class extends SpectreProjectableElement {
1382
1415
  get nativeInput() {
1383
1416
  return this.querySelector("[data-sp-radio-native]");
1384
1417
  }
1385
- get isDisabled() {
1386
- return (this.disabled ?? false) || (this.loading ?? false);
1387
- }
1388
1418
  get visibleLabelFallback() {
1389
1419
  const trimmedLabel = this.label?.trim();
1390
1420
  return trimmedLabel ? trimmedLabel : void 0;
@@ -1427,7 +1457,8 @@ var SpectreRadioElement = class extends SpectreProjectableElement {
1427
1457
  const labelContent = this.hasProjectedContent ? this.projectedContent : this.visibleLabelFallback ? lit.html`<span
1428
1458
  class="${spectreUi.getInputLabelClasses({ disabled: this.isDisabled })}"
1429
1459
  data-sp-radio-label-fallback
1430
- >${this.visibleLabelFallback}</span>` : lit.nothing;
1460
+ >${this.visibleLabelFallback}</span
1461
+ >` : lit.nothing;
1431
1462
  return lit.html`<label data-sp-radio-label>
1432
1463
  <input
1433
1464
  aria-busy="${this.loading ? "true" : "false"}"
@@ -1449,7 +1480,10 @@ var SpectreRadioElement = class extends SpectreProjectableElement {
1449
1480
  @change="${this.handleChange}"
1450
1481
  @input="${this.handleInput}"
1451
1482
  />
1452
- <span class="sp-radio-indicator" data-sp-radio-indicator></span>
1483
+ <span
1484
+ class="${spectreUi.getRadioClasses({ checked: this.checked ?? false, disabled: this.isDisabled })}"
1485
+ data-sp-radio-indicator
1486
+ ></span>
1453
1487
  ${labelContent}
1454
1488
  </label>`;
1455
1489
  }
@@ -1478,11 +1512,15 @@ var SpectreLabelElement = class extends SpectreProjectableElement {
1478
1512
  constructor() {
1479
1513
  super(...arguments);
1480
1514
  this.disabled = false;
1515
+ this.required = false;
1481
1516
  }
1482
1517
  willUpdate(changedProperties) {
1483
1518
  if (changedProperties.has("disabled") && this.disabled == null) {
1484
1519
  this.disabled = false;
1485
1520
  }
1521
+ if (changedProperties.has("required") && this.required == null) {
1522
+ this.required = false;
1523
+ }
1486
1524
  }
1487
1525
  get isDisabled() {
1488
1526
  return this.disabled ?? false;
@@ -1520,7 +1558,7 @@ var SpectreLabelElement = class extends SpectreProjectableElement {
1520
1558
  aria-describedby="${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}"
1521
1559
  aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
1522
1560
  aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
1523
- class="${spectreUi.getInputLabelClasses({ disabled: this.isDisabled })}"
1561
+ class="${spectreUi.getLabelClasses({ disabled: this.isDisabled, required: this.required ?? false })}"
1524
1562
  data-sp-label-native
1525
1563
  for="${ifDefined_js.ifDefined(this.htmlFor || void 0)}"
1526
1564
  id="${ifDefined_js.ifDefined(this.id || void 0)}"
@@ -1532,7 +1570,8 @@ var SpectreLabelElement = class extends SpectreProjectableElement {
1532
1570
  };
1533
1571
  SpectreLabelElement.properties = {
1534
1572
  disabled: { type: Boolean, reflect: true },
1535
- htmlFor: { attribute: "for", type: String, reflect: true }
1573
+ htmlFor: { attribute: "for", type: String, reflect: true },
1574
+ required: { type: Boolean, reflect: true }
1536
1575
  };
1537
1576
  function defineSpectreLabel(tagName = "sp-label") {
1538
1577
  const existingElement = customElements.get(tagName);
@@ -1584,9 +1623,6 @@ var SpectreFieldsetElement = class extends SpectreProjectableElement {
1584
1623
  const trimmedLegend = this.legend?.trim();
1585
1624
  return trimmedLegend ? trimmedLegend : void 0;
1586
1625
  }
1587
- get isDisabled() {
1588
- return (this.disabled ?? false) || (this.loading ?? false);
1589
- }
1590
1626
  getContentContainer() {
1591
1627
  return this.querySelector("[data-sp-fieldset-native]");
1592
1628
  }
@@ -1618,6 +1654,10 @@ var SpectreFieldsetElement = class extends SpectreProjectableElement {
1618
1654
  this.getContentContainer()?.blur();
1619
1655
  }
1620
1656
  render() {
1657
+ const legendClasses = spectreUi.getFieldsetLegendClasses();
1658
+ const legendContent = this.visibleLegend ? lit.html`<legend class="${legendClasses}" data-sp-fieldset-legend>
1659
+ ${this.visibleLegend}
1660
+ </legend>` : lit.nothing;
1621
1661
  return lit.html`<fieldset
1622
1662
  aria-busy="${this.loading ? "true" : "false"}"
1623
1663
  aria-describedby="${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}"
@@ -1626,6 +1666,7 @@ var SpectreFieldsetElement = class extends SpectreProjectableElement {
1626
1666
  aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
1627
1667
  autocapitalize="${ifDefined_js.ifDefined(this.autocapitalize || void 0)}"
1628
1668
  ?autofocus="${this.autofocus}"
1669
+ class="${spectreUi.getFieldsetClasses({ disabled: this.isDisabled })}"
1629
1670
  data-sp-fieldset-native
1630
1671
  ?disabled="${this.isDisabled}"
1631
1672
  form="${ifDefined_js.ifDefined(this.form || void 0)}"
@@ -1634,10 +1675,7 @@ var SpectreFieldsetElement = class extends SpectreProjectableElement {
1634
1675
  spellcheck="${ifDefined_js.ifDefined(this.getAttribute("spellcheck") ?? void 0)}"
1635
1676
  title="${ifDefined_js.ifDefined(this.title || void 0)}"
1636
1677
  >
1637
- ${this.visibleLegend ? lit.html`<legend
1638
- class="${spectreUi.getInputLabelClasses({ disabled: this.isDisabled })}"
1639
- data-sp-fieldset-legend
1640
- >${this.visibleLegend}</legend>` : lit.nothing}
1678
+ ${legendContent}
1641
1679
  ${this.hasProjectedContent ? this.projectedContent : lit.nothing}
1642
1680
  </fieldset>`;
1643
1681
  }
@@ -1716,9 +1754,6 @@ var SpectreBadgeElement = class extends SpectreProjectableElement {
1716
1754
  variant: this.variant
1717
1755
  });
1718
1756
  }
1719
- get isDisabled() {
1720
- return (this.disabled ?? false) || (this.loading ?? false);
1721
- }
1722
1757
  render() {
1723
1758
  return lit.html`<span
1724
1759
  aria-busy="${this.loading ? "true" : "false"}"
@@ -1728,6 +1763,7 @@ var SpectreBadgeElement = class extends SpectreProjectableElement {
1728
1763
  class="${this.badgeClasses}"
1729
1764
  data-sp-badge-native
1730
1765
  id="${ifDefined_js.ifDefined(this.id || void 0)}"
1766
+ role="${ifDefined_js.ifDefined(this.hasForwardedLabel ? "group" : void 0)}"
1731
1767
  title="${ifDefined_js.ifDefined(this.title || void 0)}"
1732
1768
  >
1733
1769
  ${this.hasProjectedContent ? this.projectedContent : lit.nothing}
@@ -1811,9 +1847,6 @@ var SpectreCardElement = class extends SpectreProjectableElement {
1811
1847
  variant: this.variant
1812
1848
  });
1813
1849
  }
1814
- get isDisabled() {
1815
- return (this.disabled ?? false) || (this.loading ?? false);
1816
- }
1817
1850
  render() {
1818
1851
  return lit.html`<div
1819
1852
  aria-busy="${this.loading ? "true" : "false"}"
@@ -1823,6 +1856,7 @@ var SpectreCardElement = class extends SpectreProjectableElement {
1823
1856
  class="${this.cardClasses}"
1824
1857
  data-sp-card-native
1825
1858
  id="${ifDefined_js.ifDefined(this.id || void 0)}"
1859
+ role="${ifDefined_js.ifDefined(this.hasForwardedLabel ? "group" : void 0)}"
1826
1860
  title="${ifDefined_js.ifDefined(this.title || void 0)}"
1827
1861
  >
1828
1862
  ${this.hasProjectedContent ? this.projectedContent : lit.nothing}
@@ -1912,9 +1946,6 @@ var SpectreIconBoxElement = class extends SpectreProjectableElement {
1912
1946
  variant: this.variant
1913
1947
  });
1914
1948
  }
1915
- get isDisabled() {
1916
- return (this.disabled ?? false) || (this.loading ?? false);
1917
- }
1918
1949
  render() {
1919
1950
  return lit.html`<div
1920
1951
  aria-busy="${this.loading ? "true" : "false"}"
@@ -1924,6 +1955,7 @@ var SpectreIconBoxElement = class extends SpectreProjectableElement {
1924
1955
  class="${this.iconBoxClasses}"
1925
1956
  data-sp-icon-box-native
1926
1957
  id="${ifDefined_js.ifDefined(this.id || void 0)}"
1958
+ role="${ifDefined_js.ifDefined(this.hasForwardedLabel ? "group" : void 0)}"
1927
1959
  title="${ifDefined_js.ifDefined(this.title || void 0)}"
1928
1960
  >
1929
1961
  ${this.hasProjectedContent ? this.projectedContent : lit.nothing}
@@ -1994,9 +2026,6 @@ var SpectreRatingElement = class extends SpectreBaseElement {
1994
2026
  size: this.size
1995
2027
  });
1996
2028
  }
1997
- get isDisabled() {
1998
- return (this.disabled ?? false) || (this.loading ?? false);
1999
- }
2000
2029
  get effectiveMax() {
2001
2030
  return this.max ?? 5;
2002
2031
  }
@@ -2011,7 +2040,11 @@ var SpectreRatingElement = class extends SpectreBaseElement {
2011
2040
  renderStars() {
2012
2041
  const stars = [];
2013
2042
  for (let i = 1; i <= this.effectiveMax; i++) {
2014
- stars.push(lit.html`<span class="${spectreUi.getRatingStarClasses(i <= this.effectiveValue)}"></span>`);
2043
+ stars.push(
2044
+ lit.html`<span
2045
+ class="${spectreUi.getRatingStarClasses(i <= this.effectiveValue)}"
2046
+ ></span>`
2047
+ );
2015
2048
  }
2016
2049
  return stars;
2017
2050
  }
@@ -2029,7 +2062,10 @@ var SpectreRatingElement = class extends SpectreBaseElement {
2029
2062
  title="${ifDefined_js.ifDefined(this.title || void 0)}"
2030
2063
  >
2031
2064
  <div class="${spectreUi.getRatingStarsClasses()}">${this.renderStars()}</div>
2032
- ${trimmedLabel ? lit.html`<span class="${spectreUi.getRatingTextClasses({ disabled: this.isDisabled })}">${trimmedLabel}</span>` : lit.nothing}
2065
+ ${trimmedLabel ? lit.html`<span
2066
+ class="${spectreUi.getRatingTextClasses({ disabled: this.isDisabled })}"
2067
+ >${trimmedLabel}</span
2068
+ >` : lit.nothing}
2033
2069
  </div>`;
2034
2070
  }
2035
2071
  };
@@ -2106,9 +2142,6 @@ var SpectreTestimonialElement = class extends SpectreProjectableElement {
2106
2142
  variant: this.variant
2107
2143
  });
2108
2144
  }
2109
- get isDisabled() {
2110
- return (this.disabled ?? false) || (this.loading ?? false);
2111
- }
2112
2145
  render() {
2113
2146
  return lit.html`<div
2114
2147
  aria-busy="${this.loading ? "true" : "false"}"
@@ -2118,6 +2151,7 @@ var SpectreTestimonialElement = class extends SpectreProjectableElement {
2118
2151
  class="${this.testimonialClasses}"
2119
2152
  data-sp-testimonial-native
2120
2153
  id="${ifDefined_js.ifDefined(this.id || void 0)}"
2154
+ role="${ifDefined_js.ifDefined(this.hasForwardedLabel ? "group" : void 0)}"
2121
2155
  title="${ifDefined_js.ifDefined(this.title || void 0)}"
2122
2156
  >
2123
2157
  ${this.hasProjectedContent ? this.projectedContent : lit.nothing}
@@ -2201,9 +2235,6 @@ var SpectreAlertElement = class extends SpectreProjectableElement {
2201
2235
  variant: this.variant
2202
2236
  });
2203
2237
  }
2204
- get isDisabled() {
2205
- return (this.disabled ?? false) || (this.loading ?? false);
2206
- }
2207
2238
  render() {
2208
2239
  return lit.html`<div
2209
2240
  aria-busy="${this.loading ? "true" : "false"}"
@@ -2303,9 +2334,6 @@ var SpectreAvatarElement = class extends SpectreProjectableElement {
2303
2334
  size: this.size
2304
2335
  });
2305
2336
  }
2306
- get isDisabled() {
2307
- return (this.disabled ?? false) || (this.loading ?? false);
2308
- }
2309
2337
  render() {
2310
2338
  return lit.html`<div
2311
2339
  aria-busy="${this.loading ? "true" : "false"}"
@@ -2315,6 +2343,7 @@ var SpectreAvatarElement = class extends SpectreProjectableElement {
2315
2343
  class="${this.avatarClasses}"
2316
2344
  data-sp-avatar-native
2317
2345
  id="${ifDefined_js.ifDefined(this.id || void 0)}"
2346
+ role="${ifDefined_js.ifDefined(this.hasForwardedLabel ? "group" : void 0)}"
2318
2347
  title="${ifDefined_js.ifDefined(this.title || void 0)}"
2319
2348
  >
2320
2349
  ${this.hasProjectedContent ? this.projectedContent : lit.nothing}
@@ -2482,9 +2511,6 @@ var SpectreTagElement = class extends SpectreProjectableElement {
2482
2511
  variant: this.variant
2483
2512
  });
2484
2513
  }
2485
- get isDisabled() {
2486
- return (this.disabled ?? false) || (this.loading ?? false);
2487
- }
2488
2514
  render() {
2489
2515
  return lit.html`<span
2490
2516
  aria-busy="${this.loading ? "true" : "false"}"
@@ -2494,6 +2520,7 @@ var SpectreTagElement = class extends SpectreProjectableElement {
2494
2520
  class="${this.tagClasses}"
2495
2521
  data-sp-tag-native
2496
2522
  id="${ifDefined_js.ifDefined(this.id || void 0)}"
2523
+ role="${ifDefined_js.ifDefined(this.hasForwardedLabel ? "group" : void 0)}"
2497
2524
  title="${ifDefined_js.ifDefined(this.title || void 0)}"
2498
2525
  >
2499
2526
  ${this.hasProjectedContent ? this.projectedContent : lit.nothing}
@@ -2575,9 +2602,6 @@ var SpectrePricingCardElement = class extends SpectreProjectableElement {
2575
2602
  loading: this.loading ?? false
2576
2603
  });
2577
2604
  }
2578
- get isDisabled() {
2579
- return (this.disabled ?? false) || (this.loading ?? false);
2580
- }
2581
2605
  render() {
2582
2606
  return lit.html`<div
2583
2607
  aria-busy="${this.loading ? "true" : "false"}"
@@ -2587,6 +2611,7 @@ var SpectrePricingCardElement = class extends SpectreProjectableElement {
2587
2611
  class="${this.pricingCardClasses}"
2588
2612
  data-sp-pricing-card-native
2589
2613
  id="${ifDefined_js.ifDefined(this.id || void 0)}"
2614
+ role="${ifDefined_js.ifDefined(this.hasForwardedLabel ? "group" : void 0)}"
2590
2615
  title="${ifDefined_js.ifDefined(this.title || void 0)}"
2591
2616
  >
2592
2617
  ${this.hasProjectedContent ? this.projectedContent : lit.nothing}
@@ -2608,6 +2633,259 @@ function defineSpectrePricingCard(tagName = "sp-pricing-card") {
2608
2633
  customElements.define(tagName, SpectrePricingCardElement);
2609
2634
  return SpectrePricingCardElement;
2610
2635
  }
2636
+ var SpectreContainerElement = class extends SpectreProjectableElement {
2637
+ constructor() {
2638
+ super(...arguments);
2639
+ this.maxWidth = void 0;
2640
+ }
2641
+ get id() {
2642
+ return super.id;
2643
+ }
2644
+ set id(value) {
2645
+ super.id = value;
2646
+ }
2647
+ get title() {
2648
+ return super.title;
2649
+ }
2650
+ set title(value) {
2651
+ super.title = value;
2652
+ }
2653
+ getContentContainer() {
2654
+ return this.querySelector("[data-sp-container-native]");
2655
+ }
2656
+ isInternalNode(node) {
2657
+ if (node.nodeType !== Node.ELEMENT_NODE) {
2658
+ return false;
2659
+ }
2660
+ const el = node;
2661
+ return el.hasAttribute("data-sp-container-native");
2662
+ }
2663
+ willUpdate(changedProperties) {
2664
+ if (changedProperties.has("maxWidth") && this.maxWidth != null && !isContainerMaxWidth(this.maxWidth)) {
2665
+ this.maxWidth = void 0;
2666
+ }
2667
+ }
2668
+ get containerClasses() {
2669
+ return spectreUi.getContainerClasses(
2670
+ this.maxWidth != null ? { maxWidth: this.maxWidth } : {}
2671
+ );
2672
+ }
2673
+ render() {
2674
+ return lit.html`<div
2675
+ aria-describedby="${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}"
2676
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
2677
+ aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
2678
+ class="${this.containerClasses}"
2679
+ data-sp-container-native
2680
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
2681
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
2682
+ >
2683
+ ${this.hasProjectedContent ? this.projectedContent : lit.nothing}
2684
+ </div>`;
2685
+ }
2686
+ };
2687
+ SpectreContainerElement.properties = {
2688
+ maxWidth: { attribute: "max-width", type: String, reflect: true }
2689
+ };
2690
+ function defineSpectreContainer(tagName = "sp-container") {
2691
+ const existingElement = customElements.get(tagName);
2692
+ if (existingElement) {
2693
+ return existingElement;
2694
+ }
2695
+ customElements.define(tagName, SpectreContainerElement);
2696
+ return SpectreContainerElement;
2697
+ }
2698
+ var SpectreGridElement = class extends SpectreProjectableElement {
2699
+ constructor() {
2700
+ super(...arguments);
2701
+ this.columns = 1;
2702
+ this.gap = "md";
2703
+ }
2704
+ get id() {
2705
+ return super.id;
2706
+ }
2707
+ set id(value) {
2708
+ super.id = value;
2709
+ }
2710
+ get title() {
2711
+ return super.title;
2712
+ }
2713
+ set title(value) {
2714
+ super.title = value;
2715
+ }
2716
+ getContentContainer() {
2717
+ return this.querySelector("[data-sp-grid-native]");
2718
+ }
2719
+ isInternalNode(node) {
2720
+ if (node.nodeType !== Node.ELEMENT_NODE) {
2721
+ return false;
2722
+ }
2723
+ const el = node;
2724
+ return el.hasAttribute("data-sp-grid-native");
2725
+ }
2726
+ willUpdate(changedProperties) {
2727
+ if (changedProperties.has("columns")) {
2728
+ const normalized = normalizeInt(this.columns, void 0, 1);
2729
+ this.columns = normalized != null && isGridColumns(normalized) ? normalized : 1;
2730
+ }
2731
+ if (changedProperties.has("gap") && (this.gap == null || !isGridGap(this.gap))) {
2732
+ this.gap = "md";
2733
+ }
2734
+ }
2735
+ get gridClasses() {
2736
+ return spectreUi.getGridClasses({
2737
+ columns: this.columns,
2738
+ gap: this.gap
2739
+ });
2740
+ }
2741
+ render() {
2742
+ return lit.html`<div
2743
+ aria-describedby="${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}"
2744
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
2745
+ aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
2746
+ class="${this.gridClasses}"
2747
+ data-sp-grid-native
2748
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
2749
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
2750
+ >
2751
+ ${this.hasProjectedContent ? this.projectedContent : lit.nothing}
2752
+ </div>`;
2753
+ }
2754
+ };
2755
+ SpectreGridElement.properties = {
2756
+ columns: { type: Number, reflect: true },
2757
+ gap: { type: String, reflect: true }
2758
+ };
2759
+ function defineSpectreGrid(tagName = "sp-grid") {
2760
+ const existingElement = customElements.get(tagName);
2761
+ if (existingElement) {
2762
+ return existingElement;
2763
+ }
2764
+ customElements.define(tagName, SpectreGridElement);
2765
+ return SpectreGridElement;
2766
+ }
2767
+ var SpectreSectionElement = class extends SpectreProjectableElement {
2768
+ get id() {
2769
+ return super.id;
2770
+ }
2771
+ set id(value) {
2772
+ super.id = value;
2773
+ }
2774
+ get title() {
2775
+ return super.title;
2776
+ }
2777
+ set title(value) {
2778
+ super.title = value;
2779
+ }
2780
+ getContentContainer() {
2781
+ return this.querySelector("[data-sp-section-native]");
2782
+ }
2783
+ isInternalNode(node) {
2784
+ if (node.nodeType !== Node.ELEMENT_NODE) {
2785
+ return false;
2786
+ }
2787
+ const el = node;
2788
+ return el.hasAttribute("data-sp-section-native");
2789
+ }
2790
+ get sectionClasses() {
2791
+ return spectreUi.getSectionClasses({});
2792
+ }
2793
+ render() {
2794
+ return lit.html`<section
2795
+ aria-describedby="${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}"
2796
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
2797
+ aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
2798
+ class="${this.sectionClasses}"
2799
+ data-sp-section-native
2800
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
2801
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
2802
+ >
2803
+ ${this.hasProjectedContent ? this.projectedContent : lit.nothing}
2804
+ </section>`;
2805
+ }
2806
+ };
2807
+ function defineSpectreSection(tagName = "sp-section") {
2808
+ const existingElement = customElements.get(tagName);
2809
+ if (existingElement) {
2810
+ return existingElement;
2811
+ }
2812
+ customElements.define(tagName, SpectreSectionElement);
2813
+ return SpectreSectionElement;
2814
+ }
2815
+ var SpectreStackElement = class extends SpectreProjectableElement {
2816
+ constructor() {
2817
+ super(...arguments);
2818
+ this.align = "center";
2819
+ this.basis = void 0;
2820
+ this.direction = "vertical";
2821
+ }
2822
+ get id() {
2823
+ return super.id;
2824
+ }
2825
+ set id(value) {
2826
+ super.id = value;
2827
+ }
2828
+ get title() {
2829
+ return super.title;
2830
+ }
2831
+ set title(value) {
2832
+ super.title = value;
2833
+ }
2834
+ getContentContainer() {
2835
+ return this.querySelector("[data-sp-stack-native]");
2836
+ }
2837
+ isInternalNode(node) {
2838
+ if (node.nodeType !== Node.ELEMENT_NODE) {
2839
+ return false;
2840
+ }
2841
+ const el = node;
2842
+ return el.hasAttribute("data-sp-stack-native");
2843
+ }
2844
+ willUpdate(changedProperties) {
2845
+ if (changedProperties.has("direction") && (this.direction == null || !isStackDirection(this.direction))) {
2846
+ this.direction = "vertical";
2847
+ }
2848
+ if (changedProperties.has("basis") && this.basis != null && !isStackBasis(this.basis)) {
2849
+ this.basis = void 0;
2850
+ }
2851
+ if (changedProperties.has("align") && (this.align == null || !isStackAlign(this.align))) {
2852
+ this.align = "center";
2853
+ }
2854
+ }
2855
+ get stackClasses() {
2856
+ return spectreUi.getStackClasses({
2857
+ align: this.align,
2858
+ direction: this.direction,
2859
+ ...this.basis != null ? { basis: this.basis } : {}
2860
+ });
2861
+ }
2862
+ render() {
2863
+ return lit.html`<div
2864
+ aria-describedby="${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}"
2865
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
2866
+ aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
2867
+ class="${this.stackClasses}"
2868
+ data-sp-stack-native
2869
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
2870
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
2871
+ >
2872
+ ${this.hasProjectedContent ? this.projectedContent : lit.nothing}
2873
+ </div>`;
2874
+ }
2875
+ };
2876
+ SpectreStackElement.properties = {
2877
+ align: { type: String, reflect: true },
2878
+ basis: { type: String, reflect: true },
2879
+ direction: { type: String, reflect: true }
2880
+ };
2881
+ function defineSpectreStack(tagName = "sp-stack") {
2882
+ const existingElement = customElements.get(tagName);
2883
+ if (existingElement) {
2884
+ return existingElement;
2885
+ }
2886
+ customElements.define(tagName, SpectreStackElement);
2887
+ return SpectreStackElement;
2888
+ }
2611
2889
 
2612
2890
  // src/index.ts
2613
2891
  function defineSpectreComponents() {
@@ -2629,6 +2907,10 @@ function defineSpectreComponents() {
2629
2907
  defineSpectreSpinner();
2630
2908
  defineSpectreTag();
2631
2909
  defineSpectrePricingCard();
2910
+ defineSpectreContainer();
2911
+ defineSpectreGrid();
2912
+ defineSpectreSection();
2913
+ defineSpectreStack();
2632
2914
  }
2633
2915
 
2634
2916
  exports.SpectreAlertElement = SpectreAlertElement;
@@ -2637,15 +2919,19 @@ exports.SpectreBadgeElement = SpectreBadgeElement;
2637
2919
  exports.SpectreButtonElement = SpectreButtonElement;
2638
2920
  exports.SpectreCardElement = SpectreCardElement;
2639
2921
  exports.SpectreCheckboxElement = SpectreCheckboxElement;
2922
+ exports.SpectreContainerElement = SpectreContainerElement;
2640
2923
  exports.SpectreFieldsetElement = SpectreFieldsetElement;
2924
+ exports.SpectreGridElement = SpectreGridElement;
2641
2925
  exports.SpectreIconBoxElement = SpectreIconBoxElement;
2642
2926
  exports.SpectreInputElement = SpectreInputElement;
2643
2927
  exports.SpectreLabelElement = SpectreLabelElement;
2644
2928
  exports.SpectrePricingCardElement = SpectrePricingCardElement;
2645
2929
  exports.SpectreRadioElement = SpectreRadioElement;
2646
2930
  exports.SpectreRatingElement = SpectreRatingElement;
2931
+ exports.SpectreSectionElement = SpectreSectionElement;
2647
2932
  exports.SpectreSelectElement = SpectreSelectElement;
2648
2933
  exports.SpectreSpinnerElement = SpectreSpinnerElement;
2934
+ exports.SpectreStackElement = SpectreStackElement;
2649
2935
  exports.SpectreTagElement = SpectreTagElement;
2650
2936
  exports.SpectreTestimonialElement = SpectreTestimonialElement;
2651
2937
  exports.SpectreTextareaElement = SpectreTextareaElement;
@@ -2656,15 +2942,19 @@ exports.defineSpectreButton = defineSpectreButton;
2656
2942
  exports.defineSpectreCard = defineSpectreCard;
2657
2943
  exports.defineSpectreCheckbox = defineSpectreCheckbox;
2658
2944
  exports.defineSpectreComponents = defineSpectreComponents;
2945
+ exports.defineSpectreContainer = defineSpectreContainer;
2659
2946
  exports.defineSpectreFieldset = defineSpectreFieldset;
2947
+ exports.defineSpectreGrid = defineSpectreGrid;
2660
2948
  exports.defineSpectreIconBox = defineSpectreIconBox;
2661
2949
  exports.defineSpectreInput = defineSpectreInput;
2662
2950
  exports.defineSpectreLabel = defineSpectreLabel;
2663
2951
  exports.defineSpectrePricingCard = defineSpectrePricingCard;
2664
2952
  exports.defineSpectreRadio = defineSpectreRadio;
2665
2953
  exports.defineSpectreRating = defineSpectreRating;
2954
+ exports.defineSpectreSection = defineSpectreSection;
2666
2955
  exports.defineSpectreSelect = defineSpectreSelect;
2667
2956
  exports.defineSpectreSpinner = defineSpectreSpinner;
2957
+ exports.defineSpectreStack = defineSpectreStack;
2668
2958
  exports.defineSpectreTag = defineSpectreTag;
2669
2959
  exports.defineSpectreTestimonial = defineSpectreTestimonial;
2670
2960
  exports.defineSpectreTextarea = defineSpectreTextarea;
@@ -2678,6 +2968,9 @@ exports.spectreButtonSizes = spectreInputSizes;
2678
2968
  exports.spectreButtonTypes = spectreButtonTypes;
2679
2969
  exports.spectreButtonVariants = spectreButtonVariants;
2680
2970
  exports.spectreCardVariants = spectreCardVariants;
2971
+ exports.spectreContainerMaxWidths = spectreContainerMaxWidths;
2972
+ exports.spectreGridColumns = spectreGridColumns;
2973
+ exports.spectreGridGaps = spectreGridGaps;
2681
2974
  exports.spectreIconBoxSizes = spectreInputSizes;
2682
2975
  exports.spectreIconBoxVariants = spectreIconBoxVariants;
2683
2976
  exports.spectreInputSizes = spectreInputSizes;
@@ -2685,6 +2978,9 @@ exports.spectreInputTypes = spectreInputTypes;
2685
2978
  exports.spectreRatingSizes = spectreInputSizes;
2686
2979
  exports.spectreSpinnerSizes = spectreInputSizes;
2687
2980
  exports.spectreSpinnerVariants = spectreSpinnerVariants;
2981
+ exports.spectreStackAligns = spectreStackAligns;
2982
+ exports.spectreStackBases = spectreStackBases;
2983
+ exports.spectreStackDirections = spectreStackDirections;
2688
2984
  exports.spectreTagSizes = spectreInputSizes;
2689
2985
  exports.spectreTagVariants = spectreTagVariants;
2690
2986
  exports.spectreTestimonialVariants = spectreTestimonialVariants;