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