@phcdevworks/spectre-components 1.6.0 → 1.7.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 (110) hide show
  1. package/README.md +174 -1
  2. package/dist/alert.cjs.map +1 -1
  3. package/dist/alert.d.cts +2 -2
  4. package/dist/alert.d.ts +2 -2
  5. package/dist/alert.js.map +1 -1
  6. package/dist/avatar.cjs.map +1 -1
  7. package/dist/avatar.d.cts +2 -2
  8. package/dist/avatar.d.ts +2 -2
  9. package/dist/avatar.js.map +1 -1
  10. package/dist/badge.cjs.map +1 -1
  11. package/dist/badge.d.cts +2 -2
  12. package/dist/badge.d.ts +2 -2
  13. package/dist/badge.js.map +1 -1
  14. package/dist/button.cjs.map +1 -1
  15. package/dist/button.d.cts +2 -2
  16. package/dist/button.d.ts +2 -2
  17. package/dist/button.js.map +1 -1
  18. package/dist/card.cjs.map +1 -1
  19. package/dist/card.d.cts +2 -2
  20. package/dist/card.d.ts +2 -2
  21. package/dist/card.js.map +1 -1
  22. package/dist/container.cjs.map +1 -1
  23. package/dist/container.d.cts +2 -2
  24. package/dist/container.d.ts +2 -2
  25. package/dist/container.js.map +1 -1
  26. package/dist/dropdown.cjs +486 -0
  27. package/dist/dropdown.cjs.map +1 -0
  28. package/dist/dropdown.d.cts +69 -0
  29. package/dist/dropdown.d.ts +69 -0
  30. package/dist/dropdown.js +482 -0
  31. package/dist/dropdown.js.map +1 -0
  32. package/dist/{form-8KZeQRgr.d.cts → form-DgzRhNmg.d.cts} +7 -1
  33. package/dist/{form-8KZeQRgr.d.ts → form-DgzRhNmg.d.ts} +7 -1
  34. package/dist/grid.cjs.map +1 -1
  35. package/dist/grid.d.cts +2 -2
  36. package/dist/grid.d.ts +2 -2
  37. package/dist/grid.js.map +1 -1
  38. package/dist/icon-box.cjs.map +1 -1
  39. package/dist/icon-box.d.cts +2 -2
  40. package/dist/icon-box.d.ts +2 -2
  41. package/dist/icon-box.js.map +1 -1
  42. package/dist/index.cjs +924 -0
  43. package/dist/index.cjs.map +1 -1
  44. package/dist/index.d.cts +7 -1
  45. package/dist/index.d.ts +7 -1
  46. package/dist/index.js +911 -2
  47. package/dist/index.js.map +1 -1
  48. package/dist/input.cjs.map +1 -1
  49. package/dist/input.d.cts +2 -2
  50. package/dist/input.d.ts +2 -2
  51. package/dist/input.js.map +1 -1
  52. package/dist/modal.cjs +519 -0
  53. package/dist/modal.cjs.map +1 -0
  54. package/dist/modal.d.cts +52 -0
  55. package/dist/modal.d.ts +52 -0
  56. package/dist/modal.js +516 -0
  57. package/dist/modal.js.map +1 -0
  58. package/dist/nav.cjs +424 -0
  59. package/dist/nav.cjs.map +1 -0
  60. package/dist/nav.d.cts +45 -0
  61. package/dist/nav.d.ts +45 -0
  62. package/dist/nav.js +421 -0
  63. package/dist/nav.js.map +1 -0
  64. package/dist/rating.cjs.map +1 -1
  65. package/dist/rating.d.cts +2 -2
  66. package/dist/rating.d.ts +2 -2
  67. package/dist/rating.js.map +1 -1
  68. package/dist/select.cjs.map +1 -1
  69. package/dist/select.d.cts +1 -1
  70. package/dist/select.d.ts +1 -1
  71. package/dist/select.js.map +1 -1
  72. package/dist/sidebar.cjs +481 -0
  73. package/dist/sidebar.cjs.map +1 -0
  74. package/dist/sidebar.d.cts +50 -0
  75. package/dist/sidebar.d.ts +50 -0
  76. package/dist/sidebar.js +478 -0
  77. package/dist/sidebar.js.map +1 -0
  78. package/dist/spinner.cjs.map +1 -1
  79. package/dist/spinner.d.cts +2 -2
  80. package/dist/spinner.d.ts +2 -2
  81. package/dist/spinner.js.map +1 -1
  82. package/dist/stack.cjs.map +1 -1
  83. package/dist/stack.d.cts +2 -2
  84. package/dist/stack.d.ts +2 -2
  85. package/dist/stack.js.map +1 -1
  86. package/dist/tag.cjs.map +1 -1
  87. package/dist/tag.d.cts +2 -2
  88. package/dist/tag.d.ts +2 -2
  89. package/dist/tag.js.map +1 -1
  90. package/dist/testimonial.cjs.map +1 -1
  91. package/dist/testimonial.d.cts +2 -2
  92. package/dist/testimonial.d.ts +2 -2
  93. package/dist/testimonial.js.map +1 -1
  94. package/dist/textarea.cjs.map +1 -1
  95. package/dist/textarea.d.cts +1 -1
  96. package/dist/textarea.d.ts +1 -1
  97. package/dist/textarea.js.map +1 -1
  98. package/dist/toast.cjs +475 -0
  99. package/dist/toast.cjs.map +1 -0
  100. package/dist/toast.d.cts +68 -0
  101. package/dist/toast.d.ts +68 -0
  102. package/dist/toast.js +471 -0
  103. package/dist/toast.js.map +1 -0
  104. package/dist/tooltip.cjs +444 -0
  105. package/dist/tooltip.cjs.map +1 -0
  106. package/dist/tooltip.d.cts +50 -0
  107. package/dist/tooltip.d.ts +50 -0
  108. package/dist/tooltip.js +440 -0
  109. package/dist/tooltip.js.map +1 -0
  110. package/package.json +34 -4
package/dist/index.cjs CHANGED
@@ -172,6 +172,37 @@ var spectreStackAligns = ["center", "stretch"];
172
172
  function isStackAlign(value) {
173
173
  return spectreStackAligns.includes(value);
174
174
  }
175
+ var spectreDropdownPlacements = [
176
+ "bottom-start",
177
+ "bottom-end",
178
+ "top-start",
179
+ "top-end"
180
+ ];
181
+ function isDropdownPlacement(value) {
182
+ return spectreDropdownPlacements.includes(
183
+ value
184
+ );
185
+ }
186
+ var spectreToastVariants = [
187
+ "info",
188
+ "success",
189
+ "warning",
190
+ "danger"
191
+ ];
192
+ function isToastVariant(value) {
193
+ return spectreToastVariants.includes(value);
194
+ }
195
+ var spectreTooltipPlacements = [
196
+ "top",
197
+ "bottom",
198
+ "left",
199
+ "right"
200
+ ];
201
+ function isTooltipPlacement(value) {
202
+ return spectreTooltipPlacements.includes(
203
+ value
204
+ );
205
+ }
175
206
  function normalizeInt(value, fallback, min = 0) {
176
207
  if (value == null || typeof value !== "number" || !Number.isInteger(value) || value < min) {
177
208
  return fallback;
@@ -2886,6 +2917,878 @@ function defineSpectreStack(tagName = "sp-stack") {
2886
2917
  customElements.define(tagName, SpectreStackElement);
2887
2918
  return SpectreStackElement;
2888
2919
  }
2920
+ var SpectreDropdownElement = class extends SpectreBaseElement {
2921
+ constructor() {
2922
+ super(...arguments);
2923
+ this.fullWidth = false;
2924
+ this.open = false;
2925
+ this.placement = "bottom-start";
2926
+ this.triggerLabel = "Toggle menu";
2927
+ this.triggerContent = [];
2928
+ this.menuContent = [];
2929
+ this.handleDocumentClick = (event) => {
2930
+ if (!this.open) {
2931
+ return;
2932
+ }
2933
+ if (!event.composedPath().includes(this)) {
2934
+ this.close();
2935
+ }
2936
+ };
2937
+ this.handleDocumentKeydown = (event) => {
2938
+ if (event.key === "Escape" && this.open) {
2939
+ this.close();
2940
+ this.triggerElement?.focus();
2941
+ }
2942
+ };
2943
+ }
2944
+ get id() {
2945
+ return super.id;
2946
+ }
2947
+ set id(value) {
2948
+ super.id = value;
2949
+ }
2950
+ get title() {
2951
+ return super.title;
2952
+ }
2953
+ set title(value) {
2954
+ super.title = value;
2955
+ }
2956
+ isInternalNode(node) {
2957
+ if (node.nodeType !== Node.ELEMENT_NODE) {
2958
+ return false;
2959
+ }
2960
+ const el = node;
2961
+ return el.hasAttribute("data-sp-dropdown-menu") || el.hasAttribute("data-sp-dropdown-trigger");
2962
+ }
2963
+ syncProjectedContent() {
2964
+ const nextTriggerContent = [];
2965
+ const nextMenuContent = [];
2966
+ this.childNodes.forEach((node) => {
2967
+ if (this.isInternalNode(node)) {
2968
+ return;
2969
+ }
2970
+ const isTriggerSlot = node.nodeType === Node.ELEMENT_NODE && node.getAttribute("slot") === "trigger";
2971
+ if (isTriggerSlot) {
2972
+ nextTriggerContent.push(node);
2973
+ } else {
2974
+ nextMenuContent.push(node);
2975
+ }
2976
+ });
2977
+ const changed = nextTriggerContent.length !== this.triggerContent.length || nextTriggerContent.some((n, i) => n !== this.triggerContent[i]) || nextMenuContent.length !== this.menuContent.length || nextMenuContent.some((n, i) => n !== this.menuContent[i]);
2978
+ if (changed) {
2979
+ this.triggerContent = nextTriggerContent;
2980
+ this.menuContent = nextMenuContent;
2981
+ }
2982
+ return changed;
2983
+ }
2984
+ get hasTriggerContent() {
2985
+ return hasMeaningfulContent(this.triggerContent);
2986
+ }
2987
+ get hasMenuContent() {
2988
+ return hasMeaningfulContent(this.menuContent);
2989
+ }
2990
+ connectedCallback() {
2991
+ super.connectedCallback();
2992
+ this.syncProjectedContent();
2993
+ this.startContentObserver();
2994
+ document.addEventListener("click", this.handleDocumentClick);
2995
+ document.addEventListener("keydown", this.handleDocumentKeydown);
2996
+ }
2997
+ disconnectedCallback() {
2998
+ this.stopContentObserver();
2999
+ document.removeEventListener("click", this.handleDocumentClick);
3000
+ document.removeEventListener("keydown", this.handleDocumentKeydown);
3001
+ super.disconnectedCallback();
3002
+ }
3003
+ update(changedProperties) {
3004
+ this.stopContentObserver();
3005
+ super.update(changedProperties);
3006
+ this.startContentObserver();
3007
+ }
3008
+ startContentObserver() {
3009
+ if (this.contentObserver) {
3010
+ return;
3011
+ }
3012
+ this.contentObserver = new MutationObserver(() => {
3013
+ if (this.syncProjectedContent()) {
3014
+ this.requestUpdate();
3015
+ }
3016
+ });
3017
+ this.contentObserver.observe(this, { childList: true });
3018
+ }
3019
+ stopContentObserver() {
3020
+ this.contentObserver?.disconnect();
3021
+ this.contentObserver = void 0;
3022
+ }
3023
+ willUpdate(changedProperties) {
3024
+ if (changedProperties.has("fullWidth") && this.fullWidth == null) {
3025
+ this.fullWidth = false;
3026
+ }
3027
+ if (changedProperties.has("open") && this.open == null) {
3028
+ this.open = false;
3029
+ }
3030
+ if (changedProperties.has("placement") && (this.placement == null || !isDropdownPlacement(this.placement))) {
3031
+ this.placement = "bottom-start";
3032
+ }
3033
+ if (changedProperties.has("triggerLabel") && !this.triggerLabel) {
3034
+ this.triggerLabel = "Toggle menu";
3035
+ }
3036
+ }
3037
+ get triggerElement() {
3038
+ return this.querySelector("[data-sp-dropdown-trigger]");
3039
+ }
3040
+ toggle() {
3041
+ if (this.open) {
3042
+ this.close();
3043
+ } else {
3044
+ this.openMenu();
3045
+ }
3046
+ }
3047
+ openMenu() {
3048
+ if (this.open) {
3049
+ return;
3050
+ }
3051
+ this.open = true;
3052
+ this.dispatchEvent(new CustomEvent("sp-open", { bubbles: true }));
3053
+ }
3054
+ close() {
3055
+ if (!this.open) {
3056
+ return;
3057
+ }
3058
+ this.open = false;
3059
+ this.dispatchEvent(new CustomEvent("sp-close", { bubbles: true }));
3060
+ }
3061
+ get dropdownClasses() {
3062
+ return spectreUi.getDropdownClasses({ fullWidth: this.fullWidth ?? false });
3063
+ }
3064
+ get menuClasses() {
3065
+ return spectreUi.getDropdownMenuClasses({
3066
+ open: this.open ?? false,
3067
+ placement: this.placement
3068
+ });
3069
+ }
3070
+ render() {
3071
+ return lit.html`<div
3072
+ class="${this.dropdownClasses}"
3073
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
3074
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
3075
+ >
3076
+ <button
3077
+ aria-expanded="${this.open ? "true" : "false"}"
3078
+ aria-haspopup="true"
3079
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel ?? this.triggerLabel)}"
3080
+ class="sp-dropdown__trigger"
3081
+ data-sp-dropdown-trigger
3082
+ type="button"
3083
+ @click="${() => this.toggle()}"
3084
+ >
3085
+ ${this.hasTriggerContent ? this.triggerContent : this.triggerLabel}
3086
+ </button>
3087
+ <div class="${this.menuClasses}" data-sp-dropdown-menu>
3088
+ ${this.hasMenuContent ? this.menuContent : lit.nothing}
3089
+ </div>
3090
+ </div>`;
3091
+ }
3092
+ };
3093
+ SpectreDropdownElement.properties = {
3094
+ fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
3095
+ open: { type: Boolean, reflect: true },
3096
+ placement: { type: String, reflect: true },
3097
+ triggerLabel: { attribute: "trigger-label", type: String }
3098
+ };
3099
+ function defineSpectreDropdown(tagName = "sp-dropdown") {
3100
+ const existingElement = customElements.get(tagName);
3101
+ if (existingElement) {
3102
+ return existingElement;
3103
+ }
3104
+ customElements.define(tagName, SpectreDropdownElement);
3105
+ return SpectreDropdownElement;
3106
+ }
3107
+ var FOCUSABLE_SELECTOR = [
3108
+ "a[href]",
3109
+ "button:not([disabled])",
3110
+ "input:not([disabled])",
3111
+ "select:not([disabled])",
3112
+ "textarea:not([disabled])",
3113
+ '[tabindex]:not([tabindex="-1"])'
3114
+ ].join(",");
3115
+ var SpectreModalElement = class extends SpectreProjectableElement {
3116
+ constructor() {
3117
+ super(...arguments);
3118
+ this.fullWidth = false;
3119
+ this.open = false;
3120
+ this.previouslyFocusedElement = null;
3121
+ this.handleDocumentKeydown = (event) => {
3122
+ if (!this.open) {
3123
+ return;
3124
+ }
3125
+ if (event.key === "Escape") {
3126
+ this.close();
3127
+ return;
3128
+ }
3129
+ if (event.key === "Tab") {
3130
+ this.trapFocus(event);
3131
+ }
3132
+ };
3133
+ }
3134
+ get id() {
3135
+ return super.id;
3136
+ }
3137
+ set id(value) {
3138
+ super.id = value;
3139
+ }
3140
+ get title() {
3141
+ return super.title;
3142
+ }
3143
+ set title(value) {
3144
+ super.title = value;
3145
+ }
3146
+ getContentContainer() {
3147
+ return this.querySelector("[data-sp-modal-native]");
3148
+ }
3149
+ isInternalNode(node) {
3150
+ if (node.nodeType !== Node.ELEMENT_NODE) {
3151
+ return false;
3152
+ }
3153
+ const el = node;
3154
+ return el.hasAttribute("data-sp-modal-native") || el.hasAttribute("data-sp-modal-overlay");
3155
+ }
3156
+ willUpdate(changedProperties) {
3157
+ if (changedProperties.has("fullWidth") && this.fullWidth == null) {
3158
+ this.fullWidth = false;
3159
+ }
3160
+ if (changedProperties.has("open") && this.open == null) {
3161
+ this.open = false;
3162
+ }
3163
+ }
3164
+ updated(changedProperties) {
3165
+ super.updated(changedProperties);
3166
+ if (!changedProperties.has("open")) {
3167
+ return;
3168
+ }
3169
+ if (this.open) {
3170
+ this.previouslyFocusedElement = document.activeElement;
3171
+ this.focusFirstElement();
3172
+ } else if (this.previouslyFocusedElement) {
3173
+ this.previouslyFocusedElement.focus();
3174
+ this.previouslyFocusedElement = null;
3175
+ }
3176
+ }
3177
+ connectedCallback() {
3178
+ super.connectedCallback();
3179
+ document.addEventListener("keydown", this.handleDocumentKeydown);
3180
+ }
3181
+ disconnectedCallback() {
3182
+ document.removeEventListener("keydown", this.handleDocumentKeydown);
3183
+ super.disconnectedCallback();
3184
+ }
3185
+ get modalElement() {
3186
+ return this.querySelector("[data-sp-modal-native]");
3187
+ }
3188
+ get focusableElements() {
3189
+ const modal = this.modalElement;
3190
+ if (!modal) {
3191
+ return [];
3192
+ }
3193
+ return Array.from(modal.querySelectorAll(FOCUSABLE_SELECTOR));
3194
+ }
3195
+ focusFirstElement() {
3196
+ const [first] = this.focusableElements;
3197
+ (first ?? this.modalElement)?.focus();
3198
+ }
3199
+ trapFocus(event) {
3200
+ const focusable = this.focusableElements;
3201
+ if (focusable.length === 0) {
3202
+ event.preventDefault();
3203
+ return;
3204
+ }
3205
+ const first = focusable[0];
3206
+ const last = focusable[focusable.length - 1];
3207
+ const active = document.activeElement;
3208
+ if (event.shiftKey && active === first) {
3209
+ event.preventDefault();
3210
+ last?.focus();
3211
+ } else if (!event.shiftKey && active === last) {
3212
+ event.preventDefault();
3213
+ first?.focus();
3214
+ }
3215
+ }
3216
+ close() {
3217
+ if (!this.open) {
3218
+ return;
3219
+ }
3220
+ this.open = false;
3221
+ this.dispatchEvent(new CustomEvent("sp-close", { bubbles: true }));
3222
+ }
3223
+ get overlayClasses() {
3224
+ return spectreUi.getModalOverlayClasses({ open: this.open ?? false });
3225
+ }
3226
+ get modalClasses() {
3227
+ return spectreUi.getModalClasses({
3228
+ open: this.open ?? false,
3229
+ fullWidth: this.fullWidth ?? false
3230
+ });
3231
+ }
3232
+ render() {
3233
+ const isHidden = !this.open;
3234
+ return lit.html`<div
3235
+ aria-hidden="${ifDefined_js.ifDefined(isHidden ? "true" : void 0)}"
3236
+ class="${this.overlayClasses}"
3237
+ data-sp-modal-overlay
3238
+ @click="${(event) => {
3239
+ if (event.target === event.currentTarget) {
3240
+ this.close();
3241
+ }
3242
+ }}"
3243
+ >
3244
+ <div
3245
+ aria-describedby="${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}"
3246
+ aria-hidden="${ifDefined_js.ifDefined(isHidden ? "true" : void 0)}"
3247
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
3248
+ aria-labelledby="${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}"
3249
+ aria-modal="true"
3250
+ class="${this.modalClasses}"
3251
+ data-sp-modal-native
3252
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
3253
+ role="dialog"
3254
+ tabindex="-1"
3255
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
3256
+ >
3257
+ ${this.hasProjectedContent ? this.projectedContent : lit.nothing}
3258
+ </div>
3259
+ </div>`;
3260
+ }
3261
+ };
3262
+ SpectreModalElement.properties = {
3263
+ fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
3264
+ open: { type: Boolean, reflect: true }
3265
+ };
3266
+ function defineSpectreModal(tagName = "sp-modal") {
3267
+ const existingElement = customElements.get(tagName);
3268
+ if (existingElement) {
3269
+ return existingElement;
3270
+ }
3271
+ customElements.define(tagName, SpectreModalElement);
3272
+ return SpectreModalElement;
3273
+ }
3274
+ var SpectreNavElement = class extends SpectreProjectableElement {
3275
+ constructor() {
3276
+ super(...arguments);
3277
+ this.bordered = false;
3278
+ this.fullWidth = false;
3279
+ this.sticky = false;
3280
+ }
3281
+ get id() {
3282
+ return super.id;
3283
+ }
3284
+ set id(value) {
3285
+ super.id = value;
3286
+ }
3287
+ get title() {
3288
+ return super.title;
3289
+ }
3290
+ set title(value) {
3291
+ super.title = value;
3292
+ }
3293
+ getContentContainer() {
3294
+ return this.querySelector("[data-sp-nav-native]");
3295
+ }
3296
+ isInternalNode(node) {
3297
+ if (node.nodeType !== Node.ELEMENT_NODE) {
3298
+ return false;
3299
+ }
3300
+ const el = node;
3301
+ return el.hasAttribute("data-sp-nav-native");
3302
+ }
3303
+ willUpdate(changedProperties) {
3304
+ if (changedProperties.has("bordered") && this.bordered == null) {
3305
+ this.bordered = false;
3306
+ }
3307
+ if (changedProperties.has("fullWidth") && this.fullWidth == null) {
3308
+ this.fullWidth = false;
3309
+ }
3310
+ if (changedProperties.has("sticky") && this.sticky == null) {
3311
+ this.sticky = false;
3312
+ }
3313
+ }
3314
+ get navClasses() {
3315
+ return spectreUi.getNavClasses({
3316
+ bordered: this.bordered ?? false,
3317
+ fullWidth: this.fullWidth ?? false,
3318
+ sticky: this.sticky ?? false
3319
+ });
3320
+ }
3321
+ render() {
3322
+ return lit.html`<nav
3323
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
3324
+ class="${this.navClasses}"
3325
+ data-sp-nav-native
3326
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
3327
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
3328
+ >
3329
+ ${this.hasProjectedContent ? this.projectedContent : lit.nothing}
3330
+ </nav>`;
3331
+ }
3332
+ };
3333
+ SpectreNavElement.properties = {
3334
+ bordered: { type: Boolean, reflect: true },
3335
+ fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
3336
+ sticky: { type: Boolean, reflect: true }
3337
+ };
3338
+ function defineSpectreNav(tagName = "sp-nav") {
3339
+ const existingElement = customElements.get(tagName);
3340
+ if (existingElement) {
3341
+ return existingElement;
3342
+ }
3343
+ customElements.define(tagName, SpectreNavElement);
3344
+ return SpectreNavElement;
3345
+ }
3346
+ var SpectreSidebarElement = class extends SpectreProjectableElement {
3347
+ constructor() {
3348
+ super(...arguments);
3349
+ this.bordered = false;
3350
+ this.open = false;
3351
+ this.toggleLabel = "Toggle sidebar";
3352
+ this.handleDocumentKeydown = (event) => {
3353
+ if (event.key === "Escape" && this.open) {
3354
+ this.close();
3355
+ }
3356
+ };
3357
+ }
3358
+ get id() {
3359
+ return super.id;
3360
+ }
3361
+ set id(value) {
3362
+ super.id = value;
3363
+ }
3364
+ get title() {
3365
+ return super.title;
3366
+ }
3367
+ set title(value) {
3368
+ super.title = value;
3369
+ }
3370
+ getContentContainer() {
3371
+ return this.querySelector("[data-sp-sidebar-native]");
3372
+ }
3373
+ isInternalNode(node) {
3374
+ if (node.nodeType !== Node.ELEMENT_NODE) {
3375
+ return false;
3376
+ }
3377
+ const el = node;
3378
+ return el.hasAttribute("data-sp-sidebar-native") || el.hasAttribute("data-sp-sidebar-toggle") || el.hasAttribute("data-sp-sidebar-backdrop");
3379
+ }
3380
+ willUpdate(changedProperties) {
3381
+ if (changedProperties.has("bordered") && this.bordered == null) {
3382
+ this.bordered = false;
3383
+ }
3384
+ if (changedProperties.has("open") && this.open == null) {
3385
+ this.open = false;
3386
+ }
3387
+ if (changedProperties.has("toggleLabel") && !this.toggleLabel) {
3388
+ this.toggleLabel = "Toggle sidebar";
3389
+ }
3390
+ if (changedProperties.has("open")) {
3391
+ HTMLElement.prototype.setAttribute.call(
3392
+ this,
3393
+ "data-sidebar-open",
3394
+ this.open ? "true" : "false"
3395
+ );
3396
+ }
3397
+ }
3398
+ connectedCallback() {
3399
+ super.connectedCallback();
3400
+ HTMLElement.prototype.setAttribute.call(
3401
+ this,
3402
+ "data-sidebar-open",
3403
+ this.open ? "true" : "false"
3404
+ );
3405
+ document.addEventListener("keydown", this.handleDocumentKeydown);
3406
+ }
3407
+ disconnectedCallback() {
3408
+ document.removeEventListener("keydown", this.handleDocumentKeydown);
3409
+ super.disconnectedCallback();
3410
+ }
3411
+ toggle() {
3412
+ if (this.open) {
3413
+ this.close();
3414
+ } else {
3415
+ this.openSidebar();
3416
+ }
3417
+ }
3418
+ openSidebar() {
3419
+ if (this.open) {
3420
+ return;
3421
+ }
3422
+ this.open = true;
3423
+ this.dispatchEvent(new CustomEvent("sp-open", { bubbles: true }));
3424
+ }
3425
+ close() {
3426
+ if (!this.open) {
3427
+ return;
3428
+ }
3429
+ this.open = false;
3430
+ this.dispatchEvent(new CustomEvent("sp-close", { bubbles: true }));
3431
+ }
3432
+ get sidebarClasses() {
3433
+ return spectreUi.getSidebarClasses({ bordered: this.bordered ?? false });
3434
+ }
3435
+ render() {
3436
+ return lit.html`<button
3437
+ aria-expanded="${this.open ? "true" : "false"}"
3438
+ aria-label="${ifDefined_js.ifDefined(this.toggleLabel)}"
3439
+ class="${spectreUi.getSidebarToggleClasses()}"
3440
+ data-sp-sidebar-toggle
3441
+ type="button"
3442
+ @click="${() => this.toggle()}"
3443
+ >
3444
+ &#9776;
3445
+ </button>
3446
+ <div
3447
+ class="${spectreUi.getSidebarBackdropClasses()}"
3448
+ data-sp-sidebar-backdrop
3449
+ @click="${() => this.close()}"
3450
+ ></div>
3451
+ <aside
3452
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
3453
+ class="${this.sidebarClasses}"
3454
+ data-sp-sidebar-native
3455
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
3456
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
3457
+ >
3458
+ ${this.hasProjectedContent ? this.projectedContent : lit.nothing}
3459
+ </aside>`;
3460
+ }
3461
+ };
3462
+ SpectreSidebarElement.properties = {
3463
+ bordered: { type: Boolean, reflect: true },
3464
+ open: { type: Boolean, reflect: false },
3465
+ toggleLabel: { attribute: "toggle-label", type: String }
3466
+ };
3467
+ function defineSpectreSidebar(tagName = "sp-sidebar") {
3468
+ const existingElement = customElements.get(tagName);
3469
+ if (existingElement) {
3470
+ return existingElement;
3471
+ }
3472
+ customElements.define(tagName, SpectreSidebarElement);
3473
+ return SpectreSidebarElement;
3474
+ }
3475
+ var SpectreToastElement = class extends SpectreBaseElement {
3476
+ constructor() {
3477
+ super(...arguments);
3478
+ this.dismissed = false;
3479
+ this.fullWidth = false;
3480
+ this.variant = "info";
3481
+ this.iconContent = [];
3482
+ this.bodyContent = [];
3483
+ }
3484
+ get id() {
3485
+ return super.id;
3486
+ }
3487
+ set id(value) {
3488
+ super.id = value;
3489
+ }
3490
+ get title() {
3491
+ return super.title;
3492
+ }
3493
+ set title(value) {
3494
+ super.title = value;
3495
+ }
3496
+ isInternalNode(node) {
3497
+ if (node.nodeType !== Node.ELEMENT_NODE) {
3498
+ return false;
3499
+ }
3500
+ const el = node;
3501
+ return el.hasAttribute("data-sp-toast-native") || el.hasAttribute("data-sp-toast-icon");
3502
+ }
3503
+ syncProjectedContent() {
3504
+ const nextIconContent = [];
3505
+ const nextBodyContent = [];
3506
+ this.childNodes.forEach((node) => {
3507
+ if (this.isInternalNode(node)) {
3508
+ return;
3509
+ }
3510
+ const isIconSlot = node.nodeType === Node.ELEMENT_NODE && node.getAttribute("slot") === "icon";
3511
+ if (isIconSlot) {
3512
+ nextIconContent.push(node);
3513
+ } else {
3514
+ nextBodyContent.push(node);
3515
+ }
3516
+ });
3517
+ const changed = nextIconContent.length !== this.iconContent.length || nextIconContent.some((n, i) => n !== this.iconContent[i]) || nextBodyContent.length !== this.bodyContent.length || nextBodyContent.some((n, i) => n !== this.bodyContent[i]);
3518
+ if (changed) {
3519
+ this.iconContent = nextIconContent;
3520
+ this.bodyContent = nextBodyContent;
3521
+ }
3522
+ return changed;
3523
+ }
3524
+ get hasIconContent() {
3525
+ return hasMeaningfulContent(this.iconContent);
3526
+ }
3527
+ get hasBodyContent() {
3528
+ return hasMeaningfulContent(this.bodyContent);
3529
+ }
3530
+ connectedCallback() {
3531
+ super.connectedCallback();
3532
+ this.syncProjectedContent();
3533
+ this.startContentObserver();
3534
+ }
3535
+ disconnectedCallback() {
3536
+ this.stopContentObserver();
3537
+ this.clearAutoDismissTimer();
3538
+ super.disconnectedCallback();
3539
+ }
3540
+ update(changedProperties) {
3541
+ this.stopContentObserver();
3542
+ super.update(changedProperties);
3543
+ this.startContentObserver();
3544
+ }
3545
+ startContentObserver() {
3546
+ if (this.contentObserver) {
3547
+ return;
3548
+ }
3549
+ this.contentObserver = new MutationObserver(() => {
3550
+ if (this.syncProjectedContent()) {
3551
+ this.requestUpdate();
3552
+ }
3553
+ });
3554
+ this.contentObserver.observe(this, { childList: true });
3555
+ }
3556
+ stopContentObserver() {
3557
+ this.contentObserver?.disconnect();
3558
+ this.contentObserver = void 0;
3559
+ }
3560
+ willUpdate(changedProperties) {
3561
+ if (changedProperties.has("dismissed") && this.dismissed == null) {
3562
+ this.dismissed = false;
3563
+ }
3564
+ if (changedProperties.has("fullWidth") && this.fullWidth == null) {
3565
+ this.fullWidth = false;
3566
+ }
3567
+ if (changedProperties.has("variant") && (this.variant == null || !isToastVariant(this.variant))) {
3568
+ this.variant = "info";
3569
+ }
3570
+ if (changedProperties.has("autoDismiss")) {
3571
+ this.autoDismiss = normalizeInt(this.autoDismiss, void 0, 0);
3572
+ }
3573
+ }
3574
+ updated(changedProperties) {
3575
+ super.updated(changedProperties);
3576
+ if (changedProperties.has("dismissed") || changedProperties.has("autoDismiss")) {
3577
+ this.clearAutoDismissTimer();
3578
+ if (!this.dismissed && this.autoDismiss) {
3579
+ this.autoDismissTimer = setTimeout(() => {
3580
+ this.dismiss();
3581
+ }, this.autoDismiss);
3582
+ }
3583
+ }
3584
+ }
3585
+ clearAutoDismissTimer() {
3586
+ if (this.autoDismissTimer) {
3587
+ clearTimeout(this.autoDismissTimer);
3588
+ this.autoDismissTimer = void 0;
3589
+ }
3590
+ }
3591
+ show() {
3592
+ if (!this.dismissed) {
3593
+ return;
3594
+ }
3595
+ this.dismissed = false;
3596
+ this.dispatchEvent(new CustomEvent("sp-show", { bubbles: true }));
3597
+ }
3598
+ dismiss() {
3599
+ if (this.dismissed) {
3600
+ return;
3601
+ }
3602
+ this.dismissed = true;
3603
+ this.dispatchEvent(new CustomEvent("sp-dismiss", { bubbles: true }));
3604
+ }
3605
+ get toastClasses() {
3606
+ return spectreUi.getToastClasses({
3607
+ variant: this.variant,
3608
+ dismissed: this.dismissed ?? false,
3609
+ fullWidth: this.fullWidth ?? false
3610
+ });
3611
+ }
3612
+ get iconClasses() {
3613
+ return spectreUi.getToastIconClasses({ variant: this.variant });
3614
+ }
3615
+ render() {
3616
+ return lit.html`<div
3617
+ aria-atomic="true"
3618
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
3619
+ aria-live="polite"
3620
+ class="${this.toastClasses}"
3621
+ data-sp-toast-native
3622
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
3623
+ role="status"
3624
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
3625
+ >
3626
+ ${this.hasIconContent ? lit.html`<div class="${this.iconClasses}" data-sp-toast-icon>
3627
+ ${this.iconContent}
3628
+ </div>` : lit.nothing}
3629
+ ${this.hasBodyContent ? this.bodyContent : lit.nothing}
3630
+ </div>`;
3631
+ }
3632
+ };
3633
+ SpectreToastElement.properties = {
3634
+ autoDismiss: { attribute: "auto-dismiss", type: Number },
3635
+ dismissed: { type: Boolean, reflect: true },
3636
+ fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
3637
+ variant: { type: String, reflect: true }
3638
+ };
3639
+ function defineSpectreToast(tagName = "sp-toast") {
3640
+ const existingElement = customElements.get(tagName);
3641
+ if (existingElement) {
3642
+ return existingElement;
3643
+ }
3644
+ customElements.define(tagName, SpectreToastElement);
3645
+ return SpectreToastElement;
3646
+ }
3647
+ var SpectreTooltipElement = class extends SpectreBaseElement {
3648
+ constructor() {
3649
+ super(...arguments);
3650
+ this.placement = "top";
3651
+ this.visible = false;
3652
+ this.triggerContent = [];
3653
+ this.tooltipContent = [];
3654
+ }
3655
+ get id() {
3656
+ return super.id;
3657
+ }
3658
+ set id(value) {
3659
+ super.id = value;
3660
+ }
3661
+ get title() {
3662
+ return super.title;
3663
+ }
3664
+ set title(value) {
3665
+ super.title = value;
3666
+ }
3667
+ isInternalNode(node) {
3668
+ if (node.nodeType !== Node.ELEMENT_NODE) {
3669
+ return false;
3670
+ }
3671
+ const el = node;
3672
+ return el.hasAttribute("data-sp-tooltip-native") || el.hasAttribute("data-sp-tooltip-trigger");
3673
+ }
3674
+ syncProjectedContent() {
3675
+ const nextTooltipContent = [];
3676
+ const nextTriggerContent = [];
3677
+ this.childNodes.forEach((node) => {
3678
+ if (this.isInternalNode(node)) {
3679
+ return;
3680
+ }
3681
+ const isTooltipSlot = node.nodeType === Node.ELEMENT_NODE && node.getAttribute("slot") === "tooltip";
3682
+ if (isTooltipSlot) {
3683
+ nextTooltipContent.push(node);
3684
+ } else {
3685
+ nextTriggerContent.push(node);
3686
+ }
3687
+ });
3688
+ const changed = nextTooltipContent.length !== this.tooltipContent.length || nextTooltipContent.some((n, i) => n !== this.tooltipContent[i]) || nextTriggerContent.length !== this.triggerContent.length || nextTriggerContent.some((n, i) => n !== this.triggerContent[i]);
3689
+ if (changed) {
3690
+ this.tooltipContent = nextTooltipContent;
3691
+ this.triggerContent = nextTriggerContent;
3692
+ }
3693
+ return changed;
3694
+ }
3695
+ get hasTooltipContent() {
3696
+ return hasMeaningfulContent(this.tooltipContent);
3697
+ }
3698
+ connectedCallback() {
3699
+ var _a, _b;
3700
+ super.connectedCallback();
3701
+ this.syncProjectedContent();
3702
+ this.startContentObserver();
3703
+ (_a = this.style).position || (_a.position = "relative");
3704
+ (_b = this.style).display || (_b.display = "inline-block");
3705
+ }
3706
+ disconnectedCallback() {
3707
+ this.stopContentObserver();
3708
+ super.disconnectedCallback();
3709
+ }
3710
+ update(changedProperties) {
3711
+ this.stopContentObserver();
3712
+ super.update(changedProperties);
3713
+ this.startContentObserver();
3714
+ }
3715
+ startContentObserver() {
3716
+ if (this.contentObserver) {
3717
+ return;
3718
+ }
3719
+ this.contentObserver = new MutationObserver(() => {
3720
+ if (this.syncProjectedContent()) {
3721
+ this.requestUpdate();
3722
+ }
3723
+ });
3724
+ this.contentObserver.observe(this, { childList: true });
3725
+ }
3726
+ stopContentObserver() {
3727
+ this.contentObserver?.disconnect();
3728
+ this.contentObserver = void 0;
3729
+ }
3730
+ willUpdate(changedProperties) {
3731
+ if (changedProperties.has("placement") && (this.placement == null || !isTooltipPlacement(this.placement))) {
3732
+ this.placement = "top";
3733
+ }
3734
+ if (changedProperties.has("visible") && this.visible == null) {
3735
+ this.visible = false;
3736
+ }
3737
+ }
3738
+ show() {
3739
+ if (this.visible) {
3740
+ return;
3741
+ }
3742
+ this.visible = true;
3743
+ this.dispatchEvent(new CustomEvent("sp-show", { bubbles: true }));
3744
+ }
3745
+ hide() {
3746
+ if (!this.visible) {
3747
+ return;
3748
+ }
3749
+ this.visible = false;
3750
+ this.dispatchEvent(new CustomEvent("sp-hide", { bubbles: true }));
3751
+ }
3752
+ get tooltipClasses() {
3753
+ return spectreUi.getTooltipClasses({
3754
+ placement: this.placement,
3755
+ visible: this.visible ?? false
3756
+ });
3757
+ }
3758
+ render() {
3759
+ return lit.html`<span
3760
+ data-sp-tooltip-trigger
3761
+ @focusin="${() => this.show()}"
3762
+ @focusout="${() => this.hide()}"
3763
+ @mouseenter="${() => this.show()}"
3764
+ @mouseleave="${() => this.hide()}"
3765
+ >
3766
+ ${this.triggerContent}
3767
+ </span>
3768
+ <span
3769
+ aria-label="${ifDefined_js.ifDefined(this.forwardedAriaLabel)}"
3770
+ class="${this.tooltipClasses}"
3771
+ data-sp-tooltip-native
3772
+ id="${ifDefined_js.ifDefined(this.id || void 0)}"
3773
+ role="tooltip"
3774
+ title="${ifDefined_js.ifDefined(this.title || void 0)}"
3775
+ >
3776
+ ${this.hasTooltipContent ? this.tooltipContent : lit.nothing}
3777
+ </span>`;
3778
+ }
3779
+ };
3780
+ SpectreTooltipElement.properties = {
3781
+ placement: { type: String, reflect: true },
3782
+ visible: { type: Boolean, reflect: true }
3783
+ };
3784
+ function defineSpectreTooltip(tagName = "sp-tooltip") {
3785
+ const existingElement = customElements.get(tagName);
3786
+ if (existingElement) {
3787
+ return existingElement;
3788
+ }
3789
+ customElements.define(tagName, SpectreTooltipElement);
3790
+ return SpectreTooltipElement;
3791
+ }
2889
3792
 
2890
3793
  // src/index.ts
2891
3794
  function defineSpectreComponents() {
@@ -2911,6 +3814,12 @@ function defineSpectreComponents() {
2911
3814
  defineSpectreGrid();
2912
3815
  defineSpectreSection();
2913
3816
  defineSpectreStack();
3817
+ defineSpectreDropdown();
3818
+ defineSpectreModal();
3819
+ defineSpectreNav();
3820
+ defineSpectreSidebar();
3821
+ defineSpectreToast();
3822
+ defineSpectreTooltip();
2914
3823
  }
2915
3824
 
2916
3825
  exports.SpectreAlertElement = SpectreAlertElement;
@@ -2920,21 +3829,27 @@ exports.SpectreButtonElement = SpectreButtonElement;
2920
3829
  exports.SpectreCardElement = SpectreCardElement;
2921
3830
  exports.SpectreCheckboxElement = SpectreCheckboxElement;
2922
3831
  exports.SpectreContainerElement = SpectreContainerElement;
3832
+ exports.SpectreDropdownElement = SpectreDropdownElement;
2923
3833
  exports.SpectreFieldsetElement = SpectreFieldsetElement;
2924
3834
  exports.SpectreGridElement = SpectreGridElement;
2925
3835
  exports.SpectreIconBoxElement = SpectreIconBoxElement;
2926
3836
  exports.SpectreInputElement = SpectreInputElement;
2927
3837
  exports.SpectreLabelElement = SpectreLabelElement;
3838
+ exports.SpectreModalElement = SpectreModalElement;
3839
+ exports.SpectreNavElement = SpectreNavElement;
2928
3840
  exports.SpectrePricingCardElement = SpectrePricingCardElement;
2929
3841
  exports.SpectreRadioElement = SpectreRadioElement;
2930
3842
  exports.SpectreRatingElement = SpectreRatingElement;
2931
3843
  exports.SpectreSectionElement = SpectreSectionElement;
2932
3844
  exports.SpectreSelectElement = SpectreSelectElement;
3845
+ exports.SpectreSidebarElement = SpectreSidebarElement;
2933
3846
  exports.SpectreSpinnerElement = SpectreSpinnerElement;
2934
3847
  exports.SpectreStackElement = SpectreStackElement;
2935
3848
  exports.SpectreTagElement = SpectreTagElement;
2936
3849
  exports.SpectreTestimonialElement = SpectreTestimonialElement;
2937
3850
  exports.SpectreTextareaElement = SpectreTextareaElement;
3851
+ exports.SpectreToastElement = SpectreToastElement;
3852
+ exports.SpectreTooltipElement = SpectreTooltipElement;
2938
3853
  exports.defineSpectreAlert = defineSpectreAlert;
2939
3854
  exports.defineSpectreAvatar = defineSpectreAvatar;
2940
3855
  exports.defineSpectreBadge = defineSpectreBadge;
@@ -2943,21 +3858,27 @@ exports.defineSpectreCard = defineSpectreCard;
2943
3858
  exports.defineSpectreCheckbox = defineSpectreCheckbox;
2944
3859
  exports.defineSpectreComponents = defineSpectreComponents;
2945
3860
  exports.defineSpectreContainer = defineSpectreContainer;
3861
+ exports.defineSpectreDropdown = defineSpectreDropdown;
2946
3862
  exports.defineSpectreFieldset = defineSpectreFieldset;
2947
3863
  exports.defineSpectreGrid = defineSpectreGrid;
2948
3864
  exports.defineSpectreIconBox = defineSpectreIconBox;
2949
3865
  exports.defineSpectreInput = defineSpectreInput;
2950
3866
  exports.defineSpectreLabel = defineSpectreLabel;
3867
+ exports.defineSpectreModal = defineSpectreModal;
3868
+ exports.defineSpectreNav = defineSpectreNav;
2951
3869
  exports.defineSpectrePricingCard = defineSpectrePricingCard;
2952
3870
  exports.defineSpectreRadio = defineSpectreRadio;
2953
3871
  exports.defineSpectreRating = defineSpectreRating;
2954
3872
  exports.defineSpectreSection = defineSpectreSection;
2955
3873
  exports.defineSpectreSelect = defineSpectreSelect;
3874
+ exports.defineSpectreSidebar = defineSpectreSidebar;
2956
3875
  exports.defineSpectreSpinner = defineSpectreSpinner;
2957
3876
  exports.defineSpectreStack = defineSpectreStack;
2958
3877
  exports.defineSpectreTag = defineSpectreTag;
2959
3878
  exports.defineSpectreTestimonial = defineSpectreTestimonial;
2960
3879
  exports.defineSpectreTextarea = defineSpectreTextarea;
3880
+ exports.defineSpectreToast = defineSpectreToast;
3881
+ exports.defineSpectreTooltip = defineSpectreTooltip;
2961
3882
  exports.spectreAlertSizes = spectreInputSizes;
2962
3883
  exports.spectreAlertVariants = spectreAlertVariants;
2963
3884
  exports.spectreAvatarShapes = spectreAvatarShapes;
@@ -2969,6 +3890,7 @@ exports.spectreButtonTypes = spectreButtonTypes;
2969
3890
  exports.spectreButtonVariants = spectreButtonVariants;
2970
3891
  exports.spectreCardVariants = spectreCardVariants;
2971
3892
  exports.spectreContainerMaxWidths = spectreContainerMaxWidths;
3893
+ exports.spectreDropdownPlacements = spectreDropdownPlacements;
2972
3894
  exports.spectreGridColumns = spectreGridColumns;
2973
3895
  exports.spectreGridGaps = spectreGridGaps;
2974
3896
  exports.spectreIconBoxSizes = spectreInputSizes;
@@ -2984,5 +3906,7 @@ exports.spectreStackDirections = spectreStackDirections;
2984
3906
  exports.spectreTagSizes = spectreInputSizes;
2985
3907
  exports.spectreTagVariants = spectreTagVariants;
2986
3908
  exports.spectreTestimonialVariants = spectreTestimonialVariants;
3909
+ exports.spectreToastVariants = spectreToastVariants;
3910
+ exports.spectreTooltipPlacements = spectreTooltipPlacements;
2987
3911
  //# sourceMappingURL=index.cjs.map
2988
3912
  //# sourceMappingURL=index.cjs.map