@compa11y/web 0.1.0 → 0.1.3

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 (37) hide show
  1. package/README.md +608 -0
  2. package/dist/compa11y.iife.js +1126 -27
  3. package/dist/compa11y.js +3671 -716
  4. package/dist/components/button.d.ts +31 -0
  5. package/dist/components/checkbox.d.ts +159 -0
  6. package/dist/components/combobox.d.ts +2 -3
  7. package/dist/components/dialog.d.ts +2 -3
  8. package/dist/components/dialog.test.d.ts +0 -1
  9. package/dist/components/input.d.ts +40 -0
  10. package/dist/components/listbox.d.ts +85 -0
  11. package/dist/components/menu.d.ts +2 -3
  12. package/dist/components/menu.test.d.ts +0 -1
  13. package/dist/components/radio-group.d.ts +86 -0
  14. package/dist/components/select.d.ts +46 -0
  15. package/dist/components/switch.d.ts +2 -3
  16. package/dist/components/tabs.d.ts +2 -3
  17. package/dist/components/tabs.test.d.ts +0 -1
  18. package/dist/components/textarea.d.ts +40 -0
  19. package/dist/index.d.ts +8 -2
  20. package/dist/utils/base-element.d.ts +1 -2
  21. package/dist/utils/styles.d.ts +44 -1
  22. package/package.json +39 -3
  23. package/dist/compa11y.iife.js.map +0 -1
  24. package/dist/compa11y.js.map +0 -1
  25. package/dist/compa11y.umd.cjs +0 -533
  26. package/dist/compa11y.umd.cjs.map +0 -1
  27. package/dist/components/combobox.d.ts.map +0 -1
  28. package/dist/components/dialog.d.ts.map +0 -1
  29. package/dist/components/dialog.test.d.ts.map +0 -1
  30. package/dist/components/menu.d.ts.map +0 -1
  31. package/dist/components/menu.test.d.ts.map +0 -1
  32. package/dist/components/switch.d.ts.map +0 -1
  33. package/dist/components/tabs.d.ts.map +0 -1
  34. package/dist/components/tabs.test.d.ts.map +0 -1
  35. package/dist/index.d.ts.map +0 -1
  36. package/dist/utils/base-element.d.ts.map +0 -1
  37. package/dist/utils/styles.d.ts.map +0 -1
@@ -1,533 +0,0 @@
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