vrembem 1.42.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dev/scripts.js CHANGED
@@ -59,10 +59,290 @@ var camelCase = function camelCase(str) {
59
59
  });
60
60
  };
61
61
 
62
+ function _settle(pact, state, value) {
63
+ if (!pact.s) {
64
+ if (value instanceof _Pact) {
65
+ if (value.s) {
66
+ if (state & 1) {
67
+ state = value.s;
68
+ }
69
+
70
+ value = value.v;
71
+ } else {
72
+ value.o = _settle.bind(null, pact, state);
73
+ return;
74
+ }
75
+ }
76
+
77
+ if (value && value.then) {
78
+ value.then(_settle.bind(null, pact, state), _settle.bind(null, pact, 2));
79
+ return;
80
+ }
81
+
82
+ pact.s = state;
83
+ pact.v = value;
84
+ var observer = pact.o;
85
+
86
+ if (observer) {
87
+ observer(pact);
88
+ }
89
+ }
90
+ }
91
+
92
+ var _Pact = /*#__PURE__*/function () {
93
+ function _Pact() {}
94
+
95
+ _Pact.prototype.then = function (onFulfilled, onRejected) {
96
+ var result = new _Pact();
97
+ var state = this.s;
98
+
99
+ if (state) {
100
+ var callback = state & 1 ? onFulfilled : onRejected;
101
+
102
+ if (callback) {
103
+ try {
104
+ _settle(result, 1, callback(this.v));
105
+ } catch (e) {
106
+ _settle(result, 2, e);
107
+ }
108
+
109
+ return result;
110
+ } else {
111
+ return this;
112
+ }
113
+ }
114
+
115
+ this.o = function (_this) {
116
+ try {
117
+ var value = _this.v;
118
+
119
+ if (_this.s & 1) {
120
+ _settle(result, 1, onFulfilled ? onFulfilled(value) : value);
121
+ } else if (onRejected) {
122
+ _settle(result, 1, onRejected(value));
123
+ } else {
124
+ _settle(result, 2, value);
125
+ }
126
+ } catch (e) {
127
+ _settle(result, 2, e);
128
+ }
129
+ };
130
+
131
+ return result;
132
+ };
133
+
134
+ return _Pact;
135
+ }();
136
+
137
+ function _isSettledPact(thenable) {
138
+ return thenable instanceof _Pact && thenable.s & 1;
139
+ }
140
+
141
+ function _for(test, update, body) {
142
+ var stage;
143
+
144
+ for (;;) {
145
+ var shouldContinue = test();
146
+
147
+ if (_isSettledPact(shouldContinue)) {
148
+ shouldContinue = shouldContinue.v;
149
+ }
150
+
151
+ if (!shouldContinue) {
152
+ return result;
153
+ }
154
+
155
+ if (shouldContinue.then) {
156
+ stage = 0;
157
+ break;
158
+ }
159
+
160
+ var result = body();
161
+
162
+ if (result && result.then) {
163
+ if (_isSettledPact(result)) {
164
+ result = result.s;
165
+ } else {
166
+ stage = 1;
167
+ break;
168
+ }
169
+ }
170
+
171
+ if (update) {
172
+ var updateValue = update();
173
+
174
+ if (updateValue && updateValue.then && !_isSettledPact(updateValue)) {
175
+ stage = 2;
176
+ break;
177
+ }
178
+ }
179
+ }
180
+
181
+ var pact = new _Pact();
182
+
183
+ var reject = _settle.bind(null, pact, 2);
184
+
185
+ (stage === 0 ? shouldContinue.then(_resumeAfterTest) : stage === 1 ? result.then(_resumeAfterBody) : updateValue.then(_resumeAfterUpdate)).then(void 0, reject);
186
+ return pact;
187
+
188
+ function _resumeAfterBody(value) {
189
+ result = value;
190
+
191
+ do {
192
+ if (update) {
193
+ updateValue = update();
194
+
195
+ if (updateValue && updateValue.then && !_isSettledPact(updateValue)) {
196
+ updateValue.then(_resumeAfterUpdate).then(void 0, reject);
197
+ return;
198
+ }
199
+ }
200
+
201
+ shouldContinue = test();
202
+
203
+ if (!shouldContinue || _isSettledPact(shouldContinue) && !shouldContinue.v) {
204
+ _settle(pact, 1, result);
205
+
206
+ return;
207
+ }
208
+
209
+ if (shouldContinue.then) {
210
+ shouldContinue.then(_resumeAfterTest).then(void 0, reject);
211
+ return;
212
+ }
213
+
214
+ result = body();
215
+
216
+ if (_isSettledPact(result)) {
217
+ result = result.v;
218
+ }
219
+ } while (!result || !result.then);
220
+
221
+ result.then(_resumeAfterBody).then(void 0, reject);
222
+ }
223
+
224
+ function _resumeAfterTest(shouldContinue) {
225
+ if (shouldContinue) {
226
+ result = body();
227
+
228
+ if (result && result.then) {
229
+ result.then(_resumeAfterBody).then(void 0, reject);
230
+ } else {
231
+ _resumeAfterBody(result);
232
+ }
233
+ } else {
234
+ _settle(pact, 1, result);
235
+ }
236
+ }
237
+
238
+ function _resumeAfterUpdate() {
239
+ if (shouldContinue = test()) {
240
+ if (shouldContinue.then) {
241
+ shouldContinue.then(_resumeAfterTest).then(void 0, reject);
242
+ } else {
243
+ _resumeAfterTest(shouldContinue);
244
+ }
245
+ } else {
246
+ _settle(pact, 1, result);
247
+ }
248
+ }
249
+ }
250
+
251
+ var Collection = /*#__PURE__*/function () {
252
+ function Collection() {
253
+ this.collection = [];
254
+ }
255
+
256
+ var _proto = Collection.prototype;
257
+
258
+ _proto.register = function register(item) {
259
+ try {
260
+ var _this2 = this;
261
+
262
+ return Promise.resolve(_this2.deregister(item)).then(function () {
263
+ _this2.collection.push(item);
264
+
265
+ return _this2.collection;
266
+ });
267
+ } catch (e) {
268
+ return Promise.reject(e);
269
+ }
270
+ };
271
+
272
+ _proto.deregister = function deregister(ref) {
273
+ try {
274
+ var _this4 = this;
275
+
276
+ var index = _this4.collection.findIndex(function (entry) {
277
+ return entry === ref;
278
+ });
279
+
280
+ if (index >= 0) {
281
+ var entry = _this4.collection[index];
282
+ Object.getOwnPropertyNames(entry).forEach(function (prop) {
283
+ delete entry[prop];
284
+ });
285
+
286
+ _this4.collection.splice(index, 1);
287
+ }
288
+
289
+ return Promise.resolve(_this4.collection);
290
+ } catch (e) {
291
+ return Promise.reject(e);
292
+ }
293
+ };
294
+
295
+ _proto.registerCollection = function registerCollection(items) {
296
+ try {
297
+ var _this6 = this;
298
+
299
+ return Promise.resolve(Promise.all(Array.from(items, function (item) {
300
+ _this6.register(item);
301
+ }))).then(function () {
302
+ return _this6.collection;
303
+ });
304
+ } catch (e) {
305
+ return Promise.reject(e);
306
+ }
307
+ };
308
+
309
+ _proto.deregisterCollection = function deregisterCollection() {
310
+ try {
311
+ var _temp3 = function _temp3() {
312
+ return _this8.collection;
313
+ };
314
+
315
+ var _this8 = this;
316
+
317
+ var _temp4 = _for(function () {
318
+ return _this8.collection.length > 0;
319
+ }, void 0, function () {
320
+ return Promise.resolve(_this8.deregister(_this8.collection[0])).then(function () {});
321
+ });
322
+
323
+ return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(_temp3) : _temp3(_temp4));
324
+ } catch (e) {
325
+ return Promise.reject(e);
326
+ }
327
+ };
328
+
329
+ _proto.get = function get(value, key) {
330
+ if (key === void 0) {
331
+ key = 'id';
332
+ }
333
+
334
+ return this.collection.find(function (item) {
335
+ return item[key] === value;
336
+ });
337
+ };
338
+
339
+ return Collection;
340
+ }();
341
+
62
342
  var focusableSelectors = ['a[href]:not([tabindex^="-"])', 'area[href]:not([tabindex^="-"])', 'input:not([type="hidden"]):not([type="radio"]):not([disabled]):not([tabindex^="-"])', 'input[type="radio"]:not([disabled]):not([tabindex^="-"])', 'select:not([disabled]):not([tabindex^="-"])', 'textarea:not([disabled]):not([tabindex^="-"])', 'button:not([disabled]):not([tabindex^="-"])', 'iframe:not([tabindex^="-"])', 'audio[controls]:not([tabindex^="-"])', 'video[controls]:not([tabindex^="-"])', '[contenteditable]:not([tabindex^="-"])', '[tabindex]:not([tabindex^="-"])'];
63
343
 
64
344
  var focusTarget = function focusTarget(target, settings) {
65
- var innerFocus = target.querySelector("[data-" + settings.dataFocus + "]");
345
+ var innerFocus = target.querySelector(settings.selectorFocus);
66
346
 
67
347
  if (innerFocus) {
68
348
  innerFocus.focus();
@@ -72,10 +352,6 @@ var focusTarget = function focusTarget(target, settings) {
72
352
  }
73
353
  };
74
354
  var focusTrigger = function focusTrigger(obj) {
75
- if (obj === void 0) {
76
- obj = null;
77
- }
78
-
79
355
  if (!obj || !obj.memory || !obj.memory.trigger) return;
80
356
  obj.memory.trigger.focus();
81
357
  obj.memory.trigger = null;
@@ -89,6 +365,7 @@ var FocusTrap = /*#__PURE__*/function () {
89
365
  var _proto = FocusTrap.prototype;
90
366
 
91
367
  _proto.init = function init(target) {
368
+ this.destroy();
92
369
  this.target = target;
93
370
  this.inner = this.target.querySelector('[tabindex="-1"]');
94
371
  this.focusable = this.getFocusable();
@@ -176,20 +453,6 @@ var FocusTrap = /*#__PURE__*/function () {
176
453
  return FocusTrap;
177
454
  }();
178
455
 
179
- /**
180
- * Get an element(s) from a selector or return value if not a string.
181
- * @param {String} selector - Selector to query.
182
- * @param {Boolean} single - Whether to return a single or all matches.
183
- */
184
- var getElement = function getElement(selector, single) {
185
- if (single === void 0) {
186
- single = 0;
187
- }
188
-
189
- if (typeof selector !== 'string') return selector;
190
- return single ? document.querySelector(selector) : document.querySelectorAll(selector);
191
- };
192
-
193
456
  /**
194
457
  * Checks an element or NodeList whether they contain a class or classes.
195
458
  * Ref: https://davidwalsh.name/nodelist-array
@@ -218,64 +481,6 @@ var hyphenCase = function hyphenCase(str) {
218
481
  });
219
482
  };
220
483
 
221
- /**
222
- * Moves element(s) in the DOM based on a reference and move type.
223
- * @param {String} target - The element(s) to move.
224
- * @param {String} type - Move type can be 'after', 'before', 'append' or 'prepend'.
225
- * @param {String} reference - The reference element the move is relative to.
226
- */
227
-
228
- function moveElement(target, type, reference) {
229
- if (reference === void 0) {
230
- reference = false;
231
- }
232
-
233
- if (reference) {
234
- var els = getElement(target);
235
- if (!els.length) throw new Error("Move target element \"" + target + "\" not found!");
236
- var ref = getElement(reference, 1);
237
- if (!ref) throw new Error("Move reference element \"" + reference + "\" not found!");
238
- els.forEach(function (el) {
239
- switch (type) {
240
- case 'after':
241
- ref.after(el);
242
- return {
243
- ref: ref,
244
- el: el,
245
- type: type
246
- };
247
-
248
- case 'before':
249
- ref.before(el);
250
- return {
251
- ref: ref,
252
- el: el,
253
- type: type
254
- };
255
-
256
- case 'append':
257
- ref.append(el);
258
- return {
259
- ref: ref,
260
- el: el,
261
- type: type
262
- };
263
-
264
- case 'prepend':
265
- ref.prepend(el);
266
- return {
267
- ref: ref,
268
- el: el,
269
- type: type
270
- };
271
-
272
- default:
273
- throw new Error("Move type \"" + type + "\" does not exist!");
274
- }
275
- });
276
- }
277
- }
278
-
279
484
  /**
280
485
  * Remove a class or classes from an element or NodeList.
281
486
  * @param {Node || NodeList} el - Element(s) to remove class(es) from.
@@ -291,6 +496,48 @@ var removeClass = function removeClass(el) {
291
496
  });
292
497
  };
293
498
 
499
+ /**
500
+ * Teleports an element in the DOM based on a reference and teleport method.
501
+ * Provide the comment node as the reference to teleport the element back to its
502
+ * previous location.
503
+ * @param {Node} what - What element to teleport.
504
+ * @param {String || Node} where - Where to teleport the element.
505
+ * @param {String} how - How (method) to teleport the element, e.g: 'after',
506
+ * 'before', 'append' or 'prepend'.
507
+ * @return {Node} Return the return reference if it was teleported else return
508
+ * null if it was returned to a comment reference.
509
+ */
510
+ function teleport(what, where, how) {
511
+ // Check if ref is either a comment or element node.
512
+ var isComment = where.nodeType === Node.COMMENT_NODE;
513
+ var isElement = where.nodeType === Node.ELEMENT_NODE; // Get the reference element.
514
+
515
+ where = isComment || isElement ? where : document.querySelector(where); // If ref is a comment, set teleport type to 'after'.
516
+
517
+ if (isComment) how = 'after'; // Must be a valid reference element and method.
518
+
519
+ if (!where) throw new Error("Not a valid teleport reference: '" + where + "'");
520
+ if (typeof where[how] != 'function') throw new Error("Not a valid teleport method: '" + how + "'"); // Initial return ref is null.
521
+
522
+ var returnRef = null; // If ref is not a comment, set a return reference comment.
523
+
524
+ if (!isComment) {
525
+ returnRef = document.createComment('teleported #' + what.id);
526
+ what.before(returnRef);
527
+ } // Teleport the target node.
528
+
529
+
530
+ where[how](what); // Delete the comment node if element was returned to a comment reference.
531
+
532
+ if (isComment) {
533
+ where.remove();
534
+ } // Return the return reference if it was teleported else return null if it was
535
+ // returned to a comment reference.
536
+
537
+
538
+ return returnRef;
539
+ }
540
+
294
541
  /**
295
542
  * Toggle a class or classes on an element or NodeList.
296
543
  * @param {Node || NodeList} el - Element(s) to toggle class(es) on.
@@ -350,19 +597,38 @@ var index = {
350
597
  setTabindex: setTabindex,
351
598
  addClass: addClass,
352
599
  camelCase: camelCase,
600
+ Collection: Collection,
353
601
  focusTarget: focusTarget,
354
602
  focusTrigger: focusTrigger,
355
603
  FocusTrap: FocusTrap,
356
- getElement: getElement,
357
604
  hasClass: hasClass,
358
605
  hyphenCase: hyphenCase,
359
- moveElement: moveElement,
360
606
  removeClass: removeClass,
607
+ teleport: teleport,
361
608
  toggleClass: toggleClass,
362
609
  openTransition: openTransition,
363
610
  closeTransition: closeTransition
364
611
  };
365
612
 
613
+ function _defineProperties(target, props) {
614
+ for (var i = 0; i < props.length; i++) {
615
+ var descriptor = props[i];
616
+ descriptor.enumerable = descriptor.enumerable || false;
617
+ descriptor.configurable = true;
618
+ if ("value" in descriptor) descriptor.writable = true;
619
+ Object.defineProperty(target, descriptor.key, descriptor);
620
+ }
621
+ }
622
+
623
+ function _createClass(Constructor, protoProps, staticProps) {
624
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
625
+ if (staticProps) _defineProperties(Constructor, staticProps);
626
+ Object.defineProperty(Constructor, "prototype", {
627
+ writable: false
628
+ });
629
+ return Constructor;
630
+ }
631
+
366
632
  function _extends() {
367
633
  _extends = Object.assign || function (target) {
368
634
  for (var i = 1; i < arguments.length; i++) {
@@ -492,7 +758,10 @@ var defaults$2 = {
492
758
  dataOpen: 'drawer-open',
493
759
  dataClose: 'drawer-close',
494
760
  dataBreakpoint: 'drawer-breakpoint',
495
- dataFocus: 'drawer-focus',
761
+ // Selectors
762
+ selectorFocus: '[data-focus]',
763
+ selectorInert: null,
764
+ selectorOverflow: null,
496
765
  // State classes
497
766
  stateOpened: 'is-opened',
498
767
  stateOpening: 'is-opening',
@@ -500,9 +769,6 @@ var defaults$2 = {
500
769
  stateClosed: 'is-closed',
501
770
  // Classes
502
771
  classModal: 'drawer_modal',
503
- // Selectors
504
- selectorInert: null,
505
- selectorOverflow: null,
506
772
  // Feature toggles
507
773
  breakpoints: null,
508
774
  customEventPrefix: 'drawer:',
@@ -663,7 +929,7 @@ var close$2 = function close(drawerKey) {
663
929
  }
664
930
  };
665
931
 
666
- function handlerClick$2(event) {
932
+ function handlerClick$1(event) {
667
933
  // Working catch
668
934
  if (this.working) return; // Toggle data trigger
669
935
 
@@ -713,7 +979,7 @@ function handlerClick$2(event) {
713
979
  return;
714
980
  }
715
981
  }
716
- function handlerKeydown$2(event) {
982
+ function handlerKeydown$1(event) {
717
983
  // Working catch
718
984
  if (this.working) return;
719
985
 
@@ -897,8 +1163,8 @@ var Drawer = /*#__PURE__*/function () {
897
1163
  this.state = {};
898
1164
  this.focusTrap = new FocusTrap();
899
1165
  this.breakpoint = new Breakpoint(this);
900
- this.__handlerClick = handlerClick$2.bind(this);
901
- this.__handlerKeydown = handlerKeydown$2.bind(this);
1166
+ this.__handlerClick = handlerClick$1.bind(this);
1167
+ this.__handlerKeydown = handlerKeydown$1.bind(this);
902
1168
  if (this.settings.autoInit) this.init();
903
1169
  }
904
1170
 
@@ -1016,136 +1282,303 @@ var Drawer = /*#__PURE__*/function () {
1016
1282
  var defaults$1 = {
1017
1283
  autoInit: false,
1018
1284
  // Data attributes
1019
- dataModal: 'modal',
1020
- dataDialog: 'modal-dialog',
1021
1285
  dataOpen: 'modal-open',
1022
1286
  dataClose: 'modal-close',
1023
- dataFocus: 'modal-focus',
1024
- dataRequired: 'modal-required',
1287
+ dataReplace: 'modal-replace',
1025
1288
  dataConfig: 'modal-config',
1289
+ // Selectors
1290
+ selectorModal: '.modal',
1291
+ selectorDialog: '.modal__dialog',
1292
+ selectorRequired: '[role="alertdialog"]',
1293
+ selectorFocus: '[data-focus]',
1294
+ selectorInert: null,
1295
+ selectorOverflow: 'body',
1026
1296
  // State classes
1027
1297
  stateOpened: 'is-opened',
1028
1298
  stateOpening: 'is-opening',
1029
1299
  stateClosing: 'is-closing',
1030
1300
  stateClosed: 'is-closed',
1031
- // Selector
1032
- selectorInert: null,
1033
- selectorOverflow: 'body',
1034
- // Feature toggles
1301
+ // Feature settings
1035
1302
  customEventPrefix: 'modal:',
1036
1303
  eventListeners: true,
1037
- moveModals: {
1038
- ref: null,
1039
- type: null
1040
- },
1304
+ teleport: null,
1305
+ teleportMethod: 'append',
1041
1306
  setTabindex: true,
1042
1307
  transition: true
1043
1308
  };
1044
1309
 
1045
- function getModalConfig(modal) {
1046
- var json = modal.getAttribute("data-" + this.settings.dataConfig);
1310
+ function updateGlobalState() {
1311
+ // Set inert state based on if a modal is active.
1312
+ setInert(!!this.active, this.settings.selectorInert); // Set overflow state based on if a modal is active.
1047
1313
 
1048
- if (json) {
1049
- var config = JSON.parse(json);
1050
- return _extends({}, this.settings, config);
1314
+ setOverflowHidden(!!this.active, this.settings.selectorOverflow); // Update the z-index of the stack.
1315
+
1316
+ updateStackIndex(this.stack);
1317
+ }
1318
+ function updateFocusState() {
1319
+ // Check if there's an active modal
1320
+ if (this.active) {
1321
+ // Set focus and init focus trap on active modal.
1322
+ focusTarget(this.active.target, this.settings);
1323
+ this.focusTrap.init(this.active.target);
1051
1324
  } else {
1052
- return this.settings;
1325
+ // Set focus to root trigger and destroy focus trap.
1326
+ focusTrigger(this);
1327
+ this.focusTrap.destroy();
1053
1328
  }
1054
1329
  }
1055
- function getModal(modalKey) {
1056
- if (typeof modalKey !== 'string') return modalKey;
1057
- return document.querySelector("[data-" + this.settings.dataModal + "=\"" + modalKey + "\"]");
1330
+ function updateStackIndex(stack) {
1331
+ stack.forEach(function (entry, index) {
1332
+ entry.target.style.zIndex = null;
1333
+ var value = getComputedStyle(entry.target)['z-index'];
1334
+ entry.target.style.zIndex = parseInt(value) + index + 1;
1335
+ });
1058
1336
  }
1059
- function modalNotFound(key) {
1060
- return Promise.reject(new Error("Did not find modal with key: \"" + key + "\""));
1337
+ function getConfig$1(el) {
1338
+ var string = el.getAttribute("data-" + this.settings.dataConfig) || '';
1339
+ var json = string.replace(/'/g, '"');
1340
+ return json ? JSON.parse(json) : {};
1061
1341
  }
1062
- function moveModals(type, ref) {
1063
- if (type === void 0) {
1064
- type = this.settings.moveModals.type;
1065
- }
1342
+ function getModal(query) {
1343
+ // Get the entry from collection.
1344
+ var entry = typeof query === 'string' ? this.get(query) : this.get(query.id); // Return entry if it was resolved, otherwise throw error.
1066
1345
 
1067
- if (ref === void 0) {
1068
- ref = this.settings.moveModals.ref;
1346
+ if (entry) {
1347
+ return entry;
1348
+ } else {
1349
+ throw new Error("Modal not found in collection with id of \"" + query + "\".");
1069
1350
  }
1070
-
1071
- var modals = document.querySelectorAll("[data-" + this.settings.dataModal + "]");
1072
- if (modals.length) moveElement(modals, type, ref);
1073
1351
  }
1352
+ function getModalID(obj) {
1353
+ // If it's a string, return the string.
1354
+ if (typeof obj === 'string') {
1355
+ return obj;
1356
+ } // If it's an HTML element.
1357
+ else if (typeof obj.hasAttribute === 'function') {
1358
+ // If it's a modal open trigger, return data value.
1359
+ if (obj.hasAttribute("data-" + this.settings.dataOpen)) {
1360
+ return obj.getAttribute("data-" + this.settings.dataOpen);
1361
+ } // If it's a modal close trigger, return data value or false.
1362
+ else if (obj.hasAttribute("data-" + this.settings.dataClose)) {
1363
+ return obj.getAttribute("data-" + this.settings.dataClose) || false;
1364
+ } // If it's a modal replace trigger, return data value.
1365
+ else if (obj.hasAttribute("data-" + this.settings.dataReplace)) {
1366
+ return obj.getAttribute("data-" + this.settings.dataReplace);
1367
+ } // If it's a modal target, return the id.
1368
+ else if (obj.closest(this.settings.selectorModal)) {
1369
+ obj = obj.closest(this.settings.selectorModal);
1370
+ return obj.id || false;
1371
+ } // Return false if no id was found.
1372
+ else return false;
1373
+ } // If it has an id property, return its value.
1374
+ else if (obj.id) {
1375
+ return obj.id;
1376
+ } // Return false if no id was found.
1377
+ else return false;
1378
+ }
1379
+ function getModalElements(query) {
1380
+ var id = getModalID.call(this, query);
1381
+
1382
+ if (id) {
1383
+ var target = document.querySelector("#" + id);
1384
+ var dialog = target ? target.querySelector(this.settings.selectorDialog) : null;
1074
1385
 
1075
- var close$1 = function close(returnFocus) {
1076
- if (returnFocus === void 0) {
1077
- returnFocus = true;
1386
+ if (!target && !dialog) {
1387
+ return {
1388
+ error: new Error("No modal elements found using the ID: \"" + id + "\".")
1389
+ };
1390
+ } else if (!dialog) {
1391
+ return {
1392
+ error: new Error('Modal is missing dialog element.')
1393
+ };
1394
+ } else {
1395
+ return {
1396
+ target: target,
1397
+ dialog: dialog
1398
+ };
1399
+ }
1400
+ } else {
1401
+ return {
1402
+ error: new Error('Could not resolve the modal ID.')
1403
+ };
1078
1404
  }
1405
+ }
1079
1406
 
1407
+ var handleClick = function handleClick(event) {
1080
1408
  try {
1081
1409
  var _this2 = this;
1082
1410
 
1083
- var modal = document.querySelector("[data-" + _this2.settings.dataModal + "]." + _this2.settings.stateOpened);
1411
+ // If an open or replace button was clicked, open or replace the modal.
1412
+ var trigger = event.target.closest("[data-" + _this2.settings.dataOpen + "], [data-" + _this2.settings.dataReplace + "]");
1084
1413
 
1085
- if (modal) {
1086
- _this2.working = true;
1087
- var config = getModalConfig.call(_this2, modal);
1088
- setInert(false, config.selectorInert);
1089
- setOverflowHidden(false, config.selectorOverflow);
1090
- return Promise.resolve(closeTransition(modal, config)).then(function () {
1091
- if (returnFocus) focusTrigger(_this2);
1414
+ if (trigger) {
1415
+ event.preventDefault(); // Save the trigger if it's not coming from inside a modal.
1092
1416
 
1093
- _this2.focusTrap.destroy();
1417
+ var fromModal = event.target.closest(_this2.settings.selectorModal);
1418
+ if (!fromModal) _this2.memory.trigger = trigger; // Get the modal.
1094
1419
 
1095
- modal.dispatchEvent(new CustomEvent(config.customEventPrefix + 'closed', {
1096
- detail: _this2,
1097
- bubbles: true
1098
- }));
1099
- _this2.working = false;
1100
- return modal;
1101
- });
1102
- } else {
1103
- return Promise.resolve(modal);
1420
+ var modal = _this2.get(getModalID.call(_this2, trigger)); // Depending on the button type, either open or replace the modal.
1421
+
1422
+
1423
+ return Promise.resolve(trigger.matches("[data-" + _this2.settings.dataOpen + "]") ? modal.open() : modal.replace());
1424
+ } // If a close button was clicked, close the modal.
1425
+
1426
+
1427
+ trigger = event.target.closest("[data-" + _this2.settings.dataClose + "]");
1428
+
1429
+ if (trigger) {
1430
+ event.preventDefault(); // Get the value of the data attribute.
1431
+
1432
+ var value = trigger.getAttribute("data-" + _this2.settings.dataClose); // Close all if * wildcard is passed, otherwise close a single modal.
1433
+
1434
+ return Promise.resolve(value === '*' ? _this2.closeAll() : _this2.close(value));
1435
+ } // If the modal screen was clicked, close the modal.
1436
+
1437
+
1438
+ if (event.target.matches(_this2.settings.selectorModal) && !event.target.querySelector(_this2.settings.selectorRequired)) {
1439
+ return Promise.resolve(_this2.close(getModalID.call(_this2, event.target)));
1104
1440
  }
1441
+
1442
+ return Promise.resolve();
1105
1443
  } catch (e) {
1106
1444
  return Promise.reject(e);
1107
1445
  }
1108
1446
  };
1447
+ function handleKeydown(event) {
1448
+ // If escape key was pressed.
1449
+ if (event.key === 'Escape') {
1450
+ // If a modal is opened and not required, close the modal.
1451
+ if (this.active && !this.active.dialog.matches(this.settings.selectorRequired)) {
1452
+ return this.close();
1453
+ }
1454
+ }
1455
+ }
1456
+
1457
+ var deregister$1 = function deregister(obj, close) {
1458
+ if (close === void 0) {
1459
+ close = true;
1460
+ }
1109
1461
 
1110
- var handlerClick$1 = function handlerClick(event) {
1111
1462
  try {
1112
- var _temp3 = function _temp3(_result) {
1113
- if (_exit2) return _result;
1463
+ var _temp5 = function _temp5() {
1464
+ // Return the modified collection.
1465
+ return _this2.collection;
1466
+ };
1114
1467
 
1115
- // Close click
1116
- if (event.target.closest("[data-" + _this2.settings.dataClose + "]")) {
1117
- event.preventDefault();
1468
+ var _this2 = this;
1118
1469
 
1119
- _this2.close();
1470
+ // Return collection if nothing was passed.
1471
+ if (!obj) return Promise.resolve(_this2.collection); // Check if entry has been registered in the collection.
1120
1472
 
1121
- return;
1122
- } // Root click
1473
+ var index = _this2.collection.findIndex(function (entry) {
1474
+ return entry.id === obj.id;
1475
+ });
1476
+
1477
+ var _temp6 = function () {
1478
+ if (index >= 0) {
1479
+ var _temp7 = function _temp7() {
1480
+ // Return teleported modal if a reference has been set.
1481
+ if (_entry.getSetting('teleport')) {
1482
+ _entry.teleportReturn();
1483
+ } // Delete properties from collection entry.
1484
+
1485
+
1486
+ Object.getOwnPropertyNames(_entry).forEach(function (prop) {
1487
+ delete _entry[prop];
1488
+ }); // Remove entry from collection.
1489
+
1490
+ _this2.collection.splice(index, 1);
1491
+ };
1492
+
1493
+ // Get the collection entry.
1494
+ var _entry = _this2.collection[index]; // If entry is in the opened state, close it.
1495
+
1496
+ var _temp8 = function () {
1497
+ if (close && _entry.state === 'opened') {
1498
+ return Promise.resolve(_entry.close(false)).then(function () {});
1499
+ } else {
1500
+ // Get index of modal in stack array.
1501
+ var stackIndex = _this2.stack.findIndex(function (item) {
1502
+ return item.id === _entry.id;
1503
+ }); // Remove modal from stack array.
1123
1504
 
1124
1505
 
1125
- if (event.target.hasAttribute("data-" + _this2.settings.dataModal) && !event.target.hasAttribute("data-" + _this2.settings.dataRequired)) {
1126
- _this2.close();
1506
+ if (stackIndex >= 0) {
1507
+ _this2.stack.splice(stackIndex, 1);
1508
+ }
1509
+ }
1510
+ }();
1511
+
1512
+ return _temp8 && _temp8.then ? _temp8.then(_temp7) : _temp7(_temp8);
1127
1513
  }
1128
- };
1514
+ }();
1515
+
1516
+ return Promise.resolve(_temp6 && _temp6.then ? _temp6.then(_temp5) : _temp5(_temp6));
1517
+ } catch (e) {
1518
+ return Promise.reject(e);
1519
+ }
1520
+ };
1521
+
1522
+ var open$1 = function open(query, transition, bulk) {
1523
+ if (bulk === void 0) {
1524
+ bulk = false;
1525
+ }
1526
+
1527
+ try {
1528
+ var _temp3 = function _temp3() {
1529
+ // Update the focus state if this is not a bulk action.
1530
+ if (!bulk) {
1531
+ updateFocusState.call(_this2);
1532
+ } // Dispatch custom opened event.
1533
+
1534
+
1535
+ modal.target.dispatchEvent(new CustomEvent(config.customEventPrefix + 'opened', {
1536
+ detail: _this2,
1537
+ bubbles: true
1538
+ })); // Return the modal.
1129
1539
 
1130
- var _exit2;
1540
+ return modal;
1541
+ };
1131
1542
 
1132
1543
  var _this2 = this;
1133
1544
 
1134
- // Working catch
1135
- if (_this2.working) return Promise.resolve(); // Trigger click
1545
+ // Get the modal from collection.
1546
+ var modal = getModal.call(_this2, query); // Get the modal configuration.
1547
+
1548
+ var config = _extends({}, _this2.settings, modal.settings); // Add transition parameter to configuration.
1549
+
1550
+
1551
+ if (transition !== undefined) config.transition = transition; // Check if modal is already in the stack.
1552
+
1553
+ var index = _this2.stack.findIndex(function (entry) {
1554
+ return entry.id === modal.id;
1555
+ }); // If modal is already open.
1556
+
1557
+
1558
+ if (index >= 0) {
1559
+ // Remove modal from stack array.
1560
+ _this2.stack.splice(index, 1); // Move back to end of stack.
1561
+
1562
+
1563
+ _this2.stack.push(modal);
1564
+ } // If modal is closed.
1136
1565
 
1137
- var trigger = event.target.closest("[data-" + _this2.settings.dataOpen + "]");
1138
1566
 
1139
1567
  var _temp4 = function () {
1140
- if (trigger) {
1141
- event.preventDefault();
1142
- var modalKey = trigger.getAttribute("data-" + _this2.settings.dataOpen);
1143
- var fromModal = event.target.closest("[data-" + _this2.settings.dataModal + "]");
1144
- if (!fromModal) _this2.memory.trigger = trigger;
1145
- return Promise.resolve(_this2.close(!fromModal)).then(function () {
1146
- _this2.open(modalKey);
1568
+ if (modal.state === 'closed') {
1569
+ // Update modal state.
1570
+ modal.state = 'opening'; // Apply z-index styles based on stack length.
1571
+
1572
+ modal.target.style.zIndex = null;
1573
+ var value = getComputedStyle(modal.target)['z-index'];
1574
+ modal.target.style.zIndex = parseInt(value) + _this2.stack.length + 1; // Store modal in stack array.
1147
1575
 
1148
- _exit2 = 1;
1576
+ _this2.stack.push(modal); // Run the open transition.
1577
+
1578
+
1579
+ return Promise.resolve(openTransition(modal.target, config)).then(function () {
1580
+ // Update modal state.
1581
+ modal.state = 'opened';
1149
1582
  });
1150
1583
  }
1151
1584
  }();
@@ -1155,343 +1588,387 @@ var handlerClick$1 = function handlerClick(event) {
1155
1588
  return Promise.reject(e);
1156
1589
  }
1157
1590
  };
1158
- function handlerKeydown$1(event) {
1159
- // Working catch
1160
- if (this.working) return;
1161
-
1162
- if (event.key === 'Escape') {
1163
- var target = document.querySelector("[data-" + this.settings.dataModal + "]." + this.settings.stateOpened);
1164
1591
 
1165
- if (target && !target.hasAttribute("data-" + this.settings.dataRequired)) {
1166
- this.close();
1167
- }
1592
+ var close$1 = function close(query, transition, bulk) {
1593
+ if (bulk === void 0) {
1594
+ bulk = false;
1168
1595
  }
1169
- }
1170
1596
 
1171
- function setInitialState() {
1172
- var _this = this;
1597
+ try {
1598
+ var _this2 = this;
1173
1599
 
1174
- var modals = document.querySelectorAll("[data-" + this.settings.dataModal + "]");
1175
- modals.forEach(function (el) {
1176
- // Remove opened state setup
1177
- if (el.classList.contains(_this.settings.stateOpened)) {
1178
- setInert(false, _this.settings.selectorInert);
1179
- setOverflowHidden(false, _this.settings.selectorOverflow);
1180
- focusTrigger(_this);
1600
+ // Get the modal from collection, or top modal in stack if no query is provided.
1601
+ var modal = query ? getModal.call(_this2, query) : _this2.active; // If a modal exists and its state is opened.
1181
1602
 
1182
- _this.focusTrap.destroy();
1183
- } // Remove all state classes and add the default state (closed)
1603
+ var _temp2 = function () {
1604
+ if (modal && modal.state === 'opened') {
1605
+ // Update modal state.
1606
+ modal.state = 'closing'; // Get the modal configuration.
1184
1607
 
1608
+ var config = _extends({}, _this2.settings, modal.settings); // Add transition parameter to configuration.
1185
1609
 
1186
- removeClass(el, _this.settings.stateOpened, _this.settings.stateOpening, _this.settings.stateClosing);
1187
- addClass(el, _this.settings.stateClosed);
1188
- });
1189
- }
1190
1610
 
1191
- var open$1 = function open(modalKey) {
1192
- try {
1193
- var _this2 = this;
1611
+ if (transition !== undefined) config.transition = transition; // Remove focus from active element.
1194
1612
 
1195
- var modal = getModal.call(_this2, modalKey);
1196
- if (!modal) return Promise.resolve(modalNotFound(modalKey));
1197
- var config = getModalConfig.call(_this2, modal);
1613
+ document.activeElement.blur(); // Run the close transition.
1198
1614
 
1199
- if (hasClass(modal, config.stateClosed)) {
1200
- _this2.working = true;
1201
- setOverflowHidden(true, config.selectorOverflow);
1202
- return Promise.resolve(openTransition(modal, config)).then(function () {
1203
- _this2.focusTrap.init(modal);
1615
+ return Promise.resolve(closeTransition(modal.target, config)).then(function () {
1616
+ // Remove z-index styles.
1617
+ modal.target.style.zIndex = null; // Get index of modal in stack array.
1204
1618
 
1205
- focusTarget(modal, config);
1206
- setInert(true, config.selectorInert);
1207
- modal.dispatchEvent(new CustomEvent(config.customEventPrefix + 'opened', {
1208
- detail: _this2,
1209
- bubbles: true
1210
- }));
1211
- _this2.working = false;
1212
- return modal;
1213
- });
1214
- } else {
1215
- return Promise.resolve(modal);
1216
- }
1619
+ var index = _this2.stack.findIndex(function (entry) {
1620
+ return entry.id === modal.id;
1621
+ }); // Remove modal from stack array.
1622
+
1623
+
1624
+ _this2.stack.splice(index, 1); // Update the focus state if this is not a bulk action.
1625
+
1626
+
1627
+ if (!bulk) {
1628
+ updateFocusState.call(_this2);
1629
+ } // Update modal state.
1630
+
1631
+
1632
+ modal.state = 'closed'; // Dispatch custom closed event.
1633
+
1634
+ modal.target.dispatchEvent(new CustomEvent(config.customEventPrefix + 'closed', {
1635
+ detail: _this2,
1636
+ bubbles: true
1637
+ }));
1638
+ });
1639
+ }
1640
+ }();
1641
+
1642
+ return Promise.resolve(_temp2 && _temp2.then ? _temp2.then(function () {
1643
+ // Return the modal.
1644
+ return modal;
1645
+ }) : modal);
1217
1646
  } catch (e) {
1218
1647
  return Promise.reject(e);
1219
1648
  }
1220
1649
  };
1221
1650
 
1222
- var Modal = /*#__PURE__*/function () {
1223
- function Modal(options) {
1224
- this.defaults = defaults$1;
1225
- this.settings = _extends({}, this.defaults, options);
1226
- this.working = false;
1227
- this.memory = {};
1228
- this.focusTrap = new FocusTrap();
1229
- this.__handlerClick = handlerClick$1.bind(this);
1230
- this.__handlerKeydown = handlerKeydown$1.bind(this);
1231
- if (this.settings.autoInit) this.init();
1232
- }
1651
+ var closeAll$1 = function closeAll(exclude, transition) {
1652
+ try {
1653
+ var _this2 = this;
1233
1654
 
1234
- var _proto = Modal.prototype;
1655
+ var result = [];
1656
+ return Promise.resolve(Promise.all(_this2.stack.map(function (modal) {
1657
+ try {
1658
+ var _temp3 = function _temp3() {
1659
+ modal.trigger = null;
1660
+ };
1661
+
1662
+ var _temp4 = function () {
1663
+ if (exclude && exclude === modal.id) {
1664
+ Promise.resolve();
1665
+ } else {
1666
+ var _push2 = result.push;
1667
+ return Promise.resolve(close$1.call(_this2, modal, transition, true)).then(function (_close$call) {
1668
+ _push2.call(result, _close$call);
1669
+ });
1670
+ }
1671
+ }();
1235
1672
 
1236
- _proto.init = function init(options) {
1237
- if (options === void 0) {
1238
- options = null;
1239
- }
1673
+ return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(_temp3) : _temp3(_temp4));
1674
+ } catch (e) {
1675
+ return Promise.reject(e);
1676
+ }
1677
+ }))).then(function () {
1678
+ return result;
1679
+ });
1680
+ } catch (e) {
1681
+ return Promise.reject(e);
1682
+ }
1683
+ };
1240
1684
 
1241
- if (options) this.settings = _extends({}, this.settings, options);
1242
- this.moveModals();
1243
- this.setInitialState();
1685
+ var replace = function replace(query, transition) {
1686
+ try {
1687
+ var _temp3 = function _temp3() {
1688
+ // Update the focus state.
1689
+ updateFocusState.call(_this2); // Return the modals there were opened and closed.
1244
1690
 
1245
- if (this.settings.setTabindex) {
1246
- this.setTabindex();
1247
- }
1691
+ return {
1692
+ opened: resultOpened,
1693
+ closed: resultClosed
1694
+ };
1695
+ };
1248
1696
 
1249
- if (this.settings.eventListeners) {
1250
- this.initEventListeners();
1251
- }
1252
- };
1697
+ var _this2 = this;
1253
1698
 
1254
- _proto.destroy = function destroy() {
1255
- this.memory = {};
1699
+ // Get the modal from collection.
1700
+ var modal = getModal.call(_this2, query); // Setup results for return.
1256
1701
 
1257
- if (this.settings.eventListeners) {
1258
- this.destroyEventListeners();
1259
- }
1260
- }
1261
- /**
1262
- * Event listeners
1263
- */
1264
- ;
1702
+ var resultOpened, resultClosed;
1265
1703
 
1266
- _proto.initEventListeners = function initEventListeners() {
1267
- document.addEventListener('click', this.__handlerClick, false);
1268
- document.addEventListener('touchend', this.__handlerClick, false);
1269
- document.addEventListener('keydown', this.__handlerKeydown, false);
1270
- };
1704
+ var _temp4 = function () {
1705
+ if (modal.state === 'opened') {
1706
+ // If modal is open, close all modals except for replacement.
1707
+ resultOpened = modal;
1708
+ return Promise.resolve(closeAll$1.call(_this2, modal.id, transition)).then(function (_closeAll$call) {
1709
+ resultClosed = _closeAll$call;
1710
+ });
1711
+ } else {
1712
+ // If modal is closed, close all and open replacement at the same time.
1713
+ resultOpened = open$1.call(_this2, modal, transition, true);
1714
+ resultClosed = closeAll$1.call(_this2, false, transition);
1715
+ return Promise.resolve(Promise.all([resultOpened, resultClosed])).then(function () {});
1716
+ }
1717
+ }();
1271
1718
 
1272
- _proto.destroyEventListeners = function destroyEventListeners() {
1273
- document.removeEventListener('click', this.__handlerClick, false);
1274
- document.removeEventListener('touchend', this.__handlerClick, false);
1275
- document.removeEventListener('keydown', this.__handlerKeydown, false);
1719
+ return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(_temp3) : _temp3(_temp4));
1720
+ } catch (e) {
1721
+ return Promise.reject(e);
1276
1722
  }
1277
- /**
1278
- * Helpers
1279
- */
1280
- ;
1723
+ };
1281
1724
 
1282
- _proto.getModal = function getModal$1(modalKey) {
1283
- return getModal.call(this, modalKey);
1284
- };
1725
+ var register$1 = function register(target, dialog) {
1726
+ try {
1727
+ var _this2 = this;
1285
1728
 
1286
- _proto.setTabindex = function setTabindex$1() {
1287
- return setTabindex("\n [data-" + this.settings.dataModal + "]\n [data-" + this.settings.dataDialog + "]\n ");
1288
- };
1729
+ // Deregister entry incase it has already been registered.
1730
+ return Promise.resolve(deregister$1.call(_this2, target, false)).then(function () {
1731
+ // Save root this for use inside methods API.
1732
+ var root = _this2; // Setup methods API.
1733
+
1734
+ var methods = {
1735
+ open: function open(transition) {
1736
+ return open$1.call(root, this, transition);
1737
+ },
1738
+ close: function close(transition) {
1739
+ return close$1.call(root, this, transition);
1740
+ },
1741
+ replace: function replace$1(transition) {
1742
+ return replace.call(root, this, transition);
1743
+ },
1744
+ deregister: function deregister() {
1745
+ return deregister$1.call(root, this);
1746
+ },
1747
+ teleport: function teleport$1(ref, method) {
1748
+ if (ref === void 0) {
1749
+ ref = this.getSetting('teleport');
1750
+ }
1289
1751
 
1290
- _proto.setInitialState = function setInitialState$1() {
1291
- return setInitialState.call(this);
1292
- };
1752
+ if (method === void 0) {
1753
+ method = this.getSetting('teleportMethod');
1754
+ }
1293
1755
 
1294
- _proto.moveModals = function moveModals$1(type, ref) {
1295
- return moveModals.call(this, type, ref);
1296
- }
1297
- /**
1298
- * Change state functionality
1299
- */
1300
- ;
1756
+ if (!this.returnRef) {
1757
+ this.returnRef = teleport(this.target, ref, method);
1758
+ return this.target;
1759
+ } else {
1760
+ console.error('Element has already been teleported:', this.target);
1761
+ return false;
1762
+ }
1763
+ },
1764
+ teleportReturn: function teleportReturn() {
1765
+ if (this.returnRef) {
1766
+ this.returnRef = teleport(this.target, this.returnRef);
1767
+ return this.target;
1768
+ } else {
1769
+ console.error('No return reference found:', this.target);
1770
+ return false;
1771
+ }
1772
+ },
1773
+ getSetting: function getSetting(key) {
1774
+ return key in this.settings ? this.settings[key] : root.settings[key];
1775
+ }
1776
+ }; // Setup the modal object.
1301
1777
 
1302
- _proto.open = function open(modalKey) {
1303
- return open$1.call(this, modalKey);
1304
- };
1778
+ var entry = _extends({
1779
+ id: target.id,
1780
+ state: 'closed',
1781
+ settings: getConfig$1.call(_this2, target),
1782
+ target: target,
1783
+ dialog: dialog,
1784
+ returnRef: null
1785
+ }, methods); // Set aria-modal attribute to true.
1305
1786
 
1306
- _proto.close = function close(returnFocus) {
1307
- return close$1.call(this, returnFocus);
1308
- };
1309
1787
 
1310
- return Modal;
1311
- }();
1788
+ entry.dialog.setAttribute('aria-modal', 'true'); // If a role attribute is not set, set it to "dialog" as the default.
1312
1789
 
1313
- var Collection = /*#__PURE__*/function () {
1314
- function Collection() {
1315
- this.collection = [];
1316
- }
1790
+ if (!entry.dialog.hasAttribute('role')) {
1791
+ entry.dialog.setAttribute('role', 'dialog');
1792
+ } // Set tabindex="-1" so dialog is focusable via JS or click.
1317
1793
 
1318
- var _proto = Collection.prototype;
1319
1794
 
1320
- _proto.register = function register(item) {
1321
- this.deregister(item);
1322
- this.collection.push(item);
1323
- return this.collection;
1324
- };
1795
+ if (entry.getSetting('setTabindex')) {
1796
+ entry.dialog.setAttribute('tabindex', '-1');
1797
+ } // Teleport modal if a reference has been set.
1325
1798
 
1326
- _proto.deregister = function deregister(ref) {
1327
- var index = this.collection.findIndex(function (entry) {
1328
- return entry === ref;
1329
- });
1330
1799
 
1331
- if (index >= 0) {
1332
- var entry = this.collection[index];
1333
- Object.getOwnPropertyNames(entry).forEach(function (prop) {
1334
- delete entry[prop];
1335
- });
1336
- this.collection.splice(index, 1);
1337
- }
1800
+ if (entry.getSetting('teleport')) {
1801
+ entry.teleport();
1802
+ } // Add entry to collection.
1338
1803
 
1339
- return this.collection;
1340
- };
1341
1804
 
1342
- _proto.registerCollection = function registerCollection(items) {
1343
- var _this = this;
1805
+ _this2.collection.push(entry); // Setup initial state.
1344
1806
 
1345
- items.forEach(function (item) {
1346
- _this.register(item);
1347
- });
1348
- return this.collection;
1349
- };
1350
1807
 
1351
- _proto.deregisterCollection = function deregisterCollection() {
1352
- while (this.collection.length > 0) {
1353
- this.deregister(this.collection[0]);
1354
- }
1808
+ if (entry.target.classList.contains(_this2.settings.stateOpened)) {
1809
+ // Open modal with transitions disabled.
1810
+ entry.open(false);
1811
+ } else {
1812
+ // Remove transition state classes.
1813
+ entry.target.classList.remove(_this2.settings.stateOpening);
1814
+ entry.target.classList.remove(_this2.settings.stateClosing); // Add closed state class.
1355
1815
 
1356
- return this.collection;
1357
- };
1816
+ entry.target.classList.add(_this2.settings.stateClosed);
1817
+ } // Return the registered entry.
1358
1818
 
1359
- _proto.get = function get(query, key) {
1360
- if (key === void 0) {
1361
- key = 'id';
1362
- }
1363
1819
 
1364
- var result = this.collection.find(function (item) {
1365
- return item[key] === query;
1820
+ return entry;
1366
1821
  });
1367
- return result || null;
1368
- };
1822
+ } catch (e) {
1823
+ return Promise.reject(e);
1824
+ }
1825
+ };
1369
1826
 
1370
- return Collection;
1371
- }();
1827
+ var Modal = /*#__PURE__*/function (_Collection) {
1828
+ _inheritsLoose(Modal, _Collection);
1372
1829
 
1373
- var defaults = {
1374
- autoInit: false,
1375
- // Selectors
1376
- selectorPopover: '.popover',
1377
- selectorArrow: '.popover__arrow',
1378
- // State classes
1379
- stateActive: 'is-active',
1380
- // Feature toggles
1381
- eventListeners: true,
1382
- eventType: 'click',
1383
- placement: 'bottom'
1384
- };
1830
+ function Modal(options) {
1831
+ var _this;
1832
+
1833
+ _this = _Collection.call(this) || this;
1834
+ _this.defaults = defaults$1;
1835
+ _this.settings = _extends({}, _this.defaults, options);
1836
+ _this.memory = {};
1837
+ _this.focusTrap = new FocusTrap(); // Setup a proxy for stack array.
1385
1838
 
1386
- function close(popover) {
1387
- // Update state class
1388
- popover.target.classList.remove(this.settings.stateActive); // Update a11y attributes
1839
+ _this.stack = new Proxy([], {
1840
+ set: function set(target, property, value) {
1841
+ target[property] = value; // Update global state whenever the length property of stack changes.
1389
1842
 
1390
- if (popover.trigger.hasAttribute('aria-controls')) {
1391
- popover.trigger.setAttribute('aria-expanded', 'false');
1392
- } // Disable popper event listeners
1843
+ if (property === 'length') {
1844
+ updateGlobalState.call(_assertThisInitialized(_this));
1845
+ }
1393
1846
 
1847
+ return true;
1848
+ }
1849
+ });
1850
+ _this.__handleClick = handleClick.bind(_assertThisInitialized(_this));
1851
+ _this.__handleKeydown = handleKeydown.bind(_assertThisInitialized(_this));
1852
+ if (_this.settings.autoInit) _this.init();
1853
+ return _this;
1854
+ }
1394
1855
 
1395
- popover.popper.setOptions({
1396
- modifiers: [{
1397
- name: 'eventListeners',
1398
- enabled: false
1399
- }]
1400
- }); // Update popover state
1856
+ var _proto = Modal.prototype;
1401
1857
 
1402
- popover.state = 'closed'; // Clear memory if popover trigger matches the one saved in memory
1858
+ _proto.init = function init(options) {
1859
+ try {
1860
+ var _this3 = this;
1403
1861
 
1404
- if (popover.trigger === this.memory.trigger) {
1405
- this.memory.trigger = null;
1406
- } // Return the popover
1862
+ // Update settings with passed options.
1863
+ if (options) _this3.settings = _extends({}, _this3.settings, options); // Get all the modals.
1407
1864
 
1865
+ var modals = document.querySelectorAll(_this3.settings.selectorModal); // Register the collections array with modal instances.
1408
1866
 
1409
- return popover;
1410
- }
1411
- function closeAll() {
1412
- this.collection.forEach(function (popover) {
1413
- if (popover.state === 'opened') {
1414
- popover.close();
1867
+ return Promise.resolve(_this3.registerCollection(modals)).then(function () {
1868
+ if (_this3.settings.eventListeners) {
1869
+ _this3.initEventListeners();
1870
+ }
1871
+ }); // If eventListeners are enabled, init event listeners.
1872
+ } catch (e) {
1873
+ return Promise.reject(e);
1415
1874
  }
1416
- }); // Return the collection
1875
+ };
1417
1876
 
1418
- return this.collection;
1419
- }
1420
- function closeCheck(popover) {
1421
- // Only run closeCheck if provided popover is currently open
1422
- if (popover.state != 'opened') return; // Needed to correctly check which element is currently being focused
1877
+ _proto.destroy = function destroy() {
1878
+ try {
1879
+ var _this5 = this;
1423
1880
 
1424
- setTimeout(function () {
1425
- // Check if trigger or target are being hovered
1426
- var isHovered = popover.target.closest(':hover') === popover.target || popover.trigger.closest(':hover') === popover.trigger; // Check if trigger or target are being focused
1881
+ // Clear any stored memory.
1882
+ _this5.memory = {}; // Remove all entries from the collection.
1427
1883
 
1428
- var isFocused = document.activeElement.closest("#" + popover.id + ", [aria-controls=\"" + popover.id + "\"]"); // Close if the trigger and target are not currently hovered or focused
1884
+ return Promise.resolve(_this5.deregisterCollection()).then(function () {
1885
+ if (_this5.settings.eventListeners) {
1886
+ _this5.destroyEventListeners();
1887
+ }
1888
+ }); // If eventListeners are enabled, destroy event listeners.
1889
+ } catch (e) {
1890
+ return Promise.reject(e);
1891
+ }
1892
+ };
1429
1893
 
1430
- if (!isHovered && !isFocused) {
1431
- popover.close();
1432
- } // Return the popover
1894
+ _proto.initEventListeners = function initEventListeners() {
1895
+ document.addEventListener('click', this.__handleClick, false);
1896
+ document.addEventListener('touchend', this.__handleClick, false);
1897
+ document.addEventListener('keydown', this.__handleKeydown, false);
1898
+ };
1433
1899
 
1900
+ _proto.destroyEventListeners = function destroyEventListeners() {
1901
+ document.removeEventListener('click', this.__handleClick, false);
1902
+ document.removeEventListener('touchend', this.__handleClick, false);
1903
+ document.removeEventListener('keydown', this.__handleKeydown, false);
1904
+ };
1434
1905
 
1435
- return popover;
1436
- }, 1);
1437
- }
1906
+ _proto.register = function register(query) {
1907
+ var els = getModalElements.call(this, query);
1908
+ if (els.error) return Promise.reject(els.error);
1909
+ return register$1.call(this, els.target, els.dialog);
1910
+ };
1438
1911
 
1439
- function handlerClick(popover) {
1440
- if (popover.target.classList.contains(this.settings.stateActive)) {
1441
- popover.close();
1442
- } else {
1443
- this.memory.trigger = popover.trigger;
1444
- popover.open();
1445
- documentClick.call(this, popover);
1446
- }
1447
- }
1448
- function handlerKeydown(event) {
1449
- var _this = this;
1912
+ _proto.deregister = function deregister(query) {
1913
+ var modal = this.get(getModalID.call(this, query));
1914
+ return deregister$1.call(this, modal);
1915
+ };
1916
+
1917
+ _proto.open = function open(id, transition) {
1918
+ return open$1.call(this, id, transition);
1919
+ };
1450
1920
 
1451
- switch (event.key) {
1452
- case 'Escape':
1453
- if (this.memory.trigger) {
1454
- this.memory.trigger.focus();
1455
- }
1921
+ _proto.close = function close(id, transition) {
1922
+ return close$1.call(this, id, transition);
1923
+ };
1456
1924
 
1457
- closeAll.call(this);
1458
- return;
1925
+ _proto.replace = function replace$1(id, transition) {
1926
+ return replace.call(this, id, transition);
1927
+ };
1459
1928
 
1460
- case 'Tab':
1461
- this.collection.forEach(function (popover) {
1462
- closeCheck.call(_this, popover);
1463
- });
1464
- return;
1929
+ _proto.closeAll = function closeAll(exclude, transition) {
1930
+ if (exclude === void 0) {
1931
+ exclude = false;
1932
+ }
1465
1933
 
1466
- default:
1467
- return;
1468
- }
1469
- }
1470
- function documentClick(popover) {
1471
- var root = this;
1472
- document.addEventListener('click', function _f(event) {
1473
- // Check if a popover was clicked
1474
- var result = event.target.closest("#" + popover.id + ", [aria-controls=\"" + popover.id + "\"]");
1934
+ try {
1935
+ var _this7 = this;
1475
1936
 
1476
- if (!result) {
1477
- // If it doesn't match and popover is open, close it and remove event listener
1478
- if (popover.target && popover.target.classList.contains(root.settings.stateActive)) {
1479
- popover.close();
1480
- }
1937
+ return Promise.resolve(closeAll$1.call(_this7, exclude, transition)).then(function (result) {
1938
+ updateFocusState.call(_this7);
1939
+ return result;
1940
+ });
1941
+ } catch (e) {
1942
+ return Promise.reject(e);
1943
+ }
1944
+ };
1481
1945
 
1482
- this.removeEventListener('click', _f);
1483
- } else {
1484
- // If it does match and popover isn't currently active, remove event listener
1485
- if (popover.target && !popover.target.classList.contains(root.settings.stateActive)) {
1486
- this.removeEventListener('click', _f);
1487
- }
1946
+ _createClass(Modal, [{
1947
+ key: "active",
1948
+ get: function get() {
1949
+ return this.stack[this.stack.length - 1];
1488
1950
  }
1489
- });
1490
- }
1951
+ }]);
1952
+
1953
+ return Modal;
1954
+ }(Collection);
1955
+
1956
+ var defaults = {
1957
+ autoInit: false,
1958
+ // Selectors
1959
+ selectorPopover: '.popover',
1960
+ selectorArrow: '.popover__arrow',
1961
+ // State classes
1962
+ stateActive: 'is-active',
1963
+ // Feature settings
1964
+ eventListeners: true,
1965
+ eventType: 'click',
1966
+ placement: 'bottom'
1967
+ };
1491
1968
 
1492
1969
  function getConfig(el, settings) {
1493
- // Get the computed styles of the popover
1494
- var styles = getComputedStyle(el); // Setup the config obj with default values
1970
+ // Get the computed styles of the element.
1971
+ var styles = getComputedStyle(el); // Setup the config obj with default values.
1495
1972
 
1496
1973
  var config = {
1497
1974
  'placement': settings.placement,
@@ -1501,29 +1978,29 @@ function getConfig(el, settings) {
1501
1978
  'flip-padding': 0,
1502
1979
  'arrow-element': settings.selectorArrow,
1503
1980
  'arrow-padding': 0
1504
- }; // Loop through config obj
1981
+ }; // Loop through config obj.
1505
1982
 
1506
1983
  for (var prop in config) {
1507
- // Get the CSS variable property values
1984
+ // Get the CSS variable property values.
1508
1985
  var prefix = getComputedStyle(document.body).getPropertyValue('--vrembem-variable-prefix');
1509
- var value = styles.getPropertyValue("--" + prefix + "popover-" + prop).trim(); // If a value was found, replace the default in config obj
1986
+ var value = styles.getPropertyValue("--" + prefix + "popover-" + prop).trim(); // If a value was found, replace the default in config obj.
1510
1987
 
1511
1988
  if (value) {
1512
1989
  config[prop] = value;
1513
1990
  }
1514
- } // Return the config obj
1991
+ } // Return the config obj.
1515
1992
 
1516
1993
 
1517
1994
  return config;
1518
1995
  }
1519
1996
  function getPadding(value) {
1520
- var padding; // Split the value by spaces if it's a string
1997
+ var padding; // Split the value by spaces if it's a string.
1521
1998
 
1522
- var array = typeof value === 'string' ? value.trim().split(' ') : [value]; // Convert individual values to integers
1999
+ var array = typeof value === 'string' ? value.trim().split(' ') : [value]; // Convert individual values to integers.
1523
2000
 
1524
2001
  array.forEach(function (item, index) {
1525
2002
  array[index] = parseInt(item, 10);
1526
- }); // Build the padding object based on the number of values passed
2003
+ }); // Build the padding object based on the number of values passed.
1527
2004
 
1528
2005
  switch (array.length) {
1529
2006
  case 1:
@@ -1560,7 +2037,7 @@ function getPadding(value) {
1560
2037
  default:
1561
2038
  padding = false;
1562
2039
  break;
1563
- } // Return the padding object
2040
+ } // Return the padding object.
1564
2041
 
1565
2042
 
1566
2043
  return padding;
@@ -1589,27 +2066,38 @@ function getModifiers(options) {
1589
2066
  }
1590
2067
  }];
1591
2068
  }
2069
+ function getPopover(query) {
2070
+ // Get the entry from collection.
2071
+ var entry = typeof query === 'string' ? this.get(query) : this.get(query.id); // Return entry if it was resolved, otherwise throw error.
2072
+
2073
+ if (entry) {
2074
+ return entry;
2075
+ } else {
2076
+ throw new Error("Popover not found in collection with id of \"" + query + "\".");
2077
+ }
2078
+ }
1592
2079
  function getPopoverID(obj) {
1593
- // If it's a string
2080
+ // If it's a string, return the string.
1594
2081
  if (typeof obj === 'string') {
1595
2082
  return obj;
1596
- } // If it's an HTML element
2083
+ } // If it's an HTML element.
1597
2084
  else if (typeof obj.hasAttribute === 'function') {
1598
- // If it's a popover trigger
1599
- if (obj.hasAttribute('aria-controls')) {
2085
+ // If it's a popover target, return the id.
2086
+ if (obj.closest(this.settings.selectorPopover)) {
2087
+ obj = obj.closest(this.settings.selectorPopover);
2088
+ return obj.id;
2089
+ } // If it's a popover trigger, return value of aria-controls.
2090
+ else if (obj.hasAttribute('aria-controls')) {
1600
2091
  return obj.getAttribute('aria-controls');
1601
- } // If it's a popover tooltip trigger
2092
+ } // If it's a popover tooltip trigger, return the value of aria-describedby.
1602
2093
  else if (obj.hasAttribute('aria-describedby')) {
1603
2094
  return obj.getAttribute('aria-describedby');
1604
- } // If it's a popover target
1605
- else if (obj.closest(this.settings.selectorPopover)) {
1606
- return obj.id;
1607
- } // Return false if no id was found
2095
+ } // Return false if no id was found.
1608
2096
  else return false;
1609
- } // If it has an ID property
2097
+ } // If it has an id property, return its value.
1610
2098
  else if (obj.id) {
1611
2099
  return obj.id;
1612
- } // Return false if no id was found
2100
+ } // Return false if no id was found.
1613
2101
  else return false;
1614
2102
  }
1615
2103
  function getPopoverElements(query) {
@@ -1620,15 +2108,17 @@ function getPopoverElements(query) {
1620
2108
  var target = document.querySelector("#" + id);
1621
2109
 
1622
2110
  if (!trigger && !target) {
1623
- console.error('No popover elements found using the provided ID:', id);
2111
+ return {
2112
+ error: new Error("No popover elements found using the ID: \"" + id + "\".")
2113
+ };
1624
2114
  } else if (!trigger) {
1625
- console.error('No popover trigger associated with the provided popover:', target);
2115
+ return {
2116
+ error: new Error('No popover trigger associated with the provided popover.')
2117
+ };
1626
2118
  } else if (!target) {
1627
- console.error('No popover associated with the provided popover trigger:', trigger);
1628
- }
1629
-
1630
- if (!trigger || !target) {
1631
- return false;
2119
+ return {
2120
+ error: new Error('No popover associated with the provided popover trigger.')
2121
+ };
1632
2122
  } else {
1633
2123
  return {
1634
2124
  trigger: trigger,
@@ -1636,10 +2126,149 @@ function getPopoverElements(query) {
1636
2126
  };
1637
2127
  }
1638
2128
  } else {
1639
- console.error('Could not resolve the popover ID:', query);
1640
- return false;
2129
+ return {
2130
+ error: new Error('Could not resolve the popover ID.')
2131
+ };
2132
+ }
2133
+ }
2134
+
2135
+ var closeAll = function closeAll() {
2136
+ try {
2137
+ var _this4 = this;
2138
+
2139
+ var result = [];
2140
+ return Promise.resolve(Promise.all(_this4.collection.map(function (popover) {
2141
+ try {
2142
+ var _temp4 = function () {
2143
+ if (popover.state === 'opened') {
2144
+ var _push2 = result.push;
2145
+ return Promise.resolve(close.call(_this4, popover)).then(function (_close$call) {
2146
+ _push2.call(result, _close$call);
2147
+ });
2148
+ }
2149
+ }();
2150
+
2151
+ return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(function () {}) : void 0);
2152
+ } catch (e) {
2153
+ return Promise.reject(e);
2154
+ }
2155
+ }))).then(function () {
2156
+ return result;
2157
+ });
2158
+ } catch (e) {
2159
+ return Promise.reject(e);
2160
+ }
2161
+ };
2162
+ var close = function close(query) {
2163
+ try {
2164
+ var _temp2 = function _temp2(popover) {
2165
+ // If a modal exists and its state is opened.
2166
+ if (popover && popover.state === 'opened') {
2167
+ // Update state class.
2168
+ popover.target.classList.remove(_this2.settings.stateActive); // Update accessibility attribute(s).
2169
+
2170
+ if (popover.trigger.hasAttribute('aria-controls')) {
2171
+ popover.trigger.setAttribute('aria-expanded', 'false');
2172
+ } // Disable popper event listeners.
2173
+
2174
+
2175
+ popover.popper.setOptions({
2176
+ modifiers: [{
2177
+ name: 'eventListeners',
2178
+ enabled: false
2179
+ }]
2180
+ }); // Update popover state.
2181
+
2182
+ popover.state = 'closed'; // Clear memory if popover trigger matches the one saved in memory.
2183
+
2184
+ if (popover.trigger === _this2.memory.trigger) {
2185
+ _this2.memory.trigger = null;
2186
+ }
2187
+ } // Return the popover.
2188
+
2189
+
2190
+ return popover;
2191
+ };
2192
+
2193
+ var _this2 = this;
2194
+
2195
+ // Get the popover from collection.
2196
+ return Promise.resolve(query ? _temp2(getPopover.call(_this2, query)) : Promise.resolve(closeAll.call(_this2)).then(_temp2));
2197
+ } catch (e) {
2198
+ return Promise.reject(e);
2199
+ }
2200
+ };
2201
+ function closeCheck(popover) {
2202
+ // Only run closeCheck if provided popover is currently open.
2203
+ if (popover.state != 'opened') return; // Needed to correctly check which element is currently being focused.
2204
+
2205
+ setTimeout(function () {
2206
+ // Check if trigger or target are being hovered.
2207
+ var isHovered = popover.target.closest(':hover') === popover.target || popover.trigger.closest(':hover') === popover.trigger; // Check if trigger or target are being focused.
2208
+
2209
+ var isFocused = document.activeElement.closest("#" + popover.id + ", [aria-controls=\"" + popover.id + "\"]"); // Close if the trigger and target are not currently hovered or focused.
2210
+
2211
+ if (!isHovered && !isFocused) {
2212
+ popover.close();
2213
+ } // Return the popover.
2214
+
2215
+
2216
+ return popover;
2217
+ }, 1);
2218
+ }
2219
+
2220
+ function handlerClick(popover) {
2221
+ if (popover.state === 'opened') {
2222
+ popover.close();
2223
+ } else {
2224
+ this.memory.trigger = popover.trigger;
2225
+ popover.open();
2226
+ documentClick.call(this, popover);
2227
+ }
2228
+ }
2229
+ function handlerKeydown(event) {
2230
+ var _this = this;
2231
+
2232
+ switch (event.key) {
2233
+ case 'Escape':
2234
+ if (this.memory.trigger) {
2235
+ this.memory.trigger.focus();
2236
+ }
2237
+
2238
+ closeAll.call(this);
2239
+ return;
2240
+
2241
+ case 'Tab':
2242
+ this.collection.forEach(function (popover) {
2243
+ closeCheck.call(_this, popover);
2244
+ });
2245
+ return;
2246
+
2247
+ default:
2248
+ return;
1641
2249
  }
1642
2250
  }
2251
+ function documentClick(popover) {
2252
+ var root = this;
2253
+ document.addEventListener('click', function _f(event) {
2254
+ // Check if a popover was clicked.
2255
+ var result = event.target.closest("#" + popover.id + ", [aria-controls=\"" + popover.id + "\"]");
2256
+
2257
+ if (!result) {
2258
+ // If it doesn't match and popover is open, close it and remove event listener.
2259
+ if (popover.target && popover.target.classList.contains(root.settings.stateActive)) {
2260
+ popover.close();
2261
+ }
2262
+
2263
+ this.removeEventListener('click', _f);
2264
+ } else {
2265
+ // If it does match and popover isn't currently active, remove event listener.
2266
+ if (popover.target && !popover.target.classList.contains(root.settings.stateActive)) {
2267
+ this.removeEventListener('click', _f);
2268
+ }
2269
+ }
2270
+ });
2271
+ }
1643
2272
 
1644
2273
  var top = 'top';
1645
2274
  var bottom = 'bottom';
@@ -1941,6 +2570,10 @@ function getContainingBlock(element) {
1941
2570
 
1942
2571
  var currentNode = getParentNode(element);
1943
2572
 
2573
+ if (isShadowRoot(currentNode)) {
2574
+ currentNode = currentNode.host;
2575
+ }
2576
+
1944
2577
  while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {
1945
2578
  var css = getComputedStyle$1(currentNode); // This is non-exhaustive but covers the most common CSS properties that
1946
2579
  // create a containing block.
@@ -2164,7 +2797,7 @@ function mapToStyles(_ref2) {
2164
2797
 
2165
2798
  if (placement === top || (placement === left || placement === right) && variation === end) {
2166
2799
  sideY = bottom;
2167
- var offsetY = isFixed && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]
2800
+ var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]
2168
2801
  offsetParent[heightProp];
2169
2802
  y -= offsetY - popperRect.height;
2170
2803
  y *= gpuAcceleration ? 1 : -1;
@@ -2172,7 +2805,7 @@ function mapToStyles(_ref2) {
2172
2805
 
2173
2806
  if (placement === left || (placement === top || placement === bottom) && variation === end) {
2174
2807
  sideX = right;
2175
- var offsetX = isFixed && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]
2808
+ var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]
2176
2809
  offsetParent[widthProp];
2177
2810
  x -= offsetX - popperRect.width;
2178
2811
  x *= gpuAcceleration ? 1 : -1;
@@ -3424,169 +4057,201 @@ var createPopper = /*#__PURE__*/popperGenerator({
3424
4057
  defaultModifiers: defaultModifiers
3425
4058
  }); // eslint-disable-next-line import/no-unused-modules
3426
4059
 
3427
- function open(popover) {
3428
- // Update state class
3429
- popover.target.classList.add(this.settings.stateActive); // Update a11y attribute
4060
+ var deregister = function deregister(obj) {
4061
+ try {
4062
+ var _this2 = this;
4063
+
4064
+ // Return collection if nothing was passed.
4065
+ if (!obj) return Promise.resolve(_this2.collection); // Check if entry has been registered in the collection.
4066
+
4067
+ var index = _this2.collection.findIndex(function (entry) {
4068
+ return entry.id === obj.id;
4069
+ });
4070
+
4071
+ if (index >= 0) {
4072
+ // Get the collection entry.
4073
+ var entry = _this2.collection[index]; // If entry is in the opened state, close it.
4074
+
4075
+ if (entry.state === 'opened') {
4076
+ entry.close();
4077
+ } // Clean up the popper instance.
3430
4078
 
3431
- if (popover.trigger.hasAttribute('aria-controls')) {
3432
- popover.trigger.setAttribute('aria-expanded', 'true');
3433
- } // Update popover config
3434
4079
 
4080
+ entry.popper.destroy(); // Remove event listeners.
3435
4081
 
3436
- popover.config = getConfig(popover.target, this.settings); // Enable popper event listeners and set placement/modifiers
4082
+ deregisterEventListeners(entry); // Delete properties from collection entry.
4083
+
4084
+ Object.getOwnPropertyNames(entry).forEach(function (prop) {
4085
+ delete entry[prop];
4086
+ }); // Remove entry from collection.
4087
+
4088
+ _this2.collection.splice(index, 1);
4089
+ } // Return the modified collection.
4090
+
4091
+
4092
+ return Promise.resolve(_this2.collection);
4093
+ } catch (e) {
4094
+ return Promise.reject(e);
4095
+ }
4096
+ };
4097
+ function deregisterEventListeners(entry) {
4098
+ // If event listeners have been setup.
4099
+ if (entry.__eventListeners) {
4100
+ // Loop through listeners and remove from the appropriate elements.
4101
+ entry.__eventListeners.forEach(function (evObj) {
4102
+ evObj.el.forEach(function (el) {
4103
+ evObj.type.forEach(function (type) {
4104
+ entry[el].removeEventListener(type, evObj.listener, false);
4105
+ });
4106
+ });
4107
+ }); // Remove eventListeners object from collection.
3437
4108
 
3438
- popover.popper.setOptions({
3439
- placement: popover.config['placement'],
3440
- modifiers: [{
3441
- name: 'eventListeners',
3442
- enabled: true
3443
- }].concat(getModifiers(popover.config))
3444
- }); // Update popover position
3445
4109
 
3446
- popover.popper.update(); // Update popover state
4110
+ delete entry.__eventListeners;
4111
+ } // Return the entry object.
3447
4112
 
3448
- popover.state = 'opened'; // Return the popover
3449
4113
 
3450
- return popover;
4114
+ return entry;
3451
4115
  }
3452
4116
 
3453
- function register(trigger, target) {
3454
- // Deregister popover if it already exists in the collection
3455
- this.deregister(target.id); // Create popper instance
4117
+ var open = function open(query) {
4118
+ try {
4119
+ var _this2 = this;
3456
4120
 
3457
- var popperInstance = createPopper(trigger, target); // Save root this for use inside object & create methods API
4121
+ // Get the popover from collection.
4122
+ var popover = getPopover.call(_this2, query); // Update state class.
3458
4123
 
3459
- var root = this;
3460
- var methods = {
3461
- open: function open$1() {
3462
- open.call(root, this);
3463
- },
3464
- close: function close$1() {
3465
- close.call(root, this);
3466
- },
3467
- deregister: function deregister() {
3468
- _deregister.call(root, this);
3469
- }
3470
- }; // Build popover object and push to collection array
4124
+ popover.target.classList.add(_this2.settings.stateActive); // Update accessibility attribute(s).
3471
4125
 
3472
- var popover = _extends({
3473
- id: target.id,
3474
- state: 'closed',
3475
- trigger: trigger,
3476
- target: target,
3477
- popper: popperInstance,
3478
- config: getConfig(target, this.settings)
3479
- }, methods); // Setup event listeners
4126
+ if (popover.trigger.hasAttribute('aria-controls')) {
4127
+ popover.trigger.setAttribute('aria-expanded', 'true');
4128
+ } // Update popover config.
3480
4129
 
3481
4130
 
3482
- registerEventListeners.call(this, popover); // Set initial state of popover
4131
+ popover.config = getConfig(popover.target, _this2.settings); // Enable popper event listeners and set placement/modifiers.
3483
4132
 
3484
- if (popover.target.classList.contains(this.settings.stateActive)) {
3485
- popover.open();
3486
- documentClick.call(this, popover);
3487
- } else {
3488
- popover.close();
3489
- } // Add item to collection
4133
+ popover.popper.setOptions({
4134
+ placement: popover.config['placement'],
4135
+ modifiers: [{
4136
+ name: 'eventListeners',
4137
+ enabled: true
4138
+ }].concat(getModifiers(popover.config))
4139
+ }); // Update popover position.
3490
4140
 
4141
+ popover.popper.update(); // Update popover state.
3491
4142
 
3492
- this.collection.push(popover); // Return the popover object
4143
+ popover.state = 'opened'; // Return the popover.
3493
4144
 
3494
- return popover;
3495
- }
4145
+ return Promise.resolve(popover);
4146
+ } catch (e) {
4147
+ return Promise.reject(e);
4148
+ }
4149
+ };
4150
+
4151
+ var register = function register(trigger, target) {
4152
+ try {
4153
+ var _this2 = this;
3496
4154
 
3497
- function _deregister(popover) {
3498
- // Check if this item has been registered in the collection
3499
- var index = this.collection.findIndex(function (entry) {
3500
- return entry.id === popover.id;
3501
- }); // If the entry exists in the collection
4155
+ // Deregister entry incase it has already been registered.
4156
+ deregister.call(_this2, target); // Save root this for use inside methods API.
3502
4157
 
3503
- if (index >= 0) {
3504
- // Get the collection entry
3505
- var entry = this.collection[index]; // Close the collection entry if it's open
3506
4158
 
3507
- if (entry.state === 'opened') {
3508
- entry.close();
3509
- } // Clean up the popper instance
4159
+ var root = _this2; // Setup methods API.
3510
4160
 
4161
+ var methods = {
4162
+ open: function open$1() {
4163
+ return open.call(root, this);
4164
+ },
4165
+ close: function close$1() {
4166
+ return close.call(root, this);
4167
+ },
4168
+ deregister: function deregister$1() {
4169
+ return deregister.call(root, this);
4170
+ }
4171
+ }; // Setup the popover object.
3511
4172
 
3512
- entry.popper.destroy(); // Remove event listeners
4173
+ var entry = _extends({
4174
+ id: target.id,
4175
+ state: 'closed',
4176
+ trigger: trigger,
4177
+ target: target,
4178
+ popper: createPopper(trigger, target),
4179
+ config: getConfig(target, _this2.settings)
4180
+ }, methods); // Set aria-expanded to false if trigger has aria-controls attribute.
3513
4181
 
3514
- deregisterEventListeners(entry); // Delete properties from collection entry
3515
4182
 
3516
- Object.getOwnPropertyNames(entry).forEach(function (prop) {
3517
- delete entry[prop];
3518
- }); // Remove entry from collection
4183
+ if (entry.trigger.hasAttribute('aria-controls')) {
4184
+ entry.trigger.setAttribute('aria-expanded', 'false');
4185
+ } // Setup event listeners.
3519
4186
 
3520
- this.collection.splice(index, 1);
3521
- } // Return the new collection
3522
4187
 
4188
+ registerEventListeners.call(_this2, entry); // Add entry to collection.
3523
4189
 
3524
- return this.collection;
3525
- }
3526
- function registerEventListeners(popover) {
3527
- // If event listeners aren't already setup
3528
- if (!popover.__eventListeners) {
3529
- // Add event listeners based on event type
3530
- var eventType = popover.config['event'];
4190
+ _this2.collection.push(entry); // Set initial state.
4191
+
4192
+
4193
+ var _temp2 = function () {
4194
+ if (entry.target.classList.contains(_this2.settings.stateActive)) {
4195
+ return Promise.resolve(entry.open()).then(function () {
4196
+ documentClick.call(_this2, entry);
4197
+ });
4198
+ }
4199
+ }();
4200
+
4201
+ return Promise.resolve(_temp2 && _temp2.then ? _temp2.then(function () {
4202
+ // Return the registered entry.
4203
+ return entry;
4204
+ }) : entry);
4205
+ } catch (e) {
4206
+ return Promise.reject(e);
4207
+ }
4208
+ };
4209
+ function registerEventListeners(entry) {
4210
+ // If event listeners aren't already setup.
4211
+ if (!entry.__eventListeners) {
4212
+ // Add event listeners based on event type.
4213
+ var eventType = entry.config['event']; // If the event type is hover.
3531
4214
 
3532
4215
  if (eventType === 'hover') {
3533
- // Setup event listeners object for hover
3534
- popover.__eventListeners = [{
4216
+ // Setup event listeners object for hover.
4217
+ entry.__eventListeners = [{
3535
4218
  el: ['trigger'],
3536
4219
  type: ['mouseenter', 'focus'],
3537
- listener: open.bind(this, popover)
4220
+ listener: open.bind(this, entry)
3538
4221
  }, {
3539
4222
  el: ['trigger', 'target'],
3540
4223
  type: ['mouseleave', 'focusout'],
3541
- listener: closeCheck.bind(this, popover)
3542
- }]; // Loop through listeners and apply to appropriate elements
4224
+ listener: closeCheck.bind(this, entry)
4225
+ }]; // Loop through listeners and apply to the appropriate elements.
3543
4226
 
3544
- popover.__eventListeners.forEach(function (evObj) {
4227
+ entry.__eventListeners.forEach(function (evObj) {
3545
4228
  evObj.el.forEach(function (el) {
3546
4229
  evObj.type.forEach(function (type) {
3547
- popover[el].addEventListener(type, evObj.listener, false);
4230
+ entry[el].addEventListener(type, evObj.listener, false);
3548
4231
  });
3549
4232
  });
3550
4233
  });
3551
- } else {
3552
- // Setup event listeners object for click
3553
- popover.__eventListeners = [{
4234
+ } // Else the event type is click.
4235
+ else {
4236
+ // Setup event listeners object for click.
4237
+ entry.__eventListeners = [{
3554
4238
  el: ['trigger'],
3555
4239
  type: ['click'],
3556
- listener: handlerClick.bind(this, popover)
3557
- }]; // Loop through listeners and apply to appropriate elements
4240
+ listener: handlerClick.bind(this, entry)
4241
+ }]; // Loop through listeners and apply to the appropriate elements.
3558
4242
 
3559
- popover.__eventListeners.forEach(function (evObj) {
4243
+ entry.__eventListeners.forEach(function (evObj) {
3560
4244
  evObj.el.forEach(function (el) {
3561
4245
  evObj.type.forEach(function (type) {
3562
- popover[el].addEventListener(type, evObj.listener, false);
4246
+ entry[el].addEventListener(type, evObj.listener, false);
3563
4247
  });
3564
4248
  });
3565
4249
  });
3566
4250
  }
3567
- } // Return the popover object
3568
-
3569
-
3570
- return popover;
3571
- }
3572
- function deregisterEventListeners(popover) {
3573
- // If event listeners have been setup
3574
- if (popover.__eventListeners) {
3575
- // Loop through listeners and remove from appropriate elements
3576
- popover.__eventListeners.forEach(function (evObj) {
3577
- evObj.el.forEach(function (el) {
3578
- evObj.type.forEach(function (type) {
3579
- popover[el].removeEventListener(type, evObj.listener, false);
3580
- });
3581
- });
3582
- }); // Remove eventListeners object from collection
3583
-
3584
-
3585
- delete popover.__eventListeners;
3586
- } // Return the popover object
4251
+ } // Return the entry object.
3587
4252
 
3588
4253
 
3589
- return popover;
4254
+ return entry;
3590
4255
  }
3591
4256
 
3592
4257
  var Popover = /*#__PURE__*/function (_Collection) {
@@ -3597,11 +4262,8 @@ var Popover = /*#__PURE__*/function (_Collection) {
3597
4262
 
3598
4263
  _this = _Collection.call(this) || this;
3599
4264
  _this.defaults = defaults;
3600
- _this.settings = _extends({}, _this.defaults, options); // this.collection = [];
3601
-
3602
- _this.memory = {
3603
- trigger: null
3604
- };
4265
+ _this.settings = _extends({}, _this.defaults, options);
4266
+ _this.memory = {};
3605
4267
  _this.__handlerKeydown = handlerKeydown.bind(_assertThisInitialized(_this));
3606
4268
  if (_this.settings.autoInit) _this.init();
3607
4269
  return _this;
@@ -3610,52 +4272,58 @@ var Popover = /*#__PURE__*/function (_Collection) {
3610
4272
  var _proto = Popover.prototype;
3611
4273
 
3612
4274
  _proto.init = function init(options) {
3613
- if (options === void 0) {
3614
- options = null;
3615
- }
3616
-
3617
- // Update settings with passed options
3618
- if (options) this.settings = _extends({}, this.settings, options); // Get all the popovers
4275
+ try {
4276
+ var _this3 = this;
3619
4277
 
3620
- var popovers = document.querySelectorAll(this.settings.selectorPopover); // Build the collections array with popover instances
4278
+ // Update settings with passed options.
4279
+ if (options) _this3.settings = _extends({}, _this3.settings, options); // Get all the popovers.
3621
4280
 
3622
- this.registerCollection(popovers); // If eventListeners is enabled
4281
+ var popovers = document.querySelectorAll(_this3.settings.selectorPopover); // Register the collections array with popover instances.
3623
4282
 
3624
- if (this.settings.eventListeners) {
3625
- // Pass false to initEventListeners() since registerCollection()
3626
- // already adds event listeners to popovers
3627
- this.initEventListeners(false);
4283
+ return Promise.resolve(_this3.registerCollection(popovers)).then(function () {
4284
+ if (_this3.settings.eventListeners) {
4285
+ // Pass false to initEventListeners() since registerCollection()
4286
+ // already adds event listeners to popovers.
4287
+ _this3.initEventListeners(false);
4288
+ }
4289
+ }); // If eventListeners are enabled, init event listeners.
4290
+ } catch (e) {
4291
+ return Promise.reject(e);
3628
4292
  }
3629
4293
  };
3630
4294
 
3631
4295
  _proto.destroy = function destroy() {
3632
- // Deregister all popovers from collection
3633
- this.deregisterCollection(); // If eventListeners is enabled
4296
+ try {
4297
+ var _this5 = this;
3634
4298
 
3635
- if (this.settings.eventListeners) {
3636
- // Pass false to destroyEventListeners() since deregisterCollection()
3637
- // already removes event listeners from popovers
3638
- this.destroyEventListeners(false);
4299
+ // Clear any stored memory.
4300
+ _this5.memory = {}; // Remove all entries from the collection.
4301
+
4302
+ return Promise.resolve(_this5.deregisterCollection()).then(function () {
4303
+ if (_this5.settings.eventListeners) {
4304
+ // Pass false to destroyEventListeners() since deregisterCollection()
4305
+ // already removes event listeners from popovers.
4306
+ _this5.destroyEventListeners(false);
4307
+ }
4308
+ }); // If eventListeners are enabled, destroy event listeners.
4309
+ } catch (e) {
4310
+ return Promise.reject(e);
3639
4311
  }
3640
- }
3641
- /**
3642
- * Event listeners
3643
- */
3644
- ;
4312
+ };
3645
4313
 
3646
4314
  _proto.initEventListeners = function initEventListeners(processCollection) {
3647
- var _this2 = this;
4315
+ var _this6 = this;
3648
4316
 
3649
4317
  if (processCollection === void 0) {
3650
4318
  processCollection = true;
3651
4319
  }
3652
4320
 
3653
4321
  if (processCollection) {
3654
- // Loop through collection and setup event listeners
4322
+ // Loop through collection and setup event listeners.
3655
4323
  this.collection.forEach(function (popover) {
3656
- registerEventListeners.call(_this2, popover);
4324
+ registerEventListeners.call(_this6, popover);
3657
4325
  });
3658
- } // Add keydown global event listener
4326
+ } // Add keydown global event listener.
3659
4327
 
3660
4328
 
3661
4329
  document.addEventListener('keydown', this.__handlerKeydown, false);
@@ -3667,50 +4335,33 @@ var Popover = /*#__PURE__*/function (_Collection) {
3667
4335
  }
3668
4336
 
3669
4337
  if (processCollection) {
3670
- // Loop through collection and remove event listeners
4338
+ // Loop through collection and remove event listeners.
3671
4339
  this.collection.forEach(function (popover) {
3672
4340
  deregisterEventListeners(popover);
3673
4341
  });
3674
- } // Remove keydown global event listener
4342
+ } // Remove keydown global event listener.
3675
4343
 
3676
4344
 
3677
4345
  document.removeEventListener('keydown', this.__handlerKeydown, false);
3678
- }
3679
- /**
3680
- * Register popover functionality
3681
- */
3682
- ;
4346
+ };
3683
4347
 
3684
4348
  _proto.register = function register$1(query) {
3685
4349
  var els = getPopoverElements.call(this, query);
3686
- if (!els) return false;
4350
+ if (els.error) return Promise.reject(els.error);
3687
4351
  return register.call(this, els.trigger, els.target);
3688
4352
  };
3689
4353
 
3690
- _proto.deregister = function deregister(query) {
3691
- var popover = this.get(getPopoverID(query));
3692
- if (!popover) return false;
3693
- return _deregister.call(this, popover);
3694
- }
3695
- /**
3696
- * Change state functionality
3697
- */
3698
- ;
4354
+ _proto.deregister = function deregister$1(query) {
4355
+ var popover = this.get(getPopoverID.call(this, query));
4356
+ return deregister.call(this, popover);
4357
+ };
3699
4358
 
3700
- _proto.open = function open(id) {
3701
- var popover = this.get(id);
3702
- if (!popover) return false;
3703
- return popover.open();
4359
+ _proto.open = function open$1(id) {
4360
+ return open.call(this, id);
3704
4361
  };
3705
4362
 
3706
- _proto.close = function close(id) {
3707
- if (id) {
3708
- var popover = this.get(id);
3709
- if (!popover) return false;
3710
- return popover.close();
3711
- } else {
3712
- return closeAll.call(this);
3713
- }
4363
+ _proto.close = function close$1(id) {
4364
+ return close.call(this, id);
3714
4365
  };
3715
4366
 
3716
4367
  return Popover;