inclusive-elements 0.5.5 → 0.5.7

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.
@@ -1,13 +1,14 @@
1
- var u = Object.defineProperty;
2
- var p = (o, e, t) => e in o ? u(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
3
- var a = (o, e, t) => (p(o, typeof e != "symbol" ? e + "" : e, t), t);
4
- import { createFocusTrap as f } from "focus-trap";
5
- import { hello as b, goodbye as m } from "hello-goodbye";
6
- const n = class n extends HTMLElement {
1
+ var d = Object.defineProperty;
2
+ var l = (n, s, t) => s in n ? d(n, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[s] = t;
3
+ var o = (n, s, t) => (l(n, typeof s != "symbol" ? s + "" : s, t), t);
4
+ import { createFocusTrap as p } from "focus-trap";
5
+ import { hello as f, goodbye as m } from "hello-goodbye";
6
+ const a = class a extends HTMLElement {
7
7
  constructor() {
8
8
  super();
9
- a(this, "focusTrap");
10
- a(this, "connected", !1);
9
+ o(this, "focusTrap");
10
+ o(this, "focusTrapPaused", !1);
11
+ o(this, "connected", !1);
11
12
  const t = document.createElement("template");
12
13
  t.innerHTML = `
13
14
  <div part="backdrop" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0"></div>
@@ -15,23 +16,34 @@ const n = class n extends HTMLElement {
15
16
  `;
16
17
  const i = this.attachShadow({ mode: "open" });
17
18
  i.appendChild(t.content.cloneNode(!0)), this.backdrop.addEventListener("click", () => {
18
- var s;
19
- this.hasAttribute("static") ? (s = n.attention) == null || s.call(n, i.children[1]) : this.close();
20
- }), this.focusTrap = f(this, {
19
+ var e;
20
+ this.hasAttribute("static") ? (e = a.attention) == null || e.call(a, i.children[1]) : this.close();
21
+ }), this.focusTrap = p(this, {
21
22
  escapeDeactivates: !1,
22
23
  allowOutsideClick: !0,
23
24
  preventScroll: !0,
24
- initialFocus: () => this.querySelector("[autofocus]") || void 0
25
+ // This runs after a delay on every activate and unpause, so the trap
26
+ // may be paused by then. If focus is already inside the modal (e.g.
27
+ // returned there by an overlay that has just closed), leave it.
28
+ initialFocus: () => {
29
+ if (this.focusTrap.paused)
30
+ return !1;
31
+ if (!this.contains(document.activeElement))
32
+ return this.querySelector("[autofocus]") || void 0;
33
+ },
34
+ // Content that is still loading may have nothing tabbable yet. The
35
+ // content element is focusable itself, so trap focus there until it does.
36
+ fallbackFocus: () => this.content ?? this
37
+ }), this.addEventListener("keydown", (e) => {
38
+ e.key === "Escape" && this.open && !this.focusTrapPaused && !this.focusTrap.paused && !e.defaultPrevented && (e.preventDefault(), e.stopPropagation(), this.close());
25
39
  });
26
40
  }
27
41
  static get observedAttributes() {
28
42
  return ["open"];
29
43
  }
30
44
  connectedCallback() {
31
- var t, i, s, c, h, l;
32
- this.connected = !0, (t = this.content) != null && t.hasAttribute("role") || (i = this.content) == null || i.setAttribute("role", "dialog"), (s = this.content) != null && s.hasAttribute("aria-modal") || (c = this.content) == null || c.setAttribute("aria-modal", "true"), (h = this.content) != null && h.hasAttribute("tabindex") || (l = this.content) == null || l.setAttribute("tabindex", "-1"), this.addEventListener("keydown", (r) => {
33
- r.key === "Escape" && this.open && (r.preventDefault(), r.stopPropagation(), this.close());
34
- }), this.open && this.wasOpened();
45
+ var t, i, e, r, c, u;
46
+ this.connected = !0, (t = this.content) != null && t.hasAttribute("role") || (i = this.content) == null || i.setAttribute("role", "dialog"), (e = this.content) != null && e.hasAttribute("aria-modal") || (r = this.content) == null || r.setAttribute("aria-modal", "true"), (c = this.content) != null && c.hasAttribute("tabindex") || (u = this.content) == null || u.setAttribute("tabindex", "-1"), this.open && this.wasOpened();
35
47
  }
36
48
  disconnectedCallback() {
37
49
  this.connected = !1;
@@ -48,18 +60,27 @@ const n = class n extends HTMLElement {
48
60
  const t = new Event("beforeclose", { cancelable: !0 });
49
61
  this.dispatchEvent(t) && (this.open = !1);
50
62
  }
51
- attributeChangedCallback(t, i, s) {
52
- t !== "open" || !this.connected || (s !== null ? this.wasOpened() : this.wasClosed());
63
+ /**
64
+ * Temporarily stop trapping focus and handling Escape, so that another
65
+ * overlay opened from within the modal (e.g. a lightbox mounted in
66
+ * <body>) can manage focus itself.
67
+ */
68
+ pauseFocusTrap() {
69
+ this.focusTrapPaused = !0, this.focusTrap.pause();
70
+ }
71
+ resumeFocusTrap() {
72
+ this.focusTrapPaused = !1, this.focusTrap.unpause();
73
+ }
74
+ attributeChangedCallback(t, i, e) {
75
+ t !== "open" || !this.connected || (e !== null ? this.wasOpened() : this.wasClosed());
53
76
  }
54
77
  async wasOpened() {
55
- document.documentElement.style.overflow = "hidden", this.hidden = !1, b(this), requestAnimationFrame(() => {
56
- var t;
57
- return (t = this.focusTrap) == null ? void 0 : t.activate();
78
+ document.documentElement.style.overflow = "hidden", this.hidden = !1, f(this), requestAnimationFrame(() => {
79
+ this.open && (this.focusTrap.activate(), this.focusTrapPaused ? this.focusTrap.pause() : this.focusTrap.unpause());
58
80
  }), this.dispatchEvent(new Event("open"));
59
81
  }
60
82
  wasClosed() {
61
- var t;
62
- document.documentElement.style.overflow = "", (t = this.focusTrap) == null || t.deactivate(), m(this).then(() => this.hidden = !0), this.dispatchEvent(new Event("close"));
83
+ document.documentElement.style.overflow = "", this.focusTrap.deactivate(), this.focusTrapPaused = !1, m(this).then(() => this.hidden = !0), this.dispatchEvent(new Event("close"));
63
84
  }
64
85
  get backdrop() {
65
86
  var t;
@@ -69,7 +90,7 @@ const n = class n extends HTMLElement {
69
90
  return this.firstElementChild;
70
91
  }
71
92
  };
72
- a(n, "attention", (t) => t.animate(
93
+ o(a, "attention", (t) => t.animate(
73
94
  [
74
95
  { transform: "scale(1)" },
75
96
  { transform: "scale(1.1)" },
@@ -77,7 +98,7 @@ a(n, "attention", (t) => t.animate(
77
98
  ],
78
99
  300
79
100
  ));
80
- let d = n;
101
+ let h = a;
81
102
  export {
82
- d as default
103
+ h as default
83
104
  };
@@ -1,7 +1,8 @@
1
1
  export default class ModalElement extends HTMLElement {
2
2
  static attention: (el: Element) => void;
3
3
  static get observedAttributes(): string[];
4
- private focusTrap?;
4
+ private focusTrap;
5
+ private focusTrapPaused;
5
6
  private connected;
6
7
  constructor();
7
8
  connectedCallback(): void;
@@ -9,6 +10,13 @@ export default class ModalElement extends HTMLElement {
9
10
  get open(): boolean;
10
11
  set open(val: boolean);
11
12
  close(): void;
13
+ /**
14
+ * Temporarily stop trapping focus and handling Escape, so that another
15
+ * overlay opened from within the modal (e.g. a lightbox mounted in
16
+ * <body>) can manage focus itself.
17
+ */
18
+ pauseFocusTrap(): void;
19
+ resumeFocusTrap(): void;
12
20
  attributeChangedCallback(name: string, oldValue: string, newValue: string): void;
13
21
  private wasOpened;
14
22
  private wasClosed;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inclusive-elements",
3
- "version": "0.5.5",
3
+ "version": "0.5.7",
4
4
  "description": "Accessible, lightweight, unstyled implementations of common UI controls.",
5
5
  "module": "dist/inclusive-elements.js",
6
6
  "type": "module",