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