annotate design_system/src/components/overlays.js @ 266:efaf4c63cc94

fix clean production bundle staging Recreate deployment staging before copying the Bazel bundle and verify required inference runtime paths before promoting it. Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Fri, 07 Aug 2026 12:52:30 -0700
parents 2b6e732087ff
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
254
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1 let nextOverlayId = 1;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
3 function uniqueId(prefix) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
4 let id;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
5 do id = `${prefix}-${nextOverlayId++}`;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
6 while (document.getElementById(id));
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
7 return id;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
8 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
9
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
10 function rememberAttribute(state, element, name) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
11 let attributes = state.get(element);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
12 if (!attributes) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
13 attributes = new Map();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
14 state.set(element, attributes);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
15 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
16 if (!attributes.has(name)) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
17 attributes.set(name, element.getAttribute(name));
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
18 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
19 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
20
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
21 function setManagedAttribute(state, element, name, value) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
22 rememberAttribute(state, element, name);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
23 if (value === null) element.removeAttribute(name);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
24 else element.setAttribute(name, value);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
25 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
26
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
27 function restoreAttributes(state) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
28 for (const [element, attributes] of state) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
29 for (const [name, value] of attributes) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
30 if (value === null) element.removeAttribute(name);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
31 else element.setAttribute(name, value);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
32 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
33 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
34 state.clear();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
35 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
36
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
37 function resetManagedAttribute(state, element, name) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
38 const attributes = state.get(element);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
39 if (!attributes?.has(name)) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
40 const value = attributes.get(name);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
41 if (value === null) element.removeAttribute(name);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
42 else element.setAttribute(name, value);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
43 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
44
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
45 function ensureId(state, element, prefix) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
46 const existing = element.id && document.getElementById(element.id);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
47 if (!element.id || (existing && existing !== element)) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
48 setManagedAttribute(state, element, "id", uniqueId(prefix));
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
49 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
50 return element.id;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
51 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
52
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
53 function eventElement(event) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
54 return event.target instanceof Element ? event.target : null;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
55 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
56
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
57 const OVERLAY_COMPONENTS = [
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
58 "zen-dialog",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
59 "zen-alert-dialog",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
60 "zen-sheet",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
61 "zen-drawer",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
62 "zen-popover",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
63 "zen-hover-card",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
64 "zen-tooltip",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
65 ].join(",");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
66
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
67 function ownedElement(host, selector) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
68 return [...host.querySelectorAll(selector)].find(
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
69 element => element.closest(OVERLAY_COMPONENTS) === host,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
70 ) || null;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
71 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
72
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
73 /**
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
74 * Wires a native modal dialog to explicit trigger and close controls.
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
75 *
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
76 * @extends {HTMLElement}
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
77 */
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
78 export class ZenDialog extends HTMLElement {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
79 static dialogRole = null;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
80
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
81 constructor() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
82 super();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
83 this._managed = new Map();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
84 this._open = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
85 this._openedByComponent = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
86 this._onTriggerClick = event => {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
87 event.preventDefault();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
88 this.open();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
89 };
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
90 this._onDialogClick = event => {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
91 const control = eventElement(event)?.closest("[data-zen-close]");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
92 if (!control || !this._dialog?.contains(control)) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
93 const value = control.hasAttribute("value")
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
94 ? control.getAttribute("value")
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
95 : undefined;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
96 this.close(value);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
97 };
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
98 this._onNativeClose = () => this.syncOpen(false);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
99 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
100
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
101 connectedCallback() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
102 this._observer ||= new MutationObserver(() => this.sync());
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
103 this._observer.observe(this, { childList: true, subtree: true });
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
104 this.sync();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
105 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
106
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
107 sync() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
108 const trigger = ownedElement(this, "button[data-zen-trigger]");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
109 const dialog = ownedElement(this, "dialog");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
110 if (trigger === this._trigger && dialog === this._dialog) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
111 if (this._openedByComponent) this.close();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
112 this.unbind();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
113 this._trigger = trigger;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
114 this._dialog = dialog;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
115 if (!this._trigger || !this._dialog) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
116
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
117 const id = ensureId(this._managed, this._dialog, this.localName);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
118 setManagedAttribute(
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
119 this._managed,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
120 this._trigger,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
121 "aria-haspopup",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
122 "dialog",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
123 );
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
124 setManagedAttribute(this._managed, this._trigger, "aria-controls", id);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
125 if (this.constructor.dialogRole) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
126 setManagedAttribute(
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
127 this._managed,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
128 this._dialog,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
129 "role",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
130 this.constructor.dialogRole,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
131 );
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
132 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
133 this._trigger.addEventListener("click", this._onTriggerClick);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
134 this._dialog.addEventListener("click", this._onDialogClick);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
135 this._dialog.addEventListener("close", this._onNativeClose);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
136 this.syncOpen(this._dialog.open);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
137 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
138
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
139 unbind() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
140 this._trigger?.removeEventListener("click", this._onTriggerClick);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
141 this._dialog?.removeEventListener("click", this._onDialogClick);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
142 this._dialog?.removeEventListener("close", this._onNativeClose);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
143 restoreAttributes(this._managed);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
144 this._trigger = null;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
145 this._dialog = null;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
146 this._open = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
147 this._openedByComponent = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
148 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
149
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
150 disconnectedCallback() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
151 this._observer?.disconnect();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
152 if (this._openedByComponent) this.close();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
153 this.unbind();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
154 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
155
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
156 open() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
157 if (!this._dialog || this._dialog.open || this._open) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
158 try {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
159 if (typeof this._dialog.showModal === "function") {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
160 this._dialog.showModal();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
161 } else {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
162 setManagedAttribute(this._managed, this._dialog, "open", "");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
163 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
164 this._openedByComponent = true;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
165 this.syncOpen(true);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
166 } catch {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
167 this.syncOpen(Boolean(this._dialog.open));
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
168 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
169 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
170
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
171 close(returnValue) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
172 if (!this._dialog || (!this._dialog.open && !this._open)) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
173 if (typeof this._dialog.close === "function") {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
174 if (returnValue === undefined) this._dialog.close();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
175 else this._dialog.close(returnValue);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
176 } else {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
177 setManagedAttribute(this._managed, this._dialog, "open", null);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
178 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
179 this.syncOpen(false);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
180 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
181
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
182 syncOpen(open) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
183 this._open = open;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
184 if (!open) this._openedByComponent = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
185 if (this._trigger) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
186 setManagedAttribute(
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
187 this._managed,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
188 this._trigger,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
189 "aria-expanded",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
190 String(open),
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
191 );
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
192 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
193 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
194 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
195
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
196 /**
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
197 * Presents a native modal with alert-dialog semantics.
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
198 *
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
199 * @extends {ZenDialog}
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
200 */
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
201 export class ZenAlertDialog extends ZenDialog {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
202 static dialogRole = "alertdialog";
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
203 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
204
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
205 /**
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
206 * Presents a native dialog as an edge-aligned sheet.
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
207 *
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
208 * @extends {ZenDialog}
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
209 */
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
210 export class ZenSheet extends ZenDialog {}
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
211
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
212 /**
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
213 * Presents a native dialog as a drawer.
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
214 *
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
215 * @extends {ZenDialog}
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
216 */
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
217 export class ZenDrawer extends ZenDialog {}
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
218
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
219 function isPopoverOpen(element) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
220 try {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
221 return element.matches(":popover-open");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
222 } catch {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
223 return false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
224 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
225 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
226
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
227 /**
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
228 * Connects a trigger to a native popover with an accessible fallback.
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
229 *
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
230 * @extends {HTMLElement}
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
231 */
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
232 export class ZenPopover extends HTMLElement {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
233 constructor() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
234 super();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
235 this._managed = new Map();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
236 this._open = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
237 this._onClick = event => {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
238 const target = eventElement(event);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
239 if (!target) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
240 if (this._trigger?.contains(target)) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
241 event.preventDefault();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
242 this.toggle();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
243 } else if (this._content?.contains(target) &&
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
244 target.closest("[data-zen-close]")) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
245 this.hide();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
246 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
247 };
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
248 this._onToggle = event => {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
249 this.syncOpen(event.newState
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
250 ? event.newState === "open"
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
251 : isPopoverOpen(this._content));
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
252 };
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
253 this._onDocumentPointerDown = event => {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
254 if (!this._native && this._open && !this.contains(event.target)) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
255 this.hide();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
256 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
257 };
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
258 this._onDocumentKeyDown = event => {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
259 if (!this._native && this._open && event.key === "Escape") {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
260 this.hide();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
261 this._trigger?.focus();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
262 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
263 };
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
264 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
265
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
266 connectedCallback() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
267 this.addEventListener("click", this._onClick);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
268 document.addEventListener("pointerdown", this._onDocumentPointerDown);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
269 document.addEventListener("keydown", this._onDocumentKeyDown);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
270 this._observer ||= new MutationObserver(() => this.sync());
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
271 this._observer.observe(this, { childList: true, subtree: true });
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
272 this.sync();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
273 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
274
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
275 sync() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
276 const trigger = ownedElement(this, "[data-zen-trigger]");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
277 const content = ownedElement(
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
278 this,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
279 "[data-zen-content], [popover]",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
280 );
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
281 if (trigger === this._trigger && content === this._content) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
282 if (this._open) this.hide();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
283 this.unbindElements();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
284 this._trigger = trigger;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
285 this._content = content;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
286 if (!this._trigger || !this._content) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
287
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
288 const id = ensureId(this._managed, this._content, "zen-popover");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
289 setManagedAttribute(this._managed, this._trigger, "aria-controls", id);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
290 this._native = typeof this._content.showPopover === "function" &&
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
291 typeof this._content.hidePopover === "function";
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
292 if (this._native && !this._content.hasAttribute("popover")) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
293 setManagedAttribute(this._managed, this._content, "popover", "auto");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
294 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
295 if (this._native && "popoverTargetElement" in this._trigger) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
296 this._originalPopoverTarget = this._trigger.popoverTargetElement;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
297 this._trigger.popoverTargetElement = this._content;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
298 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
299 if (this._native) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
300 setManagedAttribute(this._managed, this._content, "hidden", null);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
301 } else {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
302 setManagedAttribute(this._managed, this._content, "hidden", "");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
303 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
304
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
305 this._content.addEventListener("toggle", this._onToggle);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
306 this.syncOpen(this._native && isPopoverOpen(this._content));
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
307 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
308
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
309 unbindElements() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
310 this._content?.removeEventListener("toggle", this._onToggle);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
311 if (this._trigger && "popoverTargetElement" in this._trigger) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
312 this._trigger.popoverTargetElement = this._originalPopoverTarget || null;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
313 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
314 restoreAttributes(this._managed);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
315 this._trigger = null;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
316 this._content = null;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
317 this._native = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
318 this._open = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
319 this._originalPopoverTarget = null;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
320 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
321
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
322 disconnectedCallback() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
323 this._observer?.disconnect();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
324 this.removeEventListener("click", this._onClick);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
325 document.removeEventListener("pointerdown", this._onDocumentPointerDown);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
326 document.removeEventListener("keydown", this._onDocumentKeyDown);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
327 if (this._open) this.hide();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
328 this.unbindElements();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
329 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
330
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
331 toggle() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
332 if (this._open || isPopoverOpen(this._content)) this.hide();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
333 else this.show();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
334 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
335
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
336 show() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
337 if (!this._content || this._open) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
338 if (this._native) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
339 try {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
340 this._content.showPopover();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
341 } catch {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
342 this._native = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
343 setManagedAttribute(this._managed, this._content, "hidden", null);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
344 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
345 } else {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
346 setManagedAttribute(this._managed, this._content, "hidden", null);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
347 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
348 this.syncOpen(true);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
349 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
350
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
351 hide() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
352 if (!this._content || !this._open) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
353 if (this._native) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
354 try {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
355 this._content.hidePopover();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
356 } catch {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
357 this._native = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
358 setManagedAttribute(this._managed, this._content, "hidden", "");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
359 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
360 } else {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
361 setManagedAttribute(this._managed, this._content, "hidden", "");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
362 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
363 this.syncOpen(false);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
364 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
365
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
366 syncOpen(open) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
367 this._open = open;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
368 if (this._trigger) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
369 setManagedAttribute(
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
370 this._managed,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
371 this._trigger,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
372 "aria-expanded",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
373 String(open),
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
374 );
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
375 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
376 if (!this._native && this._content) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
377 setManagedAttribute(
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
378 this._managed,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
379 this._content,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
380 "hidden",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
381 open ? null : "",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
382 );
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
383 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
384 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
385 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
386
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
387 class ZenTimedOverlay extends HTMLElement {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
388 static delay = 150;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
389 static tooltip = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
390
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
391 constructor() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
392 super();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
393 this._managed = new Map();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
394 this._timer = null;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
395 this._open = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
396 this._pointerWithin = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
397 this._focusWithin = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
398 this._onPointerEnter = () => {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
399 this._pointerWithin = true;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
400 this.schedule(true);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
401 };
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
402 this._onPointerLeave = event => {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
403 if (event.relatedTarget instanceof Node &&
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
404 this.contains(event.relatedTarget)) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
405 this._pointerWithin = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
406 this.schedule(this._focusWithin);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
407 };
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
408 this._onFocusIn = () => {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
409 this._focusWithin = true;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
410 this.schedule(true);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
411 };
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
412 this._onFocusOut = event => {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
413 if (event.relatedTarget instanceof Node &&
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
414 this.contains(event.relatedTarget)) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
415 this._focusWithin = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
416 this.schedule(this._pointerWithin);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
417 };
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
418 this._onKeyDown = event => {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
419 if (event.key !== "Escape" || !this._open) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
420 clearTimeout(this._timer);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
421 this._timer = null;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
422 this.setOpen(false);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
423 };
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
424 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
425
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
426 connectedCallback() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
427 this.addEventListener("keydown", this._onKeyDown);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
428 this._observer ||= new MutationObserver(() => this.sync());
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
429 this._observer.observe(this, { childList: true, subtree: true });
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
430 this.sync();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
431 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
432
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
433 sync() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
434 const trigger = ownedElement(this, "[data-zen-trigger]");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
435 const content = ownedElement(this, "[data-zen-content]");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
436 if (trigger === this._trigger && content === this._content) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
437 this.unbindElements();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
438 this._trigger = trigger;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
439 this._content = content;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
440 if (!this._trigger || !this._content) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
441
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
442 const id = ensureId(this._managed, this._content, this.localName);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
443 setManagedAttribute(this._managed, this._content, "hidden", "");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
444 if (this.constructor.tooltip) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
445 setManagedAttribute(this._managed, this._content, "role", "tooltip");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
446 const ids = new Set(
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
447 (this._trigger.getAttribute("aria-describedby") || "")
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
448 .split(/\s+/)
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
449 .filter(Boolean),
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
450 );
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
451 ids.add(id);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
452 setManagedAttribute(
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
453 this._managed,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
454 this._trigger,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
455 "aria-describedby",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
456 [...ids].join(" "),
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
457 );
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
458 } else {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
459 setManagedAttribute(this._managed, this._trigger, "aria-controls", id);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
460 setManagedAttribute(
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
461 this._managed,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
462 this._trigger,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
463 "aria-expanded",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
464 "false",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
465 );
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
466 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
467
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
468 for (const element of [this._trigger, this._content]) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
469 element.addEventListener("pointerenter", this._onPointerEnter);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
470 element.addEventListener("pointerleave", this._onPointerLeave);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
471 element.addEventListener("focusin", this._onFocusIn);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
472 element.addEventListener("focusout", this._onFocusOut);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
473 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
474 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
475
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
476 unbindElements() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
477 clearTimeout(this._timer);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
478 this._timer = null;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
479 for (const element of [this._trigger, this._content]) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
480 element?.removeEventListener("pointerenter", this._onPointerEnter);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
481 element?.removeEventListener("pointerleave", this._onPointerLeave);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
482 element?.removeEventListener("focusin", this._onFocusIn);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
483 element?.removeEventListener("focusout", this._onFocusOut);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
484 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
485 restoreAttributes(this._managed);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
486 this._trigger = null;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
487 this._content = null;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
488 this._open = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
489 this._pointerWithin = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
490 this._focusWithin = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
491 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
492
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
493 disconnectedCallback() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
494 this._observer?.disconnect();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
495 this.removeEventListener("keydown", this._onKeyDown);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
496 this.unbindElements();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
497 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
498
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
499 schedule(open) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
500 clearTimeout(this._timer);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
501 this._timer = setTimeout(
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
502 () => this.setOpen(open),
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
503 this.constructor.delay,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
504 );
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
505 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
506
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
507 setOpen(open) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
508 if (!this._content || open === this._open) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
509 this._open = open;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
510 setManagedAttribute(
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
511 this._managed,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
512 this._content,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
513 "hidden",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
514 open ? null : "",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
515 );
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
516 if (!this.constructor.tooltip) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
517 setManagedAttribute(
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
518 this._managed,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
519 this._trigger,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
520 "aria-expanded",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
521 String(open),
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
522 );
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
523 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
524 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
525 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
526
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
527 /**
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
528 * Shows supplemental interactive content on hover or focus.
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
529 *
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
530 * @extends {ZenTimedOverlay}
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
531 */
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
532 export class ZenHoverCard extends ZenTimedOverlay {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
533 static delay = 150;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
534 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
535
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
536 /**
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
537 * Shows a delayed non-interactive description on hover or focus.
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
538 *
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
539 * @extends {ZenTimedOverlay}
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
540 */
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
541 export class ZenTooltip extends ZenTimedOverlay {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
542 static delay = 350;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
543 static tooltip = true;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
544 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
545
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
546 const MENU_COMPONENTS = [
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
547 "zen-dropdown-menu",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
548 "zen-context-menu",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
549 "zen-menubar",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
550 "zen-navigation-menu",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
551 ].join(",");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
552 const MENU_SELECTOR = "[data-zen-menu], [role='menu'], [data-zen-content]";
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
553 const ITEM_SELECTOR = [
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
554 "[role='menuitem']",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
555 "[role='menuitemcheckbox']",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
556 "[role='menuitemradio']",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
557 "[data-zen-menu-item]",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
558 "a[href]",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
559 "button",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
560 "input[type='button']",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
561 "input[type='submit']",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
562 ].join(",");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
563
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
564 class ZenMenu extends HTMLElement {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
565 static contextMenu = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
566 static menubar = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
567 static multiple = false;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
568
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
569 constructor() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
570 super();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
571 this._managed = new Map();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
572 this._pairs = [];
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
573 this._openPair = null;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
574 this._onClick = event => {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
575 const target = eventElement(event);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
576 if (!target) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
577 const pair = this._pairs.find(({ trigger }) =>
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
578 trigger.contains(target));
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
579 if (pair) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
580 event.preventDefault();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
581 if (this._openPair === pair) this.close(false);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
582 else this.open(pair, 0, this.constructor.contextMenu ? event : null);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
583 return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
584 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
585 const item = target.closest(ITEM_SELECTOR);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
586 if (this._openPair?.menu.contains(target) &&
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
587 item &&
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
588 !item.hasAttribute("disabled") &&
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
589 item.getAttribute("aria-disabled") !== "true") {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
590 this.close(true);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
591 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
592 };
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
593 this._onContextMenu = event => {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
594 if (!this.constructor.contextMenu ||
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
595 this._pairs.some(({ menu }) => menu.contains(event.target))) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
596 event.preventDefault();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
597 this.open(this._pairs[0], 0, event);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
598 };
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
599 this._onKeyDown = event => this.handleKeyDown(event);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
600 this._onDocumentPointerDown = event => {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
601 if (!this._openPair) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
602 const { trigger, menu } = this._openPair;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
603 if (!trigger.contains(event.target) && !menu.contains(event.target)) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
604 this.close(false);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
605 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
606 };
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
607 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
608
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
609 connectedCallback() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
610 this.setupPairs();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
611 this.addEventListener("click", this._onClick);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
612 this.addEventListener("contextmenu", this._onContextMenu);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
613 this.addEventListener("keydown", this._onKeyDown);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
614 document.addEventListener("pointerdown", this._onDocumentPointerDown);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
615 this._observer ||= new MutationObserver(() => this.refreshPairs());
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
616 this._observer.observe(this, { childList: true, subtree: true });
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
617 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
618
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
619 disconnectedCallback() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
620 this._observer?.disconnect();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
621 this.removeEventListener("click", this._onClick);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
622 this.removeEventListener("contextmenu", this._onContextMenu);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
623 this.removeEventListener("keydown", this._onKeyDown);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
624 document.removeEventListener("pointerdown", this._onDocumentPointerDown);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
625 this._openPair = null;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
626 restoreAttributes(this._managed);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
627 this._pairs = [];
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
628 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
629
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
630 refreshPairs() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
631 if (this._openPair) this.close(false);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
632 restoreAttributes(this._managed);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
633 this._pairs = [];
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
634 this.setupPairs();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
635 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
636
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
637 ownedElements(selector) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
638 return [...this.querySelectorAll(selector)].filter(element =>
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
639 element.closest(MENU_COMPONENTS) === this);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
640 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
641
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
642 setupPairs() {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
643 let triggers = this.ownedElements("[data-zen-trigger]");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
644 const menus = this.ownedElements(MENU_SELECTOR);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
645 triggers = triggers.filter(trigger =>
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
646 !menus.some(menu => menu.contains(trigger)));
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
647 if (!this.constructor.multiple) triggers = triggers.slice(0, 1);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
648
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
649 const unused = new Set(menus);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
650 for (const trigger of triggers) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
651 const controlled = trigger.getAttribute("aria-controls");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
652 let menu = controlled
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
653 ? menus.find(candidate => candidate.id === controlled)
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
654 : null;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
655 if (!menu) menu = [...unused][0];
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
656 if (!menu) continue;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
657 unused.delete(menu);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
658
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
659 const triggerId = ensureId(this._managed, trigger, `${this.localName}-trigger`);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
660 const menuId = ensureId(this._managed, menu, `${this.localName}-menu`);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
661 setManagedAttribute(this._managed, trigger, "aria-haspopup", "menu");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
662 setManagedAttribute(this._managed, trigger, "aria-controls", menuId);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
663 setManagedAttribute(this._managed, trigger, "aria-expanded", "false");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
664 setManagedAttribute(this._managed, menu, "role", "menu");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
665 setManagedAttribute(this._managed, menu, "aria-labelledby", triggerId);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
666 setManagedAttribute(this._managed, menu, "hidden", "");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
667 if (this.constructor.menubar) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
668 setManagedAttribute(this._managed, trigger, "role", "menuitem");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
669 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
670 const pair = { trigger, menu };
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
671 this._pairs.push(pair);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
672 this.prepareItems(pair);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
673 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
674 if (this.constructor.menubar) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
675 setManagedAttribute(this._managed, this, "role", "menubar");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
676 this.setMenubarTabStop(this._pairs[0]);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
677 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
678 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
679
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
680 prepareItems(pair) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
681 const items = [...pair.menu.querySelectorAll(ITEM_SELECTOR)].filter(item =>
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
682 item.closest(MENU_SELECTOR) === pair.menu &&
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
683 !item.hidden &&
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
684 !item.hasAttribute("disabled") &&
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
685 item.getAttribute("aria-disabled") !== "true");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
686 for (const item of items) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
687 if (!item.hasAttribute("role")) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
688 setManagedAttribute(this._managed, item, "role", "menuitem");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
689 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
690 setManagedAttribute(this._managed, item, "tabindex", "-1");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
691 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
692 return items;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
693 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
694
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
695 open(pair, itemIndex = 0, pointerEvent = null) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
696 if (!pair) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
697 if (this._openPair && this._openPair !== pair) this.close(false);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
698 this._openPair = pair;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
699 if (this.constructor.menubar) this.setMenubarTabStop(pair);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
700 if (pointerEvent) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
701 rememberAttribute(this._managed, pair.menu, "style");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
702 pair.menu.style.position = "fixed";
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
703 pair.menu.style.left = `${Number(pointerEvent.clientX) || 0}px`;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
704 pair.menu.style.top = `${Number(pointerEvent.clientY) || 0}px`;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
705 } else {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
706 resetManagedAttribute(this._managed, pair.menu, "style");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
707 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
708 setManagedAttribute(this._managed, pair.menu, "hidden", null);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
709 setManagedAttribute(this._managed, pair.trigger, "aria-expanded", "true");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
710 const items = this.prepareItems(pair);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
711 if (items.length) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
712 const index = itemIndex < 0 ? items.length - 1 : itemIndex;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
713 setManagedAttribute(this._managed, items[index], "tabindex", "0");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
714 items[index].focus();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
715 } else {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
716 setManagedAttribute(this._managed, pair.menu, "tabindex", "-1");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
717 pair.menu.focus();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
718 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
719 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
720
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
721 close(restoreFocus) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
722 if (!this._openPair) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
723 const pair = this._openPair;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
724 this._openPair = null;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
725 setManagedAttribute(this._managed, pair.menu, "hidden", "");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
726 setManagedAttribute(this._managed, pair.trigger, "aria-expanded", "false");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
727 resetManagedAttribute(this._managed, pair.menu, "style");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
728 if (restoreFocus) pair.trigger.focus();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
729 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
730
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
731 moveItem(pair, offset, edge = null) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
732 const active = document.activeElement;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
733 const items = this.prepareItems(pair);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
734 if (!items.length) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
735 let index = items.indexOf(active);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
736 if (edge === "first") index = 0;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
737 else if (edge === "last") index = items.length - 1;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
738 else index = (Math.max(index, 0) + offset + items.length) % items.length;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
739 setManagedAttribute(this._managed, items[index], "tabindex", "0");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
740 items[index].focus();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
741 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
742
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
743 moveMenubarTrigger(pair, offset, openMenu) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
744 const index = this._pairs.indexOf(pair);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
745 const next = this._pairs[
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
746 (index + offset + this._pairs.length) % this._pairs.length
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
747 ];
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
748 this.setMenubarTabStop(next);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
749 if (openMenu) this.open(next);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
750 else next.trigger.focus();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
751 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
752
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
753 setMenubarTabStop(activePair) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
754 for (const pair of this._pairs) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
755 setManagedAttribute(
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
756 this._managed,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
757 pair.trigger,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
758 "tabindex",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
759 pair === activePair ? "0" : "-1",
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
760 );
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
761 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
762 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
763
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
764 handleKeyDown(event) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
765 const target = eventElement(event);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
766 if (!target) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
767 const triggerPair = this._pairs.find(({ trigger }) =>
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
768 trigger.contains(target));
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
769 if (triggerPair) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
770 if (this.constructor.menubar &&
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
771 (event.key === "ArrowRight" || event.key === "ArrowLeft")) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
772 event.preventDefault();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
773 this.moveMenubarTrigger(
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
774 triggerPair,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
775 event.key === "ArrowRight" ? 1 : -1,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
776 false,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
777 );
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
778 } else if (["Enter", " ", "ArrowDown", "ArrowUp"].includes(event.key)) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
779 event.preventDefault();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
780 this.open(triggerPair, event.key === "ArrowUp" ? -1 : 0);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
781 } else if (event.key === "Escape" && this._openPair) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
782 event.preventDefault();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
783 this.close(true);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
784 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
785 return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
786 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
787
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
788 const pair = this._pairs.find(({ menu }) => menu.contains(target));
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
789 if (!pair || this._openPair !== pair) return;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
790 if (event.key === "ArrowDown") {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
791 event.preventDefault();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
792 this.moveItem(pair, 1);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
793 } else if (event.key === "ArrowUp") {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
794 event.preventDefault();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
795 this.moveItem(pair, -1);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
796 } else if (event.key === "Home" || event.key === "End") {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
797 event.preventDefault();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
798 this.moveItem(pair, 0, event.key === "Home" ? "first" : "last");
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
799 } else if (event.key === "Escape") {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
800 event.preventDefault();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
801 this.close(true);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
802 } else if (event.key === "Tab") {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
803 this.close(false);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
804 } else if (this.constructor.menubar &&
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
805 (event.key === "ArrowRight" || event.key === "ArrowLeft")) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
806 event.preventDefault();
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
807 this.moveMenubarTrigger(
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
808 pair,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
809 event.key === "ArrowRight" ? 1 : -1,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
810 true,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
811 );
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
812 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
813 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
814 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
815
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
816 /**
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
817 * Provides an accessible action menu opened from a native trigger.
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
818 *
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
819 * @extends {ZenMenu}
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
820 */
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
821 export class ZenDropdownMenu extends ZenMenu {}
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
822
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
823 /**
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
824 * Opens an accessible action menu at the pointer location.
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
825 *
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
826 * @extends {ZenMenu}
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
827 */
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
828 export class ZenContextMenu extends ZenMenu {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
829 static contextMenu = true;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
830 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
831
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
832 /**
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
833 * Coordinates multiple keyboard-accessible application menus.
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
834 *
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
835 * @extends {ZenMenu}
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
836 */
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
837 export class ZenMenubar extends ZenMenu {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
838 static menubar = true;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
839 static multiple = true;
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
840 }
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
841
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
842 /**
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
843 * Provides keyboard-accessible navigation flyouts.
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
844 *
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
845 * @extends {ZenMenu}
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
846 */
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
847 export class ZenNavigationMenu extends ZenMenu {}
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
848
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
849 const definitions = {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
850 "zen-dialog": ZenDialog,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
851 "zen-alert-dialog": ZenAlertDialog,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
852 "zen-sheet": ZenSheet,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
853 "zen-drawer": ZenDrawer,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
854 "zen-popover": ZenPopover,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
855 "zen-hover-card": ZenHoverCard,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
856 "zen-tooltip": ZenTooltip,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
857 "zen-dropdown-menu": ZenDropdownMenu,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
858 "zen-context-menu": ZenContextMenu,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
859 "zen-menubar": ZenMenubar,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
860 "zen-navigation-menu": ZenNavigationMenu,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
861 };
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
862
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
863 for (const [name, constructor] of Object.entries(definitions)) {
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
864 if (!customElements.get(name)) customElements.define(name, constructor);
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
865 }