vrembem 4.0.0-next.26 → 4.0.0-next.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dev/index.js CHANGED
@@ -5,7 +5,126 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
5
5
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
6
6
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
7
7
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
8
- var _handler, _entryPrototype, _focusable, _handleFocusTrap, _handleFocusLock, _handleClick, _handleKeydown, _handleClick2, _handleKeydown2, _handleKeydown3;
8
+ var _handler, _focusable, _handleFocusTrap, _handleFocusLock, _mode, _state, _breakpoint, _handleClick, _handleKeydown, _handleClick2, _handleKeydown2, _eventListeners, _isHovered, _handleKeydown3;
9
+ function toCamel(value) {
10
+ return value.split("-").map((word, index2) => index2 === 0 ? word : word.charAt(0).toUpperCase() + word.slice(1)).join("");
11
+ }
12
+ function toKebab(value) {
13
+ return value.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
14
+ }
15
+ function toMilliseconds(value) {
16
+ if (typeof value === "number") {
17
+ return value;
18
+ }
19
+ const parsed = parseFloat(value);
20
+ if (!Number.isNaN(parsed)) {
21
+ const isMilliseconds = value.includes("ms");
22
+ return parsed * (isMilliseconds ? 1 : 1e3);
23
+ }
24
+ throw new Error(`Could not convert value to milliseconds: ${value}`);
25
+ }
26
+ function getPrefix() {
27
+ return getComputedStyle(document.body).getPropertyValue("--vb-prefix").trim();
28
+ }
29
+ function cssVar(property, options) {
30
+ const settings = {
31
+ fallback: null,
32
+ element: document.body,
33
+ ...options
34
+ };
35
+ if (property.slice(0, 2) !== "--") {
36
+ const prefixValue = getPrefix();
37
+ if (prefixValue) {
38
+ property = `${prefixValue}${property}`;
39
+ }
40
+ property = `--${property}`;
41
+ }
42
+ const cssValue = getComputedStyle(settings.element).getPropertyValue(property).trim();
43
+ if (cssValue) {
44
+ return cssValue;
45
+ } else {
46
+ if (settings.fallback) {
47
+ return settings.fallback;
48
+ } else {
49
+ throw new Error(`CSS variable "${property}" was not found!`);
50
+ }
51
+ }
52
+ }
53
+ function getConfig(el, dataConfig = "config") {
54
+ const string = el.getAttribute(`data-${dataConfig}`) || "";
55
+ const json = string.replace(/'/g, '"');
56
+ return json ? JSON.parse(json) : {};
57
+ }
58
+ function getCustomProps(entry) {
59
+ const styles = getComputedStyle(entry.el);
60
+ const result = {};
61
+ const keys = Object.keys(entry.context.settings);
62
+ for (let i = 0; i < keys.length; i++) {
63
+ const prefix = getPrefix();
64
+ const module = entry.context.module.toLowerCase();
65
+ const key = toKebab(keys[i]);
66
+ const value = styles.getPropertyValue(`--${prefix}${module}-${key}`).trim();
67
+ if (value) {
68
+ result[key] = value;
69
+ }
70
+ }
71
+ return result;
72
+ }
73
+ function getElement(query) {
74
+ if (typeof query === "string") {
75
+ return document.getElementById(query);
76
+ } else if (query instanceof HTMLElement) {
77
+ return query;
78
+ } else {
79
+ return null;
80
+ }
81
+ }
82
+ async function lifecycleHook(name, ...args) {
83
+ if (name in this && typeof this[name] === "function") {
84
+ await this[name](...args);
85
+ }
86
+ }
87
+ function transition(el, init, interim, final, duration = 0) {
88
+ return new Promise((resolve) => {
89
+ el.classList.remove(init);
90
+ el.classList.add(interim);
91
+ setTimeout(() => {
92
+ el.classList.add(final);
93
+ el.classList.remove(interim);
94
+ resolve(el);
95
+ }, toMilliseconds(duration));
96
+ });
97
+ }
98
+ function setOverflowHidden(state, selector) {
99
+ if (selector) {
100
+ const els = document.querySelectorAll(selector);
101
+ els.forEach((el) => {
102
+ if (state) {
103
+ el.style.overflow = "hidden";
104
+ } else {
105
+ el.style.removeProperty("overflow");
106
+ }
107
+ });
108
+ }
109
+ }
110
+ function setInert(state, selector) {
111
+ if (selector) {
112
+ const els = document.querySelectorAll(selector);
113
+ els.forEach((el) => {
114
+ if (state) {
115
+ el.inert = true;
116
+ el.setAttribute("aria-hidden", true);
117
+ } else {
118
+ el.inert = null;
119
+ el.removeAttribute("aria-hidden");
120
+ }
121
+ });
122
+ }
123
+ }
124
+ function setGlobalState(state, selectorInert, selectorOverflow) {
125
+ setInert(!!state, selectorInert);
126
+ setOverflowHidden(!!state, selectorOverflow);
127
+ }
9
128
  class Breakpoint {
10
129
  constructor(value, handler) {
11
130
  __privateAdd(this, _handler);
@@ -44,107 +163,146 @@ class Breakpoint {
44
163
  _handler = new WeakMap();
45
164
  class Collection {
46
165
  constructor(options = {}) {
47
- __privateAdd(this, _entryPrototype);
48
- const root = this;
49
166
  this.module = this.constructor.name;
50
167
  this.collection = [];
51
- this.settings = Object.assign({ dataConfig: "config" }, options);
52
- __privateSet(this, _entryPrototype, {
53
- applySettings(obj) {
54
- return Object.assign(this.settings, obj);
55
- },
56
- getDataConfig() {
57
- return Object.assign(this.dataConfig, getConfig(this.el, this.getSetting("dataConfig")));
58
- },
59
- getCustomProps() {
60
- return Object.assign(this.customProps, getCustomProps(this.el, root.module, this.customPropKeys));
61
- },
62
- getSetting(key) {
63
- const camel = toCamel(key);
64
- const kebab = toKebab(key);
65
- if ("dataConfig" in this && camel in this.dataConfig) {
66
- return this.dataConfig[camel];
67
- }
68
- if ("customProps" in this && kebab in this.customProps) {
69
- return this.customProps[kebab];
70
- }
71
- if ("settings" in this && camel in this.settings) {
72
- return this.settings[camel];
73
- }
74
- if ("settings" in root && camel in root.settings) {
75
- return root.settings[camel];
76
- }
77
- throw new Error(`${root.module} setting does not exist: ${key}`);
78
- },
79
- teleport(ref = this.getSetting("teleport"), method = this.getSetting("teleportMethod")) {
80
- if (!this.returnRef) {
81
- this.returnRef = teleport(this.el, ref, method);
82
- return this.el;
83
- } else {
84
- console.error("Element has already been teleported:", this.el);
85
- return false;
86
- }
87
- },
88
- teleportReturn() {
89
- if (this.returnRef) {
90
- this.returnRef = teleport(this.el, this.returnRef);
91
- return this.el;
92
- } else {
93
- console.error("No return reference found:", this.el);
94
- return false;
95
- }
96
- }
97
- });
168
+ this.settings = Object.assign({
169
+ dataConfig: "config",
170
+ teleport: null,
171
+ teleportMethod: "append"
172
+ }, options);
98
173
  }
99
- createEntry(query, overrides = {}) {
100
- const el = getElement(query);
101
- const entry = Object.create(__privateGet(this, _entryPrototype));
102
- Object.assign(entry, {
103
- id: el == null ? void 0 : el.id,
104
- el,
105
- settings: {},
106
- dataConfig: {},
107
- customProps: {},
108
- customPropKeys: [],
109
- returnRef: null
110
- }, overrides);
111
- return entry;
174
+ get(value, key = "id") {
175
+ return this.collection.find((entry) => entry[key] === value);
112
176
  }
113
- async register(item) {
114
- await this.deregister(item);
115
- this.collection.push(item);
116
- return this.collection;
177
+ applySettings(obj) {
178
+ return Object.assign(this.settings, obj);
179
+ }
180
+ async createEntry(query, config) {
181
+ return new CollectionEntry(this, query, config);
182
+ }
183
+ async register(query, config = {}) {
184
+ await this.deregister((query == null ? void 0 : query.id) || query, true);
185
+ const entry = await this.createEntry(query, config);
186
+ await entry.mount();
187
+ await lifecycleHook.call(this, "beforeRegister", entry);
188
+ await lifecycleHook.call(entry, "beforeRegister");
189
+ this.collection.push(entry);
190
+ await lifecycleHook.call(entry, "afterRegister");
191
+ await lifecycleHook.call(this, "afterRegister", entry);
192
+ return entry;
117
193
  }
118
- async deregister(ref) {
119
- const index2 = this.collection.findIndex((entry) => {
120
- return entry === ref;
121
- });
122
- if (index2 >= 0) {
194
+ async deregister(id, reReg = false) {
195
+ const index2 = this.collection.findIndex((entry) => entry.id === id);
196
+ if (~index2) {
123
197
  const entry = this.collection[index2];
198
+ await entry.unmount(reReg);
199
+ await lifecycleHook.call(this, "beforeDeregister", entry);
200
+ await lifecycleHook.call(entry, "beforeDeregister", reReg);
124
201
  Object.getOwnPropertyNames(entry).forEach((prop) => {
125
- delete entry[prop];
202
+ if (prop != "beforeDeregister" && prop != "afterDeregister") {
203
+ delete entry[prop];
204
+ }
126
205
  });
127
206
  this.collection.splice(index2, 1);
207
+ await lifecycleHook.call(entry, "afterDeregister", reReg);
208
+ await lifecycleHook.call(this, "afterDeregister", entry);
128
209
  }
129
210
  return this.collection;
130
211
  }
131
- async registerCollection(items) {
132
- await Promise.all(Array.from(items, (item) => {
133
- this.register(item);
134
- }));
135
- return this.collection;
212
+ async mount(options = {}) {
213
+ this.applySettings(options);
214
+ await lifecycleHook.call(this, "beforeMount");
215
+ const els = document.querySelectorAll(this.settings.selector);
216
+ for (const el of els) {
217
+ await this.register(el);
218
+ }
219
+ await lifecycleHook.call(this, "afterMount");
220
+ return this;
136
221
  }
137
- async deregisterCollection() {
222
+ async unmount() {
223
+ await lifecycleHook.call(this, "beforeUnmount");
138
224
  while (this.collection.length > 0) {
139
- await this.deregister(this.collection[0]);
225
+ await this.deregister(this.collection[0].id);
140
226
  }
141
- return this.collection;
227
+ await lifecycleHook.call(this, "afterUnmount");
228
+ return this;
142
229
  }
143
- get(value, key = "id") {
144
- return this.collection.find((entry) => entry[key] === value);
230
+ }
231
+ class CollectionEntry {
232
+ constructor(context, query, options = {}) {
233
+ this.context = context;
234
+ this.id = (query == null ? void 0 : query.id) || query;
235
+ this.el = getElement(query);
236
+ this.settings = Object.assign({}, options);
237
+ this.dataConfig = {};
238
+ this.customProps = {};
239
+ this.returnRef = null;
240
+ }
241
+ applySettings(obj) {
242
+ return Object.assign(this.settings, obj);
243
+ }
244
+ getDataConfig() {
245
+ return Object.assign(this.dataConfig, getConfig(this.el, this.getSetting("dataConfig")));
246
+ }
247
+ getCustomProps() {
248
+ return Object.assign(this.customProps, getCustomProps(this));
249
+ }
250
+ getSetting(key) {
251
+ const camel = toCamel(key);
252
+ const kebab = toKebab(key);
253
+ if ("dataConfig" in this && camel in this.dataConfig) {
254
+ return this.dataConfig[camel];
255
+ }
256
+ if ("customProps" in this && kebab in this.customProps) {
257
+ return this.customProps[kebab];
258
+ }
259
+ if ("settings" in this && camel in this.settings) {
260
+ return this.settings[camel];
261
+ }
262
+ if ("settings" in this.context && camel in this.context.settings) {
263
+ return this.context.settings[camel];
264
+ }
265
+ throw new Error(`${this.context.module} setting does not exist: ${key}`);
266
+ }
267
+ async mount(options = {}) {
268
+ if (this.el === null) {
269
+ throw new Error(`${this.context.module} element was not found with ID: "${this.id}"`);
270
+ }
271
+ this.applySettings(options);
272
+ this.getDataConfig();
273
+ this.getCustomProps();
274
+ await lifecycleHook.call(this, "beforeMount");
275
+ if (this.getSetting("teleport")) {
276
+ this.teleport();
277
+ }
278
+ await lifecycleHook.call(this, "afterMount");
279
+ }
280
+ async unmount(reMount = false) {
281
+ await lifecycleHook.call(this, "beforeUnmount", reMount);
282
+ if (this.getSetting("teleport")) {
283
+ this.teleportReturn();
284
+ }
285
+ await lifecycleHook.call(this, "afterUnmount", reMount);
286
+ }
287
+ teleport(ref = this.getSetting("teleport"), method = this.getSetting("teleportMethod")) {
288
+ if (!this.returnRef) {
289
+ this.returnRef = teleport(this.el, ref, method);
290
+ return this.el;
291
+ } else {
292
+ console.error("Element has already been teleported:", this.el);
293
+ return false;
294
+ }
295
+ }
296
+ teleportReturn() {
297
+ if (this.returnRef) {
298
+ this.returnRef = teleport(this.el, this.returnRef);
299
+ return this.el;
300
+ } else {
301
+ console.error("No return reference found:", this.el);
302
+ return false;
303
+ }
145
304
  }
146
305
  }
147
- _entryPrototype = new WeakMap();
148
306
  class FocusTrap {
149
307
  constructor(el = null, selectorFocus = "[data-focus]") {
150
308
  __privateAdd(this, _focusable);
@@ -247,58 +405,6 @@ function handleFocusLock(event) {
247
405
  const isTab = event.key === "Tab" || event.keyCode === 9;
248
406
  if (isTab) event.preventDefault();
249
407
  }
250
- function getPrefix() {
251
- return getComputedStyle(document.body).getPropertyValue("--vb-prefix").trim();
252
- }
253
- function cssVar(property, options) {
254
- const settings = {
255
- fallback: null,
256
- element: document.body,
257
- ...options
258
- };
259
- if (property.slice(0, 2) !== "--") {
260
- const prefixValue = getPrefix();
261
- if (prefixValue) {
262
- property = `${prefixValue}${property}`;
263
- }
264
- property = `--${property}`;
265
- }
266
- const cssValue = getComputedStyle(settings.element).getPropertyValue(property).trim();
267
- if (cssValue) {
268
- return cssValue;
269
- } else {
270
- if (settings.fallback) {
271
- return settings.fallback;
272
- } else {
273
- throw new Error(`CSS variable "${property}" was not found!`);
274
- }
275
- }
276
- }
277
- function getConfig(el, dataConfig = "config") {
278
- const string = el.getAttribute(`data-${dataConfig}`) || "";
279
- const json = string.replace(/'/g, '"');
280
- return json ? JSON.parse(json) : {};
281
- }
282
- function getCustomProps(el, module, array) {
283
- const styles = getComputedStyle(el);
284
- const result = {};
285
- for (let i = 0; i < array.length; i++) {
286
- const prefix = getPrefix();
287
- const value = styles.getPropertyValue(`--${prefix}${module.toLowerCase()}-${array[i]}`).trim();
288
- if (value) {
289
- result[array[i]] = value;
290
- }
291
- }
292
- return result;
293
- }
294
- function getElement(query) {
295
- if (typeof query === "string") {
296
- return document.getElementById(query);
297
- } else if (query instanceof HTMLElement) {
298
- return query;
299
- }
300
- return void 0;
301
- }
302
408
  function localStore(key, enable = true) {
303
409
  const local = localStorage.getItem(key);
304
410
  const store = local ? JSON.parse(local) : {};
@@ -402,75 +508,26 @@ function themeStore(options) {
402
508
  api.callback("onInit");
403
509
  return api;
404
510
  }
405
- function toCamel(value) {
406
- return value.split("-").map((word, index2) => index2 === 0 ? word : word.charAt(0).toUpperCase() + word.slice(1)).join("");
407
- }
408
- function toKebab(value) {
409
- return value.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
410
- }
411
- function transition(el, from, to, duration = "transition-duration") {
412
- return new Promise((resolve) => {
413
- if (typeof duration === "string") {
414
- const cssValue = cssVar(duration, { element: el });
415
- const ms = cssValue.includes("ms") ? true : false;
416
- duration = parseFloat(cssValue) * (ms ? 1 : 1e3);
417
- }
418
- el.classList.remove(from.finish);
419
- el.classList.add(to.start);
420
- setTimeout(() => {
421
- el.classList.add(to.finish);
422
- el.classList.remove(to.start);
423
- resolve(el);
424
- }, duration);
425
- });
426
- }
427
- function setOverflowHidden(state, selector) {
428
- if (selector) {
429
- const els = document.querySelectorAll(selector);
430
- els.forEach((el) => {
431
- if (state) {
432
- el.style.overflow = "hidden";
433
- } else {
434
- el.style.removeProperty("overflow");
435
- }
436
- });
437
- }
438
- }
439
- function setInert(state, selector) {
440
- if (selector) {
441
- const els = document.querySelectorAll(selector);
442
- els.forEach((el) => {
443
- if (state) {
444
- el.inert = true;
445
- el.setAttribute("aria-hidden", true);
446
- } else {
447
- el.inert = null;
448
- el.removeAttribute("aria-hidden");
449
- }
450
- });
451
- }
452
- }
453
- function updateGlobalState(state, selectorInert, selectorOverflow) {
454
- setInert(!!state, selectorInert);
455
- setOverflowHidden(!!state, selectorOverflow);
456
- }
457
511
  const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
458
512
  __proto__: null,
459
513
  Breakpoint,
460
514
  Collection,
515
+ CollectionEntry,
461
516
  FocusTrap,
462
517
  cssVar,
463
518
  getConfig,
464
519
  getCustomProps,
465
520
  getElement,
466
521
  getPrefix,
522
+ lifecycleHook,
467
523
  localStore,
524
+ setGlobalState,
468
525
  teleport,
469
526
  themeStore,
470
527
  toCamel,
471
528
  toKebab,
472
- transition,
473
- updateGlobalState
529
+ toMilliseconds,
530
+ transition
474
531
  }, Symbol.toStringTag, { value: "Module" }));
475
532
  const defaults$2 = {
476
533
  // Data attributes
@@ -479,7 +536,7 @@ const defaults$2 = {
479
536
  dataToggle: "drawer-toggle",
480
537
  dataBreakpoint: "drawer-breakpoint",
481
538
  // Selectors
482
- selectorDrawer: ".drawer",
539
+ selector: ".drawer",
483
540
  selectorDialog: ".drawer__dialog",
484
541
  selectorScreen: ".drawer",
485
542
  selectorFocus: "[data-focus]",
@@ -495,7 +552,6 @@ const defaults$2 = {
495
552
  // Feature toggles
496
553
  breakpoints: null,
497
554
  customEventPrefix: "drawer:",
498
- eventListeners: true,
499
555
  store: true,
500
556
  storeKey: "VB:DrawerState",
501
557
  setTabindex: true,
@@ -553,28 +609,154 @@ function getBreakpoint(drawer) {
553
609
  }
554
610
  }
555
611
  function getDrawer(query) {
556
- const entry = typeof query === "string" ? this.get(query) : this.get(query.id);
612
+ const entry = typeof query === "string" ? this.get(query) : query;
557
613
  if (entry) {
558
614
  return entry;
559
615
  } else {
560
616
  throw new Error(`Drawer not found in collection with id of "${query.id || query}".`);
561
617
  }
562
- }
563
- function updateFocusState$1(entry) {
564
- if (entry.state === "opened") {
565
- if (entry.mode === "modal") {
566
- this.focusTrap.mount(entry.dialog, this.settings.selectorFocus);
567
- } else {
568
- this.focusTrap.focus(entry.dialog, this.settings.selectorFocus);
618
+ }
619
+ function updateFocusState$1(entry) {
620
+ if (entry.state === "opened") {
621
+ if (entry.mode === "modal") {
622
+ this.focusTrap.mount(entry.dialog, this.settings.selectorFocus);
623
+ } else {
624
+ this.focusTrap.focus(entry.dialog, this.settings.selectorFocus);
625
+ }
626
+ } else {
627
+ if (entry.trigger) {
628
+ entry.trigger.focus();
629
+ entry.trigger = null;
630
+ }
631
+ this.focusTrap.unmount();
632
+ }
633
+ }
634
+ function switchMode(entry) {
635
+ switch (entry.mode) {
636
+ case "inline":
637
+ return toInline.call(this, entry);
638
+ case "modal":
639
+ return toModal.call(this, entry);
640
+ default:
641
+ throw new Error(`"${entry.mode}" is not a valid drawer mode.`);
642
+ }
643
+ }
644
+ async function toInline(entry) {
645
+ entry.el.classList.remove(entry.getSetting("classModal"));
646
+ entry.dialog.removeAttribute("aria-modal");
647
+ setGlobalState(false, entry.getSetting("selectorInert"), entry.getSetting("selectorOverflow"));
648
+ this.focusTrap.unmount();
649
+ await applyInlineState(entry);
650
+ entry.el.dispatchEvent(new CustomEvent(entry.getSetting("customEventPrefix") + "switchMode", {
651
+ detail: this,
652
+ bubbles: true
653
+ }));
654
+ return entry;
655
+ }
656
+ async function toModal(entry) {
657
+ entry.el.classList.add(entry.getSetting("classModal"));
658
+ entry.dialog.setAttribute("aria-modal", "true");
659
+ await entry.close(false, false);
660
+ entry.el.dispatchEvent(new CustomEvent(entry.getSetting("customEventPrefix") + "switchMode", {
661
+ detail: this,
662
+ bubbles: true
663
+ }));
664
+ return entry;
665
+ }
666
+ class DrawerEntry extends CollectionEntry {
667
+ constructor(context, query, options = {}) {
668
+ super(context, query, options);
669
+ __privateAdd(this, _mode);
670
+ __privateAdd(this, _state);
671
+ __privateAdd(this, _breakpoint);
672
+ this.dialog = null;
673
+ this.trigger = null;
674
+ __privateSet(this, _breakpoint, new Breakpoint());
675
+ __privateSet(this, _mode, "indeterminate");
676
+ __privateSet(this, _state, "indeterminate");
677
+ this.inlineState = "indeterminate";
678
+ }
679
+ get breakpoint() {
680
+ return getBreakpoint.call(this.context, this.el);
681
+ }
682
+ get store() {
683
+ return this.context.store.get(this.id);
684
+ }
685
+ get mode() {
686
+ return __privateGet(this, _mode);
687
+ }
688
+ set mode(value) {
689
+ __privateSet(this, _mode, value);
690
+ switchMode.call(this.context, this);
691
+ }
692
+ get state() {
693
+ return __privateGet(this, _state);
694
+ }
695
+ set state(value) {
696
+ __privateSet(this, _state, value);
697
+ if (this.mode === "inline" && value != "opening" && value != "closing") {
698
+ this.inlineState = value;
699
+ if (this.getSetting("store")) {
700
+ this.context.store.set(this.id, value);
701
+ }
702
+ }
703
+ if (value === "indeterminate") {
704
+ this.el.classList.remove(this.getSetting("stateOpened"));
705
+ this.el.classList.remove(this.getSetting("stateOpening"));
706
+ this.el.classList.remove(this.getSetting("stateClosed"));
707
+ this.el.classList.remove(this.getSetting("stateClosing"));
708
+ }
709
+ }
710
+ async open(transition2, focus) {
711
+ return this.context.open(this, transition2, focus);
712
+ }
713
+ async close(transition2, focus) {
714
+ return this.context.close(this, transition2, focus);
715
+ }
716
+ async toggle(transition2, focus) {
717
+ return this.context.toggle(this, transition2, focus);
718
+ }
719
+ async deregister() {
720
+ return this.context.deregister(this.id);
721
+ }
722
+ mountBreakpoint() {
723
+ const value = this.breakpoint;
724
+ const handler = this.handleBreakpoint.bind(this);
725
+ __privateGet(this, _breakpoint).mount(value, handler);
726
+ }
727
+ unmountBreakpoint() {
728
+ __privateGet(this, _breakpoint).unmount();
729
+ }
730
+ handleBreakpoint(event) {
731
+ const bpMode = event.matches ? "inline" : "modal";
732
+ if (this.mode != bpMode) {
733
+ this.mode = bpMode;
569
734
  }
570
- } else {
571
- if (entry.trigger) {
572
- entry.trigger.focus();
573
- entry.trigger = null;
735
+ }
736
+ async beforeMount() {
737
+ const dialog = this.el.querySelector(this.getSetting("selectorDialog"));
738
+ this.dialog = dialog ? dialog : this.el;
739
+ if (this.getSetting("setTabindex")) {
740
+ this.dialog.setAttribute("tabindex", "-1");
574
741
  }
575
- this.focusTrap.unmount();
742
+ applyInitialState(this);
743
+ this.inlineState = this.state;
744
+ this.mode = this.el.classList.contains(this.getSetting("classModal")) ? "modal" : "inline";
745
+ if (this.breakpoint) {
746
+ this.mountBreakpoint();
747
+ }
748
+ }
749
+ async beforeUnmount(close2 = true) {
750
+ if (close2 && this.state === "opened") {
751
+ await this.close(false);
752
+ }
753
+ this.context.store.set(this.id);
754
+ this.unmountBreakpoint();
576
755
  }
577
756
  }
757
+ _mode = new WeakMap();
758
+ _state = new WeakMap();
759
+ _breakpoint = new WeakMap();
578
760
  async function handleClick$2(event) {
579
761
  const trigger = event.target.closest(`
580
762
  [data-${this.settings.dataOpen}],
@@ -607,8 +789,8 @@ async function handleClick$2(event) {
607
789
  entry.trigger = trigger;
608
790
  return entry.close();
609
791
  } else {
610
- const parent = event.target.closest(this.settings.selectorDrawer);
611
- if (parent) return this.close(parent);
792
+ const parent = event.target.closest(this.settings.selector);
793
+ if (parent) return this.close(parent.id);
612
794
  }
613
795
  });
614
796
  }
@@ -620,45 +802,27 @@ async function handleClick$2(event) {
620
802
  }
621
803
  function handleKeydown$2(event) {
622
804
  if (event.key === "Escape") {
623
- if (this.activeModal) return this.close(this.activeModal);
624
- }
625
- }
626
- async function deregister$2(obj, close2 = true) {
627
- const index2 = this.collection.findIndex((entry) => {
628
- return entry.id === obj.id;
629
- });
630
- if (index2 >= 0) {
631
- const entry = this.collection[index2];
632
- if (close2 && entry.state === "opened") {
633
- await entry.close(false);
634
- }
635
- this.store.set(entry.id);
636
- entry.unmountBreakpoint();
637
- Object.getOwnPropertyNames(entry).forEach((prop) => {
638
- delete entry[prop];
639
- });
640
- this.collection.splice(index2, 1);
805
+ if (this.activeModal) return this.close(this.activeModal.id);
641
806
  }
642
- return this.collection;
643
807
  }
644
808
  async function open$2(query, transitionOverride, focus = true) {
645
809
  const entry = getDrawer.call(this, query);
646
810
  if (entry.state === "closed" || entry.state === "indeterminate") {
647
811
  entry.state = "opening";
648
812
  if (transitionOverride != void 0 ? transitionOverride : entry.getSetting("transition")) {
649
- await transition(entry.el, {
650
- start: entry.getSetting("stateClosing"),
651
- finish: entry.getSetting("stateClosed")
652
- }, {
653
- start: entry.getSetting("stateOpening"),
654
- finish: entry.getSetting("stateOpened")
655
- }, entry.getSetting("transitionDuration"));
813
+ await transition(
814
+ entry.el,
815
+ entry.getSetting("stateClosed"),
816
+ entry.getSetting("stateOpening"),
817
+ entry.getSetting("stateOpened"),
818
+ entry.getSetting("transitionDuration")
819
+ );
656
820
  } else {
657
821
  entry.el.classList.add(entry.getSetting("stateOpened"));
658
822
  entry.el.classList.remove(entry.getSetting("stateClosed"));
659
823
  }
660
824
  entry.state = "opened";
661
- if (entry.mode === "modal") updateGlobalState(true, entry.getSetting("selectorInert"), entry.getSetting("selectorOverflow"));
825
+ if (entry.mode === "modal") setGlobalState(true, entry.getSetting("selectorInert"), entry.getSetting("selectorOverflow"));
662
826
  if (focus) {
663
827
  updateFocusState$1.call(this, entry);
664
828
  }
@@ -675,19 +839,19 @@ async function close$2(query, transitionOverride, focus = true) {
675
839
  entry.state = "closing";
676
840
  document.activeElement.blur();
677
841
  if (transitionOverride != void 0 ? transitionOverride : entry.getSetting("transition")) {
678
- await transition(entry.el, {
679
- start: entry.getSetting("stateOpening"),
680
- finish: entry.getSetting("stateOpened")
681
- }, {
682
- start: entry.getSetting("stateClosing"),
683
- finish: entry.getSetting("stateClosed")
684
- }, entry.getSetting("transitionDuration"));
842
+ await transition(
843
+ entry.el,
844
+ entry.getSetting("stateOpened"),
845
+ entry.getSetting("stateClosing"),
846
+ entry.getSetting("stateClosed"),
847
+ entry.getSetting("transitionDuration")
848
+ );
685
849
  } else {
686
850
  entry.el.classList.add(entry.getSetting("stateClosed"));
687
851
  entry.el.classList.remove(entry.getSetting("stateOpened"));
688
852
  }
689
853
  entry.state = "closed";
690
- if (entry.mode === "modal") updateGlobalState(false, entry.getSetting("selectorInert"), entry.getSetting("selectorOverflow"));
854
+ if (entry.mode === "modal") setGlobalState(false, entry.getSetting("selectorInert"), entry.getSetting("selectorOverflow"));
691
855
  if (focus) {
692
856
  updateFocusState$1.call(this, entry);
693
857
  }
@@ -706,186 +870,44 @@ async function toggle(query, transition2, focus) {
706
870
  return close$2.call(this, entry, transition2, focus);
707
871
  }
708
872
  }
709
- function switchMode(entry) {
710
- switch (entry.mode) {
711
- case "inline":
712
- return toInline.call(this, entry);
713
- case "modal":
714
- return toModal.call(this, entry);
715
- default:
716
- throw new Error(`"${entry.mode}" is not a valid drawer mode.`);
717
- }
718
- }
719
- async function toInline(entry) {
720
- entry.el.classList.remove(entry.getSetting("classModal"));
721
- entry.dialog.removeAttribute("aria-modal");
722
- updateGlobalState(false, entry.getSetting("selectorInert"), entry.getSetting("selectorOverflow"));
723
- this.focusTrap.unmount();
724
- await applyInlineState(entry);
725
- entry.el.dispatchEvent(new CustomEvent(entry.getSetting("customEventPrefix") + "switchMode", {
726
- detail: this,
727
- bubbles: true
728
- }));
729
- return entry;
730
- }
731
- async function toModal(entry) {
732
- entry.el.classList.add(entry.getSetting("classModal"));
733
- entry.dialog.setAttribute("aria-modal", "true");
734
- await close$2.call(this, entry, false, false);
735
- entry.el.dispatchEvent(new CustomEvent(entry.getSetting("customEventPrefix") + "switchMode", {
736
- detail: this,
737
- bubbles: true
738
- }));
739
- return entry;
740
- }
741
- async function register$2(el, config = {}) {
742
- await deregister$2.call(this, el, false);
743
- const root = this;
744
- const breakpoint = new Breakpoint();
745
- let _mode, _state = "indeterminate";
746
- const entry = this.createEntry(el);
747
- Object.assign(entry, {
748
- dialog: null,
749
- trigger: null,
750
- inlineState: "indeterminate",
751
- open(transition2, focus) {
752
- return open$2.call(root, this, transition2, focus);
753
- },
754
- close(transition2, focus) {
755
- return close$2.call(root, this, transition2, focus);
756
- },
757
- toggle(transition2, focus) {
758
- return toggle.call(root, this, transition2, focus);
759
- },
760
- deregister() {
761
- return deregister$2.call(root, this);
762
- },
763
- mountBreakpoint() {
764
- const value = this.breakpoint;
765
- const handler = this.handleBreakpoint.bind(this);
766
- breakpoint.mount(value, handler);
767
- return this;
768
- },
769
- unmountBreakpoint() {
770
- breakpoint.unmount();
771
- return this;
772
- },
773
- handleBreakpoint(event) {
774
- const bpMode = event.matches ? "inline" : "modal";
775
- if (this.mode != bpMode) {
776
- this.mode = bpMode;
777
- }
778
- return this;
779
- }
780
- });
781
- Object.defineProperties(entry, Object.getOwnPropertyDescriptors({
782
- get breakpoint() {
783
- return getBreakpoint.call(root, el);
784
- },
785
- get store() {
786
- return root.store.get(this.id);
787
- },
788
- get mode() {
789
- return _mode;
790
- },
791
- set mode(value) {
792
- _mode = value;
793
- switchMode.call(root, this);
794
- },
795
- get state() {
796
- return _state;
797
- },
798
- set state(value) {
799
- _state = value;
800
- if (this.mode === "inline" && value != "opening" && value != "closing") {
801
- this.inlineState = value;
802
- if (this.getSetting("store")) {
803
- root.store.set(this.id, value);
804
- }
805
- }
806
- if (value === "indeterminate") {
807
- this.el.classList.remove(this.getSetting("stateOpened"));
808
- this.el.classList.remove(this.getSetting("stateOpening"));
809
- this.el.classList.remove(this.getSetting("stateClosed"));
810
- this.el.classList.remove(this.getSetting("stateClosing"));
811
- }
812
- }
813
- }));
814
- entry.applySettings(config);
815
- entry.getDataConfig();
816
- if (entry.getSetting("teleport")) {
817
- entry.teleport();
818
- }
819
- this.collection.push(entry);
820
- const dialog = el.querySelector(entry.getSetting("selectorDialog"));
821
- entry.dialog = dialog ? dialog : el;
822
- if (entry.getSetting("setTabindex")) {
823
- entry.dialog.setAttribute("tabindex", "-1");
824
- }
825
- applyInitialState(entry);
826
- entry.inlineState = entry.state;
827
- entry.mode = el.classList.contains(entry.getSetting("classModal")) ? "modal" : "inline";
828
- if (entry.breakpoint) {
829
- entry.mountBreakpoint();
830
- }
831
- return entry;
832
- }
833
873
  class Drawer extends Collection {
834
874
  constructor(options) {
835
875
  super({ ...defaults$2, ...options });
836
876
  __privateAdd(this, _handleClick);
837
877
  __privateAdd(this, _handleKeydown);
838
878
  this.focusTrap = new FocusTrap();
839
- this.store = localStore(this.settings.storeKey, this.settings.store);
840
879
  __privateSet(this, _handleClick, handleClick$2.bind(this));
841
880
  __privateSet(this, _handleKeydown, handleKeydown$2.bind(this));
881
+ this.store = localStore(this.settings.storeKey, this.settings.store);
842
882
  }
843
883
  get activeModal() {
844
884
  return this.collection.find((entry) => {
845
885
  return entry.state === "opened" && entry.mode === "modal";
846
886
  });
847
887
  }
848
- async mount(options = null) {
849
- if (options) this.settings = { ...this.settings, ...options };
850
- const drawers = document.querySelectorAll(this.settings.selectorDrawer);
851
- await this.registerCollection(drawers);
852
- if (this.settings.eventListeners) {
853
- this.mountEventListeners();
854
- }
855
- return this;
888
+ async createEntry(query, config) {
889
+ return new DrawerEntry(this, query, config);
856
890
  }
857
- async unmount() {
858
- await this.deregisterCollection();
859
- if (this.settings.eventListeners) {
860
- this.unmountEventListeners();
861
- }
862
- return this;
891
+ async open(id, transition2, focus) {
892
+ return open$2.call(this, id, transition2, focus);
893
+ }
894
+ async close(id, transition2, focus) {
895
+ return close$2.call(this, id, transition2, focus);
896
+ }
897
+ async toggle(id, transition2, focus) {
898
+ return toggle.call(this, id, transition2, focus);
863
899
  }
864
- mountEventListeners() {
900
+ async afterMount() {
865
901
  document.addEventListener("click", __privateGet(this, _handleClick), false);
866
902
  document.addEventListener("keydown", __privateGet(this, _handleKeydown), false);
867
903
  }
868
- unmountEventListeners() {
904
+ async beforeUnmount() {
905
+ this.trigger = null;
906
+ }
907
+ async afterUnmount() {
869
908
  document.removeEventListener("click", __privateGet(this, _handleClick), false);
870
909
  document.removeEventListener("keydown", __privateGet(this, _handleKeydown), false);
871
910
  }
872
- register(query, config = {}) {
873
- let el = typeof query == "string" ? document.getElementById(query) : query;
874
- return el ? register$2.call(this, el, config) : Promise.reject(new Error(`Failed to register; drawer not found with ID of: "${query.id || query}".`));
875
- }
876
- deregister(query) {
877
- let obj = this.get(query.id || query);
878
- return obj ? deregister$2.call(this, obj) : Promise.reject(new Error(`Failed to deregister; drawer does not exist in collection with ID of: "${query.id || query}".`));
879
- }
880
- open(id, transition2, focus) {
881
- return open$2.call(this, id, transition2, focus);
882
- }
883
- close(id, transition2, focus) {
884
- return close$2.call(this, id, transition2, focus);
885
- }
886
- toggle(id, transition2, focus) {
887
- return toggle.call(this, id, transition2, focus);
888
- }
889
911
  }
890
912
  _handleClick = new WeakMap();
891
913
  _handleKeydown = new WeakMap();
@@ -895,7 +917,7 @@ const defaults$1 = {
895
917
  dataClose: "modal-close",
896
918
  dataReplace: "modal-replace",
897
919
  // Selectors
898
- selectorModal: ".modal",
920
+ selector: ".modal",
899
921
  selectorDialog: ".modal__dialog",
900
922
  selectorScreen: ".modal",
901
923
  selectorRequired: '[role="alertdialog"]',
@@ -909,13 +931,61 @@ const defaults$1 = {
909
931
  stateClosed: "is-closed",
910
932
  // Feature settings
911
933
  customEventPrefix: "modal:",
912
- eventListeners: true,
913
934
  setTabindex: true,
914
935
  teleport: null,
915
936
  teleportMethod: "append",
916
937
  transition: true,
917
938
  transitionDuration: "modal-transition-duration"
918
939
  };
940
+ class ModalEntry extends CollectionEntry {
941
+ constructor(context, query, options = {}) {
942
+ super(context, query, options);
943
+ this.state = "closed";
944
+ this.dialog = null;
945
+ }
946
+ get isRequired() {
947
+ return this.dialog.matches(this.getSetting("selectorRequired"));
948
+ }
949
+ async open(transition2, focus) {
950
+ return this.context.open(this, transition2, focus);
951
+ }
952
+ async close(transition2, focus) {
953
+ return this.context.close(this, transition2, focus);
954
+ }
955
+ async replace(transition2, focus) {
956
+ return this.context.replace(this, transition2, focus);
957
+ }
958
+ async deregister() {
959
+ return this.context.deregister(this.id);
960
+ }
961
+ async beforeMount() {
962
+ const dialog = this.el.querySelector(this.getSetting("selectorDialog"));
963
+ this.dialog = dialog ? dialog : this.el;
964
+ this.dialog.setAttribute("aria-modal", "true");
965
+ if (!this.dialog.hasAttribute("role")) {
966
+ this.dialog.setAttribute("role", "dialog");
967
+ }
968
+ if (this.getSetting("setTabindex")) {
969
+ this.dialog.setAttribute("tabindex", "-1");
970
+ }
971
+ }
972
+ async afterRegister() {
973
+ if (this.el.classList.contains(this.getSetting("stateOpened"))) {
974
+ await this.open(false);
975
+ } else {
976
+ this.el.classList.remove(this.getSetting("stateOpening"));
977
+ this.el.classList.remove(this.getSetting("stateClosing"));
978
+ this.el.classList.add(this.getSetting("stateClosed"));
979
+ }
980
+ }
981
+ async beforeUnmount(reMount = false) {
982
+ if (!reMount && this.state === "opened") {
983
+ await this.close(false);
984
+ } else {
985
+ this.context.stack.remove(this);
986
+ }
987
+ }
988
+ }
919
989
  function getModal(query) {
920
990
  const entry = typeof query === "string" ? this.get(query) : this.get(query.id);
921
991
  if (entry) {
@@ -946,14 +1016,14 @@ async function handleClick$1(event) {
946
1016
  if (trigger.matches(`[data-${this.settings.dataOpen}]`)) {
947
1017
  const selector = trigger.getAttribute(`data-${this.settings.dataOpen}`).trim();
948
1018
  const entry = getModal.call(this, selector);
949
- const fromModal = event.target.closest(this.settings.selectorModal);
1019
+ const fromModal = event.target.closest(this.settings.selector);
950
1020
  if (!fromModal) this.trigger = trigger;
951
1021
  return entry.open();
952
1022
  }
953
1023
  if (trigger.matches(`[data-${this.settings.dataReplace}]`)) {
954
1024
  const selector = trigger.getAttribute(`data-${this.settings.dataReplace}`).trim();
955
1025
  const entry = getModal.call(this, selector);
956
- const fromModal = event.target.closest(this.settings.selectorModal);
1026
+ const fromModal = event.target.closest(this.settings.selector);
957
1027
  if (!fromModal) this.trigger = trigger;
958
1028
  return entry.replace();
959
1029
  }
@@ -973,27 +1043,6 @@ function handleKeydown$1(event) {
973
1043
  }
974
1044
  }
975
1045
  }
976
- async function deregister$1(obj, close2 = true) {
977
- const index2 = this.collection.findIndex((entry) => {
978
- return entry.id === obj.id;
979
- });
980
- if (index2 >= 0) {
981
- const entry = this.collection[index2];
982
- if (close2 && entry.state === "opened") {
983
- await entry.close(false);
984
- } else {
985
- this.stack.remove(entry);
986
- }
987
- if (entry.getSetting("teleport")) {
988
- entry.teleportReturn();
989
- }
990
- Object.getOwnPropertyNames(entry).forEach((prop) => {
991
- delete entry[prop];
992
- });
993
- this.collection.splice(index2, 1);
994
- }
995
- return this.collection;
996
- }
997
1046
  async function open$1(query, transitionOverride = void 0, focus = true) {
998
1047
  const entry = getModal.call(this, query);
999
1048
  this.stack.moveToTop(entry);
@@ -1001,13 +1050,13 @@ async function open$1(query, transitionOverride = void 0, focus = true) {
1001
1050
  entry.state = "opening";
1002
1051
  this.stack.add(entry);
1003
1052
  if (transitionOverride != void 0 ? transitionOverride : entry.getSetting("transition")) {
1004
- await transition(entry.el, {
1005
- start: entry.getSetting("stateClosing"),
1006
- finish: entry.getSetting("stateClosed")
1007
- }, {
1008
- start: entry.getSetting("stateOpening"),
1009
- finish: entry.getSetting("stateOpened")
1010
- }, entry.getSetting("transitionDuration"));
1053
+ await transition(
1054
+ entry.el,
1055
+ entry.getSetting("stateClosed"),
1056
+ entry.getSetting("stateOpening"),
1057
+ entry.getSetting("stateOpened"),
1058
+ entry.getSetting("transitionDuration")
1059
+ );
1011
1060
  } else {
1012
1061
  entry.el.classList.add(entry.getSetting("stateOpened"));
1013
1062
  entry.el.classList.remove(entry.getSetting("stateClosed"));
@@ -1029,13 +1078,13 @@ async function close$1(query, transitionOverride, focus = true) {
1029
1078
  entry.state = "closing";
1030
1079
  document.activeElement.blur();
1031
1080
  if (transitionOverride != void 0 ? transitionOverride : entry.getSetting("transition")) {
1032
- await transition(entry.el, {
1033
- start: entry.getSetting("stateOpening"),
1034
- finish: entry.getSetting("stateOpened")
1035
- }, {
1036
- start: entry.getSetting("stateClosing"),
1037
- finish: entry.getSetting("stateClosed")
1038
- }, entry.getSetting("transitionDuration"));
1081
+ await transition(
1082
+ entry.el,
1083
+ entry.getSetting("stateOpened"),
1084
+ entry.getSetting("stateClosing"),
1085
+ entry.getSetting("stateClosed"),
1086
+ entry.getSetting("transitionDuration")
1087
+ );
1039
1088
  } else {
1040
1089
  entry.el.classList.add(entry.getSetting("stateClosed"));
1041
1090
  entry.el.classList.remove(entry.getSetting("stateOpened"));
@@ -1080,55 +1129,6 @@ async function replace(query, transition2, focus = true) {
1080
1129
  }
1081
1130
  return { opened: resultOpened, closed: resultClosed };
1082
1131
  }
1083
- async function register$1(el, config = {}) {
1084
- await deregister$1.call(this, el, false);
1085
- const root = this;
1086
- const entry = this.createEntry(el);
1087
- Object.assign(entry, {
1088
- state: "closed",
1089
- dialog: null,
1090
- open(transition2, focus) {
1091
- return open$1.call(root, this, transition2, focus);
1092
- },
1093
- close(transition2, focus) {
1094
- return close$1.call(root, this, transition2, focus);
1095
- },
1096
- replace(transition2, focus) {
1097
- return replace.call(root, this, transition2, focus);
1098
- },
1099
- deregister() {
1100
- return deregister$1.call(root, this);
1101
- }
1102
- });
1103
- Object.defineProperties(entry, Object.getOwnPropertyDescriptors({
1104
- get isRequired() {
1105
- return this.dialog.matches(this.getSetting("selectorRequired"));
1106
- }
1107
- }));
1108
- entry.applySettings(config);
1109
- entry.getDataConfig();
1110
- const dialog = el.querySelector(entry.getSetting("selectorDialog"));
1111
- entry.dialog = dialog ? dialog : el;
1112
- entry.dialog.setAttribute("aria-modal", "true");
1113
- if (!entry.dialog.hasAttribute("role")) {
1114
- entry.dialog.setAttribute("role", "dialog");
1115
- }
1116
- if (entry.getSetting("setTabindex")) {
1117
- entry.dialog.setAttribute("tabindex", "-1");
1118
- }
1119
- if (entry.getSetting("teleport")) {
1120
- entry.teleport();
1121
- }
1122
- this.collection.push(entry);
1123
- if (entry.el.classList.contains(entry.getSetting("stateOpened"))) {
1124
- await entry.open(false);
1125
- } else {
1126
- entry.el.classList.remove(entry.getSetting("stateOpening"));
1127
- entry.el.classList.remove(entry.getSetting("stateClosing"));
1128
- entry.el.classList.add(entry.getSetting("stateClosed"));
1129
- }
1130
- return entry;
1131
- }
1132
1132
  function stack(settings) {
1133
1133
  const stackArray = [];
1134
1134
  return {
@@ -1146,8 +1146,8 @@ function stack(settings) {
1146
1146
  entry.el.style.zIndex = parseInt(value) + index2 + 1;
1147
1147
  });
1148
1148
  },
1149
- updateGlobalState() {
1150
- updateGlobalState(this.top, settings.selectorInert, settings.selectorOverflow);
1149
+ setGlobalState() {
1150
+ setGlobalState(this.top, settings.selectorInert, settings.selectorOverflow);
1151
1151
  this.updateIndex();
1152
1152
  },
1153
1153
  add(entry) {
@@ -1155,7 +1155,7 @@ function stack(settings) {
1155
1155
  const value = getComputedStyle(entry.el)["z-index"];
1156
1156
  entry.el.style.zIndex = parseInt(value) + stackArray.length + 1;
1157
1157
  stackArray.push(entry);
1158
- this.updateGlobalState();
1158
+ this.setGlobalState();
1159
1159
  },
1160
1160
  remove(entry) {
1161
1161
  const index2 = stackArray.findIndex((item) => {
@@ -1164,7 +1164,7 @@ function stack(settings) {
1164
1164
  if (index2 >= 0) {
1165
1165
  entry.el.style.zIndex = null;
1166
1166
  stackArray.splice(index2, 1);
1167
- this.updateGlobalState();
1167
+ this.setGlobalState();
1168
1168
  }
1169
1169
  },
1170
1170
  moveToTop(entry) {
@@ -1185,53 +1185,23 @@ class Modal extends Collection {
1185
1185
  __privateAdd(this, _handleKeydown2);
1186
1186
  this.trigger = null;
1187
1187
  this.focusTrap = new FocusTrap();
1188
- this.stack = stack(this.settings);
1189
1188
  __privateSet(this, _handleClick2, handleClick$1.bind(this));
1190
1189
  __privateSet(this, _handleKeydown2, handleKeydown$1.bind(this));
1190
+ this.stack = stack(this.settings);
1191
1191
  }
1192
1192
  get active() {
1193
1193
  return this.stack.top;
1194
1194
  }
1195
- async mount(options) {
1196
- if (options) this.settings = { ...this.settings, ...options };
1197
- const modals = document.querySelectorAll(this.settings.selectorModal);
1198
- await this.registerCollection(modals);
1199
- if (this.settings.eventListeners) {
1200
- this.mountEventListeners();
1201
- }
1202
- return this;
1203
- }
1204
- async unmount() {
1205
- this.trigger = null;
1206
- await this.deregisterCollection();
1207
- if (this.settings.eventListeners) {
1208
- this.unmountEventListeners();
1209
- }
1210
- return this;
1211
- }
1212
- mountEventListeners() {
1213
- document.addEventListener("click", __privateGet(this, _handleClick2), false);
1214
- document.addEventListener("keydown", __privateGet(this, _handleKeydown2), false);
1215
- }
1216
- unmountEventListeners() {
1217
- document.removeEventListener("click", __privateGet(this, _handleClick2), false);
1218
- document.removeEventListener("keydown", __privateGet(this, _handleKeydown2), false);
1219
- }
1220
- register(query, config = {}) {
1221
- let el = typeof query == "string" ? document.getElementById(query) : query;
1222
- return el ? register$1.call(this, el, config) : Promise.reject(new Error(`Failed to register; modal not found with ID of: "${query.id || query}".`));
1195
+ async createEntry(query, config) {
1196
+ return new ModalEntry(this, query, config);
1223
1197
  }
1224
- deregister(query) {
1225
- let obj = this.get(query.id || query);
1226
- return obj ? deregister$1.call(this, obj) : Promise.reject(new Error(`Failed to deregister; modal does not exist in collection with ID of: "${query.id || query}".`));
1227
- }
1228
- open(id, transition2, focus) {
1198
+ async open(id, transition2, focus) {
1229
1199
  return open$1.call(this, id, transition2, focus);
1230
1200
  }
1231
- close(id, transition2, focus) {
1201
+ async close(id, transition2, focus) {
1232
1202
  return close$1.call(this, id, transition2, focus);
1233
1203
  }
1234
- replace(id, transition2, focus) {
1204
+ async replace(id, transition2, focus) {
1235
1205
  return replace.call(this, id, transition2, focus);
1236
1206
  }
1237
1207
  async closeAll(exclude = false, transition2, focus = true) {
@@ -1241,17 +1211,28 @@ class Modal extends Collection {
1241
1211
  }
1242
1212
  return result;
1243
1213
  }
1214
+ async afterMount() {
1215
+ document.addEventListener("click", __privateGet(this, _handleClick2), false);
1216
+ document.addEventListener("keydown", __privateGet(this, _handleKeydown2), false);
1217
+ }
1218
+ async beforeUnmount() {
1219
+ this.trigger = null;
1220
+ }
1221
+ async afterUnmount() {
1222
+ document.removeEventListener("click", __privateGet(this, _handleClick2), false);
1223
+ document.removeEventListener("keydown", __privateGet(this, _handleKeydown2), false);
1224
+ }
1244
1225
  }
1245
1226
  _handleClick2 = new WeakMap();
1246
1227
  _handleKeydown2 = new WeakMap();
1247
1228
  const defaults = {
1248
1229
  // Selectors
1249
- selectorPopover: ".popover",
1230
+ selector: ".popover",
1250
1231
  selectorTooltip: ".popover_tooltip",
1251
1232
  selectorArrow: ".popover__arrow",
1252
1233
  // State classes
1253
1234
  stateActive: "is-active",
1254
- // Custom property defaults
1235
+ // Custom properties and their defaults
1255
1236
  placement: "bottom",
1256
1237
  event: "click",
1257
1238
  offset: 0,
@@ -1260,7 +1241,6 @@ const defaults = {
1260
1241
  arrowPadding: 0,
1261
1242
  toggleDelay: 0,
1262
1243
  // Feature settings
1263
- eventListeners: true,
1264
1244
  teleport: null,
1265
1245
  teleportMethod: "append"
1266
1246
  };
@@ -1353,38 +1333,6 @@ function getPopover(query) {
1353
1333
  throw new Error(`Popover not found in collection with id of "${query}".`);
1354
1334
  }
1355
1335
  }
1356
- function getPopoverID(obj) {
1357
- if (typeof obj === "string") {
1358
- return obj;
1359
- } else if (typeof obj.hasAttribute === "function") {
1360
- if (obj.closest(this.settings.selectorPopover)) {
1361
- obj = obj.closest(this.settings.selectorPopover);
1362
- return obj.id;
1363
- } else if (obj.hasAttribute("aria-controls")) {
1364
- return obj.getAttribute("aria-controls");
1365
- } else if (obj.hasAttribute("aria-describedby")) {
1366
- return obj.getAttribute("aria-describedby");
1367
- } else return false;
1368
- } else return false;
1369
- }
1370
- function getPopoverElements(query) {
1371
- const id = getPopoverID.call(this, query);
1372
- if (id) {
1373
- const popover = document.querySelector(`#${id}`);
1374
- const trigger = document.querySelector(`[aria-controls="${id}"]`) || document.querySelector(`[aria-describedby="${id}"]`);
1375
- if (!trigger && !popover) {
1376
- return { error: new Error(`No popover elements found using the ID: "${id}".`) };
1377
- } else if (!trigger) {
1378
- return { error: new Error(`No popover trigger associated with the provided popover: "${id}".`) };
1379
- } else if (!popover) {
1380
- return { error: new Error(`No popover associated with the provided popover trigger: "${id}".`) };
1381
- } else {
1382
- return { popover, trigger };
1383
- }
1384
- } else {
1385
- return { error: new Error("Could not resolve the popover ID.") };
1386
- }
1387
- }
1388
1336
  async function close(query) {
1389
1337
  const popover = query ? getPopover.call(this, query) : await closeAll.call(this);
1390
1338
  if (popover && popover.state === "opened") {
@@ -1393,7 +1341,7 @@ async function close(query) {
1393
1341
  if (!popover.isTooltip) {
1394
1342
  popover.trigger.setAttribute("aria-expanded", "false");
1395
1343
  }
1396
- popover.cleanup();
1344
+ popover.floatingCleanup();
1397
1345
  popover.state = "closed";
1398
1346
  if (popover.trigger === this.trigger) {
1399
1347
  this.trigger = null;
@@ -1430,7 +1378,6 @@ function handleClick(popover) {
1430
1378
  } else {
1431
1379
  this.trigger = popover.trigger;
1432
1380
  popover.open();
1433
- handleDocumentClick.call(this, popover);
1434
1381
  }
1435
1382
  }
1436
1383
  function handleTooltipClick(popover) {
@@ -1504,40 +1451,130 @@ function handleDocumentClick(popover) {
1504
1451
  }
1505
1452
  });
1506
1453
  }
1507
- async function deregister(obj) {
1508
- const index2 = this.collection.findIndex((entry) => {
1509
- return entry.id === obj.id;
1510
- });
1511
- if (index2 >= 0) {
1512
- const entry = this.collection[index2];
1513
- if (entry.state === "opened") {
1514
- entry.close();
1515
- }
1516
- entry.cleanup();
1517
- deregisterEventListeners(entry);
1518
- if (entry.getSetting("teleport")) {
1519
- entry.teleportReturn();
1520
- }
1521
- Object.getOwnPropertyNames(entry).forEach((prop) => {
1522
- delete entry[prop];
1454
+ class PopoverEntry extends CollectionEntry {
1455
+ constructor(context, query, options = {}) {
1456
+ super(context, query, options);
1457
+ __privateAdd(this, _eventListeners);
1458
+ __privateAdd(this, _isHovered);
1459
+ this.state = "closed";
1460
+ this.toggleDelayId = null;
1461
+ this.trigger = null;
1462
+ __privateSet(this, _eventListeners, null);
1463
+ __privateSet(this, _isHovered, {
1464
+ el: false,
1465
+ trigger: false
1523
1466
  });
1524
- this.collection.splice(index2, 1);
1467
+ this.floatingCleanup = () => {
1468
+ };
1525
1469
  }
1526
- return this.collection;
1527
- }
1528
- function deregisterEventListeners(entry) {
1529
- if (entry._eventListeners) {
1530
- entry._eventListeners.forEach((evObj) => {
1531
- evObj.el.forEach((el) => {
1532
- evObj.type.forEach((type) => {
1533
- entry[el].removeEventListener(type, evObj.listener, false);
1470
+ get isTooltip() {
1471
+ return !!this.el.closest(this.getSetting("selectorTooltip")) || this.el.getAttribute("role") == "tooltip";
1472
+ }
1473
+ get isHovered() {
1474
+ return __privateGet(this, _isHovered).el || __privateGet(this, _isHovered).trigger;
1475
+ }
1476
+ set isHovered(event) {
1477
+ const state = event.type == "mouseenter" ? true : event.type == "mouseleave" ? false : void 0;
1478
+ if (state == void 0) return;
1479
+ switch (event.target) {
1480
+ case this.el:
1481
+ __privateGet(this, _isHovered).el = state;
1482
+ break;
1483
+ case this.trigger:
1484
+ __privateGet(this, _isHovered).trigger = state;
1485
+ break;
1486
+ }
1487
+ }
1488
+ async open() {
1489
+ return this.context.open(this);
1490
+ }
1491
+ async close() {
1492
+ return this.context.close(this);
1493
+ }
1494
+ async deregister() {
1495
+ return this.context.deregister(this.id);
1496
+ }
1497
+ registerEventListeners() {
1498
+ if (!__privateGet(this, _eventListeners)) {
1499
+ const eventType = this.getSetting("event");
1500
+ if (eventType === "hover") {
1501
+ __privateSet(this, _eventListeners, [{
1502
+ el: ["el", "trigger"],
1503
+ type: ["mouseenter", "focus"],
1504
+ listener: handleMouseEnter.bind(this.context, this)
1505
+ }, {
1506
+ el: ["el", "trigger"],
1507
+ type: ["mouseleave", "focusout"],
1508
+ listener: handleMouseLeave.bind(this.context, this)
1509
+ }, {
1510
+ el: ["trigger"],
1511
+ type: ["click"],
1512
+ listener: handleTooltipClick.bind(this.context, this)
1513
+ }]);
1514
+ __privateGet(this, _eventListeners).forEach((evObj) => {
1515
+ evObj.el.forEach((el) => {
1516
+ evObj.type.forEach((type) => {
1517
+ this[el].addEventListener(type, evObj.listener, false);
1518
+ });
1519
+ });
1520
+ });
1521
+ } else {
1522
+ __privateSet(this, _eventListeners, [{
1523
+ el: ["trigger"],
1524
+ type: ["click"],
1525
+ listener: handleClick.bind(this.context, this)
1526
+ }]);
1527
+ __privateGet(this, _eventListeners).forEach((evObj) => {
1528
+ evObj.el.forEach((el) => {
1529
+ evObj.type.forEach((type) => {
1530
+ this[el].addEventListener(type, evObj.listener, false);
1531
+ });
1532
+ });
1533
+ });
1534
+ }
1535
+ }
1536
+ }
1537
+ deregisterEventListeners() {
1538
+ if (__privateGet(this, _eventListeners)) {
1539
+ __privateGet(this, _eventListeners).forEach((evObj) => {
1540
+ evObj.el.forEach((el) => {
1541
+ evObj.type.forEach((type) => {
1542
+ this[el].removeEventListener(type, evObj.listener, false);
1543
+ });
1534
1544
  });
1535
1545
  });
1536
- });
1537
- delete entry._eventListeners;
1546
+ __privateSet(this, _eventListeners, null);
1547
+ }
1548
+ }
1549
+ async beforeMount() {
1550
+ this.trigger = document.querySelector(
1551
+ `[aria-controls="${this.id}"], [aria-describedby="${this.id}"]`
1552
+ );
1553
+ if (this.isTooltip) {
1554
+ this.settings.event = "hover";
1555
+ this.el.setAttribute("role", "tooltip");
1556
+ } else {
1557
+ this.trigger.setAttribute("aria-expanded", "false");
1558
+ }
1559
+ this.registerEventListeners();
1560
+ }
1561
+ async afterRegister() {
1562
+ if (this.el.classList.contains(this.getSetting("stateActive"))) {
1563
+ await this.open();
1564
+ } else {
1565
+ this.el.inert = true;
1566
+ }
1567
+ }
1568
+ async beforeUnmount() {
1569
+ if (this.state === "opened") {
1570
+ await this.close();
1571
+ }
1572
+ this.floatingCleanup();
1573
+ this.deregisterEventListeners();
1538
1574
  }
1539
- return entry;
1540
1575
  }
1576
+ _eventListeners = new WeakMap();
1577
+ _isHovered = new WeakMap();
1541
1578
  const min = Math.min;
1542
1579
  const max = Math.max;
1543
1580
  const round = Math.round;
@@ -2960,7 +2997,7 @@ async function open(query) {
2960
2997
  const middlewareOptions = getMiddlewareOptions(popover);
2961
2998
  const arrowEl = popover.el.querySelector(middlewareOptions.arrow.element);
2962
2999
  middlewareOptions.arrow.element = arrowEl ? arrowEl : void 0;
2963
- popover.cleanup = autoUpdate(popover.trigger, popover.el, () => {
3000
+ popover.floatingCleanup = autoUpdate(popover.trigger, popover.el, () => {
2964
3001
  computePosition(popover.trigger, popover.el, {
2965
3002
  placement: popover.getSetting("placement"),
2966
3003
  middleware: [
@@ -2982,189 +3019,43 @@ async function open(query) {
2982
3019
  });
2983
3020
  });
2984
3021
  popover.state = "opened";
2985
- return popover;
2986
- }
2987
- async function register(el, trigger, config = {}) {
2988
- await deregister.call(this, el);
2989
- const root = this;
2990
- const _isHovered = {
2991
- el: false,
2992
- trigger: false
2993
- };
2994
- const _customPropKeys = [
2995
- "placement",
2996
- "event",
2997
- "offset",
2998
- "flip-padding",
2999
- "shift-padding",
3000
- "arrow-padding",
3001
- "toggle-delay"
3002
- ];
3003
- const entry = this.createEntry(el, { customPropKeys: _customPropKeys });
3004
- Object.assign(entry, {
3005
- state: "closed",
3006
- trigger,
3007
- toggleDelayId: null,
3008
- cleanup: () => {
3009
- },
3010
- open() {
3011
- return open.call(root, this);
3012
- },
3013
- close() {
3014
- return close.call(root, this);
3015
- },
3016
- deregister() {
3017
- return deregister.call(root, this);
3018
- }
3019
- });
3020
- Object.defineProperties(entry, Object.getOwnPropertyDescriptors({
3021
- set isHovered(event) {
3022
- const state = event.type == "mouseenter" ? true : event.type == "mouseleave" ? false : void 0;
3023
- if (state == void 0) return;
3024
- switch (event.target) {
3025
- case this.el:
3026
- _isHovered.el = state;
3027
- break;
3028
- case this.trigger:
3029
- _isHovered.trigger = state;
3030
- break;
3031
- }
3032
- },
3033
- get isHovered() {
3034
- return _isHovered.el || _isHovered.trigger;
3035
- },
3036
- get isTooltip() {
3037
- return !!el.closest(root.settings.selectorTooltip) || el.getAttribute("role") == "tooltip";
3038
- }
3039
- }));
3040
- if (entry.isTooltip) {
3041
- entry.settings.event = "hover";
3042
- }
3043
- entry.applySettings(config);
3044
- entry.getDataConfig();
3045
- entry.getCustomProps();
3046
- if (entry.isTooltip) {
3047
- entry.el.setAttribute("role", "tooltip");
3048
- }
3049
- if (!entry.isTooltip) {
3050
- entry.trigger.setAttribute("aria-expanded", "false");
3051
- }
3052
- registerEventListeners.call(this, entry);
3053
- if (entry.getSetting("teleport")) {
3054
- entry.teleport();
3055
- }
3056
- this.collection.push(entry);
3057
- if (entry.el.classList.contains(this.settings.stateActive)) {
3058
- await entry.open();
3059
- handleDocumentClick.call(this, entry);
3060
- } else {
3061
- entry.el.inert = true;
3062
- }
3063
- return entry;
3064
- }
3065
- function registerEventListeners(entry) {
3066
- if (!entry._eventListeners) {
3067
- const eventType = entry.getSetting("event");
3068
- if (eventType === "hover") {
3069
- entry._eventListeners = [{
3070
- el: ["el", "trigger"],
3071
- type: ["mouseenter", "focus"],
3072
- listener: handleMouseEnter.bind(this, entry)
3073
- }, {
3074
- el: ["el", "trigger"],
3075
- type: ["mouseleave", "focusout"],
3076
- listener: handleMouseLeave.bind(this, entry)
3077
- }, {
3078
- el: ["trigger"],
3079
- type: ["click"],
3080
- listener: handleTooltipClick.bind(this, entry)
3081
- }];
3082
- entry._eventListeners.forEach((evObj) => {
3083
- evObj.el.forEach((el) => {
3084
- evObj.type.forEach((type) => {
3085
- entry[el].addEventListener(type, evObj.listener, false);
3086
- });
3087
- });
3088
- });
3089
- } else {
3090
- entry._eventListeners = [{
3091
- el: ["trigger"],
3092
- type: ["click"],
3093
- listener: handleClick.bind(this, entry)
3094
- }];
3095
- entry._eventListeners.forEach((evObj) => {
3096
- evObj.el.forEach((el) => {
3097
- evObj.type.forEach((type) => {
3098
- entry[el].addEventListener(type, evObj.listener, false);
3099
- });
3100
- });
3101
- });
3102
- }
3022
+ if (popover.getSetting("event") === "click") {
3023
+ handleDocumentClick.call(this, popover);
3103
3024
  }
3104
- return entry;
3025
+ return popover;
3105
3026
  }
3106
3027
  class Popover extends Collection {
3107
- constructor(options) {
3028
+ constructor(options = {}) {
3108
3029
  super({ ...defaults, ...options });
3109
3030
  __privateAdd(this, _handleKeydown3);
3110
3031
  this.trigger = null;
3111
3032
  __privateSet(this, _handleKeydown3, handleKeydown.bind(this));
3112
3033
  }
3113
3034
  get active() {
3114
- return this.collection.find((popover) => popover.state == "opened");
3035
+ return this.get("opened", "state");
3115
3036
  }
3116
3037
  get activeHover() {
3117
3038
  return this.collection.find((popover) => {
3118
3039
  return popover.state == "opened" && popover.getSetting("event") == "hover";
3119
3040
  });
3120
3041
  }
3121
- async mount(options) {
3122
- if (options) this.settings = { ...this.settings, ...options };
3123
- const popovers = document.querySelectorAll(this.settings.selectorPopover);
3124
- await this.registerCollection(popovers);
3125
- if (this.settings.eventListeners) {
3126
- this.mountEventListeners(false);
3127
- }
3128
- return this;
3129
- }
3130
- async unmount() {
3131
- this.trigger = null;
3132
- await this.deregisterCollection();
3133
- if (this.settings.eventListeners) {
3134
- this.unmountEventListeners(false);
3135
- }
3136
- return this;
3137
- }
3138
- mountEventListeners(processCollection = true) {
3139
- if (processCollection) {
3140
- this.collection.forEach((popover) => {
3141
- registerEventListeners.call(this, popover);
3142
- });
3143
- }
3144
- document.addEventListener("keydown", __privateGet(this, _handleKeydown3), false);
3042
+ async createEntry(query, config) {
3043
+ return new PopoverEntry(this, query, config);
3145
3044
  }
3146
- unmountEventListeners(processCollection = true) {
3147
- if (processCollection) {
3148
- this.collection.forEach((popover) => {
3149
- deregisterEventListeners(popover);
3150
- });
3151
- }
3152
- document.removeEventListener("keydown", __privateGet(this, _handleKeydown3), false);
3045
+ async open(id) {
3046
+ return open.call(this, id);
3153
3047
  }
3154
- register(query, config = {}) {
3155
- const els = getPopoverElements.call(this, query);
3156
- if (els.error) return Promise.reject(els.error);
3157
- return register.call(this, els.popover, els.trigger, config);
3048
+ async close(id) {
3049
+ return close.call(this, id);
3158
3050
  }
3159
- deregister(query) {
3160
- let obj = this.get(query.id || query);
3161
- return obj ? deregister.call(this, obj) : Promise.reject(new Error(`Failed to deregister; popover does not exist in collection with ID of: "${query.id || query}".`));
3051
+ async afterMount() {
3052
+ document.addEventListener("keydown", __privateGet(this, _handleKeydown3), false);
3162
3053
  }
3163
- open(id) {
3164
- return open.call(this, id);
3054
+ async beforeUnmount() {
3055
+ this.trigger = null;
3165
3056
  }
3166
- close(id) {
3167
- return close.call(this, id);
3057
+ async afterUnmount() {
3058
+ document.removeEventListener("keydown", __privateGet(this, _handleKeydown3), false);
3168
3059
  }
3169
3060
  }
3170
3061
  _handleKeydown3 = new WeakMap();