vrembem 1.41.0 → 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,466 +1282,693 @@ 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',
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',
1025
1296
  // State classes
1026
1297
  stateOpened: 'is-opened',
1027
1298
  stateOpening: 'is-opening',
1028
1299
  stateClosing: 'is-closing',
1029
1300
  stateClosed: 'is-closed',
1030
- // Selector
1031
- selectorInert: null,
1032
- selectorOverflow: 'body',
1033
- // Feature toggles
1301
+ // Feature settings
1034
1302
  customEventPrefix: 'modal:',
1035
1303
  eventListeners: true,
1036
- moveModals: {
1037
- ref: null,
1038
- type: null
1039
- },
1304
+ teleport: null,
1305
+ teleportMethod: 'append',
1040
1306
  setTabindex: true,
1041
1307
  transition: true
1042
1308
  };
1043
1309
 
1044
- var close$1 = function close(returnFocus) {
1045
- if (returnFocus === void 0) {
1046
- returnFocus = true;
1047
- }
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.
1048
1313
 
1049
- try {
1050
- var _this2 = this;
1314
+ setOverflowHidden(!!this.active, this.settings.selectorOverflow); // Update the z-index of the stack.
1051
1315
 
1052
- var modal = document.querySelector("[data-" + _this2.settings.dataModal + "]." + _this2.settings.stateOpened);
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);
1324
+ } else {
1325
+ // Set focus to root trigger and destroy focus trap.
1326
+ focusTrigger(this);
1327
+ this.focusTrap.destroy();
1328
+ }
1329
+ }
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
+ });
1336
+ }
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) : {};
1341
+ }
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.
1053
1345
 
1054
- if (modal) {
1055
- _this2.working = true;
1056
- setInert(false, _this2.settings.selectorInert);
1057
- setOverflowHidden(false, _this2.settings.selectorOverflow);
1058
- return Promise.resolve(closeTransition(modal, _this2.settings)).then(function () {
1059
- if (returnFocus) focusTrigger(_this2);
1346
+ if (entry) {
1347
+ return entry;
1348
+ } else {
1349
+ throw new Error("Modal not found in collection with id of \"" + query + "\".");
1350
+ }
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);
1060
1381
 
1061
- _this2.focusTrap.destroy();
1382
+ if (id) {
1383
+ var target = document.querySelector("#" + id);
1384
+ var dialog = target ? target.querySelector(this.settings.selectorDialog) : null;
1062
1385
 
1063
- modal.dispatchEvent(new CustomEvent(_this2.settings.customEventPrefix + 'closed', {
1064
- detail: _this2,
1065
- bubbles: true
1066
- }));
1067
- _this2.working = false;
1068
- return modal;
1069
- });
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
+ };
1070
1394
  } else {
1071
- return Promise.resolve(modal);
1395
+ return {
1396
+ target: target,
1397
+ dialog: dialog
1398
+ };
1072
1399
  }
1073
- } catch (e) {
1074
- return Promise.reject(e);
1400
+ } else {
1401
+ return {
1402
+ error: new Error('Could not resolve the modal ID.')
1403
+ };
1075
1404
  }
1076
- };
1405
+ }
1077
1406
 
1078
- var handlerClick$1 = function handlerClick(event) {
1407
+ var handleClick = function handleClick(event) {
1079
1408
  try {
1080
- var _temp3 = function _temp3(_result) {
1081
- if (_exit2) return _result;
1409
+ var _this2 = this;
1082
1410
 
1083
- // Close click
1084
- if (event.target.closest("[data-" + _this2.settings.dataClose + "]")) {
1085
- event.preventDefault();
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 + "]");
1086
1413
 
1087
- _this2.close();
1414
+ if (trigger) {
1415
+ event.preventDefault(); // Save the trigger if it's not coming from inside a modal.
1088
1416
 
1089
- return;
1090
- } // Root click
1417
+ var fromModal = event.target.closest(_this2.settings.selectorModal);
1418
+ if (!fromModal) _this2.memory.trigger = trigger; // Get the modal.
1091
1419
 
1420
+ var modal = _this2.get(getModalID.call(_this2, trigger)); // Depending on the button type, either open or replace the modal.
1092
1421
 
1093
- if (event.target.hasAttribute("data-" + _this2.settings.dataModal) && !event.target.hasAttribute("data-" + _this2.settings.dataRequired)) {
1094
- _this2.close();
1095
- }
1096
- };
1097
1422
 
1098
- var _exit2;
1423
+ return Promise.resolve(trigger.matches("[data-" + _this2.settings.dataOpen + "]") ? modal.open() : modal.replace());
1424
+ } // If a close button was clicked, close the modal.
1099
1425
 
1100
- var _this2 = this;
1101
1426
 
1102
- // Working catch
1103
- if (_this2.working) return Promise.resolve(); // Trigger click
1427
+ trigger = event.target.closest("[data-" + _this2.settings.dataClose + "]");
1104
1428
 
1105
- var trigger = event.target.closest("[data-" + _this2.settings.dataOpen + "]");
1429
+ if (trigger) {
1430
+ event.preventDefault(); // Get the value of the data attribute.
1106
1431
 
1107
- var _temp4 = function () {
1108
- if (trigger) {
1109
- event.preventDefault();
1110
- var modalKey = trigger.getAttribute("data-" + _this2.settings.dataOpen);
1111
- var fromModal = event.target.closest("[data-" + _this2.settings.dataModal + "]");
1112
- if (!fromModal) _this2.memory.trigger = trigger;
1113
- return Promise.resolve(_this2.close(!fromModal)).then(function () {
1114
- _this2.open(modalKey);
1432
+ var value = trigger.getAttribute("data-" + _this2.settings.dataClose); // Close all if * wildcard is passed, otherwise close a single modal.
1115
1433
 
1116
- _exit2 = 1;
1117
- });
1118
- }
1119
- }();
1434
+ return Promise.resolve(value === '*' ? _this2.closeAll() : _this2.close(value));
1435
+ } // If the modal screen was clicked, close the modal.
1120
1436
 
1121
- return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(_temp3) : _temp3(_temp4));
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)));
1440
+ }
1441
+
1442
+ return Promise.resolve();
1122
1443
  } catch (e) {
1123
1444
  return Promise.reject(e);
1124
1445
  }
1125
1446
  };
1126
- function handlerKeydown$1(event) {
1127
- // Working catch
1128
- if (this.working) return;
1129
-
1447
+ function handleKeydown(event) {
1448
+ // If escape key was pressed.
1130
1449
  if (event.key === 'Escape') {
1131
- var target = document.querySelector("[data-" + this.settings.dataModal + "]." + this.settings.stateOpened);
1132
-
1133
- if (target && !target.hasAttribute("data-" + this.settings.dataRequired)) {
1134
- this.close();
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();
1135
1453
  }
1136
1454
  }
1137
1455
  }
1138
1456
 
1139
- function getModal(modalKey) {
1140
- if (typeof modalKey !== 'string') return modalKey;
1141
- return document.querySelector("[data-" + this.settings.dataModal + "=\"" + modalKey + "\"]");
1142
- }
1143
- function modalNotFound(key) {
1144
- return Promise.reject(new Error("Did not find modal with key: \"" + key + "\""));
1145
- }
1146
- function moveModals(type, ref) {
1147
- if (type === void 0) {
1148
- type = this.settings.moveModals.type;
1457
+ var deregister$1 = function deregister(obj, close) {
1458
+ if (close === void 0) {
1459
+ close = true;
1149
1460
  }
1150
1461
 
1151
- if (ref === void 0) {
1152
- ref = this.settings.moveModals.ref;
1153
- }
1462
+ try {
1463
+ var _temp5 = function _temp5() {
1464
+ // Return the modified collection.
1465
+ return _this2.collection;
1466
+ };
1154
1467
 
1155
- var modals = document.querySelectorAll("[data-" + this.settings.dataModal + "]");
1156
- if (modals.length) moveElement(modals, type, ref);
1157
- }
1468
+ var _this2 = this;
1158
1469
 
1159
- function setInitialState() {
1160
- var _this = this;
1470
+ // Return collection if nothing was passed.
1471
+ if (!obj) return Promise.resolve(_this2.collection); // Check if entry has been registered in the collection.
1161
1472
 
1162
- var modals = document.querySelectorAll("[data-" + this.settings.dataModal + "]");
1163
- modals.forEach(function (el) {
1164
- // Remove opened state setup
1165
- if (el.classList.contains(_this.settings.stateOpened)) {
1166
- setInert(false, _this.settings.selectorInert);
1167
- setOverflowHidden(false, _this.settings.selectorOverflow);
1168
- focusTrigger(_this);
1473
+ var index = _this2.collection.findIndex(function (entry) {
1474
+ return entry.id === obj.id;
1475
+ });
1169
1476
 
1170
- _this.focusTrap.destroy();
1171
- } // Remove all state classes and add the default state (closed)
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.
1172
1484
 
1173
1485
 
1174
- removeClass(el, _this.settings.stateOpened, _this.settings.stateOpening, _this.settings.stateClosing);
1175
- addClass(el, _this.settings.stateClosed);
1176
- });
1177
- }
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.
1504
+
1505
+
1506
+ if (stackIndex >= 0) {
1507
+ _this2.stack.splice(stackIndex, 1);
1508
+ }
1509
+ }
1510
+ }();
1511
+
1512
+ return _temp8 && _temp8.then ? _temp8.then(_temp7) : _temp7(_temp8);
1513
+ }
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
+ }
1178
1526
 
1179
- var open$1 = function open(modalKey) {
1180
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.
1539
+
1540
+ return modal;
1541
+ };
1542
+
1181
1543
  var _this2 = this;
1182
1544
 
1183
- var modal = getModal.call(_this2, modalKey);
1184
- if (!modal) return Promise.resolve(modalNotFound(modalKey));
1545
+ // Get the modal from collection.
1546
+ var modal = getModal.call(_this2, query); // Get the modal configuration.
1185
1547
 
1186
- if (hasClass(modal, _this2.settings.stateClosed)) {
1187
- _this2.working = true;
1188
- setOverflowHidden(true, _this2.settings.selectorOverflow);
1189
- return Promise.resolve(openTransition(modal, _this2.settings)).then(function () {
1190
- _this2.focusTrap.init(modal);
1548
+ var config = _extends({}, _this2.settings, modal.settings); // Add transition parameter to configuration.
1191
1549
 
1192
- focusTarget(modal, _this2.settings);
1193
- setInert(true, _this2.settings.selectorInert);
1194
- modal.dispatchEvent(new CustomEvent(_this2.settings.customEventPrefix + 'opened', {
1195
- detail: _this2,
1196
- bubbles: true
1197
- }));
1198
- _this2.working = false;
1199
- return modal;
1200
- });
1201
- } else {
1202
- return Promise.resolve(modal);
1203
- }
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.
1565
+
1566
+
1567
+ var _temp4 = function () {
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.
1575
+
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';
1582
+ });
1583
+ }
1584
+ }();
1585
+
1586
+ return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(_temp3) : _temp3(_temp4));
1204
1587
  } catch (e) {
1205
1588
  return Promise.reject(e);
1206
1589
  }
1207
1590
  };
1208
1591
 
1209
- var Modal = /*#__PURE__*/function () {
1210
- function Modal(options) {
1211
- this.defaults = defaults$1;
1212
- this.settings = _extends({}, this.defaults, options);
1213
- this.working = false;
1214
- this.memory = {};
1215
- this.focusTrap = new FocusTrap();
1216
- this.__handlerClick = handlerClick$1.bind(this);
1217
- this.__handlerKeydown = handlerKeydown$1.bind(this);
1218
- if (this.settings.autoInit) this.init();
1592
+ var close$1 = function close(query, transition, bulk) {
1593
+ if (bulk === void 0) {
1594
+ bulk = false;
1219
1595
  }
1220
1596
 
1221
- var _proto = Modal.prototype;
1597
+ try {
1598
+ var _this2 = this;
1222
1599
 
1223
- _proto.init = function init(options) {
1224
- if (options === void 0) {
1225
- options = null;
1226
- }
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.
1227
1602
 
1228
- if (options) this.settings = _extends({}, this.settings, options);
1229
- this.moveModals();
1230
- this.setInitialState();
1603
+ var _temp2 = function () {
1604
+ if (modal && modal.state === 'opened') {
1605
+ // Update modal state.
1606
+ modal.state = 'closing'; // Get the modal configuration.
1231
1607
 
1232
- if (this.settings.setTabindex) {
1233
- this.setTabindex();
1234
- }
1608
+ var config = _extends({}, _this2.settings, modal.settings); // Add transition parameter to configuration.
1235
1609
 
1236
- if (this.settings.eventListeners) {
1237
- this.initEventListeners();
1238
- }
1239
- };
1240
1610
 
1241
- _proto.destroy = function destroy() {
1242
- this.memory = {};
1611
+ if (transition !== undefined) config.transition = transition; // Remove focus from active element.
1243
1612
 
1244
- if (this.settings.eventListeners) {
1245
- this.destroyEventListeners();
1246
- }
1613
+ document.activeElement.blur(); // Run the close transition.
1614
+
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.
1618
+
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);
1646
+ } catch (e) {
1647
+ return Promise.reject(e);
1247
1648
  }
1248
- /**
1249
- * Event listeners
1250
- */
1251
- ;
1649
+ };
1252
1650
 
1253
- _proto.initEventListeners = function initEventListeners() {
1254
- document.addEventListener('click', this.__handlerClick, false);
1255
- document.addEventListener('touchend', this.__handlerClick, false);
1256
- document.addEventListener('keydown', this.__handlerKeydown, false);
1257
- };
1651
+ var closeAll$1 = function closeAll(exclude, transition) {
1652
+ try {
1653
+ var _this2 = this;
1258
1654
 
1259
- _proto.destroyEventListeners = function destroyEventListeners() {
1260
- document.removeEventListener('click', this.__handlerClick, false);
1261
- document.removeEventListener('touchend', this.__handlerClick, false);
1262
- document.removeEventListener('keydown', this.__handlerKeydown, false);
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
+ }();
1672
+
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);
1263
1682
  }
1264
- /**
1265
- * Helpers
1266
- */
1267
- ;
1683
+ };
1268
1684
 
1269
- _proto.getModal = function getModal$1(modalKey) {
1270
- return getModal.call(this, modalKey);
1271
- };
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.
1272
1690
 
1273
- _proto.setTabindex = function setTabindex$1() {
1274
- return setTabindex("\n [data-" + this.settings.dataModal + "]\n [data-" + this.settings.dataDialog + "]\n ");
1275
- };
1691
+ return {
1692
+ opened: resultOpened,
1693
+ closed: resultClosed
1694
+ };
1695
+ };
1276
1696
 
1277
- _proto.setInitialState = function setInitialState$1() {
1278
- return setInitialState.call(this);
1279
- };
1697
+ var _this2 = this;
1698
+
1699
+ // Get the modal from collection.
1700
+ var modal = getModal.call(_this2, query); // Setup results for return.
1280
1701
 
1281
- _proto.moveModals = function moveModals$1(type, ref) {
1282
- return moveModals.call(this, type, ref);
1702
+ var resultOpened, resultClosed;
1703
+
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
+ }();
1718
+
1719
+ return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(_temp3) : _temp3(_temp4));
1720
+ } catch (e) {
1721
+ return Promise.reject(e);
1283
1722
  }
1284
- /**
1285
- * Change state functionality
1286
- */
1287
- ;
1723
+ };
1288
1724
 
1289
- _proto.open = function open(modalKey) {
1290
- return open$1.call(this, modalKey);
1291
- };
1725
+ var register$1 = function register(target, dialog) {
1726
+ try {
1727
+ var _this2 = this;
1292
1728
 
1293
- _proto.close = function close(returnFocus) {
1294
- return close$1.call(this, returnFocus);
1295
- };
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
+ }
1296
1751
 
1297
- return Modal;
1298
- }();
1752
+ if (method === void 0) {
1753
+ method = this.getSetting('teleportMethod');
1754
+ }
1299
1755
 
1300
- var Collection = /*#__PURE__*/function () {
1301
- function Collection() {
1302
- this.collection = [];
1303
- }
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.
1304
1777
 
1305
- var _proto = Collection.prototype;
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.
1306
1786
 
1307
- _proto.register = function register(item) {
1308
- this.deregister(item);
1309
- this.collection.push(item);
1310
- return this.collection;
1311
- };
1312
1787
 
1313
- _proto.deregister = function deregister(ref) {
1314
- var index = this.collection.findIndex(function (entry) {
1315
- return entry === ref;
1316
- });
1788
+ entry.dialog.setAttribute('aria-modal', 'true'); // If a role attribute is not set, set it to "dialog" as the default.
1317
1789
 
1318
- if (index >= 0) {
1319
- var entry = this.collection[index];
1320
- Object.getOwnPropertyNames(entry).forEach(function (prop) {
1321
- delete entry[prop];
1322
- });
1323
- this.collection.splice(index, 1);
1324
- }
1790
+ if (!entry.dialog.hasAttribute('role')) {
1791
+ entry.dialog.setAttribute('role', 'dialog');
1792
+ } // Set tabindex="-1" so dialog is focusable via JS or click.
1325
1793
 
1326
- return this.collection;
1327
- };
1328
1794
 
1329
- _proto.registerCollection = function registerCollection(items) {
1330
- var _this = this;
1795
+ if (entry.getSetting('setTabindex')) {
1796
+ entry.dialog.setAttribute('tabindex', '-1');
1797
+ } // Teleport modal if a reference has been set.
1331
1798
 
1332
- items.forEach(function (item) {
1333
- _this.register(item);
1334
- });
1335
- return this.collection;
1336
- };
1337
1799
 
1338
- _proto.deregisterCollection = function deregisterCollection() {
1339
- while (this.collection.length > 0) {
1340
- this.deregister(this.collection[0]);
1341
- }
1800
+ if (entry.getSetting('teleport')) {
1801
+ entry.teleport();
1802
+ } // Add entry to collection.
1342
1803
 
1343
- return this.collection;
1344
- };
1345
1804
 
1346
- _proto.get = function get(query, key) {
1347
- if (key === void 0) {
1348
- key = 'id';
1349
- }
1805
+ _this2.collection.push(entry); // Setup initial state.
1350
1806
 
1351
- var result = this.collection.find(function (item) {
1352
- return item[key] === query;
1353
- });
1354
- return result || null;
1355
- };
1356
1807
 
1357
- return Collection;
1358
- }();
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.
1359
1815
 
1360
- var defaults = {
1361
- autoInit: false,
1362
- // Selectors
1363
- selectorPopover: '.popover',
1364
- selectorArrow: '.popover__arrow',
1365
- // State classes
1366
- stateActive: 'is-active',
1367
- // Feature toggles
1368
- eventListeners: true,
1369
- eventType: 'click',
1370
- placement: 'bottom'
1816
+ entry.target.classList.add(_this2.settings.stateClosed);
1817
+ } // Return the registered entry.
1818
+
1819
+
1820
+ return entry;
1821
+ });
1822
+ } catch (e) {
1823
+ return Promise.reject(e);
1824
+ }
1371
1825
  };
1372
1826
 
1373
- function close(popover) {
1374
- // Update state class
1375
- popover.target.classList.remove(this.settings.stateActive); // Update a11y attributes
1827
+ var Modal = /*#__PURE__*/function (_Collection) {
1828
+ _inheritsLoose(Modal, _Collection);
1829
+
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.
1376
1838
 
1377
- popover.trigger.setAttribute('aria-expanded', 'false'); // Disable popper event listeners
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.
1378
1842
 
1379
- popover.popper.setOptions({
1380
- modifiers: [{
1381
- name: 'eventListeners',
1382
- enabled: false
1383
- }]
1384
- }); // Update popover state
1843
+ if (property === 'length') {
1844
+ updateGlobalState.call(_assertThisInitialized(_this));
1845
+ }
1385
1846
 
1386
- popover.state = 'closed'; // Clear memory if popover trigger matches the one saved in memory
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
+ }
1387
1855
 
1388
- if (popover.trigger === this.memory.trigger) {
1389
- this.memory.trigger = null;
1390
- } // Return the popover
1856
+ var _proto = Modal.prototype;
1391
1857
 
1858
+ _proto.init = function init(options) {
1859
+ try {
1860
+ var _this3 = this;
1392
1861
 
1393
- return popover;
1394
- }
1395
- function closeAll() {
1396
- this.collection.forEach(function (popover) {
1397
- if (popover.state === 'opened') {
1398
- popover.close();
1862
+ // Update settings with passed options.
1863
+ if (options) _this3.settings = _extends({}, _this3.settings, options); // Get all the modals.
1864
+
1865
+ var modals = document.querySelectorAll(_this3.settings.selectorModal); // Register the collections array with modal instances.
1866
+
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);
1399
1874
  }
1400
- }); // Return the collection
1875
+ };
1401
1876
 
1402
- return this.collection;
1403
- }
1404
- function closeCheck(popover) {
1405
- // Only run closeCheck if provided popover is currently open
1406
- 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;
1407
1880
 
1408
- setTimeout(function () {
1409
- // Check if trigger or target are being hovered
1410
- 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.
1411
1883
 
1412
- 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
+ };
1413
1893
 
1414
- if (!isHovered && !isFocused) {
1415
- popover.close();
1416
- } // 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
+ };
1417
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
+ };
1418
1905
 
1419
- return popover;
1420
- }, 1);
1421
- }
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
+ };
1422
1911
 
1423
- function handlerClick(popover) {
1424
- if (popover.target.classList.contains(this.settings.stateActive)) {
1425
- popover.close();
1426
- } else {
1427
- this.memory.trigger = popover.trigger;
1428
- popover.open();
1429
- documentClick.call(this, popover);
1430
- }
1431
- }
1432
- function handlerKeydown(event) {
1433
- 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
+ };
1920
+
1921
+ _proto.close = function close(id, transition) {
1922
+ return close$1.call(this, id, transition);
1923
+ };
1434
1924
 
1435
- switch (event.key) {
1436
- case 'Escape':
1437
- if (this.memory.trigger) {
1438
- this.memory.trigger.focus();
1439
- }
1925
+ _proto.replace = function replace$1(id, transition) {
1926
+ return replace.call(this, id, transition);
1927
+ };
1440
1928
 
1441
- closeAll.call(this);
1442
- return;
1929
+ _proto.closeAll = function closeAll(exclude, transition) {
1930
+ if (exclude === void 0) {
1931
+ exclude = false;
1932
+ }
1443
1933
 
1444
- case 'Tab':
1445
- this.collection.forEach(function (popover) {
1446
- closeCheck.call(_this, popover);
1934
+ try {
1935
+ var _this7 = this;
1936
+
1937
+ return Promise.resolve(closeAll$1.call(_this7, exclude, transition)).then(function (result) {
1938
+ updateFocusState.call(_this7);
1939
+ return result;
1447
1940
  });
1448
- return;
1941
+ } catch (e) {
1942
+ return Promise.reject(e);
1943
+ }
1944
+ };
1449
1945
 
1450
- default:
1451
- return;
1452
- }
1453
- }
1454
- function documentClick(popover) {
1455
- var root = this;
1456
- document.addEventListener('click', function _f(event) {
1457
- // Check if a popover was clicked
1458
- var result = event.target.closest("#" + popover.id + ", [aria-controls=\"" + popover.id + "\"]");
1946
+ _createClass(Modal, [{
1947
+ key: "active",
1948
+ get: function get() {
1949
+ return this.stack[this.stack.length - 1];
1950
+ }
1951
+ }]);
1459
1952
 
1460
- if (!result) {
1461
- // If it doesn't match and popover is open, close it and remove event listener
1462
- if (popover.target && popover.target.classList.contains(root.settings.stateActive)) {
1463
- popover.close();
1464
- }
1953
+ return Modal;
1954
+ }(Collection);
1465
1955
 
1466
- this.removeEventListener('click', _f);
1467
- } else {
1468
- // If it does match and popover isn't currently active, remove event listener
1469
- if (popover.target && !popover.target.classList.contains(root.settings.stateActive)) {
1470
- this.removeEventListener('click', _f);
1471
- }
1472
- }
1473
- });
1474
- }
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
+ };
1475
1968
 
1476
1969
  function getConfig(el, settings) {
1477
- // Get the computed styles of the popover
1478
- 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.
1479
1972
 
1480
1973
  var config = {
1481
1974
  'placement': settings.placement,
@@ -1485,29 +1978,29 @@ function getConfig(el, settings) {
1485
1978
  'flip-padding': 0,
1486
1979
  'arrow-element': settings.selectorArrow,
1487
1980
  'arrow-padding': 0
1488
- }; // Loop through config obj
1981
+ }; // Loop through config obj.
1489
1982
 
1490
1983
  for (var prop in config) {
1491
- // Get the CSS variable property values
1984
+ // Get the CSS variable property values.
1492
1985
  var prefix = getComputedStyle(document.body).getPropertyValue('--vrembem-variable-prefix');
1493
- 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.
1494
1987
 
1495
1988
  if (value) {
1496
1989
  config[prop] = value;
1497
1990
  }
1498
- } // Return the config obj
1991
+ } // Return the config obj.
1499
1992
 
1500
1993
 
1501
1994
  return config;
1502
1995
  }
1503
1996
  function getPadding(value) {
1504
- 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.
1505
1998
 
1506
- 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.
1507
2000
 
1508
2001
  array.forEach(function (item, index) {
1509
2002
  array[index] = parseInt(item, 10);
1510
- }); // Build the padding object based on the number of values passed
2003
+ }); // Build the padding object based on the number of values passed.
1511
2004
 
1512
2005
  switch (array.length) {
1513
2006
  case 1:
@@ -1544,7 +2037,7 @@ function getPadding(value) {
1544
2037
  default:
1545
2038
  padding = false;
1546
2039
  break;
1547
- } // Return the padding object
2040
+ } // Return the padding object.
1548
2041
 
1549
2042
 
1550
2043
  return padding;
@@ -1573,43 +2066,59 @@ function getModifiers(options) {
1573
2066
  }
1574
2067
  }];
1575
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
+ }
1576
2079
  function getPopoverID(obj) {
1577
- // If it's a string
2080
+ // If it's a string, return the string.
1578
2081
  if (typeof obj === 'string') {
1579
2082
  return obj;
1580
- } // If it's an HTML element
2083
+ } // If it's an HTML element.
1581
2084
  else if (typeof obj.hasAttribute === 'function') {
1582
- // If it's a popover trigger
1583
- if (obj.hasAttribute('aria-controls')) {
1584
- return obj.getAttribute('aria-controls');
1585
- } // If it's a popover target
1586
- else if (obj.closest(this.settings.selectorPopover)) {
2085
+ // If it's a popover target, return the id.
2086
+ if (obj.closest(this.settings.selectorPopover)) {
2087
+ obj = obj.closest(this.settings.selectorPopover);
1587
2088
  return obj.id;
1588
- } // Return false if no id was found
2089
+ } // If it's a popover trigger, return value of aria-controls.
2090
+ else if (obj.hasAttribute('aria-controls')) {
2091
+ return obj.getAttribute('aria-controls');
2092
+ } // If it's a popover tooltip trigger, return the value of aria-describedby.
2093
+ else if (obj.hasAttribute('aria-describedby')) {
2094
+ return obj.getAttribute('aria-describedby');
2095
+ } // Return false if no id was found.
1589
2096
  else return false;
1590
- } // If it has an ID property
2097
+ } // If it has an id property, return its value.
1591
2098
  else if (obj.id) {
1592
2099
  return obj.id;
1593
- } // Return false if no id was found
2100
+ } // Return false if no id was found.
1594
2101
  else return false;
1595
2102
  }
1596
2103
  function getPopoverElements(query) {
1597
2104
  var id = getPopoverID.call(this, query);
1598
2105
 
1599
2106
  if (id) {
1600
- var trigger = document.querySelector("[aria-controls=\"" + id + "\"]");
2107
+ var trigger = document.querySelector("[aria-controls=\"" + id + "\"]") || document.querySelector("[aria-describedby=\"" + id + "\"]");
1601
2108
  var target = document.querySelector("#" + id);
1602
2109
 
1603
2110
  if (!trigger && !target) {
1604
- 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
+ };
1605
2114
  } else if (!trigger) {
1606
- 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
+ };
1607
2118
  } else if (!target) {
1608
- console.error('No popover associated with the provided popover trigger:', trigger);
1609
- }
1610
-
1611
- if (!trigger || !target) {
1612
- return false;
2119
+ return {
2120
+ error: new Error('No popover associated with the provided popover trigger.')
2121
+ };
1613
2122
  } else {
1614
2123
  return {
1615
2124
  trigger: trigger,
@@ -1617,10 +2126,149 @@ function getPopoverElements(query) {
1617
2126
  };
1618
2127
  }
1619
2128
  } else {
1620
- console.error('Could not resolve the popover ID:', query);
1621
- 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;
1622
2249
  }
1623
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
+ }
1624
2272
 
1625
2273
  var top = 'top';
1626
2274
  var bottom = 'bottom';
@@ -1922,6 +2570,10 @@ function getContainingBlock(element) {
1922
2570
 
1923
2571
  var currentNode = getParentNode(element);
1924
2572
 
2573
+ if (isShadowRoot(currentNode)) {
2574
+ currentNode = currentNode.host;
2575
+ }
2576
+
1925
2577
  while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {
1926
2578
  var css = getComputedStyle$1(currentNode); // This is non-exhaustive but covers the most common CSS properties that
1927
2579
  // create a containing block.
@@ -2145,7 +2797,7 @@ function mapToStyles(_ref2) {
2145
2797
 
2146
2798
  if (placement === top || (placement === left || placement === right) && variation === end) {
2147
2799
  sideY = bottom;
2148
- 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]
2149
2801
  offsetParent[heightProp];
2150
2802
  y -= offsetY - popperRect.height;
2151
2803
  y *= gpuAcceleration ? 1 : -1;
@@ -2153,7 +2805,7 @@ function mapToStyles(_ref2) {
2153
2805
 
2154
2806
  if (placement === left || (placement === top || placement === bottom) && variation === end) {
2155
2807
  sideX = right;
2156
- 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]
2157
2809
  offsetParent[widthProp];
2158
2810
  x -= offsetX - popperRect.width;
2159
2811
  x *= gpuAcceleration ? 1 : -1;
@@ -3405,166 +4057,201 @@ var createPopper = /*#__PURE__*/popperGenerator({
3405
4057
  defaultModifiers: defaultModifiers
3406
4058
  }); // eslint-disable-next-line import/no-unused-modules
3407
4059
 
3408
- function open(popover) {
3409
- // Update state class
3410
- 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.
4078
+
3411
4079
 
3412
- popover.trigger.setAttribute('aria-expanded', 'true'); // Update popover config
4080
+ entry.popper.destroy(); // Remove event listeners.
3413
4081
 
3414
- 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.
3415
4108
 
3416
- popover.popper.setOptions({
3417
- placement: popover.config['placement'],
3418
- modifiers: [{
3419
- name: 'eventListeners',
3420
- enabled: true
3421
- }].concat(getModifiers(popover.config))
3422
- }); // Update popover position
3423
4109
 
3424
- popover.popper.update(); // Update popover state
4110
+ delete entry.__eventListeners;
4111
+ } // Return the entry object.
3425
4112
 
3426
- popover.state = 'opened'; // Return the popover
3427
4113
 
3428
- return popover;
4114
+ return entry;
3429
4115
  }
3430
4116
 
3431
- function register(trigger, target) {
3432
- // Deregister popover if it already exists in the collection
3433
- this.deregister(target.id); // Create popper instance
4117
+ var open = function open(query) {
4118
+ try {
4119
+ var _this2 = this;
3434
4120
 
3435
- 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.
3436
4123
 
3437
- var root = this;
3438
- var methods = {
3439
- open: function open$1() {
3440
- open.call(root, this);
3441
- },
3442
- close: function close$1() {
3443
- close.call(root, this);
3444
- },
3445
- deregister: function deregister() {
3446
- _deregister.call(root, this);
3447
- }
3448
- }; // Build popover object and push to collection array
4124
+ popover.target.classList.add(_this2.settings.stateActive); // Update accessibility attribute(s).
3449
4125
 
3450
- var popover = _extends({
3451
- id: target.id,
3452
- state: 'closed',
3453
- trigger: trigger,
3454
- target: target,
3455
- popper: popperInstance,
3456
- config: getConfig(target, this.settings)
3457
- }, methods); // Setup event listeners
4126
+ if (popover.trigger.hasAttribute('aria-controls')) {
4127
+ popover.trigger.setAttribute('aria-expanded', 'true');
4128
+ } // Update popover config.
3458
4129
 
3459
4130
 
3460
- 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.
3461
4132
 
3462
- if (popover.target.classList.contains(this.settings.stateActive)) {
3463
- popover.open();
3464
- documentClick.call(this, popover);
3465
- } else {
3466
- popover.close();
3467
- } // 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.
3468
4140
 
4141
+ popover.popper.update(); // Update popover state.
3469
4142
 
3470
- this.collection.push(popover); // Return the popover object
4143
+ popover.state = 'opened'; // Return the popover.
3471
4144
 
3472
- return popover;
3473
- }
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;
3474
4154
 
3475
- function _deregister(popover) {
3476
- // Check if this item has been registered in the collection
3477
- var index = this.collection.findIndex(function (entry) {
3478
- return entry.id === popover.id;
3479
- }); // 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.
3480
4157
 
3481
- if (index >= 0) {
3482
- // Get the collection entry
3483
- var entry = this.collection[index]; // Close the collection entry if it's open
3484
4158
 
3485
- if (entry.state === 'opened') {
3486
- entry.close();
3487
- } // Clean up the popper instance
4159
+ var root = _this2; // Setup methods API.
3488
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.
3489
4172
 
3490
- 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.
3491
4181
 
3492
- deregisterEventListeners(entry); // Delete properties from collection entry
3493
4182
 
3494
- Object.getOwnPropertyNames(entry).forEach(function (prop) {
3495
- delete entry[prop];
3496
- }); // Remove entry from collection
4183
+ if (entry.trigger.hasAttribute('aria-controls')) {
4184
+ entry.trigger.setAttribute('aria-expanded', 'false');
4185
+ } // Setup event listeners.
3497
4186
 
3498
- this.collection.splice(index, 1);
3499
- } // Return the new collection
3500
4187
 
4188
+ registerEventListeners.call(_this2, entry); // Add entry to collection.
3501
4189
 
3502
- return this.collection;
3503
- }
3504
- function registerEventListeners(popover) {
3505
- // If event listeners aren't already setup
3506
- if (!popover.__eventListeners) {
3507
- // Add event listeners based on event type
3508
- 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.
3509
4214
 
3510
4215
  if (eventType === 'hover') {
3511
- // Setup event listeners object for hover
3512
- popover.__eventListeners = [{
4216
+ // Setup event listeners object for hover.
4217
+ entry.__eventListeners = [{
3513
4218
  el: ['trigger'],
3514
4219
  type: ['mouseenter', 'focus'],
3515
- listener: open.bind(this, popover)
4220
+ listener: open.bind(this, entry)
3516
4221
  }, {
3517
4222
  el: ['trigger', 'target'],
3518
4223
  type: ['mouseleave', 'focusout'],
3519
- listener: closeCheck.bind(this, popover)
3520
- }]; // Loop through listeners and apply to appropriate elements
4224
+ listener: closeCheck.bind(this, entry)
4225
+ }]; // Loop through listeners and apply to the appropriate elements.
3521
4226
 
3522
- popover.__eventListeners.forEach(function (evObj) {
4227
+ entry.__eventListeners.forEach(function (evObj) {
3523
4228
  evObj.el.forEach(function (el) {
3524
4229
  evObj.type.forEach(function (type) {
3525
- popover[el].addEventListener(type, evObj.listener, false);
4230
+ entry[el].addEventListener(type, evObj.listener, false);
3526
4231
  });
3527
4232
  });
3528
4233
  });
3529
- } else {
3530
- // Setup event listeners object for click
3531
- popover.__eventListeners = [{
4234
+ } // Else the event type is click.
4235
+ else {
4236
+ // Setup event listeners object for click.
4237
+ entry.__eventListeners = [{
3532
4238
  el: ['trigger'],
3533
4239
  type: ['click'],
3534
- listener: handlerClick.bind(this, popover)
3535
- }]; // Loop through listeners and apply to appropriate elements
4240
+ listener: handlerClick.bind(this, entry)
4241
+ }]; // Loop through listeners and apply to the appropriate elements.
3536
4242
 
3537
- popover.__eventListeners.forEach(function (evObj) {
4243
+ entry.__eventListeners.forEach(function (evObj) {
3538
4244
  evObj.el.forEach(function (el) {
3539
4245
  evObj.type.forEach(function (type) {
3540
- popover[el].addEventListener(type, evObj.listener, false);
4246
+ entry[el].addEventListener(type, evObj.listener, false);
3541
4247
  });
3542
4248
  });
3543
4249
  });
3544
4250
  }
3545
- } // Return the popover object
3546
-
3547
-
3548
- return popover;
3549
- }
3550
- function deregisterEventListeners(popover) {
3551
- // If event listeners have been setup
3552
- if (popover.__eventListeners) {
3553
- // Loop through listeners and remove from appropriate elements
3554
- popover.__eventListeners.forEach(function (evObj) {
3555
- evObj.el.forEach(function (el) {
3556
- evObj.type.forEach(function (type) {
3557
- popover[el].removeEventListener(type, evObj.listener, false);
3558
- });
3559
- });
3560
- }); // Remove eventListeners object from collection
3561
-
3562
-
3563
- delete popover.__eventListeners;
3564
- } // Return the popover object
4251
+ } // Return the entry object.
3565
4252
 
3566
4253
 
3567
- return popover;
4254
+ return entry;
3568
4255
  }
3569
4256
 
3570
4257
  var Popover = /*#__PURE__*/function (_Collection) {
@@ -3575,11 +4262,8 @@ var Popover = /*#__PURE__*/function (_Collection) {
3575
4262
 
3576
4263
  _this = _Collection.call(this) || this;
3577
4264
  _this.defaults = defaults;
3578
- _this.settings = _extends({}, _this.defaults, options); // this.collection = [];
3579
-
3580
- _this.memory = {
3581
- trigger: null
3582
- };
4265
+ _this.settings = _extends({}, _this.defaults, options);
4266
+ _this.memory = {};
3583
4267
  _this.__handlerKeydown = handlerKeydown.bind(_assertThisInitialized(_this));
3584
4268
  if (_this.settings.autoInit) _this.init();
3585
4269
  return _this;
@@ -3588,52 +4272,58 @@ var Popover = /*#__PURE__*/function (_Collection) {
3588
4272
  var _proto = Popover.prototype;
3589
4273
 
3590
4274
  _proto.init = function init(options) {
3591
- if (options === void 0) {
3592
- options = null;
3593
- }
3594
-
3595
- // Update settings with passed options
3596
- if (options) this.settings = _extends({}, this.settings, options); // Get all the popovers
4275
+ try {
4276
+ var _this3 = this;
3597
4277
 
3598
- 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.
3599
4280
 
3600
- this.registerCollection(popovers); // If eventListeners is enabled
4281
+ var popovers = document.querySelectorAll(_this3.settings.selectorPopover); // Register the collections array with popover instances.
3601
4282
 
3602
- if (this.settings.eventListeners) {
3603
- // Pass false to initEventListeners() since registerCollection()
3604
- // already adds event listeners to popovers
3605
- 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);
3606
4292
  }
3607
4293
  };
3608
4294
 
3609
4295
  _proto.destroy = function destroy() {
3610
- // Deregister all popovers from collection
3611
- this.deregisterCollection(); // If eventListeners is enabled
4296
+ try {
4297
+ var _this5 = this;
3612
4298
 
3613
- if (this.settings.eventListeners) {
3614
- // Pass false to destroyEventListeners() since deregisterCollection()
3615
- // already removes event listeners from popovers
3616
- 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);
3617
4311
  }
3618
- }
3619
- /**
3620
- * Event listeners
3621
- */
3622
- ;
4312
+ };
3623
4313
 
3624
4314
  _proto.initEventListeners = function initEventListeners(processCollection) {
3625
- var _this2 = this;
4315
+ var _this6 = this;
3626
4316
 
3627
4317
  if (processCollection === void 0) {
3628
4318
  processCollection = true;
3629
4319
  }
3630
4320
 
3631
4321
  if (processCollection) {
3632
- // Loop through collection and setup event listeners
4322
+ // Loop through collection and setup event listeners.
3633
4323
  this.collection.forEach(function (popover) {
3634
- registerEventListeners.call(_this2, popover);
4324
+ registerEventListeners.call(_this6, popover);
3635
4325
  });
3636
- } // Add keydown global event listener
4326
+ } // Add keydown global event listener.
3637
4327
 
3638
4328
 
3639
4329
  document.addEventListener('keydown', this.__handlerKeydown, false);
@@ -3645,50 +4335,33 @@ var Popover = /*#__PURE__*/function (_Collection) {
3645
4335
  }
3646
4336
 
3647
4337
  if (processCollection) {
3648
- // Loop through collection and remove event listeners
4338
+ // Loop through collection and remove event listeners.
3649
4339
  this.collection.forEach(function (popover) {
3650
4340
  deregisterEventListeners(popover);
3651
4341
  });
3652
- } // Remove keydown global event listener
4342
+ } // Remove keydown global event listener.
3653
4343
 
3654
4344
 
3655
4345
  document.removeEventListener('keydown', this.__handlerKeydown, false);
3656
- }
3657
- /**
3658
- * Register popover functionality
3659
- */
3660
- ;
4346
+ };
3661
4347
 
3662
4348
  _proto.register = function register$1(query) {
3663
4349
  var els = getPopoverElements.call(this, query);
3664
- if (!els) return false;
4350
+ if (els.error) return Promise.reject(els.error);
3665
4351
  return register.call(this, els.trigger, els.target);
3666
4352
  };
3667
4353
 
3668
- _proto.deregister = function deregister(query) {
3669
- var popover = this.get(getPopoverID(query));
3670
- if (!popover) return false;
3671
- return _deregister.call(this, popover);
3672
- }
3673
- /**
3674
- * Change state functionality
3675
- */
3676
- ;
4354
+ _proto.deregister = function deregister$1(query) {
4355
+ var popover = this.get(getPopoverID.call(this, query));
4356
+ return deregister.call(this, popover);
4357
+ };
3677
4358
 
3678
- _proto.open = function open(id) {
3679
- var popover = this.get(id);
3680
- if (!popover) return false;
3681
- return popover.open();
4359
+ _proto.open = function open$1(id) {
4360
+ return open.call(this, id);
3682
4361
  };
3683
4362
 
3684
- _proto.close = function close(id) {
3685
- if (id) {
3686
- var popover = this.get(id);
3687
- if (!popover) return false;
3688
- return popover.close();
3689
- } else {
3690
- return closeAll.call(this);
3691
- }
4363
+ _proto.close = function close$1(id) {
4364
+ return close.call(this, id);
3692
4365
  };
3693
4366
 
3694
4367
  return Popover;