accessible-kit 1.0.0 → 1.0.2

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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,69 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.0.1] - 2025-12-20
9
+
10
+ ### Changed
11
+ - **BREAKING**: Removed automatic initialization from all components
12
+ - Components now require manual initialization via `initComponentName()` functions
13
+ - Removed global `window.a11yKit` namespace registration
14
+ - Updated all demo HTML files to use manual initialization with `DOMContentLoaded`
15
+ - Updated documentation and examples in README.md to reflect manual initialization
16
+ - Updated all component usage examples to show proper initialization pattern
17
+
18
+ ### Fixed
19
+ - Fixed dropdown instance tracking - replaced `window.a11yKit._dropdownInstances` with static class property `AccessibleDropdown.instances`
20
+ - Fixed tree-shaking compatibility - `sideEffects: false` in package.json now works correctly
21
+ - Fixed module bundler compatibility (Astro, Vite, Webpack) - no more side effects on import
22
+
23
+ ### Added
24
+ - Static instance tracking for dropdown component using `AccessibleDropdown.instances`
25
+
26
+ ### Migration Guide (1.0.0 → 1.0.1)
27
+
28
+ #### Before (1.0.0):
29
+ ```javascript
30
+ // Components initialized automatically on import
31
+ import 'accessible-kit/dropdown';
32
+ // Dropdown was auto-initialized
33
+ ```
34
+
35
+ #### After (1.0.1):
36
+ ```javascript
37
+ // Manual initialization required
38
+ import { initDropdowns } from 'accessible-kit/dropdown';
39
+
40
+ document.addEventListener('DOMContentLoaded', () => {
41
+ initDropdowns();
42
+ });
43
+ ```
44
+
45
+ #### Benefits of this change:
46
+ - ✅ True tree-shaking support - only used components are bundled
47
+ - ✅ SSR framework compatibility (Astro, Next.js, SvelteKit)
48
+ - ✅ Better control over initialization timing
49
+ - ✅ No unwanted side effects on import
50
+ - ✅ Follows modern JavaScript best practices
51
+
52
+ ## [1.0.0] - 2024-12-XX
53
+
54
+ ### Added
55
+ - Initial release
56
+ - Dropdown component with full ARIA support
57
+ - Tabs component following WAI-ARIA Tabs Pattern
58
+ - Accordion/Collapse components with keyboard navigation
59
+ - Modal component with focus trap
60
+ - Offcanvas component with slide-out panels
61
+ - Complete keyboard navigation support
62
+ - Dark mode and high contrast mode support
63
+ - Reduced motion support
64
+ - Separated core/theme CSS architecture
65
+ - Zero dependencies
66
+ - Full TypeScript-ready exports
67
+
68
+ [1.0.1]: https://github.com/5ulo/accessible-kit/compare/v1.0.0...v1.0.1
69
+ [1.0.0]: https://github.com/5ulo/accessible-kit/releases/tag/v1.0.0
package/README.md CHANGED
@@ -54,21 +54,24 @@ npm install accessible-kit
54
54
  yarn add accessible-kit
55
55
  ```
56
56
 
57
- ### CDN
57
+ ### CDN (ES Modules)
58
58
 
59
59
  ```html
60
- <!-- All components -->
61
- <script src="https://unpkg.com/accessible-kit/src/js/index.js"></script>
62
-
63
- <!-- Individual component -->
64
- <script src="https://unpkg.com/accessible-kit/src/js/a11y-dropdown.js"></script>
60
+ <!-- Individual component with manual initialization -->
61
+ <script type="module">
62
+ import { initDropdowns } from 'https://unpkg.com/accessible-kit/src/js/a11y-dropdown.js';
63
+
64
+ document.addEventListener('DOMContentLoaded', () => {
65
+ initDropdowns();
66
+ });
67
+ </script>
65
68
  <link rel="stylesheet" href="https://unpkg.com/accessible-kit/src/css/a11y-dropdown.core.css">
66
69
  <link rel="stylesheet" href="https://unpkg.com/accessible-kit/src/css/a11y-dropdown.theme.css">
67
70
  ```
68
71
 
69
72
  ## 🚀 Quick Start
70
73
 
71
- ### Using CDN
74
+ ### Using ES Modules (Recommended for Modern Browsers)
72
75
 
73
76
  ```html
74
77
  <!DOCTYPE html>
@@ -93,7 +96,13 @@ yarn add accessible-kit
93
96
  </div>
94
97
  </div>
95
98
 
96
- <script src="https://unpkg.com/accessible-kit/src/js/a11y-dropdown.js"></script>
99
+ <script type="module">
100
+ import { initDropdowns } from 'https://unpkg.com/accessible-kit/src/js/a11y-dropdown.js';
101
+
102
+ document.addEventListener('DOMContentLoaded', () => {
103
+ initDropdowns();
104
+ });
105
+ </script>
97
106
  </body>
98
107
  </html>
99
108
  ```
@@ -101,21 +110,26 @@ yarn add accessible-kit
101
110
  ### Using NPM/Modules
102
111
 
103
112
  ```javascript
104
- // Import all components
105
- import 'accessible-kit';
106
-
107
- // Or import specific components
108
- import 'accessible-kit/dropdown';
109
- import 'accessible-kit/tabs';
113
+ // Import specific components (best for tree-shaking)
114
+ import { initDropdowns } from 'accessible-kit/dropdown';
115
+ import { initTabs } from 'accessible-kit/tabs';
110
116
 
111
117
  // Import styles
112
118
  import 'accessible-kit/styles/dropdown-core';
113
119
  import 'accessible-kit/styles/dropdown-theme';
114
120
 
115
- // Initialize
116
- a11yKit.initAll();
117
- // or
118
- a11yKit.initDropdowns();
121
+ // Initialize after DOM is ready
122
+ document.addEventListener('DOMContentLoaded', () => {
123
+ initDropdowns();
124
+ initTabs();
125
+ });
126
+
127
+ // Or import all components
128
+ import { initAll } from 'accessible-kit';
129
+
130
+ document.addEventListener('DOMContentLoaded', () => {
131
+ initAll();
132
+ });
119
133
  ```
120
134
 
121
135
  ### Module Imports (ES6+)
@@ -202,11 +216,15 @@ Fully accessible dropdown component with keyboard navigation and ARIA support.
202
216
  ### JavaScript Initialization
203
217
 
204
218
  ```javascript
205
- // Auto-initialize all dropdowns
206
- initDropdowns();
219
+ import { initDropdowns, Dropdown } from 'accessible-kit/dropdown';
220
+
221
+ // Initialize all dropdowns
222
+ document.addEventListener('DOMContentLoaded', () => {
223
+ initDropdowns();
224
+ });
207
225
 
208
226
  // Or manual initialization with options
209
- const dropdown = new AccessibleDropdown(element, {
227
+ const dropdown = new Dropdown(element, {
210
228
  closeOnSelect: true,
211
229
  closeOnOutsideClick: true,
212
230
  closeOnEscape: true,
@@ -390,11 +408,15 @@ Fully accessible tabs component following WAI-ARIA Tabs Pattern.
390
408
  ### JavaScript Initialization
391
409
 
392
410
  ```javascript
393
- // Auto-initialize all tabs
394
- initTabs();
411
+ import { initTabs, Tabs } from 'accessible-kit/tabs';
395
412
 
396
- // Manual initialization
397
- const tabs = new AccessibleTabs(element, {
413
+ // Initialize all tabs
414
+ document.addEventListener('DOMContentLoaded', () => {
415
+ initTabs();
416
+ });
417
+
418
+ // Or manual initialization with options
419
+ const tabs = new Tabs(element, {
398
420
  activeIndex: 0, // Initial active tab (0-based)
399
421
  automatic: true, // Auto-activate on arrow keys
400
422
  orientation: 'horizontal', // 'horizontal' or 'vertical'
@@ -591,11 +613,15 @@ Fully accessible accordion component with keyboard navigation.
591
613
  ### JavaScript Initialization
592
614
 
593
615
  ```javascript
594
- // Auto-initialize all accordions
595
- initAccordions();
616
+ import { initAccordions, Accordion } from 'accessible-kit/accordion';
617
+
618
+ // Initialize all accordions
619
+ document.addEventListener('DOMContentLoaded', () => {
620
+ initAccordions();
621
+ });
596
622
 
597
- // Manual initialization
598
- const accordion = new AccessibleAccordion(element, {
623
+ // Or manual initialization with options
624
+ const accordion = new Accordion(element, {
599
625
  allowMultiple: false,
600
626
  allowToggle: true,
601
627
  defaultExpanded: [],
@@ -808,11 +834,15 @@ Accessible modal dialogs with focus trap following WAI-ARIA Dialog Pattern.
808
834
  ### JavaScript Initialization
809
835
 
810
836
  ```javascript
811
- // Auto-initialize all modals
812
- initModals();
837
+ import { initModals, Modal } from 'accessible-kit/modal';
838
+
839
+ // Initialize all modals
840
+ document.addEventListener('DOMContentLoaded', () => {
841
+ initModals();
842
+ });
813
843
 
814
- // Manual initialization
815
- const modal = new AccessibleModal(element, {
844
+ // Or manual initialization with options
845
+ const modal = new Modal(element, {
816
846
  closeOnBackdropClick: true,
817
847
  closeOnEscape: true,
818
848
  lockScroll: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "accessible-kit",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Lightweight, accessible UI component library with full ARIA support. Zero dependencies, vanilla JavaScript.",
5
5
  "main": "src/js/index.js",
6
6
  "type": "module",
@@ -61,21 +61,52 @@
61
61
  "./accordion": {
62
62
  "import": "./src/js/a11y-accordion.js"
63
63
  },
64
- "./styles/dropdown-core": "./src/css/a11y-dropdown.core.css",
65
- "./styles/dropdown-theme": "./src/css/a11y-dropdown.theme.css",
66
- "./styles/tabs-core": "./src/css/a11y-tabs.core.css",
67
- "./styles/tabs-theme": "./src/css/a11y-tabs.theme.css",
68
- "./styles/offcanvas-core": "./src/css/a11y-offcanvas.core.css",
69
- "./styles/offcanvas-theme": "./src/css/a11y-offcanvas.theme.css",
70
- "./styles/modal-core": "./src/css/a11y-modal.core.css",
71
- "./styles/modal-theme": "./src/css/a11y-modal.theme.css",
72
- "./styles/accordion-core": "./src/css/a11y-accordion.core.css",
73
- "./styles/accordion-theme": "./src/css/a11y-accordion.theme.css"
64
+ "./styles/dropdown-core": {
65
+ "style": "./src/css/a11y-dropdown.core.css",
66
+ "default": "./src/css/a11y-dropdown.core.css"
67
+ },
68
+ "./styles/dropdown-theme": {
69
+ "style": "./src/css/a11y-dropdown.theme.css",
70
+ "default": "./src/css/a11y-dropdown.theme.css"
71
+ },
72
+ "./styles/tabs-core": {
73
+ "style": "./src/css/a11y-tabs.core.css",
74
+ "default": "./src/css/a11y-tabs.core.css"
75
+ },
76
+ "./styles/tabs-theme": {
77
+ "style": "./src/css/a11y-tabs.theme.css",
78
+ "default": "./src/css/a11y-tabs.theme.css"
79
+ },
80
+ "./styles/offcanvas-core": {
81
+ "style": "./src/css/a11y-offcanvas.core.css",
82
+ "default": "./src/css/a11y-offcanvas.core.css"
83
+ },
84
+ "./styles/offcanvas-theme": {
85
+ "style": "./src/css/a11y-offcanvas.theme.css",
86
+ "default": "./src/css/a11y-offcanvas.theme.css"
87
+ },
88
+ "./styles/modal-core": {
89
+ "style": "./src/css/a11y-modal.core.css",
90
+ "default": "./src/css/a11y-modal.core.css"
91
+ },
92
+ "./styles/modal-theme": {
93
+ "style": "./src/css/a11y-modal.theme.css",
94
+ "default": "./src/css/a11y-modal.theme.css"
95
+ },
96
+ "./styles/accordion-core": {
97
+ "style": "./src/css/a11y-accordion.core.css",
98
+ "default": "./src/css/a11y-accordion.core.css"
99
+ },
100
+ "./styles/accordion-theme": {
101
+ "style": "./src/css/a11y-accordion.theme.css",
102
+ "default": "./src/css/a11y-accordion.theme.css"
103
+ }
74
104
  },
75
105
  "files": [
76
106
  "src/js",
77
107
  "src/css",
78
108
  "README.md",
109
+ "CHANGELOG.md",
79
110
  "LICENSE"
80
111
  ]
81
112
  }
@@ -408,34 +408,22 @@ class AccessibleCollapse extends AccessibleAccordion {
408
408
  }
409
409
  }
410
410
 
411
- // Auto-initialize standalone collapses only
411
+ /**
412
+ * Initialize standalone collapses only
413
+ * Call this manually after DOM is ready
414
+ */
412
415
  function initCollapses() {
413
416
  return new AccessibleCollapse();
414
417
  }
415
418
 
416
- // Auto-initialize accordions (both collapses and accordion groups)
419
+ /**
420
+ * Initialize accordions (both collapses and accordion groups)
421
+ * Call this manually after DOM is ready
422
+ */
417
423
  function initAccordions() {
418
424
  return new AccessibleAccordion();
419
425
  }
420
426
 
421
- // Initialize on DOM ready (only if not using module bundler)
422
- if (typeof window !== 'undefined' && !window.a11yKitManualInit) {
423
- if (document.readyState === 'loading') {
424
- document.addEventListener('DOMContentLoaded', initAccordions);
425
- } else {
426
- initAccordions();
427
- }
428
- }
429
-
430
- // Register in global namespace for CDN usage
431
- if (typeof window !== 'undefined') {
432
- window.a11yKit = window.a11yKit || {};
433
- window.a11yKit.Collapse = AccessibleCollapse;
434
- window.a11yKit.Accordion = AccessibleAccordion;
435
- window.a11yKit.initCollapses = initCollapses;
436
- window.a11yKit.initAccordions = initAccordions;
437
- }
438
-
439
427
  // ES6 exports with short aliases
440
428
  export {
441
429
  AccessibleCollapse,
@@ -5,6 +5,9 @@
5
5
  */
6
6
 
7
7
  class AccessibleDropdown {
8
+ // Static array to track all dropdown instances
9
+ static instances = [];
10
+
8
11
  constructor(element, options = {}) {
9
12
  this.dropdown = element;
10
13
  this.button = element.querySelector("[data-dropdown-button]");
@@ -28,12 +31,8 @@ class AccessibleDropdown {
28
31
  this.currentIndex = -1;
29
32
  this.hoverTimeout = null;
30
33
 
31
- // Register instance globally for managing multiple dropdowns
32
- if (typeof window !== 'undefined') {
33
- window.a11yKit = window.a11yKit || {};
34
- window.a11yKit._dropdownInstances = window.a11yKit._dropdownInstances || [];
35
- window.a11yKit._dropdownInstances.push(this);
36
- }
34
+ // Register this instance
35
+ AccessibleDropdown.instances.push(this);
37
36
 
38
37
  this.init();
39
38
  }
@@ -120,13 +119,11 @@ class AccessibleDropdown {
120
119
  if (this.isOpen) return;
121
120
 
122
121
  // Close other dropdowns first
123
- if (typeof window !== 'undefined' && window.a11yKit._dropdownInstances) {
124
- window.a11yKit._dropdownInstances.forEach(instance => {
125
- if (instance !== this && instance.isOpen) {
126
- instance.close();
127
- }
128
- });
129
- }
122
+ AccessibleDropdown.instances.forEach(instance => {
123
+ if (instance !== this && instance.isOpen) {
124
+ instance.close();
125
+ }
126
+ });
130
127
 
131
128
  this.isOpen = true;
132
129
  this.dropdown.classList.add("is-open");
@@ -313,7 +310,10 @@ class AccessibleDropdown {
313
310
  }
314
311
  }
315
312
 
316
- // Auto-initialize dropdowns
313
+ /**
314
+ * Initialize all dropdowns on the page
315
+ * Call this manually after DOM is ready
316
+ */
317
317
  function initDropdowns() {
318
318
  const dropdowns = document.querySelectorAll("[data-dropdown]");
319
319
  const instances = [];
@@ -333,21 +333,5 @@ function initDropdowns() {
333
333
  return instances;
334
334
  }
335
335
 
336
- // Initialize on DOM ready (only if not using module bundler)
337
- if (typeof window !== 'undefined' && !window.a11yKitManualInit) {
338
- if (document.readyState === 'loading') {
339
- document.addEventListener('DOMContentLoaded', initDropdowns);
340
- } else {
341
- initDropdowns();
342
- }
343
- }
344
-
345
- // Register in global namespace for CDN usage
346
- if (typeof window !== 'undefined') {
347
- window.a11yKit = window.a11yKit || {};
348
- window.a11yKit.Dropdown = AccessibleDropdown;
349
- window.a11yKit.initDropdowns = initDropdowns;
350
- }
351
-
352
336
  // ES6 exports with short aliases
353
337
  export { AccessibleDropdown, AccessibleDropdown as Dropdown, initDropdowns };
@@ -251,7 +251,10 @@ class AccessibleModal {
251
251
  }
252
252
  }
253
253
 
254
- // Auto-initialize modals
254
+ /**
255
+ * Initialize all modals on the page
256
+ * Call this manually after DOM is ready
257
+ */
255
258
  function initModals() {
256
259
  const modalElements = document.querySelectorAll("[data-modal]");
257
260
  const instances = [];
@@ -270,21 +273,5 @@ function initModals() {
270
273
  return instances;
271
274
  }
272
275
 
273
- // Initialize on DOM ready (only if not using module bundler)
274
- if (typeof window !== 'undefined' && !window.a11yKitManualInit) {
275
- if (document.readyState === 'loading') {
276
- document.addEventListener('DOMContentLoaded', initModals);
277
- } else {
278
- initModals();
279
- }
280
- }
281
-
282
- // Register in global namespace for CDN usage
283
- if (typeof window !== 'undefined') {
284
- window.a11yKit = window.a11yKit || {};
285
- window.a11yKit.Modal = AccessibleModal;
286
- window.a11yKit.initModals = initModals;
287
- }
288
-
289
276
  // ES6 exports with short aliases
290
277
  export { AccessibleModal, AccessibleModal as Modal, initModals };
@@ -259,7 +259,10 @@ class AccessibleOffcanvas {
259
259
  }
260
260
  }
261
261
 
262
- // Auto-initialize offcanvas
262
+ /**
263
+ * Initialize all offcanvas elements on the page
264
+ * Call this manually after DOM is ready
265
+ */
263
266
  function initOffcanvas() {
264
267
  const offcanvasElements = document.querySelectorAll("[data-offcanvas]");
265
268
  const instances = [];
@@ -278,21 +281,5 @@ function initOffcanvas() {
278
281
  return instances;
279
282
  }
280
283
 
281
- // Initialize on DOM ready (only if not using module bundler)
282
- if (typeof window !== 'undefined' && !window.a11yKitManualInit) {
283
- if (document.readyState === 'loading') {
284
- document.addEventListener('DOMContentLoaded', initOffcanvas);
285
- } else {
286
- initOffcanvas();
287
- }
288
- }
289
-
290
- // Register in global namespace for CDN usage
291
- if (typeof window !== 'undefined') {
292
- window.a11yKit = window.a11yKit || {};
293
- window.a11yKit.Offcanvas = AccessibleOffcanvas;
294
- window.a11yKit.initOffcanvas = initOffcanvas;
295
- }
296
-
297
284
  // ES6 exports with short aliases
298
285
  export { AccessibleOffcanvas, AccessibleOffcanvas as Offcanvas, initOffcanvas };
@@ -298,7 +298,10 @@ class AccessibleTabs {
298
298
  }
299
299
  }
300
300
 
301
- // Auto-initialize tabs
301
+ /**
302
+ * Initialize all tabs on the page
303
+ * Call this manually after DOM is ready
304
+ */
302
305
  function initTabs() {
303
306
  const tabsElements = document.querySelectorAll("[data-tabs]");
304
307
  const instances = [];
@@ -316,21 +319,5 @@ function initTabs() {
316
319
  return instances;
317
320
  }
318
321
 
319
- // Initialize on DOM ready (only if not using module bundler)
320
- if (typeof window !== 'undefined' && !window.a11yKitManualInit) {
321
- if (document.readyState === 'loading') {
322
- document.addEventListener('DOMContentLoaded', initTabs);
323
- } else {
324
- initTabs();
325
- }
326
- }
327
-
328
- // Register in global namespace for CDN usage
329
- if (typeof window !== 'undefined') {
330
- window.a11yKit = window.a11yKit || {};
331
- window.a11yKit.Tabs = AccessibleTabs;
332
- window.a11yKit.initTabs = initTabs;
333
- }
334
-
335
322
  // ES6 exports with short aliases
336
323
  export { AccessibleTabs, AccessibleTabs as Tabs, initTabs };
package/src/js/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * a11y-kit
3
3
  * Lightweight, accessible UI component library with full ARIA support
4
4
  *
5
- * @version 1.0.0
5
+ * @version 1.0.2
6
6
  * @license MIT
7
7
  */
8
8
 
@@ -15,7 +15,7 @@ export { AccessibleCollapse, Collapse, initCollapses, AccessibleAccordion, Accor
15
15
 
16
16
  /**
17
17
  * Initialize all components at once
18
- * Convenient helper for auto-initializing all a11y-kit components
18
+ * Convenient helper for manually initializing all a11y-kit components
19
19
  */
20
20
  export function initAll() {
21
21
  const instances = {
@@ -29,18 +29,3 @@ export function initAll() {
29
29
 
30
30
  return instances;
31
31
  }
32
-
33
- // Auto-initialize on DOM ready if not using module bundler
34
- if (typeof window !== 'undefined' && !window.a11yKitManualInit) {
35
- if (document.readyState === 'loading') {
36
- document.addEventListener('DOMContentLoaded', initAll);
37
- } else {
38
- initAll();
39
- }
40
- }
41
-
42
- // Register in global namespace for CDN usage
43
- if (typeof window !== 'undefined') {
44
- window.a11yKit = window.a11yKit || {};
45
- window.a11yKit.initAll = initAll;
46
- }