{"_id":"@bluecadet/embla-carousel-a11y","_rev":"3-09226c7eb01d82d5afa4cc5b8eaecb2c","name":"@bluecadet/embla-carousel-a11y","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@bluecadet/embla-carousel-a11y","version":"0.1.0","author":{"name":"Bluecadet"},"license":"MIT","_id":"@bluecadet/embla-carousel-a11y@0.1.0","maintainers":[{"name":"baerkins","email":"shaun.baer@gmail.com"},{"name":"peteinge","email":"pete.inge@gmail.com"},{"name":"benjaminbojko","email":"b@bbojko.de"},{"name":"claytercek","email":"clay@tercek.me"},{"name":"bluecadetreleases","email":"releases@bluecadet.com"}],"homepage":"https://github.com/bluecadet/orbit/blob/main/packages/embla-carousel-a11y#readme","bugs":{"url":"https://github.com/bluecadet/orbit/issues"},"dist":{"shasum":"08fd53b0509f6b8d43cf2ed741cce6bee390a69a","tarball":"https://registry.npmjs.org/@bluecadet/embla-carousel-a11y/-/embla-carousel-a11y-0.1.0.tgz","fileCount":6,"integrity":"sha512-nU0t4Lo/h2aeg12BKip/+eR+sJezd6cYLg6NmjsAts2iHFtRH0/ECgBPzlmiaFLkQPLYefEPyB73LmpIrb5x2g==","signatures":[{"sig":"MEQCIEtQyc80rWHitAff+4o6xrJzZRAFUfqIoxZLoLlNfdNCAiAzI2ZS0KNQJXL2Qg+YdJhLNz46KkEZhQzjX+03zaz1JA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":25858},"type":"module","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./package.json":"./package.json"},"gitHead":"0207abd95c4a0fd3355f7d566e19ead806cab44a","scripts":{"dev":"tsup --watch","lint":"eslint","test":"vitest","build":"tsup","clean":"git clean -xdf .turbo node_modules dist .cache","format":"prettier --check . --ignore-path ../../.gitignore","typecheck":"tsc --noEmit"},"_npmUser":{"name":"bluecadetreleases","email":"releases@bluecadet.com"},"repository":{"url":"git+https://github.com/bluecadet/orbit.git","type":"git"},"_npmVersion":"10.9.2","description":"A11y Plugin for Embla Carousel","directories":{},"sideEffects":false,"_nodeVersion":"23.10.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.2","eslint":"^9.19.0","vitest":"^3.0.9","prettier":"^3.4.2","happy-dom":"^17.4.4","typescript":"^5.7.3","@repo/eslint":"*","@repo/prettier":"*","@repo/typescript":"*"},"peerDependencies":{"embla-carousel":"^8.5.2"},"_npmOperationalInternal":{"tmp":"tmp/embla-carousel-a11y_0.1.0_1743540336929_0.3369542284206666","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@bluecadet/embla-carousel-a11y","version":"0.1.1","keywords":["accessibility","a11y","react","js","ts","javascript","typescript","carousel","slider","drag","aria"],"author":{"url":"https://bluecadet.com","name":"Bluecadet"},"license":"MIT","_id":"@bluecadet/embla-carousel-a11y@0.1.1","maintainers":[{"name":"baerkins","email":"shaun.baer@gmail.com"},{"name":"peteinge","email":"pete.inge@gmail.com"},{"name":"benjaminbojko","email":"b@bbojko.de"},{"name":"claytercek","email":"clay@tercek.me"},{"name":"bluecadetreleases","email":"releases@bluecadet.com"}],"homepage":"https://github.com/bluecadet/orbit/blob/main/packages/embla-carousel-a11y#readme","bugs":{"url":"https://github.com/bluecadet/orbit/issues"},"dist":{"shasum":"f0a6b472dede1aa0c03a8879f217ff7ecae48f56","tarball":"https://registry.npmjs.org/@bluecadet/embla-carousel-a11y/-/embla-carousel-a11y-0.1.1.tgz","fileCount":6,"integrity":"sha512-aV65QWMhHLcz4tBieGjteL8vsa5zbXhLEzv8at1ug7TNAqyNUwxuo55l8mkDgibViLeJQJXAC1bu5SVCB2gPmA==","signatures":[{"sig":"MEUCIFtfA7xzxDjy2Vo/p7gH83WQZi3xdYnZ+hek76zp1BvNAiEAvhxtXJCIW6X9tQ/yFXUBFKxvv2XvTqGuflsDSfH5Z/Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":26264},"type":"module","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./package.json":"./package.json"},"gitHead":"a9588c91a19d41c3764fb4b116cd9b3ee351ea4c","scripts":{"dev":"tsup --watch","lint":"eslint","test":"vitest","build":"tsup","clean":"git clean -xdf .turbo node_modules dist .cache","format":"prettier --check . --ignore-path ../../.gitignore","typecheck":"tsc --noEmit"},"_npmUser":{"name":"bluecadetreleases","email":"releases@bluecadet.com"},"repository":{"url":"git+https://github.com/bluecadet/orbit.git","type":"git"},"_npmVersion":"10.9.2","description":"A11y Plugin for Embla Carousel","directories":{},"sideEffects":false,"_nodeVersion":"23.11.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.2","eslint":"^9.19.0","vitest":"^3.0.9","prettier":"^3.4.2","happy-dom":"^17.4.4","typescript":"^5.7.3","@repo/eslint":"*","@repo/prettier":"*","@repo/typescript":"*"},"peerDependencies":{"embla-carousel":"^8.5.2"},"_npmOperationalInternal":{"tmp":"tmp/embla-carousel-a11y_0.1.1_1744913511765_0.26015154935368234","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@bluecadet/embla-carousel-a11y","version":"0.1.2","description":"A11y Plugin for Embla Carousel","sideEffects":false,"license":"MIT","type":"module","exports":{"./package.json":"./package.json",".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"build":"tsup","dev":"tsup --watch","clean":"git clean -xdf .turbo node_modules dist .cache","format":"prettier --check . --ignore-path .gitignore","format:fix":"prettier --check . --write --ignore-path .gitignore","lint":"eslint","lint:fix":"eslint --fix","typecheck":"tsc --noEmit","test":"vitest","changeset":"changeset"},"devDependencies":{"@changesets/cli":"^2.29.2","@eslint/compat":"^1.2.8","@eslint/js":"^9.24.0","@ianvs/prettier-plugin-sort-imports":"^4.4.1","eslint":"^9.24.0","globals":"^16.0.0","happy-dom":"^17.4.4","prettier":"^3.5.3","tsup":"^8.0.2","typescript":"^5.8.3","typescript-eslint":"^8.30.1","vitest":"^3.0.9"},"peerDependencies":{"embla-carousel":"^8.5.2"},"repository":{"type":"git","url":"git+https://github.com/bluecadet/embla-carousel-a11y.git"},"maintainers":[{"name":"baerkins","email":"shaun.baer@gmail.com"},{"name":"peteinge","email":"pete.inge@gmail.com"},{"name":"benjaminbojko","email":"b@bbojko.de"},{"name":"claytercek","email":"clay@tercek.me"},{"name":"bluecadetreleases","email":"releases@bluecadet.com"}],"author":{"name":"Bluecadet","url":"https://bluecadet.com"},"bugs":{"url":"https://github.com/bluecadet/embla-carousel-a11y/issues"},"homepage":"https://github.com/bluecadet/embla-carousel-a11y#readme","keywords":["accessibility","a11y","react","js","ts","javascript","typescript","carousel","slider","drag","aria"],"_id":"@bluecadet/embla-carousel-a11y@0.1.2","gitHead":"f3e0b6512692c88772dfe11e36327cf2eb6e9a92","_nodeVersion":"23.11.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-0szt3WLs3UqngJq9prWuLyDzW5Lcu4MQ0Hnuat8bDegZnevx5yBEFEJZcH4Z/Eg1h5QTO39xuSeDcq80UD8IPA==","shasum":"4f7b3bcbea013456f99793b58cdbfe3211845ebf","tarball":"https://registry.npmjs.org/@bluecadet/embla-carousel-a11y/-/embla-carousel-a11y-0.1.2.tgz","fileCount":7,"unpackedSize":27591,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDx+w/UByOybXYDlO1nTh9YGC5X9c2nKE/WyuG7+WYCtwIhAPAc4Ux+Vp+B8AqwvDQZzC0b4/f9zumj9I73zO/syZGR"}]},"_npmUser":{"name":"bluecadetreleases","email":"releases@bluecadet.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/embla-carousel-a11y_0.1.2_1744923575708_0.6347356598992135"},"_hasShrinkwrap":false}},"time":{"created":"2025-04-01T20:45:36.825Z","modified":"2025-04-17T20:59:36.129Z","0.1.0":"2025-04-01T20:45:37.125Z","0.1.1":"2025-04-17T18:11:51.957Z","0.1.2":"2025-04-17T20:59:35.880Z"},"bugs":{"url":"https://github.com/bluecadet/embla-carousel-a11y/issues"},"author":{"name":"Bluecadet","url":"https://bluecadet.com"},"license":"MIT","homepage":"https://github.com/bluecadet/embla-carousel-a11y#readme","keywords":["accessibility","a11y","react","js","ts","javascript","typescript","carousel","slider","drag","aria"],"repository":{"type":"git","url":"git+https://github.com/bluecadet/embla-carousel-a11y.git"},"description":"A11y Plugin for Embla Carousel","maintainers":[{"name":"baerkins","email":"shaun.baer@gmail.com"},{"name":"peteinge","email":"pete.inge@gmail.com"},{"name":"benjaminbojko","email":"b@bbojko.de"},{"name":"claytercek","email":"clay@tercek.me"},{"name":"bluecadetreleases","email":"releases@bluecadet.com"}],"readme":"# Embla Carousel A11y Plugin\n\nAn accessibility plugin for [Embla Carousel](https://www.embla-carousel.com/) that follows WAI-ARIA Authoring Practices for carousels.\n\n## Features\n\n- Adds proper ARIA roles and attributes to carousel elements\n- Creates an accessible live region to announce slide changes\n- Respects user-provided ARIA attributes\n- Shows helpful development warnings for accessibility improvements\n\n## Installation\n\n```bash\n# npm\nnpm install embla-carousel @bluecadet/embla-carousel-a11y\n\n# yarn\nyarn add embla-carousel @bluecadet/embla-carousel-a11y\n\n# pnpm\npnpm add embla-carousel @bluecadet/embla-carousel-a11y\n```\n\n## Basic Usage\n\n```typescript\nimport A11y from \"@bluecadet/embla-carousel-a11y\";\nimport EmblaCarousel from \"embla-carousel\";\n\n// Initialize Embla with the A11y plugin\nconst emblaNode = document.querySelector(\".embla\");\nconst embla = EmblaCarousel(emblaNode, { loop: true }, [A11y()]);\n\n// The plugin is accessible through embla.plugins().a11y\nconst a11yPlugin = embla.plugins().a11y;\n```\n\n## API Reference\n\n### Options\n\nThe A11y plugin accepts the following options:\n\n| Option                      | Type                  | Default                                       | Description                                                                                         |\n| --------------------------- | --------------------- | --------------------------------------------- | --------------------------------------------------------------------------------------------------- |\n| `carouselLabel`             | `string \\| undefined` | `undefined`                                   | A custom label for the carousel. If not provided, uses an existing `aria-label` or sets a default.  |\n| `slideSelector`             | `string \\| undefined` | `undefined`                                   | Custom selector for slide elements. If not provided, uses Embla's default slide nodes.              |\n| `announceSlideChanges`      | `boolean`             | `true`                                        | Whether to announce slide changes to screen readers.                                                |\n| `slideAnnouncementTemplate` | `string`              | `\"Slide {{currentSlide}} of {{totalSlides}}\"` | Template for slide change announcements. Use `{{currentSlide}}` and `{{totalSlides}}` as variables. |\n| `showDeveloperWarnings`     | `boolean`             | `true`                                        | Whether to show developer console warnings in non-production environments.                          |\n\n### Plugin Methods\n\nThe A11y plugin exposes the following methods:\n\n| Method     | Description                                                                                                        |\n| ---------- | ------------------------------------------------------------------------------------------------------------------ |\n| `update()` | Updates ARIA attributes based on the current carousel state. Called automatically when the selected slide changes. |\n\n## Accessibility Features\n\nThis plugin implements the following accessibility features:\n\n### Proper ARIA Roles and Attributes\n\n- Adds `role=\"region\"` to the carousel container\n- Adds `aria-roledescription=\"carousel\"` to identify it as a carousel\n- Adds proper `aria-label` (or respects existing labels)\n- Adds `role=\"group\"` and `aria-roledescription=\"slide\"` to slides\n- Applies `aria-hidden=\"true\"` to non-visible slides\n- Sets `aria-setsize` and `aria-posinset` for proper slide position information\n\n### Live Region for Announcements\n\n- Creates a visually hidden live region for screen reader announcements\n- Announces the current slide position when navigation occurs\n- Uses customizable announcement templates\n\n### Respecting User Attributes\n\n- Detects existing ARIA attributes provided by the user before initialization\n- Preserves these attributes instead of overriding them\n- Only updates dynamic attributes like `aria-hidden` as needed\n\n### Development Warnings\n\nIn development mode, the plugin provides helpful console warnings for accessibility improvements:\n\n- Warns when no accessible name (label) is provided for the carousel\n- Suggests adding descriptive labels to slides\n- Can be disabled in production or via options\n\n## Best Practices for Accessible Carousels\n\nFor maximum accessibility, we recommend:\n\n1. **Provide meaningful labels**: Use the `carouselLabel` option or add `aria-label` attributes to your carousel and slides with descriptive content.\n\n```html\n<div class=\"embla\" aria-label=\"Featured products\">\n  <div class=\"embla__container\">\n    <div class=\"embla__slide\" aria-label=\"Red summer dress, $49.99\">...</div>\n    <div class=\"embla__slide\" aria-label=\"Blue winter coat, $89.99\">...</div>\n  </div>\n</div>\n```\n\n2. **Add accessible navigation controls**: Include Previous/Next buttons with proper labels.\n\n```html\n<button class=\"embla__prev\" aria-label=\"Previous slide\">Prev</button>\n<div class=\"embla\">...</div>\n<button class=\"embla__next\" aria-label=\"Next slide\">Next</button>\n```\n\n3. **Pause autoplay on interaction**: If using autoplay, pause it when users interact with the carousel.\n\n```js\nconst options = {\n  loop: true,\n  autoplay: true,\n};\n\nconst embla = EmblaCarousel(emblaNode, options, [A11y()]);\n\n// Pause autoplay on focus within the carousel\nemblaNode.addEventListener(\"focusin\", () => {\n  embla.plugins().autoplay.stop();\n});\n\n// Resume when focus leaves\nemblaNode.addEventListener(\"focusout\", (event) => {\n  if (!emblaNode.contains(event.relatedTarget)) {\n    embla.plugins().autoplay.play();\n  }\n});\n```\n\n## Why Accessibility Matters\n\nMaking your carousel accessible ensures that:\n\n- Users with screen readers can understand and navigate your content\n- Keyboard-only users can access all carousel features\n- Your site complies with accessibility standards like WCAG\n- You reach a wider audience, including people with disabilities\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n","readmeFilename":"README.md"}