@zag-js/live-region 0.9.1 → 0.10.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 (2) hide show
  1. package/package.json +4 -3
  2. package/src/index.ts +64 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zag-js/live-region",
3
- "version": "0.9.1",
3
+ "version": "0.10.0",
4
4
  "description": "Implementing live region for screen readers",
5
5
  "keywords": [
6
6
  "js",
@@ -13,10 +13,11 @@
13
13
  "repository": "https://github.com/chakra-ui/zag/tree/main/packages/utilities/live-region",
14
14
  "sideEffects": false,
15
15
  "files": [
16
- "dist/**/*"
16
+ "dist",
17
+ "src"
17
18
  ],
18
19
  "dependencies": {
19
- "@zag-js/visually-hidden": "0.9.1"
20
+ "@zag-js/visually-hidden": "0.10.0"
20
21
  },
21
22
  "devDependencies": {
22
23
  "clean-package": "2.2.0"
package/src/index.ts ADDED
@@ -0,0 +1,64 @@
1
+ import { setVisuallyHidden } from "@zag-js/visually-hidden"
2
+
3
+ export type LiveRegionOptions = {
4
+ level: "polite" | "assertive"
5
+ document?: Document
6
+ root?: HTMLElement | null
7
+ delay?: number
8
+ }
9
+
10
+ export type LiveRegion = ReturnType<typeof createLiveRegion>
11
+
12
+ const ID = "__live-region__"
13
+
14
+ export function createLiveRegion(opts: Partial<LiveRegionOptions> = {}) {
15
+ const { level = "polite", document: doc = document, root, delay: _delay = 0 } = opts
16
+
17
+ const win = doc.defaultView ?? window
18
+ const parent = root ?? doc.body
19
+
20
+ function announce(message: string, delay?: number) {
21
+ const oldRegion = doc.getElementById(ID)
22
+
23
+ // remove old region
24
+ oldRegion?.remove()
25
+
26
+ // Did an override level get set?
27
+ delay = delay ?? _delay
28
+
29
+ // create fresh region
30
+ const region = doc.createElement("span")
31
+ region.id = ID
32
+ region.dataset.liveAnnouncer = "true"
33
+
34
+ // Determine redundant role
35
+ const role = level !== "assertive" ? "status" : "alert"
36
+
37
+ // add role and attributes
38
+ region.setAttribute("aria-live", level)
39
+ region.setAttribute("role", role)
40
+
41
+ // hide live region
42
+ setVisuallyHidden(region)
43
+
44
+ parent.appendChild(region)
45
+
46
+ // populate region to trigger it
47
+ win.setTimeout(() => {
48
+ region.textContent = message
49
+ }, delay)
50
+ }
51
+
52
+ function destroy() {
53
+ const oldRegion = doc.getElementById(ID)
54
+ oldRegion?.remove()
55
+ }
56
+
57
+ return {
58
+ announce,
59
+ destroy,
60
+ toJSON() {
61
+ return ID
62
+ },
63
+ }
64
+ }