@compa11y/web 0.1.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.
@@ -0,0 +1,533 @@
1
+ (function(a,o){typeof exports=="object"&&typeof module<"u"?o(exports,require("@compa11y/core")):typeof define=="function"&&define.amd?define(["exports","@compa11y/core"],o):(a=typeof globalThis<"u"?globalThis:a||self,o(a.compa11y={},a.compa11yCore))})(this,function(a,o){"use strict";class d extends HTMLElement{constructor(){super(),this._internals=null,this._id=o.generateId(this.tagName.toLowerCase().replace("a11y-","")),"attachInternals"in this&&(this._internals=this.attachInternals())}static get observedAttributes(){return[]}connectedCallback(){this.setupAccessibility(),this.render(),this.setupEventListeners()}disconnectedCallback(){this.cleanupEventListeners()}attributeChangedCallback(e,t,i){t!==i&&this.onAttributeChange(e,t,i)}setupEventListeners(){}cleanupEventListeners(){}onAttributeChange(e,t,i){}emit(e,t){return this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0,cancelable:!0}))}getSlot(e){var t;return((t=this.shadowRoot)==null?void 0:t.querySelector(`slot[name="${e}"]`))??null}getSlottedElements(e){var s;const t=e?`slot[name="${e}"]`:"slot:not([name])",i=(s=this.shadowRoot)==null?void 0:s.querySelector(t);return(i==null?void 0:i.assignedElements())??[]}}function c(l,e){customElements.get(l)||customElements.define(l,e)}const _=`
2
+ appearance: none;
3
+ background: none;
4
+ border: none;
5
+ padding: 0;
6
+ margin: 0;
7
+ font: inherit;
8
+ color: inherit;
9
+ cursor: pointer;
10
+ `,u=`
11
+ :host {
12
+ display: block;
13
+ box-sizing: border-box;
14
+ }
15
+
16
+ :host([hidden]) {
17
+ display: none !important;
18
+ }
19
+
20
+ *,
21
+ *::before,
22
+ *::after {
23
+ box-sizing: inherit;
24
+ }
25
+
26
+
27
+ :host(:focus-visible),
28
+ :focus-visible {
29
+ outline: 2px solid var(--compa11y-focus-color, #0066cc);
30
+ outline-offset: 2px;
31
+ }
32
+
33
+ `,x=`
34
+ ${u}
35
+
36
+ :host {
37
+ position: fixed;
38
+ inset: 0;
39
+ z-index: var(--compa11y-dialog-z-index, 9999);
40
+ display: flex;
41
+ align-items: center;
42
+ justify-content: center;
43
+ }
44
+
45
+ .overlay {
46
+ position: absolute;
47
+ inset: 0;
48
+ background: var(--compa11y-dialog-overlay-bg, rgba(0, 0, 0, 0.5));
49
+ }
50
+
51
+ .dialog {
52
+ position: relative;
53
+ background: var(--compa11y-dialog-bg, white);
54
+ border-radius: var(--compa11y-dialog-radius, 8px);
55
+ padding: var(--compa11y-dialog-padding, 1.5rem);
56
+ max-width: var(--compa11y-dialog-max-width, 500px);
57
+ max-height: var(--compa11y-dialog-max-height, 85vh);
58
+ overflow: auto;
59
+ box-shadow: var(--compa11y-dialog-shadow, 0 25px 50px -12px rgba(0, 0, 0, 0.25));
60
+ }
61
+
62
+ ::slotted([slot="title"]) {
63
+ margin: 0 0 0.5rem 0;
64
+ font-size: 1.25rem;
65
+ font-weight: 600;
66
+ }
67
+
68
+ ::slotted([slot="description"]) {
69
+ margin: 0 0 1rem 0;
70
+ color: var(--compa11y-dialog-description-color, #666);
71
+ }
72
+ `,w=`
73
+ ${u}
74
+
75
+ :host {
76
+ position: relative;
77
+ display: inline-block;
78
+ }
79
+
80
+ .menu-content {
81
+ position: absolute;
82
+ top: 100%;
83
+ left: 0;
84
+ z-index: var(--compa11y-menu-z-index, 1000);
85
+ min-width: var(--compa11y-menu-min-width, 160px);
86
+ background: var(--compa11y-menu-bg, white);
87
+ border: var(--compa11y-menu-border, 1px solid #e0e0e0);
88
+ border-radius: var(--compa11y-menu-radius, 4px);
89
+ box-shadow: var(--compa11y-menu-shadow, 0 4px 6px -1px rgba(0, 0, 0, 0.1));
90
+ padding: var(--compa11y-menu-padding, 0.25rem 0);
91
+ margin-top: var(--compa11y-menu-offset, 4px);
92
+ }
93
+
94
+ .menu-content[hidden] {
95
+ display: none;
96
+ }
97
+
98
+ ::slotted([role="menuitem"]) {
99
+ display: block;
100
+ width: 100%;
101
+ padding: 0.5rem 1rem;
102
+ text-align: left;
103
+ background: none;
104
+ border: none;
105
+ cursor: pointer;
106
+ font: inherit;
107
+ }
108
+
109
+ ::slotted([role="menuitem"]:hover),
110
+ ::slotted([role="menuitem"][data-highlighted="true"]) {
111
+ background: var(--compa11y-menu-item-hover-bg, #f5f5f5);
112
+ }
113
+
114
+ ::slotted([role="menuitem"][aria-disabled="true"]) {
115
+ opacity: 0.5;
116
+ cursor: not-allowed;
117
+ }
118
+
119
+ ::slotted([role="separator"]) {
120
+ height: 1px;
121
+ margin: 0.25rem 0;
122
+ background: var(--compa11y-menu-separator-color, #e0e0e0);
123
+ }
124
+ `,E=`
125
+ ${u}
126
+
127
+ .tablist {
128
+ display: flex;
129
+ border-bottom: var(--compa11y-tabs-border, 1px solid #e0e0e0);
130
+ gap: var(--compa11y-tabs-gap, 0);
131
+ }
132
+
133
+ :host([orientation="vertical"]) .tablist {
134
+ flex-direction: column;
135
+ border-bottom: none;
136
+ border-right: var(--compa11y-tabs-border, 1px solid #e0e0e0);
137
+ }
138
+
139
+ ::slotted([role="tab"]) {
140
+ ${_}
141
+ padding: var(--compa11y-tab-padding, 0.75rem 1rem);
142
+ border-bottom: 2px solid transparent;
143
+ margin-bottom: -1px;
144
+ font-weight: 500;
145
+ color: var(--compa11y-tab-color, #666);
146
+ transition: all 0.15s ease;
147
+ }
148
+
149
+ ::slotted([role="tab"]:hover) {
150
+ color: var(--compa11y-tab-hover-color, #333);
151
+ }
152
+
153
+ ::slotted([role="tab"][aria-selected="true"]) {
154
+ color: var(--compa11y-tab-active-color, #0066cc);
155
+ border-bottom-color: currentColor;
156
+ }
157
+
158
+ ::slotted([role="tab"][aria-disabled="true"]) {
159
+ opacity: 0.5;
160
+ cursor: not-allowed;
161
+ }
162
+
163
+ ::slotted([role="tabpanel"]) {
164
+ padding: var(--compa11y-tabpanel-padding, 1rem 0);
165
+ }
166
+
167
+ ::slotted([role="tabpanel"][hidden]) {
168
+ display: none;
169
+ }
170
+ `,A=`
171
+ ${u}
172
+
173
+ :host {
174
+ display: inline-block;
175
+ position: relative;
176
+ width: var(--compa11y-combobox-width, 250px);
177
+ }
178
+
179
+ .combobox-wrapper {
180
+ position: relative;
181
+ }
182
+
183
+ .input-wrapper {
184
+ position: relative;
185
+ display: flex;
186
+ align-items: center;
187
+ }
188
+
189
+ input {
190
+ width: 100%;
191
+ padding: var(--compa11y-combobox-input-padding, 0.5rem 2rem 0.5rem 0.75rem);
192
+ border: var(--compa11y-combobox-border, 1px solid #ccc);
193
+ border-radius: var(--compa11y-combobox-radius, 4px);
194
+ font: inherit;
195
+ background: var(--compa11y-combobox-bg, white);
196
+ color: var(--compa11y-combobox-color, inherit);
197
+ }
198
+
199
+ input:focus {
200
+ outline: 2px solid var(--compa11y-focus-color, #0066cc);
201
+ outline-offset: -1px;
202
+ border-color: var(--compa11y-focus-color, #0066cc);
203
+ }
204
+
205
+ input::placeholder {
206
+ color: var(--compa11y-combobox-placeholder-color, #999);
207
+ }
208
+
209
+ input:disabled {
210
+ background: var(--compa11y-combobox-disabled-bg, #f5f5f5);
211
+ cursor: not-allowed;
212
+ opacity: 0.7;
213
+ }
214
+
215
+ .chevron {
216
+ position: absolute;
217
+ right: 0.5rem;
218
+ pointer-events: none;
219
+ font-size: 0.75rem;
220
+ color: var(--compa11y-combobox-chevron-color, #666);
221
+ transition: transform 0.15s ease;
222
+ }
223
+
224
+ :host([open]) .chevron {
225
+ transform: rotate(180deg);
226
+ }
227
+
228
+ .clear-button {
229
+ ${_}
230
+ position: absolute;
231
+ right: 1.5rem;
232
+ width: 1.25rem;
233
+ height: 1.25rem;
234
+ display: flex;
235
+ align-items: center;
236
+ justify-content: center;
237
+ border-radius: 50%;
238
+ font-size: 1rem;
239
+ color: var(--compa11y-combobox-clear-color, #666);
240
+ }
241
+
242
+ .clear-button:hover {
243
+ background: var(--compa11y-combobox-clear-hover-bg, rgba(0, 0, 0, 0.1));
244
+ }
245
+
246
+ .clear-button[hidden] {
247
+ display: none;
248
+ }
249
+
250
+ .listbox {
251
+ position: absolute;
252
+ top: 100%;
253
+ left: 0;
254
+ right: 0;
255
+ z-index: var(--compa11y-combobox-z-index, 1000);
256
+ max-height: var(--compa11y-combobox-max-height, 200px);
257
+ overflow-y: auto;
258
+ margin: 0;
259
+ padding: var(--compa11y-combobox-listbox-padding, 0.25rem 0);
260
+ background: var(--compa11y-combobox-listbox-bg, white);
261
+ border: var(--compa11y-combobox-listbox-border, 1px solid #e0e0e0);
262
+ border-radius: var(--compa11y-combobox-radius, 4px);
263
+ box-shadow: var(--compa11y-combobox-shadow, 0 4px 6px -1px rgba(0, 0, 0, 0.1));
264
+ list-style: none;
265
+ }
266
+
267
+ /* Flip chevron when listbox is positioned above */
268
+ :host([data-position="top"]) .chevron {
269
+ transform: rotate(180deg);
270
+ }
271
+
272
+ :host([data-position="top"][open]) .chevron {
273
+ transform: rotate(0deg);
274
+ }
275
+
276
+ .listbox[hidden] {
277
+ display: none;
278
+ }
279
+
280
+ .listbox li[role="option"] {
281
+ padding: var(--compa11y-combobox-option-padding, 0.5rem 0.75rem);
282
+ cursor: pointer;
283
+ transition: background 0.1s ease;
284
+ }
285
+
286
+ .listbox li[role="option"]:hover,
287
+ .listbox li[role="option"].highlighted {
288
+ background: var(--compa11y-combobox-option-hover-bg, #f5f5f5);
289
+ }
290
+
291
+ .listbox li[role="option"][aria-selected="true"] {
292
+ background: var(--compa11y-combobox-option-selected-bg, #e6f0ff);
293
+ font-weight: 500;
294
+ }
295
+
296
+ .listbox li[role="option"].disabled,
297
+ .listbox li[role="option"][aria-disabled="true"] {
298
+ opacity: 0.5;
299
+ cursor: not-allowed;
300
+ }
301
+
302
+ .empty-message {
303
+ padding: var(--compa11y-combobox-option-padding, 0.5rem 0.75rem);
304
+ color: var(--compa11y-combobox-empty-color, #666);
305
+ font-style: italic;
306
+ }
307
+
308
+ .options-source {
309
+ display: none;
310
+ }
311
+ `,k=`
312
+ ${u}
313
+
314
+ :host {
315
+ display: inline-block;
316
+ }
317
+
318
+ .switch-wrapper {
319
+ display: inline-flex;
320
+ align-items: center;
321
+ gap: var(--compa11y-switch-gap, 0.5rem);
322
+ }
323
+
324
+ /* Size variants */
325
+ .switch-wrapper.size-sm .switch-track {
326
+ width: var(--compa11y-switch-width-sm, 32px);
327
+ height: var(--compa11y-switch-height-sm, 18px);
328
+ }
329
+
330
+ .switch-wrapper.size-sm .switch-thumb {
331
+ width: var(--compa11y-switch-thumb-sm, 14px);
332
+ height: var(--compa11y-switch-thumb-sm, 14px);
333
+ }
334
+
335
+ .switch-wrapper.size-sm .switch-track.checked .switch-thumb {
336
+ transform: translateX(14px);
337
+ }
338
+
339
+ .switch-wrapper.size-md .switch-track {
340
+ width: var(--compa11y-switch-width-md, 44px);
341
+ height: var(--compa11y-switch-height-md, 24px);
342
+ }
343
+
344
+ .switch-wrapper.size-md .switch-thumb {
345
+ width: var(--compa11y-switch-thumb-md, 20px);
346
+ height: var(--compa11y-switch-thumb-md, 20px);
347
+ }
348
+
349
+ .switch-wrapper.size-md .switch-track.checked .switch-thumb {
350
+ transform: translateX(20px);
351
+ }
352
+
353
+ .switch-wrapper.size-lg .switch-track {
354
+ width: var(--compa11y-switch-width-lg, 56px);
355
+ height: var(--compa11y-switch-height-lg, 30px);
356
+ }
357
+
358
+ .switch-wrapper.size-lg .switch-thumb {
359
+ width: var(--compa11y-switch-thumb-lg, 26px);
360
+ height: var(--compa11y-switch-thumb-lg, 26px);
361
+ }
362
+
363
+ .switch-wrapper.size-lg .switch-track.checked .switch-thumb {
364
+ transform: translateX(26px);
365
+ }
366
+
367
+ .switch-track {
368
+ position: relative;
369
+ display: inline-flex;
370
+ align-items: center;
371
+ flex-shrink: 0;
372
+ padding: 2px;
373
+ border: none;
374
+ border-radius: var(--compa11y-switch-radius, 9999px);
375
+ background: var(--compa11y-switch-bg, #d1d5db);
376
+ cursor: pointer;
377
+ transition: background-color 0.2s ease;
378
+ outline: none;
379
+ }
380
+
381
+ .switch-track:focus-visible {
382
+ outline: 2px solid var(--compa11y-focus-color, #0066cc);
383
+ outline-offset: 2px;
384
+ }
385
+
386
+ .switch-track.checked {
387
+ background: var(--compa11y-switch-checked-bg, #0066cc);
388
+ }
389
+
390
+ .switch-track:disabled {
391
+ opacity: 0.5;
392
+ cursor: not-allowed;
393
+ }
394
+
395
+ .switch-thumb {
396
+ position: absolute;
397
+ left: 2px;
398
+ background: var(--compa11y-switch-thumb-bg, white);
399
+ border-radius: 50%;
400
+ box-shadow: var(--compa11y-switch-thumb-shadow, 0 1px 3px rgba(0, 0, 0, 0.2));
401
+ transition: transform 0.2s ease;
402
+ pointer-events: none;
403
+ }
404
+
405
+ .switch-label {
406
+ user-select: none;
407
+ cursor: pointer;
408
+ color: var(--compa11y-switch-label-color, inherit);
409
+ }
410
+
411
+ .switch-label.disabled {
412
+ opacity: 0.5;
413
+ cursor: not-allowed;
414
+ }
415
+ `,v='button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';class b extends d{constructor(){super(...arguments),this._open=!1,this._previouslyFocused=null,this._triggerElement=null,this.handleTriggerClick=()=>{this.open=!0},this.handleClose=()=>{this.open=!1},this.handleKeyDown=e=>{var t;if(this._open){if(e.key==="Escape"){this.getAttribute("close-on-escape")!=="false"&&(e.preventDefault(),this.handleClose());return}if(e.key==="Tab"){e.preventDefault();const i=this.getFocusableElements();if(i.length===0)return;const s=((t=this.shadowRoot)==null?void 0:t.activeElement)||document.activeElement;let n=i.findIndex(p=>p===s);n===-1&&(n=e.shiftKey?0:i.length-1);let r;e.shiftKey?r=n===0?i.length-1:n-1:r=n===i.length-1?0:n+1;const h=i[r];h&&h.focus()}}}}static get observedAttributes(){return["open","trigger","close-on-outside-click","close-on-escape"]}get open(){return this._open}set open(e){const t=this._open;this._open=e,e!==t&&(e?this.showDialog():this.hideDialog()),this.toggleAttribute("open",e)}setupAccessibility(){}render(){const e=this.attachShadow({mode:"open"}),t=`${this._id}-title`,i=`${this._id}-desc`;e.innerHTML=`
416
+ <style>${x}</style>
417
+ <div class="overlay" part="overlay"></div>
418
+ <div
419
+ class="dialog"
420
+ role="dialog"
421
+ aria-modal="true"
422
+ aria-labelledby="${t}"
423
+ aria-describedby="${i}"
424
+ part="dialog"
425
+ >
426
+ <div id="${t}" part="title">
427
+ <slot name="title"></slot>
428
+ </div>
429
+ <div id="${i}" part="description">
430
+ <slot name="description"></slot>
431
+ </div>
432
+ <div part="content">
433
+ <slot></slot>
434
+ </div>
435
+ <div part="actions">
436
+ <slot name="actions"></slot>
437
+ </div>
438
+ </div>
439
+ `,this._open||(this.style.display="none")}setupEventListeners(){var i;const e=this.getAttribute("trigger");if(e){const s=()=>{this._triggerElement=document.querySelector(e),this._triggerElement&&(this._triggerElement.addEventListener("click",this.handleTriggerClick),this._triggerElement.hasAttribute("tabindex")||this._triggerElement.setAttribute("tabindex","0"))};s(),this._triggerElement||requestAnimationFrame(()=>{s(),this._triggerElement||setTimeout(s,0)})}const t=(i=this.shadowRoot)==null?void 0:i.querySelector(".overlay");this.getAttribute("close-on-outside-click")!=="false"&&(t==null||t.addEventListener("click",this.handleClose)),this.addEventListener("keydown",this.handleKeyDown)}cleanupEventListeners(){var e;(e=this._triggerElement)==null||e.removeEventListener("click",this.handleTriggerClick),this.removeEventListener("keydown",this.handleKeyDown)}onAttributeChange(e,t,i){e==="open"&&(this.open=i!==null)}getFocusableElements(){const e=[];return this.querySelectorAll(v).forEach(i=>e.push(i)),this.shadowRoot&&this.shadowRoot.querySelectorAll(v).forEach(s=>{s.classList.contains("overlay")||e.push(s)}),e}showDialog(){this._previouslyFocused=document.activeElement,this.style.display="flex",requestAnimationFrame(()=>{const t=this.getFocusableElements()[0];t&&t.focus()}),document.body.style.overflow="hidden",o.announce("Dialog opened",{politeness:"polite"}),this.emit("a11y-dialog-open")}hideDialog(){var e;this.style.display="none",document.body.style.overflow="",(e=this._previouslyFocused)==null||e.focus(),this._previouslyFocused=null,o.announce("Dialog closed",{politeness:"polite"}),this.emit("a11y-dialog-close")}show(){this.open=!0}close(){this.open=!1}}c("a11y-dialog",b);class m extends d{constructor(){super(...arguments),this._open=!1,this._highlightedIndex=-1,this._menuItems=[],this.updateMenuItems=()=>{this._menuItems=Array.from(this.querySelectorAll('[role="menuitem"]:not([aria-disabled="true"])')),this._menuItems.forEach((e,t)=>{e.id=e.id||`${this._id}-item-${t}`,e.setAttribute("tabindex","-1")})},this._lastClickTime=0,this.handleTriggerClick=()=>{const e=Date.now();e-this._lastClickTime<50||(this._lastClickTime=e,this.toggle())},this.handleTriggerKeyDown=e=>{switch(e.key){case"Enter":case" ":e.preventDefault(),this.toggle(),this._open&&this.highlightItem(0);break;case"ArrowDown":e.preventDefault(),this._open||this.show(),this.highlightItem(0);break;case"ArrowUp":e.preventDefault(),this._open||this.show(),this.highlightItem(this._menuItems.length-1);break}},this.handleMenuKeyDown=e=>{if(!this._open)return;const t=e.target;if(!(!t.hasAttribute("role")||t.getAttribute("role")!=="menuitem"))switch(e.key){case"ArrowDown":e.preventDefault(),this.highlightItem((this._highlightedIndex+1)%this._menuItems.length);break;case"ArrowUp":e.preventDefault(),this.highlightItem((this._highlightedIndex-1+this._menuItems.length)%this._menuItems.length);break;case"Home":e.preventDefault(),this.highlightItem(0);break;case"End":e.preventDefault(),this.highlightItem(this._menuItems.length-1);break;case"Enter":case" ":e.preventDefault(),this.selectItem(this._highlightedIndex);break;case"Escape":e.preventDefault(),this.close();break;case"Tab":this.close();break}},this.handleItemClick=e=>{const t=e.target;if(t.getAttribute("role")==="menuitem"&&t.getAttribute("aria-disabled")!=="true"){const i=this._menuItems.indexOf(t);this.selectItem(i)}},this.handleMouseOver=e=>{const t=e.target;if(t.getAttribute("role")==="menuitem"){const i=this._menuItems.indexOf(t);i!==-1&&this.highlightItem(i,!1)}},this.handleOutsideClick=e=>{if(!this._open)return;e.composedPath().includes(this)||this.close()}}static get observedAttributes(){return["open"]}get open(){return this._open}set open(e){const t=this._open;this._open=e,e!==t&&this.updateMenuVisibility(),this.toggleAttribute("open",e)}setupAccessibility(){const e=this.querySelector('[slot="trigger"]');e&&(e.setAttribute("aria-haspopup","menu"),e.setAttribute("aria-expanded",String(this._open)),e.id=e.id||`${this._id}-trigger`,e.hasAttribute("tabindex")||e.setAttribute("tabindex","0"))}render(){const e=this.attachShadow({mode:"open"});e.innerHTML=`
440
+ <style>${w}</style>
441
+ <slot name="trigger"></slot>
442
+ <div
443
+ class="menu-content"
444
+ role="menu"
445
+ aria-labelledby="${this._id}-trigger"
446
+ tabindex="-1"
447
+ hidden
448
+ part="menu"
449
+ >
450
+ <slot></slot>
451
+ </div>
452
+ `}setupEventListeners(){var s,n;const e=this.querySelector('[slot="trigger"]');e==null||e.addEventListener("click",this.handleTriggerClick),e==null||e.addEventListener("keydown",this.handleTriggerKeyDown);const t=(s=this.shadowRoot)==null?void 0:s.querySelector('slot[name="trigger"]');t==null||t.addEventListener("click",this.handleTriggerClick),this.addEventListener("click",this.handleItemClick),this.addEventListener("keydown",this.handleMenuKeyDown),this.addEventListener("mouseover",this.handleMouseOver),document.addEventListener("mousedown",this.handleOutsideClick);const i=(n=this.shadowRoot)==null?void 0:n.querySelector("slot:not([name])");i==null||i.addEventListener("slotchange",this.updateMenuItems),this.updateMenuItems()}cleanupEventListeners(){document.removeEventListener("mousedown",this.handleOutsideClick)}onAttributeChange(e,t,i){e==="open"&&(this.open=i!==null)}highlightItem(e,t=!0){var s;if(this._highlightedIndex>=0){const n=this._menuItems[this._highlightedIndex];n==null||n.removeAttribute("data-highlighted")}this._highlightedIndex=e;const i=this._menuItems[e];if(i){i.setAttribute("data-highlighted","true"),t&&i.focus();const n=(s=this.shadowRoot)==null?void 0:s.querySelector('[role="menu"]');n==null||n.setAttribute("aria-activedescendant",i.id)}}selectItem(e){const t=this._menuItems[e];t&&(this.emit("a11y-menu-select",{item:t,index:e}),t.click()),this.close()}updateMenuVisibility(){var i;const e=(i=this.shadowRoot)==null?void 0:i.querySelector(".menu-content"),t=this.querySelector('[slot="trigger"]');this._open?(e==null||e.removeAttribute("hidden"),t==null||t.setAttribute("aria-expanded","true"),this.updateMenuItems(),this.emit("a11y-menu-open")):(e==null||e.setAttribute("hidden",""),t==null||t.setAttribute("aria-expanded","false"),this._highlightedIndex=-1,this._menuItems.forEach(s=>{s.removeAttribute("data-highlighted")}),t==null||t.focus(),this.emit("a11y-menu-close"))}show(){this.open=!0}close(){this.open=!1}toggle(){this.open=!this._open}}c("a11y-menu",m);class g extends d{constructor(){super(...arguments),this._tabs=[],this._panels=[],this._selectedIndex=0,this.updateTabsAndPanels=()=>{this._tabs=Array.from(this.querySelectorAll('[role="tab"]')),this._panels=Array.from(this.querySelectorAll('[role="tabpanel"]')),this._tabs.forEach((e,t)=>{const i=this._panels[t],s=e.id||`${this._id}-tab-${t}`,n=(i==null?void 0:i.id)||`${this._id}-panel-${t}`;e.id=s,e.setAttribute("aria-controls",n),e.setAttribute("tabindex",t===this._selectedIndex?"0":"-1"),e.setAttribute("aria-selected",String(t===this._selectedIndex)),e.hasAttribute("slot")||e.setAttribute("slot","tab"),i&&(i.id=n,i.setAttribute("aria-labelledby",s),i.setAttribute("tabindex","0"),i.hidden=t!==this._selectedIndex,i.hasAttribute("slot")||i.setAttribute("slot","panel"))}),this.updateSelection()},this.handleClick=e=>{const t=e.target;if(t.getAttribute("role")==="tab"){const i=this._tabs.indexOf(t);i!==-1&&t.getAttribute("aria-disabled")!=="true"&&this.selectTab(i)}},this.handleKeyDown=e=>{var h;if(e.target.getAttribute("role")!=="tab")return;const i=this.orientation==="horizontal",s=i?"ArrowRight":"ArrowDown",n=i?"ArrowLeft":"ArrowUp";let r=this._selectedIndex;switch(e.key){case s:e.preventDefault(),r=(this._selectedIndex+1)%this._tabs.length;break;case n:e.preventDefault(),r=(this._selectedIndex-1+this._tabs.length)%this._tabs.length;break;case"Home":e.preventDefault(),r=0;break;case"End":e.preventDefault(),r=this._tabs.length-1;break;default:return}(h=this._tabs[r])==null||h.focus(),this.activationMode==="automatic"&&this.selectTab(r)}}static get observedAttributes(){return["orientation","activation-mode","selected-index"]}get selectedIndex(){return this._selectedIndex}set selectedIndex(e){e>=0&&e<this._tabs.length&&(this._selectedIndex=e,this.updateSelection())}get orientation(){return this.getAttribute("orientation")||"horizontal"}get activationMode(){return this.getAttribute("activation-mode")||"automatic"}setupAccessibility(){this.updateTabsAndPanels()}render(){const e=this.attachShadow({mode:"open"});e.innerHTML=`
453
+ <style>${E}</style>
454
+ <div class="tablist" role="tablist" aria-orientation="${this.orientation}" part="tablist">
455
+ <slot name="tab"></slot>
456
+ </div>
457
+ <div class="panels" part="panels">
458
+ <slot name="panel"></slot>
459
+ </div>
460
+ <slot></slot>
461
+ `}setupEventListeners(){var s,n,r;this.addEventListener("click",this.handleClick),this.addEventListener("keydown",this.handleKeyDown);const e=(s=this.shadowRoot)==null?void 0:s.querySelector('slot[name="tab"]'),t=(n=this.shadowRoot)==null?void 0:n.querySelector('slot[name="panel"]'),i=(r=this.shadowRoot)==null?void 0:r.querySelector("slot:not([name])");e==null||e.addEventListener("slotchange",this.updateTabsAndPanels),t==null||t.addEventListener("slotchange",this.updateTabsAndPanels),i==null||i.addEventListener("slotchange",this.updateTabsAndPanels)}onAttributeChange(e,t,i){var s;if(e==="orientation"){const n=(s=this.shadowRoot)==null?void 0:s.querySelector('[role="tablist"]');n==null||n.setAttribute("aria-orientation",i||"horizontal")}e==="selected-index"&&i&&(this.selectedIndex=parseInt(i,10))}selectTab(e){const t=this._selectedIndex;if(this._selectedIndex=e,this.updateSelection(),t!==e){const i=this._tabs[e];o.announce(`${(i==null?void 0:i.textContent)||"Tab"} selected`),this.emit("a11y-tabs-change",{index:e,tab:this._tabs[e],panel:this._panels[e]})}}updateSelection(){this._tabs.forEach((e,t)=>{const i=t===this._selectedIndex;e.setAttribute("aria-selected",String(i)),e.setAttribute("tabindex",i?"0":"-1")}),this._panels.forEach((e,t)=>{e.hidden=t!==this._selectedIndex})}select(e){this.selectTab(e)}next(){this.selectTab((this._selectedIndex+1)%this._tabs.length)}previous(){this.selectTab((this._selectedIndex-1+this._tabs.length)%this._tabs.length)}}c("a11y-tabs",g);class f extends d{constructor(){super(...arguments),this._open=!1,this._highlightedIndex=-1,this._options=[],this._filteredOptions=[],this._inputValue="",this._selectedValue=null,this._inputElement=null,this._listboxElement=null,this.updateOptions=()=>{const e=Array.from(this.querySelectorAll("option"));this._options=e.map(t=>({value:t.getAttribute("value")||t.textContent||"",label:t.textContent||"",disabled:t.hasAttribute("disabled"),element:t})),this._filteredOptions=[...this._options],this.renderOptions()},this.handleInput=e=>{const t=e.target;this._inputValue=t.value;const i=this._inputValue.toLowerCase();this._filteredOptions=i?this._options.filter(n=>n.label.toLowerCase().includes(i)):[...this._options],this.renderOptions(),this.open=!0,this._highlightedIndex=0,this.updateHighlight(),this.updateClearButton();const s=this._filteredOptions.length;o.announce(s===0?"No results":`${s} result${s===1?"":"s"} available`)},this.handleFocus=()=>{this.open=!0},this.handleBlur=()=>{setTimeout(()=>{var e;(e=this.shadowRoot)!=null&&e.activeElement||(this.open=!1)},150)},this.handleKeyDown=e=>{switch(e.key){case"ArrowDown":e.preventDefault(),this._open?this._highlightedIndex=Math.min(this._highlightedIndex+1,this._filteredOptions.length-1):(this.open=!0,this._highlightedIndex=0),this.updateHighlight();break;case"ArrowUp":e.preventDefault(),this._open?this._highlightedIndex=Math.max(this._highlightedIndex-1,0):(this.open=!0,this._highlightedIndex=this._filteredOptions.length-1),this.updateHighlight();break;case"Enter":if(e.preventDefault(),this._open&&this._highlightedIndex>=0){const t=this._filteredOptions[this._highlightedIndex];t&&!t.disabled&&this.selectOption(t)}break;case"Escape":e.preventDefault(),this.open=!1,this._highlightedIndex=-1;break;case"Home":this._open&&(e.preventDefault(),this._highlightedIndex=0,this.updateHighlight());break;case"End":this._open&&(e.preventDefault(),this._highlightedIndex=this._filteredOptions.length-1,this.updateHighlight());break;case"Tab":this._open&&(this.open=!1,this._highlightedIndex=-1);break}},this.handleOptionClick=e=>{const t=e.currentTarget,i=parseInt(t.dataset.index||"0",10),s=this._filteredOptions[i];s&&!s.disabled&&this.selectOption(s)},this.handleOptionHover=e=>{const t=e.currentTarget,i=parseInt(t.dataset.index||"0",10),s=this._filteredOptions[i];s&&!s.disabled&&(this._highlightedIndex=i,this.updateHighlight())},this.handleClear=()=>{this._inputValue="",this._selectedValue=null,this._inputElement&&(this._inputElement.value="",this._inputElement.focus()),this._filteredOptions=[...this._options],this.renderOptions(),this.updateClearButton(),this.emit("a11y-combobox-clear"),this.emit("a11y-combobox-change",{value:null,label:null})},this.handleOutsideClick=e=>{if(!this._open)return;e.composedPath().includes(this)||(this.open=!1)}}static get observedAttributes(){return["open","value","placeholder","disabled","clearable"]}get open(){return this._open}set open(e){const t=this._open;this._open=e,e!==t&&this.updateListboxVisibility(),this.toggleAttribute("open",e)}get value(){return this._selectedValue}set value(e){this._selectedValue=e;const t=this._options.find(i=>i.value===e);t&&(this._inputValue=t.label,this._inputElement&&(this._inputElement.value=t.label)),this.setAttribute("value",e||"")}setupAccessibility(){}render(){const e=this.attachShadow({mode:"open"}),t=`${this._id}-input`,i=`${this._id}-listbox`,s=this.getAttribute("placeholder")||"Search...",n=this.hasAttribute("clearable");e.innerHTML=`
462
+ <style>${A}</style>
463
+ <div class="combobox-wrapper" part="wrapper">
464
+ <div class="input-wrapper" part="input-wrapper">
465
+ <input
466
+ id="${t}"
467
+ type="text"
468
+ role="combobox"
469
+ autocomplete="off"
470
+ aria-expanded="false"
471
+ aria-controls="${i}"
472
+ aria-haspopup="listbox"
473
+ aria-autocomplete="list"
474
+ placeholder="${s}"
475
+ part="input"
476
+ />
477
+ ${n?`
478
+ <button
479
+ type="button"
480
+ class="clear-button"
481
+ aria-label="Clear selection"
482
+ tabindex="-1"
483
+ hidden
484
+ part="clear-button"
485
+ >×</button>
486
+ `:""}
487
+ <span class="chevron" aria-hidden="true" part="chevron">▼</span>
488
+ </div>
489
+ <ul
490
+ id="${i}"
491
+ role="listbox"
492
+ aria-labelledby="${t}"
493
+ class="listbox"
494
+ tabindex="-1"
495
+ hidden
496
+ part="listbox"
497
+ ></ul>
498
+ </div>
499
+ <div class="options-source" hidden>
500
+ <slot></slot>
501
+ </div>
502
+ `,this._inputElement=e.querySelector("input"),this._listboxElement=e.querySelector(".listbox")}setupEventListeners(){var i,s,n,r,h,p;(i=this._inputElement)==null||i.addEventListener("input",this.handleInput),(s=this._inputElement)==null||s.addEventListener("focus",this.handleFocus),(n=this._inputElement)==null||n.addEventListener("blur",this.handleBlur),(r=this._inputElement)==null||r.addEventListener("keydown",this.handleKeyDown);const e=(h=this.shadowRoot)==null?void 0:h.querySelector(".clear-button");e==null||e.addEventListener("click",this.handleClear),document.addEventListener("mousedown",this.handleOutsideClick);const t=(p=this.shadowRoot)==null?void 0:p.querySelector("slot");t==null||t.addEventListener("slotchange",this.updateOptions),this.updateOptions()}cleanupEventListeners(){document.removeEventListener("mousedown",this.handleOutsideClick)}onAttributeChange(e,t,i){e==="open"&&(this.open=i!==null),e==="value"&&(this.value=i),e==="disabled"&&this._inputElement&&(this._inputElement.disabled=i!==null),e==="placeholder"&&this._inputElement&&(this._inputElement.placeholder=i||"Search...")}renderOptions(){this._listboxElement&&(this._listboxElement.innerHTML=this._filteredOptions.length===0?'<li role="presentation" class="empty-message" part="empty">No results found</li>':this._filteredOptions.map((e,t)=>`
503
+ <li
504
+ id="${this._id}-option-${t}"
505
+ role="option"
506
+ aria-selected="${this._selectedValue===e.value}"
507
+ aria-disabled="${e.disabled}"
508
+ data-value="${e.value}"
509
+ data-index="${t}"
510
+ part="option"
511
+ ${e.disabled?'class="disabled"':""}
512
+ >${e.label}</li>
513
+ `).join(""),this._listboxElement.querySelectorAll('[role="option"]').forEach(e=>{e.addEventListener("click",this.handleOptionClick),e.addEventListener("mouseenter",this.handleOptionHover)}))}selectOption(e){this._selectedValue=e.value,this._inputValue=e.label,this._inputElement&&(this._inputElement.value=e.label),this.open=!1,this._highlightedIndex=-1,this.renderOptions(),this.updateClearButton(),o.announce(`${e.label} selected`),this.emit("a11y-combobox-select",{value:e.value,label:e.label}),this.emit("a11y-combobox-change",{value:e.value,label:e.label})}updateHighlight(){var e,t,i,s;if((e=this._listboxElement)==null||e.querySelectorAll('[role="option"]').forEach((n,r)=>{n.classList.toggle("highlighted",r===this._highlightedIndex)}),this._highlightedIndex>=0){const n=`${this._id}-option-${this._highlightedIndex}`;(t=this._inputElement)==null||t.setAttribute("aria-activedescendant",n);const r=(i=this._listboxElement)==null?void 0:i.querySelector(`#${n}`);r==null||r.scrollIntoView({block:"nearest",behavior:"smooth"})}else(s=this._inputElement)==null||s.removeAttribute("aria-activedescendant")}updateListboxVisibility(){!this._listboxElement||!this._inputElement||(this._open?(this._listboxElement.hidden=!1,this._inputElement.setAttribute("aria-expanded","true"),this.updateListboxPosition(),this.emit("a11y-combobox-open")):(this._listboxElement.hidden=!0,this._inputElement.setAttribute("aria-expanded","false"),this._highlightedIndex=-1,this.updateHighlight(),this._listboxElement.style.top="",this._listboxElement.style.bottom="",this.removeAttribute("data-position"),this.emit("a11y-combobox-close")))}updateListboxPosition(){if(!this._listboxElement||!this._inputElement)return;const e=this._inputElement.getBoundingClientRect(),t=window.innerHeight,i=Math.min(this._listboxElement.scrollHeight,200),s=t-e.bottom,n=e.top;s<i+8&&n>s?(this._listboxElement.style.top="auto",this._listboxElement.style.bottom="100%",this._listboxElement.style.marginTop="0",this._listboxElement.style.marginBottom="4px",this.setAttribute("data-position","top")):(this._listboxElement.style.top="100%",this._listboxElement.style.bottom="auto",this._listboxElement.style.marginTop="4px",this._listboxElement.style.marginBottom="0",this.setAttribute("data-position","bottom"))}updateClearButton(){var t;const e=(t=this.shadowRoot)==null?void 0:t.querySelector(".clear-button");e&&(e.hidden=!this._inputValue)}show(){this.open=!0}close(){this.open=!1}clear(){this.handleClear()}}c("a11y-combobox",f);class y extends d{constructor(){super(...arguments),this._checked=!1,this._button=null,this._label=null,this.handleClick=()=>{this.toggle()},this.handleKeyDown=e=>{this.disabled||(e.key===" "||e.key==="Enter")&&(e.preventDefault(),this.toggle())},this.handleLabelClick=()=>{var e;this.disabled||(this.toggle(),(e=this._button)==null||e.focus())}}static get observedAttributes(){return["checked","disabled","label","size","aria-label"]}get checked(){return this._checked}set checked(e){const t=this._checked;this._checked=e,this.toggleAttribute("checked",e),e!==t&&(this.updateVisualState(),this.emit("change",{checked:e}))}get disabled(){return this.hasAttribute("disabled")}set disabled(e){this.toggleAttribute("disabled",e),this.updateDisabledState()}get label(){return this.getAttribute("label")||""}set label(e){e?this.setAttribute("label",e):this.removeAttribute("label")}get size(){const e=this.getAttribute("size");return e==="sm"||e==="lg"?e:"md"}set size(e){this.setAttribute("size",e)}setupAccessibility(){var e;this.getAttribute("role"),typeof process<"u"&&((e=process.env)==null?void 0:e.NODE_ENV)!=="production"&&!this.label&&!this.getAttribute("aria-label")&&console.warn(`[compa11y/Switch] Switch has no accessible label. Add label="..." or aria-label="..." attribute.
514
+ 💡 Suggestion: <a11y-switch label="Enable feature"></a11y-switch>`)}render(){const e=this.attachShadow({mode:"open"}),t=`${this._id}-label`,i=!!this.label,s=this.getAttribute("aria-label"),n=i?"":s?`aria-label="${s}"`:"",r=i?`aria-labelledby="${t}"`:"";e.innerHTML=`
515
+ <style>${k}</style>
516
+ <div class="switch-wrapper size-${this.size}" part="wrapper">
517
+ <button
518
+ type="button"
519
+ role="switch"
520
+ aria-checked="${this._checked}"
521
+ ${n}
522
+ ${r}
523
+ ${this.disabled?"disabled":""}
524
+ class="switch-track ${this._checked?"checked":""}"
525
+ part="track"
526
+ tabindex="${this.disabled?"-1":"0"}"
527
+ >
528
+ <span class="switch-thumb" part="thumb" aria-hidden="true"></span>
529
+ </button>
530
+ ${i?`<label id="${t}" class="switch-label ${this.disabled?"disabled":""}" part="label">${this.label}</label>`:""}
531
+ </div>
532
+ `,this._button=e.querySelector("button"),this._label=e.querySelector("label")}setupEventListeners(){var e,t,i;(e=this._button)==null||e.addEventListener("click",this.handleClick),(t=this._button)==null||t.addEventListener("keydown",this.handleKeyDown),(i=this._label)==null||i.addEventListener("click",this.handleLabelClick)}cleanupEventListeners(){var e,t,i;(e=this._button)==null||e.removeEventListener("click",this.handleClick),(t=this._button)==null||t.removeEventListener("keydown",this.handleKeyDown),(i=this._label)==null||i.removeEventListener("click",this.handleLabelClick)}onAttributeChange(e,t,i){switch(e){case"checked":this._checked=i!==null,this.updateVisualState();break;case"disabled":this.updateDisabledState();break;case"label":case"aria-label":this.shadowRoot&&(this.shadowRoot.innerHTML="",this.render(),this.setupEventListeners());break;case"size":this.updateSizeClass();break}}updateVisualState(){this._button&&(this._button.setAttribute("aria-checked",String(this._checked)),this._button.classList.toggle("checked",this._checked))}updateDisabledState(){this._button&&(this.disabled?(this._button.setAttribute("disabled",""),this._button.setAttribute("tabindex","-1")):(this._button.removeAttribute("disabled"),this._button.setAttribute("tabindex","0"))),this._label&&this._label.classList.toggle("disabled",this.disabled)}updateSizeClass(){var t;const e=(t=this.shadowRoot)==null?void 0:t.querySelector(".switch-wrapper");e&&(e.classList.remove("size-sm","size-md","size-lg"),e.classList.add(`size-${this.size}`))}toggle(){if(this.disabled)return;this.checked=!this.checked;const e=this.label||this.getAttribute("aria-label")||"Switch";o.announcePolite(`${e} ${this.checked?"on":"off"}`)}setChecked(e){this.checked=e}}if(c("a11y-switch",y),typeof window<"u"){const l=()=>{o.initAnnouncer(),o.initFocusVisible()};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",l):l(),window.compa11y={A11yDialog:b,A11yMenu:m,A11yTabs:g,A11yCombobox:f,A11ySwitch:y,initAnnouncer:o.initAnnouncer,announce:o.announce,announcePolite:o.announcePolite,announceAssertive:o.announceAssertive,announceStatus:o.announceStatus,announceError:o.announceError,initFocusVisible:o.initFocusVisible,createFocusTrap:o.createFocusTrap,createFocusScope:o.createFocusScope,createRovingTabindex:o.createRovingTabindex,createKeyboardManager:o.createKeyboardManager,KeyboardPatterns:o.KeyboardPatterns,createTypeAhead:o.createTypeAhead,aria:o.aria,buildAriaProps:o.buildAriaProps,hasAccessibleName:o.hasAccessibleName,isBrowser:o.isBrowser,prefersReducedMotion:o.prefersReducedMotion,prefersHighContrast:o.prefersHighContrast,prefersDarkMode:o.prefersDarkMode}}Object.defineProperty(a,"KeyboardPatterns",{enumerable:!0,get:()=>o.KeyboardPatterns}),Object.defineProperty(a,"announce",{enumerable:!0,get:()=>o.announce}),Object.defineProperty(a,"announceAssertive",{enumerable:!0,get:()=>o.announceAssertive}),Object.defineProperty(a,"announceError",{enumerable:!0,get:()=>o.announceError}),Object.defineProperty(a,"announcePolite",{enumerable:!0,get:()=>o.announcePolite}),Object.defineProperty(a,"announceStatus",{enumerable:!0,get:()=>o.announceStatus}),Object.defineProperty(a,"aria",{enumerable:!0,get:()=>o.aria}),Object.defineProperty(a,"buildAriaProps",{enumerable:!0,get:()=>o.buildAriaProps}),Object.defineProperty(a,"createFocusScope",{enumerable:!0,get:()=>o.createFocusScope}),Object.defineProperty(a,"createFocusTrap",{enumerable:!0,get:()=>o.createFocusTrap}),Object.defineProperty(a,"createKeyboardManager",{enumerable:!0,get:()=>o.createKeyboardManager}),Object.defineProperty(a,"createRovingTabindex",{enumerable:!0,get:()=>o.createRovingTabindex}),Object.defineProperty(a,"createTypeAhead",{enumerable:!0,get:()=>o.createTypeAhead}),Object.defineProperty(a,"hasAccessibleName",{enumerable:!0,get:()=>o.hasAccessibleName}),Object.defineProperty(a,"initAnnouncer",{enumerable:!0,get:()=>o.initAnnouncer}),Object.defineProperty(a,"initFocusVisible",{enumerable:!0,get:()=>o.initFocusVisible}),Object.defineProperty(a,"isBrowser",{enumerable:!0,get:()=>o.isBrowser}),Object.defineProperty(a,"prefersDarkMode",{enumerable:!0,get:()=>o.prefersDarkMode}),Object.defineProperty(a,"prefersHighContrast",{enumerable:!0,get:()=>o.prefersHighContrast}),Object.defineProperty(a,"prefersReducedMotion",{enumerable:!0,get:()=>o.prefersReducedMotion}),a.A11yCombobox=f,a.A11yDialog=b,a.A11yMenu=m,a.A11ySwitch=y,a.A11yTabs=g,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})});
533
+ //# sourceMappingURL=compa11y.umd.cjs.map