@phcdevworks/spectre-components 1.20.0 → 1.21.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 (350) hide show
  1. package/README.md +672 -49
  2. package/dist/accordion-item.cjs +540 -0
  3. package/dist/accordion-item.cjs.map +1 -0
  4. package/dist/accordion-item.d.cts +59 -0
  5. package/dist/accordion-item.d.ts +59 -0
  6. package/dist/accordion-item.js +537 -0
  7. package/dist/accordion-item.js.map +1 -0
  8. package/dist/accordion.cjs +468 -0
  9. package/dist/accordion.cjs.map +1 -0
  10. package/dist/accordion.d.cts +38 -0
  11. package/dist/accordion.d.ts +38 -0
  12. package/dist/accordion.js +465 -0
  13. package/dist/accordion.js.map +1 -0
  14. package/dist/alert.cjs +166 -65
  15. package/dist/alert.cjs.map +1 -1
  16. package/dist/alert.d.cts +41 -8
  17. package/dist/alert.d.ts +41 -8
  18. package/dist/alert.js +168 -67
  19. package/dist/alert.js.map +1 -1
  20. package/dist/avatar.cjs +27 -1
  21. package/dist/avatar.cjs.map +1 -1
  22. package/dist/avatar.d.cts +19 -3
  23. package/dist/avatar.d.ts +19 -3
  24. package/dist/avatar.js +27 -1
  25. package/dist/avatar.js.map +1 -1
  26. package/dist/badge.cjs +35 -2
  27. package/dist/badge.cjs.map +1 -1
  28. package/dist/badge.d.cts +31 -3
  29. package/dist/badge.d.ts +31 -3
  30. package/dist/badge.js +35 -2
  31. package/dist/badge.js.map +1 -1
  32. package/dist/breadcrumb.cjs +464 -0
  33. package/dist/breadcrumb.cjs.map +1 -0
  34. package/dist/breadcrumb.d.cts +32 -0
  35. package/dist/breadcrumb.d.ts +32 -0
  36. package/dist/breadcrumb.js +461 -0
  37. package/dist/breadcrumb.js.map +1 -0
  38. package/dist/button.cjs +32 -2
  39. package/dist/button.cjs.map +1 -1
  40. package/dist/button.d.cts +19 -3
  41. package/dist/button.d.ts +19 -3
  42. package/dist/button.js +32 -2
  43. package/dist/button.js.map +1 -1
  44. package/dist/card-bleed.cjs +458 -0
  45. package/dist/card-bleed.cjs.map +1 -0
  46. package/dist/card-bleed.d.cts +37 -0
  47. package/dist/card-bleed.d.ts +37 -0
  48. package/dist/card-bleed.js +455 -0
  49. package/dist/card-bleed.js.map +1 -0
  50. package/dist/card.cjs +27 -1
  51. package/dist/card.cjs.map +1 -1
  52. package/dist/card.d.cts +19 -3
  53. package/dist/card.d.ts +19 -3
  54. package/dist/card.js +27 -1
  55. package/dist/card.js.map +1 -1
  56. package/dist/carousel.cjs +655 -0
  57. package/dist/carousel.cjs.map +1 -0
  58. package/dist/carousel.d.cts +79 -0
  59. package/dist/carousel.d.ts +79 -0
  60. package/dist/carousel.js +652 -0
  61. package/dist/carousel.js.map +1 -0
  62. package/dist/checkbox.cjs +3 -1
  63. package/dist/checkbox.cjs.map +1 -1
  64. package/dist/checkbox.js +3 -1
  65. package/dist/checkbox.js.map +1 -1
  66. package/dist/choice-card.cjs +524 -0
  67. package/dist/choice-card.cjs.map +1 -0
  68. package/dist/choice-card.d.cts +81 -0
  69. package/dist/choice-card.d.ts +81 -0
  70. package/dist/choice-card.js +521 -0
  71. package/dist/choice-card.js.map +1 -0
  72. package/dist/container.cjs +23 -6
  73. package/dist/container.cjs.map +1 -1
  74. package/dist/container.d.cts +9 -3
  75. package/dist/container.d.ts +9 -3
  76. package/dist/container.js +23 -7
  77. package/dist/container.js.map +1 -1
  78. package/dist/datepicker.cjs +580 -0
  79. package/dist/datepicker.cjs.map +1 -0
  80. package/dist/datepicker.d.cts +78 -0
  81. package/dist/datepicker.d.ts +78 -0
  82. package/dist/datepicker.js +577 -0
  83. package/dist/datepicker.js.map +1 -0
  84. package/dist/dom-CX9bgbcQ.d.cts +3 -0
  85. package/dist/dom-CX9bgbcQ.d.ts +3 -0
  86. package/dist/dropdown.cjs +24 -0
  87. package/dist/dropdown.cjs.map +1 -1
  88. package/dist/dropdown.d.cts +3 -2
  89. package/dist/dropdown.d.ts +3 -2
  90. package/dist/dropdown.js +25 -1
  91. package/dist/dropdown.js.map +1 -1
  92. package/dist/external-auth-button.cjs +494 -0
  93. package/dist/external-auth-button.cjs.map +1 -0
  94. package/dist/external-auth-button.d.cts +71 -0
  95. package/dist/external-auth-button.d.ts +71 -0
  96. package/dist/external-auth-button.js +491 -0
  97. package/dist/external-auth-button.js.map +1 -0
  98. package/dist/fieldset.cjs +3 -1
  99. package/dist/fieldset.cjs.map +1 -1
  100. package/dist/fieldset.js +3 -1
  101. package/dist/fieldset.js.map +1 -1
  102. package/dist/file-input.cjs +371 -0
  103. package/dist/file-input.cjs.map +1 -0
  104. package/dist/file-input.d.cts +96 -0
  105. package/dist/file-input.d.ts +96 -0
  106. package/dist/file-input.js +367 -0
  107. package/dist/file-input.js.map +1 -0
  108. package/dist/footer-chip.cjs +22 -2
  109. package/dist/footer-chip.cjs.map +1 -1
  110. package/dist/footer-chip.d.cts +12 -1
  111. package/dist/footer-chip.d.ts +12 -1
  112. package/dist/footer-chip.js +22 -2
  113. package/dist/footer-chip.js.map +1 -1
  114. package/dist/footer-link.cjs +19 -1
  115. package/dist/footer-link.cjs.map +1 -1
  116. package/dist/footer-link.d.cts +12 -1
  117. package/dist/footer-link.d.ts +12 -1
  118. package/dist/footer-link.js +19 -1
  119. package/dist/footer-link.js.map +1 -1
  120. package/dist/footer.cjs +30 -1
  121. package/dist/footer.cjs.map +1 -1
  122. package/dist/footer.d.cts +2 -1
  123. package/dist/footer.d.ts +2 -1
  124. package/dist/footer.js +31 -2
  125. package/dist/footer.js.map +1 -1
  126. package/dist/{form-DpPtizpY.d.cts → form-CVO7mlDa.d.cts} +38 -9
  127. package/dist/{form-DpPtizpY.d.ts → form-CVO7mlDa.d.ts} +38 -9
  128. package/dist/grid.cjs +35 -1
  129. package/dist/grid.cjs.map +1 -1
  130. package/dist/grid.d.cts +9 -3
  131. package/dist/grid.d.ts +9 -3
  132. package/dist/grid.js +35 -2
  133. package/dist/grid.js.map +1 -1
  134. package/dist/icon-box.cjs +27 -1
  135. package/dist/icon-box.cjs.map +1 -1
  136. package/dist/icon-box.d.cts +19 -3
  137. package/dist/icon-box.d.ts +19 -3
  138. package/dist/icon-box.js +27 -1
  139. package/dist/icon-box.js.map +1 -1
  140. package/dist/index.cjs +3654 -107
  141. package/dist/index.cjs.map +1 -1
  142. package/dist/index.d.cts +26 -1
  143. package/dist/index.d.ts +26 -1
  144. package/dist/index.js +3594 -110
  145. package/dist/index.js.map +1 -1
  146. package/dist/input-group.cjs +471 -0
  147. package/dist/input-group.cjs.map +1 -0
  148. package/dist/input-group.d.cts +31 -0
  149. package/dist/input-group.d.ts +31 -0
  150. package/dist/input-group.js +468 -0
  151. package/dist/input-group.js.map +1 -0
  152. package/dist/input.cjs +96 -4
  153. package/dist/input.cjs.map +1 -1
  154. package/dist/input.d.cts +45 -6
  155. package/dist/input.d.ts +45 -6
  156. package/dist/input.js +98 -6
  157. package/dist/input.js.map +1 -1
  158. package/dist/label.cjs +3 -1
  159. package/dist/label.cjs.map +1 -1
  160. package/dist/label.js +3 -1
  161. package/dist/label.js.map +1 -1
  162. package/dist/list-group-item.cjs +367 -0
  163. package/dist/list-group-item.cjs.map +1 -0
  164. package/dist/list-group-item.d.cts +73 -0
  165. package/dist/list-group-item.d.ts +73 -0
  166. package/dist/list-group-item.js +364 -0
  167. package/dist/list-group-item.js.map +1 -0
  168. package/dist/list-group.cjs +610 -0
  169. package/dist/list-group.cjs.map +1 -0
  170. package/dist/list-group.d.cts +58 -0
  171. package/dist/list-group.d.ts +58 -0
  172. package/dist/list-group.js +607 -0
  173. package/dist/list-group.js.map +1 -0
  174. package/dist/modal.cjs +38 -35
  175. package/dist/modal.cjs.map +1 -1
  176. package/dist/modal.d.cts +1 -3
  177. package/dist/modal.d.ts +1 -3
  178. package/dist/modal.js +38 -35
  179. package/dist/modal.js.map +1 -1
  180. package/dist/nav-item.cjs +107 -4
  181. package/dist/nav-item.cjs.map +1 -1
  182. package/dist/nav-item.d.cts +52 -2
  183. package/dist/nav-item.d.ts +52 -2
  184. package/dist/nav-item.js +108 -5
  185. package/dist/nav-item.js.map +1 -1
  186. package/dist/nav.cjs +25 -1
  187. package/dist/nav.cjs.map +1 -1
  188. package/dist/nav.d.cts +2 -1
  189. package/dist/nav.d.ts +2 -1
  190. package/dist/nav.js +26 -2
  191. package/dist/nav.js.map +1 -1
  192. package/dist/offcanvas.cjs +621 -0
  193. package/dist/offcanvas.cjs.map +1 -0
  194. package/dist/offcanvas.d.cts +61 -0
  195. package/dist/offcanvas.d.ts +61 -0
  196. package/dist/offcanvas.js +617 -0
  197. package/dist/offcanvas.js.map +1 -0
  198. package/dist/pagination.cjs +452 -0
  199. package/dist/pagination.cjs.map +1 -0
  200. package/dist/pagination.d.cts +69 -0
  201. package/dist/pagination.d.ts +69 -0
  202. package/dist/pagination.js +448 -0
  203. package/dist/pagination.js.map +1 -0
  204. package/dist/popover.cjs +534 -0
  205. package/dist/popover.cjs.map +1 -0
  206. package/dist/popover.d.cts +59 -0
  207. package/dist/popover.d.ts +59 -0
  208. package/dist/popover.js +530 -0
  209. package/dist/popover.js.map +1 -0
  210. package/dist/pricing-card.cjs +121 -64
  211. package/dist/pricing-card.cjs.map +1 -1
  212. package/dist/pricing-card.d.cts +21 -7
  213. package/dist/pricing-card.d.ts +21 -7
  214. package/dist/pricing-card.js +122 -65
  215. package/dist/pricing-card.js.map +1 -1
  216. package/dist/progress.cjs +403 -0
  217. package/dist/progress.cjs.map +1 -0
  218. package/dist/progress.d.cts +70 -0
  219. package/dist/progress.d.ts +70 -0
  220. package/dist/progress.js +398 -0
  221. package/dist/progress.js.map +1 -0
  222. package/dist/prose.cjs +425 -0
  223. package/dist/prose.cjs.map +1 -0
  224. package/dist/prose.d.cts +21 -0
  225. package/dist/prose.d.ts +21 -0
  226. package/dist/prose.js +422 -0
  227. package/dist/prose.js.map +1 -0
  228. package/dist/radio.cjs +3 -1
  229. package/dist/radio.cjs.map +1 -1
  230. package/dist/radio.js +3 -1
  231. package/dist/radio.js.map +1 -1
  232. package/dist/range.cjs +381 -0
  233. package/dist/range.cjs.map +1 -0
  234. package/dist/range.d.cts +76 -0
  235. package/dist/range.d.ts +76 -0
  236. package/dist/range.js +378 -0
  237. package/dist/range.js.map +1 -0
  238. package/dist/rating.cjs +33 -0
  239. package/dist/rating.cjs.map +1 -1
  240. package/dist/rating.d.cts +38 -3
  241. package/dist/rating.d.ts +38 -3
  242. package/dist/rating.js +33 -0
  243. package/dist/rating.js.map +1 -1
  244. package/dist/section.cjs +27 -3
  245. package/dist/section.cjs.map +1 -1
  246. package/dist/section.d.cts +16 -1
  247. package/dist/section.d.ts +16 -1
  248. package/dist/section.js +27 -4
  249. package/dist/section.js.map +1 -1
  250. package/dist/select.cjs +6 -1
  251. package/dist/select.cjs.map +1 -1
  252. package/dist/select.d.cts +7 -1
  253. package/dist/select.d.ts +7 -1
  254. package/dist/select.js +6 -1
  255. package/dist/select.js.map +1 -1
  256. package/dist/sidebar-link.cjs +19 -1
  257. package/dist/sidebar-link.cjs.map +1 -1
  258. package/dist/sidebar-link.d.cts +13 -2
  259. package/dist/sidebar-link.d.ts +13 -2
  260. package/dist/sidebar-link.js +19 -1
  261. package/dist/sidebar-link.js.map +1 -1
  262. package/dist/sidebar-toggle.cjs +3 -1
  263. package/dist/sidebar-toggle.cjs.map +1 -1
  264. package/dist/sidebar-toggle.js +3 -1
  265. package/dist/sidebar-toggle.js.map +1 -1
  266. package/dist/sidebar.cjs +33 -1
  267. package/dist/sidebar.cjs.map +1 -1
  268. package/dist/sidebar.d.cts +1 -0
  269. package/dist/sidebar.d.ts +1 -0
  270. package/dist/sidebar.js +34 -2
  271. package/dist/sidebar.js.map +1 -1
  272. package/dist/spinner.cjs +2 -1
  273. package/dist/spinner.cjs.map +1 -1
  274. package/dist/spinner.d.cts +2 -2
  275. package/dist/spinner.d.ts +2 -2
  276. package/dist/spinner.js +2 -1
  277. package/dist/spinner.js.map +1 -1
  278. package/dist/stack.cjs +4 -2
  279. package/dist/stack.cjs.map +1 -1
  280. package/dist/stack.d.cts +2 -2
  281. package/dist/stack.d.ts +2 -2
  282. package/dist/stack.js +4 -2
  283. package/dist/stack.js.map +1 -1
  284. package/dist/states-Bgzwu_XZ.d.cts +9 -0
  285. package/dist/states-Bgzwu_XZ.d.ts +9 -0
  286. package/dist/stepper.cjs +495 -0
  287. package/dist/stepper.cjs.map +1 -0
  288. package/dist/stepper.d.cts +40 -0
  289. package/dist/stepper.d.ts +40 -0
  290. package/dist/stepper.js +491 -0
  291. package/dist/stepper.js.map +1 -0
  292. package/dist/switch.cjs +492 -0
  293. package/dist/switch.cjs.map +1 -0
  294. package/dist/switch.d.cts +82 -0
  295. package/dist/switch.d.ts +82 -0
  296. package/dist/switch.js +488 -0
  297. package/dist/switch.js.map +1 -0
  298. package/dist/tab-panel.cjs +465 -0
  299. package/dist/tab-panel.cjs.map +1 -0
  300. package/dist/tab-panel.d.cts +48 -0
  301. package/dist/tab-panel.d.ts +48 -0
  302. package/dist/tab-panel.js +462 -0
  303. package/dist/tab-panel.js.map +1 -0
  304. package/dist/table.cjs +506 -0
  305. package/dist/table.cjs.map +1 -0
  306. package/dist/table.d.cts +54 -0
  307. package/dist/table.d.ts +54 -0
  308. package/dist/table.js +501 -0
  309. package/dist/table.js.map +1 -0
  310. package/dist/tabs.cjs +596 -0
  311. package/dist/tabs.cjs.map +1 -0
  312. package/dist/tabs.d.cts +65 -0
  313. package/dist/tabs.d.ts +65 -0
  314. package/dist/tabs.js +592 -0
  315. package/dist/tabs.js.map +1 -0
  316. package/dist/tag.cjs +27 -1
  317. package/dist/tag.cjs.map +1 -1
  318. package/dist/tag.d.cts +19 -3
  319. package/dist/tag.d.ts +19 -3
  320. package/dist/tag.js +27 -1
  321. package/dist/tag.js.map +1 -1
  322. package/dist/testimonial.cjs +130 -64
  323. package/dist/testimonial.cjs.map +1 -1
  324. package/dist/testimonial.d.cts +23 -8
  325. package/dist/testimonial.d.ts +23 -8
  326. package/dist/testimonial.js +131 -65
  327. package/dist/testimonial.js.map +1 -1
  328. package/dist/text.cjs +65 -6
  329. package/dist/text.cjs.map +1 -1
  330. package/dist/text.d.cts +24 -3
  331. package/dist/text.d.ts +24 -3
  332. package/dist/text.js +64 -8
  333. package/dist/text.js.map +1 -1
  334. package/dist/textarea.cjs +3 -0
  335. package/dist/textarea.cjs.map +1 -1
  336. package/dist/textarea.d.cts +7 -1
  337. package/dist/textarea.d.ts +7 -1
  338. package/dist/textarea.js +3 -0
  339. package/dist/textarea.js.map +1 -1
  340. package/dist/toast.cjs +2 -1
  341. package/dist/toast.cjs.map +1 -1
  342. package/dist/toast.d.cts +2 -2
  343. package/dist/toast.d.ts +2 -2
  344. package/dist/toast.js +2 -1
  345. package/dist/toast.js.map +1 -1
  346. package/dist/tooltip.cjs.map +1 -1
  347. package/dist/tooltip.d.cts +2 -2
  348. package/dist/tooltip.d.ts +2 -2
  349. package/dist/tooltip.js.map +1 -1
  350. package/package.json +126 -11
package/dist/index.cjs CHANGED
@@ -5,6 +5,7 @@ var lit = require('lit');
5
5
  var ifDefined_js = require('lit/directives/if-defined.js');
6
6
  var live_js = require('lit/directives/live.js');
7
7
  var staticHtml_js = require('lit/static-html.js');
8
+ var styleMap_js = require('lit/directives/style-map.js');
8
9
 
9
10
  // src/utils/form.ts
10
11
  var spectreInputSizes = ["sm", "md", "lg"];
@@ -19,7 +20,11 @@ var spectreButtonVariants = [
19
20
  "success",
20
21
  "cta",
21
22
  "accent",
22
- "inverse"
23
+ "inverse",
24
+ "warning",
25
+ "link",
26
+ "light",
27
+ "dark"
23
28
  ];
24
29
  function isButtonVariant(value) {
25
30
  return spectreButtonVariants.includes(value);
@@ -57,7 +62,8 @@ var spectreBadgeVariants = [
57
62
  "outline",
58
63
  "accent",
59
64
  "cta",
60
- "inverse"
65
+ "inverse",
66
+ "brand"
61
67
  ];
62
68
  function isBadgeVariant(value) {
63
69
  return spectreBadgeVariants.includes(value);
@@ -67,7 +73,8 @@ var spectreAlertVariants = [
67
73
  "success",
68
74
  "warning",
69
75
  "danger",
70
- "neutral"
76
+ "neutral",
77
+ "brand"
71
78
  ];
72
79
  function isAlertVariant(value) {
73
80
  return spectreAlertVariants.includes(value);
@@ -139,7 +146,8 @@ var spectreSpinnerVariants = [
139
146
  "info",
140
147
  "neutral",
141
148
  "accent",
142
- "cta"
149
+ "cta",
150
+ "inverse"
143
151
  ];
144
152
  function isSpinnerVariant(value) {
145
153
  return spectreSpinnerVariants.includes(value);
@@ -169,7 +177,7 @@ var spectreAvatarShapes = ["circle", "square"];
169
177
  function isAvatarShape(value) {
170
178
  return spectreAvatarShapes.includes(value);
171
179
  }
172
- var spectreContainerMaxWidths = ["prose"];
180
+ var spectreContainerMaxWidths = ["none", "prose", "wide"];
173
181
  function isContainerMaxWidth(value) {
174
182
  return spectreContainerMaxWidths.includes(
175
183
  value
@@ -324,7 +332,7 @@ var spectreStackDirections = ["vertical", "horizontal"];
324
332
  function isStackDirection(value) {
325
333
  return spectreStackDirections.includes(value);
326
334
  }
327
- var spectreStackBases = ["sidebar"];
335
+ var spectreStackBases = ["none", "sidebar"];
328
336
  function isStackBasis(value) {
329
337
  return spectreStackBases.includes(value);
330
338
  }
@@ -355,7 +363,8 @@ var spectreToastVariants = [
355
363
  "info",
356
364
  "success",
357
365
  "warning",
358
- "danger"
366
+ "danger",
367
+ "neutral"
359
368
  ];
360
369
  function isToastVariant(value) {
361
370
  return spectreToastVariants.includes(value);
@@ -399,7 +408,12 @@ var spectreTextVariants = [
399
408
  "meta",
400
409
  "brand",
401
410
  "onInverse",
402
- "onInverseMuted"
411
+ "onInverseMuted",
412
+ "onSurface",
413
+ "onSurfaceMuted",
414
+ "onSurfaceSubtle",
415
+ "onSurfaceMeta",
416
+ "onSurfaceBrand"
403
417
  ];
404
418
  function isTextVariant(value) {
405
419
  return spectreTextVariants.includes(value);
@@ -430,6 +444,114 @@ var spectreTextTransforms = [
430
444
  function isTextTransform(value) {
431
445
  return spectreTextTransforms.includes(value);
432
446
  }
447
+ var spectreTabsVariants = ["line", "pill"];
448
+ function isTabsVariant(value) {
449
+ return spectreTabsVariants.includes(value);
450
+ }
451
+ var spectreOffcanvasPlacements = [
452
+ "start",
453
+ "end",
454
+ "top",
455
+ "bottom"
456
+ ];
457
+ function isOffcanvasPlacement(value) {
458
+ return spectreOffcanvasPlacements.includes(
459
+ value
460
+ );
461
+ }
462
+ var spectreTableSizes = ["sm", "md"];
463
+ function isTableSize(value) {
464
+ return spectreTableSizes.includes(value);
465
+ }
466
+ var spectreStepperOrientations = ["horizontal", "vertical"];
467
+ function isStepperOrientation(value) {
468
+ return spectreStepperOrientations.includes(
469
+ value
470
+ );
471
+ }
472
+ var spectreSpacingScale = ["sm", "md", "lg"];
473
+ function isSpacingStep(value) {
474
+ return spectreSpacingScale.includes(value);
475
+ }
476
+ var spectreGridColStarts = [
477
+ 1,
478
+ 2,
479
+ 3,
480
+ 4,
481
+ 5,
482
+ 6,
483
+ 7,
484
+ 8,
485
+ 9,
486
+ 10,
487
+ 11,
488
+ 12
489
+ ];
490
+ function isGridColStart(value) {
491
+ return spectreGridColStarts.includes(value);
492
+ }
493
+ function isGridColStartOptions(value) {
494
+ if (typeof value !== "object" || value === null) {
495
+ return false;
496
+ }
497
+ const candidate = value;
498
+ return (candidate.base === void 0 || isGridColStart(candidate.base)) && (candidate.md === void 0 || isGridColStart(candidate.md)) && (candidate.lg === void 0 || isGridColStart(candidate.lg));
499
+ }
500
+ var spectrePopoverPlacements = [
501
+ "top",
502
+ "bottom",
503
+ "left",
504
+ "right"
505
+ ];
506
+ function isPopoverPlacement(value) {
507
+ return spectrePopoverPlacements.includes(
508
+ value
509
+ );
510
+ }
511
+ var spectreProgressVariants = [
512
+ "brand",
513
+ "neutral",
514
+ "info",
515
+ "success",
516
+ "warning",
517
+ "danger"
518
+ ];
519
+ function isProgressVariant(value) {
520
+ return spectreProgressVariants.includes(
521
+ value
522
+ );
523
+ }
524
+ var spectreTextPresets = ["heading", "display", "lead"];
525
+ function isTextPreset(value) {
526
+ return spectreTextPresets.includes(value);
527
+ }
528
+ var spectreHeadingLevels = [
529
+ "h1",
530
+ "h2",
531
+ "h3",
532
+ "h4",
533
+ "h5",
534
+ "h6"
535
+ ];
536
+ function isHeadingLevel(value) {
537
+ return spectreHeadingLevels.includes(value);
538
+ }
539
+ var spectreDisplayLevels = [1, 2, 3, 4, 5, 6];
540
+ function isDisplayLevel(value) {
541
+ return spectreDisplayLevels.includes(value);
542
+ }
543
+ var spectreTableRowVariants = [
544
+ "neutral",
545
+ "info",
546
+ "success",
547
+ "warning",
548
+ "danger"
549
+ ];
550
+ function isTableRowVariant(value) {
551
+ return spectreTableRowVariants.includes(
552
+ value
553
+ );
554
+ }
433
555
  function normalizeInt(value, fallback, min = 0) {
434
556
  if (value == null || typeof value !== "number" || !Number.isInteger(value) || value < min) {
435
557
  return fallback;
@@ -718,6 +840,22 @@ function hasMeaningfulContent(nodes) {
718
840
  return false;
719
841
  });
720
842
  }
843
+ var idCounter = 0;
844
+ function createUniqueId(prefix) {
845
+ idCounter += 1;
846
+ return `${prefix}-${idCounter}`;
847
+ }
848
+ function replaceClasses(element, previous, next) {
849
+ const nextTokens = next.split(/\s+/).filter(Boolean);
850
+ previous.split(/\s+/).filter((token) => token && !nextTokens.includes(token)).forEach((token) => element.classList.remove(token));
851
+ element.classList.add(...nextTokens);
852
+ }
853
+ var spectreKindKey = /* @__PURE__ */ Symbol.for(
854
+ "phcdevworks.spectre-components.kind"
855
+ );
856
+ function isSpectreKind(node, kind) {
857
+ return node[spectreKindKey] === kind;
858
+ }
721
859
 
722
860
  // src/utils/projectable.ts
723
861
  var SpectreProjectableElement = class extends SpectreBaseElement {
@@ -753,7 +891,9 @@ var SpectreProjectableElement = class extends SpectreBaseElement {
753
891
  nextProjectedContent.push(node);
754
892
  }
755
893
  });
756
- const hasChanged = nextProjectedContent.length !== this.projectedContent.length || nextProjectedContent.some((node, index) => node !== this.projectedContent[index]);
894
+ const hasChanged = nextProjectedContent.length !== this.projectedContent.length || nextProjectedContent.some(
895
+ (node, index) => node !== this.projectedContent[index]
896
+ );
757
897
  if (hasChanged) {
758
898
  this.projectedContent = nextProjectedContent;
759
899
  }
@@ -783,9 +923,31 @@ var SpectreProjectableElement = class extends SpectreBaseElement {
783
923
  this.contentObserver = void 0;
784
924
  }
785
925
  };
926
+
927
+ // src/utils/states.ts
928
+ var hoverFocusStateProperties = {
929
+ focused: { type: Boolean, reflect: true },
930
+ hovered: { type: Boolean, reflect: true }
931
+ };
932
+ var interactionStateProperties = {
933
+ ...hoverFocusStateProperties,
934
+ active: { type: Boolean, reflect: true }
935
+ };
936
+ function hoverFocusStates(element) {
937
+ return {
938
+ focused: element.focused ?? false,
939
+ hovered: element.hovered ?? false
940
+ };
941
+ }
942
+ function interactionStates(element) {
943
+ return { ...hoverFocusStates(element), active: element.active ?? false };
944
+ }
786
945
  var SpectreButtonElement = class extends SpectreProjectableElement {
787
946
  constructor() {
788
947
  super(...arguments);
948
+ this.active = false;
949
+ this.focused = false;
950
+ this.hovered = false;
789
951
  this.compact = false;
790
952
  this.disabled = false;
791
953
  this.fullWidth = false;
@@ -869,6 +1031,7 @@ var SpectreButtonElement = class extends SpectreProjectableElement {
869
1031
  }
870
1032
  get buttonClasses() {
871
1033
  const recipeClasses = spectreUi.getButtonClasses({
1034
+ ...interactionStates(this),
872
1035
  compact: this.compact ?? false,
873
1036
  disabled: this.isDisabled,
874
1037
  fullWidth: this.fullWidth ?? false,
@@ -948,6 +1111,7 @@ var SpectreButtonElement = class extends SpectreProjectableElement {
948
1111
  }
949
1112
  };
950
1113
  SpectreButtonElement.properties = {
1114
+ ...interactionStateProperties,
951
1115
  compact: { type: Boolean, reflect: true },
952
1116
  disabled: { type: Boolean, reflect: true },
953
1117
  form: { type: String },
@@ -978,6 +1142,9 @@ function defineSpectreButton(tagName = "sp-button") {
978
1142
  var SpectreInputElement = class extends SpectreBaseElement {
979
1143
  constructor() {
980
1144
  super(...arguments);
1145
+ this.active = false;
1146
+ this.focused = false;
1147
+ this.hovered = false;
981
1148
  this.disabled = false;
982
1149
  this.fullWidth = false;
983
1150
  this.invalid = false;
@@ -989,6 +1156,10 @@ var SpectreInputElement = class extends SpectreBaseElement {
989
1156
  this.success = false;
990
1157
  this.type = "text";
991
1158
  this.value = "";
1159
+ this.errorMessage = void 0;
1160
+ this.helperText = void 0;
1161
+ this.label = void 0;
1162
+ this.generatedId = createUniqueId("sp-input");
992
1163
  }
993
1164
  get autocapitalize() {
994
1165
  return super.autocapitalize;
@@ -1063,12 +1234,30 @@ var SpectreInputElement = class extends SpectreBaseElement {
1063
1234
  }
1064
1235
  get inputClasses() {
1065
1236
  return spectreUi.getInputClasses({
1237
+ ...interactionStates(this),
1066
1238
  fullWidth: this.fullWidth ?? false,
1067
1239
  pill: this.pill ?? false,
1068
1240
  size: this.size,
1069
- state: this.isDisabled ? this.disabled ? "disabled" : "loading" : this.invalid ? "error" : this.success ? "success" : "default"
1241
+ state: this.isDisabled ? this.disabled ? "disabled" : "loading" : this.invalid || this.errorMessage ? "error" : this.success ? "success" : "default"
1070
1242
  });
1071
1243
  }
1244
+ get inputId() {
1245
+ return this.id || this.generatedId;
1246
+ }
1247
+ get hasFieldChrome() {
1248
+ return Boolean(this.label || this.helperText || this.errorMessage);
1249
+ }
1250
+ // An error message replaces the helper text while it is shown.
1251
+ get messageId() {
1252
+ if (this.errorMessage) {
1253
+ return `${this.inputId}-error`;
1254
+ }
1255
+ return this.helperText ? `${this.inputId}-helper` : void 0;
1256
+ }
1257
+ get describedBy() {
1258
+ const ids = [this.forwardedAriaDescribedBy, this.messageId].filter(Boolean);
1259
+ return ids.length > 0 ? ids.join(" ") : void 0;
1260
+ }
1072
1261
  get nativeInput() {
1073
1262
  return this.querySelector("[data-sp-input-native]");
1074
1263
  }
@@ -1086,11 +1275,48 @@ var SpectreInputElement = class extends SpectreBaseElement {
1086
1275
  blur() {
1087
1276
  this.nativeInput?.blur();
1088
1277
  }
1278
+ renderMessage() {
1279
+ if (this.errorMessage) {
1280
+ return lit.html`<p
1281
+ aria-atomic="true"
1282
+ aria-live="polite"
1283
+ class="${spectreUi.getInputErrorMessageClasses()}"
1284
+ id="${this.inputId}-error"
1285
+ >
1286
+ ${this.errorMessage}
1287
+ </p>`;
1288
+ }
1289
+ if (this.helperText) {
1290
+ return lit.html`<p
1291
+ class="${spectreUi.getInputHelperTextClasses({ disabled: this.isDisabled })}"
1292
+ id="${this.inputId}-helper"
1293
+ >
1294
+ ${this.helperText}
1295
+ </p>`;
1296
+ }
1297
+ return lit.nothing;
1298
+ }
1299
+ // Without a label or message the native input renders alone, as before.
1089
1300
  render() {
1301
+ if (!this.hasFieldChrome) {
1302
+ return this.renderInput();
1303
+ }
1304
+ return lit.html`<div class="${spectreUi.getInputWrapperClasses()}" data-sp-input-wrapper>
1305
+ ${this.label ? lit.html`<label
1306
+ class="${spectreUi.getInputLabelClasses({ disabled: this.isDisabled })}"
1307
+ for="${this.inputId}"
1308
+ >${this.label}</label
1309
+ >` : lit.nothing}
1310
+ ${this.renderInput()} ${this.renderMessage()}
1311
+ </div>`;
1312
+ }
1313
+ renderInput() {
1090
1314
  return lit.html`<input
1091
1315
  aria-busy="${this.loading ? "true" : "false"}"
1092
- aria-describedby="${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}"
1093
- aria-invalid="${ifDefined_js.ifDefined(this.invalid ? "true" : void 0)}"
1316
+ aria-describedby="${ifDefined_js.ifDefined(this.describedBy)}"
1317
+ aria-invalid="${ifDefined_js.ifDefined(
1318
+ this.invalid || this.errorMessage ? "true" : void 0
1319
+ )}"
1094
1320
  aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
1095
1321
  aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
1096
1322
  autocapitalize="${ifDefined_js.ifDefined(this.autocapitalize || void 0)}"
@@ -1103,7 +1329,7 @@ var SpectreInputElement = class extends SpectreBaseElement {
1103
1329
  form="${ifDefined_js.ifDefined(this.form || void 0)}"
1104
1330
  ?readonly="${this.readonly}"
1105
1331
  ?required="${this.required}"
1106
- id="${ifDefined_js.ifDefined(this.id || void 0)}"
1332
+ id="${ifDefined_js.ifDefined(this.hasFieldChrome ? this.inputId : this.id || void 0)}"
1107
1333
  inputmode="${ifDefined_js.ifDefined(this.inputmode || void 0)}"
1108
1334
  list="${ifDefined_js.ifDefined(this.list || void 0)}"
1109
1335
  max="${ifDefined_js.ifDefined(this.max || void 0)}"
@@ -1124,9 +1350,13 @@ var SpectreInputElement = class extends SpectreBaseElement {
1124
1350
  }
1125
1351
  };
1126
1352
  SpectreInputElement.properties = {
1353
+ ...interactionStateProperties,
1127
1354
  autocomplete: { type: String, reflect: true },
1128
1355
  disabled: { type: Boolean, reflect: true },
1129
1356
  enterkeyhint: { type: String, reflect: true },
1357
+ errorMessage: { attribute: "error-message", type: String },
1358
+ helperText: { attribute: "helper-text", type: String },
1359
+ label: { type: String },
1130
1360
  form: { type: String },
1131
1361
  fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
1132
1362
  inputmode: { type: String, reflect: true },
@@ -1161,6 +1391,7 @@ var DEFAULT_ROWS = 2;
1161
1391
  var SpectreTextareaElement = class extends SpectreBaseElement {
1162
1392
  constructor() {
1163
1393
  super(...arguments);
1394
+ this.focused = false;
1164
1395
  this.disabled = false;
1165
1396
  this.fullWidth = false;
1166
1397
  this.invalid = false;
@@ -1246,6 +1477,7 @@ var SpectreTextareaElement = class extends SpectreBaseElement {
1246
1477
  }
1247
1478
  get textareaClasses() {
1248
1479
  return spectreUi.getTextareaClasses({
1480
+ focused: this.focused ?? false,
1249
1481
  fullWidth: this.fullWidth ?? false,
1250
1482
  pill: this.pill ?? false,
1251
1483
  size: this.size,
@@ -1304,6 +1536,7 @@ var SpectreTextareaElement = class extends SpectreBaseElement {
1304
1536
  }
1305
1537
  };
1306
1538
  SpectreTextareaElement.properties = {
1539
+ focused: { type: Boolean, reflect: true },
1307
1540
  autocomplete: { type: String, reflect: true },
1308
1541
  disabled: { type: Boolean, reflect: true },
1309
1542
  enterkeyhint: { type: String, reflect: true },
@@ -1335,6 +1568,7 @@ function defineSpectreTextarea(tagName = "sp-textarea") {
1335
1568
  var SpectreSelectElement = class extends SpectreProjectableElement {
1336
1569
  constructor() {
1337
1570
  super(...arguments);
1571
+ this.focused = false;
1338
1572
  this.disabled = false;
1339
1573
  this.fullWidth = false;
1340
1574
  this.invalid = false;
@@ -1440,6 +1674,7 @@ var SpectreSelectElement = class extends SpectreProjectableElement {
1440
1674
  }
1441
1675
  get selectClasses() {
1442
1676
  return spectreUi.getSelectClasses({
1677
+ focused: this.focused ?? false,
1443
1678
  fullWidth: this.fullWidth ?? false,
1444
1679
  pill: this.pill ?? false,
1445
1680
  size: this.size,
@@ -1490,6 +1725,7 @@ var SpectreSelectElement = class extends SpectreProjectableElement {
1490
1725
  }
1491
1726
  };
1492
1727
  SpectreSelectElement.properties = {
1728
+ focused: { type: Boolean, reflect: true },
1493
1729
  autocomplete: { type: String, reflect: true },
1494
1730
  disabled: { type: Boolean, reflect: true },
1495
1731
  form: { type: String },
@@ -2000,6 +2236,11 @@ function defineSpectreFieldset(tagName = "sp-fieldset") {
2000
2236
  var SpectreBadgeElement = class extends SpectreProjectableElement {
2001
2237
  constructor() {
2002
2238
  super(...arguments);
2239
+ this.dot = false;
2240
+ this.interactive = false;
2241
+ this.active = false;
2242
+ this.focused = false;
2243
+ this.hovered = false;
2003
2244
  this.accentRail = void 0;
2004
2245
  this.accentRailColor = void 0;
2005
2246
  this.disabled = false;
@@ -2056,6 +2297,9 @@ var SpectreBadgeElement = class extends SpectreProjectableElement {
2056
2297
  }
2057
2298
  get badgeClasses() {
2058
2299
  const recipeClasses = spectreUi.getBadgeClasses({
2300
+ dot: this.dot ?? false,
2301
+ interactive: this.interactive ?? false,
2302
+ ...interactionStates(this),
2059
2303
  ...this.accentRail !== void 0 && {
2060
2304
  accentRail: this.accentRail
2061
2305
  },
@@ -2088,6 +2332,9 @@ var SpectreBadgeElement = class extends SpectreProjectableElement {
2088
2332
  }
2089
2333
  };
2090
2334
  SpectreBadgeElement.properties = {
2335
+ dot: { type: Boolean, reflect: true },
2336
+ interactive: { type: Boolean, reflect: true },
2337
+ ...interactionStateProperties,
2091
2338
  accentRail: { attribute: "accent-rail", type: String, reflect: true },
2092
2339
  accentRailColor: {
2093
2340
  attribute: "accent-rail-color",
@@ -2132,6 +2379,9 @@ var paddedConverter = {
2132
2379
  var SpectreCardElement = class extends SpectreProjectableElement {
2133
2380
  constructor() {
2134
2381
  super(...arguments);
2382
+ this.active = false;
2383
+ this.focused = false;
2384
+ this.hovered = false;
2135
2385
  this.accent = void 0;
2136
2386
  this.accentColor = void 0;
2137
2387
  this.disabled = false;
@@ -2192,6 +2442,7 @@ var SpectreCardElement = class extends SpectreProjectableElement {
2192
2442
  }
2193
2443
  get cardClasses() {
2194
2444
  const recipeClasses = spectreUi.getCardClasses({
2445
+ ...interactionStates(this),
2195
2446
  ...this.accent !== void 0 && {
2196
2447
  accent: this.accent
2197
2448
  },
@@ -2225,6 +2476,7 @@ var SpectreCardElement = class extends SpectreProjectableElement {
2225
2476
  }
2226
2477
  };
2227
2478
  SpectreCardElement.properties = {
2479
+ ...interactionStateProperties,
2228
2480
  accent: { type: String, reflect: true },
2229
2481
  accentColor: { attribute: "accent-color", type: String, reflect: true },
2230
2482
  disabled: { type: Boolean, reflect: true },
@@ -2246,6 +2498,9 @@ function defineSpectreCard(tagName = "sp-card") {
2246
2498
  var SpectreIconBoxElement = class extends SpectreProjectableElement {
2247
2499
  constructor() {
2248
2500
  super(...arguments);
2501
+ this.active = false;
2502
+ this.focused = false;
2503
+ this.hovered = false;
2249
2504
  this.disabled = false;
2250
2505
  this.fullWidth = false;
2251
2506
  this.interactive = false;
@@ -2301,6 +2556,7 @@ var SpectreIconBoxElement = class extends SpectreProjectableElement {
2301
2556
  }
2302
2557
  get iconBoxClasses() {
2303
2558
  return spectreUi.getIconBoxClasses({
2559
+ ...interactionStates(this),
2304
2560
  disabled: this.isDisabled,
2305
2561
  fullWidth: this.fullWidth ?? false,
2306
2562
  interactive: this.interactive ?? false,
@@ -2327,6 +2583,7 @@ var SpectreIconBoxElement = class extends SpectreProjectableElement {
2327
2583
  }
2328
2584
  };
2329
2585
  SpectreIconBoxElement.properties = {
2586
+ ...interactionStateProperties,
2330
2587
  disabled: { type: Boolean, reflect: true },
2331
2588
  fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
2332
2589
  interactive: { type: Boolean, reflect: true },
@@ -2346,6 +2603,12 @@ function defineSpectreIconBox(tagName = "sp-icon-box") {
2346
2603
  var SpectreRatingElement = class extends SpectreBaseElement {
2347
2604
  constructor() {
2348
2605
  super(...arguments);
2606
+ this.fullWidth = false;
2607
+ this.pill = false;
2608
+ this.interactive = false;
2609
+ this.active = false;
2610
+ this.focused = false;
2611
+ this.hovered = false;
2349
2612
  this.disabled = false;
2350
2613
  this.loading = false;
2351
2614
  this.max = 5;
@@ -2385,6 +2648,10 @@ var SpectreRatingElement = class extends SpectreBaseElement {
2385
2648
  }
2386
2649
  get ratingClasses() {
2387
2650
  return spectreUi.getRatingClasses({
2651
+ fullWidth: this.fullWidth ?? false,
2652
+ pill: this.pill ?? false,
2653
+ interactive: this.interactive ?? false,
2654
+ ...interactionStates(this),
2388
2655
  disabled: this.isDisabled,
2389
2656
  loading: this.loading ?? false,
2390
2657
  size: this.size
@@ -2434,6 +2701,10 @@ var SpectreRatingElement = class extends SpectreBaseElement {
2434
2701
  }
2435
2702
  };
2436
2703
  SpectreRatingElement.properties = {
2704
+ fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
2705
+ pill: { type: Boolean, reflect: true },
2706
+ interactive: { type: Boolean, reflect: true },
2707
+ ...interactionStateProperties,
2437
2708
  disabled: { type: Boolean, reflect: true },
2438
2709
  label: { type: String, reflect: true },
2439
2710
  loading: { type: Boolean, reflect: true },
@@ -2449,9 +2720,105 @@ function defineSpectreRating(tagName = "sp-rating") {
2449
2720
  customElements.define(tagName, SpectreRatingElement);
2450
2721
  return SpectreRatingElement;
2451
2722
  }
2452
- var SpectreTestimonialElement = class extends SpectreProjectableElement {
2723
+
2724
+ // src/utils/projection.ts
2725
+ function slotOf(node) {
2726
+ if (node.nodeType !== Node.ELEMENT_NODE) {
2727
+ return void 0;
2728
+ }
2729
+ return node.getAttribute("slot") ?? void 0;
2730
+ }
2731
+ var ProjectionController = class {
2732
+ constructor(host, internalAttributes) {
2733
+ this.host = host;
2734
+ this.internalAttributes = internalAttributes;
2735
+ this.projected = [];
2736
+ host.addController(this);
2737
+ }
2738
+ hostConnected() {
2739
+ this.sync();
2740
+ this.observe();
2741
+ }
2742
+ hostDisconnected() {
2743
+ this.disconnect();
2744
+ }
2745
+ hostUpdate() {
2746
+ this.sync();
2747
+ this.disconnect();
2748
+ }
2749
+ hostUpdated() {
2750
+ this.observe();
2751
+ }
2752
+ // Every projected node in authored order, regardless of slot.
2753
+ all() {
2754
+ return [...this.projected];
2755
+ }
2756
+ // Omitting `slot` returns the nodes without a slot attribute.
2757
+ nodes(slot) {
2758
+ return this.projected.filter((node) => slotOf(node) === slot);
2759
+ }
2760
+ elements(slot) {
2761
+ return this.nodes(slot).filter(
2762
+ (node) => node.nodeType === Node.ELEMENT_NODE
2763
+ );
2764
+ }
2765
+ has(slot) {
2766
+ return hasMeaningfulContent(this.nodes(slot));
2767
+ }
2768
+ isInternalNode(node) {
2769
+ return node.nodeType === Node.ELEMENT_NODE && this.internalAttributes.some(
2770
+ (name) => node.hasAttribute(name)
2771
+ );
2772
+ }
2773
+ isProjectable(node) {
2774
+ if (node.nodeType === Node.COMMENT_NODE || this.isInternalNode(node)) {
2775
+ return false;
2776
+ }
2777
+ if (node.nodeType === Node.TEXT_NODE && this.hostHasRendered) {
2778
+ return Boolean(node.textContent?.trim());
2779
+ }
2780
+ return true;
2781
+ }
2782
+ get hostHasRendered() {
2783
+ return this.host.hasUpdated;
2784
+ }
2785
+ sync() {
2786
+ const next = [
2787
+ .../* @__PURE__ */ new Set([
2788
+ ...this.projected.filter((node) => this.host.contains(node)),
2789
+ ...Array.from(this.host.childNodes).filter(
2790
+ (node) => this.isProjectable(node)
2791
+ )
2792
+ ])
2793
+ ];
2794
+ const changed = next.length !== this.projected.length || next.some((node, index) => node !== this.projected[index]);
2795
+ if (changed) {
2796
+ this.projected = next;
2797
+ }
2798
+ return changed;
2799
+ }
2800
+ observe() {
2801
+ if (this.observer || !this.host.isConnected) {
2802
+ return;
2803
+ }
2804
+ this.observer = new MutationObserver(() => {
2805
+ if (this.sync()) {
2806
+ this.host.requestUpdate();
2807
+ }
2808
+ });
2809
+ this.observer.observe(this.host, { childList: true });
2810
+ }
2811
+ disconnect() {
2812
+ this.observer?.disconnect();
2813
+ this.observer = void 0;
2814
+ }
2815
+ };
2816
+ var SpectreTestimonialElement = class extends SpectreBaseElement {
2453
2817
  constructor() {
2454
2818
  super(...arguments);
2819
+ this.active = false;
2820
+ this.focused = false;
2821
+ this.hovered = false;
2455
2822
  this.accent = void 0;
2456
2823
  this.accentColor = void 0;
2457
2824
  this.disabled = false;
@@ -2459,6 +2826,9 @@ var SpectreTestimonialElement = class extends SpectreProjectableElement {
2459
2826
  this.interactive = false;
2460
2827
  this.loading = false;
2461
2828
  this.variant = "elevated";
2829
+ this.projection = new ProjectionController(this, [
2830
+ "data-sp-testimonial-native"
2831
+ ]);
2462
2832
  }
2463
2833
  get id() {
2464
2834
  return super.id;
@@ -2472,16 +2842,6 @@ var SpectreTestimonialElement = class extends SpectreProjectableElement {
2472
2842
  set title(value) {
2473
2843
  super.title = value;
2474
2844
  }
2475
- getContentContainer() {
2476
- return this.querySelector("[data-sp-testimonial-native]");
2477
- }
2478
- isInternalNode(node) {
2479
- if (node.nodeType !== Node.ELEMENT_NODE) {
2480
- return false;
2481
- }
2482
- const el = node;
2483
- return el.hasAttribute("data-sp-testimonial-native");
2484
- }
2485
2845
  willUpdate(changedProperties) {
2486
2846
  if (changedProperties.has("accent") && this.accent != null && !isAccentEdge(this.accent)) {
2487
2847
  this.accent = void 0;
@@ -2507,6 +2867,7 @@ var SpectreTestimonialElement = class extends SpectreProjectableElement {
2507
2867
  }
2508
2868
  get testimonialClasses() {
2509
2869
  return spectreUi.getTestimonialClasses({
2870
+ ...interactionStates(this),
2510
2871
  ...this.accent !== void 0 && {
2511
2872
  accent: this.accent
2512
2873
  },
@@ -2520,6 +2881,24 @@ var SpectreTestimonialElement = class extends SpectreProjectableElement {
2520
2881
  variant: this.variant
2521
2882
  });
2522
2883
  }
2884
+ renderAuthor() {
2885
+ const hasName = this.projection.has("author-name");
2886
+ const hasTitle = this.projection.has("author-title");
2887
+ if (!this.projection.has("author-image") && !hasName && !hasTitle) {
2888
+ return lit.nothing;
2889
+ }
2890
+ return lit.html`<div class="${spectreUi.getTestimonialAuthorClasses()}">
2891
+ ${this.projection.nodes("author-image")}
2892
+ ${hasName || hasTitle ? lit.html`<div class="${spectreUi.getTestimonialAuthorInfoClasses()}">
2893
+ ${hasName ? lit.html`<div class="${spectreUi.getTestimonialAuthorNameClasses()}">
2894
+ ${this.projection.nodes("author-name")}
2895
+ </div>` : lit.nothing}
2896
+ ${hasTitle ? lit.html`<div class="${spectreUi.getTestimonialAuthorTitleClasses()}">
2897
+ ${this.projection.nodes("author-title")}
2898
+ </div>` : lit.nothing}
2899
+ </div>` : lit.nothing}
2900
+ </div>`;
2901
+ }
2523
2902
  render() {
2524
2903
  return lit.html`<div
2525
2904
  aria-busy="${this.loading ? "true" : "false"}"
@@ -2532,11 +2911,15 @@ var SpectreTestimonialElement = class extends SpectreProjectableElement {
2532
2911
  role="${ifDefined_js.ifDefined(this.hasForwardedLabel ? "group" : void 0)}"
2533
2912
  title="${ifDefined_js.ifDefined(this.title || void 0)}"
2534
2913
  >
2535
- ${this.hasProjectedContent ? this.projectedContent : lit.nothing}
2914
+ ${this.projection.has("quote") ? lit.html`<div class="${spectreUi.getTestimonialQuoteClasses()}">
2915
+ ${this.projection.nodes("quote")}
2916
+ </div>` : lit.nothing}
2917
+ ${this.projection.nodes()} ${this.renderAuthor()}
2536
2918
  </div>`;
2537
2919
  }
2538
2920
  };
2539
2921
  SpectreTestimonialElement.properties = {
2922
+ ...interactionStateProperties,
2540
2923
  accent: { type: String, reflect: true },
2541
2924
  accentColor: { attribute: "accent-color", type: String, reflect: true },
2542
2925
  disabled: { type: Boolean, reflect: true },
@@ -2553,15 +2936,46 @@ function defineSpectreTestimonial(tagName = "sp-testimonial") {
2553
2936
  customElements.define(tagName, SpectreTestimonialElement);
2554
2937
  return SpectreTestimonialElement;
2555
2938
  }
2556
- var SpectreAlertElement = class extends SpectreProjectableElement {
2939
+ var paths = {
2940
+ check: lit.svg`<path d="M3 8.5l3 3 7-7" />`,
2941
+ chevronDown: lit.svg`<path d="M4 6l4 4 4-4" />`,
2942
+ chevronLeft: lit.svg`<path d="M10 4l-4 4 4 4" />`,
2943
+ chevronRight: lit.svg`<path d="M6 4l4 4-4 4" />`,
2944
+ close: lit.svg`<path d="M4 4l8 8M12 4l-8 8" />`
2945
+ };
2946
+ function renderIcon(name, sizeClass = "sp-icon-sm") {
2947
+ return lit.html`<svg
2948
+ aria-hidden="true"
2949
+ class="${sizeClass}"
2950
+ fill="none"
2951
+ focusable="false"
2952
+ stroke="currentColor"
2953
+ stroke-linecap="round"
2954
+ stroke-linejoin="round"
2955
+ stroke-width="2"
2956
+ viewBox="0 0 16 16"
2957
+ >
2958
+ ${paths[name]}
2959
+ </svg>`;
2960
+ }
2961
+ var SpectreAlertElement = class extends SpectreBaseElement {
2557
2962
  constructor() {
2558
2963
  super(...arguments);
2964
+ this.interactive = false;
2965
+ this.active = false;
2966
+ this.focused = false;
2967
+ this.hovered = false;
2968
+ this.dismissLabel = "Dismiss";
2559
2969
  this.dismissed = false;
2970
+ this.dismissible = false;
2560
2971
  this.disabled = false;
2561
2972
  this.fullWidth = false;
2562
2973
  this.loading = false;
2563
2974
  this.size = "md";
2564
2975
  this.variant = "info";
2976
+ this.projection = new ProjectionController(this, [
2977
+ "data-sp-alert-native"
2978
+ ]);
2565
2979
  }
2566
2980
  get id() {
2567
2981
  return super.id;
@@ -2575,20 +2989,16 @@ var SpectreAlertElement = class extends SpectreProjectableElement {
2575
2989
  set title(value) {
2576
2990
  super.title = value;
2577
2991
  }
2578
- getContentContainer() {
2579
- return this.querySelector("[data-sp-alert-native]");
2580
- }
2581
- isInternalNode(node) {
2582
- if (node.nodeType !== Node.ELEMENT_NODE) {
2583
- return false;
2584
- }
2585
- const el = node;
2586
- return el.hasAttribute("data-sp-alert-native");
2587
- }
2588
2992
  willUpdate(changedProperties) {
2993
+ if (changedProperties.has("dismissLabel") && !this.dismissLabel) {
2994
+ this.dismissLabel = "Dismiss";
2995
+ }
2589
2996
  if (changedProperties.has("dismissed") && this.dismissed == null) {
2590
2997
  this.dismissed = false;
2591
2998
  }
2999
+ if (changedProperties.has("dismissible") && this.dismissible == null) {
3000
+ this.dismissible = false;
3001
+ }
2592
3002
  if (changedProperties.has("disabled") && this.disabled == null) {
2593
3003
  this.disabled = false;
2594
3004
  }
@@ -2605,10 +3015,20 @@ var SpectreAlertElement = class extends SpectreProjectableElement {
2605
3015
  this.size = "md";
2606
3016
  }
2607
3017
  }
3018
+ dismiss() {
3019
+ if (this.dismissed) {
3020
+ return;
3021
+ }
3022
+ this.dismissed = true;
3023
+ this.dispatchEvent(new CustomEvent("sp-dismiss", { bubbles: true }));
3024
+ }
2608
3025
  get alertClasses() {
2609
3026
  return spectreUi.getAlertClasses({
3027
+ interactive: this.interactive ?? false,
3028
+ ...interactionStates(this),
2610
3029
  disabled: this.isDisabled,
2611
3030
  dismissed: this.dismissed ?? false,
3031
+ dismissible: this.dismissible ?? false,
2612
3032
  fullWidth: this.fullWidth ?? false,
2613
3033
  loading: this.loading ?? false,
2614
3034
  size: this.size,
@@ -2627,12 +3047,28 @@ var SpectreAlertElement = class extends SpectreProjectableElement {
2627
3047
  role="alert"
2628
3048
  title="${ifDefined_js.ifDefined(this.title || void 0)}"
2629
3049
  >
2630
- ${this.hasProjectedContent ? this.projectedContent : lit.nothing}
3050
+ ${this.projection.has("icon") ? lit.html`<span class="${spectreUi.getAlertIconClasses()}"
3051
+ >${this.projection.nodes("icon")}</span
3052
+ >` : lit.nothing}
3053
+ ${this.projection.has() ? this.projection.nodes() : lit.nothing}
3054
+ ${this.dismissible ? lit.html`<button
3055
+ aria-label="${this.dismissLabel ?? "Dismiss"}"
3056
+ class="${spectreUi.getAlertDismissClasses()}"
3057
+ data-sp-alert-dismiss
3058
+ type="button"
3059
+ @click="${() => this.dismiss()}"
3060
+ >
3061
+ ${renderIcon("close")}
3062
+ </button>` : lit.nothing}
2631
3063
  </div>`;
2632
3064
  }
2633
3065
  };
2634
3066
  SpectreAlertElement.properties = {
3067
+ interactive: { type: Boolean, reflect: true },
3068
+ ...interactionStateProperties,
3069
+ dismissLabel: { attribute: "dismiss-label", type: String },
2635
3070
  dismissed: { type: Boolean, reflect: true },
3071
+ dismissible: { type: Boolean, reflect: true },
2636
3072
  disabled: { type: Boolean, reflect: true },
2637
3073
  fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
2638
3074
  loading: { type: Boolean, reflect: true },
@@ -2650,6 +3086,9 @@ function defineSpectreAlert(tagName = "sp-alert") {
2650
3086
  var SpectreAvatarElement = class extends SpectreProjectableElement {
2651
3087
  constructor() {
2652
3088
  super(...arguments);
3089
+ this.active = false;
3090
+ this.focused = false;
3091
+ this.hovered = false;
2653
3092
  this.disabled = false;
2654
3093
  this.fullWidth = false;
2655
3094
  this.interactive = false;
@@ -2705,6 +3144,7 @@ var SpectreAvatarElement = class extends SpectreProjectableElement {
2705
3144
  }
2706
3145
  get avatarClasses() {
2707
3146
  return spectreUi.getAvatarClasses({
3147
+ ...interactionStates(this),
2708
3148
  disabled: this.isDisabled,
2709
3149
  fullWidth: this.fullWidth ?? false,
2710
3150
  interactive: this.interactive ?? false,
@@ -2731,6 +3171,7 @@ var SpectreAvatarElement = class extends SpectreProjectableElement {
2731
3171
  }
2732
3172
  };
2733
3173
  SpectreAvatarElement.properties = {
3174
+ ...interactionStateProperties,
2734
3175
  disabled: { type: Boolean, reflect: true },
2735
3176
  fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
2736
3177
  interactive: { type: Boolean, reflect: true },
@@ -2822,6 +3263,9 @@ function defineSpectreSpinner(tagName = "sp-spinner") {
2822
3263
  var SpectreTagElement = class extends SpectreProjectableElement {
2823
3264
  constructor() {
2824
3265
  super(...arguments);
3266
+ this.active = false;
3267
+ this.focused = false;
3268
+ this.hovered = false;
2825
3269
  this.dismissible = false;
2826
3270
  this.disabled = false;
2827
3271
  this.fullWidth = false;
@@ -2881,6 +3325,7 @@ var SpectreTagElement = class extends SpectreProjectableElement {
2881
3325
  }
2882
3326
  get tagClasses() {
2883
3327
  return spectreUi.getTagClasses({
3328
+ ...interactionStates(this),
2884
3329
  disabled: this.isDisabled,
2885
3330
  dismissible: this.dismissible ?? false,
2886
3331
  fullWidth: this.fullWidth ?? false,
@@ -2908,6 +3353,7 @@ var SpectreTagElement = class extends SpectreProjectableElement {
2908
3353
  }
2909
3354
  };
2910
3355
  SpectreTagElement.properties = {
3356
+ ...interactionStateProperties,
2911
3357
  dismissible: { type: Boolean, reflect: true },
2912
3358
  disabled: { type: Boolean, reflect: true },
2913
3359
  fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
@@ -2925,9 +3371,12 @@ function defineSpectreTag(tagName = "sp-tag") {
2925
3371
  customElements.define(tagName, SpectreTagElement);
2926
3372
  return SpectreTagElement;
2927
3373
  }
2928
- var SpectrePricingCardElement = class extends SpectreProjectableElement {
3374
+ var SpectrePricingCardElement = class extends SpectreBaseElement {
2929
3375
  constructor() {
2930
3376
  super(...arguments);
3377
+ this.active = false;
3378
+ this.focused = false;
3379
+ this.hovered = false;
2931
3380
  this.accent = void 0;
2932
3381
  this.accentColor = void 0;
2933
3382
  this.disabled = false;
@@ -2935,6 +3384,9 @@ var SpectrePricingCardElement = class extends SpectreProjectableElement {
2935
3384
  this.fullHeight = false;
2936
3385
  this.interactive = false;
2937
3386
  this.loading = false;
3387
+ this.projection = new ProjectionController(this, [
3388
+ "data-sp-pricing-card-native"
3389
+ ]);
2938
3390
  }
2939
3391
  get id() {
2940
3392
  return super.id;
@@ -2948,16 +3400,6 @@ var SpectrePricingCardElement = class extends SpectreProjectableElement {
2948
3400
  set title(value) {
2949
3401
  super.title = value;
2950
3402
  }
2951
- getContentContainer() {
2952
- return this.querySelector("[data-sp-pricing-card-native]");
2953
- }
2954
- isInternalNode(node) {
2955
- if (node.nodeType !== Node.ELEMENT_NODE) {
2956
- return false;
2957
- }
2958
- const el = node;
2959
- return el.hasAttribute("data-sp-pricing-card-native");
2960
- }
2961
3403
  willUpdate(changedProperties) {
2962
3404
  if (changedProperties.has("accent") && this.accent != null && !isAccentEdge(this.accent)) {
2963
3405
  this.accent = void 0;
@@ -2983,6 +3425,7 @@ var SpectrePricingCardElement = class extends SpectreProjectableElement {
2983
3425
  }
2984
3426
  get pricingCardClasses() {
2985
3427
  return spectreUi.getPricingCardClasses({
3428
+ ...interactionStates(this),
2986
3429
  ...this.accent !== void 0 && {
2987
3430
  accent: this.accent
2988
3431
  },
@@ -3008,11 +3451,24 @@ var SpectrePricingCardElement = class extends SpectreProjectableElement {
3008
3451
  role="${ifDefined_js.ifDefined(this.hasForwardedLabel ? "group" : void 0)}"
3009
3452
  title="${ifDefined_js.ifDefined(this.title || void 0)}"
3010
3453
  >
3011
- ${this.hasProjectedContent ? this.projectedContent : lit.nothing}
3454
+ ${this.projection.nodes("header")}
3455
+ ${this.projection.has("badge") ? lit.html`<div class="${spectreUi.getPricingCardBadgeClasses()}">
3456
+ ${this.projection.nodes("badge")}
3457
+ </div>` : lit.nothing}
3458
+ ${this.projection.has("price") ? lit.html`<div class="${spectreUi.getPricingCardPriceContainerClasses()}">
3459
+ <div class="${spectreUi.getPricingCardPriceClasses()}">
3460
+ ${this.projection.nodes("price")}
3461
+ </div>
3462
+ </div>` : lit.nothing}
3463
+ ${this.projection.has("description") ? lit.html`<div class="${spectreUi.getPricingCardDescriptionClasses()}">
3464
+ ${this.projection.nodes("description")}
3465
+ </div>` : lit.nothing}
3466
+ ${this.projection.nodes()} ${this.projection.nodes("footer")}
3012
3467
  </div>`;
3013
3468
  }
3014
3469
  };
3015
3470
  SpectrePricingCardElement.properties = {
3471
+ ...interactionStateProperties,
3016
3472
  accent: { type: String, reflect: true },
3017
3473
  accentColor: { attribute: "accent-color", type: String, reflect: true },
3018
3474
  disabled: { type: Boolean, reflect: true },
@@ -3034,6 +3490,7 @@ var SpectreContainerElement = class extends SpectreProjectableElement {
3034
3490
  super(...arguments);
3035
3491
  this.innerClass = void 0;
3036
3492
  this.maxWidth = void 0;
3493
+ this.padding = void 0;
3037
3494
  }
3038
3495
  get id() {
3039
3496
  return super.id;
@@ -3048,9 +3505,9 @@ var SpectreContainerElement = class extends SpectreProjectableElement {
3048
3505
  super.title = value;
3049
3506
  }
3050
3507
  connectedCallback() {
3051
- var _a;
3508
+ var _a5;
3052
3509
  super.connectedCallback();
3053
- (_a = this.style).display || (_a.display = "block");
3510
+ (_a5 = this.style).display || (_a5.display = "block");
3054
3511
  }
3055
3512
  getContentContainer() {
3056
3513
  return this.querySelector("[data-sp-container-native]");
@@ -3066,11 +3523,19 @@ var SpectreContainerElement = class extends SpectreProjectableElement {
3066
3523
  if (changedProperties.has("maxWidth") && this.maxWidth != null && !isContainerMaxWidth(this.maxWidth)) {
3067
3524
  this.maxWidth = void 0;
3068
3525
  }
3526
+ if (changedProperties.has("padding") && this.padding != null && !isSpacingStep(this.padding)) {
3527
+ this.padding = void 0;
3528
+ }
3069
3529
  }
3070
3530
  get containerClasses() {
3071
- const recipeClasses = spectreUi.getContainerClasses(
3072
- this.maxWidth != null ? { maxWidth: this.maxWidth } : {}
3073
- );
3531
+ const recipeClasses = spectreUi.getContainerClasses({
3532
+ ...this.maxWidth != null && {
3533
+ maxWidth: this.maxWidth
3534
+ },
3535
+ ...this.padding != null && {
3536
+ padding: this.padding
3537
+ }
3538
+ });
3074
3539
  const utilityClasses = sanitizeUtilityClasses(this.innerClass);
3075
3540
  return utilityClasses ? `${recipeClasses} ${utilityClasses}` : recipeClasses;
3076
3541
  }
@@ -3090,7 +3555,8 @@ var SpectreContainerElement = class extends SpectreProjectableElement {
3090
3555
  };
3091
3556
  SpectreContainerElement.properties = {
3092
3557
  innerClass: { attribute: "inner-class", type: String },
3093
- maxWidth: { attribute: "max-width", type: String, reflect: true }
3558
+ maxWidth: { attribute: "max-width", type: String, reflect: true },
3559
+ padding: { type: String, reflect: true }
3094
3560
  };
3095
3561
  function defineSpectreContainer(tagName = "sp-container") {
3096
3562
  const existingElement = customElements.get(tagName);
@@ -3167,7 +3633,7 @@ var SpectreGridElement = class extends SpectreProjectableElement {
3167
3633
  super.removeAttribute(qualifiedName);
3168
3634
  }
3169
3635
  connectedCallback() {
3170
- var _a;
3636
+ var _a5;
3171
3637
  const initialRole = HTMLElement.prototype.getAttribute.call(this, "role");
3172
3638
  if (initialRole !== null) {
3173
3639
  HTMLElement.prototype.removeAttribute.call(this, "role");
@@ -3176,7 +3642,7 @@ var SpectreGridElement = class extends SpectreProjectableElement {
3176
3642
  if (initialRole !== null) {
3177
3643
  this.role = initialRole;
3178
3644
  }
3179
- (_a = this.style).display || (_a.display = "block");
3645
+ (_a5 = this.style).display || (_a5.display = "block");
3180
3646
  }
3181
3647
  getContentContainer() {
3182
3648
  return this.querySelector("[data-sp-grid-native]");
@@ -3211,6 +3677,9 @@ var SpectreGridElement = class extends SpectreProjectableElement {
3211
3677
  if (changedProperties.has("offset") && this.offset !== void 0 && !isGridOffset(this.offset) && !isGridOffsetOptions(this.offset)) {
3212
3678
  this.offset = void 0;
3213
3679
  }
3680
+ if (changedProperties.has("colStart") && this.colStart !== void 0 && !isGridColStart(this.colStart) && !isGridColStartOptions(this.colStart)) {
3681
+ this.colStart = void 0;
3682
+ }
3214
3683
  if (changedProperties.has("rowSpan") && this.rowSpan !== void 0 && !isGridSpan(this.rowSpan) && !isGridSpanOptions(this.rowSpan)) {
3215
3684
  this.rowSpan = void 0;
3216
3685
  }
@@ -3245,6 +3714,9 @@ var SpectreGridElement = class extends SpectreProjectableElement {
3245
3714
  ...this.offset !== void 0 && {
3246
3715
  offset: this.offset
3247
3716
  },
3717
+ ...this.colStart !== void 0 && {
3718
+ colStart: this.colStart
3719
+ },
3248
3720
  ...this.rowSpan !== void 0 && {
3249
3721
  rowSpan: this.rowSpan
3250
3722
  },
@@ -3284,6 +3756,7 @@ var SpectreGridElement = class extends SpectreProjectableElement {
3284
3756
  };
3285
3757
  SpectreGridElement.properties = {
3286
3758
  align: { type: String, reflect: true },
3759
+ colStart: { attribute: "col-start", type: Object },
3287
3760
  columns: { type: Number, reflect: true },
3288
3761
  columnGap: { attribute: "column-gap", type: String, reflect: true },
3289
3762
  explicitTemplate: { attribute: "explicit-template", type: Object },
@@ -3309,7 +3782,9 @@ function defineSpectreGrid(tagName = "sp-grid") {
3309
3782
  var SpectreSectionElement = class extends SpectreProjectableElement {
3310
3783
  constructor() {
3311
3784
  super(...arguments);
3785
+ this.gap = void 0;
3312
3786
  this.innerClass = void 0;
3787
+ this.spacing = void 0;
3313
3788
  }
3314
3789
  get id() {
3315
3790
  return super.id;
@@ -3324,9 +3799,9 @@ var SpectreSectionElement = class extends SpectreProjectableElement {
3324
3799
  super.title = value;
3325
3800
  }
3326
3801
  connectedCallback() {
3327
- var _a;
3802
+ var _a5;
3328
3803
  super.connectedCallback();
3329
- (_a = this.style).display || (_a.display = "block");
3804
+ (_a5 = this.style).display || (_a5.display = "block");
3330
3805
  }
3331
3806
  getContentContainer() {
3332
3807
  return this.querySelector("[data-sp-section-native]");
@@ -3338,8 +3813,21 @@ var SpectreSectionElement = class extends SpectreProjectableElement {
3338
3813
  const el = node;
3339
3814
  return el.hasAttribute("data-sp-section-native");
3340
3815
  }
3816
+ willUpdate(changedProperties) {
3817
+ if (changedProperties.has("gap") && this.gap != null && !isSpacingStep(this.gap)) {
3818
+ this.gap = void 0;
3819
+ }
3820
+ if (changedProperties.has("spacing") && this.spacing != null && !isSpacingStep(this.spacing)) {
3821
+ this.spacing = void 0;
3822
+ }
3823
+ }
3341
3824
  get sectionClasses() {
3342
- const recipeClasses = spectreUi.getSectionClasses({});
3825
+ const recipeClasses = spectreUi.getSectionClasses({
3826
+ ...this.gap != null && { gap: this.gap },
3827
+ ...this.spacing != null && {
3828
+ spacing: this.spacing
3829
+ }
3830
+ });
3343
3831
  const utilityClasses = sanitizeUtilityClasses(this.innerClass);
3344
3832
  return utilityClasses ? `${recipeClasses} ${utilityClasses}` : recipeClasses;
3345
3833
  }
@@ -3358,7 +3846,9 @@ var SpectreSectionElement = class extends SpectreProjectableElement {
3358
3846
  }
3359
3847
  };
3360
3848
  SpectreSectionElement.properties = {
3361
- innerClass: { attribute: "inner-class", type: String }
3849
+ gap: { type: String, reflect: true },
3850
+ innerClass: { attribute: "inner-class", type: String },
3851
+ spacing: { type: String, reflect: true }
3362
3852
  };
3363
3853
  function defineSpectreSection(tagName = "sp-section") {
3364
3854
  const existingElement = customElements.get(tagName);
@@ -3390,9 +3880,9 @@ var SpectreStackElement = class extends SpectreProjectableElement {
3390
3880
  super.title = value;
3391
3881
  }
3392
3882
  connectedCallback() {
3393
- var _a;
3883
+ var _a5;
3394
3884
  super.connectedCallback();
3395
- (_a = this.style).display || (_a.display = "block");
3885
+ (_a5 = this.style).display || (_a5.display = "block");
3396
3886
  }
3397
3887
  getContentContainer() {
3398
3888
  return this.querySelector("[data-sp-stack-native]");
@@ -3457,6 +3947,22 @@ function defineSpectreStack(tagName = "sp-stack") {
3457
3947
  customElements.define(tagName, SpectreStackElement);
3458
3948
  return SpectreStackElement;
3459
3949
  }
3950
+
3951
+ // src/utils/parts.ts
3952
+ function applyPartClasses(elements, parts) {
3953
+ for (const element of elements) {
3954
+ const part = element.getAttribute("slot");
3955
+ const classes = part ? parts[part] : void 0;
3956
+ if (classes) {
3957
+ element.classList.add(...classes.split(/\s+/).filter(Boolean));
3958
+ }
3959
+ }
3960
+ }
3961
+ function childElements(nodes) {
3962
+ return nodes.filter(
3963
+ (node) => node.nodeType === Node.ELEMENT_NODE
3964
+ );
3965
+ }
3460
3966
  var SpectreDropdownElement = class extends SpectreBaseElement {
3461
3967
  constructor() {
3462
3968
  super(...arguments);
@@ -3597,6 +4103,14 @@ var SpectreDropdownElement = class extends SpectreBaseElement {
3597
4103
  this.viewport = false;
3598
4104
  }
3599
4105
  }
4106
+ updated(changedProperties) {
4107
+ super.updated(changedProperties);
4108
+ applyPartClasses(childElements(this.menuContent), {
4109
+ divider: spectreUi.getDropdownDividerClasses(),
4110
+ header: spectreUi.getDropdownHeaderClasses(),
4111
+ item: spectreUi.getDropdownItemClasses()
4112
+ });
4113
+ }
3600
4114
  get triggerElement() {
3601
4115
  return this.querySelector("[data-sp-dropdown-trigger]");
3602
4116
  }
@@ -3706,9 +4220,9 @@ var SpectreFooterElement = class extends SpectreProjectableElement {
3706
4220
  super.title = value;
3707
4221
  }
3708
4222
  connectedCallback() {
3709
- var _a;
4223
+ var _a5;
3710
4224
  super.connectedCallback();
3711
- (_a = this.style).display || (_a.display = "block");
4225
+ (_a5 = this.style).display || (_a5.display = "block");
3712
4226
  }
3713
4227
  getContentContainer() {
3714
4228
  return this.querySelector("[data-sp-footer-native]");
@@ -3748,6 +4262,22 @@ var SpectreFooterElement = class extends SpectreProjectableElement {
3748
4262
  const utilityClasses = sanitizeUtilityClasses(this.innerClass);
3749
4263
  return utilityClasses ? `${recipeClasses} ${utilityClasses}` : recipeClasses;
3750
4264
  }
4265
+ // Footer parts usually sit inside authored columns, so markers are matched
4266
+ // at any depth.
4267
+ updated(changedProperties) {
4268
+ super.updated(changedProperties);
4269
+ const native = this.querySelector("[data-sp-footer-native]");
4270
+ if (!native) {
4271
+ return;
4272
+ }
4273
+ applyPartClasses(native.querySelectorAll("[slot]"), {
4274
+ divider: spectreUi.getFooterDividerClasses(),
4275
+ heading: spectreUi.getFooterHeadingClasses(),
4276
+ links: spectreUi.getFooterLinksClasses(),
4277
+ muted: spectreUi.getFooterMutedClasses(),
4278
+ text: spectreUi.getFooterTextClasses()
4279
+ });
4280
+ }
3751
4281
  render() {
3752
4282
  return lit.html`<footer
3753
4283
  aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
@@ -3778,6 +4308,8 @@ function defineSpectreFooter(tagName = "sp-footer") {
3778
4308
  var SpectreFooterChipElement = class extends SpectreProjectableElement {
3779
4309
  constructor() {
3780
4310
  super(...arguments);
4311
+ this.focused = false;
4312
+ this.hovered = false;
3781
4313
  this.disabled = false;
3782
4314
  }
3783
4315
  get id() {
@@ -3808,7 +4340,10 @@ var SpectreFooterChipElement = class extends SpectreProjectableElement {
3808
4340
  }
3809
4341
  }
3810
4342
  get footerChipClasses() {
3811
- return spectreUi.getFooterChipClasses({ disabled: this.disabled ?? false });
4343
+ return spectreUi.getFooterChipClasses({
4344
+ ...hoverFocusStates(this),
4345
+ disabled: this.disabled ?? false
4346
+ });
3812
4347
  }
3813
4348
  render() {
3814
4349
  return lit.html`<span
@@ -3824,6 +4359,7 @@ var SpectreFooterChipElement = class extends SpectreProjectableElement {
3824
4359
  }
3825
4360
  };
3826
4361
  SpectreFooterChipElement.properties = {
4362
+ ...hoverFocusStateProperties,
3827
4363
  disabled: { type: Boolean, reflect: true }
3828
4364
  };
3829
4365
  function defineSpectreFooterChip(tagName = "sp-footer-chip") {
@@ -3837,6 +4373,8 @@ function defineSpectreFooterChip(tagName = "sp-footer-chip") {
3837
4373
  var SpectreFooterLinkElement = class extends SpectreProjectableElement {
3838
4374
  constructor() {
3839
4375
  super(...arguments);
4376
+ this.focused = false;
4377
+ this.hovered = false;
3840
4378
  this.active = false;
3841
4379
  this.disabled = false;
3842
4380
  this.href = void 0;
@@ -3873,6 +4411,7 @@ var SpectreFooterLinkElement = class extends SpectreProjectableElement {
3873
4411
  }
3874
4412
  get footerLinkClasses() {
3875
4413
  return spectreUi.getFooterLinkClasses({
4414
+ ...hoverFocusStates(this),
3876
4415
  active: this.active ?? false,
3877
4416
  disabled: this.disabled ?? false
3878
4417
  });
@@ -3894,6 +4433,7 @@ var SpectreFooterLinkElement = class extends SpectreProjectableElement {
3894
4433
  }
3895
4434
  };
3896
4435
  SpectreFooterLinkElement.properties = {
4436
+ ...hoverFocusStateProperties,
3897
4437
  active: { type: Boolean, reflect: true },
3898
4438
  disabled: { type: Boolean, reflect: true },
3899
4439
  href: { type: String }
@@ -3906,6 +4446,8 @@ function defineSpectreFooterLink(tagName = "sp-footer-link") {
3906
4446
  customElements.define(tagName, SpectreFooterLinkElement);
3907
4447
  return SpectreFooterLinkElement;
3908
4448
  }
4449
+
4450
+ // src/utils/focus.ts
3909
4451
  var FOCUSABLE_SELECTOR = [
3910
4452
  "a[href]",
3911
4453
  "button:not([disabled])",
@@ -3914,6 +4456,29 @@ var FOCUSABLE_SELECTOR = [
3914
4456
  "textarea:not([disabled])",
3915
4457
  '[tabindex]:not([tabindex="-1"])'
3916
4458
  ].join(",");
4459
+ function getFocusableElements(root) {
4460
+ if (!root) {
4461
+ return [];
4462
+ }
4463
+ return Array.from(root.querySelectorAll(FOCUSABLE_SELECTOR));
4464
+ }
4465
+ function trapFocus(event, root) {
4466
+ const focusable = getFocusableElements(root);
4467
+ if (focusable.length === 0) {
4468
+ event.preventDefault();
4469
+ return;
4470
+ }
4471
+ const first = focusable[0];
4472
+ const last = focusable[focusable.length - 1];
4473
+ const active = document.activeElement;
4474
+ if (event.shiftKey && active === first) {
4475
+ event.preventDefault();
4476
+ last?.focus();
4477
+ } else if (!event.shiftKey && active === last) {
4478
+ event.preventDefault();
4479
+ first?.focus();
4480
+ }
4481
+ }
3917
4482
  var SpectreModalElement = class extends SpectreProjectableElement {
3918
4483
  constructor() {
3919
4484
  super(...arguments);
@@ -3931,7 +4496,7 @@ var SpectreModalElement = class extends SpectreProjectableElement {
3931
4496
  return;
3932
4497
  }
3933
4498
  if (event.key === "Tab") {
3934
- this.trapFocus(event);
4499
+ trapFocus(event, this.modalElement);
3935
4500
  }
3936
4501
  };
3937
4502
  }
@@ -3995,36 +4560,12 @@ var SpectreModalElement = class extends SpectreProjectableElement {
3995
4560
  get modalElement() {
3996
4561
  return this.querySelector("[data-sp-modal-native]");
3997
4562
  }
3998
- get focusableElements() {
3999
- const modal = this.modalElement;
4000
- if (!modal) {
4001
- return [];
4002
- }
4003
- return Array.from(modal.querySelectorAll(FOCUSABLE_SELECTOR));
4004
- }
4005
4563
  focusFirstElement() {
4006
- const [first] = this.focusableElements;
4564
+ const [first] = getFocusableElements(this.modalElement);
4007
4565
  (first ?? this.modalElement)?.focus();
4008
4566
  }
4009
- trapFocus(event) {
4010
- const focusable = this.focusableElements;
4011
- if (focusable.length === 0) {
4012
- event.preventDefault();
4013
- return;
4014
- }
4015
- const first = focusable[0];
4016
- const last = focusable[focusable.length - 1];
4017
- const active = document.activeElement;
4018
- if (event.shiftKey && active === first) {
4019
- event.preventDefault();
4020
- last?.focus();
4021
- } else if (!event.shiftKey && active === last) {
4022
- event.preventDefault();
4023
- first?.focus();
4024
- }
4025
- }
4026
- close() {
4027
- if (!this.open) {
4567
+ close() {
4568
+ if (!this.open) {
4028
4569
  return;
4029
4570
  }
4030
4571
  this.open = false;
@@ -4113,9 +4654,9 @@ var SpectreNavElement = class extends SpectreProjectableElement {
4113
4654
  super.title = value;
4114
4655
  }
4115
4656
  connectedCallback() {
4116
- var _a;
4657
+ var _a5;
4117
4658
  super.connectedCallback();
4118
- (_a = this.style).display || (_a.display = "block");
4659
+ (_a5 = this.style).display || (_a5.display = "block");
4119
4660
  }
4120
4661
  getContentContainer() {
4121
4662
  return this.querySelector("[data-sp-nav-native]");
@@ -4163,6 +4704,12 @@ var SpectreNavElement = class extends SpectreProjectableElement {
4163
4704
  const utilityClasses = sanitizeUtilityClasses(this.innerClass);
4164
4705
  return utilityClasses ? `${recipeClasses} ${utilityClasses}` : recipeClasses;
4165
4706
  }
4707
+ updated(changedProperties) {
4708
+ super.updated(changedProperties);
4709
+ applyPartClasses(childElements(this.projectedContent), {
4710
+ links: spectreUi.getNavLinksClasses()
4711
+ });
4712
+ }
4166
4713
  render() {
4167
4714
  return lit.html`<nav
4168
4715
  aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
@@ -4195,12 +4742,20 @@ function defineSpectreNav(tagName = "sp-nav") {
4195
4742
  var SpectreNavItemElement = class extends SpectreBaseElement {
4196
4743
  constructor() {
4197
4744
  super(...arguments);
4745
+ this.focused = false;
4746
+ this.hovered = false;
4747
+ this.accent = void 0;
4748
+ this.accentColor = void 0;
4749
+ this.active = false;
4750
+ this.disabled = false;
4198
4751
  this.dropdown = false;
4752
+ this.fullWidth = false;
4199
4753
  this.href = void 0;
4200
4754
  this.label = void 0;
4201
4755
  this.mega = false;
4202
4756
  this.open = false;
4203
4757
  this.placement = "bottom-start";
4758
+ this.viewport = false;
4204
4759
  this.triggerContent = [];
4205
4760
  this.menuContent = [];
4206
4761
  this.handleDocumentClick = (event) => {
@@ -4298,6 +4853,24 @@ var SpectreNavItemElement = class extends SpectreBaseElement {
4298
4853
  this.contentObserver = void 0;
4299
4854
  }
4300
4855
  willUpdate(changedProperties) {
4856
+ if (changedProperties.has("accent") && this.accent != null && !isAccentEdge(this.accent)) {
4857
+ this.accent = void 0;
4858
+ }
4859
+ if (changedProperties.has("accentColor") && this.accentColor != null && !isAccentColor(this.accentColor)) {
4860
+ this.accentColor = void 0;
4861
+ }
4862
+ if (changedProperties.has("active") && this.active == null) {
4863
+ this.active = false;
4864
+ }
4865
+ if (changedProperties.has("disabled") && this.disabled == null) {
4866
+ this.disabled = false;
4867
+ }
4868
+ if (changedProperties.has("fullWidth") && this.fullWidth == null) {
4869
+ this.fullWidth = false;
4870
+ }
4871
+ if (changedProperties.has("viewport") && this.viewport == null) {
4872
+ this.viewport = false;
4873
+ }
4301
4874
  if (changedProperties.has("dropdown") && this.dropdown == null) {
4302
4875
  this.dropdown = false;
4303
4876
  }
@@ -4311,6 +4884,14 @@ var SpectreNavItemElement = class extends SpectreBaseElement {
4311
4884
  this.placement = "bottom-start";
4312
4885
  }
4313
4886
  }
4887
+ updated(changedProperties) {
4888
+ super.updated(changedProperties);
4889
+ applyPartClasses(childElements(this.menuContent), {
4890
+ divider: spectreUi.getDropdownDividerClasses(),
4891
+ header: spectreUi.getDropdownHeaderClasses(),
4892
+ item: spectreUi.getDropdownItemClasses()
4893
+ });
4894
+ }
4314
4895
  get triggerElement() {
4315
4896
  return this.querySelector("[data-sp-nav-item-trigger]");
4316
4897
  }
@@ -4336,23 +4917,40 @@ var SpectreNavItemElement = class extends SpectreBaseElement {
4336
4917
  this.dispatchEvent(new CustomEvent("sp-close", { bubbles: true }));
4337
4918
  }
4338
4919
  get wrapperClasses() {
4339
- return spectreUi.getDropdownClasses({ mega: this.mega ?? false });
4920
+ return spectreUi.getDropdownClasses({
4921
+ fullWidth: this.fullWidth ?? false,
4922
+ mega: this.mega ?? false,
4923
+ viewport: this.viewport ?? false
4924
+ });
4340
4925
  }
4341
4926
  get menuClasses() {
4342
4927
  return spectreUi.getDropdownMenuClasses({
4928
+ ...this.accent !== void 0 && {
4929
+ accent: this.accent
4930
+ },
4931
+ ...this.accentColor !== void 0 && {
4932
+ accentColor: this.accentColor
4933
+ },
4343
4934
  mega: this.mega ?? false,
4935
+ viewport: this.viewport ?? false,
4344
4936
  open: this.open ?? false,
4345
4937
  placement: this.placement
4346
4938
  });
4347
4939
  }
4348
4940
  get navLinkClasses() {
4349
- return spectreUi.getNavLinkClasses();
4941
+ return spectreUi.getNavLinkClasses({
4942
+ ...hoverFocusStates(this),
4943
+ active: this.active ?? false,
4944
+ disabled: this.disabled ?? false
4945
+ });
4350
4946
  }
4351
4947
  renderLink() {
4352
4948
  return lit.html`<a
4949
+ aria-current="${ifDefined_js.ifDefined(this.active ? "page" : void 0)}"
4950
+ aria-disabled="${ifDefined_js.ifDefined(this.disabled ? "true" : void 0)}"
4353
4951
  aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
4354
4952
  class="${this.navLinkClasses}"
4355
- href="${ifDefined_js.ifDefined(this.href)}"
4953
+ href="${ifDefined_js.ifDefined(this.disabled ? void 0 : this.href)}"
4356
4954
  id="${ifDefined_js.ifDefined(this.id || void 0)}"
4357
4955
  title="${ifDefined_js.ifDefined(this.title || void 0)}"
4358
4956
  >${this.hasMenuContent ? this.menuContent : this.label}</a
@@ -4370,6 +4968,7 @@ var SpectreNavItemElement = class extends SpectreBaseElement {
4370
4968
  aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel ?? this.label)}"
4371
4969
  class="${this.navLinkClasses}"
4372
4970
  data-sp-nav-item-trigger
4971
+ ?disabled="${this.disabled ?? false}"
4373
4972
  type="button"
4374
4973
  @click="${() => this.toggle()}"
4375
4974
  >
@@ -4385,12 +4984,19 @@ var SpectreNavItemElement = class extends SpectreBaseElement {
4385
4984
  }
4386
4985
  };
4387
4986
  SpectreNavItemElement.properties = {
4987
+ ...hoverFocusStateProperties,
4988
+ accent: { type: String, reflect: true },
4989
+ accentColor: { attribute: "accent-color", type: String, reflect: true },
4990
+ active: { type: Boolean, reflect: true },
4991
+ disabled: { type: Boolean, reflect: true },
4388
4992
  dropdown: { type: Boolean, reflect: true },
4993
+ fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
4389
4994
  href: { type: String },
4390
4995
  label: { type: String },
4391
4996
  mega: { type: Boolean, reflect: true },
4392
4997
  open: { type: Boolean, reflect: true },
4393
- placement: { type: String, reflect: true }
4998
+ placement: { type: String, reflect: true },
4999
+ viewport: { type: Boolean, reflect: true }
4394
5000
  };
4395
5001
  function defineSpectreNavItem(tagName = "sp-nav-item") {
4396
5002
  const existingElement = customElements.get(tagName);
@@ -4493,6 +5099,20 @@ var SpectreSidebarElement = class extends SpectreProjectableElement {
4493
5099
  get sidebarClasses() {
4494
5100
  return spectreUi.getSidebarClasses({ bordered: this.bordered ?? false });
4495
5101
  }
5102
+ updated(changedProperties) {
5103
+ super.updated(changedProperties);
5104
+ const elements = childElements(this.projectedContent);
5105
+ applyPartClasses(elements, {
5106
+ group: spectreUi.getSidebarGroupClasses(),
5107
+ header: spectreUi.getSidebarHeaderClasses()
5108
+ });
5109
+ elements.filter((element) => element.getAttribute("slot") === "group").forEach((group) => {
5110
+ const summary = group.querySelector(":scope > summary");
5111
+ summary?.classList.add(
5112
+ ...spectreUi.getSidebarGroupSummaryClasses().split(/\s+/).filter(Boolean)
5113
+ );
5114
+ });
5115
+ }
4496
5116
  render() {
4497
5117
  return lit.html`${this.hideToggle ? lit.nothing : lit.html`<button
4498
5118
  aria-expanded="${this.open ? "true" : "false"}"
@@ -4537,6 +5157,8 @@ function defineSpectreSidebar(tagName = "sp-sidebar") {
4537
5157
  var SpectreSidebarLinkElement = class extends SpectreProjectableElement {
4538
5158
  constructor() {
4539
5159
  super(...arguments);
5160
+ this.focused = false;
5161
+ this.hovered = false;
4540
5162
  this.active = false;
4541
5163
  this.disabled = false;
4542
5164
  this.href = void 0;
@@ -4577,6 +5199,7 @@ var SpectreSidebarLinkElement = class extends SpectreProjectableElement {
4577
5199
  }
4578
5200
  get sidebarLinkClasses() {
4579
5201
  return spectreUi.getSidebarLinkClasses({
5202
+ ...hoverFocusStates(this),
4580
5203
  active: this.active ?? false,
4581
5204
  disabled: this.disabled ?? false,
4582
5205
  level: this.level
@@ -4599,6 +5222,7 @@ var SpectreSidebarLinkElement = class extends SpectreProjectableElement {
4599
5222
  }
4600
5223
  };
4601
5224
  SpectreSidebarLinkElement.properties = {
5225
+ ...hoverFocusStateProperties,
4602
5226
  active: { type: Boolean, reflect: true },
4603
5227
  disabled: { type: Boolean, reflect: true },
4604
5228
  href: { type: String },
@@ -4974,12 +5598,12 @@ var SpectreTooltipElement = class extends SpectreBaseElement {
4974
5598
  return hasMeaningfulContent(this.tooltipContent);
4975
5599
  }
4976
5600
  connectedCallback() {
4977
- var _a, _b;
5601
+ var _a5, _b5;
4978
5602
  super.connectedCallback();
4979
5603
  this.syncProjectedContent();
4980
5604
  this.startContentObserver();
4981
- (_a = this.style).position || (_a.position = "relative");
4982
- (_b = this.style).display || (_b.display = "inline-block");
5605
+ (_a5 = this.style).position || (_a5.position = "relative");
5606
+ (_b5 = this.style).display || (_b5.display = "inline-block");
4983
5607
  }
4984
5608
  disconnectedCallback() {
4985
5609
  this.stopContentObserver();
@@ -5094,11 +5718,23 @@ var LEVEL_TAGS = {
5094
5718
  var SpectreTextElement = class extends SpectreProjectableElement {
5095
5719
  constructor() {
5096
5720
  super(...arguments);
5721
+ this.displayLevel = void 0;
5722
+ this.headingLevel = void 0;
5097
5723
  this.level = "p";
5724
+ this.preset = void 0;
5098
5725
  this.size = "md";
5099
5726
  this.variant = "default";
5100
5727
  }
5101
5728
  willUpdate(changedProperties) {
5729
+ if (changedProperties.has("displayLevel") && this.displayLevel != null && !isDisplayLevel(this.displayLevel)) {
5730
+ this.displayLevel = void 0;
5731
+ }
5732
+ if (changedProperties.has("headingLevel") && this.headingLevel != null && !isHeadingLevel(this.headingLevel)) {
5733
+ this.headingLevel = void 0;
5734
+ }
5735
+ if (changedProperties.has("preset") && this.preset != null && !isTextPreset(this.preset)) {
5736
+ this.preset = void 0;
5737
+ }
5102
5738
  if (changedProperties.has("family") && !isTextFamily(this.family)) {
5103
5739
  this.family = void 0;
5104
5740
  }
@@ -5137,19 +5773,34 @@ var SpectreTextElement = class extends SpectreProjectableElement {
5137
5773
  const el = node;
5138
5774
  return el.hasAttribute("data-sp-text-native");
5139
5775
  }
5140
- render() {
5141
- const tag = LEVEL_TAGS[this.level ?? "p"];
5142
- const textClasses = spectreUi.getTextClasses({
5776
+ // A typography preset replaces the text recipe: each sets its own size,
5777
+ // weight, and color.
5778
+ get textClasses() {
5779
+ const level = this.level ?? "p";
5780
+ switch (this.preset) {
5781
+ case "heading":
5782
+ return spectreUi.getHeadingClasses({
5783
+ level: this.headingLevel ?? (isHeadingLevel(level) ? level : "h2")
5784
+ });
5785
+ case "display":
5786
+ return spectreUi.getDisplayClasses({ level: this.displayLevel ?? 1 });
5787
+ case "lead":
5788
+ return spectreUi.getLeadClasses();
5789
+ }
5790
+ return spectreUi.getTextClasses({
5143
5791
  ...this.family !== void 0 && { family: this.family },
5144
5792
  size: this.size ?? "md",
5145
5793
  ...this.transform !== void 0 && { transform: this.transform },
5146
5794
  variant: this.variant ?? "default"
5147
5795
  });
5796
+ }
5797
+ render() {
5798
+ const tag = LEVEL_TAGS[this.level ?? "p"];
5148
5799
  return staticHtml_js.html`<${tag}
5149
5800
  aria-describedby="${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}"
5150
5801
  aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
5151
5802
  aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
5152
- class="${textClasses}"
5803
+ class="${this.textClasses}"
5153
5804
  data-sp-text-native
5154
5805
  id="${ifDefined_js.ifDefined(this.id || void 0)}"
5155
5806
  title="${ifDefined_js.ifDefined(this.title || void 0)}"
@@ -5157,8 +5808,11 @@ var SpectreTextElement = class extends SpectreProjectableElement {
5157
5808
  }
5158
5809
  };
5159
5810
  SpectreTextElement.properties = {
5811
+ displayLevel: { attribute: "display-level", type: Number, reflect: true },
5160
5812
  family: { type: String, reflect: true },
5813
+ headingLevel: { attribute: "heading-level", type: String, reflect: true },
5161
5814
  level: { type: String, reflect: true },
5815
+ preset: { type: String, reflect: true },
5162
5816
  size: { type: String, reflect: true },
5163
5817
  transform: { type: String, reflect: true },
5164
5818
  variant: { type: String, reflect: true }
@@ -5171,6 +5825,2813 @@ function defineSpectreText(tagName = "sp-text") {
5171
5825
  customElements.define(tagName, SpectreTextElement);
5172
5826
  return SpectreTextElement;
5173
5827
  }
5828
+ var SpectreTabsElement = class extends SpectreBaseElement {
5829
+ constructor() {
5830
+ super(...arguments);
5831
+ this.fullWidth = false;
5832
+ this.selectedIndex = 0;
5833
+ this.variant = "line";
5834
+ this.vertical = false;
5835
+ this.baseId = createUniqueId("sp-tabs");
5836
+ this.projection = new ProjectionController(this, [
5837
+ "data-sp-tabs-native"
5838
+ ]);
5839
+ this.handlePanelChange = (event) => {
5840
+ event.stopPropagation();
5841
+ this.requestUpdate();
5842
+ };
5843
+ this.handleKeydown = async (event) => {
5844
+ const enabled = this.panels.map((panel, index) => panel.disabled ? -1 : index).filter((index) => index >= 0);
5845
+ if (enabled.length === 0) {
5846
+ return;
5847
+ }
5848
+ const position = enabled.indexOf(this.activeIndex);
5849
+ const previousKey = this.vertical ? "ArrowUp" : "ArrowLeft";
5850
+ const nextKey = this.vertical ? "ArrowDown" : "ArrowRight";
5851
+ let target;
5852
+ switch (event.key) {
5853
+ case previousKey:
5854
+ target = enabled[(position - 1 + enabled.length) % enabled.length];
5855
+ break;
5856
+ case nextKey:
5857
+ target = enabled[(position + 1) % enabled.length];
5858
+ break;
5859
+ case "Home":
5860
+ target = enabled[0];
5861
+ break;
5862
+ case "End":
5863
+ target = enabled[enabled.length - 1];
5864
+ break;
5865
+ default:
5866
+ return;
5867
+ }
5868
+ if (target === void 0) {
5869
+ return;
5870
+ }
5871
+ event.preventDefault();
5872
+ this.select(target);
5873
+ await this.updateComplete;
5874
+ this.tabButtons[target]?.focus();
5875
+ };
5876
+ }
5877
+ get id() {
5878
+ return super.id;
5879
+ }
5880
+ set id(value) {
5881
+ super.id = value;
5882
+ }
5883
+ get title() {
5884
+ return super.title;
5885
+ }
5886
+ set title(value) {
5887
+ super.title = value;
5888
+ }
5889
+ connectedCallback() {
5890
+ var _a5;
5891
+ super.connectedCallback();
5892
+ (_a5 = this.style).display || (_a5.display = "block");
5893
+ this.addEventListener("sp-tab-panel-change", this.handlePanelChange);
5894
+ }
5895
+ disconnectedCallback() {
5896
+ this.removeEventListener("sp-tab-panel-change", this.handlePanelChange);
5897
+ super.disconnectedCallback();
5898
+ }
5899
+ willUpdate(changedProperties) {
5900
+ if (changedProperties.has("fullWidth") && this.fullWidth == null) {
5901
+ this.fullWidth = false;
5902
+ }
5903
+ if (changedProperties.has("selectedIndex")) {
5904
+ this.selectedIndex = normalizeInt(this.selectedIndex, 0);
5905
+ }
5906
+ if (changedProperties.has("variant") && (this.variant == null || !isTabsVariant(this.variant))) {
5907
+ this.variant = "line";
5908
+ }
5909
+ if (changedProperties.has("vertical") && this.vertical == null) {
5910
+ this.vertical = false;
5911
+ }
5912
+ }
5913
+ updated(changedProperties) {
5914
+ super.updated(changedProperties);
5915
+ const activeIndex = this.activeIndex;
5916
+ this.panels.forEach((panel, index) => {
5917
+ panel.selected = index === activeIndex;
5918
+ panel.tabId = this.tabId(index);
5919
+ });
5920
+ }
5921
+ get panels() {
5922
+ return this.projection.elements().filter(
5923
+ (element) => isSpectreKind(element, "tab-panel")
5924
+ );
5925
+ }
5926
+ // Falls back to the first enabled panel when the requested one is missing
5927
+ // or disabled; -1 when every panel is disabled.
5928
+ get activeIndex() {
5929
+ const panels = this.panels;
5930
+ const index = this.selectedIndex ?? 0;
5931
+ if (panels[index] && !panels[index].disabled) {
5932
+ return index;
5933
+ }
5934
+ return panels.findIndex((panel) => !panel.disabled);
5935
+ }
5936
+ tabId(index) {
5937
+ return `${this.baseId}-tab-${index}`;
5938
+ }
5939
+ get tabButtons() {
5940
+ return Array.from(
5941
+ this.querySelectorAll("[data-sp-tabs-tab]")
5942
+ ).filter(
5943
+ (button) => button.closest("[data-sp-tabs-native]") === this.native
5944
+ );
5945
+ }
5946
+ get native() {
5947
+ return this.querySelector("[data-sp-tabs-native]");
5948
+ }
5949
+ select(index) {
5950
+ const panel = this.panels[index];
5951
+ if (!panel || panel.disabled || index === this.activeIndex) {
5952
+ return;
5953
+ }
5954
+ this.selectedIndex = index;
5955
+ this.dispatchEvent(
5956
+ new CustomEvent("sp-change", { bubbles: true, detail: { index } })
5957
+ );
5958
+ }
5959
+ get tabsClasses() {
5960
+ return spectreUi.getTabsClasses({
5961
+ fullWidth: this.fullWidth ?? false,
5962
+ variant: this.variant,
5963
+ vertical: this.vertical ?? false
5964
+ });
5965
+ }
5966
+ render() {
5967
+ const panels = this.panels;
5968
+ const activeIndex = this.activeIndex;
5969
+ return lit.html`<div
5970
+ class="${this.tabsClasses}"
5971
+ data-sp-tabs-native
5972
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
5973
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
5974
+ >
5975
+ <div
5976
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
5977
+ aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
5978
+ aria-orientation="${ifDefined_js.ifDefined(this.vertical ? "vertical" : void 0)}"
5979
+ class="${spectreUi.getTabsListClasses()}"
5980
+ role="tablist"
5981
+ @keydown="${this.handleKeydown}"
5982
+ >
5983
+ ${panels.map((panel, index) => {
5984
+ const active = index === activeIndex;
5985
+ return lit.html`<button
5986
+ aria-controls="${panel.panelId}"
5987
+ aria-selected="${active ? "true" : "false"}"
5988
+ class="${spectreUi.getTabsItemClasses({
5989
+ active,
5990
+ disabled: panel.disabled ?? false
5991
+ })}"
5992
+ data-sp-tabs-tab
5993
+ ?disabled="${panel.disabled ?? false}"
5994
+ id="${this.tabId(index)}"
5995
+ role="tab"
5996
+ tabindex="${active ? "0" : "-1"}"
5997
+ type="button"
5998
+ @click="${() => this.select(index)}"
5999
+ >
6000
+ ${panel.label ?? ""}
6001
+ </button>`;
6002
+ })}
6003
+ </div>
6004
+ ${this.projection.nodes()}
6005
+ </div>`;
6006
+ }
6007
+ };
6008
+ SpectreTabsElement.properties = {
6009
+ fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
6010
+ selectedIndex: { attribute: "selected-index", type: Number, reflect: true },
6011
+ variant: { type: String, reflect: true },
6012
+ vertical: { type: Boolean, reflect: true }
6013
+ };
6014
+ function defineSpectreTabs(tagName = "sp-tabs") {
6015
+ const existingElement = customElements.get(tagName);
6016
+ if (existingElement) {
6017
+ return existingElement;
6018
+ }
6019
+ customElements.define(tagName, SpectreTabsElement);
6020
+ return SpectreTabsElement;
6021
+ }
6022
+ var _a, _b;
6023
+ var SpectreTabPanelElement = class extends (_b = SpectreBaseElement, _a = spectreKindKey, _b) {
6024
+ constructor() {
6025
+ super(...arguments);
6026
+ this[_a] = "tab-panel";
6027
+ this.disabled = false;
6028
+ this.label = void 0;
6029
+ // Owned by the parent `sp-tabs`, which sets it from its `selectedIndex`.
6030
+ this.selected = false;
6031
+ this.tabId = void 0;
6032
+ this.generatedId = createUniqueId("sp-tab-panel");
6033
+ this.projection = new ProjectionController(this, [
6034
+ "data-sp-tab-panel-native"
6035
+ ]);
6036
+ }
6037
+ get id() {
6038
+ return super.id;
6039
+ }
6040
+ set id(value) {
6041
+ super.id = value;
6042
+ }
6043
+ get title() {
6044
+ return super.title;
6045
+ }
6046
+ set title(value) {
6047
+ super.title = value;
6048
+ }
6049
+ get panelId() {
6050
+ return this.id || this.generatedId;
6051
+ }
6052
+ connectedCallback() {
6053
+ var _a5;
6054
+ super.connectedCallback();
6055
+ (_a5 = this.style).display || (_a5.display = "contents");
6056
+ }
6057
+ willUpdate(changedProperties) {
6058
+ if (changedProperties.has("disabled") && this.disabled == null) {
6059
+ this.disabled = false;
6060
+ }
6061
+ }
6062
+ updated(changedProperties) {
6063
+ super.updated(changedProperties);
6064
+ if (changedProperties.has("label") || changedProperties.has("disabled")) {
6065
+ this.dispatchEvent(
6066
+ new CustomEvent("sp-tab-panel-change", { bubbles: true })
6067
+ );
6068
+ }
6069
+ }
6070
+ render() {
6071
+ return lit.html`<div
6072
+ aria-labelledby="${ifDefined_js.ifDefined(this.tabId)}"
6073
+ class="${spectreUi.getTabsPanelClasses()}"
6074
+ data-sp-tab-panel-native
6075
+ ?hidden="${!this.selected}"
6076
+ id="${this.panelId}"
6077
+ role="tabpanel"
6078
+ tabindex="0"
6079
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
6080
+ >
6081
+ ${this.projection.nodes()}
6082
+ </div>`;
6083
+ }
6084
+ };
6085
+ SpectreTabPanelElement.properties = {
6086
+ disabled: { type: Boolean, reflect: true },
6087
+ label: { type: String },
6088
+ selected: { type: Boolean, reflect: true },
6089
+ tabId: { attribute: false }
6090
+ };
6091
+ function defineSpectreTabPanel(tagName = "sp-tab-panel") {
6092
+ const existingElement = customElements.get(tagName);
6093
+ if (existingElement) {
6094
+ return existingElement;
6095
+ }
6096
+ customElements.define(tagName, SpectreTabPanelElement);
6097
+ return SpectreTabPanelElement;
6098
+ }
6099
+ var SpectreAccordionElement = class extends SpectreBaseElement {
6100
+ constructor() {
6101
+ super(...arguments);
6102
+ this.flush = false;
6103
+ this.multiple = false;
6104
+ this.projection = new ProjectionController(this, [
6105
+ "data-sp-accordion-native"
6106
+ ]);
6107
+ this.handleItemOpen = (event) => {
6108
+ if (this.multiple) {
6109
+ return;
6110
+ }
6111
+ const items = this.items;
6112
+ const opened = items.find((item) => item === event.target);
6113
+ if (!opened) {
6114
+ return;
6115
+ }
6116
+ items.forEach((item) => {
6117
+ if (item !== opened) {
6118
+ item.open = false;
6119
+ }
6120
+ });
6121
+ };
6122
+ }
6123
+ get id() {
6124
+ return super.id;
6125
+ }
6126
+ set id(value) {
6127
+ super.id = value;
6128
+ }
6129
+ get title() {
6130
+ return super.title;
6131
+ }
6132
+ set title(value) {
6133
+ super.title = value;
6134
+ }
6135
+ connectedCallback() {
6136
+ var _a5;
6137
+ super.connectedCallback();
6138
+ (_a5 = this.style).display || (_a5.display = "block");
6139
+ this.addEventListener("sp-open", this.handleItemOpen);
6140
+ }
6141
+ disconnectedCallback() {
6142
+ this.removeEventListener("sp-open", this.handleItemOpen);
6143
+ super.disconnectedCallback();
6144
+ }
6145
+ willUpdate(changedProperties) {
6146
+ if (changedProperties.has("flush") && this.flush == null) {
6147
+ this.flush = false;
6148
+ }
6149
+ if (changedProperties.has("multiple") && this.multiple == null) {
6150
+ this.multiple = false;
6151
+ }
6152
+ }
6153
+ get items() {
6154
+ return this.projection.elements().filter(
6155
+ (element) => isSpectreKind(element, "accordion-item")
6156
+ );
6157
+ }
6158
+ render() {
6159
+ return lit.html`<div
6160
+ class="${spectreUi.getAccordionClasses({ flush: this.flush ?? false })}"
6161
+ data-sp-accordion-native
6162
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
6163
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
6164
+ >
6165
+ ${this.projection.nodes()}
6166
+ </div>`;
6167
+ }
6168
+ };
6169
+ SpectreAccordionElement.properties = {
6170
+ flush: { type: Boolean, reflect: true },
6171
+ multiple: { type: Boolean, reflect: true }
6172
+ };
6173
+ function defineSpectreAccordion(tagName = "sp-accordion") {
6174
+ const existingElement = customElements.get(tagName);
6175
+ if (existingElement) {
6176
+ return existingElement;
6177
+ }
6178
+ customElements.define(tagName, SpectreAccordionElement);
6179
+ return SpectreAccordionElement;
6180
+ }
6181
+ var _a2, _b2;
6182
+ var SpectreAccordionItemElement = class extends (_b2 = SpectreBaseElement, _a2 = spectreKindKey, _b2) {
6183
+ constructor() {
6184
+ super(...arguments);
6185
+ this[_a2] = "accordion-item";
6186
+ this.focused = false;
6187
+ this.hovered = false;
6188
+ this.disabled = false;
6189
+ this.label = void 0;
6190
+ this.open = false;
6191
+ this.generatedId = createUniqueId("sp-accordion-item");
6192
+ this.appliedHostClasses = "";
6193
+ this.projection = new ProjectionController(this, [
6194
+ "data-sp-accordion-item-header",
6195
+ "data-sp-accordion-item-panel"
6196
+ ]);
6197
+ }
6198
+ get id() {
6199
+ return super.id;
6200
+ }
6201
+ set id(value) {
6202
+ super.id = value;
6203
+ }
6204
+ get title() {
6205
+ return super.title;
6206
+ }
6207
+ set title(value) {
6208
+ super.title = value;
6209
+ }
6210
+ connectedCallback() {
6211
+ var _a5;
6212
+ super.connectedCallback();
6213
+ (_a5 = this.style).display || (_a5.display = "block");
6214
+ }
6215
+ willUpdate(changedProperties) {
6216
+ if (changedProperties.has("disabled") && this.disabled == null) {
6217
+ this.disabled = false;
6218
+ }
6219
+ if (changedProperties.has("open") && this.open == null) {
6220
+ this.open = false;
6221
+ }
6222
+ const hostClasses = spectreUi.getAccordionItemClasses({
6223
+ disabled: this.disabled ?? false,
6224
+ expanded: this.open ?? false
6225
+ });
6226
+ replaceClasses(this, this.appliedHostClasses, hostClasses);
6227
+ this.appliedHostClasses = hostClasses;
6228
+ }
6229
+ get headerId() {
6230
+ return this.id || `${this.generatedId}-header`;
6231
+ }
6232
+ get panelId() {
6233
+ return `${this.generatedId}-panel`;
6234
+ }
6235
+ toggle() {
6236
+ if (this.disabled) {
6237
+ return;
6238
+ }
6239
+ this.open = !this.open;
6240
+ this.dispatchEvent(
6241
+ new CustomEvent(this.open ? "sp-open" : "sp-close", { bubbles: true })
6242
+ );
6243
+ }
6244
+ render() {
6245
+ const expanded = this.open ?? false;
6246
+ const disabled = this.disabled ?? false;
6247
+ return lit.html`<button
6248
+ aria-controls="${this.panelId}"
6249
+ aria-expanded="${expanded ? "true" : "false"}"
6250
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
6251
+ class="${spectreUi.getAccordionHeaderClasses({
6252
+ ...hoverFocusStates(this),
6253
+ disabled,
6254
+ expanded
6255
+ })}"
6256
+ data-sp-accordion-item-header
6257
+ ?disabled="${disabled}"
6258
+ id="${this.headerId}"
6259
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
6260
+ type="button"
6261
+ @click="${() => this.toggle()}"
6262
+ >
6263
+ ${this.projection.has("header") ? this.projection.nodes("header") : this.label ?? ""}
6264
+ <span class="${spectreUi.getAccordionIconClasses({ expanded })}"
6265
+ >${renderIcon("chevronDown")}</span
6266
+ >
6267
+ </button>
6268
+ <div
6269
+ aria-labelledby="${this.headerId}"
6270
+ class="${spectreUi.getAccordionPanelClasses({ expanded })}"
6271
+ data-sp-accordion-item-panel
6272
+ ?hidden="${!expanded}"
6273
+ id="${this.panelId}"
6274
+ role="region"
6275
+ >
6276
+ ${this.projection.nodes()}
6277
+ </div>`;
6278
+ }
6279
+ };
6280
+ SpectreAccordionItemElement.properties = {
6281
+ ...hoverFocusStateProperties,
6282
+ disabled: { type: Boolean, reflect: true },
6283
+ label: { type: String },
6284
+ open: { type: Boolean, reflect: true }
6285
+ };
6286
+ function defineSpectreAccordionItem(tagName = "sp-accordion-item") {
6287
+ const existingElement = customElements.get(tagName);
6288
+ if (existingElement) {
6289
+ return existingElement;
6290
+ }
6291
+ customElements.define(tagName, SpectreAccordionItemElement);
6292
+ return SpectreAccordionItemElement;
6293
+ }
6294
+ var SpectreBreadcrumbElement = class extends SpectreBaseElement {
6295
+ constructor() {
6296
+ super(...arguments);
6297
+ this.separator = void 0;
6298
+ this.projection = new ProjectionController(this, [
6299
+ "data-sp-breadcrumb-native"
6300
+ ]);
6301
+ }
6302
+ get id() {
6303
+ return super.id;
6304
+ }
6305
+ set id(value) {
6306
+ super.id = value;
6307
+ }
6308
+ get title() {
6309
+ return super.title;
6310
+ }
6311
+ set title(value) {
6312
+ super.title = value;
6313
+ }
6314
+ connectedCallback() {
6315
+ var _a5;
6316
+ super.connectedCallback();
6317
+ (_a5 = this.style).display || (_a5.display = "block");
6318
+ }
6319
+ updated(changedProperties) {
6320
+ super.updated(changedProperties);
6321
+ const linkClasses = spectreUi.getBreadcrumbLinkClasses();
6322
+ this.crumbs.forEach((crumb) => {
6323
+ if (crumb instanceof HTMLAnchorElement) {
6324
+ crumb.classList.add(linkClasses);
6325
+ }
6326
+ });
6327
+ }
6328
+ get crumbs() {
6329
+ return this.projection.nodes().filter((node) => hasMeaningfulContent([node]));
6330
+ }
6331
+ get navLabel() {
6332
+ if (this.forwardedAriaLabel) {
6333
+ return this.forwardedAriaLabel;
6334
+ }
6335
+ return this.forwardedAriaLabelledBy ? void 0 : "Breadcrumb";
6336
+ }
6337
+ render() {
6338
+ const crumbs = this.crumbs;
6339
+ const separator = this.separator?.trim();
6340
+ return lit.html`<nav
6341
+ aria-label="${ifDefined_js.ifDefined(this.navLabel)}"
6342
+ aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
6343
+ data-sp-breadcrumb-native
6344
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
6345
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
6346
+ >
6347
+ <ol
6348
+ class="${spectreUi.getBreadcrumbClasses({ customSeparator: Boolean(separator) })}"
6349
+ >
6350
+ ${crumbs.map((crumb, index) => {
6351
+ const current = index === crumbs.length - 1;
6352
+ return lit.html`<li
6353
+ aria-current="${ifDefined_js.ifDefined(current ? "page" : void 0)}"
6354
+ class="${spectreUi.getBreadcrumbItemClasses({ current })}"
6355
+ >
6356
+ ${separator && index > 0 ? lit.html`<span
6357
+ aria-hidden="true"
6358
+ class="${spectreUi.getBreadcrumbSeparatorClasses()}"
6359
+ >${separator}</span
6360
+ >` : lit.nothing}${crumb}
6361
+ </li>`;
6362
+ })}
6363
+ </ol>
6364
+ </nav>`;
6365
+ }
6366
+ };
6367
+ SpectreBreadcrumbElement.properties = {
6368
+ separator: { type: String }
6369
+ };
6370
+ function defineSpectreBreadcrumb(tagName = "sp-breadcrumb") {
6371
+ const existingElement = customElements.get(tagName);
6372
+ if (existingElement) {
6373
+ return existingElement;
6374
+ }
6375
+ customElements.define(tagName, SpectreBreadcrumbElement);
6376
+ return SpectreBreadcrumbElement;
6377
+ }
6378
+ function isInteractiveItem(item) {
6379
+ return Boolean(item.href) || (item.interactive ?? false);
6380
+ }
6381
+ var SpectreListGroupElement = class extends SpectreBaseElement {
6382
+ constructor() {
6383
+ super(...arguments);
6384
+ this.accent = void 0;
6385
+ this.accentColor = void 0;
6386
+ this.flush = false;
6387
+ this.horizontal = false;
6388
+ this.projection = new ProjectionController(this, [
6389
+ "data-sp-list-group-native"
6390
+ ]);
6391
+ this.handleItemChange = (event) => {
6392
+ event.stopPropagation();
6393
+ this.requestUpdate();
6394
+ };
6395
+ }
6396
+ get id() {
6397
+ return super.id;
6398
+ }
6399
+ set id(value) {
6400
+ super.id = value;
6401
+ }
6402
+ get title() {
6403
+ return super.title;
6404
+ }
6405
+ set title(value) {
6406
+ super.title = value;
6407
+ }
6408
+ connectedCallback() {
6409
+ var _a5;
6410
+ super.connectedCallback();
6411
+ (_a5 = this.style).display || (_a5.display = "block");
6412
+ this.addEventListener("sp-list-group-item-change", this.handleItemChange);
6413
+ }
6414
+ disconnectedCallback() {
6415
+ this.removeEventListener("sp-list-group-item-change", this.handleItemChange);
6416
+ super.disconnectedCallback();
6417
+ }
6418
+ willUpdate(changedProperties) {
6419
+ if (changedProperties.has("accent") && this.accent != null && !isAccentEdge(this.accent)) {
6420
+ this.accent = void 0;
6421
+ }
6422
+ if (changedProperties.has("accentColor") && this.accentColor != null && !isAccentColor(this.accentColor)) {
6423
+ this.accentColor = void 0;
6424
+ }
6425
+ if (changedProperties.has("flush") && this.flush == null) {
6426
+ this.flush = false;
6427
+ }
6428
+ if (changedProperties.has("horizontal") && this.horizontal == null) {
6429
+ this.horizontal = false;
6430
+ }
6431
+ }
6432
+ updated(changedProperties) {
6433
+ super.updated(changedProperties);
6434
+ this.items.forEach((item) => {
6435
+ applyPartClasses(item.children, {
6436
+ heading: spectreUi.getListGroupItemHeadingClasses(),
6437
+ text: spectreUi.getListGroupItemTextClasses()
6438
+ });
6439
+ });
6440
+ }
6441
+ get items() {
6442
+ return this.projection.elements().filter(
6443
+ (element) => isSpectreKind(element, "list-group-item")
6444
+ );
6445
+ }
6446
+ get listClasses() {
6447
+ return spectreUi.getListGroupClasses({
6448
+ ...this.accent !== void 0 && {
6449
+ accent: this.accent
6450
+ },
6451
+ ...this.accentColor !== void 0 && {
6452
+ accentColor: this.accentColor
6453
+ },
6454
+ flush: this.flush ?? false,
6455
+ horizontal: this.horizontal ?? false
6456
+ });
6457
+ }
6458
+ itemClasses(item) {
6459
+ return spectreUi.getListGroupItemClasses({
6460
+ ...hoverFocusStates(item),
6461
+ active: item.active ?? false,
6462
+ disabled: item.disabled ?? false,
6463
+ interactive: isInteractiveItem(item),
6464
+ selected: item.selected ?? false
6465
+ });
6466
+ }
6467
+ select(item) {
6468
+ item.dispatchEvent(new CustomEvent("sp-select", { bubbles: true }));
6469
+ }
6470
+ renderRow(item) {
6471
+ const classes = this.itemClasses(item);
6472
+ const current = item.active ? "true" : void 0;
6473
+ const disabled = item.disabled ?? false;
6474
+ const id = item.id || void 0;
6475
+ const label = item.ariaLabel?.trim() || void 0;
6476
+ const title = item.title || void 0;
6477
+ if (item.href) {
6478
+ return lit.html`<a
6479
+ aria-current="${ifDefined_js.ifDefined(current)}"
6480
+ aria-disabled="${ifDefined_js.ifDefined(disabled ? "true" : void 0)}"
6481
+ aria-label="${ifDefined_js.ifDefined(label)}"
6482
+ class="${classes}"
6483
+ data-sp-list-group-row
6484
+ href="${ifDefined_js.ifDefined(disabled ? void 0 : item.href)}"
6485
+ id="${ifDefined_js.ifDefined(id)}"
6486
+ target="${ifDefined_js.ifDefined(item.target)}"
6487
+ title="${ifDefined_js.ifDefined(title)}"
6488
+ @click="${() => this.select(item)}"
6489
+ >${item}</a
6490
+ >`;
6491
+ }
6492
+ if (item.interactive) {
6493
+ return lit.html`<button
6494
+ aria-current="${ifDefined_js.ifDefined(current)}"
6495
+ aria-label="${ifDefined_js.ifDefined(label)}"
6496
+ class="${classes}"
6497
+ data-sp-list-group-row
6498
+ ?disabled="${disabled}"
6499
+ id="${ifDefined_js.ifDefined(id)}"
6500
+ title="${ifDefined_js.ifDefined(title)}"
6501
+ type="button"
6502
+ @click="${() => this.select(item)}"
6503
+ >
6504
+ ${item}
6505
+ </button>`;
6506
+ }
6507
+ return lit.html`<div
6508
+ aria-current="${ifDefined_js.ifDefined(current)}"
6509
+ aria-label="${ifDefined_js.ifDefined(label)}"
6510
+ class="${classes}"
6511
+ data-sp-list-group-row
6512
+ id="${ifDefined_js.ifDefined(id)}"
6513
+ title="${ifDefined_js.ifDefined(title)}"
6514
+ >
6515
+ ${item}
6516
+ </div>`;
6517
+ }
6518
+ render() {
6519
+ const items = this.items;
6520
+ if (!items.some(isInteractiveItem)) {
6521
+ return lit.html`<ul
6522
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
6523
+ aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
6524
+ class="${this.listClasses}"
6525
+ data-sp-list-group-native
6526
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
6527
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
6528
+ >
6529
+ ${items.map(
6530
+ (item) => lit.html`<li
6531
+ aria-current="${ifDefined_js.ifDefined(item.active ? "true" : void 0)}"
6532
+ aria-label="${ifDefined_js.ifDefined(item.ariaLabel?.trim() || void 0)}"
6533
+ class="${this.itemClasses(item)}"
6534
+ data-sp-list-group-row
6535
+ id="${ifDefined_js.ifDefined(item.id || void 0)}"
6536
+ title="${ifDefined_js.ifDefined(item.title || void 0)}"
6537
+ >
6538
+ ${item}
6539
+ </li>`
6540
+ )}
6541
+ </ul>`;
6542
+ }
6543
+ return lit.html`<div
6544
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
6545
+ aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
6546
+ class="${this.listClasses}"
6547
+ data-sp-list-group-native
6548
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
6549
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
6550
+ >
6551
+ ${items.map((item) => this.renderRow(item))}
6552
+ </div>`;
6553
+ }
6554
+ };
6555
+ SpectreListGroupElement.properties = {
6556
+ accent: { type: String, reflect: true },
6557
+ accentColor: { attribute: "accent-color", type: String, reflect: true },
6558
+ flush: { type: Boolean, reflect: true },
6559
+ horizontal: { type: Boolean, reflect: true }
6560
+ };
6561
+ function defineSpectreListGroup(tagName = "sp-list-group") {
6562
+ const existingElement = customElements.get(tagName);
6563
+ if (existingElement) {
6564
+ return existingElement;
6565
+ }
6566
+ customElements.define(tagName, SpectreListGroupElement);
6567
+ return SpectreListGroupElement;
6568
+ }
6569
+ var _a3, _b3;
6570
+ var SpectreListGroupItemElement = class extends (_b3 = SpectreBaseElement, _a3 = spectreKindKey, _b3) {
6571
+ constructor() {
6572
+ super(...arguments);
6573
+ this[_a3] = "list-group-item";
6574
+ this.focused = false;
6575
+ this.hovered = false;
6576
+ this.active = false;
6577
+ this.disabled = false;
6578
+ this.href = void 0;
6579
+ this.interactive = false;
6580
+ this.selected = false;
6581
+ this.target = void 0;
6582
+ }
6583
+ get id() {
6584
+ return super.id;
6585
+ }
6586
+ set id(value) {
6587
+ super.id = value;
6588
+ }
6589
+ get title() {
6590
+ return super.title;
6591
+ }
6592
+ set title(value) {
6593
+ super.title = value;
6594
+ }
6595
+ connectedCallback() {
6596
+ var _a5;
6597
+ super.connectedCallback();
6598
+ (_a5 = this.style).display || (_a5.display = "contents");
6599
+ this.contentObserver = new MutationObserver(() => this.notifyParent());
6600
+ this.contentObserver.observe(this, { childList: true });
6601
+ }
6602
+ disconnectedCallback() {
6603
+ this.contentObserver?.disconnect();
6604
+ this.contentObserver = void 0;
6605
+ super.disconnectedCallback();
6606
+ }
6607
+ notifyParent() {
6608
+ this.dispatchEvent(
6609
+ new CustomEvent("sp-list-group-item-change", { bubbles: true })
6610
+ );
6611
+ }
6612
+ willUpdate(changedProperties) {
6613
+ if (changedProperties.has("active") && this.active == null) {
6614
+ this.active = false;
6615
+ }
6616
+ if (changedProperties.has("disabled") && this.disabled == null) {
6617
+ this.disabled = false;
6618
+ }
6619
+ if (changedProperties.has("interactive") && this.interactive == null) {
6620
+ this.interactive = false;
6621
+ }
6622
+ if (changedProperties.has("selected") && this.selected == null) {
6623
+ this.selected = false;
6624
+ }
6625
+ }
6626
+ updated(changedProperties) {
6627
+ super.updated(changedProperties);
6628
+ this.notifyParent();
6629
+ }
6630
+ render() {
6631
+ return lit.nothing;
6632
+ }
6633
+ };
6634
+ SpectreListGroupItemElement.properties = {
6635
+ ...hoverFocusStateProperties,
6636
+ active: { type: Boolean, reflect: true },
6637
+ disabled: { type: Boolean, reflect: true },
6638
+ href: { type: String },
6639
+ interactive: { type: Boolean, reflect: true },
6640
+ selected: { type: Boolean, reflect: true },
6641
+ target: { type: String }
6642
+ };
6643
+ function defineSpectreListGroupItem(tagName = "sp-list-group-item") {
6644
+ const existingElement = customElements.get(tagName);
6645
+ if (existingElement) {
6646
+ return existingElement;
6647
+ }
6648
+ customElements.define(tagName, SpectreListGroupItemElement);
6649
+ return SpectreListGroupItemElement;
6650
+ }
6651
+ var SpectreOffcanvasElement = class extends SpectreBaseElement {
6652
+ constructor() {
6653
+ super(...arguments);
6654
+ this.closeLabel = "Close";
6655
+ this.label = void 0;
6656
+ this.open = false;
6657
+ this.placement = "start";
6658
+ this.previouslyFocusedElement = null;
6659
+ this.titleId = `${createUniqueId("sp-offcanvas")}-title`;
6660
+ this.projection = new ProjectionController(this, [
6661
+ "data-sp-offcanvas-backdrop",
6662
+ "data-sp-offcanvas-native"
6663
+ ]);
6664
+ this.handleDocumentKeydown = (event) => {
6665
+ if (!this.open) {
6666
+ return;
6667
+ }
6668
+ if (event.key === "Escape") {
6669
+ this.close();
6670
+ } else if (event.key === "Tab") {
6671
+ trapFocus(event, this.panelElement);
6672
+ }
6673
+ };
6674
+ }
6675
+ get id() {
6676
+ return super.id;
6677
+ }
6678
+ set id(value) {
6679
+ super.id = value;
6680
+ }
6681
+ get title() {
6682
+ return super.title;
6683
+ }
6684
+ set title(value) {
6685
+ super.title = value;
6686
+ }
6687
+ connectedCallback() {
6688
+ super.connectedCallback();
6689
+ document.addEventListener("keydown", this.handleDocumentKeydown);
6690
+ }
6691
+ disconnectedCallback() {
6692
+ document.removeEventListener("keydown", this.handleDocumentKeydown);
6693
+ super.disconnectedCallback();
6694
+ }
6695
+ willUpdate(changedProperties) {
6696
+ if (changedProperties.has("closeLabel") && !this.closeLabel) {
6697
+ this.closeLabel = "Close";
6698
+ }
6699
+ if (changedProperties.has("open") && this.open == null) {
6700
+ this.open = false;
6701
+ }
6702
+ if (changedProperties.has("placement") && (this.placement == null || !isOffcanvasPlacement(this.placement))) {
6703
+ this.placement = "start";
6704
+ }
6705
+ }
6706
+ updated(changedProperties) {
6707
+ super.updated(changedProperties);
6708
+ if (!changedProperties.has("open")) {
6709
+ return;
6710
+ }
6711
+ if (this.open) {
6712
+ this.previouslyFocusedElement = document.activeElement;
6713
+ this.focusPanel();
6714
+ } else if (this.previouslyFocusedElement) {
6715
+ this.previouslyFocusedElement.focus();
6716
+ this.previouslyFocusedElement = null;
6717
+ }
6718
+ }
6719
+ get panelElement() {
6720
+ return this.querySelector("[data-sp-offcanvas-native]");
6721
+ }
6722
+ // The panel's `visibility` transitions in from `hidden`, so it cannot take
6723
+ // focus until the slide-in finishes unless motion is disabled.
6724
+ focusPanel() {
6725
+ const panel = this.panelElement;
6726
+ const focusFirst = () => {
6727
+ const [first] = getFocusableElements(panel);
6728
+ (first ?? panel)?.focus();
6729
+ };
6730
+ focusFirst();
6731
+ if (panel && !panel.contains(document.activeElement)) {
6732
+ panel.addEventListener(
6733
+ "transitionend",
6734
+ () => {
6735
+ if (this.open) {
6736
+ focusFirst();
6737
+ }
6738
+ },
6739
+ { once: true }
6740
+ );
6741
+ }
6742
+ }
6743
+ close() {
6744
+ if (!this.open) {
6745
+ return;
6746
+ }
6747
+ this.open = false;
6748
+ this.dispatchEvent(new CustomEvent("sp-close", { bubbles: true }));
6749
+ }
6750
+ get hasHeading() {
6751
+ return this.projection.has("header") || Boolean(this.label);
6752
+ }
6753
+ get labelledBy() {
6754
+ if (this.forwardedAriaLabelledBy) {
6755
+ return this.forwardedAriaLabelledBy;
6756
+ }
6757
+ return this.hasHeading && !this.forwardedAriaLabel ? this.titleId : void 0;
6758
+ }
6759
+ render() {
6760
+ const open = this.open ?? false;
6761
+ return lit.html`<div
6762
+ aria-hidden="true"
6763
+ class="${spectreUi.getOffcanvasBackdropClasses({ open })}"
6764
+ data-sp-offcanvas-backdrop
6765
+ @click="${() => this.close()}"
6766
+ ></div>
6767
+ <div
6768
+ aria-describedby="${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}"
6769
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
6770
+ aria-labelledby="${ifDefined_js.ifDefined(this.labelledBy)}"
6771
+ aria-modal="true"
6772
+ class="${spectreUi.getOffcanvasClasses({
6773
+ open,
6774
+ placement: this.placement
6775
+ })}"
6776
+ data-sp-offcanvas-native
6777
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
6778
+ ?inert="${!open}"
6779
+ role="dialog"
6780
+ tabindex="-1"
6781
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
6782
+ >
6783
+ <div class="${spectreUi.getOffcanvasHeaderClasses()}">
6784
+ <div id="${ifDefined_js.ifDefined(this.hasHeading ? this.titleId : void 0)}">
6785
+ ${this.projection.has("header") ? this.projection.nodes("header") : this.label ?? lit.nothing}
6786
+ </div>
6787
+ <button
6788
+ aria-label="${this.closeLabel ?? "Close"}"
6789
+ class="${spectreUi.getButtonClasses({ size: "sm", variant: "ghost" })}"
6790
+ data-sp-offcanvas-close
6791
+ type="button"
6792
+ @click="${() => this.close()}"
6793
+ >
6794
+ ${renderIcon("close")}
6795
+ </button>
6796
+ </div>
6797
+ <div class="${spectreUi.getOffcanvasBodyClasses()}">
6798
+ ${this.projection.nodes()}
6799
+ </div>
6800
+ ${this.projection.has("footer") ? lit.html`<div class="${spectreUi.getOffcanvasFooterClasses()}">
6801
+ ${this.projection.nodes("footer")}
6802
+ </div>` : lit.nothing}
6803
+ </div>`;
6804
+ }
6805
+ };
6806
+ SpectreOffcanvasElement.properties = {
6807
+ closeLabel: { attribute: "close-label", type: String },
6808
+ label: { type: String },
6809
+ open: { type: Boolean, reflect: true },
6810
+ placement: { type: String, reflect: true }
6811
+ };
6812
+ function defineSpectreOffcanvas(tagName = "sp-offcanvas") {
6813
+ const existingElement = customElements.get(tagName);
6814
+ if (existingElement) {
6815
+ return existingElement;
6816
+ }
6817
+ customElements.define(tagName, SpectreOffcanvasElement);
6818
+ return SpectreOffcanvasElement;
6819
+ }
6820
+ var SpectreCarouselElement = class extends SpectreBaseElement {
6821
+ constructor() {
6822
+ super(...arguments);
6823
+ this.fade = false;
6824
+ this.hideControls = false;
6825
+ this.hideIndicators = false;
6826
+ this.index = 0;
6827
+ this.loop = false;
6828
+ this.nextLabel = "Next slide";
6829
+ this.previousLabel = "Previous slide";
6830
+ this.indexFromScroll = false;
6831
+ this.projection = new ProjectionController(this, [
6832
+ "data-sp-carousel-native"
6833
+ ]);
6834
+ this.handleKeydown = (event) => {
6835
+ if (event.key === "ArrowLeft") {
6836
+ event.preventDefault();
6837
+ this.goTo(this.activeIndex - 1);
6838
+ } else if (event.key === "ArrowRight") {
6839
+ event.preventDefault();
6840
+ this.goTo(this.activeIndex + 1);
6841
+ }
6842
+ };
6843
+ // Native swipes and scroll-snap move the viewport directly; follow them so
6844
+ // the indicators and controls stay in sync.
6845
+ this.handleScroll = (event) => {
6846
+ const viewport = event.currentTarget;
6847
+ if (this.fade || viewport.clientWidth === 0) {
6848
+ return;
6849
+ }
6850
+ const target = Math.round(viewport.scrollLeft / viewport.clientWidth);
6851
+ if (target === this.activeIndex || target >= this.slides.length) {
6852
+ return;
6853
+ }
6854
+ this.indexFromScroll = true;
6855
+ this.index = target;
6856
+ this.dispatchEvent(
6857
+ new CustomEvent("sp-change", { bubbles: true, detail: { index: target } })
6858
+ );
6859
+ };
6860
+ }
6861
+ get id() {
6862
+ return super.id;
6863
+ }
6864
+ set id(value) {
6865
+ super.id = value;
6866
+ }
6867
+ get title() {
6868
+ return super.title;
6869
+ }
6870
+ set title(value) {
6871
+ super.title = value;
6872
+ }
6873
+ connectedCallback() {
6874
+ var _a5;
6875
+ super.connectedCallback();
6876
+ (_a5 = this.style).display || (_a5.display = "block");
6877
+ }
6878
+ willUpdate(changedProperties) {
6879
+ if (changedProperties.has("fade") && this.fade == null) {
6880
+ this.fade = false;
6881
+ }
6882
+ if (changedProperties.has("hideControls") && this.hideControls == null) {
6883
+ this.hideControls = false;
6884
+ }
6885
+ if (changedProperties.has("hideIndicators") && this.hideIndicators == null) {
6886
+ this.hideIndicators = false;
6887
+ }
6888
+ if (changedProperties.has("index")) {
6889
+ this.index = normalizeInt(this.index, 0);
6890
+ }
6891
+ if (changedProperties.has("loop") && this.loop == null) {
6892
+ this.loop = false;
6893
+ }
6894
+ if (changedProperties.has("nextLabel") && !this.nextLabel) {
6895
+ this.nextLabel = "Next slide";
6896
+ }
6897
+ if (changedProperties.has("previousLabel") && !this.previousLabel) {
6898
+ this.previousLabel = "Previous slide";
6899
+ }
6900
+ }
6901
+ updated(changedProperties) {
6902
+ super.updated(changedProperties);
6903
+ this.slides.forEach((slide2) => {
6904
+ applyPartClasses(slide2.querySelectorAll("[slot]"), {
6905
+ caption: spectreUi.getCarouselCaptionClasses()
6906
+ });
6907
+ });
6908
+ const scrolledByUser = this.indexFromScroll;
6909
+ this.indexFromScroll = false;
6910
+ if (this.fade || scrolledByUser || !changedProperties.has("index")) {
6911
+ return;
6912
+ }
6913
+ const slide = this.slideWrappers[this.activeIndex];
6914
+ if (slide && typeof this.viewport?.scrollTo === "function") {
6915
+ this.viewport.scrollTo({ left: slide.offsetLeft });
6916
+ }
6917
+ }
6918
+ get slides() {
6919
+ return this.projection.elements();
6920
+ }
6921
+ get activeIndex() {
6922
+ const last = this.slides.length - 1;
6923
+ return Math.max(0, Math.min(this.index ?? 0, last));
6924
+ }
6925
+ get viewport() {
6926
+ return this.querySelector("[data-sp-carousel-viewport]");
6927
+ }
6928
+ get slideWrappers() {
6929
+ const viewport = this.viewport;
6930
+ if (!viewport) {
6931
+ return [];
6932
+ }
6933
+ return Array.from(viewport.children).filter(
6934
+ (child) => child.hasAttribute("data-sp-carousel-slide")
6935
+ );
6936
+ }
6937
+ goTo(target) {
6938
+ const count = this.slides.length;
6939
+ if (count === 0) {
6940
+ return;
6941
+ }
6942
+ let next = target;
6943
+ if (this.loop) {
6944
+ next = (target % count + count) % count;
6945
+ } else if (target < 0 || target >= count) {
6946
+ return;
6947
+ }
6948
+ if (next === this.activeIndex) {
6949
+ return;
6950
+ }
6951
+ this.index = next;
6952
+ this.dispatchEvent(
6953
+ new CustomEvent("sp-change", { bubbles: true, detail: { index: next } })
6954
+ );
6955
+ }
6956
+ get regionLabel() {
6957
+ if (this.forwardedAriaLabel) {
6958
+ return this.forwardedAriaLabel;
6959
+ }
6960
+ return this.forwardedAriaLabelledBy ? void 0 : "Carousel";
6961
+ }
6962
+ render() {
6963
+ const slides = this.slides;
6964
+ const count = slides.length;
6965
+ const active = this.activeIndex;
6966
+ const loop = this.loop ?? false;
6967
+ return lit.html`<div
6968
+ aria-label="${ifDefined_js.ifDefined(this.regionLabel)}"
6969
+ aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
6970
+ aria-roledescription="carousel"
6971
+ class="${spectreUi.getCarouselClasses({ fade: this.fade ?? false })}"
6972
+ data-sp-carousel-native
6973
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
6974
+ role="region"
6975
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
6976
+ @keydown="${this.handleKeydown}"
6977
+ >
6978
+ <div
6979
+ aria-live="polite"
6980
+ class="${spectreUi.getCarouselViewportClasses()}"
6981
+ data-sp-carousel-viewport
6982
+ @scroll="${this.handleScroll}"
6983
+ >
6984
+ ${slides.map(
6985
+ (slide, index) => lit.html`<div
6986
+ aria-label="${index + 1} of ${count}"
6987
+ aria-roledescription="slide"
6988
+ class="${spectreUi.getCarouselSlideClasses({ active: index === active })}"
6989
+ data-sp-carousel-slide
6990
+ role="group"
6991
+ >
6992
+ ${slide}
6993
+ </div>`
6994
+ )}
6995
+ </div>
6996
+ ${!this.hideControls && count > 1 ? lit.html`<button
6997
+ aria-label="${this.previousLabel ?? "Previous slide"}"
6998
+ class="${spectreUi.getCarouselControlClasses({ direction: "prev" })}"
6999
+ data-sp-carousel-prev
7000
+ ?disabled="${!loop && active === 0}"
7001
+ type="button"
7002
+ @click="${() => this.goTo(active - 1)}"
7003
+ >
7004
+ ${renderIcon("chevronLeft", "sp-icon-md")}
7005
+ </button>
7006
+ <button
7007
+ aria-label="${this.nextLabel ?? "Next slide"}"
7008
+ class="${spectreUi.getCarouselControlClasses({ direction: "next" })}"
7009
+ data-sp-carousel-next
7010
+ ?disabled="${!loop && active === count - 1}"
7011
+ type="button"
7012
+ @click="${() => this.goTo(active + 1)}"
7013
+ >
7014
+ ${renderIcon("chevronRight", "sp-icon-md")}
7015
+ </button>` : lit.nothing}
7016
+ ${!this.hideIndicators && count > 1 ? lit.html`<div class="${spectreUi.getCarouselIndicatorsClasses()}">
7017
+ ${slides.map(
7018
+ (_, index) => lit.html`<button
7019
+ aria-current="${ifDefined_js.ifDefined(
7020
+ index === active ? "true" : void 0
7021
+ )}"
7022
+ aria-label="Go to slide ${index + 1}"
7023
+ class="${spectreUi.getCarouselIndicatorClasses({
7024
+ active: index === active
7025
+ })}"
7026
+ data-sp-carousel-indicator
7027
+ type="button"
7028
+ @click="${() => this.goTo(index)}"
7029
+ ></button>`
7030
+ )}
7031
+ </div>` : lit.nothing}
7032
+ </div>`;
7033
+ }
7034
+ };
7035
+ SpectreCarouselElement.properties = {
7036
+ fade: { type: Boolean, reflect: true },
7037
+ hideControls: { attribute: "hide-controls", type: Boolean, reflect: true },
7038
+ hideIndicators: {
7039
+ attribute: "hide-indicators",
7040
+ type: Boolean,
7041
+ reflect: true
7042
+ },
7043
+ index: { type: Number, reflect: true },
7044
+ loop: { type: Boolean, reflect: true },
7045
+ nextLabel: { attribute: "next-label", type: String },
7046
+ previousLabel: { attribute: "previous-label", type: String }
7047
+ };
7048
+ function defineSpectreCarousel(tagName = "sp-carousel") {
7049
+ const existingElement = customElements.get(tagName);
7050
+ if (existingElement) {
7051
+ return existingElement;
7052
+ }
7053
+ customElements.define(tagName, SpectreCarouselElement);
7054
+ return SpectreCarouselElement;
7055
+ }
7056
+ var SpectreTableElement = class extends SpectreBaseElement {
7057
+ constructor() {
7058
+ super(...arguments);
7059
+ this.bordered = false;
7060
+ this.hoverable = false;
7061
+ this.size = "md";
7062
+ this.striped = false;
7063
+ this.appliedTableClasses = /* @__PURE__ */ new WeakMap();
7064
+ this.projection = new ProjectionController(this, [
7065
+ "data-sp-table-native"
7066
+ ]);
7067
+ }
7068
+ get id() {
7069
+ return super.id;
7070
+ }
7071
+ set id(value) {
7072
+ super.id = value;
7073
+ }
7074
+ get title() {
7075
+ return super.title;
7076
+ }
7077
+ set title(value) {
7078
+ super.title = value;
7079
+ }
7080
+ connectedCallback() {
7081
+ var _a5;
7082
+ super.connectedCallback();
7083
+ (_a5 = this.style).display || (_a5.display = "block");
7084
+ }
7085
+ willUpdate(changedProperties) {
7086
+ if (changedProperties.has("bordered") && this.bordered == null) {
7087
+ this.bordered = false;
7088
+ }
7089
+ if (changedProperties.has("hoverable") && this.hoverable == null) {
7090
+ this.hoverable = false;
7091
+ }
7092
+ if (changedProperties.has("size") && (this.size == null || !isTableSize(this.size))) {
7093
+ this.size = "md";
7094
+ }
7095
+ if (changedProperties.has("striped") && this.striped == null) {
7096
+ this.striped = false;
7097
+ }
7098
+ }
7099
+ // The authored <table> is styled in place: the HTML parser drops table
7100
+ // parts that are not inside a <table>, so the component cannot render one.
7101
+ updated(changedProperties) {
7102
+ super.updated(changedProperties);
7103
+ const classes = spectreUi.getTableClasses({
7104
+ bordered: this.bordered ?? false,
7105
+ hoverable: this.hoverable ?? false,
7106
+ size: this.size,
7107
+ striped: this.striped ?? false
7108
+ });
7109
+ this.projection.elements().filter((element) => element instanceof HTMLTableElement).forEach((table) => {
7110
+ replaceClasses(
7111
+ table,
7112
+ this.appliedTableClasses.get(table) ?? "",
7113
+ classes
7114
+ );
7115
+ this.appliedTableClasses.set(table, classes);
7116
+ table.querySelectorAll("tr").forEach((row) => this.styleRow(row));
7117
+ });
7118
+ }
7119
+ // Contextual rows opt in with `data-variant`; `aria-selected` is styled by
7120
+ // the recipe CSS directly.
7121
+ styleRow(row) {
7122
+ const variant = row.dataset.variant;
7123
+ const classes = isTableRowVariant(variant) ? spectreUi.getTableRowClasses({ variant }) : "";
7124
+ replaceClasses(row, this.appliedTableClasses.get(row) ?? "", classes);
7125
+ this.appliedTableClasses.set(row, classes);
7126
+ }
7127
+ render() {
7128
+ const labelled = Boolean(
7129
+ this.forwardedAriaLabel || this.forwardedAriaLabelledBy
7130
+ );
7131
+ return lit.html`<div
7132
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
7133
+ aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
7134
+ class="${spectreUi.getTableWrapperClasses()}"
7135
+ data-sp-table-native
7136
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
7137
+ role="${ifDefined_js.ifDefined(labelled ? "region" : void 0)}"
7138
+ tabindex="${ifDefined_js.ifDefined(labelled ? "0" : void 0)}"
7139
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
7140
+ >
7141
+ ${this.projection.nodes()}
7142
+ </div>`;
7143
+ }
7144
+ };
7145
+ SpectreTableElement.properties = {
7146
+ bordered: { type: Boolean, reflect: true },
7147
+ hoverable: { type: Boolean, reflect: true },
7148
+ size: { type: String, reflect: true },
7149
+ striped: { type: Boolean, reflect: true }
7150
+ };
7151
+ function defineSpectreTable(tagName = "sp-table") {
7152
+ const existingElement = customElements.get(tagName);
7153
+ if (existingElement) {
7154
+ return existingElement;
7155
+ }
7156
+ customElements.define(tagName, SpectreTableElement);
7157
+ return SpectreTableElement;
7158
+ }
7159
+ function pageRange(page, total, siblings) {
7160
+ const pages = (from, to) => Array.from({ length: to - from + 1 }, (_, index) => from + index);
7161
+ if (total <= siblings * 2 + 5) {
7162
+ return pages(1, total);
7163
+ }
7164
+ const left = Math.max(page - siblings, 1);
7165
+ const right = Math.min(page + siblings, total);
7166
+ const leftGap = left > 3;
7167
+ const rightGap = right < total - 2;
7168
+ const edgeCount = siblings * 2 + 3;
7169
+ if (!leftGap) {
7170
+ return [...pages(1, edgeCount), "ellipsis", total];
7171
+ }
7172
+ if (!rightGap) {
7173
+ return [1, "ellipsis", ...pages(total - edgeCount + 1, total)];
7174
+ }
7175
+ return [1, "ellipsis", ...pages(left, right), "ellipsis", total];
7176
+ }
7177
+ var SpectrePaginationElement = class extends SpectreBaseElement {
7178
+ constructor() {
7179
+ super(...arguments);
7180
+ this.hrefTemplate = void 0;
7181
+ this.nextLabel = "Next";
7182
+ this.page = 1;
7183
+ this.previousLabel = "Previous";
7184
+ this.siblings = 1;
7185
+ this.size = "md";
7186
+ this.total = 1;
7187
+ }
7188
+ get id() {
7189
+ return super.id;
7190
+ }
7191
+ set id(value) {
7192
+ super.id = value;
7193
+ }
7194
+ get title() {
7195
+ return super.title;
7196
+ }
7197
+ set title(value) {
7198
+ super.title = value;
7199
+ }
7200
+ connectedCallback() {
7201
+ var _a5;
7202
+ super.connectedCallback();
7203
+ (_a5 = this.style).display || (_a5.display = "block");
7204
+ }
7205
+ willUpdate(changedProperties) {
7206
+ if (changedProperties.has("total")) {
7207
+ this.total = normalizeInt(this.total, 1, 1);
7208
+ }
7209
+ if (changedProperties.has("page") || changedProperties.has("total")) {
7210
+ const page = normalizeInt(this.page, 1, 1) ?? 1;
7211
+ this.page = Math.min(page, this.total ?? 1);
7212
+ }
7213
+ if (changedProperties.has("siblings")) {
7214
+ this.siblings = normalizeInt(this.siblings, 1);
7215
+ }
7216
+ if (changedProperties.has("size") && (this.size == null || !isInputSize(this.size))) {
7217
+ this.size = "md";
7218
+ }
7219
+ if (changedProperties.has("previousLabel") && !this.previousLabel) {
7220
+ this.previousLabel = "Previous";
7221
+ }
7222
+ if (changedProperties.has("nextLabel") && !this.nextLabel) {
7223
+ this.nextLabel = "Next";
7224
+ }
7225
+ }
7226
+ get navLabel() {
7227
+ if (this.forwardedAriaLabel) {
7228
+ return this.forwardedAriaLabel;
7229
+ }
7230
+ return this.forwardedAriaLabelledBy ? void 0 : "Pagination";
7231
+ }
7232
+ goTo(target) {
7233
+ if (target === this.page || target < 1 || target > (this.total ?? 1)) {
7234
+ return;
7235
+ }
7236
+ this.page = target;
7237
+ this.dispatchEvent(
7238
+ new CustomEvent("sp-change", { bubbles: true, detail: { page: target } })
7239
+ );
7240
+ }
7241
+ renderItem(target, content, { active = false, disabled = false, label }) {
7242
+ const classes = spectreUi.getPaginationItemClasses({ active, disabled });
7243
+ const current = active ? "page" : void 0;
7244
+ if (this.hrefTemplate) {
7245
+ if (disabled) {
7246
+ return lit.html`<a aria-disabled="true" class="${classes}">${content}</a>`;
7247
+ }
7248
+ return lit.html`<a
7249
+ aria-current="${ifDefined_js.ifDefined(current)}"
7250
+ aria-label="${ifDefined_js.ifDefined(label)}"
7251
+ class="${classes}"
7252
+ href="${this.hrefTemplate.split("{page}").join(String(target))}"
7253
+ @click="${() => this.goTo(target)}"
7254
+ >${content}</a
7255
+ >`;
7256
+ }
7257
+ return lit.html`<button
7258
+ aria-current="${ifDefined_js.ifDefined(current)}"
7259
+ aria-label="${ifDefined_js.ifDefined(label)}"
7260
+ class="${classes}"
7261
+ ?disabled="${disabled}"
7262
+ type="button"
7263
+ @click="${() => this.goTo(target)}"
7264
+ >
7265
+ ${content}
7266
+ </button>`;
7267
+ }
7268
+ render() {
7269
+ const page = this.page ?? 1;
7270
+ const total = this.total ?? 1;
7271
+ return lit.html`<nav
7272
+ aria-label="${ifDefined_js.ifDefined(this.navLabel)}"
7273
+ aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
7274
+ data-sp-pagination-native
7275
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
7276
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
7277
+ >
7278
+ <ul
7279
+ class="${spectreUi.getPaginationClasses({ size: this.size })}"
7280
+ >
7281
+ <li>
7282
+ ${this.renderItem(page - 1, this.previousLabel ?? "Previous", {
7283
+ disabled: page <= 1
7284
+ })}
7285
+ </li>
7286
+ ${pageRange(page, total, this.siblings ?? 1).map(
7287
+ (entry) => entry === "ellipsis" ? lit.html`<li>
7288
+ <span
7289
+ aria-hidden="true"
7290
+ class="${spectreUi.getPaginationEllipsisClasses()}"
7291
+ >…</span
7292
+ >
7293
+ </li>` : lit.html`<li>
7294
+ ${this.renderItem(entry, entry, {
7295
+ active: entry === page,
7296
+ label: `Page ${entry}`
7297
+ })}
7298
+ </li>`
7299
+ )}
7300
+ <li>
7301
+ ${this.renderItem(page + 1, this.nextLabel ?? "Next", {
7302
+ disabled: page >= total
7303
+ })}
7304
+ </li>
7305
+ </ul>
7306
+ </nav>`;
7307
+ }
7308
+ };
7309
+ SpectrePaginationElement.properties = {
7310
+ hrefTemplate: { attribute: "href-template", type: String },
7311
+ nextLabel: { attribute: "next-label", type: String },
7312
+ page: { type: Number, reflect: true },
7313
+ previousLabel: { attribute: "previous-label", type: String },
7314
+ siblings: { type: Number },
7315
+ size: { type: String, reflect: true },
7316
+ total: { type: Number, reflect: true }
7317
+ };
7318
+ function defineSpectrePagination(tagName = "sp-pagination") {
7319
+ const existingElement = customElements.get(tagName);
7320
+ if (existingElement) {
7321
+ return existingElement;
7322
+ }
7323
+ customElements.define(tagName, SpectrePaginationElement);
7324
+ return SpectrePaginationElement;
7325
+ }
7326
+ var SpectreStepperElement = class extends SpectreBaseElement {
7327
+ constructor() {
7328
+ super(...arguments);
7329
+ this.current = 0;
7330
+ this.orientation = "horizontal";
7331
+ this.projection = new ProjectionController(this, [
7332
+ "data-sp-stepper-native"
7333
+ ]);
7334
+ }
7335
+ get id() {
7336
+ return super.id;
7337
+ }
7338
+ set id(value) {
7339
+ super.id = value;
7340
+ }
7341
+ get title() {
7342
+ return super.title;
7343
+ }
7344
+ set title(value) {
7345
+ super.title = value;
7346
+ }
7347
+ connectedCallback() {
7348
+ var _a5;
7349
+ super.connectedCallback();
7350
+ (_a5 = this.style).display || (_a5.display = "block");
7351
+ }
7352
+ willUpdate(changedProperties) {
7353
+ if (changedProperties.has("current")) {
7354
+ this.current = normalizeInt(this.current, 0);
7355
+ }
7356
+ if (changedProperties.has("orientation") && (this.orientation == null || !isStepperOrientation(this.orientation))) {
7357
+ this.orientation = "horizontal";
7358
+ }
7359
+ }
7360
+ stateFor(index) {
7361
+ const current = this.current ?? 0;
7362
+ if (index < current) {
7363
+ return "done";
7364
+ }
7365
+ return index === current ? "active" : "pending";
7366
+ }
7367
+ render() {
7368
+ return lit.html`<ol
7369
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
7370
+ aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
7371
+ class="${spectreUi.getStepperClasses({
7372
+ orientation: this.orientation
7373
+ })}"
7374
+ data-sp-stepper-native
7375
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
7376
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
7377
+ >
7378
+ ${this.projection.elements().map((step, index) => {
7379
+ const state = this.stateFor(index);
7380
+ return lit.html`<li
7381
+ aria-current="${ifDefined_js.ifDefined(state === "active" ? "step" : void 0)}"
7382
+ class="${spectreUi.getStepperStepClasses({ state })}"
7383
+ data-state="${state}"
7384
+ >
7385
+ <span aria-hidden="true" class="${spectreUi.getStepperIndicatorClasses()}"
7386
+ >${state === "done" ? renderIcon("check") : index + 1}</span
7387
+ >
7388
+ <span class="${spectreUi.getStepperLabelClasses()}">${step}</span>
7389
+ </li>`;
7390
+ })}
7391
+ </ol>`;
7392
+ }
7393
+ };
7394
+ SpectreStepperElement.properties = {
7395
+ current: { type: Number, reflect: true },
7396
+ orientation: { type: String, reflect: true }
7397
+ };
7398
+ function defineSpectreStepper(tagName = "sp-stepper") {
7399
+ const existingElement = customElements.get(tagName);
7400
+ if (existingElement) {
7401
+ return existingElement;
7402
+ }
7403
+ customElements.define(tagName, SpectreStepperElement);
7404
+ return SpectreStepperElement;
7405
+ }
7406
+ var SpectreCardBleedElement = class extends SpectreBaseElement {
7407
+ constructor() {
7408
+ super(...arguments);
7409
+ this.edges = void 0;
7410
+ this.padded = void 0;
7411
+ this.projection = new ProjectionController(this, [
7412
+ "data-sp-card-bleed-native"
7413
+ ]);
7414
+ }
7415
+ get id() {
7416
+ return super.id;
7417
+ }
7418
+ set id(value) {
7419
+ super.id = value;
7420
+ }
7421
+ get title() {
7422
+ return super.title;
7423
+ }
7424
+ set title(value) {
7425
+ super.title = value;
7426
+ }
7427
+ connectedCallback() {
7428
+ var _a5;
7429
+ super.connectedCallback();
7430
+ (_a5 = this.style).display || (_a5.display = "block");
7431
+ }
7432
+ willUpdate(changedProperties) {
7433
+ if (changedProperties.has("padded") && this.padded != null) {
7434
+ const padded = this.padded;
7435
+ this.padded = padded === "" ? "md" : isSpacingStep(padded) ? padded : void 0;
7436
+ }
7437
+ }
7438
+ // `edges` is a space-separated list of edges, or `all`.
7439
+ get bleedEdges() {
7440
+ const tokens = (this.edges ?? "").split(/\s+/).filter(Boolean);
7441
+ if (tokens.includes("all")) {
7442
+ return "all";
7443
+ }
7444
+ return tokens.filter(
7445
+ (token) => isAccentEdge(token)
7446
+ );
7447
+ }
7448
+ render() {
7449
+ return lit.html`<div
7450
+ class="${spectreUi.getCardBleedClasses({
7451
+ edges: this.bleedEdges,
7452
+ ...this.padded != null && {
7453
+ padded: this.padded
7454
+ }
7455
+ })}"
7456
+ data-sp-card-bleed-native
7457
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
7458
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
7459
+ >
7460
+ ${this.projection.nodes()}
7461
+ </div>`;
7462
+ }
7463
+ };
7464
+ SpectreCardBleedElement.properties = {
7465
+ edges: { type: String, reflect: true },
7466
+ padded: { type: String, reflect: true }
7467
+ };
7468
+ function defineSpectreCardBleed(tagName = "sp-card-bleed") {
7469
+ const existingElement = customElements.get(tagName);
7470
+ if (existingElement) {
7471
+ return existingElement;
7472
+ }
7473
+ customElements.define(tagName, SpectreCardBleedElement);
7474
+ return SpectreCardBleedElement;
7475
+ }
7476
+ var SpectreProseElement = class extends SpectreBaseElement {
7477
+ constructor() {
7478
+ super(...arguments);
7479
+ this.projection = new ProjectionController(this, [
7480
+ "data-sp-prose-native"
7481
+ ]);
7482
+ }
7483
+ get id() {
7484
+ return super.id;
7485
+ }
7486
+ set id(value) {
7487
+ super.id = value;
7488
+ }
7489
+ get title() {
7490
+ return super.title;
7491
+ }
7492
+ set title(value) {
7493
+ super.title = value;
7494
+ }
7495
+ connectedCallback() {
7496
+ var _a5;
7497
+ super.connectedCallback();
7498
+ (_a5 = this.style).display || (_a5.display = "block");
7499
+ }
7500
+ render() {
7501
+ return lit.html`<div
7502
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
7503
+ class="${spectreUi.getProseClasses()}"
7504
+ data-sp-prose-native
7505
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
7506
+ role="${ifDefined_js.ifDefined(this.forwardedAriaLabel ? "region" : void 0)}"
7507
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
7508
+ >
7509
+ ${this.projection.nodes()}
7510
+ </div>`;
7511
+ }
7512
+ };
7513
+ function defineSpectreProse(tagName = "sp-prose") {
7514
+ const existingElement = customElements.get(tagName);
7515
+ if (existingElement) {
7516
+ return existingElement;
7517
+ }
7518
+ customElements.define(tagName, SpectreProseElement);
7519
+ return SpectreProseElement;
7520
+ }
7521
+ var SpectreProgressElement = class extends SpectreBaseElement {
7522
+ constructor() {
7523
+ super(...arguments);
7524
+ this.indeterminate = false;
7525
+ this.label = void 0;
7526
+ this.max = 100;
7527
+ this.size = "md";
7528
+ this.value = 0;
7529
+ this.valueText = void 0;
7530
+ this.variant = "brand";
7531
+ this.labelId = `${createUniqueId("sp-progress")}-label`;
7532
+ }
7533
+ get id() {
7534
+ return super.id;
7535
+ }
7536
+ set id(value) {
7537
+ super.id = value;
7538
+ }
7539
+ get title() {
7540
+ return super.title;
7541
+ }
7542
+ set title(value) {
7543
+ super.title = value;
7544
+ }
7545
+ connectedCallback() {
7546
+ var _a5;
7547
+ super.connectedCallback();
7548
+ (_a5 = this.style).display || (_a5.display = "block");
7549
+ }
7550
+ willUpdate(changedProperties) {
7551
+ if (changedProperties.has("indeterminate") && this.indeterminate == null) {
7552
+ this.indeterminate = false;
7553
+ }
7554
+ if (changedProperties.has("max") && (typeof this.max !== "number" || !(this.max > 0))) {
7555
+ this.max = 100;
7556
+ }
7557
+ if (changedProperties.has("value") || changedProperties.has("max")) {
7558
+ const value = typeof this.value === "number" ? this.value : 0;
7559
+ this.value = Math.min(Math.max(value, 0), this.max ?? 100);
7560
+ }
7561
+ if (changedProperties.has("size") && (this.size == null || !isInputSize(this.size))) {
7562
+ this.size = "md";
7563
+ }
7564
+ if (changedProperties.has("variant") && (this.variant == null || !isProgressVariant(this.variant))) {
7565
+ this.variant = "brand";
7566
+ }
7567
+ }
7568
+ get percent() {
7569
+ return (this.value ?? 0) / (this.max ?? 100) * 100;
7570
+ }
7571
+ get labelledBy() {
7572
+ if (this.forwardedAriaLabelledBy) {
7573
+ return this.forwardedAriaLabelledBy;
7574
+ }
7575
+ return this.label && !this.forwardedAriaLabel ? this.labelId : void 0;
7576
+ }
7577
+ render() {
7578
+ const indeterminate = this.indeterminate ?? false;
7579
+ return lit.html`${this.label ? lit.html`<span class="${spectreUi.getProgressLabelClasses()}" id="${this.labelId}"
7580
+ >${this.label}</span
7581
+ >` : lit.nothing}
7582
+ <div
7583
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
7584
+ aria-labelledby="${ifDefined_js.ifDefined(this.labelledBy)}"
7585
+ aria-valuemax="${this.max ?? 100}"
7586
+ aria-valuemin="0"
7587
+ aria-valuenow="${ifDefined_js.ifDefined(indeterminate ? void 0 : this.value)}"
7588
+ aria-valuetext="${ifDefined_js.ifDefined(this.valueText || void 0)}"
7589
+ class="${spectreUi.getProgressClasses({ size: this.size })}"
7590
+ data-sp-progress-native
7591
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
7592
+ role="progressbar"
7593
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
7594
+ >
7595
+ <div
7596
+ class="${spectreUi.getProgressBarClasses({
7597
+ indeterminate,
7598
+ variant: this.variant
7599
+ })}"
7600
+ data-sp-progress-bar
7601
+ style="${styleMap_js.styleMap(indeterminate ? {} : { width: `${this.percent}%` })}"
7602
+ ></div>
7603
+ </div>`;
7604
+ }
7605
+ };
7606
+ SpectreProgressElement.properties = {
7607
+ indeterminate: { type: Boolean, reflect: true },
7608
+ label: { type: String },
7609
+ max: { type: Number, reflect: true },
7610
+ size: { type: String, reflect: true },
7611
+ value: { type: Number, reflect: true },
7612
+ valueText: { attribute: "value-text", type: String },
7613
+ variant: { type: String, reflect: true }
7614
+ };
7615
+ function defineSpectreProgress(tagName = "sp-progress") {
7616
+ const existingElement = customElements.get(tagName);
7617
+ if (existingElement) {
7618
+ return existingElement;
7619
+ }
7620
+ customElements.define(tagName, SpectreProgressElement);
7621
+ return SpectreProgressElement;
7622
+ }
7623
+ var SpectreSwitchElement = class extends SpectreBaseElement {
7624
+ constructor() {
7625
+ super(...arguments);
7626
+ this.checked = false;
7627
+ this.disabled = false;
7628
+ this.focused = false;
7629
+ this.form = void 0;
7630
+ this.label = void 0;
7631
+ this.name = void 0;
7632
+ this.required = false;
7633
+ this.size = "md";
7634
+ this.value = "on";
7635
+ this.projection = new ProjectionController(this, [
7636
+ "data-sp-switch-label"
7637
+ ]);
7638
+ }
7639
+ get id() {
7640
+ return super.id;
7641
+ }
7642
+ set id(value) {
7643
+ super.id = value;
7644
+ }
7645
+ get title() {
7646
+ return super.title;
7647
+ }
7648
+ set title(value) {
7649
+ super.title = value;
7650
+ }
7651
+ willUpdate(changedProperties) {
7652
+ if (changedProperties.has("checked") && this.checked == null) {
7653
+ this.checked = false;
7654
+ }
7655
+ if (changedProperties.has("disabled") && this.disabled == null) {
7656
+ this.disabled = false;
7657
+ }
7658
+ if (changedProperties.has("required") && this.required == null) {
7659
+ this.required = false;
7660
+ }
7661
+ if (changedProperties.has("size") && (this.size == null || !isInputSize(this.size))) {
7662
+ this.size = "md";
7663
+ }
7664
+ }
7665
+ get nativeInput() {
7666
+ return this.querySelector("[data-sp-switch-native]");
7667
+ }
7668
+ focus(options) {
7669
+ this.nativeInput?.focus(options);
7670
+ }
7671
+ blur() {
7672
+ this.nativeInput?.blur();
7673
+ }
7674
+ handleChange(event) {
7675
+ this.checked = event.currentTarget.checked;
7676
+ }
7677
+ render() {
7678
+ const disabled = this.disabled ?? false;
7679
+ const labelContent = this.projection.has() ? this.projection.nodes() : this.label ? lit.html`<span
7680
+ class="${spectreUi.getInputLabelClasses({ disabled })}"
7681
+ data-sp-switch-label-fallback
7682
+ >${this.label}</span
7683
+ >` : lit.nothing;
7684
+ return lit.html`<label data-sp-switch-label>
7685
+ <input
7686
+ aria-describedby="${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}"
7687
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
7688
+ aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
7689
+ .checked="${live_js.live(this.checked ?? false)}"
7690
+ class="${spectreUi.getSwitchClasses({
7691
+ focused: this.focused ?? false,
7692
+ size: this.size
7693
+ })}"
7694
+ data-sp-switch-native
7695
+ ?disabled="${disabled}"
7696
+ form="${ifDefined_js.ifDefined(this.form || void 0)}"
7697
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
7698
+ name="${ifDefined_js.ifDefined(this.name || void 0)}"
7699
+ ?required="${this.required ?? false}"
7700
+ role="switch"
7701
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
7702
+ type="checkbox"
7703
+ value="${ifDefined_js.ifDefined(this.value)}"
7704
+ @change="${this.handleChange}"
7705
+ />
7706
+ ${labelContent}
7707
+ </label>`;
7708
+ }
7709
+ };
7710
+ SpectreSwitchElement.properties = {
7711
+ checked: { type: Boolean, reflect: true },
7712
+ disabled: { type: Boolean, reflect: true },
7713
+ focused: { type: Boolean, reflect: true },
7714
+ form: { type: String },
7715
+ label: { type: String },
7716
+ name: { type: String, reflect: true },
7717
+ required: { type: Boolean, reflect: true },
7718
+ size: { type: String, reflect: true },
7719
+ value: { type: String }
7720
+ };
7721
+ function defineSpectreSwitch(tagName = "sp-switch") {
7722
+ const existingElement = customElements.get(tagName);
7723
+ if (existingElement) {
7724
+ return existingElement;
7725
+ }
7726
+ customElements.define(tagName, SpectreSwitchElement);
7727
+ return SpectreSwitchElement;
7728
+ }
7729
+ var SpectreRangeElement = class extends SpectreBaseElement {
7730
+ constructor() {
7731
+ super(...arguments);
7732
+ this.disabled = false;
7733
+ this.focused = false;
7734
+ this.form = void 0;
7735
+ this.max = 100;
7736
+ this.min = 0;
7737
+ this.name = void 0;
7738
+ this.step = 1;
7739
+ this.value = 50;
7740
+ }
7741
+ get id() {
7742
+ return super.id;
7743
+ }
7744
+ set id(value) {
7745
+ super.id = value;
7746
+ }
7747
+ get title() {
7748
+ return super.title;
7749
+ }
7750
+ set title(value) {
7751
+ super.title = value;
7752
+ }
7753
+ willUpdate(changedProperties) {
7754
+ if (changedProperties.has("disabled") && this.disabled == null) {
7755
+ this.disabled = false;
7756
+ }
7757
+ if (changedProperties.has("min") && typeof this.min !== "number") {
7758
+ this.min = 0;
7759
+ }
7760
+ if (changedProperties.has("max") && (typeof this.max !== "number" || this.max <= (this.min ?? 0))) {
7761
+ this.max = (this.min ?? 0) + 100;
7762
+ }
7763
+ if (changedProperties.has("value") || changedProperties.has("min") || changedProperties.has("max")) {
7764
+ const value = typeof this.value === "number" ? this.value : 0;
7765
+ this.value = Math.min(Math.max(value, this.min ?? 0), this.max ?? 100);
7766
+ }
7767
+ }
7768
+ // WebKit/Blink paint the filled track from this recipe-defined variable;
7769
+ // Firefox fills natively.
7770
+ updated(changedProperties) {
7771
+ super.updated(changedProperties);
7772
+ const min = this.min ?? 0;
7773
+ const span = (this.max ?? 100) - min;
7774
+ const percent = span > 0 ? ((this.value ?? min) - min) / span * 100 : 0;
7775
+ this.nativeInput?.style.setProperty(
7776
+ "--sp-component-range-value",
7777
+ `${percent}%`
7778
+ );
7779
+ }
7780
+ get nativeInput() {
7781
+ return this.querySelector("[data-sp-range-native]");
7782
+ }
7783
+ focus(options) {
7784
+ this.nativeInput?.focus(options);
7785
+ }
7786
+ blur() {
7787
+ this.nativeInput?.blur();
7788
+ }
7789
+ handleInput(event) {
7790
+ this.value = event.currentTarget.valueAsNumber;
7791
+ }
7792
+ render() {
7793
+ return lit.html`<input
7794
+ aria-describedby="${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}"
7795
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
7796
+ aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
7797
+ class="${spectreUi.getRangeClasses({
7798
+ disabled: this.disabled ?? false,
7799
+ focused: this.focused ?? false
7800
+ })}"
7801
+ data-sp-range-native
7802
+ ?disabled="${this.disabled ?? false}"
7803
+ form="${ifDefined_js.ifDefined(this.form || void 0)}"
7804
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
7805
+ max="${this.max ?? 100}"
7806
+ min="${this.min ?? 0}"
7807
+ name="${ifDefined_js.ifDefined(this.name || void 0)}"
7808
+ step="${this.step ?? 1}"
7809
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
7810
+ type="range"
7811
+ .value="${live_js.live(String(this.value ?? 0))}"
7812
+ @change="${this.handleInput}"
7813
+ @input="${this.handleInput}"
7814
+ />`;
7815
+ }
7816
+ };
7817
+ SpectreRangeElement.properties = {
7818
+ disabled: { type: Boolean, reflect: true },
7819
+ focused: { type: Boolean, reflect: true },
7820
+ form: { type: String },
7821
+ max: { type: Number, reflect: true },
7822
+ min: { type: Number, reflect: true },
7823
+ name: { type: String, reflect: true },
7824
+ step: { type: Number, reflect: true },
7825
+ value: { type: Number, reflect: true }
7826
+ };
7827
+ function defineSpectreRange(tagName = "sp-range") {
7828
+ const existingElement = customElements.get(tagName);
7829
+ if (existingElement) {
7830
+ return existingElement;
7831
+ }
7832
+ customElements.define(tagName, SpectreRangeElement);
7833
+ return SpectreRangeElement;
7834
+ }
7835
+ var SpectreFileInputElement = class extends SpectreBaseElement {
7836
+ constructor() {
7837
+ super(...arguments);
7838
+ this.accept = void 0;
7839
+ this.disabled = false;
7840
+ this.focused = false;
7841
+ this.form = void 0;
7842
+ this.fullWidth = false;
7843
+ this.invalid = false;
7844
+ this.multiple = false;
7845
+ this.name = void 0;
7846
+ this.required = false;
7847
+ this.size = "md";
7848
+ this.success = false;
7849
+ }
7850
+ get id() {
7851
+ return super.id;
7852
+ }
7853
+ set id(value) {
7854
+ super.id = value;
7855
+ }
7856
+ get title() {
7857
+ return super.title;
7858
+ }
7859
+ set title(value) {
7860
+ super.title = value;
7861
+ }
7862
+ willUpdate(changedProperties) {
7863
+ if (changedProperties.has("size") && (this.size == null || !isInputSize(this.size))) {
7864
+ this.size = "md";
7865
+ }
7866
+ }
7867
+ get nativeInput() {
7868
+ return this.querySelector("[data-sp-file-input-native]");
7869
+ }
7870
+ get files() {
7871
+ return this.nativeInput?.files ?? null;
7872
+ }
7873
+ focus(options) {
7874
+ this.nativeInput?.focus(options);
7875
+ }
7876
+ blur() {
7877
+ this.nativeInput?.blur();
7878
+ }
7879
+ render() {
7880
+ const state = this.invalid ? "invalid" : this.success ? "success" : "default";
7881
+ return lit.html`<input
7882
+ accept="${ifDefined_js.ifDefined(this.accept || void 0)}"
7883
+ aria-describedby="${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}"
7884
+ aria-invalid="${ifDefined_js.ifDefined(this.invalid ? "true" : void 0)}"
7885
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
7886
+ aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
7887
+ class="${spectreUi.getFileInputClasses({
7888
+ disabled: this.disabled ?? false,
7889
+ focused: this.focused ?? false,
7890
+ fullWidth: this.fullWidth ?? false,
7891
+ size: this.size,
7892
+ state
7893
+ })}"
7894
+ data-sp-file-input-native
7895
+ ?disabled="${this.disabled ?? false}"
7896
+ form="${ifDefined_js.ifDefined(this.form || void 0)}"
7897
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
7898
+ ?multiple="${this.multiple ?? false}"
7899
+ name="${ifDefined_js.ifDefined(this.name || void 0)}"
7900
+ ?required="${this.required ?? false}"
7901
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
7902
+ type="file"
7903
+ />`;
7904
+ }
7905
+ };
7906
+ SpectreFileInputElement.properties = {
7907
+ accept: { type: String, reflect: true },
7908
+ disabled: { type: Boolean, reflect: true },
7909
+ focused: { type: Boolean, reflect: true },
7910
+ form: { type: String },
7911
+ fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
7912
+ invalid: { type: Boolean, reflect: true },
7913
+ multiple: { type: Boolean, reflect: true },
7914
+ name: { type: String, reflect: true },
7915
+ required: { type: Boolean, reflect: true },
7916
+ size: { type: String, reflect: true },
7917
+ success: { type: Boolean, reflect: true }
7918
+ };
7919
+ function defineSpectreFileInput(tagName = "sp-file-input") {
7920
+ const existingElement = customElements.get(tagName);
7921
+ if (existingElement) {
7922
+ return existingElement;
7923
+ }
7924
+ customElements.define(tagName, SpectreFileInputElement);
7925
+ return SpectreFileInputElement;
7926
+ }
7927
+ var SpectreExternalAuthButtonElement = class extends SpectreBaseElement {
7928
+ constructor() {
7929
+ super(...arguments);
7930
+ this.active = false;
7931
+ this.focused = false;
7932
+ this.hovered = false;
7933
+ this.disabled = false;
7934
+ this.fullWidth = false;
7935
+ this.href = void 0;
7936
+ this.loading = false;
7937
+ this.type = "button";
7938
+ this.projection = new ProjectionController(this, [
7939
+ "data-sp-external-auth-button-native"
7940
+ ]);
7941
+ }
7942
+ get id() {
7943
+ return super.id;
7944
+ }
7945
+ set id(value) {
7946
+ super.id = value;
7947
+ }
7948
+ get title() {
7949
+ return super.title;
7950
+ }
7951
+ set title(value) {
7952
+ super.title = value;
7953
+ }
7954
+ willUpdate(changedProperties) {
7955
+ if (changedProperties.has("type") && this.type !== "button" && this.type !== "submit") {
7956
+ this.type = "button";
7957
+ }
7958
+ }
7959
+ get nativeElement() {
7960
+ return this.querySelector("[data-sp-external-auth-button-native]");
7961
+ }
7962
+ focus(options) {
7963
+ this.nativeElement?.focus(options);
7964
+ }
7965
+ blur() {
7966
+ this.nativeElement?.blur();
7967
+ }
7968
+ // A submit button inside a light-DOM form submits natively.
7969
+ render() {
7970
+ const classes = spectreUi.getExternalAuthButtonClasses({
7971
+ ...interactionStates(this),
7972
+ disabled: this.isDisabled,
7973
+ fullWidth: this.fullWidth ?? false,
7974
+ loading: this.loading ?? false
7975
+ });
7976
+ const content = lit.html`${this.projection.has("icon") ? lit.html`<span class="${spectreUi.getExternalAuthButtonIconClasses()}"
7977
+ >${this.projection.nodes("icon")}</span
7978
+ >` : lit.nothing}${this.projection.nodes()}`;
7979
+ if (this.href) {
7980
+ return lit.html`<a
7981
+ aria-busy="${ifDefined_js.ifDefined(this.loading ? "true" : void 0)}"
7982
+ aria-disabled="${ifDefined_js.ifDefined(this.isDisabled ? "true" : void 0)}"
7983
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
7984
+ class="${classes}"
7985
+ data-sp-external-auth-button-native
7986
+ href="${ifDefined_js.ifDefined(this.isDisabled ? void 0 : this.href)}"
7987
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
7988
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
7989
+ >${content}</a
7990
+ >`;
7991
+ }
7992
+ return lit.html`<button
7993
+ aria-busy="${ifDefined_js.ifDefined(this.loading ? "true" : void 0)}"
7994
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
7995
+ class="${classes}"
7996
+ data-sp-external-auth-button-native
7997
+ ?disabled="${this.isDisabled}"
7998
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
7999
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
8000
+ type="${this.type ?? "button"}"
8001
+ >
8002
+ ${content}
8003
+ </button>`;
8004
+ }
8005
+ };
8006
+ SpectreExternalAuthButtonElement.properties = {
8007
+ ...interactionStateProperties,
8008
+ disabled: { type: Boolean, reflect: true },
8009
+ fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
8010
+ href: { type: String },
8011
+ loading: { type: Boolean, reflect: true },
8012
+ type: { type: String }
8013
+ };
8014
+ function defineSpectreExternalAuthButton(tagName = "sp-external-auth-button") {
8015
+ const existingElement = customElements.get(tagName);
8016
+ if (existingElement) {
8017
+ return existingElement;
8018
+ }
8019
+ customElements.define(tagName, SpectreExternalAuthButtonElement);
8020
+ return SpectreExternalAuthButtonElement;
8021
+ }
8022
+ function owningCard(input) {
8023
+ let node = input.parentElement;
8024
+ while (node && !isSpectreKind(node, "choice-card")) {
8025
+ node = node.parentElement;
8026
+ }
8027
+ return node;
8028
+ }
8029
+ var _a4, _b4;
8030
+ var SpectreChoiceCardElement = class extends (_b4 = SpectreBaseElement, _a4 = spectreKindKey, _b4) {
8031
+ constructor() {
8032
+ super(...arguments);
8033
+ this[_a4] = "choice-card";
8034
+ this.focused = false;
8035
+ this.hovered = false;
8036
+ this.checked = false;
8037
+ this.disabled = false;
8038
+ this.form = void 0;
8039
+ this.name = void 0;
8040
+ this.required = false;
8041
+ this.type = "radio";
8042
+ this.value = void 0;
8043
+ this.projection = new ProjectionController(this, [
8044
+ "data-sp-choice-card-native"
8045
+ ]);
8046
+ }
8047
+ get id() {
8048
+ return super.id;
8049
+ }
8050
+ set id(value) {
8051
+ super.id = value;
8052
+ }
8053
+ get title() {
8054
+ return super.title;
8055
+ }
8056
+ set title(value) {
8057
+ super.title = value;
8058
+ }
8059
+ connectedCallback() {
8060
+ var _a5;
8061
+ super.connectedCallback();
8062
+ (_a5 = this.style).display || (_a5.display = "block");
8063
+ }
8064
+ willUpdate(changedProperties) {
8065
+ if (changedProperties.has("checked") && this.checked == null) {
8066
+ this.checked = false;
8067
+ }
8068
+ if (changedProperties.has("disabled") && this.disabled == null) {
8069
+ this.disabled = false;
8070
+ }
8071
+ if (changedProperties.has("type") && this.type !== "radio" && this.type !== "checkbox") {
8072
+ this.type = "radio";
8073
+ }
8074
+ }
8075
+ get nativeInput() {
8076
+ return this.querySelector("[data-sp-choice-card-input]");
8077
+ }
8078
+ focus(options) {
8079
+ this.nativeInput?.focus(options);
8080
+ }
8081
+ blur() {
8082
+ this.nativeInput?.blur();
8083
+ }
8084
+ // Checking a radio unchecks its group natively; mirror that onto the other
8085
+ // cards' `checked` properties.
8086
+ handleChange(event) {
8087
+ const input = event.currentTarget;
8088
+ this.checked = input.checked;
8089
+ if (this.type !== "radio" || !this.name) {
8090
+ return;
8091
+ }
8092
+ const root = this.getRootNode();
8093
+ root.querySelectorAll("input[data-sp-choice-card-input]").forEach((other) => {
8094
+ if (other === input || other.name !== this.name) {
8095
+ return;
8096
+ }
8097
+ const card = owningCard(other);
8098
+ if (card) {
8099
+ card.checked = other.checked;
8100
+ }
8101
+ });
8102
+ }
8103
+ render() {
8104
+ return lit.html`<label
8105
+ class="${spectreUi.getChoiceCardClasses({
8106
+ ...hoverFocusStates(this),
8107
+ disabled: this.disabled ?? false
8108
+ })}"
8109
+ data-sp-choice-card-native
8110
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
8111
+ >
8112
+ <input
8113
+ aria-describedby="${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}"
8114
+ .checked="${live_js.live(this.checked ?? false)}"
8115
+ data-sp-choice-card-input
8116
+ ?disabled="${this.disabled ?? false}"
8117
+ form="${ifDefined_js.ifDefined(this.form || void 0)}"
8118
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
8119
+ name="${ifDefined_js.ifDefined(this.name || void 0)}"
8120
+ ?required="${this.required ?? false}"
8121
+ type="${this.type ?? "radio"}"
8122
+ value="${ifDefined_js.ifDefined(this.value)}"
8123
+ @change="${this.handleChange}"
8124
+ />
8125
+ <span data-sp-choice-card-content>${this.projection.nodes()}</span>
8126
+ </label>`;
8127
+ }
8128
+ };
8129
+ SpectreChoiceCardElement.properties = {
8130
+ ...hoverFocusStateProperties,
8131
+ checked: { type: Boolean, reflect: true },
8132
+ disabled: { type: Boolean, reflect: true },
8133
+ form: { type: String },
8134
+ name: { type: String, reflect: true },
8135
+ required: { type: Boolean, reflect: true },
8136
+ type: { type: String, reflect: true },
8137
+ value: { type: String }
8138
+ };
8139
+ function defineSpectreChoiceCard(tagName = "sp-choice-card") {
8140
+ const existingElement = customElements.get(tagName);
8141
+ if (existingElement) {
8142
+ return existingElement;
8143
+ }
8144
+ customElements.define(tagName, SpectreChoiceCardElement);
8145
+ return SpectreChoiceCardElement;
8146
+ }
8147
+ function controlClasses(element) {
8148
+ if (element instanceof HTMLInputElement) {
8149
+ return element.type === "file" ? spectreUi.getFileInputClasses() : spectreUi.getInputClasses();
8150
+ }
8151
+ if (element instanceof HTMLSelectElement) {
8152
+ return spectreUi.getSelectClasses();
8153
+ }
8154
+ if (element instanceof HTMLButtonElement) {
8155
+ return spectreUi.getButtonClasses({ variant: "secondary" });
8156
+ }
8157
+ return void 0;
8158
+ }
8159
+ var SpectreInputGroupElement = class extends SpectreBaseElement {
8160
+ constructor() {
8161
+ super(...arguments);
8162
+ this.disabled = false;
8163
+ this.projection = new ProjectionController(this, [
8164
+ "data-sp-input-group-native"
8165
+ ]);
8166
+ }
8167
+ get id() {
8168
+ return super.id;
8169
+ }
8170
+ set id(value) {
8171
+ super.id = value;
8172
+ }
8173
+ get title() {
8174
+ return super.title;
8175
+ }
8176
+ set title(value) {
8177
+ super.title = value;
8178
+ }
8179
+ connectedCallback() {
8180
+ var _a5;
8181
+ super.connectedCallback();
8182
+ (_a5 = this.style).display || (_a5.display = "block");
8183
+ }
8184
+ // Native controls without an author-chosen `sp-*` class get their recipe
8185
+ // class; `slot="addon"` children become addons.
8186
+ updated(changedProperties) {
8187
+ super.updated(changedProperties);
8188
+ this.projection.elements().forEach((element) => {
8189
+ const styled = Array.from(element.classList).some(
8190
+ (name) => name.startsWith("sp-")
8191
+ );
8192
+ const classes = styled ? void 0 : controlClasses(element);
8193
+ if (classes) {
8194
+ element.classList.add(...classes.split(/\s+/).filter(Boolean));
8195
+ }
8196
+ });
8197
+ applyPartClasses(this.projection.elements("addon"), {
8198
+ addon: spectreUi.getInputGroupAddonClasses()
8199
+ });
8200
+ }
8201
+ render() {
8202
+ return lit.html`<div
8203
+ aria-disabled="${ifDefined_js.ifDefined(this.disabled ? "true" : void 0)}"
8204
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
8205
+ aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
8206
+ class="${spectreUi.getInputGroupClasses({ disabled: this.disabled ?? false })}"
8207
+ data-sp-input-group-native
8208
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
8209
+ role="group"
8210
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
8211
+ >
8212
+ ${this.projection.all()}
8213
+ </div>`;
8214
+ }
8215
+ };
8216
+ SpectreInputGroupElement.properties = {
8217
+ disabled: { type: Boolean, reflect: true }
8218
+ };
8219
+ function defineSpectreInputGroup(tagName = "sp-input-group") {
8220
+ const existingElement = customElements.get(tagName);
8221
+ if (existingElement) {
8222
+ return existingElement;
8223
+ }
8224
+ customElements.define(tagName, SpectreInputGroupElement);
8225
+ return SpectreInputGroupElement;
8226
+ }
8227
+ var SpectrePopoverElement = class extends SpectreBaseElement {
8228
+ constructor() {
8229
+ super(...arguments);
8230
+ this.label = void 0;
8231
+ this.open = false;
8232
+ this.placement = "bottom";
8233
+ this.triggerLabel = "Show details";
8234
+ this.baseId = createUniqueId("sp-popover");
8235
+ this.projection = new ProjectionController(this, [
8236
+ "data-sp-popover-trigger",
8237
+ "data-sp-popover-native"
8238
+ ]);
8239
+ this.handleDocumentClick = (event) => {
8240
+ if (this.open && !event.composedPath().includes(this)) {
8241
+ this.setOpen(false);
8242
+ }
8243
+ };
8244
+ this.handleDocumentKeydown = (event) => {
8245
+ if (event.key === "Escape" && this.open) {
8246
+ this.setOpen(false);
8247
+ this.triggerElement?.focus();
8248
+ }
8249
+ };
8250
+ }
8251
+ get id() {
8252
+ return super.id;
8253
+ }
8254
+ set id(value) {
8255
+ super.id = value;
8256
+ }
8257
+ get title() {
8258
+ return super.title;
8259
+ }
8260
+ set title(value) {
8261
+ super.title = value;
8262
+ }
8263
+ connectedCallback() {
8264
+ var _a5, _b5;
8265
+ super.connectedCallback();
8266
+ (_a5 = this.style).position || (_a5.position = "relative");
8267
+ (_b5 = this.style).display || (_b5.display = "inline-block");
8268
+ document.addEventListener("click", this.handleDocumentClick);
8269
+ document.addEventListener("keydown", this.handleDocumentKeydown);
8270
+ }
8271
+ disconnectedCallback() {
8272
+ document.removeEventListener("click", this.handleDocumentClick);
8273
+ document.removeEventListener("keydown", this.handleDocumentKeydown);
8274
+ super.disconnectedCallback();
8275
+ }
8276
+ willUpdate(changedProperties) {
8277
+ if (changedProperties.has("open") && this.open == null) {
8278
+ this.open = false;
8279
+ }
8280
+ if (changedProperties.has("placement") && (this.placement == null || !isPopoverPlacement(this.placement))) {
8281
+ this.placement = "bottom";
8282
+ }
8283
+ if (changedProperties.has("triggerLabel") && !this.triggerLabel) {
8284
+ this.triggerLabel = "Show details";
8285
+ }
8286
+ }
8287
+ get triggerElement() {
8288
+ return this.querySelector("[data-sp-popover-trigger]");
8289
+ }
8290
+ get panelId() {
8291
+ return this.id || `${this.baseId}-panel`;
8292
+ }
8293
+ get headerId() {
8294
+ return `${this.baseId}-header`;
8295
+ }
8296
+ get hasHeader() {
8297
+ return this.projection.has("header") || Boolean(this.label);
8298
+ }
8299
+ setOpen(open) {
8300
+ if (this.open === open) {
8301
+ return;
8302
+ }
8303
+ this.open = open;
8304
+ this.dispatchEvent(
8305
+ new CustomEvent(open ? "sp-open" : "sp-close", { bubbles: true })
8306
+ );
8307
+ }
8308
+ get dialogLabelledBy() {
8309
+ if (this.forwardedAriaLabel) {
8310
+ return void 0;
8311
+ }
8312
+ return this.hasHeader ? this.headerId : `${this.baseId}-trigger`;
8313
+ }
8314
+ render() {
8315
+ const open = this.open ?? false;
8316
+ return lit.html`<button
8317
+ aria-controls="${this.panelId}"
8318
+ aria-expanded="${open ? "true" : "false"}"
8319
+ aria-haspopup="dialog"
8320
+ data-sp-popover-trigger
8321
+ id="${this.baseId}-trigger"
8322
+ type="button"
8323
+ @click="${() => this.setOpen(!open)}"
8324
+ >
8325
+ ${this.projection.has("trigger") ? this.projection.nodes("trigger") : this.triggerLabel}
8326
+ </button>
8327
+ <div
8328
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
8329
+ aria-labelledby="${ifDefined_js.ifDefined(this.dialogLabelledBy)}"
8330
+ class="${spectreUi.getPopoverClasses({
8331
+ open,
8332
+ placement: this.placement
8333
+ })}"
8334
+ data-sp-popover-native
8335
+ id="${this.panelId}"
8336
+ role="dialog"
8337
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
8338
+ >
8339
+ <span aria-hidden="true" class="${spectreUi.getPopoverArrowClasses()}"></span>
8340
+ ${this.hasHeader ? lit.html`<div
8341
+ class="${spectreUi.getPopoverHeaderClasses()}"
8342
+ id="${this.headerId}"
8343
+ >
8344
+ ${this.projection.has("header") ? this.projection.nodes("header") : this.label}
8345
+ </div>` : lit.nothing}
8346
+ <div class="${spectreUi.getPopoverBodyClasses()}">${this.projection.nodes()}</div>
8347
+ </div>`;
8348
+ }
8349
+ };
8350
+ SpectrePopoverElement.properties = {
8351
+ label: { type: String },
8352
+ open: { type: Boolean, reflect: true },
8353
+ placement: { type: String, reflect: true },
8354
+ triggerLabel: { attribute: "trigger-label", type: String }
8355
+ };
8356
+ function defineSpectrePopover(tagName = "sp-popover") {
8357
+ const existingElement = customElements.get(tagName);
8358
+ if (existingElement) {
8359
+ return existingElement;
8360
+ }
8361
+ customElements.define(tagName, SpectrePopoverElement);
8362
+ return SpectrePopoverElement;
8363
+ }
8364
+ var ISO_DATE = /^(\d{4})-(\d{2})-(\d{2})$/;
8365
+ function pad(value) {
8366
+ return String(value).padStart(2, "0");
8367
+ }
8368
+ function toIsoDate(date) {
8369
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
8370
+ }
8371
+ function parseIsoDate(value) {
8372
+ const match = value ? ISO_DATE.exec(value) : null;
8373
+ if (!match) {
8374
+ return void 0;
8375
+ }
8376
+ const [year, month, day] = [
8377
+ Number(match[1]),
8378
+ Number(match[2]),
8379
+ Number(match[3])
8380
+ ];
8381
+ const date = new Date(year, month - 1, day);
8382
+ return date.getMonth() === month - 1 && date.getDate() === day ? date : void 0;
8383
+ }
8384
+ function addDays(date, days) {
8385
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);
8386
+ }
8387
+ function addMonths(date, months) {
8388
+ const target = new Date(date.getFullYear(), date.getMonth() + months, 1);
8389
+ const lastDay = new Date(
8390
+ target.getFullYear(),
8391
+ target.getMonth() + 1,
8392
+ 0
8393
+ ).getDate();
8394
+ target.setDate(Math.min(date.getDate(), lastDay));
8395
+ return target;
8396
+ }
8397
+ function today() {
8398
+ const now = /* @__PURE__ */ new Date();
8399
+ return new Date(now.getFullYear(), now.getMonth(), now.getDate());
8400
+ }
8401
+ var SpectreDatepickerElement = class extends SpectreBaseElement {
8402
+ constructor() {
8403
+ super(...arguments);
8404
+ this.locale = void 0;
8405
+ this.max = void 0;
8406
+ this.min = void 0;
8407
+ this.name = void 0;
8408
+ this.nextLabel = "Next month";
8409
+ this.previousLabel = "Previous month";
8410
+ this.value = void 0;
8411
+ this.weekStart = 0;
8412
+ // The roving-focus day; its month is the one on display.
8413
+ this.activeDate = today();
8414
+ this.titleId = `${createUniqueId("sp-datepicker")}-title`;
8415
+ this.handleKeydown = async (event) => {
8416
+ const active = this.activeDate;
8417
+ const weekday = (active.getDay() - (this.weekStart ?? 0) + 7) % 7;
8418
+ const moves = {
8419
+ ArrowLeft: () => addDays(active, -1),
8420
+ ArrowRight: () => addDays(active, 1),
8421
+ ArrowUp: () => addDays(active, -7),
8422
+ ArrowDown: () => addDays(active, 7),
8423
+ Home: () => addDays(active, -weekday),
8424
+ End: () => addDays(active, 6 - weekday),
8425
+ PageUp: () => addMonths(active, event.shiftKey ? -12 : -1),
8426
+ PageDown: () => addMonths(active, event.shiftKey ? 12 : 1)
8427
+ };
8428
+ const move = moves[event.key];
8429
+ if (!move) {
8430
+ return;
8431
+ }
8432
+ event.preventDefault();
8433
+ this.activeDate = move();
8434
+ await this.updateComplete;
8435
+ this.querySelector(
8436
+ `[data-sp-day="${toIsoDate(this.activeDate)}"]`
8437
+ )?.focus();
8438
+ };
8439
+ }
8440
+ get id() {
8441
+ return super.id;
8442
+ }
8443
+ set id(value) {
8444
+ super.id = value;
8445
+ }
8446
+ get title() {
8447
+ return super.title;
8448
+ }
8449
+ set title(value) {
8450
+ super.title = value;
8451
+ }
8452
+ connectedCallback() {
8453
+ var _a5;
8454
+ super.connectedCallback();
8455
+ (_a5 = this.style).display || (_a5.display = "inline-block");
8456
+ }
8457
+ willUpdate(changedProperties) {
8458
+ if (changedProperties.has("value")) {
8459
+ const parsed = parseIsoDate(this.value);
8460
+ if (this.value && !parsed) {
8461
+ this.value = void 0;
8462
+ } else if (parsed) {
8463
+ this.activeDate = parsed;
8464
+ }
8465
+ }
8466
+ if (changedProperties.has("min") && !parseIsoDate(this.min)) {
8467
+ this.min = void 0;
8468
+ }
8469
+ if (changedProperties.has("max") && !parseIsoDate(this.max)) {
8470
+ this.max = void 0;
8471
+ }
8472
+ if (changedProperties.has("weekStart")) {
8473
+ const weekStart = normalizeInt(this.weekStart, 0) ?? 0;
8474
+ this.weekStart = weekStart > 6 ? 0 : weekStart;
8475
+ }
8476
+ if (changedProperties.has("nextLabel") && !this.nextLabel) {
8477
+ this.nextLabel = "Next month";
8478
+ }
8479
+ if (changedProperties.has("previousLabel") && !this.previousLabel) {
8480
+ this.previousLabel = "Previous month";
8481
+ }
8482
+ }
8483
+ isOutOfRange(date) {
8484
+ const iso = toIsoDate(date);
8485
+ return this.min !== void 0 && iso < this.min || this.max !== void 0 && iso > this.max;
8486
+ }
8487
+ get visibleDays() {
8488
+ const first = new Date(
8489
+ this.activeDate.getFullYear(),
8490
+ this.activeDate.getMonth(),
8491
+ 1
8492
+ );
8493
+ const daysInMonth = new Date(
8494
+ first.getFullYear(),
8495
+ first.getMonth() + 1,
8496
+ 0
8497
+ ).getDate();
8498
+ const leading = (first.getDay() - (this.weekStart ?? 0) + 7) % 7;
8499
+ const count = Math.ceil((leading + daysInMonth) / 7) * 7;
8500
+ const start = addDays(first, -leading);
8501
+ return Array.from({ length: count }, (_, index) => addDays(start, index));
8502
+ }
8503
+ select(date) {
8504
+ if (this.isOutOfRange(date)) {
8505
+ return;
8506
+ }
8507
+ this.activeDate = date;
8508
+ const value = toIsoDate(date);
8509
+ if (value === this.value) {
8510
+ return;
8511
+ }
8512
+ this.value = value;
8513
+ this.dispatchEvent(
8514
+ new CustomEvent("sp-change", { bubbles: true, detail: { value } })
8515
+ );
8516
+ }
8517
+ showMonth(offset) {
8518
+ this.activeDate = addMonths(this.activeDate, offset);
8519
+ }
8520
+ renderDay(date) {
8521
+ const iso = toIsoDate(date);
8522
+ const selected = iso === this.value;
8523
+ const isToday = iso === toIsoDate(today());
8524
+ const disabled = this.isOutOfRange(date);
8525
+ const label = new Intl.DateTimeFormat(this.locale, {
8526
+ dateStyle: "full"
8527
+ }).format(date);
8528
+ return lit.html`<button
8529
+ aria-current="${ifDefined_js.ifDefined(isToday ? "date" : void 0)}"
8530
+ aria-label="${label}"
8531
+ aria-pressed="${selected ? "true" : "false"}"
8532
+ class="${spectreUi.getDayClasses({
8533
+ disabled,
8534
+ outsideMonth: date.getMonth() !== this.activeDate.getMonth(),
8535
+ selected,
8536
+ today: isToday
8537
+ })}"
8538
+ data-sp-day="${iso}"
8539
+ ?disabled="${disabled}"
8540
+ tabindex="${iso === toIsoDate(this.activeDate) ? "0" : "-1"}"
8541
+ type="button"
8542
+ @click="${() => this.select(date)}"
8543
+ >
8544
+ ${date.getDate()}
8545
+ </button>`;
8546
+ }
8547
+ render() {
8548
+ const days = this.visibleDays;
8549
+ const weekdayFormat = new Intl.DateTimeFormat(this.locale, {
8550
+ weekday: "short"
8551
+ });
8552
+ const navClasses = spectreUi.getButtonClasses({
8553
+ iconOnly: true,
8554
+ size: "sm",
8555
+ variant: "ghost"
8556
+ });
8557
+ return lit.html`<div
8558
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
8559
+ aria-labelledby="${ifDefined_js.ifDefined(
8560
+ this.forwardedAriaLabel ? void 0 : this.titleId
8561
+ )}"
8562
+ class="${spectreUi.getDatepickerClasses()}"
8563
+ data-sp-datepicker-native
8564
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
8565
+ role="group"
8566
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
8567
+ >
8568
+ <div class="${spectreUi.getDatepickerHeaderClasses()}">
8569
+ <button
8570
+ aria-label="${this.previousLabel ?? "Previous month"}"
8571
+ class="${navClasses}"
8572
+ data-sp-datepicker-prev
8573
+ type="button"
8574
+ @click="${() => this.showMonth(-1)}"
8575
+ >
8576
+ ${renderIcon("chevronLeft")}
8577
+ </button>
8578
+ <span aria-live="polite" id="${this.titleId}"
8579
+ >${new Intl.DateTimeFormat(this.locale, {
8580
+ month: "long",
8581
+ year: "numeric"
8582
+ }).format(this.activeDate)}</span
8583
+ >
8584
+ <button
8585
+ aria-label="${this.nextLabel ?? "Next month"}"
8586
+ class="${navClasses}"
8587
+ data-sp-datepicker-next
8588
+ type="button"
8589
+ @click="${() => this.showMonth(1)}"
8590
+ >
8591
+ ${renderIcon("chevronRight")}
8592
+ </button>
8593
+ </div>
8594
+ <div
8595
+ class="${spectreUi.getDatepickerGridClasses()}"
8596
+ data-sp-datepicker-grid
8597
+ @keydown="${this.handleKeydown}"
8598
+ >
8599
+ ${days.slice(0, 7).map(
8600
+ (date) => lit.html`<span
8601
+ aria-hidden="true"
8602
+ class="${spectreUi.getDatepickerWeekdayClasses()}"
8603
+ >${weekdayFormat.format(date)}</span
8604
+ >`
8605
+ )}
8606
+ ${days.map((date) => this.renderDay(date))}
8607
+ </div>
8608
+ ${this.name ? lit.html`<input
8609
+ name="${this.name}"
8610
+ type="hidden"
8611
+ .value="${this.value ?? ""}"
8612
+ />` : lit.nothing}
8613
+ </div>`;
8614
+ }
8615
+ };
8616
+ SpectreDatepickerElement.properties = {
8617
+ activeDate: { state: true },
8618
+ locale: { type: String },
8619
+ max: { type: String },
8620
+ min: { type: String },
8621
+ name: { type: String },
8622
+ nextLabel: { attribute: "next-label", type: String },
8623
+ previousLabel: { attribute: "previous-label", type: String },
8624
+ value: { type: String, reflect: true },
8625
+ weekStart: { attribute: "week-start", type: Number }
8626
+ };
8627
+ function defineSpectreDatepicker(tagName = "sp-datepicker") {
8628
+ const existingElement = customElements.get(tagName);
8629
+ if (existingElement) {
8630
+ return existingElement;
8631
+ }
8632
+ customElements.define(tagName, SpectreDatepickerElement);
8633
+ return SpectreDatepickerElement;
8634
+ }
5174
8635
 
5175
8636
  // src/index.ts
5176
8637
  function defineSpectreComponents() {
@@ -5209,29 +8670,70 @@ function defineSpectreComponents() {
5209
8670
  defineSpectreToast();
5210
8671
  defineSpectreTooltip();
5211
8672
  defineSpectreText();
8673
+ defineSpectreTabs();
8674
+ defineSpectreTabPanel();
8675
+ defineSpectreAccordion();
8676
+ defineSpectreAccordionItem();
8677
+ defineSpectreBreadcrumb();
8678
+ defineSpectreListGroup();
8679
+ defineSpectreListGroupItem();
8680
+ defineSpectreOffcanvas();
8681
+ defineSpectreCarousel();
8682
+ defineSpectreTable();
8683
+ defineSpectrePagination();
8684
+ defineSpectreStepper();
8685
+ defineSpectreCardBleed();
8686
+ defineSpectreProse();
8687
+ defineSpectreProgress();
8688
+ defineSpectreSwitch();
8689
+ defineSpectreRange();
8690
+ defineSpectreFileInput();
8691
+ defineSpectreExternalAuthButton();
8692
+ defineSpectreChoiceCard();
8693
+ defineSpectreInputGroup();
8694
+ defineSpectrePopover();
8695
+ defineSpectreDatepicker();
5212
8696
  }
5213
8697
 
8698
+ exports.SpectreAccordionElement = SpectreAccordionElement;
8699
+ exports.SpectreAccordionItemElement = SpectreAccordionItemElement;
5214
8700
  exports.SpectreAlertElement = SpectreAlertElement;
5215
8701
  exports.SpectreAvatarElement = SpectreAvatarElement;
5216
8702
  exports.SpectreBadgeElement = SpectreBadgeElement;
8703
+ exports.SpectreBreadcrumbElement = SpectreBreadcrumbElement;
5217
8704
  exports.SpectreButtonElement = SpectreButtonElement;
8705
+ exports.SpectreCardBleedElement = SpectreCardBleedElement;
5218
8706
  exports.SpectreCardElement = SpectreCardElement;
8707
+ exports.SpectreCarouselElement = SpectreCarouselElement;
5219
8708
  exports.SpectreCheckboxElement = SpectreCheckboxElement;
8709
+ exports.SpectreChoiceCardElement = SpectreChoiceCardElement;
5220
8710
  exports.SpectreContainerElement = SpectreContainerElement;
8711
+ exports.SpectreDatepickerElement = SpectreDatepickerElement;
5221
8712
  exports.SpectreDropdownElement = SpectreDropdownElement;
8713
+ exports.SpectreExternalAuthButtonElement = SpectreExternalAuthButtonElement;
5222
8714
  exports.SpectreFieldsetElement = SpectreFieldsetElement;
8715
+ exports.SpectreFileInputElement = SpectreFileInputElement;
5223
8716
  exports.SpectreFooterChipElement = SpectreFooterChipElement;
5224
8717
  exports.SpectreFooterElement = SpectreFooterElement;
5225
8718
  exports.SpectreFooterLinkElement = SpectreFooterLinkElement;
5226
8719
  exports.SpectreGridElement = SpectreGridElement;
5227
8720
  exports.SpectreIconBoxElement = SpectreIconBoxElement;
5228
8721
  exports.SpectreInputElement = SpectreInputElement;
8722
+ exports.SpectreInputGroupElement = SpectreInputGroupElement;
5229
8723
  exports.SpectreLabelElement = SpectreLabelElement;
8724
+ exports.SpectreListGroupElement = SpectreListGroupElement;
8725
+ exports.SpectreListGroupItemElement = SpectreListGroupItemElement;
5230
8726
  exports.SpectreModalElement = SpectreModalElement;
5231
8727
  exports.SpectreNavElement = SpectreNavElement;
5232
8728
  exports.SpectreNavItemElement = SpectreNavItemElement;
8729
+ exports.SpectreOffcanvasElement = SpectreOffcanvasElement;
8730
+ exports.SpectrePaginationElement = SpectrePaginationElement;
8731
+ exports.SpectrePopoverElement = SpectrePopoverElement;
5233
8732
  exports.SpectrePricingCardElement = SpectrePricingCardElement;
8733
+ exports.SpectreProgressElement = SpectreProgressElement;
8734
+ exports.SpectreProseElement = SpectreProseElement;
5234
8735
  exports.SpectreRadioElement = SpectreRadioElement;
8736
+ exports.SpectreRangeElement = SpectreRangeElement;
5235
8737
  exports.SpectreRatingElement = SpectreRatingElement;
5236
8738
  exports.SpectreSectionElement = SpectreSectionElement;
5237
8739
  exports.SpectreSelectElement = SpectreSelectElement;
@@ -5240,34 +8742,57 @@ exports.SpectreSidebarLinkElement = SpectreSidebarLinkElement;
5240
8742
  exports.SpectreSidebarToggleElement = SpectreSidebarToggleElement;
5241
8743
  exports.SpectreSpinnerElement = SpectreSpinnerElement;
5242
8744
  exports.SpectreStackElement = SpectreStackElement;
8745
+ exports.SpectreStepperElement = SpectreStepperElement;
8746
+ exports.SpectreSwitchElement = SpectreSwitchElement;
8747
+ exports.SpectreTabPanelElement = SpectreTabPanelElement;
8748
+ exports.SpectreTableElement = SpectreTableElement;
8749
+ exports.SpectreTabsElement = SpectreTabsElement;
5243
8750
  exports.SpectreTagElement = SpectreTagElement;
5244
8751
  exports.SpectreTestimonialElement = SpectreTestimonialElement;
5245
8752
  exports.SpectreTextElement = SpectreTextElement;
5246
8753
  exports.SpectreTextareaElement = SpectreTextareaElement;
5247
8754
  exports.SpectreToastElement = SpectreToastElement;
5248
8755
  exports.SpectreTooltipElement = SpectreTooltipElement;
8756
+ exports.defineSpectreAccordion = defineSpectreAccordion;
8757
+ exports.defineSpectreAccordionItem = defineSpectreAccordionItem;
5249
8758
  exports.defineSpectreAlert = defineSpectreAlert;
5250
8759
  exports.defineSpectreAvatar = defineSpectreAvatar;
5251
8760
  exports.defineSpectreBadge = defineSpectreBadge;
8761
+ exports.defineSpectreBreadcrumb = defineSpectreBreadcrumb;
5252
8762
  exports.defineSpectreButton = defineSpectreButton;
5253
8763
  exports.defineSpectreCard = defineSpectreCard;
8764
+ exports.defineSpectreCardBleed = defineSpectreCardBleed;
8765
+ exports.defineSpectreCarousel = defineSpectreCarousel;
5254
8766
  exports.defineSpectreCheckbox = defineSpectreCheckbox;
8767
+ exports.defineSpectreChoiceCard = defineSpectreChoiceCard;
5255
8768
  exports.defineSpectreComponents = defineSpectreComponents;
5256
8769
  exports.defineSpectreContainer = defineSpectreContainer;
8770
+ exports.defineSpectreDatepicker = defineSpectreDatepicker;
5257
8771
  exports.defineSpectreDropdown = defineSpectreDropdown;
8772
+ exports.defineSpectreExternalAuthButton = defineSpectreExternalAuthButton;
5258
8773
  exports.defineSpectreFieldset = defineSpectreFieldset;
8774
+ exports.defineSpectreFileInput = defineSpectreFileInput;
5259
8775
  exports.defineSpectreFooter = defineSpectreFooter;
5260
8776
  exports.defineSpectreFooterChip = defineSpectreFooterChip;
5261
8777
  exports.defineSpectreFooterLink = defineSpectreFooterLink;
5262
8778
  exports.defineSpectreGrid = defineSpectreGrid;
5263
8779
  exports.defineSpectreIconBox = defineSpectreIconBox;
5264
8780
  exports.defineSpectreInput = defineSpectreInput;
8781
+ exports.defineSpectreInputGroup = defineSpectreInputGroup;
5265
8782
  exports.defineSpectreLabel = defineSpectreLabel;
8783
+ exports.defineSpectreListGroup = defineSpectreListGroup;
8784
+ exports.defineSpectreListGroupItem = defineSpectreListGroupItem;
5266
8785
  exports.defineSpectreModal = defineSpectreModal;
5267
8786
  exports.defineSpectreNav = defineSpectreNav;
5268
8787
  exports.defineSpectreNavItem = defineSpectreNavItem;
8788
+ exports.defineSpectreOffcanvas = defineSpectreOffcanvas;
8789
+ exports.defineSpectrePagination = defineSpectrePagination;
8790
+ exports.defineSpectrePopover = defineSpectrePopover;
5269
8791
  exports.defineSpectrePricingCard = defineSpectrePricingCard;
8792
+ exports.defineSpectreProgress = defineSpectreProgress;
8793
+ exports.defineSpectreProse = defineSpectreProse;
5270
8794
  exports.defineSpectreRadio = defineSpectreRadio;
8795
+ exports.defineSpectreRange = defineSpectreRange;
5271
8796
  exports.defineSpectreRating = defineSpectreRating;
5272
8797
  exports.defineSpectreSection = defineSpectreSection;
5273
8798
  exports.defineSpectreSelect = defineSpectreSelect;
@@ -5276,6 +8801,11 @@ exports.defineSpectreSidebarLink = defineSpectreSidebarLink;
5276
8801
  exports.defineSpectreSidebarToggle = defineSpectreSidebarToggle;
5277
8802
  exports.defineSpectreSpinner = defineSpectreSpinner;
5278
8803
  exports.defineSpectreStack = defineSpectreStack;
8804
+ exports.defineSpectreStepper = defineSpectreStepper;
8805
+ exports.defineSpectreSwitch = defineSpectreSwitch;
8806
+ exports.defineSpectreTabPanel = defineSpectreTabPanel;
8807
+ exports.defineSpectreTable = defineSpectreTable;
8808
+ exports.defineSpectreTabs = defineSpectreTabs;
5279
8809
  exports.defineSpectreTag = defineSpectreTag;
5280
8810
  exports.defineSpectreTestimonial = defineSpectreTestimonial;
5281
8811
  exports.defineSpectreText = defineSpectreText;
@@ -5295,26 +8825,43 @@ exports.spectreCardAccentColors = spectreAccentColors;
5295
8825
  exports.spectreCardAccentEdges = spectreAccentEdges;
5296
8826
  exports.spectreCardVariants = spectreCardVariants;
5297
8827
  exports.spectreContainerMaxWidths = spectreContainerMaxWidths;
8828
+ exports.spectreContainerPaddings = spectreSpacingScale;
8829
+ exports.spectreDisplayLevels = spectreDisplayLevels;
5298
8830
  exports.spectreDropdownPlacements = spectreDropdownPlacements;
8831
+ exports.spectreFileInputSizes = spectreInputSizes;
5299
8832
  exports.spectreGridAligns = spectreGridAligns;
8833
+ exports.spectreGridColStarts = spectreGridColStarts;
5300
8834
  exports.spectreGridColumns = spectreGridColumns;
5301
8835
  exports.spectreGridGaps = spectreGridGaps;
8836
+ exports.spectreHeadingLevels = spectreHeadingLevels;
5302
8837
  exports.spectreIconBoxSizes = spectreInputSizes;
5303
8838
  exports.spectreIconBoxVariants = spectreIconBoxVariants;
5304
8839
  exports.spectreInputSizes = spectreInputSizes;
5305
8840
  exports.spectreInputTypes = spectreInputTypes;
8841
+ exports.spectreOffcanvasPlacements = spectreOffcanvasPlacements;
8842
+ exports.spectrePaginationSizes = spectreInputSizes;
8843
+ exports.spectrePopoverPlacements = spectrePopoverPlacements;
8844
+ exports.spectreProgressSizes = spectreInputSizes;
8845
+ exports.spectreProgressVariants = spectreProgressVariants;
5306
8846
  exports.spectreRatingSizes = spectreInputSizes;
8847
+ exports.spectreSectionSpacings = spectreSpacingScale;
5307
8848
  exports.spectreSpinnerSizes = spectreInputSizes;
5308
8849
  exports.spectreSpinnerVariants = spectreSpinnerVariants;
5309
8850
  exports.spectreStackAligns = spectreStackAligns;
5310
8851
  exports.spectreStackBases = spectreStackBases;
5311
8852
  exports.spectreStackDirections = spectreStackDirections;
5312
8853
  exports.spectreStackGaps = spectreStackGaps;
8854
+ exports.spectreStepperOrientations = spectreStepperOrientations;
8855
+ exports.spectreSwitchSizes = spectreInputSizes;
8856
+ exports.spectreTableRowVariants = spectreTableRowVariants;
8857
+ exports.spectreTableSizes = spectreTableSizes;
8858
+ exports.spectreTabsVariants = spectreTabsVariants;
5313
8859
  exports.spectreTagSizes = spectreInputSizes;
5314
8860
  exports.spectreTagVariants = spectreTagVariants;
5315
8861
  exports.spectreTestimonialVariants = spectreTestimonialVariants;
5316
8862
  exports.spectreTextFamilies = spectreTextFamilies;
5317
8863
  exports.spectreTextLevels = spectreTextLevels;
8864
+ exports.spectreTextPresets = spectreTextPresets;
5318
8865
  exports.spectreTextSizes = spectreTextSizes;
5319
8866
  exports.spectreTextVariants = spectreTextVariants;
5320
8867
  exports.spectreToastVariants = spectreToastVariants;