aria-ease 3.0.2 → 4.0.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 (44) hide show
  1. package/README.md +6 -6
  2. package/bin/cli.cjs +90 -22
  3. package/bin/cli.js +1 -1
  4. package/bin/{contractTestRunnerPlaywright-TLQZGKW7.js → contractTestRunnerPlaywright-EZLNNJV5.js} +43 -10
  5. package/bin/{test-Q7W3WQEA.js → test-45KMD4F4.js} +47 -12
  6. package/dist/{contractTestRunnerPlaywright-7U2O33SR.js → contractTestRunnerPlaywright-UQQI5MYS.js} +43 -10
  7. package/dist/index.cjs +663 -38
  8. package/dist/index.d.cts +88 -6
  9. package/dist/index.d.ts +88 -6
  10. package/dist/index.js +616 -28
  11. package/dist/src/{Types.d-uG0Hm1yK.d.ts → Types.d-BrHSyS03.d.cts} +17 -0
  12. package/dist/src/{Types.d-uG0Hm1yK.d.cts → Types.d-BrHSyS03.d.ts} +17 -0
  13. package/dist/src/accordion/index.cjs +159 -0
  14. package/dist/src/accordion/index.d.cts +19 -2
  15. package/dist/src/accordion/index.d.ts +19 -2
  16. package/dist/src/accordion/index.js +159 -1
  17. package/dist/src/block/index.cjs +1 -1
  18. package/dist/src/block/index.d.cts +6 -2
  19. package/dist/src/block/index.d.ts +6 -2
  20. package/dist/src/block/index.js +1 -1
  21. package/dist/src/checkbox/index.cjs +129 -0
  22. package/dist/src/checkbox/index.d.cts +15 -2
  23. package/dist/src/checkbox/index.d.ts +15 -2
  24. package/dist/src/checkbox/index.js +129 -1
  25. package/dist/src/combobox/index.d.cts +1 -1
  26. package/dist/src/combobox/index.d.ts +1 -1
  27. package/dist/src/menu/index.cjs +13 -15
  28. package/dist/src/menu/index.d.cts +1 -1
  29. package/dist/src/menu/index.d.ts +1 -1
  30. package/dist/src/menu/index.js +13 -15
  31. package/dist/src/radio/index.cjs +122 -0
  32. package/dist/src/radio/index.d.cts +17 -2
  33. package/dist/src/radio/index.d.ts +17 -2
  34. package/dist/src/radio/index.js +122 -1
  35. package/dist/src/toggle/index.cjs +145 -0
  36. package/dist/src/toggle/index.d.cts +17 -2
  37. package/dist/src/toggle/index.d.ts +17 -2
  38. package/dist/src/toggle/index.js +145 -1
  39. package/dist/src/utils/test/{contractTestRunnerPlaywright-7U2O33SR.js → contractTestRunnerPlaywright-UQQI5MYS.js} +43 -10
  40. package/dist/src/utils/test/index.cjs +90 -22
  41. package/dist/src/utils/test/index.d.cts +5 -4
  42. package/dist/src/utils/test/index.d.ts +5 -4
  43. package/dist/src/utils/test/index.js +47 -12
  44. package/package.json +1 -1
@@ -19,6 +19,23 @@ interface AccessibilityInstance {
19
19
  refresh?: () => void;
20
20
  openMenu?: () => void;
21
21
  closeMenu?: () => void;
22
+ // Accordion methods
23
+ expandItem?: (index: number) => void;
24
+ collapseItem?: (index: number) => void;
25
+ toggleItem?: (index: number) => void;
26
+ // Radio methods
27
+ selectRadio?: (index: number) => void;
28
+ getSelectedIndex?: () => number;
29
+ // Checkbox methods
30
+ toggleCheckbox?: (index: number) => void;
31
+ setCheckboxState?: (index: number, checked: boolean) => void;
32
+ getCheckedStates?: () => boolean[];
33
+ getCheckedIndices?: () => number[];
34
+ // Toggle methods
35
+ toggleButton?: (index: number) => void;
36
+ setPressed?: (index: number, pressed: boolean) => void;
37
+ getPressedStates?: () => boolean[];
38
+ getPressedIndices?: () => number[];
22
39
  }
23
40
 
24
41
  interface ComboboxConfig {
@@ -19,6 +19,23 @@ interface AccessibilityInstance {
19
19
  refresh?: () => void;
20
20
  openMenu?: () => void;
21
21
  closeMenu?: () => void;
22
+ // Accordion methods
23
+ expandItem?: (index: number) => void;
24
+ collapseItem?: (index: number) => void;
25
+ toggleItem?: (index: number) => void;
26
+ // Radio methods
27
+ selectRadio?: (index: number) => void;
28
+ getSelectedIndex?: () => number;
29
+ // Checkbox methods
30
+ toggleCheckbox?: (index: number) => void;
31
+ setCheckboxState?: (index: number, checked: boolean) => void;
32
+ getCheckedStates?: () => boolean[];
33
+ getCheckedIndices?: () => number[];
34
+ // Toggle methods
35
+ toggleButton?: (index: number) => void;
36
+ setPressed?: (index: number, pressed: boolean) => void;
37
+ getPressedStates?: () => boolean[];
38
+ getPressedIndices?: () => number[];
22
39
  }
23
40
 
24
41
  interface ComboboxConfig {
@@ -26,4 +26,163 @@ function updateAccordionTriggerAriaAttributes(accordionId, accordionTriggersClas
26
26
  });
27
27
  }
28
28
 
29
+ // src/accordion/src/makeAccordionAccessible/makeAccordionAccessible.ts
30
+ function makeAccordionAccessible({ accordionId, triggersClass, panelsClass, allowMultiple = false }) {
31
+ const accordionContainer = document.querySelector(`#${accordionId}`);
32
+ if (!accordionContainer) {
33
+ console.error(`[aria-ease] Element with id="${accordionId}" not found. Make sure the accordion container exists before calling makeAccordionAccessible.`);
34
+ return { cleanup: () => {
35
+ } };
36
+ }
37
+ const triggers = Array.from(accordionContainer.querySelectorAll(`.${triggersClass}`));
38
+ if (triggers.length === 0) {
39
+ console.error(`[aria-ease] No elements with class="${triggersClass}" found. Make sure accordion triggers exist before calling makeAccordionAccessible.`);
40
+ return { cleanup: () => {
41
+ } };
42
+ }
43
+ const panels = Array.from(accordionContainer.querySelectorAll(`.${panelsClass}`));
44
+ if (panels.length === 0) {
45
+ console.error(`[aria-ease] No elements with class="${panelsClass}" found. Make sure accordion panels exist before calling makeAccordionAccessible.`);
46
+ return { cleanup: () => {
47
+ } };
48
+ }
49
+ if (triggers.length !== panels.length) {
50
+ console.error(`[aria-ease] Accordion trigger/panel mismatch: found ${triggers.length} triggers but ${panels.length} panels.`);
51
+ return { cleanup: () => {
52
+ } };
53
+ }
54
+ const handlerMap = /* @__PURE__ */ new WeakMap();
55
+ const clickHandlerMap = /* @__PURE__ */ new WeakMap();
56
+ function initialize() {
57
+ triggers.forEach((trigger, index) => {
58
+ const panel = panels[index];
59
+ if (!trigger.id) {
60
+ trigger.id = `${accordionId}-trigger-${index}`;
61
+ }
62
+ if (!panel.id) {
63
+ panel.id = `${accordionId}-panel-${index}`;
64
+ }
65
+ trigger.setAttribute("aria-controls", panel.id);
66
+ trigger.setAttribute("aria-expanded", "false");
67
+ panel.setAttribute("role", "region");
68
+ panel.setAttribute("aria-labelledby", trigger.id);
69
+ panel.style.display = "none";
70
+ });
71
+ }
72
+ function expandItem(index) {
73
+ if (index < 0 || index >= triggers.length) {
74
+ console.error(`[aria-ease] Invalid accordion index: ${index}`);
75
+ return;
76
+ }
77
+ const trigger = triggers[index];
78
+ const panel = panels[index];
79
+ trigger.setAttribute("aria-expanded", "true");
80
+ panel.style.display = "block";
81
+ }
82
+ function collapseItem(index) {
83
+ if (index < 0 || index >= triggers.length) {
84
+ console.error(`[aria-ease] Invalid accordion index: ${index}`);
85
+ return;
86
+ }
87
+ const trigger = triggers[index];
88
+ const panel = panels[index];
89
+ trigger.setAttribute("aria-expanded", "false");
90
+ panel.style.display = "none";
91
+ }
92
+ function toggleItem(index) {
93
+ const trigger = triggers[index];
94
+ const isExpanded = trigger.getAttribute("aria-expanded") === "true";
95
+ if (isExpanded) {
96
+ collapseItem(index);
97
+ } else {
98
+ if (!allowMultiple) {
99
+ triggers.forEach((_, i) => {
100
+ if (i !== index) {
101
+ collapseItem(i);
102
+ }
103
+ });
104
+ }
105
+ expandItem(index);
106
+ }
107
+ }
108
+ function handleTriggerClick(index) {
109
+ return () => {
110
+ toggleItem(index);
111
+ };
112
+ }
113
+ function handleTriggerKeydown(index) {
114
+ return (event) => {
115
+ const { key } = event;
116
+ switch (key) {
117
+ case "Enter":
118
+ case " ":
119
+ event.preventDefault();
120
+ toggleItem(index);
121
+ break;
122
+ case "ArrowDown":
123
+ event.preventDefault();
124
+ {
125
+ const nextIndex = (index + 1) % triggers.length;
126
+ triggers[nextIndex].focus();
127
+ }
128
+ break;
129
+ case "ArrowUp":
130
+ event.preventDefault();
131
+ {
132
+ const prevIndex = (index - 1 + triggers.length) % triggers.length;
133
+ triggers[prevIndex].focus();
134
+ }
135
+ break;
136
+ case "Home":
137
+ event.preventDefault();
138
+ triggers[0].focus();
139
+ break;
140
+ case "End":
141
+ event.preventDefault();
142
+ triggers[triggers.length - 1].focus();
143
+ break;
144
+ }
145
+ };
146
+ }
147
+ function addListeners() {
148
+ triggers.forEach((trigger, index) => {
149
+ const clickHandler = handleTriggerClick(index);
150
+ const keydownHandler = handleTriggerKeydown(index);
151
+ trigger.addEventListener("click", clickHandler);
152
+ trigger.addEventListener("keydown", keydownHandler);
153
+ handlerMap.set(trigger, keydownHandler);
154
+ clickHandlerMap.set(trigger, clickHandler);
155
+ });
156
+ }
157
+ function removeListeners() {
158
+ triggers.forEach((trigger) => {
159
+ const keydownHandler = handlerMap.get(trigger);
160
+ const clickHandler = clickHandlerMap.get(trigger);
161
+ if (keydownHandler) {
162
+ trigger.removeEventListener("keydown", keydownHandler);
163
+ handlerMap.delete(trigger);
164
+ }
165
+ if (clickHandler) {
166
+ trigger.removeEventListener("click", clickHandler);
167
+ clickHandlerMap.delete(trigger);
168
+ }
169
+ });
170
+ }
171
+ function cleanup() {
172
+ removeListeners();
173
+ triggers.forEach((_, index) => {
174
+ collapseItem(index);
175
+ });
176
+ }
177
+ initialize();
178
+ addListeners();
179
+ return {
180
+ expandItem,
181
+ collapseItem,
182
+ toggleItem,
183
+ cleanup
184
+ };
185
+ }
186
+
187
+ exports.makeAccordionAccessible = makeAccordionAccessible;
29
188
  exports.updateAccordionTriggerAriaAttributes = updateAccordionTriggerAriaAttributes;
@@ -1,4 +1,4 @@
1
- import { A as AccordionStates } from '../Types.d-uG0Hm1yK.cjs';
1
+ import { A as AccordionStates, a as AccessibilityInstance } from '../Types.d-BrHSyS03.cjs';
2
2
 
3
3
  /**
4
4
  * Adds screen reader accessibility to accordions. Updates the aria attributes of the accordion trigger button. Trigger button element must possess the following aria attributes; aria-expanded, aria-controls, aria-label (for only non-text triggers).
@@ -10,4 +10,21 @@ import { A as AccordionStates } from '../Types.d-uG0Hm1yK.cjs';
10
10
 
11
11
  declare function updateAccordionTriggerAriaAttributes(accordionId: string, accordionTriggersClass: string, accordionStates: AccordionStates[], clickedTriggerIndex: number): void;
12
12
 
13
- export { updateAccordionTriggerAriaAttributes };
13
+ /**
14
+ * Makes an accordion accessible by managing ARIA attributes, keyboard navigation, and state.
15
+ * Handles multiple accordion items with proper focus management and keyboard interactions.
16
+ * @param {string} accordionId - The id of the accordion container.
17
+ * @param {string} triggersClass - The shared class of all accordion trigger buttons.
18
+ * @param {string} panelsClass - The shared class of all accordion panels.
19
+ * @param {boolean} allowMultiple - Whether multiple panels can be open simultaneously (default: false).
20
+ */
21
+
22
+ interface AccordionConfig {
23
+ accordionId: string;
24
+ triggersClass: string;
25
+ panelsClass: string;
26
+ allowMultiple?: boolean;
27
+ }
28
+ declare function makeAccordionAccessible({ accordionId, triggersClass, panelsClass, allowMultiple }: AccordionConfig): AccessibilityInstance;
29
+
30
+ export { makeAccordionAccessible, updateAccordionTriggerAriaAttributes };
@@ -1,4 +1,4 @@
1
- import { A as AccordionStates } from '../Types.d-uG0Hm1yK.js';
1
+ import { A as AccordionStates, a as AccessibilityInstance } from '../Types.d-BrHSyS03.js';
2
2
 
3
3
  /**
4
4
  * Adds screen reader accessibility to accordions. Updates the aria attributes of the accordion trigger button. Trigger button element must possess the following aria attributes; aria-expanded, aria-controls, aria-label (for only non-text triggers).
@@ -10,4 +10,21 @@ import { A as AccordionStates } from '../Types.d-uG0Hm1yK.js';
10
10
 
11
11
  declare function updateAccordionTriggerAriaAttributes(accordionId: string, accordionTriggersClass: string, accordionStates: AccordionStates[], clickedTriggerIndex: number): void;
12
12
 
13
- export { updateAccordionTriggerAriaAttributes };
13
+ /**
14
+ * Makes an accordion accessible by managing ARIA attributes, keyboard navigation, and state.
15
+ * Handles multiple accordion items with proper focus management and keyboard interactions.
16
+ * @param {string} accordionId - The id of the accordion container.
17
+ * @param {string} triggersClass - The shared class of all accordion trigger buttons.
18
+ * @param {string} panelsClass - The shared class of all accordion panels.
19
+ * @param {boolean} allowMultiple - Whether multiple panels can be open simultaneously (default: false).
20
+ */
21
+
22
+ interface AccordionConfig {
23
+ accordionId: string;
24
+ triggersClass: string;
25
+ panelsClass: string;
26
+ allowMultiple?: boolean;
27
+ }
28
+ declare function makeAccordionAccessible({ accordionId, triggersClass, panelsClass, allowMultiple }: AccordionConfig): AccessibilityInstance;
29
+
30
+ export { makeAccordionAccessible, updateAccordionTriggerAriaAttributes };
@@ -24,4 +24,162 @@ function updateAccordionTriggerAriaAttributes(accordionId, accordionTriggersClas
24
24
  });
25
25
  }
26
26
 
27
- export { updateAccordionTriggerAriaAttributes };
27
+ // src/accordion/src/makeAccordionAccessible/makeAccordionAccessible.ts
28
+ function makeAccordionAccessible({ accordionId, triggersClass, panelsClass, allowMultiple = false }) {
29
+ const accordionContainer = document.querySelector(`#${accordionId}`);
30
+ if (!accordionContainer) {
31
+ console.error(`[aria-ease] Element with id="${accordionId}" not found. Make sure the accordion container exists before calling makeAccordionAccessible.`);
32
+ return { cleanup: () => {
33
+ } };
34
+ }
35
+ const triggers = Array.from(accordionContainer.querySelectorAll(`.${triggersClass}`));
36
+ if (triggers.length === 0) {
37
+ console.error(`[aria-ease] No elements with class="${triggersClass}" found. Make sure accordion triggers exist before calling makeAccordionAccessible.`);
38
+ return { cleanup: () => {
39
+ } };
40
+ }
41
+ const panels = Array.from(accordionContainer.querySelectorAll(`.${panelsClass}`));
42
+ if (panels.length === 0) {
43
+ console.error(`[aria-ease] No elements with class="${panelsClass}" found. Make sure accordion panels exist before calling makeAccordionAccessible.`);
44
+ return { cleanup: () => {
45
+ } };
46
+ }
47
+ if (triggers.length !== panels.length) {
48
+ console.error(`[aria-ease] Accordion trigger/panel mismatch: found ${triggers.length} triggers but ${panels.length} panels.`);
49
+ return { cleanup: () => {
50
+ } };
51
+ }
52
+ const handlerMap = /* @__PURE__ */ new WeakMap();
53
+ const clickHandlerMap = /* @__PURE__ */ new WeakMap();
54
+ function initialize() {
55
+ triggers.forEach((trigger, index) => {
56
+ const panel = panels[index];
57
+ if (!trigger.id) {
58
+ trigger.id = `${accordionId}-trigger-${index}`;
59
+ }
60
+ if (!panel.id) {
61
+ panel.id = `${accordionId}-panel-${index}`;
62
+ }
63
+ trigger.setAttribute("aria-controls", panel.id);
64
+ trigger.setAttribute("aria-expanded", "false");
65
+ panel.setAttribute("role", "region");
66
+ panel.setAttribute("aria-labelledby", trigger.id);
67
+ panel.style.display = "none";
68
+ });
69
+ }
70
+ function expandItem(index) {
71
+ if (index < 0 || index >= triggers.length) {
72
+ console.error(`[aria-ease] Invalid accordion index: ${index}`);
73
+ return;
74
+ }
75
+ const trigger = triggers[index];
76
+ const panel = panels[index];
77
+ trigger.setAttribute("aria-expanded", "true");
78
+ panel.style.display = "block";
79
+ }
80
+ function collapseItem(index) {
81
+ if (index < 0 || index >= triggers.length) {
82
+ console.error(`[aria-ease] Invalid accordion index: ${index}`);
83
+ return;
84
+ }
85
+ const trigger = triggers[index];
86
+ const panel = panels[index];
87
+ trigger.setAttribute("aria-expanded", "false");
88
+ panel.style.display = "none";
89
+ }
90
+ function toggleItem(index) {
91
+ const trigger = triggers[index];
92
+ const isExpanded = trigger.getAttribute("aria-expanded") === "true";
93
+ if (isExpanded) {
94
+ collapseItem(index);
95
+ } else {
96
+ if (!allowMultiple) {
97
+ triggers.forEach((_, i) => {
98
+ if (i !== index) {
99
+ collapseItem(i);
100
+ }
101
+ });
102
+ }
103
+ expandItem(index);
104
+ }
105
+ }
106
+ function handleTriggerClick(index) {
107
+ return () => {
108
+ toggleItem(index);
109
+ };
110
+ }
111
+ function handleTriggerKeydown(index) {
112
+ return (event) => {
113
+ const { key } = event;
114
+ switch (key) {
115
+ case "Enter":
116
+ case " ":
117
+ event.preventDefault();
118
+ toggleItem(index);
119
+ break;
120
+ case "ArrowDown":
121
+ event.preventDefault();
122
+ {
123
+ const nextIndex = (index + 1) % triggers.length;
124
+ triggers[nextIndex].focus();
125
+ }
126
+ break;
127
+ case "ArrowUp":
128
+ event.preventDefault();
129
+ {
130
+ const prevIndex = (index - 1 + triggers.length) % triggers.length;
131
+ triggers[prevIndex].focus();
132
+ }
133
+ break;
134
+ case "Home":
135
+ event.preventDefault();
136
+ triggers[0].focus();
137
+ break;
138
+ case "End":
139
+ event.preventDefault();
140
+ triggers[triggers.length - 1].focus();
141
+ break;
142
+ }
143
+ };
144
+ }
145
+ function addListeners() {
146
+ triggers.forEach((trigger, index) => {
147
+ const clickHandler = handleTriggerClick(index);
148
+ const keydownHandler = handleTriggerKeydown(index);
149
+ trigger.addEventListener("click", clickHandler);
150
+ trigger.addEventListener("keydown", keydownHandler);
151
+ handlerMap.set(trigger, keydownHandler);
152
+ clickHandlerMap.set(trigger, clickHandler);
153
+ });
154
+ }
155
+ function removeListeners() {
156
+ triggers.forEach((trigger) => {
157
+ const keydownHandler = handlerMap.get(trigger);
158
+ const clickHandler = clickHandlerMap.get(trigger);
159
+ if (keydownHandler) {
160
+ trigger.removeEventListener("keydown", keydownHandler);
161
+ handlerMap.delete(trigger);
162
+ }
163
+ if (clickHandler) {
164
+ trigger.removeEventListener("click", clickHandler);
165
+ clickHandlerMap.delete(trigger);
166
+ }
167
+ });
168
+ }
169
+ function cleanup() {
170
+ removeListeners();
171
+ triggers.forEach((_, index) => {
172
+ collapseItem(index);
173
+ });
174
+ }
175
+ initialize();
176
+ addListeners();
177
+ return {
178
+ expandItem,
179
+ collapseItem,
180
+ toggleItem,
181
+ cleanup
182
+ };
183
+ }
184
+
185
+ export { makeAccordionAccessible, updateAccordionTriggerAriaAttributes };
@@ -79,7 +79,7 @@ function handleKeyPress(event, elementItems, elementItemIndex, menuElementDiv, t
79
79
  }
80
80
 
81
81
  // src/block/src/makeBlockAccessible/makeBlockAccessible.ts
82
- function makeBlockAccessible(blockId, blockItemsClass) {
82
+ function makeBlockAccessible({ blockId, blockItemsClass }) {
83
83
  const blockDiv = document.querySelector(`#${blockId}`);
84
84
  if (!blockDiv) {
85
85
  console.error(`[aria-ease] Element with id="${blockId}" not found. Make sure the block element exists before calling makeBlockAccessible.`);
@@ -1,4 +1,4 @@
1
- import { a as AccessibilityInstance } from '../Types.d-uG0Hm1yK.cjs';
1
+ import { a as AccessibilityInstance } from '../Types.d-BrHSyS03.cjs';
2
2
 
3
3
  /**
4
4
  * Adds keyboard interaction to block. The block traps focus and can be interacted with using the keyboard.
@@ -6,6 +6,10 @@ import { a as AccessibilityInstance } from '../Types.d-uG0Hm1yK.cjs';
6
6
  * @param {string} blockItemsClass The shared class of the elements that are children of the block.
7
7
  */
8
8
 
9
- declare function makeBlockAccessible(blockId: string, blockItemsClass: string): AccessibilityInstance;
9
+ interface BlockConfig {
10
+ blockId: string;
11
+ blockItemsClass: string;
12
+ }
13
+ declare function makeBlockAccessible({ blockId, blockItemsClass }: BlockConfig): AccessibilityInstance;
10
14
 
11
15
  export { makeBlockAccessible };
@@ -1,4 +1,4 @@
1
- import { a as AccessibilityInstance } from '../Types.d-uG0Hm1yK.js';
1
+ import { a as AccessibilityInstance } from '../Types.d-BrHSyS03.js';
2
2
 
3
3
  /**
4
4
  * Adds keyboard interaction to block. The block traps focus and can be interacted with using the keyboard.
@@ -6,6 +6,10 @@ import { a as AccessibilityInstance } from '../Types.d-uG0Hm1yK.js';
6
6
  * @param {string} blockItemsClass The shared class of the elements that are children of the block.
7
7
  */
8
8
 
9
- declare function makeBlockAccessible(blockId: string, blockItemsClass: string): AccessibilityInstance;
9
+ interface BlockConfig {
10
+ blockId: string;
11
+ blockItemsClass: string;
12
+ }
13
+ declare function makeBlockAccessible({ blockId, blockItemsClass }: BlockConfig): AccessibilityInstance;
10
14
 
11
15
  export { makeBlockAccessible };
@@ -1,7 +1,7 @@
1
1
  import { handleKeyPress } from '../chunk-TBJ6MIC7.js';
2
2
 
3
3
  // src/block/src/makeBlockAccessible/makeBlockAccessible.ts
4
- function makeBlockAccessible(blockId, blockItemsClass) {
4
+ function makeBlockAccessible({ blockId, blockItemsClass }) {
5
5
  const blockDiv = document.querySelector(`#${blockId}`);
6
6
  if (!blockDiv) {
7
7
  console.error(`[aria-ease] Element with id="${blockId}" not found. Make sure the block element exists before calling makeBlockAccessible.`);
@@ -31,4 +31,133 @@ function updateCheckboxAriaAttributes(checkboxId, checkboxesClass, checkboxState
31
31
  });
32
32
  }
33
33
 
34
+ // src/checkbox/src/makeCheckboxAccessible/makeCheckboxAccessible.ts
35
+ function makeCheckboxAccessible({ checkboxGroupId, checkboxesClass }) {
36
+ const checkboxGroup = document.querySelector(`#${checkboxGroupId}`);
37
+ if (!checkboxGroup) {
38
+ console.error(`[aria-ease] Element with id="${checkboxGroupId}" not found. Make sure the checkbox group container exists before calling makeCheckboxAccessible.`);
39
+ return { cleanup: () => {
40
+ } };
41
+ }
42
+ const checkboxes = Array.from(checkboxGroup.querySelectorAll(`.${checkboxesClass}`));
43
+ if (checkboxes.length === 0) {
44
+ console.error(`[aria-ease] No elements with class="${checkboxesClass}" found. Make sure checkboxes exist before calling makeCheckboxAccessible.`);
45
+ return { cleanup: () => {
46
+ } };
47
+ }
48
+ const handlerMap = /* @__PURE__ */ new WeakMap();
49
+ const clickHandlerMap = /* @__PURE__ */ new WeakMap();
50
+ function initialize() {
51
+ if (!checkboxGroup.getAttribute("role")) {
52
+ checkboxGroup.setAttribute("role", "group");
53
+ }
54
+ checkboxes.forEach((checkbox) => {
55
+ checkbox.setAttribute("role", "checkbox");
56
+ if (!checkbox.hasAttribute("aria-checked")) {
57
+ checkbox.setAttribute("aria-checked", "false");
58
+ }
59
+ if (!checkbox.hasAttribute("tabindex")) {
60
+ checkbox.setAttribute("tabindex", "0");
61
+ }
62
+ });
63
+ }
64
+ function toggleCheckbox(index) {
65
+ if (index < 0 || index >= checkboxes.length) {
66
+ console.error(`[aria-ease] Invalid checkbox index: ${index}`);
67
+ return;
68
+ }
69
+ const checkbox = checkboxes[index];
70
+ const isChecked = checkbox.getAttribute("aria-checked") === "true";
71
+ checkbox.setAttribute("aria-checked", isChecked ? "false" : "true");
72
+ }
73
+ function setCheckboxState(index, checked) {
74
+ if (index < 0 || index >= checkboxes.length) {
75
+ console.error(`[aria-ease] Invalid checkbox index: ${index}`);
76
+ return;
77
+ }
78
+ checkboxes[index].setAttribute("aria-checked", checked ? "true" : "false");
79
+ }
80
+ function handleCheckboxClick(index) {
81
+ return () => {
82
+ toggleCheckbox(index);
83
+ };
84
+ }
85
+ function handleCheckboxKeydown(index) {
86
+ return (event) => {
87
+ const { key } = event;
88
+ switch (key) {
89
+ case " ":
90
+ event.preventDefault();
91
+ toggleCheckbox(index);
92
+ break;
93
+ case "ArrowDown":
94
+ event.preventDefault();
95
+ {
96
+ const nextIndex = (index + 1) % checkboxes.length;
97
+ checkboxes[nextIndex].focus();
98
+ }
99
+ break;
100
+ case "ArrowUp":
101
+ event.preventDefault();
102
+ {
103
+ const prevIndex = (index - 1 + checkboxes.length) % checkboxes.length;
104
+ checkboxes[prevIndex].focus();
105
+ }
106
+ break;
107
+ case "Home":
108
+ event.preventDefault();
109
+ checkboxes[0].focus();
110
+ break;
111
+ case "End":
112
+ event.preventDefault();
113
+ checkboxes[checkboxes.length - 1].focus();
114
+ break;
115
+ }
116
+ };
117
+ }
118
+ function addListeners() {
119
+ checkboxes.forEach((checkbox, index) => {
120
+ const clickHandler = handleCheckboxClick(index);
121
+ const keydownHandler = handleCheckboxKeydown(index);
122
+ checkbox.addEventListener("click", clickHandler);
123
+ checkbox.addEventListener("keydown", keydownHandler);
124
+ handlerMap.set(checkbox, keydownHandler);
125
+ clickHandlerMap.set(checkbox, clickHandler);
126
+ });
127
+ }
128
+ function removeListeners() {
129
+ checkboxes.forEach((checkbox) => {
130
+ const keydownHandler = handlerMap.get(checkbox);
131
+ const clickHandler = clickHandlerMap.get(checkbox);
132
+ if (keydownHandler) {
133
+ checkbox.removeEventListener("keydown", keydownHandler);
134
+ handlerMap.delete(checkbox);
135
+ }
136
+ if (clickHandler) {
137
+ checkbox.removeEventListener("click", clickHandler);
138
+ clickHandlerMap.delete(checkbox);
139
+ }
140
+ });
141
+ }
142
+ function cleanup() {
143
+ removeListeners();
144
+ }
145
+ function getCheckedStates() {
146
+ return checkboxes.map((checkbox) => checkbox.getAttribute("aria-checked") === "true");
147
+ }
148
+ function getCheckedIndices() {
149
+ return checkboxes.map((checkbox, index) => checkbox.getAttribute("aria-checked") === "true" ? index : -1).filter((index) => index !== -1);
150
+ }
151
+ initialize();
152
+ addListeners();
153
+ return {
154
+ toggleCheckbox,
155
+ setCheckboxState,
156
+ getCheckedStates,
157
+ getCheckedIndices,
158
+ cleanup
159
+ };
160
+ }
161
+
162
+ exports.makeCheckboxAccessible = makeCheckboxAccessible;
34
163
  exports.updateCheckboxAriaAttributes = updateCheckboxAriaAttributes;
@@ -1,4 +1,4 @@
1
- import { C as CheckboxStates } from '../Types.d-uG0Hm1yK.cjs';
1
+ import { C as CheckboxStates, a as AccessibilityInstance } from '../Types.d-BrHSyS03.cjs';
2
2
 
3
3
  /**
4
4
  * Adds screen reader accessibility to multiple checkboxes. Updates the aria attributes of the checkboxes. Checkbox elements must possess the following aria attributes; aria-checked and aria-label.
@@ -10,4 +10,17 @@ import { C as CheckboxStates } from '../Types.d-uG0Hm1yK.cjs';
10
10
 
11
11
  declare function updateCheckboxAriaAttributes(checkboxId: string, checkboxesClass: string, checkboxStates: CheckboxStates[], currentPressedCheckboxIndex: number): void;
12
12
 
13
- export { updateCheckboxAriaAttributes };
13
+ /**
14
+ * Makes a checkbox group accessible by managing ARIA attributes and keyboard navigation.
15
+ * Handles multiple independent checkboxes with proper focus management and keyboard interactions.
16
+ * @param {string} checkboxGroupId - The id of the checkbox group container.
17
+ * @param {string} checkboxesClass - The shared class of all checkboxes.
18
+ */
19
+
20
+ interface CheckboxConfig {
21
+ checkboxGroupId: string;
22
+ checkboxesClass: string;
23
+ }
24
+ declare function makeCheckboxAccessible({ checkboxGroupId, checkboxesClass }: CheckboxConfig): AccessibilityInstance;
25
+
26
+ export { makeCheckboxAccessible, updateCheckboxAriaAttributes };
@@ -1,4 +1,4 @@
1
- import { C as CheckboxStates } from '../Types.d-uG0Hm1yK.js';
1
+ import { C as CheckboxStates, a as AccessibilityInstance } from '../Types.d-BrHSyS03.js';
2
2
 
3
3
  /**
4
4
  * Adds screen reader accessibility to multiple checkboxes. Updates the aria attributes of the checkboxes. Checkbox elements must possess the following aria attributes; aria-checked and aria-label.
@@ -10,4 +10,17 @@ import { C as CheckboxStates } from '../Types.d-uG0Hm1yK.js';
10
10
 
11
11
  declare function updateCheckboxAriaAttributes(checkboxId: string, checkboxesClass: string, checkboxStates: CheckboxStates[], currentPressedCheckboxIndex: number): void;
12
12
 
13
- export { updateCheckboxAriaAttributes };
13
+ /**
14
+ * Makes a checkbox group accessible by managing ARIA attributes and keyboard navigation.
15
+ * Handles multiple independent checkboxes with proper focus management and keyboard interactions.
16
+ * @param {string} checkboxGroupId - The id of the checkbox group container.
17
+ * @param {string} checkboxesClass - The shared class of all checkboxes.
18
+ */
19
+
20
+ interface CheckboxConfig {
21
+ checkboxGroupId: string;
22
+ checkboxesClass: string;
23
+ }
24
+ declare function makeCheckboxAccessible({ checkboxGroupId, checkboxesClass }: CheckboxConfig): AccessibilityInstance;
25
+
26
+ export { makeCheckboxAccessible, updateCheckboxAriaAttributes };