{"_id":"@a11y_craft/aria-announce","_rev":"2-17896a806683198ee38dbb9147882cd3","name":"@a11y_craft/aria-announce","dist-tags":{"latest":"1.0.2"},"versions":{"1.0.1":{"name":"@a11y_craft/aria-announce","version":"1.0.1","keywords":["accessibility","a11y","aria","aria-live","screen-reader","wcag","announcer"],"author":{"name":"Nidhi Gajera"},"license":"MIT","_id":"@a11y_craft/aria-announce@1.0.1","maintainers":[{"name":"nidhi.g","email":"nidhigajera2610@gmail.com"}],"homepage":"https://github.com/nidhiG2610/aria-announce#readme","bugs":{"url":"https://github.com/nidhiG2610/aria-announce/issues"},"dist":{"shasum":"37e5cba40d92eacc502769cebdfe1b0857b60102","tarball":"https://registry.npmjs.org/@a11y_craft/aria-announce/-/aria-announce-1.0.1.tgz","fileCount":9,"integrity":"sha512-fEyBO1cxgFhHEA2OiU6gEUUvcuS2l7L61fwy/5rmPmCin5S7sVLsdHef2HpE/fH7mgi0pl/P9GcVUIrRrRv0uw==","signatures":[{"sig":"MEYCIQCIF3Kz4+8v7O5cfg4Ytt0c+ElqpXsa8kxPX5GX1wjCMgIhAPY3Z6dBYwc8AwhgUqczyTMoXyKPpwdg3fHTAHECtOoH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":31809},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"4043aac8e81a9d4fad8c8e537afbbcd891a78960","scripts":{"test":"jest","build":"tsup","test:watch":"jest --watch","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"nidhi.g","email":"nidhigajera2610@gmail.com"},"repository":{"url":"git+https://github.com/nidhiG2610/aria-announce.git","type":"git"},"_npmVersion":"11.3.0","description":"Tiny, zero-dependency aria-live region manager for accessible screen reader announcements","directories":{},"sideEffects":false,"_nodeVersion":"22.13.1","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","tsup":"^8.0.2","ts-jest":"^29.1.4","typescript":"^5.4.5","@types/jest":"^29.5.12","jest-environment-jsdom":"^29.7.0"},"_npmOperationalInternal":{"tmp":"tmp/aria-announce_1.0.1_1775776037860_0.7030639292594032","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@a11y_craft/aria-announce","version":"1.0.2","description":"Tiny, zero-dependency aria-live region manager for screen reader announcements (VoiceOver, NVDA, JAWS) — works with React, Vue, Svelte, and vanilla JS","keywords":["accessibility","a11y","aria","aria-live","screen-reader","wcag","wcag2","wcag22","announcer","announce","live-region","wai-aria","voiceover","nvda","jaws","talkback","narrator","react","react-aria","react-announce","vue","svelte","angular","accessible","status-message","typescript","zero-dependency"],"author":{"name":"Nidhi Gajera"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/nidhiG2610/aria-announce.git"},"main":"./dist/index.js","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"sideEffects":false,"scripts":{"build":"tsup","test":"jest","test:watch":"jest --watch","prepublishOnly":"npm run build && npm test"},"devDependencies":{"@types/jest":"^29.5.12","jest":"^29.7.0","jest-environment-jsdom":"^29.7.0","ts-jest":"^29.1.4","tsup":"^8.0.2","typescript":"^5.4.5"},"_id":"@a11y_craft/aria-announce@1.0.2","gitHead":"f9b8e01ca338baad4c6e48bd893f4ff65b6f8784","bugs":{"url":"https://github.com/nidhiG2610/aria-announce/issues"},"homepage":"https://github.com/nidhiG2610/aria-announce#readme","_nodeVersion":"22.13.1","_npmVersion":"11.3.0","dist":{"integrity":"sha512-hR2Ll2u51CvqIh3Cgmjuw29EgfmFPXaIYggfhBSW3JgVsgQWPDTKXTIawXF+d7HpLIp03jEFl3SE6/PkzHcfOg==","shasum":"e815047f717a6de5f4a6f67f4827e5096592a1c2","tarball":"https://registry.npmjs.org/@a11y_craft/aria-announce/-/aria-announce-1.0.2.tgz","fileCount":9,"unpackedSize":32877,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC23RjW5OA0Akmy2N6K5MhiQaGMSDjPPHnshRSMtBWTgAIhAKXxmUuY5jSaCHa0BxBSnTs2OR3mN83L59bIBQZhSag/"}]},"_npmUser":{"name":"nidhi.g","email":"nidhigajera2610@gmail.com"},"directories":{},"maintainers":[{"name":"nidhi.g","email":"nidhigajera2610@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/aria-announce_1.0.2_1776189908856_0.5503268318192303"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-09T23:07:17.764Z","modified":"2026-04-14T18:05:09.127Z","1.0.1":"2026-04-09T23:07:18.009Z","1.0.2":"2026-04-14T18:05:08.995Z"},"bugs":{"url":"https://github.com/nidhiG2610/aria-announce/issues"},"author":{"name":"Nidhi Gajera"},"license":"MIT","homepage":"https://github.com/nidhiG2610/aria-announce#readme","keywords":["accessibility","a11y","aria","aria-live","screen-reader","wcag","wcag2","wcag22","announcer","announce","live-region","wai-aria","voiceover","nvda","jaws","talkback","narrator","react","react-aria","react-announce","vue","svelte","angular","accessible","status-message","typescript","zero-dependency"],"repository":{"type":"git","url":"git+https://github.com/nidhiG2610/aria-announce.git"},"description":"Tiny, zero-dependency aria-live region manager for screen reader announcements (VoiceOver, NVDA, JAWS) — works with React, Vue, Svelte, and vanilla JS","maintainers":[{"name":"nidhi.g","email":"nidhigajera2610@gmail.com"}],"readme":"# @a11y_craft/aria-announce\n\n> Tiny, zero-dependency `aria-live` announcer for screen readers — works with React, Vue, Svelte, Angular, and vanilla JS.\n\n[![npm version](https://img.shields.io/npm/v/@a11y_craft/aria-announce)](https://www.npmjs.com/package/@a11y_craft/aria-announce)\n[![bundle size](https://img.shields.io/bundlephobia/minzip/@a11y_craft/aria-announce)](https://bundlephobia.com/package/@a11y_craft/aria-announce)\n[![license](https://img.shields.io/npm/l/@a11y_craft/aria-announce)](./LICENSE)\n\n**Screen reader support:** VoiceOver (macOS/iOS) · NVDA · JAWS · TalkBack (Android) · Narrator (Windows)\n\n**Framework support:** React · Vue · Svelte · Angular · vanilla JS · any DOM environment\n\n## Why\n\n`aria-live` regions are the standard way to make dynamic content accessible to screen reader users — but getting them right is tricky:\n\n- Setting text on an existing live region doesn't always re-trigger screen readers\n- Sending messages too fast causes announcements to be dropped\n- Duplicate messages within a short window create noise\n- Most existing packages are framework-specific, heavy, or abandoned\n\n`aria-announce` solves all of this in **~1 KB**, with no dependencies.\n\n## Install\n\n```bash\nnpm install @a11y_craft/aria-announce\n# or\nyarn add @a11y_craft/aria-announce\n# or\npnpm add @a11y_craft/aria-announce\n```\n\n## Quick Start\n\n```ts\nimport { announce } from '@a11y_craft/aria-announce';\n\nannounce('Your file has been saved.');\n```\n\nThat's it. No setup, no providers, no configuration required.\n\n## API\n\n### `announce(message, options?)`\n\nThe main function. Queues a message for announcement.\n\n```ts\nannounce('3 results found');\nannounce('Session expiring in 1 minute', { politeness: 'assertive' });\n```\n\n**Options:**\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `politeness` | `'polite' \\| 'assertive'` | `'polite'` | Politeness level of the announcement |\n| `delay` | `number` (ms) | `100` | Delay before announcing — helps screen readers catch the update |\n| `dedupeMs` | `number` (ms) | `500` | Suppress duplicate messages within this window |\n\n### `announce.polite(message)`\n\nShorthand for polite announcements (non-interrupting).\n\n```ts\nannounce.polite('Form submitted successfully.');\n```\n\n### `announce.assertive(message)`\n\nShorthand for assertive announcements (interrupts the screen reader immediately).\n\n```ts\nannounce.assertive('Error: Please fill in all required fields.');\n```\n\nUse `assertive` sparingly — it interrupts whatever the user is currently hearing.\n\n### `announce.clear()`\n\nClears the queue and empties all live regions.\n\n```ts\nannounce.clear();\n```\n\n### `announce.destroy()`\n\nRemoves the aria-live DOM elements entirely. Useful for cleanup in SPAs or tests.\n\n```ts\nannounce.destroy();\n```\n\n---\n\n## Usage Examples\n\n### Vanilla JS\n\n```js\nimport { announce } from '@a11y_craft/aria-announce';\n\ndocument.querySelector('#save-btn').addEventListener('click', async () => {\n  await saveData();\n  announce('Changes saved successfully.');\n});\n\ndocument.querySelector('#delete-btn').addEventListener('click', () => {\n  announce.assertive('Item deleted.');\n});\n```\n\n### React\n\n```tsx\nimport { announce } from '@a11y_craft/aria-announce';\n\nfunction SaveButton() {\n  const handleSave = async () => {\n    await save();\n    announce('Draft saved.');\n  };\n\n  return <button onClick={handleSave}>Save</button>;\n}\n```\n\nNo provider needed. Works in any component, anywhere in the tree.\n\n```tsx\n// In a toast/notification system\nfunction showToast(message: string, type: 'info' | 'error') {\n  if (type === 'error') {\n    announce.assertive(message);\n  } else {\n    announce.polite(message);\n  }\n}\n```\n\n### Vue\n\n```vue\n<script setup>\nimport { announce } from '@a11y_craft/aria-announce';\n\nasync function handleSubmit() {\n  await submitForm();\n  announce('Form submitted successfully.');\n}\n</script>\n\n<template>\n  <button @click=\"handleSubmit\">Submit</button>\n</template>\n```\n\n### Svelte\n\n```svelte\n<script>\n  import { announce } from '@a11y_craft/aria-announce';\n\n  async function handleUpload() {\n    await upload();\n    announce('File uploaded.');\n  }\n</script>\n\n<button on:click={handleUpload}>Upload</button>\n```\n\n### With a loading state\n\n```ts\nimport { announce } from '@a11y_craft/aria-announce';\n\nasync function fetchResults(query: string) {\n  announce('Loading results...');\n  const results = await search(query);\n  announce(`${results.length} results found for \"${query}\".`);\n}\n```\n\n---\n\n## How It Works\n\nOn the first call, `aria-announce` creates two visually hidden `aria-live` elements in the document body — one `polite`, one `assertive`:\n\n```html\n<div aria-live=\"polite\" aria-atomic=\"true\" style=\"...visually hidden...\"></div>\n<div aria-live=\"assertive\" aria-atomic=\"true\" style=\"...visually hidden...\"></div>\n```\n\nWhen you call `announce()`, it:\n1. Checks for duplicates (suppresses repeated messages within `dedupeMs`)\n2. Queues the message with the chosen politeness level\n3. Clears the region, then sets the new message (forces screen readers to re-announce)\n4. Processes the queue sequentially so rapid calls don't drop announcements\n\n---\n\n## Screen Reader Compatibility\n\n`aria-announce` is tested and works with the major screen readers:\n\n| Screen Reader | Platform | Notes |\n|---------------|----------|-------|\n| VoiceOver | macOS, iOS | Both `polite` and `assertive` |\n| NVDA | Windows | Both `polite` and `assertive` |\n| JAWS | Windows | Both `polite` and `assertive` |\n| TalkBack | Android | `aria-live` supported |\n| Narrator | Windows | Both `polite` and `assertive` |\n\n---\n\n## WCAG Compliance\n\n`aria-announce` is designed to align with [WCAG 2.2 Success Criterion 4.1.3 (Status Messages)](https://www.w3.org/WAI/WCAG22/Understanding/status-messages.html):\n\n- Uses `aria-live` with appropriate politeness levels\n- Sets `aria-atomic=\"true\"` so the full message is read, not just changed text\n- Avoids focus movement for status messages\n\n---\n\n## SSR / Server-Side Rendering\n\n`aria-announce` is a no-op in server environments. All calls are safely ignored when `document` is not available.\n\n---\n\n## TypeScript\n\nFull TypeScript support with exported types:\n\n```ts\nimport { announce } from '@a11y_craft/aria-announce';\nimport type { AnnounceOptions, AnnounceFunction } from 'aria-announce';\n\nconst options: AnnounceOptions = {\n  politeness: 'assertive',\n  delay: 50,\n  dedupeMs: 1000,\n};\n\nannounce('Upload complete.', options);\n```\n\n---\n\n## Browser Support\n\nWorks in all modern browsers. Requires a DOM environment (not SSR).\n\n---\n\n## License\n\nMIT © [Nidhi Gajera](https://github.com/nidhiG2610)\n","readmeFilename":"README.md"}