vrembem 1.42.0 → 3.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.
@@ -1,310 +1,671 @@
1
- var setInert = function setInert(state, selector) {
2
- if (selector) {
3
- var els = document.querySelectorAll(selector);
4
- els.forEach(function (el) {
5
- if (state) {
6
- el.inert = true;
7
- el.setAttribute('aria-hidden', true);
8
- } else {
9
- el.inert = null;
10
- el.removeAttribute('aria-hidden');
1
+ function _defineProperties(target, props) {
2
+ for (var i = 0; i < props.length; i++) {
3
+ var descriptor = props[i];
4
+ descriptor.enumerable = descriptor.enumerable || false;
5
+ descriptor.configurable = true;
6
+ if ("value" in descriptor) descriptor.writable = true;
7
+ Object.defineProperty(target, descriptor.key, descriptor);
8
+ }
9
+ }
10
+
11
+ function _createClass(Constructor, protoProps, staticProps) {
12
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
13
+ if (staticProps) _defineProperties(Constructor, staticProps);
14
+ Object.defineProperty(Constructor, "prototype", {
15
+ writable: false
16
+ });
17
+ return Constructor;
18
+ }
19
+
20
+ function _extends() {
21
+ _extends = Object.assign || function (target) {
22
+ for (var i = 1; i < arguments.length; i++) {
23
+ var source = arguments[i];
24
+
25
+ for (var key in source) {
26
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
27
+ target[key] = source[key];
28
+ }
11
29
  }
30
+ }
31
+
32
+ return target;
33
+ };
34
+
35
+ return _extends.apply(this, arguments);
36
+ }
37
+
38
+ function _inheritsLoose(subClass, superClass) {
39
+ subClass.prototype = Object.create(superClass.prototype);
40
+ subClass.prototype.constructor = subClass;
41
+
42
+ _setPrototypeOf(subClass, superClass);
43
+ }
44
+
45
+ function _setPrototypeOf(o, p) {
46
+ _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
47
+ o.__proto__ = p;
48
+ return o;
49
+ };
50
+
51
+ return _setPrototypeOf(o, p);
52
+ }
53
+
54
+ function _assertThisInitialized(self) {
55
+ if (self === void 0) {
56
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
57
+ }
58
+
59
+ return self;
60
+ }
61
+
62
+ var id = 0;
63
+
64
+ function _classPrivateFieldLooseKey(name) {
65
+ return "__private_" + id++ + "_" + name;
66
+ }
67
+
68
+ function _classPrivateFieldLooseBase(receiver, privateKey) {
69
+ if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {
70
+ throw new TypeError("attempted to use private field on non-instance");
71
+ }
72
+
73
+ return receiver;
74
+ }
75
+
76
+ var _handler = /*#__PURE__*/_classPrivateFieldLooseKey("handler");
77
+
78
+ var Breakpoint = /*#__PURE__*/function () {
79
+ function Breakpoint(value, handler) {
80
+ Object.defineProperty(this, _handler, {
81
+ writable: true,
82
+ value: void 0
12
83
  });
84
+ this.value = value;
85
+ _classPrivateFieldLooseBase(this, _handler)[_handler] = handler;
86
+ this.mql = null;
13
87
  }
14
- };
15
- var setOverflowHidden = function setOverflowHidden(state, selector) {
16
- if (selector) {
17
- var els = document.querySelectorAll(selector);
18
- els.forEach(function (el) {
19
- if (state) {
20
- el.style.overflow = 'hidden';
88
+
89
+ var _proto = Breakpoint.prototype;
90
+
91
+ _proto.mount = function mount(value, handler) {
92
+ // Update passed params.
93
+ if (value) this.value = value;
94
+ if (handler) _classPrivateFieldLooseBase(this, _handler)[_handler] = handler; // Guard if no breakpoint was set.
95
+
96
+ if (!this.value) return this; // Setup and store the MediaQueryList instance.
97
+
98
+ this.mql = window.matchMedia("(min-width: " + this.value + ")"); // Conditionally use addListener() for IE11 support.
99
+
100
+ if (typeof this.mql.addEventListener === 'function') {
101
+ this.mql.addEventListener('change', _classPrivateFieldLooseBase(this, _handler)[_handler]);
102
+ } else {
103
+ this.mql.addListener(_classPrivateFieldLooseBase(this, _handler)[_handler]);
104
+ } // Run the handler.
105
+
106
+
107
+ _classPrivateFieldLooseBase(this, _handler)[_handler](this.mql);
108
+
109
+ return this;
110
+ };
111
+
112
+ _proto.unmount = function unmount() {
113
+ // Guard if no MediaQueryList instance exists.
114
+ if (!this.mql) return this; // Conditionally use removeListener() for IE11 support.
115
+
116
+ if (typeof this.mql.removeEventListener === 'function') {
117
+ this.mql.removeEventListener('change', _classPrivateFieldLooseBase(this, _handler)[_handler]);
118
+ } else {
119
+ this.mql.removeListener(_classPrivateFieldLooseBase(this, _handler)[_handler]);
120
+ } // Set value, handler and MediaQueryList to null.
121
+
122
+
123
+ this.value = null;
124
+ _classPrivateFieldLooseBase(this, _handler)[_handler] = null;
125
+ this.mql = null;
126
+ return this;
127
+ };
128
+
129
+ _createClass(Breakpoint, [{
130
+ key: "handler",
131
+ get: function get() {
132
+ return _classPrivateFieldLooseBase(this, _handler)[_handler];
133
+ } // Unmount existing handler before setting a new one.
134
+ ,
135
+ set: function set(func) {
136
+ if (this.mql) {
137
+ // Conditionally use removeListener() for IE11 support.
138
+ if (typeof this.mql.removeEventListener === 'function') {
139
+ this.mql.removeEventListener('change', _classPrivateFieldLooseBase(this, _handler)[_handler]);
140
+ } else {
141
+ this.mql.removeListener(_classPrivateFieldLooseBase(this, _handler)[_handler]);
142
+ }
143
+ }
144
+
145
+ _classPrivateFieldLooseBase(this, _handler)[_handler] = func;
146
+ }
147
+ }]);
148
+
149
+ return Breakpoint;
150
+ }();
151
+
152
+ function _settle(pact, state, value) {
153
+ if (!pact.s) {
154
+ if (value instanceof _Pact) {
155
+ if (value.s) {
156
+ if (state & 1) {
157
+ state = value.s;
158
+ }
159
+
160
+ value = value.v;
21
161
  } else {
22
- el.style.removeProperty('overflow');
162
+ value.o = _settle.bind(null, pact, state);
163
+ return;
23
164
  }
24
- });
165
+ }
166
+
167
+ if (value && value.then) {
168
+ value.then(_settle.bind(null, pact, state), _settle.bind(null, pact, 2));
169
+ return;
170
+ }
171
+
172
+ pact.s = state;
173
+ pact.v = value;
174
+ var observer = pact.o;
175
+
176
+ if (observer) {
177
+ observer(pact);
178
+ }
25
179
  }
26
- };
27
- var setTabindex = function setTabindex(selector) {
28
- if (selector) {
29
- var els = document.querySelectorAll(selector);
30
- els.forEach(function (el) {
31
- el.setAttribute('tabindex', '-1');
32
- });
180
+ }
181
+
182
+ var _Pact = /*#__PURE__*/function () {
183
+ function _Pact() {}
184
+
185
+ _Pact.prototype.then = function (onFulfilled, onRejected) {
186
+ var result = new _Pact();
187
+ var state = this.s;
188
+
189
+ if (state) {
190
+ var callback = state & 1 ? onFulfilled : onRejected;
191
+
192
+ if (callback) {
193
+ try {
194
+ _settle(result, 1, callback(this.v));
195
+ } catch (e) {
196
+ _settle(result, 2, e);
197
+ }
198
+
199
+ return result;
200
+ } else {
201
+ return this;
202
+ }
203
+ }
204
+
205
+ this.o = function (_this) {
206
+ try {
207
+ var value = _this.v;
208
+
209
+ if (_this.s & 1) {
210
+ _settle(result, 1, onFulfilled ? onFulfilled(value) : value);
211
+ } else if (onRejected) {
212
+ _settle(result, 1, onRejected(value));
213
+ } else {
214
+ _settle(result, 2, value);
215
+ }
216
+ } catch (e) {
217
+ _settle(result, 2, e);
218
+ }
219
+ };
220
+
221
+ return result;
222
+ };
223
+
224
+ return _Pact;
225
+ }();
226
+
227
+ function _isSettledPact(thenable) {
228
+ return thenable instanceof _Pact && thenable.s & 1;
229
+ }
230
+
231
+ function _for(test, update, body) {
232
+ var stage;
233
+
234
+ for (;;) {
235
+ var shouldContinue = test();
236
+
237
+ if (_isSettledPact(shouldContinue)) {
238
+ shouldContinue = shouldContinue.v;
239
+ }
240
+
241
+ if (!shouldContinue) {
242
+ return result;
243
+ }
244
+
245
+ if (shouldContinue.then) {
246
+ stage = 0;
247
+ break;
248
+ }
249
+
250
+ var result = body();
251
+
252
+ if (result && result.then) {
253
+ if (_isSettledPact(result)) {
254
+ result = result.s;
255
+ } else {
256
+ stage = 1;
257
+ break;
258
+ }
259
+ }
260
+
261
+ if (update) {
262
+ var updateValue = update();
263
+
264
+ if (updateValue && updateValue.then && !_isSettledPact(updateValue)) {
265
+ stage = 2;
266
+ break;
267
+ }
268
+ }
33
269
  }
34
- };
35
270
 
36
- /**
37
- * Adds a class or classes to a Node or NodeList.
38
- * @param {Node || NodeList} el - Element(s) to add class(es) to.
39
- * @param {String || Array} cl - Class(es) to add.
40
- */
41
- var addClass = function addClass(el) {
42
- var _arguments = arguments;
43
- el = el.forEach ? el : [el];
44
- el.forEach(function (el) {
45
- var _el$classList;
271
+ var pact = new _Pact();
46
272
 
47
- (_el$classList = el.classList).add.apply(_el$classList, [].slice.call(_arguments, 1));
48
- });
49
- };
273
+ var reject = _settle.bind(null, pact, 2);
50
274
 
51
- /**
52
- * Takes a hyphen cased string and converts it to camel case.
53
- * @param {String } str - the string to convert to camel case.
54
- * @returns {Boolean} - returns a camel cased string.
55
- */
56
- var camelCase = function camelCase(str) {
57
- return str.replace(/-([a-z])/g, function (g) {
58
- return g[1].toUpperCase();
59
- });
60
- };
275
+ (stage === 0 ? shouldContinue.then(_resumeAfterTest) : stage === 1 ? result.then(_resumeAfterBody) : updateValue.then(_resumeAfterUpdate)).then(void 0, reject);
276
+ return pact;
61
277
 
62
- 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^="-"])'];
278
+ function _resumeAfterBody(value) {
279
+ result = value;
63
280
 
64
- var focusTarget = function focusTarget(target, settings) {
65
- var innerFocus = target.querySelector("[data-" + settings.dataFocus + "]");
281
+ do {
282
+ if (update) {
283
+ updateValue = update();
66
284
 
67
- if (innerFocus) {
68
- innerFocus.focus();
69
- } else {
70
- var innerElement = target.querySelector('[tabindex="-1"]');
71
- if (innerElement) innerElement.focus();
285
+ if (updateValue && updateValue.then && !_isSettledPact(updateValue)) {
286
+ updateValue.then(_resumeAfterUpdate).then(void 0, reject);
287
+ return;
288
+ }
289
+ }
290
+
291
+ shouldContinue = test();
292
+
293
+ if (!shouldContinue || _isSettledPact(shouldContinue) && !shouldContinue.v) {
294
+ _settle(pact, 1, result);
295
+
296
+ return;
297
+ }
298
+
299
+ if (shouldContinue.then) {
300
+ shouldContinue.then(_resumeAfterTest).then(void 0, reject);
301
+ return;
302
+ }
303
+
304
+ result = body();
305
+
306
+ if (_isSettledPact(result)) {
307
+ result = result.v;
308
+ }
309
+ } while (!result || !result.then);
310
+
311
+ result.then(_resumeAfterBody).then(void 0, reject);
72
312
  }
73
- };
74
- var focusTrigger = function focusTrigger(obj) {
75
- if (obj === void 0) {
76
- obj = null;
313
+
314
+ function _resumeAfterTest(shouldContinue) {
315
+ if (shouldContinue) {
316
+ result = body();
317
+
318
+ if (result && result.then) {
319
+ result.then(_resumeAfterBody).then(void 0, reject);
320
+ } else {
321
+ _resumeAfterBody(result);
322
+ }
323
+ } else {
324
+ _settle(pact, 1, result);
325
+ }
77
326
  }
78
327
 
79
- if (!obj || !obj.memory || !obj.memory.trigger) return;
80
- obj.memory.trigger.focus();
81
- obj.memory.trigger = null;
82
- };
83
- var FocusTrap = /*#__PURE__*/function () {
84
- function FocusTrap() {
85
- this.target = null;
86
- this.__handlerFocusTrap = this.handlerFocusTrap.bind(this);
328
+ function _resumeAfterUpdate() {
329
+ if (shouldContinue = test()) {
330
+ if (shouldContinue.then) {
331
+ shouldContinue.then(_resumeAfterTest).then(void 0, reject);
332
+ } else {
333
+ _resumeAfterTest(shouldContinue);
334
+ }
335
+ } else {
336
+ _settle(pact, 1, result);
337
+ }
87
338
  }
339
+ }
88
340
 
89
- var _proto = FocusTrap.prototype;
341
+ var Collection = /*#__PURE__*/function () {
342
+ function Collection() {
343
+ this.collection = [];
344
+ }
90
345
 
91
- _proto.init = function init(target) {
92
- this.target = target;
93
- this.inner = this.target.querySelector('[tabindex="-1"]');
94
- this.focusable = this.getFocusable();
346
+ var _proto = Collection.prototype;
95
347
 
96
- if (this.focusable.length) {
97
- this.focusableFirst = this.focusable[0];
98
- this.focusableLast = this.focusable[this.focusable.length - 1];
99
- this.target.addEventListener('keydown', this.__handlerFocusTrap);
100
- } else {
101
- this.target.addEventListener('keydown', this.handlerFocusLock);
348
+ _proto.register = function register(item) {
349
+ try {
350
+ var _this2 = this;
351
+
352
+ return Promise.resolve(_this2.deregister(item)).then(function () {
353
+ _this2.collection.push(item);
354
+
355
+ return _this2.collection;
356
+ });
357
+ } catch (e) {
358
+ return Promise.reject(e);
102
359
  }
103
360
  };
104
361
 
105
- _proto.destroy = function destroy() {
106
- if (!this.target) return;
107
- this.inner = null;
108
- this.focusable = null;
109
- this.focusableFirst = null;
110
- this.focusableLast = null;
111
- this.target.removeEventListener('keydown', this.__handlerFocusTrap);
112
- this.target.removeEventListener('keydown', this.handlerFocusLock);
113
- this.target = null;
114
- };
115
-
116
- _proto.refresh = function refresh() {
117
- // Check if a target has been set
118
- if (!this.target) return; // Remove existing events
119
-
120
- this.target.removeEventListener('keydown', this.__handlerFocusTrap);
121
- this.target.removeEventListener('keydown', this.handlerFocusLock); // Get the focusable elements
122
-
123
- this.focusable = this.getFocusable(); // Setup the focus handlers based on focusable length
124
-
125
- if (this.focusable.length) {
126
- // If there are focusable elements, setup focus trap
127
- this.focusableFirst = this.focusable[0];
128
- this.focusableLast = this.focusable[this.focusable.length - 1];
129
- this.target.addEventListener('keydown', this.__handlerFocusTrap);
130
- } else {
131
- // If there are no focusable elements, setup focus lock
132
- this.focusableFirst = null;
133
- this.focusableLast = null;
134
- this.target.addEventListener('keydown', this.handlerFocusLock);
362
+ _proto.deregister = function deregister(ref) {
363
+ try {
364
+ var _this4 = this;
365
+
366
+ var index = _this4.collection.findIndex(function (entry) {
367
+ return entry === ref;
368
+ });
369
+
370
+ if (index >= 0) {
371
+ var entry = _this4.collection[index];
372
+ Object.getOwnPropertyNames(entry).forEach(function (prop) {
373
+ delete entry[prop];
374
+ });
375
+
376
+ _this4.collection.splice(index, 1);
377
+ }
378
+
379
+ return Promise.resolve(_this4.collection);
380
+ } catch (e) {
381
+ return Promise.reject(e);
135
382
  }
136
383
  };
137
384
 
138
- _proto.handlerFocusTrap = function handlerFocusTrap(event) {
139
- var isTab = event.key === 'Tab' || event.keyCode === 9;
140
- if (!isTab) return;
385
+ _proto.registerCollection = function registerCollection(items) {
386
+ try {
387
+ var _this6 = this;
141
388
 
142
- if (event.shiftKey) {
143
- if (document.activeElement === this.focusableFirst || document.activeElement === this.inner) {
144
- this.focusableLast.focus();
145
- event.preventDefault();
146
- }
147
- } else {
148
- if (document.activeElement === this.focusableLast || document.activeElement === this.inner) {
149
- this.focusableFirst.focus();
150
- event.preventDefault();
151
- }
389
+ return Promise.resolve(Promise.all(Array.from(items, function (item) {
390
+ _this6.register(item);
391
+ }))).then(function () {
392
+ return _this6.collection;
393
+ });
394
+ } catch (e) {
395
+ return Promise.reject(e);
396
+ }
397
+ };
398
+
399
+ _proto.deregisterCollection = function deregisterCollection() {
400
+ try {
401
+ var _temp3 = function _temp3() {
402
+ return _this8.collection;
403
+ };
404
+
405
+ var _this8 = this;
406
+
407
+ var _temp4 = _for(function () {
408
+ return _this8.collection.length > 0;
409
+ }, void 0, function () {
410
+ return Promise.resolve(_this8.deregister(_this8.collection[0])).then(function () {});
411
+ });
412
+
413
+ return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(_temp3) : _temp3(_temp4));
414
+ } catch (e) {
415
+ return Promise.reject(e);
416
+ }
417
+ };
418
+
419
+ _proto.get = function get(value, key) {
420
+ if (key === void 0) {
421
+ key = 'id';
422
+ }
423
+
424
+ return this.collection.find(function (item) {
425
+ return item[key] === value;
426
+ });
427
+ };
428
+
429
+ return Collection;
430
+ }();
431
+
432
+ 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^="-"])'];
433
+
434
+ var _focusable = /*#__PURE__*/_classPrivateFieldLooseKey("focusable");
435
+
436
+ var _handleFocusTrap = /*#__PURE__*/_classPrivateFieldLooseKey("handleFocusTrap");
437
+
438
+ var _handleFocusLock = /*#__PURE__*/_classPrivateFieldLooseKey("handleFocusLock");
439
+
440
+ var FocusTrap = /*#__PURE__*/function () {
441
+ function FocusTrap(el, selectorFocus) {
442
+ if (el === void 0) {
443
+ el = null;
152
444
  }
445
+
446
+ if (selectorFocus === void 0) {
447
+ selectorFocus = '[data-focus]';
448
+ }
449
+
450
+ Object.defineProperty(this, _focusable, {
451
+ writable: true,
452
+ value: void 0
453
+ });
454
+ Object.defineProperty(this, _handleFocusTrap, {
455
+ writable: true,
456
+ value: void 0
457
+ });
458
+ Object.defineProperty(this, _handleFocusLock, {
459
+ writable: true,
460
+ value: void 0
461
+ });
462
+ this.el = el;
463
+ this.selectorFocus = selectorFocus;
464
+ _classPrivateFieldLooseBase(this, _handleFocusTrap)[_handleFocusTrap] = handleFocusTrap.bind(this);
465
+ _classPrivateFieldLooseBase(this, _handleFocusLock)[_handleFocusLock] = handleFocusLock.bind(this);
466
+ }
467
+
468
+ var _proto = FocusTrap.prototype;
469
+
470
+ _proto.mount = function mount(el, selectorFocus) {
471
+ // Update passed params.
472
+ if (el) this.el = el;
473
+ if (selectorFocus) this.selectorFocus = selectorFocus; // Get the focusable elements.
474
+
475
+ this.focusable = this.getFocusable(); // Set the focus on the element.
476
+
477
+ this.focus();
153
478
  };
154
479
 
155
- _proto.handlerFocusLock = function handlerFocusLock(event) {
156
- var isTab = event.key === 'Tab' || event.keyCode === 9;
157
- if (isTab) event.preventDefault();
480
+ _proto.unmount = function unmount() {
481
+ // Set element to null.
482
+ this.el = null; // Apply empty array to focusable.
483
+
484
+ this.focusable = []; // Remove event listeners
485
+
486
+ document.removeEventListener('keydown', _classPrivateFieldLooseBase(this, _handleFocusTrap)[_handleFocusTrap]);
487
+ document.removeEventListener('keydown', _classPrivateFieldLooseBase(this, _handleFocusLock)[_handleFocusLock]);
158
488
  };
159
489
 
160
- _proto.getFocusable = function getFocusable() {
161
- var focusable = [];
490
+ _proto.focus = function focus(el, selectorFocus) {
491
+ if (el === void 0) {
492
+ el = this.el;
493
+ }
494
+
495
+ if (selectorFocus === void 0) {
496
+ selectorFocus = this.selectorFocus;
497
+ }
498
+
499
+ // Query for the focus selector, otherwise return this element.
500
+ var result = el.querySelector(selectorFocus) || el; // Give the returned element focus.
501
+
502
+ result.focus();
503
+ };
504
+
505
+ _proto.getFocusable = function getFocusable(el) {
506
+ if (el === void 0) {
507
+ el = this.el;
508
+ }
509
+
510
+ // Initialize the focusable array.
511
+ var focusable = []; // Store the initial focus and scroll position.
512
+
162
513
  var initFocus = document.activeElement;
163
- var initScrollTop = this.inner ? this.inner.scrollTop : 0;
164
- this.target.querySelectorAll(focusableSelectors.join(',')).forEach(function (el) {
165
- el.focus();
514
+ var initScrollTop = el.scrollTop; // Query for all the focusable elements.
515
+
516
+ var els = el.querySelectorAll(focusableSelectors.join(',')); // Loop through all focusable elements.
166
517
 
167
- if (el === document.activeElement) {
518
+ els.forEach(function (el) {
519
+ // Set them to focus and check
520
+ el.focus(); // Test that the element took focus.
521
+
522
+ if (document.activeElement === el) {
523
+ // Add element to the focusable array.
168
524
  focusable.push(el);
169
525
  }
170
- });
171
- if (this.inner) this.inner.scrollTop = initScrollTop;
172
- initFocus.focus();
526
+ }); // Restore the initial scroll position and focus.
527
+
528
+ el.scrollTop = initScrollTop;
529
+ initFocus.focus(); // Return the focusable array.
530
+
173
531
  return focusable;
174
532
  };
175
533
 
534
+ _createClass(FocusTrap, [{
535
+ key: "focusable",
536
+ get: function get() {
537
+ return _classPrivateFieldLooseBase(this, _focusable)[_focusable];
538
+ },
539
+ set: function set(value) {
540
+ // Update the focusable value.
541
+ _classPrivateFieldLooseBase(this, _focusable)[_focusable] = value; // Apply event listeners based on new focusable array length.
542
+
543
+ if (_classPrivateFieldLooseBase(this, _focusable)[_focusable].length) {
544
+ document.removeEventListener('keydown', _classPrivateFieldLooseBase(this, _handleFocusLock)[_handleFocusLock]);
545
+ document.addEventListener('keydown', _classPrivateFieldLooseBase(this, _handleFocusTrap)[_handleFocusTrap]);
546
+ } else {
547
+ document.removeEventListener('keydown', _classPrivateFieldLooseBase(this, _handleFocusTrap)[_handleFocusTrap]);
548
+ document.addEventListener('keydown', _classPrivateFieldLooseBase(this, _handleFocusLock)[_handleFocusLock]);
549
+ }
550
+ }
551
+ }, {
552
+ key: "focusableFirst",
553
+ get: function get() {
554
+ return this.focusable[0];
555
+ }
556
+ }, {
557
+ key: "focusableLast",
558
+ get: function get() {
559
+ return this.focusable[this.focusable.length - 1];
560
+ }
561
+ }]);
562
+
176
563
  return FocusTrap;
177
564
  }();
178
565
 
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;
566
+ function handleFocusTrap(event) {
567
+ // Check if the click was a tab and return if not.
568
+ var isTab = event.key === 'Tab' || event.keyCode === 9;
569
+ if (!isTab) return; // If the shift key is pressed.
570
+
571
+ if (event.shiftKey) {
572
+ // If the active element is either the root el or first focusable.
573
+ if (document.activeElement === this.focusableFirst || document.activeElement === this.el) {
574
+ // Prevent default and focus the last focusable element instead.
575
+ event.preventDefault();
576
+ this.focusableLast.focus();
577
+ }
578
+ } else {
579
+ // If the active element is either the root el or last focusable.
580
+ if (document.activeElement === this.focusableLast || document.activeElement === this.el) {
581
+ // Prevent default and focus the first focusable element instead.
582
+ event.preventDefault();
583
+ this.focusableFirst.focus();
584
+ }
187
585
  }
586
+ }
188
587
 
189
- if (typeof selector !== 'string') return selector;
190
- return single ? document.querySelector(selector) : document.querySelectorAll(selector);
191
- };
588
+ function handleFocusLock(event) {
589
+ // Ignore the tab key by preventing default.
590
+ var isTab = event.key === 'Tab' || event.keyCode === 9;
591
+ if (isTab) event.preventDefault();
592
+ }
192
593
 
193
- /**
194
- * Checks an element or NodeList whether they contain a class or classes.
195
- * Ref: https://davidwalsh.name/nodelist-array
196
- * @param {Node} el - Element(s) to check class(es) on.
197
- * @param {String || Array} c - Class(es) to check.
198
- * @returns {Boolean} - Returns true if class exists, otherwise false.
199
- */
200
- var hasClass = function hasClass(el) {
201
- el = el.forEach ? el : [el];
202
- el = [].slice.call(el);
203
- return [].slice.call(arguments, 1).some(function (cl) {
204
- return el.some(function (el) {
205
- if (el.classList.contains(cl)) return true;
206
- });
207
- });
208
- };
594
+ function getConfig$1(el, dataConfig) {
595
+ var string = el.getAttribute("data-" + dataConfig) || '';
596
+ var json = string.replace(/'/g, '"');
597
+ return json ? JSON.parse(json) : {};
598
+ }
209
599
 
210
- /**
211
- * Takes a camel cased string and converts it to hyphen case.
212
- * @param {String } str - the string to convert to hyphen case.
213
- * @returns {Boolean} - returns a hyphen cased string.
214
- */
215
- var hyphenCase = function hyphenCase(str) {
216
- return str.replace(/([a-z][A-Z])/g, function (g) {
217
- return g[0] + '-' + g[1].toLowerCase();
600
+ function localStore(key, enable) {
601
+ if (enable === void 0) {
602
+ enable = true;
603
+ }
604
+
605
+ function getStore() {
606
+ var value = localStorage.getItem(key);
607
+ return value ? JSON.parse(value) : {};
608
+ }
609
+
610
+ function setStore(obj) {
611
+ localStorage.setItem(key, JSON.stringify(obj));
612
+ }
613
+
614
+ return new Proxy(getStore(), {
615
+ set: function set(target, property, value) {
616
+ target[property] = value;
617
+ if (enable) setStore(target);
618
+ return true;
619
+ },
620
+ deleteProperty: function deleteProperty(target, property) {
621
+ delete target[property];
622
+ if (enable) setStore(target);
623
+ return true;
624
+ }
218
625
  });
219
- };
626
+ }
220
627
 
221
628
  /**
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.
629
+ * Teleports an element in the DOM based on a reference and teleport method.
630
+ * Provide the comment node as the reference to teleport the element back to its
631
+ * previous location.
632
+ * @param {Node} what - What element to teleport.
633
+ * @param {String || Node} where - Where to teleport the element.
634
+ * @param {String} how - How (method) to teleport the element, e.g: 'after',
635
+ * 'before', 'append' or 'prepend'.
636
+ * @return {Node} Return the return reference if it was teleported else return
637
+ * null if it was returned to a comment reference.
226
638
  */
639
+ function teleport(what, where, how) {
640
+ // Check if ref is either a comment or element node.
641
+ var isComment = where.nodeType === Node.COMMENT_NODE;
642
+ var isElement = where.nodeType === Node.ELEMENT_NODE; // Get the reference element.
227
643
 
228
- function moveElement(target, type, reference) {
229
- if (reference === void 0) {
230
- reference = false;
231
- }
644
+ where = isComment || isElement ? where : document.querySelector(where); // If ref is a comment, set teleport type to 'after'.
232
645
 
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
- }
646
+ if (isComment) how = 'after'; // Must be a valid reference element and method.
647
+
648
+ if (!where) throw new Error("Not a valid teleport reference: '" + where + "'");
649
+ if (typeof where[how] != 'function') throw new Error("Not a valid teleport method: '" + how + "'"); // Initial return ref is null.
650
+
651
+ var returnRef = null; // If ref is not a comment, set a return reference comment.
652
+
653
+ if (!isComment) {
654
+ returnRef = document.createComment('teleported #' + what.id);
655
+ what.before(returnRef);
656
+ } // Teleport the target node.
278
657
 
279
- /**
280
- * Remove a class or classes from an element or NodeList.
281
- * @param {Node || NodeList} el - Element(s) to remove class(es) from.
282
- * @param {String || Array} cl - Class(es) to remove.
283
- */
284
- var removeClass = function removeClass(el) {
285
- var _arguments = arguments;
286
- el = el.forEach ? el : [el];
287
- el.forEach(function (el) {
288
- var _el$classList;
289
658
 
290
- (_el$classList = el.classList).remove.apply(_el$classList, [].slice.call(_arguments, 1));
291
- });
292
- };
659
+ where[how](what); // Delete the comment node if element was returned to a comment reference.
293
660
 
294
- /**
295
- * Toggle a class or classes on an element or NodeList.
296
- * @param {Node || NodeList} el - Element(s) to toggle class(es) on.
297
- * @param {String || Array} cl - Class(es) to toggle.
298
- */
299
- var toggleClass = function toggleClass(el) {
300
- var _arguments = arguments;
301
- el = el.forEach ? el : [el];
302
- el.forEach(function (el) {
303
- [].slice.call(_arguments, 1).forEach(function (cl) {
304
- el.classList.toggle(cl);
305
- });
306
- });
307
- };
661
+ if (isComment) {
662
+ where.remove();
663
+ } // Return the return reference if it was teleported else return null if it was
664
+ // returned to a comment reference.
665
+
666
+
667
+ return returnRef;
668
+ }
308
669
 
309
670
  var openTransition = function openTransition(el, settings) {
310
671
  return new Promise(function (resolve) {
@@ -343,67 +704,53 @@ var closeTransition = function closeTransition(el, settings) {
343
704
  });
344
705
  };
345
706
 
346
- var index = {
347
- __proto__: null,
348
- setInert: setInert,
349
- setOverflowHidden: setOverflowHidden,
350
- setTabindex: setTabindex,
351
- addClass: addClass,
352
- camelCase: camelCase,
353
- focusTarget: focusTarget,
354
- focusTrigger: focusTrigger,
355
- FocusTrap: FocusTrap,
356
- getElement: getElement,
357
- hasClass: hasClass,
358
- hyphenCase: hyphenCase,
359
- moveElement: moveElement,
360
- removeClass: removeClass,
361
- toggleClass: toggleClass,
362
- openTransition: openTransition,
363
- closeTransition: closeTransition
364
- };
365
-
366
- function _extends() {
367
- _extends = Object.assign || function (target) {
368
- for (var i = 1; i < arguments.length; i++) {
369
- var source = arguments[i];
370
-
371
- for (var key in source) {
372
- if (Object.prototype.hasOwnProperty.call(source, key)) {
373
- target[key] = source[key];
374
- }
707
+ function setOverflowHidden(state, selector) {
708
+ if (selector) {
709
+ var els = document.querySelectorAll(selector);
710
+ els.forEach(function (el) {
711
+ if (state) {
712
+ el.style.overflow = 'hidden';
713
+ } else {
714
+ el.style.removeProperty('overflow');
375
715
  }
376
- }
377
-
378
- return target;
379
- };
380
-
381
- return _extends.apply(this, arguments);
716
+ });
717
+ }
382
718
  }
383
719
 
384
- function _inheritsLoose(subClass, superClass) {
385
- subClass.prototype = Object.create(superClass.prototype);
386
- subClass.prototype.constructor = subClass;
387
-
388
- _setPrototypeOf(subClass, superClass);
720
+ function setInert(state, selector) {
721
+ if (selector) {
722
+ var els = document.querySelectorAll(selector);
723
+ els.forEach(function (el) {
724
+ if (state) {
725
+ el.inert = true;
726
+ el.setAttribute('aria-hidden', true);
727
+ } else {
728
+ el.inert = null;
729
+ el.removeAttribute('aria-hidden');
730
+ }
731
+ });
732
+ }
389
733
  }
390
734
 
391
- function _setPrototypeOf(o, p) {
392
- _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
393
- o.__proto__ = p;
394
- return o;
395
- };
735
+ function updateGlobalState(param, config) {
736
+ // Set inert state based on if a modal is active.
737
+ setInert(!!param, config.selectorInert); // Set overflow state based on if a modal is active.
396
738
 
397
- return _setPrototypeOf(o, p);
739
+ setOverflowHidden(!!param, config.selectorOverflow);
398
740
  }
399
741
 
400
- function _assertThisInitialized(self) {
401
- if (self === void 0) {
402
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
403
- }
404
-
405
- return self;
406
- }
742
+ var index = {
743
+ __proto__: null,
744
+ Breakpoint: Breakpoint,
745
+ Collection: Collection,
746
+ FocusTrap: FocusTrap,
747
+ getConfig: getConfig$1,
748
+ localStore: localStore,
749
+ teleport: teleport,
750
+ openTransition: openTransition,
751
+ closeTransition: closeTransition,
752
+ updateGlobalState: updateGlobalState
753
+ };
407
754
 
408
755
  var defaults$3 = {
409
756
  autoInit: false,
@@ -458,1027 +805,1494 @@ var Checkbox = /*#__PURE__*/function () {
458
805
  });
459
806
  };
460
807
 
461
- _proto.removeAriaState = function removeAriaState(el) {
808
+ _proto.removeAriaState = function removeAriaState(el) {
809
+ var _this2 = this;
810
+
811
+ el = el.forEach ? el : [el];
812
+ el.forEach(function (el) {
813
+ el.removeAttribute(_this2.settings.stateAttr);
814
+ });
815
+ };
816
+
817
+ _proto.setIndeterminate = function setIndeterminate(el) {
818
+ var _this3 = this;
819
+
820
+ el = el.forEach ? el : [el];
821
+ el.forEach(function (el) {
822
+ if (el.hasAttribute(_this3.settings.stateAttr)) {
823
+ el.indeterminate = true;
824
+ } else {
825
+ el.indeterminate = false;
826
+ }
827
+ });
828
+ };
829
+
830
+ return Checkbox;
831
+ }();
832
+
833
+ var defaults$2 = {
834
+ autoInit: false,
835
+ // Data attributes
836
+ dataOpen: 'drawer-open',
837
+ dataClose: 'drawer-close',
838
+ dataToggle: 'drawer-toggle',
839
+ dataBreakpoint: 'drawer-breakpoint',
840
+ dataConfig: 'drawer-config',
841
+ // Selectors
842
+ selectorDrawer: '.drawer',
843
+ selectorDialog: '.drawer__dialog',
844
+ selectorFocus: '[data-focus]',
845
+ selectorInert: null,
846
+ selectorOverflow: 'body',
847
+ // State classes
848
+ stateOpened: 'is-opened',
849
+ stateOpening: 'is-opening',
850
+ stateClosing: 'is-closing',
851
+ stateClosed: 'is-closed',
852
+ // Classes
853
+ classModal: 'drawer_modal',
854
+ // Feature toggles
855
+ breakpoints: null,
856
+ customEventPrefix: 'drawer:',
857
+ eventListeners: true,
858
+ store: true,
859
+ storeKey: 'VB:DrawerState',
860
+ setTabindex: true,
861
+ transition: true
862
+ };
863
+
864
+ function handleClick$2(event) {
865
+ var _this = this;
866
+
867
+ // If an open, close or toggle button was clicked, handle the click event.
868
+ var trigger = event.target.closest("\n [data-" + this.settings.dataOpen + "],\n [data-" + this.settings.dataToggle + "],\n [data-" + this.settings.dataClose + "]\n ");
869
+
870
+ if (trigger) {
871
+ // Prevent the default behavior of the trigger.
872
+ event.preventDefault(); // If it's a toggle trigger...
873
+
874
+ if (trigger.matches("[data-" + this.settings.dataToggle + "]")) {
875
+ var selectors = trigger.getAttribute("data-" + this.settings.dataToggle).trim().split(' ');
876
+ selectors.forEach(function (selector) {
877
+ // Get the entry from collection using the attribute value.
878
+ var entry = _this.get(selector); // Store the trigger on the entry.
879
+
880
+
881
+ entry.trigger = trigger; // Toggle the drawer
882
+
883
+ entry.toggle();
884
+ });
885
+ } // If it's a open trigger...
886
+
887
+
888
+ if (trigger.matches("[data-" + this.settings.dataOpen + "]")) {
889
+ var _selectors = trigger.getAttribute("data-" + this.settings.dataOpen).trim().split(' ');
890
+
891
+ _selectors.forEach(function (selector) {
892
+ // Get the entry from collection using the attribute value.
893
+ var entry = _this.get(selector); // Store the trigger on the entry.
894
+
895
+
896
+ entry.trigger = trigger; // Open the drawer.
897
+
898
+ entry.open();
899
+ });
900
+ } // If it's a close trigger...
901
+
902
+
903
+ if (trigger.matches("[data-" + this.settings.dataClose + "]")) {
904
+ var _selectors2 = trigger.getAttribute("data-" + this.settings.dataClose).trim().split(' ');
905
+
906
+ _selectors2.forEach(function (selector) {
907
+ if (selector) {
908
+ // Get the entry from collection using the attribute value.
909
+ var entry = _this.get(selector); // Store the trigger on the entry.
910
+
911
+
912
+ entry.trigger = trigger; // Close the drawer.
913
+
914
+ entry.close();
915
+ } else {
916
+ // If no value is set on close trigger, get the parent drawer.
917
+ var parent = event.target.closest(_this.settings.selectorDrawer); // If a parent drawer was found, close it.
918
+
919
+ if (parent) _this.close(parent);
920
+ }
921
+ });
922
+ }
923
+
924
+ return;
925
+ } // If the modal drawer screen was clicked...
926
+
927
+
928
+ if (event.target.matches(this.settings.selectorDrawer)) {
929
+ // Close the modal drawer.
930
+ this.close(event.target.id);
931
+ }
932
+ }
933
+ function handleKeydown$2(event) {
934
+ if (event.key === 'Escape') {
935
+ var modal = this.activeModal;
936
+ if (modal) this.close(modal);
937
+ }
938
+ }
939
+
940
+ var deregister$2 = function deregister(obj, close) {
941
+ if (close === void 0) {
942
+ close = true;
943
+ }
944
+
945
+ try {
946
+ var _temp5 = function _temp5() {
947
+ // Return the modified collection.
948
+ return _this2.collection;
949
+ };
950
+
951
+ var _this2 = this;
952
+
953
+ // Return collection if nothing was passed.
954
+ if (!obj) return Promise.resolve(_this2.collection); // Check if entry has been registered in the collection.
955
+
956
+ var index = _this2.collection.findIndex(function (entry) {
957
+ return entry.id === obj.id;
958
+ });
959
+
960
+ var _temp6 = function () {
961
+ if (index >= 0) {
962
+ var _temp7 = function _temp7() {
963
+ // Remove entry from local store.
964
+ delete _this2.store[_entry.id]; // Unmount the MatchMedia functionality.
965
+
966
+ _entry.unmountBreakpoint(); // Delete properties from collection entry.
967
+
968
+
969
+ Object.getOwnPropertyNames(_entry).forEach(function (prop) {
970
+ delete _entry[prop];
971
+ }); // Remove entry from collection.
972
+
973
+ _this2.collection.splice(index, 1);
974
+ };
975
+
976
+ // Get the collection entry.
977
+ var _entry = _this2.collection[index]; // If entry is in the opened state.
978
+
979
+ var _temp8 = function () {
980
+ if (close && _entry.state === 'opened') {
981
+ // Close the drawer.
982
+ return Promise.resolve(_entry.close(false)).then(function () {});
983
+ }
984
+ }();
985
+
986
+ return _temp8 && _temp8.then ? _temp8.then(_temp7) : _temp7(_temp8);
987
+ }
988
+ }();
989
+
990
+ return Promise.resolve(_temp6 && _temp6.then ? _temp6.then(_temp5) : _temp5(_temp6));
991
+ } catch (e) {
992
+ return Promise.reject(e);
993
+ }
994
+ };
995
+
996
+ function getBreakpoint(drawer) {
997
+ var prefix = getVariablePrefix();
998
+ var bp = drawer.getAttribute("data-" + this.settings.dataBreakpoint);
999
+
1000
+ if (this.settings.breakpoints && this.settings.breakpoints[bp]) {
1001
+ return this.settings.breakpoints[bp];
1002
+ } else if (getComputedStyle(document.body).getPropertyValue(prefix + bp)) {
1003
+ return getComputedStyle(document.body).getPropertyValue(prefix + bp);
1004
+ } else {
1005
+ return bp;
1006
+ }
1007
+ }
1008
+
1009
+ function getVariablePrefix() {
1010
+ var prefix = '--';
1011
+ prefix += getComputedStyle(document.body).getPropertyValue('--vrembem-variable-prefix');
1012
+ prefix += 'breakpoint-';
1013
+ return prefix;
1014
+ }
1015
+
1016
+ function getDrawer(query) {
1017
+ // Get the entry from collection.
1018
+ var entry = typeof query === 'string' ? this.get(query) : this.get(query.id); // Return entry if it was resolved, otherwise throw error.
1019
+
1020
+ if (entry) {
1021
+ return entry;
1022
+ } else {
1023
+ throw new Error("Drawer not found in collection with id of \"" + (query.id || query) + "\".");
1024
+ }
1025
+ }
1026
+
1027
+ function getDrawerID(obj) {
1028
+ // If it's a string, return the string.
1029
+ if (typeof obj === 'string') {
1030
+ return obj;
1031
+ } // If it's an HTML element.
1032
+ else if (typeof obj.hasAttribute === 'function') {
1033
+ // If it's a drawer open trigger, return data value.
1034
+ if (obj.hasAttribute("data-" + this.settings.dataOpen)) {
1035
+ return obj.getAttribute("data-" + this.settings.dataOpen);
1036
+ } // If it's a drawer close trigger, return data value or false.
1037
+ else if (obj.hasAttribute("data-" + this.settings.dataClose)) {
1038
+ return obj.getAttribute("data-" + this.settings.dataClose) || false;
1039
+ } // If it's a drawer toggle trigger, return data value.
1040
+ else if (obj.hasAttribute("data-" + this.settings.dataToggle)) {
1041
+ return obj.getAttribute("data-" + this.settings.dataToggle);
1042
+ } // If it's a drawer element, return the id.
1043
+ else if (obj.closest(this.settings.selectorDrawer)) {
1044
+ obj = obj.closest(this.settings.selectorDrawer);
1045
+ return obj.id || false;
1046
+ } // Return false if no id was found.
1047
+ else return false;
1048
+ } // If it has an id property, return its value.
1049
+ else if (obj.id) {
1050
+ return obj.id;
1051
+ } // Return false if no id was found.
1052
+ else return false;
1053
+ }
1054
+
1055
+ function getDrawerElements(query) {
1056
+ var id = getDrawerID.call(this, query);
1057
+
1058
+ if (id) {
1059
+ var drawer = document.querySelector("#" + id);
1060
+ var dialog = drawer ? drawer.querySelector(this.settings.selectorDialog) : null;
1061
+
1062
+ if (!drawer && !dialog) {
1063
+ return {
1064
+ error: new Error("No drawer elements found using the ID: \"" + id + "\".")
1065
+ };
1066
+ } else if (!dialog) {
1067
+ return {
1068
+ error: new Error('Drawer is missing dialog element.')
1069
+ };
1070
+ } else {
1071
+ return {
1072
+ drawer: drawer,
1073
+ dialog: dialog
1074
+ };
1075
+ }
1076
+ } else {
1077
+ return {
1078
+ error: new Error('Could not resolve the drawer ID.')
1079
+ };
1080
+ }
1081
+ }
1082
+
1083
+ var initialState = function initialState(entry) {
1084
+ try {
1085
+ var _this2 = this;
1086
+
1087
+ var _temp3 = function () {
1088
+ if (_this2.store[entry.id]) {
1089
+ var _temp4 = function () {
1090
+ if (_this2.store[entry.id] === 'opened') {
1091
+ return Promise.resolve(entry.open(false, false)).then(function () {});
1092
+ } else {
1093
+ return Promise.resolve(entry.close(false, false)).then(function () {});
1094
+ }
1095
+ }();
1096
+
1097
+ if (_temp4 && _temp4.then) return _temp4.then(function () {});
1098
+ } else if (entry.el.classList.contains(_this2.settings.stateOpened)) {
1099
+ // Update drawer state.
1100
+ entry.state = 'opened';
1101
+ } else {
1102
+ // Remove transition state classes.
1103
+ entry.el.classList.remove(_this2.settings.stateOpening);
1104
+ entry.el.classList.remove(_this2.settings.stateClosing); // Add closed state class.
1105
+
1106
+ entry.el.classList.add(_this2.settings.stateClosed);
1107
+ }
1108
+ }();
1109
+
1110
+ // Setup initial state using the following priority:
1111
+ // 1. If a store state is available, restore from local store.
1112
+ // 2. If opened state class is set, set state to opened.
1113
+ // 3. Else, initialize default state.
1114
+ return Promise.resolve(_temp3 && _temp3.then ? _temp3.then(function () {}) : void 0);
1115
+ } catch (e) {
1116
+ return Promise.reject(e);
1117
+ }
1118
+ };
1119
+
1120
+ function updateFocusState$1(entry) {
1121
+ // Check if there's an active modal
1122
+ if (entry.state === 'opened') {
1123
+ // Mount the focus trap on the opened drawer.
1124
+ if (entry.mode === 'modal') {
1125
+ this.focusTrap.mount(entry.dialog, this.settings.selectorFocus);
1126
+ } else {
1127
+ this.focusTrap.focus(entry.dialog, this.settings.selectorFocus);
1128
+ }
1129
+ } else {
1130
+ // Set focus to root trigger and unmount the focus trap.
1131
+ if (entry.trigger) {
1132
+ entry.trigger.focus();
1133
+ entry.trigger = null;
1134
+ }
1135
+
1136
+ this.focusTrap.unmount();
1137
+ }
1138
+ }
1139
+
1140
+ var open$2 = function open(query, transition, focus) {
1141
+ if (focus === void 0) {
1142
+ focus = true;
1143
+ }
1144
+
1145
+ try {
1146
+ var _temp3 = function _temp3() {
1147
+ // Set focus to the drawer element if the focus param is true.
1148
+ if (focus) {
1149
+ updateFocusState$1.call(_this2, drawer);
1150
+ } // Dispatch custom opened event.
1151
+
1152
+
1153
+ drawer.el.dispatchEvent(new CustomEvent(config.customEventPrefix + 'opened', {
1154
+ detail: _this2,
1155
+ bubbles: true
1156
+ })); // Return the drawer.
1157
+
1158
+ return drawer;
1159
+ };
1160
+
462
1161
  var _this2 = this;
463
1162
 
464
- el = el.forEach ? el : [el];
465
- el.forEach(function (el) {
466
- el.removeAttribute(_this2.settings.stateAttr);
467
- });
468
- };
1163
+ // Get the drawer from collection.
1164
+ var drawer = getDrawer.call(_this2, query); // Get the modal configuration.
469
1165
 
470
- _proto.setIndeterminate = function setIndeterminate(el) {
471
- var _this3 = this;
1166
+ var config = _extends({}, _this2.settings, drawer.settings); // Add transition parameter to configuration.
472
1167
 
473
- el = el.forEach ? el : [el];
474
- el.forEach(function (el) {
475
- if (el.hasAttribute(_this3.settings.stateAttr)) {
476
- el.indeterminate = true;
477
- } else {
478
- el.indeterminate = false;
479
- }
480
- });
481
- };
482
1168
 
483
- return Checkbox;
484
- }();
1169
+ if (transition !== undefined) config.transition = transition; // If drawer is closed.
485
1170
 
486
- var defaults$2 = {
487
- autoInit: false,
488
- // Data attributes
489
- dataDrawer: 'drawer',
490
- dataDialog: 'drawer-dialog',
491
- dataToggle: 'drawer-toggle',
492
- dataOpen: 'drawer-open',
493
- dataClose: 'drawer-close',
494
- dataBreakpoint: 'drawer-breakpoint',
495
- dataFocus: 'drawer-focus',
496
- // State classes
497
- stateOpened: 'is-opened',
498
- stateOpening: 'is-opening',
499
- stateClosing: 'is-closing',
500
- stateClosed: 'is-closed',
501
- // Classes
502
- classModal: 'drawer_modal',
503
- // Selectors
504
- selectorInert: null,
505
- selectorOverflow: null,
506
- // Feature toggles
507
- breakpoints: null,
508
- customEventPrefix: 'drawer:',
509
- eventListeners: true,
510
- stateSave: true,
511
- stateKey: 'DrawerState',
512
- setTabindex: true,
513
- transition: true
514
- };
1171
+ var _temp4 = function () {
1172
+ if (drawer.state === 'closed') {
1173
+ // Update drawer state.
1174
+ drawer.state = 'opening'; // Run the open transition.
515
1175
 
516
- var Breakpoint = /*#__PURE__*/function () {
517
- function Breakpoint(parent) {
518
- this.mediaQueryLists = [];
519
- this.parent = parent;
520
- this.prefix = this.getVariablePrefix();
521
- this.__check = this.check.bind(this);
1176
+ return Promise.resolve(openTransition(drawer.el, config)).then(function () {
1177
+ // Update the global state if mode is modal.
1178
+ if (drawer.mode === 'modal') updateGlobalState(true, config); // Update drawer state.
1179
+
1180
+ drawer.state = 'opened';
1181
+ });
1182
+ }
1183
+ }();
1184
+
1185
+ return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(_temp3) : _temp3(_temp4));
1186
+ } catch (e) {
1187
+ return Promise.reject(e);
522
1188
  }
1189
+ };
523
1190
 
524
- var _proto = Breakpoint.prototype;
1191
+ var close$2 = function close(query, transition, focus) {
1192
+ if (focus === void 0) {
1193
+ focus = true;
1194
+ }
525
1195
 
526
- _proto.init = function init() {
527
- var _this = this;
1196
+ try {
1197
+ var _this2 = this;
528
1198
 
529
- var drawers = document.querySelectorAll("[data-" + this.parent.settings.dataBreakpoint + "]");
530
- drawers.forEach(function (drawer) {
531
- // Setup mediaQueryList object
532
- var id = drawer.getAttribute("data-" + _this.parent.settings.dataDrawer);
533
- var key = drawer.getAttribute("data-" + _this.parent.settings.dataBreakpoint);
1199
+ // Get the drawer from collection.
1200
+ var drawer = getDrawer.call(_this2, query); // Get the modal configuration.
534
1201
 
535
- var bp = _this.getBreakpoint(key);
1202
+ var config = _extends({}, _this2.settings, drawer.settings); // Add transition parameter to configuration.
536
1203
 
537
- var mql = window.matchMedia('(min-width:' + bp + ')'); // Run match check
538
1204
 
539
- _this.match(mql, drawer); // Conditionally use addListner() for IE11 support
1205
+ if (transition !== undefined) config.transition = transition; // If drawer is opened.
540
1206
 
1207
+ var _temp2 = function () {
1208
+ if (drawer.state === 'opened') {
1209
+ // Update drawer state.
1210
+ drawer.state = 'closing'; // Remove focus from active element.
541
1211
 
542
- if (typeof mql.addEventListener === 'function') {
543
- mql.addEventListener('change', _this.__check);
544
- } else {
545
- mql.addListener(_this.__check);
546
- } // Push to mediaQueryLists array along with drawer ID
1212
+ document.activeElement.blur(); // Run the close transition.
547
1213
 
1214
+ return Promise.resolve(closeTransition(drawer.el, config)).then(function () {
1215
+ // Update the global state if mode is modal.
1216
+ if (drawer.mode === 'modal') updateGlobalState(false, config); // Set focus to the trigger element if the focus param is true.
548
1217
 
549
- _this.mediaQueryLists.push({
550
- 'mql': mql,
551
- 'drawer': id
552
- });
553
- });
554
- };
1218
+ if (focus) {
1219
+ updateFocusState$1.call(_this2, drawer);
1220
+ } // Update drawer state.
555
1221
 
556
- _proto.destroy = function destroy() {
557
- var _this2 = this;
558
1222
 
559
- if (this.mediaQueryLists && this.mediaQueryLists.length) {
560
- this.mediaQueryLists.forEach(function (item) {
561
- item.mql.removeListener(_this2.__check);
562
- });
563
- }
1223
+ drawer.state = 'closed'; // Dispatch custom closed event.
564
1224
 
565
- this.mediaQueryLists = null;
566
- };
1225
+ drawer.el.dispatchEvent(new CustomEvent(config.customEventPrefix + 'closed', {
1226
+ detail: _this2,
1227
+ bubbles: true
1228
+ }));
1229
+ });
1230
+ }
1231
+ }();
567
1232
 
568
- _proto.check = function check(event) {
569
- var _this3 = this;
1233
+ return Promise.resolve(_temp2 && _temp2.then ? _temp2.then(function () {
1234
+ // Return the drawer.
1235
+ return drawer;
1236
+ }) : drawer);
1237
+ } catch (e) {
1238
+ return Promise.reject(e);
1239
+ }
1240
+ };
570
1241
 
571
- if (event === void 0) {
572
- event = null;
573
- }
1242
+ var toggle = function toggle(query, transition, focus) {
1243
+ try {
1244
+ var _this2 = this;
574
1245
 
575
- if (this.mediaQueryLists && this.mediaQueryLists.length) {
576
- this.mediaQueryLists.forEach(function (item) {
577
- // If an event is passed, filter out drawers that don't match the query
578
- // If event is null, run all drawers through match
579
- var filter = event ? event.media == item.mql.media : true;
580
- if (!filter) return;
581
- var drawer = document.querySelector("[data-" + _this3.parent.settings.dataDrawer + "=\"" + item.drawer + "\"]");
582
- if (drawer) _this3.match(item.mql, drawer);
583
- });
584
- document.dispatchEvent(new CustomEvent(this.parent.settings.customEventPrefix + 'breakpoint', {
585
- bubbles: true
586
- }));
587
- }
588
- };
1246
+ // Get the drawer from collection.
1247
+ var drawer = getDrawer.call(_this2, query); // Open or close the drawer based on its current state.
589
1248
 
590
- _proto.match = function match(mql, drawer) {
591
- if (mql.matches) {
592
- this.parent.switchToDefault(drawer);
1249
+ if (drawer.state === 'closed') {
1250
+ return Promise.resolve(open$2.call(_this2, drawer, transition, focus));
593
1251
  } else {
594
- this.parent.switchToModal(drawer);
1252
+ return Promise.resolve(close$2.call(_this2, drawer, transition, focus));
595
1253
  }
596
- };
1254
+ } catch (e) {
1255
+ return Promise.reject(e);
1256
+ }
1257
+ };
597
1258
 
598
- _proto.getBreakpoint = function getBreakpoint(key) {
599
- var breakpoint = key;
1259
+ var toModal = function toModal(entry) {
1260
+ try {
1261
+ var _this4 = this;
600
1262
 
601
- if (this.parent.settings.breakpoints && this.parent.settings.breakpoints[key]) {
602
- breakpoint = this.parent.settings.breakpoints[key];
603
- } else if (getComputedStyle(document.body).getPropertyValue(this.prefix + key)) {
604
- breakpoint = getComputedStyle(document.body).getPropertyValue(this.prefix + key);
605
- }
1263
+ // Get the drawer configuration.
1264
+ // Add the modal class.
1265
+ entry.el.classList.add(entry.getSetting('classModal')); // Set aria-modal attribute to true.
606
1266
 
607
- return breakpoint;
608
- };
1267
+ entry.dialog.setAttribute('aria-modal', 'true'); // If there isn't a stored state but also has the opened state class...
609
1268
 
610
- _proto.getVariablePrefix = function getVariablePrefix() {
611
- var prefix = '--';
612
- prefix += getComputedStyle(document.body).getPropertyValue('--vrembem-variable-prefix');
613
- prefix += 'breakpoint-';
614
- return prefix;
615
- };
1269
+ if (!_this4.store[entry.id] && entry.el.classList.contains(entry.getSetting('stateOpened'))) {
1270
+ // Save the opened state in local store.
1271
+ _this4.store[entry.id] = 'opened';
1272
+ } // Modal drawer defaults to closed state.
616
1273
 
617
- return Breakpoint;
618
- }();
619
1274
 
620
- function getDrawer(drawerKey) {
621
- if (typeof drawerKey !== 'string') return drawerKey;
622
- return document.querySelector("[data-" + this.settings.dataDrawer + "=\"" + drawerKey + "\"]");
623
- }
624
- function drawerNotFound(key) {
625
- return Promise.reject(new Error("Did not find drawer with key: \"" + key + "\""));
626
- }
1275
+ return Promise.resolve(close$2.call(_this4, entry, false, false)).then(function () {
1276
+ // Dispatch custom switch event.
1277
+ entry.el.dispatchEvent(new CustomEvent(entry.getSetting('customEventPrefix') + 'switchMode', {
1278
+ detail: _this4,
1279
+ bubbles: true
1280
+ })); // Return the entry.
1281
+
1282
+ return entry;
1283
+ });
1284
+ } catch (e) {
1285
+ return Promise.reject(e);
1286
+ }
1287
+ };
627
1288
 
628
- var close$2 = function close(drawerKey) {
1289
+ var toInline = function toInline(entry) {
629
1290
  try {
630
1291
  var _this2 = this;
631
1292
 
632
- var drawer = _this2.getDrawer(drawerKey);
633
-
634
- if (!drawer) return Promise.resolve(drawerNotFound(drawerKey));
1293
+ // Remove the modal class.
1294
+ entry.el.classList.remove(entry.getSetting('classModal')); // Remove the aria-modal attribute.
635
1295
 
636
- if (hasClass(drawer, _this2.settings.stateOpened)) {
637
- _this2.working = true;
1296
+ entry.dialog.removeAttribute('aria-modal'); // Update the global state.
638
1297
 
639
- if (hasClass(drawer, _this2.settings.classModal)) {
640
- setInert(false, _this2.settings.selectorInert);
641
- setOverflowHidden(false, _this2.settings.selectorOverflow);
642
- }
1298
+ updateGlobalState(false, _extends({}, _this2.settings, entry.settings)); // Remove any focus traps.
643
1299
 
644
- return Promise.resolve(closeTransition(drawer, _this2.settings)).then(function () {
645
- _this2.stateSave(drawer);
1300
+ _this2.focusTrap.unmount(); // Setup initial state.
646
1301
 
647
- focusTrigger(_this2);
648
1302
 
649
- _this2.focusTrap.destroy();
1303
+ return Promise.resolve(initialState.call(_this2, entry)).then(function () {
1304
+ // Dispatch custom switch event.
1305
+ entry.el.dispatchEvent(new CustomEvent(entry.getSetting('customEventPrefix') + 'switchMode', {
1306
+ detail: _this2,
1307
+ bubbles: true
1308
+ })); // Return the entry.
650
1309
 
651
- drawer.dispatchEvent(new CustomEvent(_this2.settings.customEventPrefix + 'closed', {
652
- detail: _this2,
653
- bubbles: true
654
- }));
655
- _this2.working = false;
656
- return drawer;
657
- });
658
- } else {
659
- return Promise.resolve(drawer);
660
- }
1310
+ return entry;
1311
+ });
661
1312
  } catch (e) {
662
1313
  return Promise.reject(e);
663
1314
  }
664
1315
  };
665
1316
 
666
- function handlerClick$2(event) {
667
- // Working catch
668
- if (this.working) return; // Toggle data trigger
1317
+ function switchMode(entry) {
1318
+ switch (entry.mode) {
1319
+ case 'inline':
1320
+ return toInline.call(this, entry);
669
1321
 
670
- var trigger = event.target.closest("[data-" + this.settings.dataToggle + "]");
1322
+ case 'modal':
1323
+ return toModal.call(this, entry);
671
1324
 
672
- if (trigger) {
673
- var selector = trigger.getAttribute("data-" + this.settings.dataToggle);
674
- this.memory.trigger = trigger;
675
- this.toggle(selector);
676
- event.preventDefault();
677
- return;
678
- } // Open data trigger
1325
+ default:
1326
+ throw new Error("\"" + entry.mode + "\" is not a valid drawer mode.");
1327
+ }
1328
+ }
679
1329
 
1330
+ var register$2 = function register(el, dialog) {
1331
+ try {
1332
+ var _this2 = this;
680
1333
 
681
- trigger = event.target.closest("[data-" + this.settings.dataOpen + "]");
1334
+ // Deregister entry incase it has already been registered.
1335
+ return Promise.resolve(deregister$2.call(_this2, el, false)).then(function () {
1336
+ // Save root this for use inside methods API.
1337
+ var root = _this2; // Create an instance of the Breakpoint class.
1338
+
1339
+ var breakpoint = new Breakpoint(); // Setup methods API.
1340
+
1341
+ var methods = {
1342
+ open: function open(transition, focus) {
1343
+ return open$2.call(root, this, transition, focus);
1344
+ },
1345
+ close: function close(transition, focus) {
1346
+ return close$2.call(root, this, transition, focus);
1347
+ },
1348
+ toggle: function toggle$1(transition, focus) {
1349
+ return toggle.call(root, this, transition, focus);
1350
+ },
1351
+ deregister: function deregister() {
1352
+ return deregister$2.call(root, this);
1353
+ },
1354
+ mountBreakpoint: function mountBreakpoint() {
1355
+ var value = this.breakpoint;
1356
+ var handler = this.handleBreakpoint.bind(this);
1357
+ breakpoint.mount(value, handler);
1358
+ return this;
1359
+ },
1360
+ unmountBreakpoint: function unmountBreakpoint() {
1361
+ breakpoint.unmount();
1362
+ return this;
1363
+ },
1364
+ handleBreakpoint: function handleBreakpoint(event) {
1365
+ this.mode = event.matches ? 'inline' : 'modal';
1366
+ return this;
1367
+ },
1368
+ getSetting: function getSetting(key) {
1369
+ return key in this.settings ? this.settings[key] : root.settings[key];
1370
+ }
1371
+ }; // Setup the drawer object.
682
1372
 
683
- if (trigger) {
684
- var _selector = trigger.getAttribute("data-" + this.settings.dataOpen);
1373
+ var entry = _extends({
1374
+ id: el.id,
1375
+ el: el,
1376
+ dialog: dialog,
1377
+ trigger: null,
1378
+ settings: getConfig$1(el, _this2.settings.dataConfig),
685
1379
 
686
- this.memory.trigger = trigger;
687
- this.open(_selector);
688
- event.preventDefault();
689
- return;
690
- } // Close data trigger
1380
+ get breakpoint() {
1381
+ return getBreakpoint.call(root, el);
1382
+ },
691
1383
 
1384
+ get state() {
1385
+ return __state;
1386
+ },
692
1387
 
693
- trigger = event.target.closest("[data-" + this.settings.dataClose + "]");
1388
+ set state(value) {
1389
+ __state = value; // Save 'opened' and 'closed' states to store if mode is inline.
694
1390
 
695
- if (trigger) {
696
- var _selector2 = trigger.getAttribute("data-" + this.settings.dataClose);
1391
+ if (value === 'opened' || value === 'closed') {
1392
+ if (this.mode === 'inline') root.store[this.id] = this.state;
1393
+ }
1394
+ },
697
1395
 
698
- if (_selector2) {
699
- this.memory.trigger = trigger;
700
- this.close(_selector2);
701
- } else {
702
- var target = event.target.closest("[data-" + this.settings.dataDrawer + "]");
703
- if (target) this.close(target);
704
- }
1396
+ get mode() {
1397
+ return __mode;
1398
+ },
705
1399
 
706
- event.preventDefault();
707
- return;
708
- } // Screen modal trigger
1400
+ set mode(value) {
1401
+ __mode = value;
1402
+ switchMode.call(root, this);
1403
+ }
709
1404
 
1405
+ }, methods); // Create the state var with the initial state.
710
1406
 
711
- if (event.target.hasAttribute("data-" + this.settings.dataDrawer)) {
712
- this.close(event.target);
713
- return;
714
- }
715
- }
716
- function handlerKeydown$2(event) {
717
- // Working catch
718
- if (this.working) return;
719
1407
 
720
- if (event.key === 'Escape') {
721
- var target = document.querySelector("." + this.settings.classModal + "." + this.settings.stateOpened);
1408
+ var __state = el.classList.contains(entry.getSetting('stateOpened')) ? 'opened' : 'closed'; // Create the mode var with the initial mode.
722
1409
 
723
- if (target) {
724
- this.close(target);
725
- }
726
- }
727
- }
728
1410
 
729
- var open$2 = function open(drawerKey) {
730
- try {
731
- var _this2 = this;
1411
+ var __mode = el.classList.contains(entry.getSetting('classModal')) ? 'modal' : 'inline'; // Setup mode specific attributes.
1412
+
732
1413
 
733
- var drawer = _this2.getDrawer(drawerKey);
1414
+ if (entry.mode === 'modal') {
1415
+ // Set aria-modal attribute to true.
1416
+ entry.dialog.setAttribute('aria-modal', 'true');
1417
+ } else {
1418
+ // Remove the aria-modal attribute.
1419
+ entry.dialog.removeAttribute('aria-modal');
1420
+ } // Set tabindex="-1" so dialog is focusable via JS or click.
734
1421
 
735
- if (!drawer) return Promise.resolve(drawerNotFound(drawerKey));
736
1422
 
737
- if (!hasClass(drawer, _this2.settings.stateOpened)) {
738
- _this2.working = true;
739
- var isModal = hasClass(drawer, _this2.settings.classModal);
1423
+ if (entry.getSetting('setTabindex')) {
1424
+ entry.dialog.setAttribute('tabindex', '-1');
1425
+ } // Add entry to collection.
740
1426
 
741
- if (isModal) {
742
- setOverflowHidden(true, _this2.settings.selectorOverflow);
743
- }
744
1427
 
745
- return Promise.resolve(openTransition(drawer, _this2.settings)).then(function () {
746
- _this2.stateSave(drawer);
1428
+ _this2.collection.push(entry); // If the entry has a breakpoint...
747
1429
 
748
- if (isModal) {
749
- _this2.focusTrap.init(drawer);
750
1430
 
751
- setInert(true, _this2.settings.selectorInert);
1431
+ var _temp = function () {
1432
+ if (entry.breakpoint) {
1433
+ // Mount media query breakpoint functionality.
1434
+ entry.mountBreakpoint();
1435
+ } else {
1436
+ // Else, Setup initial state.
1437
+ return Promise.resolve(initialState.call(_this2, entry)).then(function () {});
752
1438
  }
1439
+ }();
753
1440
 
754
- focusTarget(drawer, _this2.settings);
755
- drawer.dispatchEvent(new CustomEvent(_this2.settings.customEventPrefix + 'opened', {
756
- detail: _this2,
757
- bubbles: true
758
- }));
759
- _this2.working = false;
760
- return drawer;
761
- });
762
- } else {
763
- focusTarget(drawer, _this2.settings);
764
- return Promise.resolve(drawer);
765
- }
1441
+ return _temp && _temp.then ? _temp.then(function () {
1442
+ // Return the registered entry.
1443
+ return entry;
1444
+ }) : entry;
1445
+ });
766
1446
  } catch (e) {
767
1447
  return Promise.reject(e);
768
1448
  }
769
1449
  };
770
1450
 
771
- function stateSet(settings) {
772
- // If save state is disabled
773
- if (!settings.stateSave) return stateClear(settings); // If there isn't an existing state to set
1451
+ var _handleClick$1 = /*#__PURE__*/_classPrivateFieldLooseKey("handleClick");
774
1452
 
775
- var storageCheck = localStorage.getItem(settings.stateKey);
1453
+ var _handleKeydown$2 = /*#__PURE__*/_classPrivateFieldLooseKey("handleKeydown");
776
1454
 
777
- if (!storageCheck || storageCheck && Object.keys(JSON.parse(storageCheck)).length === 0) {
778
- return stateSave(null, settings);
779
- } // Set the existing state
1455
+ var Drawer = /*#__PURE__*/function (_Collection) {
1456
+ _inheritsLoose(Drawer, _Collection);
780
1457
 
1458
+ function Drawer(options) {
1459
+ var _this;
781
1460
 
782
- var state = JSON.parse(localStorage.getItem(settings.stateKey));
783
- Object.keys(state).forEach(function (key) {
784
- var item = document.querySelector("[data-" + settings.dataDrawer + "=\"" + key + "\"]");
785
- if (!item) return;
786
- state[key] == settings.stateOpened ? addClass(item, settings.stateOpened) : removeClass(item, settings.stateOpened);
787
- });
788
- return state;
1461
+ _this = _Collection.call(this) || this;
1462
+ Object.defineProperty(_assertThisInitialized(_this), _handleClick$1, {
1463
+ writable: true,
1464
+ value: void 0
1465
+ });
1466
+ Object.defineProperty(_assertThisInitialized(_this), _handleKeydown$2, {
1467
+ writable: true,
1468
+ value: void 0
1469
+ });
1470
+ _this.defaults = defaults$2;
1471
+ _this.settings = _extends({}, _this.defaults, options);
1472
+ _this.focusTrap = new FocusTrap(); // Setup local store for inline drawer state management.
1473
+
1474
+ _this.store = localStore(_this.settings.storeKey, _this.settings.store);
1475
+ _classPrivateFieldLooseBase(_assertThisInitialized(_this), _handleClick$1)[_handleClick$1] = handleClick$2.bind(_assertThisInitialized(_this));
1476
+ _classPrivateFieldLooseBase(_assertThisInitialized(_this), _handleKeydown$2)[_handleKeydown$2] = handleKeydown$2.bind(_assertThisInitialized(_this));
1477
+ if (_this.settings.autoInit) _this.init();
1478
+ return _this;
1479
+ }
1480
+
1481
+ var _proto = Drawer.prototype;
1482
+
1483
+ _proto.init = function init(options) {
1484
+ if (options === void 0) {
1485
+ options = null;
1486
+ }
1487
+
1488
+ try {
1489
+ var _this3 = this;
1490
+
1491
+ // Update settings with passed options.
1492
+ if (options) _this3.settings = _extends({}, _this3.settings, options); // Get all the modals.
1493
+
1494
+ var drawers = document.querySelectorAll(_this3.settings.selectorDrawer); // Register the collections array with modal instances.
1495
+
1496
+ return Promise.resolve(_this3.registerCollection(drawers)).then(function () {
1497
+ // If eventListeners are enabled, init event listeners.
1498
+ if (_this3.settings.eventListeners) {
1499
+ _this3.initEventListeners();
1500
+ }
1501
+
1502
+ return _this3;
1503
+ });
1504
+ } catch (e) {
1505
+ return Promise.reject(e);
1506
+ }
1507
+ };
1508
+
1509
+ _proto.destroy = function destroy() {
1510
+ try {
1511
+ var _this5 = this;
1512
+
1513
+ // Remove all entries from the collection.
1514
+ return Promise.resolve(_this5.deregisterCollection()).then(function () {
1515
+ // If eventListeners are enabled, init event listeners.
1516
+ if (_this5.settings.eventListeners) {
1517
+ _this5.destroyEventListeners();
1518
+ }
1519
+
1520
+ return _this5;
1521
+ });
1522
+ } catch (e) {
1523
+ return Promise.reject(e);
1524
+ }
1525
+ };
1526
+
1527
+ _proto.initEventListeners = function initEventListeners() {
1528
+ document.addEventListener('click', _classPrivateFieldLooseBase(this, _handleClick$1)[_handleClick$1], false);
1529
+ document.addEventListener('touchend', _classPrivateFieldLooseBase(this, _handleClick$1)[_handleClick$1], false);
1530
+ document.addEventListener('keydown', _classPrivateFieldLooseBase(this, _handleKeydown$2)[_handleKeydown$2], false);
1531
+ };
1532
+
1533
+ _proto.destroyEventListeners = function destroyEventListeners() {
1534
+ document.removeEventListener('click', _classPrivateFieldLooseBase(this, _handleClick$1)[_handleClick$1], false);
1535
+ document.removeEventListener('touchend', _classPrivateFieldLooseBase(this, _handleClick$1)[_handleClick$1], false);
1536
+ document.removeEventListener('keydown', _classPrivateFieldLooseBase(this, _handleKeydown$2)[_handleKeydown$2], false);
1537
+ };
1538
+
1539
+ _proto.register = function register(query) {
1540
+ var els = getDrawerElements.call(this, query);
1541
+ if (els.error) return Promise.reject(els.error);
1542
+ return register$2.call(this, els.drawer, els.dialog);
1543
+ };
1544
+
1545
+ _proto.deregister = function deregister(query) {
1546
+ var entry = this.get(getDrawerID.call(this, query));
1547
+ return deregister$2.call(this, entry);
1548
+ };
1549
+
1550
+ _proto.open = function open(id, transition, focus) {
1551
+ return open$2.call(this, id, transition, focus);
1552
+ };
1553
+
1554
+ _proto.close = function close(id, transition, focus) {
1555
+ return close$2.call(this, id, transition, focus);
1556
+ };
1557
+
1558
+ _proto.toggle = function toggle$1(id, transition, focus) {
1559
+ return toggle.call(this, id, transition, focus);
1560
+ };
1561
+
1562
+ _createClass(Drawer, [{
1563
+ key: "activeModal",
1564
+ get: function get() {
1565
+ return this.collection.find(function (entry) {
1566
+ return entry.state === 'opened' && entry.mode === 'modal';
1567
+ });
1568
+ }
1569
+ }]);
1570
+
1571
+ return Drawer;
1572
+ }(Collection);
1573
+
1574
+ var defaults$1 = {
1575
+ autoInit: false,
1576
+ // Data attributes
1577
+ dataOpen: 'modal-open',
1578
+ dataClose: 'modal-close',
1579
+ dataReplace: 'modal-replace',
1580
+ dataConfig: 'modal-config',
1581
+ // Selectors
1582
+ selectorModal: '.modal',
1583
+ selectorDialog: '.modal__dialog',
1584
+ selectorRequired: '[role="alertdialog"]',
1585
+ selectorFocus: '[data-focus]',
1586
+ selectorInert: null,
1587
+ selectorOverflow: 'body',
1588
+ // State classes
1589
+ stateOpened: 'is-opened',
1590
+ stateOpening: 'is-opening',
1591
+ stateClosing: 'is-closing',
1592
+ stateClosed: 'is-closed',
1593
+ // Feature settings
1594
+ customEventPrefix: 'modal:',
1595
+ eventListeners: true,
1596
+ teleport: null,
1597
+ teleportMethod: 'append',
1598
+ setTabindex: true,
1599
+ transition: true
1600
+ };
1601
+
1602
+ function getModal(query) {
1603
+ // Get the entry from collection.
1604
+ var entry = typeof query === 'string' ? this.get(query) : this.get(query.id); // Return entry if it was resolved, otherwise throw error.
1605
+
1606
+ if (entry) {
1607
+ return entry;
1608
+ } else {
1609
+ throw new Error("Modal not found in collection with id of \"" + (query.id || query) + "\".");
1610
+ }
789
1611
  }
790
- function stateSave(target, settings) {
791
- // If save state is disabled
792
- if (!settings.stateSave) return stateClear(settings); // Get the currently saved object if it exists
793
1612
 
794
- var state = localStorage.getItem(settings.stateKey) ? JSON.parse(localStorage.getItem(settings.stateKey)) : {}; // Are we saving a single target or the entire suite?
1613
+ function getModalID(obj) {
1614
+ // If it's a string, return the string.
1615
+ if (typeof obj === 'string') {
1616
+ return obj;
1617
+ } // If it's an HTML element.
1618
+ else if (typeof obj.hasAttribute === 'function') {
1619
+ // If it's a modal open trigger, return data value.
1620
+ if (obj.hasAttribute("data-" + this.settings.dataOpen)) {
1621
+ return obj.getAttribute("data-" + this.settings.dataOpen);
1622
+ } // If it's a modal close trigger, return data value or false.
1623
+ else if (obj.hasAttribute("data-" + this.settings.dataClose)) {
1624
+ return obj.getAttribute("data-" + this.settings.dataClose) || false;
1625
+ } // If it's a modal replace trigger, return data value.
1626
+ else if (obj.hasAttribute("data-" + this.settings.dataReplace)) {
1627
+ return obj.getAttribute("data-" + this.settings.dataReplace);
1628
+ } // If it's a modal element, return the id.
1629
+ else if (obj.closest(this.settings.selectorModal)) {
1630
+ obj = obj.closest(this.settings.selectorModal);
1631
+ return obj.id || false;
1632
+ } // Return false if no id was found.
1633
+ else return false;
1634
+ } // If it has an id property, return its value.
1635
+ else if (obj.id) {
1636
+ return obj.id;
1637
+ } // Return false if no id was found.
1638
+ else return false;
1639
+ }
795
1640
 
796
- var drawers = target ? [target] : document.querySelectorAll("[data-" + settings.dataDrawer + "]"); // Loop through drawers and save their states
1641
+ function getModalElements(query) {
1642
+ var id = getModalID.call(this, query);
797
1643
 
798
- drawers.forEach(function (el) {
799
- if (hasClass(el, settings.classModal)) return;
800
- var drawerKey = el.getAttribute("data-" + settings.dataDrawer);
801
- state[drawerKey] = hasClass(el, settings.stateOpened) ? settings.stateOpened : settings.stateClosed;
802
- }); // Save to localStorage and return the state
1644
+ if (id) {
1645
+ var modal = document.querySelector("#" + id);
1646
+ var dialog = modal ? modal.querySelector(this.settings.selectorDialog) : null;
803
1647
 
804
- localStorage.setItem(settings.stateKey, JSON.stringify(state));
805
- return state;
1648
+ if (!modal && !dialog) {
1649
+ return {
1650
+ error: new Error("No modal elements found using the ID: \"" + id + "\".")
1651
+ };
1652
+ } else if (!dialog) {
1653
+ return {
1654
+ error: new Error('Modal is missing dialog element.')
1655
+ };
1656
+ } else {
1657
+ return {
1658
+ modal: modal,
1659
+ dialog: dialog
1660
+ };
1661
+ }
1662
+ } else {
1663
+ return {
1664
+ error: new Error('Could not resolve the modal ID.')
1665
+ };
1666
+ }
806
1667
  }
807
- function stateClear(settings) {
808
- if (localStorage.getItem(settings.stateKey)) {
809
- localStorage.removeItem(settings.stateKey);
1668
+
1669
+ function updateFocusState() {
1670
+ // Check if there's an active modal
1671
+ if (this.active) {
1672
+ // Mount the focus trap on the active modal.
1673
+ this.focusTrap.mount(this.active.dialog, this.settings.selectorFocus);
1674
+ } else {
1675
+ // Set focus to root trigger and unmount the focus trap.
1676
+ if (this.trigger) {
1677
+ this.trigger.focus();
1678
+ this.trigger = null;
1679
+ }
1680
+
1681
+ this.focusTrap.unmount();
810
1682
  }
1683
+ }
1684
+
1685
+ function updateStackIndex(stack) {
1686
+ stack.forEach(function (entry, index) {
1687
+ entry.el.style.zIndex = null;
1688
+ var value = getComputedStyle(entry.el)['z-index'];
1689
+ entry.el.style.zIndex = parseInt(value) + index + 1;
1690
+ });
1691
+ }
1692
+
1693
+ var handleClick$1 = function handleClick(event) {
1694
+ try {
1695
+ var _this2 = this;
1696
+
1697
+ // If an open or replace button was clicked, open or replace the modal.
1698
+ var trigger = event.target.closest("[data-" + _this2.settings.dataOpen + "], [data-" + _this2.settings.dataReplace + "]");
1699
+
1700
+ if (trigger) {
1701
+ event.preventDefault(); // Save the trigger if it's not coming from inside a modal.
811
1702
 
812
- return {};
813
- }
1703
+ var fromModal = event.target.closest(_this2.settings.selectorModal);
1704
+ if (!fromModal) _this2.trigger = trigger; // Get the modal.
814
1705
 
815
- var switchToDefault = function switchToDefault(drawerKey) {
816
- try {
817
- var _this4 = this;
1706
+ var modal = _this2.get(getModalID.call(_this2, trigger)); // Depending on the button type, either open or replace the modal.
818
1707
 
819
- // Initial guards
820
- var drawer = _this4.getDrawer(drawerKey);
821
1708
 
822
- if (!drawer) return Promise.resolve(drawerNotFound(drawerKey));
823
- if (!hasClass(drawer, _this4.settings.classModal)) return Promise.resolve(); // Tear down modal state
1709
+ return Promise.resolve(trigger.matches("[data-" + _this2.settings.dataOpen + "]") ? modal.open() : modal.replace());
1710
+ } // If a close button was clicked, close the modal.
824
1711
 
825
- setInert(false, _this4.settings.selectorInert);
826
- setOverflowHidden(false, _this4.settings.selectorOverflow);
827
- removeClass(drawer, _this4.settings.classModal);
828
1712
 
829
- _this4.focusTrap.destroy(); // Restore drawers saved state
1713
+ trigger = event.target.closest("[data-" + _this2.settings.dataClose + "]");
830
1714
 
1715
+ if (trigger) {
1716
+ event.preventDefault(); // Get the value of the data attribute.
831
1717
 
832
- drawerKey = drawer.getAttribute("data-" + _this4.settings.dataDrawer);
833
- var drawerState = _this4.state[drawerKey];
1718
+ var value = trigger.getAttribute("data-" + _this2.settings.dataClose); // Close all if * wildcard is passed, otherwise close a single modal.
834
1719
 
835
- if (drawerState == _this4.settings.stateOpened) {
836
- addClass(drawer, _this4.settings.stateOpened);
837
- removeClass(drawer, _this4.settings.stateClosed);
838
- } // Dispatch custom event
1720
+ return Promise.resolve(value === '*' ? _this2.closeAll() : _this2.close(value));
1721
+ } // If the modal screen was clicked, close the modal.
839
1722
 
840
1723
 
841
- drawer.dispatchEvent(new CustomEvent(_this4.settings.customEventPrefix + 'toDefault', {
842
- bubbles: true
843
- }));
844
- return Promise.resolve(drawer);
1724
+ if (event.target.matches(_this2.settings.selectorModal) && !event.target.querySelector(_this2.settings.selectorRequired)) {
1725
+ return Promise.resolve(_this2.close(getModalID.call(_this2, event.target)));
1726
+ }
1727
+
1728
+ return Promise.resolve();
845
1729
  } catch (e) {
846
1730
  return Promise.reject(e);
847
1731
  }
848
1732
  };
849
- var switchToModal = function switchToModal(drawerKey) {
1733
+ function handleKeydown$1(event) {
1734
+ // If escape key was pressed.
1735
+ if (event.key === 'Escape') {
1736
+ // If a modal is opened and not required, close the modal.
1737
+ if (this.active && !this.active.dialog.matches(this.settings.selectorRequired)) {
1738
+ return this.close();
1739
+ }
1740
+ }
1741
+ }
1742
+
1743
+ var deregister$1 = function deregister(obj, close) {
1744
+ if (close === void 0) {
1745
+ close = true;
1746
+ }
1747
+
850
1748
  try {
1749
+ var _temp5 = function _temp5() {
1750
+ // Return the modified collection.
1751
+ return _this2.collection;
1752
+ };
1753
+
851
1754
  var _this2 = this;
852
1755
 
853
- // Initial guards
854
- var drawer = _this2.getDrawer(drawerKey);
1756
+ // Return collection if nothing was passed.
1757
+ if (!obj) return Promise.resolve(_this2.collection); // Check if entry has been registered in the collection.
1758
+
1759
+ var index = _this2.collection.findIndex(function (entry) {
1760
+ return entry.id === obj.id;
1761
+ });
855
1762
 
856
- if (!drawer) return Promise.resolve(drawerNotFound(drawerKey));
857
- if (hasClass(drawer, _this2.settings.classModal)) return Promise.resolve(); // Enable modal state
1763
+ var _temp6 = function () {
1764
+ if (index >= 0) {
1765
+ var _temp7 = function _temp7() {
1766
+ // Return teleported modal if a reference has been set.
1767
+ if (_entry.getSetting('teleport')) {
1768
+ _entry.teleportReturn();
1769
+ } // Delete properties from collection entry.
858
1770
 
859
- addClass(drawer, _this2.settings.classModal);
860
- addClass(drawer, _this2.settings.stateClosed);
861
- removeClass(drawer, _this2.settings.stateOpened); // Dispatch custom event
862
1771
 
863
- drawer.dispatchEvent(new CustomEvent(_this2.settings.customEventPrefix + 'toModal', {
864
- bubbles: true
865
- }));
866
- return Promise.resolve(drawer);
867
- } catch (e) {
868
- return Promise.reject(e);
869
- }
870
- };
1772
+ Object.getOwnPropertyNames(_entry).forEach(function (prop) {
1773
+ delete _entry[prop];
1774
+ }); // Remove entry from collection.
871
1775
 
872
- var toggle = function toggle(drawerKey) {
873
- try {
874
- var _this2 = this;
1776
+ _this2.collection.splice(index, 1);
1777
+ };
875
1778
 
876
- var drawer = _this2.getDrawer(drawerKey);
1779
+ // Get the collection entry.
1780
+ var _entry = _this2.collection[index]; // If entry is in the opened state, close it.
877
1781
 
878
- if (!drawer) return Promise.resolve(drawerNotFound(drawerKey));
879
- var isClosed = !hasClass(drawer, _this2.settings.stateOpened);
1782
+ var _temp8 = function () {
1783
+ if (close && _entry.state === 'opened') {
1784
+ return Promise.resolve(_entry.close(false)).then(function () {});
1785
+ } else {
1786
+ // Get index of modal in stack array.
1787
+ var stackIndex = _this2.stack.findIndex(function (item) {
1788
+ return item.id === _entry.id;
1789
+ }); // Remove modal from stack array.
880
1790
 
881
- if (isClosed) {
882
- return Promise.resolve(_this2.open(drawer));
883
- } else {
884
- return Promise.resolve(_this2.close(drawer));
885
- }
1791
+
1792
+ if (stackIndex >= 0) {
1793
+ _this2.stack.splice(stackIndex, 1);
1794
+ }
1795
+ }
1796
+ }();
1797
+
1798
+ return _temp8 && _temp8.then ? _temp8.then(_temp7) : _temp7(_temp8);
1799
+ }
1800
+ }();
1801
+
1802
+ return Promise.resolve(_temp6 && _temp6.then ? _temp6.then(_temp5) : _temp5(_temp6));
886
1803
  } catch (e) {
887
1804
  return Promise.reject(e);
888
1805
  }
889
1806
  };
890
1807
 
891
- var Drawer = /*#__PURE__*/function () {
892
- function Drawer(options) {
893
- this.defaults = defaults$2;
894
- this.settings = _extends({}, this.defaults, options);
895
- this.working = false;
896
- this.memory = {};
897
- this.state = {};
898
- this.focusTrap = new FocusTrap();
899
- this.breakpoint = new Breakpoint(this);
900
- this.__handlerClick = handlerClick$2.bind(this);
901
- this.__handlerKeydown = handlerKeydown$2.bind(this);
902
- if (this.settings.autoInit) this.init();
1808
+ var open$1 = function open(query, transition, focus) {
1809
+ if (focus === void 0) {
1810
+ focus = true;
903
1811
  }
904
1812
 
905
- var _proto = Drawer.prototype;
906
-
907
- _proto.init = function init(options) {
908
- if (options === void 0) {
909
- options = null;
910
- }
911
-
912
- if (options) this.settings = _extends({}, this.settings, options);
913
- this.stateSet();
1813
+ try {
1814
+ var _temp3 = function _temp3() {
1815
+ // Update focus if the focus param is true.
1816
+ if (focus) {
1817
+ updateFocusState.call(_this2);
1818
+ } // Dispatch custom opened event.
914
1819
 
915
- if (this.settings.setTabindex) {
916
- this.setTabindex();
917
- }
918
1820
 
919
- this.breakpoint.init();
1821
+ modal.el.dispatchEvent(new CustomEvent(config.customEventPrefix + 'opened', {
1822
+ detail: _this2,
1823
+ bubbles: true
1824
+ })); // Return the modal.
920
1825
 
921
- if (this.settings.eventListeners) {
922
- this.initEventListeners();
923
- }
924
- };
1826
+ return modal;
1827
+ };
925
1828
 
926
- _proto.destroy = function destroy() {
927
- this.breakpoint.destroy();
928
- this.memory = {};
929
- this.state = {};
930
- localStorage.removeItem(this.settings.stateKey);
1829
+ var _this2 = this;
931
1830
 
932
- if (this.settings.eventListeners) {
933
- this.destroyEventListeners();
934
- }
935
- }
936
- /**
937
- * Event listeners
938
- */
939
- ;
1831
+ // Get the modal from collection.
1832
+ var modal = getModal.call(_this2, query); // Get the modal configuration.
940
1833
 
941
- _proto.initEventListeners = function initEventListeners() {
942
- document.addEventListener('click', this.__handlerClick, false);
943
- document.addEventListener('touchend', this.__handlerClick, false);
944
- document.addEventListener('keydown', this.__handlerKeydown, false);
945
- };
1834
+ var config = _extends({}, _this2.settings, modal.settings); // Add transition parameter to configuration.
946
1835
 
947
- _proto.destroyEventListeners = function destroyEventListeners() {
948
- document.removeEventListener('click', this.__handlerClick, false);
949
- document.removeEventListener('touchend', this.__handlerClick, false);
950
- document.removeEventListener('keydown', this.__handlerKeydown, false);
951
- }
952
- /**
953
- * Helpers
954
- */
955
- ;
956
1836
 
957
- _proto.getDrawer = function getDrawer$1(drawerKey) {
958
- return getDrawer.call(this, drawerKey);
959
- };
1837
+ if (transition !== undefined) config.transition = transition; // Check if modal is already in the stack.
960
1838
 
961
- _proto.setTabindex = function setTabindex$1() {
962
- return setTabindex("\n [data-" + this.settings.dataDrawer + "]\n [data-" + this.settings.dataDialog + "]\n ");
963
- }
964
- /**
965
- * Save state functionality
966
- */
967
- ;
1839
+ var index = _this2.stack.findIndex(function (entry) {
1840
+ return entry.id === modal.id;
1841
+ }); // If modal is already open.
968
1842
 
969
- _proto.stateSet = function stateSet$1() {
970
- this.state = stateSet(this.settings);
971
- };
972
1843
 
973
- _proto.stateSave = function stateSave$1(target) {
974
- if (target === void 0) {
975
- target = null;
976
- }
1844
+ if (index >= 0) {
1845
+ // Remove modal from stack array.
1846
+ _this2.stack.splice(index, 1); // Move back to end of stack.
977
1847
 
978
- this.state = stateSave(target, this.settings);
979
- };
980
1848
 
981
- _proto.stateClear = function stateClear$1() {
982
- this.state = stateClear(this.settings);
983
- }
984
- /**
985
- * SwitchTo functionality
986
- */
987
- ;
1849
+ _this2.stack.push(modal);
1850
+ } // If modal is closed.
988
1851
 
989
- _proto.switchToDefault = function switchToDefault$1(drawerKey) {
990
- return switchToDefault.call(this, drawerKey);
991
- };
992
1852
 
993
- _proto.switchToModal = function switchToModal$1(drawerKey) {
994
- return switchToModal.call(this, drawerKey);
995
- }
996
- /**
997
- * Change state functionality
998
- */
999
- ;
1853
+ var _temp4 = function () {
1854
+ if (modal.state === 'closed') {
1855
+ // Update modal state.
1856
+ modal.state = 'opening'; // Apply z-index styles based on stack length.
1000
1857
 
1001
- _proto.toggle = function toggle$1(drawerKey) {
1002
- return toggle.call(this, drawerKey);
1003
- };
1858
+ modal.el.style.zIndex = null;
1859
+ var value = getComputedStyle(modal.el)['z-index'];
1860
+ modal.el.style.zIndex = parseInt(value) + _this2.stack.length + 1; // Store modal in stack array.
1004
1861
 
1005
- _proto.open = function open(drawerKey) {
1006
- return open$2.call(this, drawerKey);
1007
- };
1862
+ _this2.stack.push(modal); // Run the open transition.
1008
1863
 
1009
- _proto.close = function close(drawerKey) {
1010
- return close$2.call(this, drawerKey);
1011
- };
1012
1864
 
1013
- return Drawer;
1014
- }();
1865
+ return Promise.resolve(openTransition(modal.el, config)).then(function () {
1866
+ // Update modal state.
1867
+ modal.state = 'opened';
1868
+ });
1869
+ }
1870
+ }();
1015
1871
 
1016
- var defaults$1 = {
1017
- autoInit: false,
1018
- // Data attributes
1019
- dataModal: 'modal',
1020
- dataDialog: 'modal-dialog',
1021
- dataOpen: 'modal-open',
1022
- dataClose: 'modal-close',
1023
- dataFocus: 'modal-focus',
1024
- dataRequired: 'modal-required',
1025
- // State classes
1026
- stateOpened: 'is-opened',
1027
- stateOpening: 'is-opening',
1028
- stateClosing: 'is-closing',
1029
- stateClosed: 'is-closed',
1030
- // Selector
1031
- selectorInert: null,
1032
- selectorOverflow: 'body',
1033
- // Feature toggles
1034
- customEventPrefix: 'modal:',
1035
- eventListeners: true,
1036
- moveModals: {
1037
- ref: null,
1038
- type: null
1039
- },
1040
- setTabindex: true,
1041
- transition: true
1872
+ return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(_temp3) : _temp3(_temp4));
1873
+ } catch (e) {
1874
+ return Promise.reject(e);
1875
+ }
1042
1876
  };
1043
1877
 
1044
- var close$1 = function close(returnFocus) {
1045
- if (returnFocus === void 0) {
1046
- returnFocus = true;
1878
+ var close$1 = function close(query, transition, focus) {
1879
+ if (focus === void 0) {
1880
+ focus = true;
1047
1881
  }
1048
1882
 
1049
1883
  try {
1050
1884
  var _this2 = this;
1051
1885
 
1052
- var modal = document.querySelector("[data-" + _this2.settings.dataModal + "]." + _this2.settings.stateOpened);
1886
+ // Get the modal from collection, or top modal in stack if no query is provided.
1887
+ var modal = query ? getModal.call(_this2, query) : _this2.active; // If a modal exists and its state is opened.
1053
1888
 
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);
1889
+ var _temp2 = function () {
1890
+ if (modal && modal.state === 'opened') {
1891
+ // Update modal state.
1892
+ modal.state = 'closing'; // Get the modal configuration.
1060
1893
 
1061
- _this2.focusTrap.destroy();
1894
+ var config = _extends({}, _this2.settings, modal.settings); // Add transition parameter to configuration.
1062
1895
 
1063
- modal.dispatchEvent(new CustomEvent(_this2.settings.customEventPrefix + 'closed', {
1064
- detail: _this2,
1065
- bubbles: true
1066
- }));
1067
- _this2.working = false;
1068
- return modal;
1069
- });
1070
- } else {
1071
- return Promise.resolve(modal);
1072
- }
1073
- } catch (e) {
1074
- return Promise.reject(e);
1075
- }
1076
- };
1077
1896
 
1078
- var handlerClick$1 = function handlerClick(event) {
1079
- try {
1080
- var _temp3 = function _temp3(_result) {
1081
- if (_exit2) return _result;
1897
+ if (transition !== undefined) config.transition = transition; // Remove focus from active element.
1082
1898
 
1083
- // Close click
1084
- if (event.target.closest("[data-" + _this2.settings.dataClose + "]")) {
1085
- event.preventDefault();
1899
+ document.activeElement.blur(); // Run the close transition.
1086
1900
 
1087
- _this2.close();
1901
+ return Promise.resolve(closeTransition(modal.el, config)).then(function () {
1902
+ // Remove z-index styles.
1903
+ modal.el.style.zIndex = null; // Get index of modal in stack array.
1088
1904
 
1089
- return;
1090
- } // Root click
1905
+ var index = _this2.stack.findIndex(function (entry) {
1906
+ return entry.id === modal.id;
1907
+ }); // Remove modal from stack array.
1091
1908
 
1092
1909
 
1093
- if (event.target.hasAttribute("data-" + _this2.settings.dataModal) && !event.target.hasAttribute("data-" + _this2.settings.dataRequired)) {
1094
- _this2.close();
1095
- }
1096
- };
1910
+ _this2.stack.splice(index, 1); // Update focus if the focus param is true.
1097
1911
 
1098
- var _exit2;
1099
1912
 
1100
- var _this2 = this;
1913
+ if (focus) {
1914
+ updateFocusState.call(_this2);
1915
+ } // Update modal state.
1101
1916
 
1102
- // Working catch
1103
- if (_this2.working) return Promise.resolve(); // Trigger click
1104
1917
 
1105
- var trigger = event.target.closest("[data-" + _this2.settings.dataOpen + "]");
1918
+ modal.state = 'closed'; // Dispatch custom closed event.
1106
1919
 
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);
1115
-
1116
- _exit2 = 1;
1920
+ modal.el.dispatchEvent(new CustomEvent(config.customEventPrefix + 'closed', {
1921
+ detail: _this2,
1922
+ bubbles: true
1923
+ }));
1117
1924
  });
1118
1925
  }
1119
1926
  }();
1120
1927
 
1121
- return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(_temp3) : _temp3(_temp4));
1928
+ return Promise.resolve(_temp2 && _temp2.then ? _temp2.then(function () {
1929
+ // Return the modal.
1930
+ return modal;
1931
+ }) : modal);
1122
1932
  } catch (e) {
1123
1933
  return Promise.reject(e);
1124
1934
  }
1125
1935
  };
1126
- function handlerKeydown$1(event) {
1127
- // Working catch
1128
- if (this.working) return;
1129
1936
 
1130
- if (event.key === 'Escape') {
1131
- var target = document.querySelector("[data-" + this.settings.dataModal + "]." + this.settings.stateOpened);
1937
+ var closeAll$1 = function closeAll(exclude, transition) {
1938
+ try {
1939
+ var _this2 = this;
1132
1940
 
1133
- if (target && !target.hasAttribute("data-" + this.settings.dataRequired)) {
1134
- this.close();
1135
- }
1136
- }
1137
- }
1941
+ var result = [];
1942
+ return Promise.resolve(Promise.all(_this2.stack.map(function (modal) {
1943
+ try {
1944
+ var _temp3 = function _temp3() {
1945
+ modal.trigger = null;
1946
+ };
1947
+
1948
+ var _temp4 = function () {
1949
+ if (exclude && exclude === modal.id) {
1950
+ Promise.resolve();
1951
+ } else {
1952
+ var _push2 = result.push;
1953
+ return Promise.resolve(close$1.call(_this2, modal, transition, false)).then(function (_close$call) {
1954
+ _push2.call(result, _close$call);
1955
+ });
1956
+ }
1957
+ }();
1138
1958
 
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;
1959
+ return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(_temp3) : _temp3(_temp4));
1960
+ } catch (e) {
1961
+ return Promise.reject(e);
1962
+ }
1963
+ }))).then(function () {
1964
+ return result;
1965
+ });
1966
+ } catch (e) {
1967
+ return Promise.reject(e);
1149
1968
  }
1969
+ };
1150
1970
 
1151
- if (ref === void 0) {
1152
- ref = this.settings.moveModals.ref;
1971
+ var replace = function replace(query, transition, focus) {
1972
+ if (focus === void 0) {
1973
+ focus = true;
1153
1974
  }
1154
1975
 
1155
- var modals = document.querySelectorAll("[data-" + this.settings.dataModal + "]");
1156
- if (modals.length) moveElement(modals, type, ref);
1157
- }
1976
+ try {
1977
+ var _temp3 = function _temp3() {
1978
+ // Update focus if the focus param is true.
1979
+ if (focus) {
1980
+ updateFocusState.call(_this2);
1981
+ } // Return the modals there were opened and closed.
1158
1982
 
1159
- function setInitialState() {
1160
- var _this = this;
1161
1983
 
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);
1984
+ return {
1985
+ opened: resultOpened,
1986
+ closed: resultClosed
1987
+ };
1988
+ };
1169
1989
 
1170
- _this.focusTrap.destroy();
1171
- } // Remove all state classes and add the default state (closed)
1990
+ var _this2 = this;
1172
1991
 
1992
+ // Get the modal from collection.
1993
+ var modal = getModal.call(_this2, query); // Setup results for return.
1173
1994
 
1174
- removeClass(el, _this.settings.stateOpened, _this.settings.stateOpening, _this.settings.stateClosing);
1175
- addClass(el, _this.settings.stateClosed);
1176
- });
1177
- }
1995
+ var resultOpened, resultClosed;
1178
1996
 
1179
- var open$1 = function open(modalKey) {
1180
- try {
1181
- var _this2 = this;
1997
+ var _temp4 = function () {
1998
+ if (modal.state === 'opened') {
1999
+ // If modal is open, close all modals except for replacement.
2000
+ resultOpened = modal;
2001
+ return Promise.resolve(closeAll$1.call(_this2, modal.id, transition)).then(function (_closeAll$call) {
2002
+ resultClosed = _closeAll$call;
2003
+ });
2004
+ } else {
2005
+ // If modal is closed, close all and open replacement at the same time.
2006
+ resultOpened = open$1.call(_this2, modal, transition, false);
2007
+ resultClosed = closeAll$1.call(_this2, false, transition);
2008
+ return Promise.resolve(Promise.all([resultOpened, resultClosed])).then(function () {});
2009
+ }
2010
+ }();
1182
2011
 
1183
- var modal = getModal.call(_this2, modalKey);
1184
- if (!modal) return Promise.resolve(modalNotFound(modalKey));
1185
-
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);
1191
-
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
- }
2012
+ return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(_temp3) : _temp3(_temp4));
1204
2013
  } catch (e) {
1205
2014
  return Promise.reject(e);
1206
2015
  }
1207
2016
  };
1208
2017
 
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();
1219
- }
2018
+ var register$1 = function register(el, dialog) {
2019
+ try {
2020
+ var _this2 = this;
1220
2021
 
1221
- var _proto = Modal.prototype;
2022
+ // Deregister entry incase it has already been registered.
2023
+ return Promise.resolve(deregister$1.call(_this2, el, false)).then(function () {
2024
+ // Save root this for use inside methods API.
2025
+ var root = _this2; // Setup methods API.
2026
+
2027
+ var methods = {
2028
+ open: function open(transition, focus) {
2029
+ return open$1.call(root, this, transition, focus);
2030
+ },
2031
+ close: function close(transition, focus) {
2032
+ return close$1.call(root, this, transition, focus);
2033
+ },
2034
+ replace: function replace$1(transition, focus) {
2035
+ return replace.call(root, this, transition, focus);
2036
+ },
2037
+ deregister: function deregister() {
2038
+ return deregister$1.call(root, this);
2039
+ },
2040
+ teleport: function teleport$1(ref, method) {
2041
+ if (ref === void 0) {
2042
+ ref = this.getSetting('teleport');
2043
+ }
1222
2044
 
1223
- _proto.init = function init(options) {
1224
- if (options === void 0) {
1225
- options = null;
1226
- }
2045
+ if (method === void 0) {
2046
+ method = this.getSetting('teleportMethod');
2047
+ }
1227
2048
 
1228
- if (options) this.settings = _extends({}, this.settings, options);
1229
- this.moveModals();
1230
- this.setInitialState();
2049
+ if (!this.returnRef) {
2050
+ this.returnRef = teleport(this.el, ref, method);
2051
+ return this.el;
2052
+ } else {
2053
+ console.error('Element has already been teleported:', this.el);
2054
+ return false;
2055
+ }
2056
+ },
2057
+ teleportReturn: function teleportReturn() {
2058
+ if (this.returnRef) {
2059
+ this.returnRef = teleport(this.el, this.returnRef);
2060
+ return this.el;
2061
+ } else {
2062
+ console.error('No return reference found:', this.el);
2063
+ return false;
2064
+ }
2065
+ },
2066
+ getSetting: function getSetting(key) {
2067
+ return key in this.settings ? this.settings[key] : root.settings[key];
2068
+ }
2069
+ }; // Setup the modal object.
1231
2070
 
1232
- if (this.settings.setTabindex) {
1233
- this.setTabindex();
1234
- }
2071
+ var entry = _extends({
2072
+ id: el.id,
2073
+ state: 'closed',
2074
+ el: el,
2075
+ dialog: dialog,
2076
+ returnRef: null,
2077
+ settings: getConfig$1(el, _this2.settings.dataConfig)
2078
+ }, methods); // Set aria-modal attribute to true.
1235
2079
 
1236
- if (this.settings.eventListeners) {
1237
- this.initEventListeners();
1238
- }
1239
- };
1240
2080
 
1241
- _proto.destroy = function destroy() {
1242
- this.memory = {};
2081
+ entry.dialog.setAttribute('aria-modal', 'true'); // If a role attribute is not set, set it to "dialog" as the default.
1243
2082
 
1244
- if (this.settings.eventListeners) {
1245
- this.destroyEventListeners();
1246
- }
1247
- }
1248
- /**
1249
- * Event listeners
1250
- */
1251
- ;
2083
+ if (!entry.dialog.hasAttribute('role')) {
2084
+ entry.dialog.setAttribute('role', 'dialog');
2085
+ } // Set tabindex="-1" so dialog is focusable via JS or click.
1252
2086
 
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
- };
1258
2087
 
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);
1263
- }
1264
- /**
1265
- * Helpers
1266
- */
1267
- ;
2088
+ if (entry.getSetting('setTabindex')) {
2089
+ entry.dialog.setAttribute('tabindex', '-1');
2090
+ } // Teleport modal if a reference has been set.
1268
2091
 
1269
- _proto.getModal = function getModal$1(modalKey) {
1270
- return getModal.call(this, modalKey);
1271
- };
1272
2092
 
1273
- _proto.setTabindex = function setTabindex$1() {
1274
- return setTabindex("\n [data-" + this.settings.dataModal + "]\n [data-" + this.settings.dataDialog + "]\n ");
1275
- };
2093
+ if (entry.getSetting('teleport')) {
2094
+ entry.teleport();
2095
+ } // Add entry to collection.
1276
2096
 
1277
- _proto.setInitialState = function setInitialState$1() {
1278
- return setInitialState.call(this);
1279
- };
1280
2097
 
1281
- _proto.moveModals = function moveModals$1(type, ref) {
1282
- return moveModals.call(this, type, ref);
1283
- }
1284
- /**
1285
- * Change state functionality
1286
- */
1287
- ;
2098
+ _this2.collection.push(entry); // Setup initial state.
1288
2099
 
1289
- _proto.open = function open(modalKey) {
1290
- return open$1.call(this, modalKey);
1291
- };
1292
2100
 
1293
- _proto.close = function close(returnFocus) {
1294
- return close$1.call(this, returnFocus);
1295
- };
2101
+ var _temp = function () {
2102
+ if (entry.el.classList.contains(_this2.settings.stateOpened)) {
2103
+ // Open entry with transitions disabled.
2104
+ return Promise.resolve(entry.open(false)).then(function () {});
2105
+ } else {
2106
+ // Remove transition state classes.
2107
+ entry.el.classList.remove(_this2.settings.stateOpening);
2108
+ entry.el.classList.remove(_this2.settings.stateClosing); // Add closed state class.
1296
2109
 
1297
- return Modal;
1298
- }();
2110
+ entry.el.classList.add(_this2.settings.stateClosed);
2111
+ }
2112
+ }();
1299
2113
 
1300
- var Collection = /*#__PURE__*/function () {
1301
- function Collection() {
1302
- this.collection = [];
2114
+ return _temp && _temp.then ? _temp.then(function () {
2115
+ // Return the registered entry.
2116
+ return entry;
2117
+ }) : entry;
2118
+ });
2119
+ } catch (e) {
2120
+ return Promise.reject(e);
1303
2121
  }
2122
+ };
1304
2123
 
1305
- var _proto = Collection.prototype;
1306
-
1307
- _proto.register = function register(item) {
1308
- this.deregister(item);
1309
- this.collection.push(item);
1310
- return this.collection;
1311
- };
1312
-
1313
- _proto.deregister = function deregister(ref) {
1314
- var index = this.collection.findIndex(function (entry) {
1315
- return entry === ref;
1316
- });
2124
+ var _handleClick = /*#__PURE__*/_classPrivateFieldLooseKey("handleClick");
1317
2125
 
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
- }
2126
+ var _handleKeydown$1 = /*#__PURE__*/_classPrivateFieldLooseKey("handleKeydown");
1325
2127
 
1326
- return this.collection;
1327
- };
2128
+ var Modal = /*#__PURE__*/function (_Collection) {
2129
+ _inheritsLoose(Modal, _Collection);
1328
2130
 
1329
- _proto.registerCollection = function registerCollection(items) {
1330
- var _this = this;
2131
+ function Modal(options) {
2132
+ var _this;
1331
2133
 
1332
- items.forEach(function (item) {
1333
- _this.register(item);
2134
+ _this = _Collection.call(this) || this;
2135
+ Object.defineProperty(_assertThisInitialized(_this), _handleClick, {
2136
+ writable: true,
2137
+ value: void 0
1334
2138
  });
1335
- return this.collection;
1336
- };
1337
-
1338
- _proto.deregisterCollection = function deregisterCollection() {
1339
- while (this.collection.length > 0) {
1340
- this.deregister(this.collection[0]);
1341
- }
1342
-
1343
- return this.collection;
1344
- };
1345
-
1346
- _proto.get = function get(query, key) {
1347
- if (key === void 0) {
1348
- key = 'id';
1349
- }
2139
+ Object.defineProperty(_assertThisInitialized(_this), _handleKeydown$1, {
2140
+ writable: true,
2141
+ value: void 0
2142
+ });
2143
+ _this.defaults = defaults$1;
2144
+ _this.settings = _extends({}, _this.defaults, options);
2145
+ _this.trigger = null;
2146
+ _this.focusTrap = new FocusTrap(); // Setup a proxy for stack array.
2147
+
2148
+ _this.stack = new Proxy([], {
2149
+ set: function set(target, property, value) {
2150
+ target[property] = value; // Update global state if stack length changed.
2151
+
2152
+ if (property === 'length') {
2153
+ updateGlobalState(_this.active, _this.settings);
2154
+ updateStackIndex(_this.stack);
2155
+ }
1350
2156
 
1351
- var result = this.collection.find(function (item) {
1352
- return item[key] === query;
2157
+ return true;
2158
+ }
1353
2159
  });
1354
- return result || null;
1355
- };
2160
+ _classPrivateFieldLooseBase(_assertThisInitialized(_this), _handleClick)[_handleClick] = handleClick$1.bind(_assertThisInitialized(_this));
2161
+ _classPrivateFieldLooseBase(_assertThisInitialized(_this), _handleKeydown$1)[_handleKeydown$1] = handleKeydown$1.bind(_assertThisInitialized(_this));
2162
+ if (_this.settings.autoInit) _this.init();
2163
+ return _this;
2164
+ }
1356
2165
 
1357
- return Collection;
1358
- }();
2166
+ var _proto = Modal.prototype;
1359
2167
 
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'
1371
- };
2168
+ _proto.init = function init(options) {
2169
+ try {
2170
+ var _this3 = this;
1372
2171
 
1373
- function close(popover) {
1374
- // Update state class
1375
- popover.target.classList.remove(this.settings.stateActive); // Update a11y attributes
2172
+ // Update settings with passed options.
2173
+ if (options) _this3.settings = _extends({}, _this3.settings, options); // Get all the modals.
1376
2174
 
1377
- if (popover.trigger.hasAttribute('aria-controls')) {
1378
- popover.trigger.setAttribute('aria-expanded', 'false');
1379
- } // Disable popper event listeners
2175
+ var modals = document.querySelectorAll(_this3.settings.selectorModal); // Register the collections array with modal instances.
1380
2176
 
2177
+ return Promise.resolve(_this3.registerCollection(modals)).then(function () {
2178
+ // If eventListeners are enabled, init event listeners.
2179
+ if (_this3.settings.eventListeners) {
2180
+ _this3.initEventListeners();
2181
+ }
1381
2182
 
1382
- popover.popper.setOptions({
1383
- modifiers: [{
1384
- name: 'eventListeners',
1385
- enabled: false
1386
- }]
1387
- }); // Update popover state
2183
+ return _this3;
2184
+ });
2185
+ } catch (e) {
2186
+ return Promise.reject(e);
2187
+ }
2188
+ };
1388
2189
 
1389
- popover.state = 'closed'; // Clear memory if popover trigger matches the one saved in memory
2190
+ _proto.destroy = function destroy() {
2191
+ try {
2192
+ var _this5 = this;
1390
2193
 
1391
- if (popover.trigger === this.memory.trigger) {
1392
- this.memory.trigger = null;
1393
- } // Return the popover
2194
+ // Clear stored trigger.
2195
+ _this5.trigger = null; // Remove all entries from the collection.
1394
2196
 
2197
+ return Promise.resolve(_this5.deregisterCollection()).then(function () {
2198
+ // If eventListeners are enabled, destroy event listeners.
2199
+ if (_this5.settings.eventListeners) {
2200
+ _this5.destroyEventListeners();
2201
+ }
1395
2202
 
1396
- return popover;
1397
- }
1398
- function closeAll() {
1399
- this.collection.forEach(function (popover) {
1400
- if (popover.state === 'opened') {
1401
- popover.close();
2203
+ return _this5;
2204
+ });
2205
+ } catch (e) {
2206
+ return Promise.reject(e);
1402
2207
  }
1403
- }); // Return the collection
2208
+ };
2209
+
2210
+ _proto.initEventListeners = function initEventListeners() {
2211
+ document.addEventListener('click', _classPrivateFieldLooseBase(this, _handleClick)[_handleClick], false);
2212
+ document.addEventListener('touchend', _classPrivateFieldLooseBase(this, _handleClick)[_handleClick], false);
2213
+ document.addEventListener('keydown', _classPrivateFieldLooseBase(this, _handleKeydown$1)[_handleKeydown$1], false);
2214
+ };
1404
2215
 
1405
- return this.collection;
1406
- }
1407
- function closeCheck(popover) {
1408
- // Only run closeCheck if provided popover is currently open
1409
- if (popover.state != 'opened') return; // Needed to correctly check which element is currently being focused
2216
+ _proto.destroyEventListeners = function destroyEventListeners() {
2217
+ document.removeEventListener('click', _classPrivateFieldLooseBase(this, _handleClick)[_handleClick], false);
2218
+ document.removeEventListener('touchend', _classPrivateFieldLooseBase(this, _handleClick)[_handleClick], false);
2219
+ document.removeEventListener('keydown', _classPrivateFieldLooseBase(this, _handleKeydown$1)[_handleKeydown$1], false);
2220
+ };
1410
2221
 
1411
- setTimeout(function () {
1412
- // Check if trigger or target are being hovered
1413
- var isHovered = popover.target.closest(':hover') === popover.target || popover.trigger.closest(':hover') === popover.trigger; // Check if trigger or target are being focused
2222
+ _proto.register = function register(query) {
2223
+ var els = getModalElements.call(this, query);
2224
+ if (els.error) return Promise.reject(els.error);
2225
+ return register$1.call(this, els.modal, els.dialog);
2226
+ };
1414
2227
 
1415
- var isFocused = document.activeElement.closest("#" + popover.id + ", [aria-controls=\"" + popover.id + "\"]"); // Close if the trigger and target are not currently hovered or focused
2228
+ _proto.deregister = function deregister(query) {
2229
+ var modal = this.get(getModalID.call(this, query));
2230
+ return deregister$1.call(this, modal);
2231
+ };
1416
2232
 
1417
- if (!isHovered && !isFocused) {
1418
- popover.close();
1419
- } // Return the popover
2233
+ _proto.open = function open(id, transition, focus) {
2234
+ return open$1.call(this, id, transition, focus);
2235
+ };
1420
2236
 
2237
+ _proto.close = function close(id, transition, focus) {
2238
+ return close$1.call(this, id, transition, focus);
2239
+ };
1421
2240
 
1422
- return popover;
1423
- }, 1);
1424
- }
2241
+ _proto.replace = function replace$1(id, transition, focus) {
2242
+ return replace.call(this, id, transition, focus);
2243
+ };
1425
2244
 
1426
- function handlerClick(popover) {
1427
- if (popover.target.classList.contains(this.settings.stateActive)) {
1428
- popover.close();
1429
- } else {
1430
- this.memory.trigger = popover.trigger;
1431
- popover.open();
1432
- documentClick.call(this, popover);
1433
- }
1434
- }
1435
- function handlerKeydown(event) {
1436
- var _this = this;
2245
+ _proto.closeAll = function closeAll(exclude, transition, focus) {
2246
+ if (exclude === void 0) {
2247
+ exclude = false;
2248
+ }
1437
2249
 
1438
- switch (event.key) {
1439
- case 'Escape':
1440
- if (this.memory.trigger) {
1441
- this.memory.trigger.focus();
1442
- }
2250
+ if (focus === void 0) {
2251
+ focus = true;
2252
+ }
1443
2253
 
1444
- closeAll.call(this);
1445
- return;
2254
+ try {
2255
+ var _this7 = this;
1446
2256
 
1447
- case 'Tab':
1448
- this.collection.forEach(function (popover) {
1449
- closeCheck.call(_this, popover);
2257
+ return Promise.resolve(closeAll$1.call(_this7, exclude, transition)).then(function (result) {
2258
+ // Update focus if the focus param is true.
2259
+ if (focus) {
2260
+ updateFocusState.call(_this7);
2261
+ }
2262
+
2263
+ return result;
1450
2264
  });
1451
- return;
2265
+ } catch (e) {
2266
+ return Promise.reject(e);
2267
+ }
2268
+ };
1452
2269
 
1453
- default:
1454
- return;
1455
- }
1456
- }
1457
- function documentClick(popover) {
1458
- var root = this;
1459
- document.addEventListener('click', function _f(event) {
1460
- // Check if a popover was clicked
1461
- var result = event.target.closest("#" + popover.id + ", [aria-controls=\"" + popover.id + "\"]");
2270
+ _createClass(Modal, [{
2271
+ key: "active",
2272
+ get: function get() {
2273
+ return this.stack[this.stack.length - 1];
2274
+ }
2275
+ }]);
1462
2276
 
1463
- if (!result) {
1464
- // If it doesn't match and popover is open, close it and remove event listener
1465
- if (popover.target && popover.target.classList.contains(root.settings.stateActive)) {
1466
- popover.close();
1467
- }
2277
+ return Modal;
2278
+ }(Collection);
1468
2279
 
1469
- this.removeEventListener('click', _f);
1470
- } else {
1471
- // If it does match and popover isn't currently active, remove event listener
1472
- if (popover.target && !popover.target.classList.contains(root.settings.stateActive)) {
1473
- this.removeEventListener('click', _f);
1474
- }
1475
- }
1476
- });
1477
- }
2280
+ var defaults = {
2281
+ autoInit: false,
2282
+ // Selectors
2283
+ selectorPopover: '.popover',
2284
+ selectorArrow: '.popover__arrow',
2285
+ // State classes
2286
+ stateActive: 'is-active',
2287
+ // Feature settings
2288
+ eventListeners: true,
2289
+ eventType: 'click',
2290
+ placement: 'bottom'
2291
+ };
1478
2292
 
1479
2293
  function getConfig(el, settings) {
1480
- // Get the computed styles of the popover
1481
- var styles = getComputedStyle(el); // Setup the config obj with default values
2294
+ // Get the computed styles of the element.
2295
+ var styles = getComputedStyle(el); // Setup the config obj with default values.
1482
2296
 
1483
2297
  var config = {
1484
2298
  'placement': settings.placement,
@@ -1488,29 +2302,30 @@ function getConfig(el, settings) {
1488
2302
  'flip-padding': 0,
1489
2303
  'arrow-element': settings.selectorArrow,
1490
2304
  'arrow-padding': 0
1491
- }; // Loop through config obj
2305
+ }; // Loop through config obj.
1492
2306
 
1493
2307
  for (var prop in config) {
1494
- // Get the CSS variable property values
2308
+ // Get the CSS variable property values.
1495
2309
  var prefix = getComputedStyle(document.body).getPropertyValue('--vrembem-variable-prefix');
1496
- var value = styles.getPropertyValue("--" + prefix + "popover-" + prop).trim(); // If a value was found, replace the default in config obj
2310
+ var value = styles.getPropertyValue("--" + prefix + "popover-" + prop).trim(); // If a value was found, replace the default in config obj.
1497
2311
 
1498
2312
  if (value) {
1499
2313
  config[prop] = value;
1500
2314
  }
1501
- } // Return the config obj
2315
+ } // Return the config obj.
1502
2316
 
1503
2317
 
1504
2318
  return config;
1505
2319
  }
2320
+
1506
2321
  function getPadding(value) {
1507
- var padding; // Split the value by spaces if it's a string
2322
+ var padding; // Split the value by spaces if it's a string.
1508
2323
 
1509
- var array = typeof value === 'string' ? value.trim().split(' ') : [value]; // Convert individual values to integers
2324
+ var array = typeof value === 'string' ? value.trim().split(' ') : [value]; // Convert individual values to integers.
1510
2325
 
1511
2326
  array.forEach(function (item, index) {
1512
2327
  array[index] = parseInt(item, 10);
1513
- }); // Build the padding object based on the number of values passed
2328
+ }); // Build the padding object based on the number of values passed.
1514
2329
 
1515
2330
  switch (array.length) {
1516
2331
  case 1:
@@ -1547,11 +2362,12 @@ function getPadding(value) {
1547
2362
  default:
1548
2363
  padding = false;
1549
2364
  break;
1550
- } // Return the padding object
2365
+ } // Return the padding object.
1551
2366
 
1552
2367
 
1553
2368
  return padding;
1554
2369
  }
2370
+
1555
2371
  function getModifiers(options) {
1556
2372
  return [{
1557
2373
  name: 'offset',
@@ -1576,57 +2392,212 @@ function getModifiers(options) {
1576
2392
  }
1577
2393
  }];
1578
2394
  }
2395
+
2396
+ function getPopover(query) {
2397
+ // Get the entry from collection.
2398
+ var entry = typeof query === 'string' ? this.get(query) : this.get(query.id); // Return entry if it was resolved, otherwise throw error.
2399
+
2400
+ if (entry) {
2401
+ return entry;
2402
+ } else {
2403
+ throw new Error("Popover not found in collection with id of \"" + query + "\".");
2404
+ }
2405
+ }
2406
+
1579
2407
  function getPopoverID(obj) {
1580
- // If it's a string
2408
+ // If it's a string, return the string.
1581
2409
  if (typeof obj === 'string') {
1582
2410
  return obj;
1583
- } // If it's an HTML element
2411
+ } // If it's an HTML element.
1584
2412
  else if (typeof obj.hasAttribute === 'function') {
1585
- // If it's a popover trigger
1586
- if (obj.hasAttribute('aria-controls')) {
2413
+ // If it's a popover element, return the id.
2414
+ if (obj.closest(this.settings.selectorPopover)) {
2415
+ obj = obj.closest(this.settings.selectorPopover);
2416
+ return obj.id;
2417
+ } // If it's a popover trigger, return value of aria-controls.
2418
+ else if (obj.hasAttribute('aria-controls')) {
1587
2419
  return obj.getAttribute('aria-controls');
1588
- } // If it's a popover tooltip trigger
2420
+ } // If it's a popover tooltip trigger, return the value of aria-describedby.
1589
2421
  else if (obj.hasAttribute('aria-describedby')) {
1590
2422
  return obj.getAttribute('aria-describedby');
1591
- } // If it's a popover target
1592
- else if (obj.closest(this.settings.selectorPopover)) {
1593
- return obj.id;
1594
- } // Return false if no id was found
2423
+ } // Return false if no id was found.
1595
2424
  else return false;
1596
- } // If it has an ID property
2425
+ } // If it has an id property, return its value.
1597
2426
  else if (obj.id) {
1598
2427
  return obj.id;
1599
- } // Return false if no id was found
2428
+ } // Return false if no id was found.
1600
2429
  else return false;
1601
2430
  }
2431
+
1602
2432
  function getPopoverElements(query) {
1603
2433
  var id = getPopoverID.call(this, query);
1604
2434
 
1605
2435
  if (id) {
2436
+ var popover = document.querySelector("#" + id);
1606
2437
  var trigger = document.querySelector("[aria-controls=\"" + id + "\"]") || document.querySelector("[aria-describedby=\"" + id + "\"]");
1607
- var target = document.querySelector("#" + id);
1608
2438
 
1609
- if (!trigger && !target) {
1610
- console.error('No popover elements found using the provided ID:', id);
2439
+ if (!trigger && !popover) {
2440
+ return {
2441
+ error: new Error("No popover elements found using the ID: \"" + id + "\".")
2442
+ };
1611
2443
  } else if (!trigger) {
1612
- console.error('No popover trigger associated with the provided popover:', target);
1613
- } else if (!target) {
1614
- console.error('No popover associated with the provided popover trigger:', trigger);
1615
- }
1616
-
1617
- if (!trigger || !target) {
1618
- return false;
2444
+ return {
2445
+ error: new Error('No popover trigger associated with the provided popover.')
2446
+ };
2447
+ } else if (!popover) {
2448
+ return {
2449
+ error: new Error('No popover associated with the provided popover trigger.')
2450
+ };
1619
2451
  } else {
1620
2452
  return {
1621
- trigger: trigger,
1622
- target: target
2453
+ popover: popover,
2454
+ trigger: trigger
1623
2455
  };
1624
2456
  }
1625
2457
  } else {
1626
- console.error('Could not resolve the popover ID:', query);
1627
- return false;
2458
+ return {
2459
+ error: new Error('Could not resolve the popover ID.')
2460
+ };
2461
+ }
2462
+ }
2463
+
2464
+ var closeAll = function closeAll() {
2465
+ try {
2466
+ var _this4 = this;
2467
+
2468
+ var result = [];
2469
+ return Promise.resolve(Promise.all(_this4.collection.map(function (popover) {
2470
+ try {
2471
+ var _temp4 = function () {
2472
+ if (popover.state === 'opened') {
2473
+ var _push2 = result.push;
2474
+ return Promise.resolve(close.call(_this4, popover)).then(function (_close$call) {
2475
+ _push2.call(result, _close$call);
2476
+ });
2477
+ }
2478
+ }();
2479
+
2480
+ return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(function () {}) : void 0);
2481
+ } catch (e) {
2482
+ return Promise.reject(e);
2483
+ }
2484
+ }))).then(function () {
2485
+ return result;
2486
+ });
2487
+ } catch (e) {
2488
+ return Promise.reject(e);
2489
+ }
2490
+ };
2491
+ var close = function close(query) {
2492
+ try {
2493
+ var _temp2 = function _temp2(popover) {
2494
+ // If a modal exists and its state is opened.
2495
+ if (popover && popover.state === 'opened') {
2496
+ // Update state class.
2497
+ popover.el.classList.remove(_this2.settings.stateActive); // Update accessibility attribute(s).
2498
+
2499
+ if (popover.trigger.hasAttribute('aria-controls')) {
2500
+ popover.trigger.setAttribute('aria-expanded', 'false');
2501
+ } // Disable popper event listeners.
2502
+
2503
+
2504
+ popover.popper.setOptions({
2505
+ modifiers: [{
2506
+ name: 'eventListeners',
2507
+ enabled: false
2508
+ }]
2509
+ }); // Update popover state.
2510
+
2511
+ popover.state = 'closed'; // Clear root trigger if popover trigger matches.
2512
+
2513
+ if (popover.trigger === _this2.trigger) {
2514
+ _this2.trigger = null;
2515
+ }
2516
+ } // Return the popover.
2517
+
2518
+
2519
+ return popover;
2520
+ };
2521
+
2522
+ var _this2 = this;
2523
+
2524
+ // Get the popover from collection.
2525
+ return Promise.resolve(query ? _temp2(getPopover.call(_this2, query)) : Promise.resolve(closeAll.call(_this2)).then(_temp2));
2526
+ } catch (e) {
2527
+ return Promise.reject(e);
2528
+ }
2529
+ };
2530
+ function closeCheck(popover) {
2531
+ // Only run closeCheck if provided popover is currently open.
2532
+ if (popover.state != 'opened') return; // Needed to correctly check which element is currently being focused.
2533
+
2534
+ setTimeout(function () {
2535
+ // Check if trigger or element are being hovered.
2536
+ var isHovered = popover.el.closest(':hover') === popover.el || popover.trigger.closest(':hover') === popover.trigger; // Check if trigger or element are being focused.
2537
+
2538
+ var isFocused = document.activeElement.closest("#" + popover.id + ", [aria-controls=\"" + popover.id + "\"]"); // Close if the trigger and element are not currently hovered or focused.
2539
+
2540
+ if (!isHovered && !isFocused) {
2541
+ popover.close();
2542
+ } // Return the popover.
2543
+
2544
+
2545
+ return popover;
2546
+ }, 1);
2547
+ }
2548
+
2549
+ function handleClick(popover) {
2550
+ if (popover.state === 'opened') {
2551
+ popover.close();
2552
+ } else {
2553
+ this.trigger = popover.trigger;
2554
+ popover.open();
2555
+ handleDocumentClick.call(this, popover);
2556
+ }
2557
+ }
2558
+ function handleKeydown(event) {
2559
+ var _this = this;
2560
+
2561
+ switch (event.key) {
2562
+ case 'Escape':
2563
+ if (this.trigger) {
2564
+ this.trigger.focus();
2565
+ }
2566
+
2567
+ closeAll.call(this);
2568
+ return;
2569
+
2570
+ case 'Tab':
2571
+ this.collection.forEach(function (popover) {
2572
+ closeCheck.call(_this, popover);
2573
+ });
2574
+ return;
2575
+
2576
+ default:
2577
+ return;
1628
2578
  }
1629
2579
  }
2580
+ function handleDocumentClick(popover) {
2581
+ var root = this;
2582
+ document.addEventListener('click', function _f(event) {
2583
+ // Check if a popover was clicked.
2584
+ var result = event.target.closest("#" + popover.id + ", [aria-controls=\"" + popover.id + "\"]");
2585
+
2586
+ if (!result) {
2587
+ // If it doesn't match and popover is open, close it and remove event listener.
2588
+ if (popover.el && popover.el.classList.contains(root.settings.stateActive)) {
2589
+ popover.close();
2590
+ }
2591
+
2592
+ this.removeEventListener('click', _f);
2593
+ } else {
2594
+ // If it does match and popover isn't currently active, remove event listener.
2595
+ if (popover.el && !popover.el.classList.contains(root.settings.stateActive)) {
2596
+ this.removeEventListener('click', _f);
2597
+ }
2598
+ }
2599
+ });
2600
+ }
1630
2601
 
1631
2602
  var top = 'top';
1632
2603
  var bottom = 'bottom';
@@ -1928,6 +2899,10 @@ function getContainingBlock(element) {
1928
2899
 
1929
2900
  var currentNode = getParentNode(element);
1930
2901
 
2902
+ if (isShadowRoot(currentNode)) {
2903
+ currentNode = currentNode.host;
2904
+ }
2905
+
1931
2906
  while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {
1932
2907
  var css = getComputedStyle$1(currentNode); // This is non-exhaustive but covers the most common CSS properties that
1933
2908
  // create a containing block.
@@ -2151,7 +3126,7 @@ function mapToStyles(_ref2) {
2151
3126
 
2152
3127
  if (placement === top || (placement === left || placement === right) && variation === end) {
2153
3128
  sideY = bottom;
2154
- var offsetY = isFixed && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]
3129
+ var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]
2155
3130
  offsetParent[heightProp];
2156
3131
  y -= offsetY - popperRect.height;
2157
3132
  y *= gpuAcceleration ? 1 : -1;
@@ -2159,7 +3134,7 @@ function mapToStyles(_ref2) {
2159
3134
 
2160
3135
  if (placement === left || (placement === top || placement === bottom) && variation === end) {
2161
3136
  sideX = right;
2162
- var offsetX = isFixed && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]
3137
+ var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]
2163
3138
  offsetParent[widthProp];
2164
3139
  x -= offsetX - popperRect.width;
2165
3140
  x *= gpuAcceleration ? 1 : -1;
@@ -3411,170 +4386,204 @@ var createPopper = /*#__PURE__*/popperGenerator({
3411
4386
  defaultModifiers: defaultModifiers
3412
4387
  }); // eslint-disable-next-line import/no-unused-modules
3413
4388
 
3414
- function open(popover) {
3415
- // Update state class
3416
- popover.target.classList.add(this.settings.stateActive); // Update a11y attribute
4389
+ var deregister = function deregister(obj) {
4390
+ try {
4391
+ var _this2 = this;
4392
+
4393
+ // Return collection if nothing was passed.
4394
+ if (!obj) return Promise.resolve(_this2.collection); // Check if entry has been registered in the collection.
4395
+
4396
+ var index = _this2.collection.findIndex(function (entry) {
4397
+ return entry.id === obj.id;
4398
+ });
4399
+
4400
+ if (index >= 0) {
4401
+ // Get the collection entry.
4402
+ var entry = _this2.collection[index]; // If entry is in the opened state, close it.
4403
+
4404
+ if (entry.state === 'opened') {
4405
+ entry.close();
4406
+ } // Clean up the popper instance.
4407
+
4408
+
4409
+ entry.popper.destroy(); // Remove event listeners.
4410
+
4411
+ deregisterEventListeners(entry); // Delete properties from collection entry.
4412
+
4413
+ Object.getOwnPropertyNames(entry).forEach(function (prop) {
4414
+ delete entry[prop];
4415
+ }); // Remove entry from collection.
3417
4416
 
3418
- if (popover.trigger.hasAttribute('aria-controls')) {
3419
- popover.trigger.setAttribute('aria-expanded', 'true');
3420
- } // Update popover config
4417
+ _this2.collection.splice(index, 1);
4418
+ } // Return the modified collection.
3421
4419
 
3422
4420
 
3423
- popover.config = getConfig(popover.target, this.settings); // Enable popper event listeners and set placement/modifiers
4421
+ return Promise.resolve(_this2.collection);
4422
+ } catch (e) {
4423
+ return Promise.reject(e);
4424
+ }
4425
+ };
4426
+ function deregisterEventListeners(entry) {
4427
+ // If event listeners have been setup.
4428
+ if (entry.__eventListeners) {
4429
+ // Loop through listeners and remove from the appropriate elements.
4430
+ entry.__eventListeners.forEach(function (evObj) {
4431
+ evObj.el.forEach(function (el) {
4432
+ evObj.type.forEach(function (type) {
4433
+ entry[el].removeEventListener(type, evObj.listener, false);
4434
+ });
4435
+ });
4436
+ }); // Remove eventListeners object from collection.
3424
4437
 
3425
- popover.popper.setOptions({
3426
- placement: popover.config['placement'],
3427
- modifiers: [{
3428
- name: 'eventListeners',
3429
- enabled: true
3430
- }].concat(getModifiers(popover.config))
3431
- }); // Update popover position
3432
4438
 
3433
- popover.popper.update(); // Update popover state
4439
+ delete entry.__eventListeners;
4440
+ } // Return the entry object.
3434
4441
 
3435
- popover.state = 'opened'; // Return the popover
3436
4442
 
3437
- return popover;
4443
+ return entry;
3438
4444
  }
3439
4445
 
3440
- function register(trigger, target) {
3441
- // Deregister popover if it already exists in the collection
3442
- this.deregister(target.id); // Create popper instance
4446
+ var open = function open(query) {
4447
+ try {
4448
+ var _this2 = this;
3443
4449
 
3444
- var popperInstance = createPopper(trigger, target); // Save root this for use inside object & create methods API
4450
+ // Get the popover from collection.
4451
+ var popover = getPopover.call(_this2, query); // Update state class.
3445
4452
 
3446
- var root = this;
3447
- var methods = {
3448
- open: function open$1() {
3449
- open.call(root, this);
3450
- },
3451
- close: function close$1() {
3452
- close.call(root, this);
3453
- },
3454
- deregister: function deregister() {
3455
- _deregister.call(root, this);
3456
- }
3457
- }; // Build popover object and push to collection array
4453
+ popover.el.classList.add(_this2.settings.stateActive); // Update accessibility attribute(s).
3458
4454
 
3459
- var popover = _extends({
3460
- id: target.id,
3461
- state: 'closed',
3462
- trigger: trigger,
3463
- target: target,
3464
- popper: popperInstance,
3465
- config: getConfig(target, this.settings)
3466
- }, methods); // Setup event listeners
4455
+ if (popover.trigger.hasAttribute('aria-controls')) {
4456
+ popover.trigger.setAttribute('aria-expanded', 'true');
4457
+ } // Update popover config.
3467
4458
 
3468
4459
 
3469
- registerEventListeners.call(this, popover); // Set initial state of popover
4460
+ popover.config = getConfig(popover.el, _this2.settings); // Enable popper event listeners and set placement/modifiers.
3470
4461
 
3471
- if (popover.target.classList.contains(this.settings.stateActive)) {
3472
- popover.open();
3473
- documentClick.call(this, popover);
3474
- } else {
3475
- popover.close();
3476
- } // Add item to collection
4462
+ popover.popper.setOptions({
4463
+ placement: popover.config['placement'],
4464
+ modifiers: [{
4465
+ name: 'eventListeners',
4466
+ enabled: true
4467
+ }].concat(getModifiers(popover.config))
4468
+ }); // Update popover position.
3477
4469
 
4470
+ popover.popper.update(); // Update popover state.
3478
4471
 
3479
- this.collection.push(popover); // Return the popover object
4472
+ popover.state = 'opened'; // Return the popover.
3480
4473
 
3481
- return popover;
3482
- }
4474
+ return Promise.resolve(popover);
4475
+ } catch (e) {
4476
+ return Promise.reject(e);
4477
+ }
4478
+ };
4479
+
4480
+ var register = function register(el, trigger) {
4481
+ try {
4482
+ var _this2 = this;
4483
+
4484
+ // Deregister entry incase it has already been registered.
4485
+ deregister.call(_this2, el); // Save root this for use inside methods API.
3483
4486
 
3484
- function _deregister(popover) {
3485
- // Check if this item has been registered in the collection
3486
- var index = this.collection.findIndex(function (entry) {
3487
- return entry.id === popover.id;
3488
- }); // If the entry exists in the collection
3489
4487
 
3490
- if (index >= 0) {
3491
- // Get the collection entry
3492
- var entry = this.collection[index]; // Close the collection entry if it's open
4488
+ var root = _this2; // Setup methods API.
3493
4489
 
3494
- if (entry.state === 'opened') {
3495
- entry.close();
3496
- } // Clean up the popper instance
4490
+ var methods = {
4491
+ open: function open$1() {
4492
+ return open.call(root, this);
4493
+ },
4494
+ close: function close$1() {
4495
+ return close.call(root, this);
4496
+ },
4497
+ deregister: function deregister$1() {
4498
+ return deregister.call(root, this);
4499
+ }
4500
+ }; // Setup the popover object.
3497
4501
 
4502
+ var entry = _extends({
4503
+ id: el.id,
4504
+ state: 'closed',
4505
+ el: el,
4506
+ trigger: trigger,
4507
+ popper: createPopper(trigger, el),
4508
+ config: getConfig(el, _this2.settings)
4509
+ }, methods); // Set aria-expanded to false if trigger has aria-controls attribute.
3498
4510
 
3499
- entry.popper.destroy(); // Remove event listeners
3500
4511
 
3501
- deregisterEventListeners(entry); // Delete properties from collection entry
4512
+ if (entry.trigger.hasAttribute('aria-controls')) {
4513
+ entry.trigger.setAttribute('aria-expanded', 'false');
4514
+ } // Setup event listeners.
3502
4515
 
3503
- Object.getOwnPropertyNames(entry).forEach(function (prop) {
3504
- delete entry[prop];
3505
- }); // Remove entry from collection
3506
4516
 
3507
- this.collection.splice(index, 1);
3508
- } // Return the new collection
4517
+ registerEventListeners.call(_this2, entry); // Add entry to collection.
3509
4518
 
4519
+ _this2.collection.push(entry); // Set initial state.
3510
4520
 
3511
- return this.collection;
3512
- }
3513
- function registerEventListeners(popover) {
3514
- // If event listeners aren't already setup
3515
- if (!popover.__eventListeners) {
3516
- // Add event listeners based on event type
3517
- var eventType = popover.config['event'];
4521
+
4522
+ var _temp2 = function () {
4523
+ if (entry.el.classList.contains(_this2.settings.stateActive)) {
4524
+ return Promise.resolve(entry.open()).then(function () {
4525
+ handleDocumentClick.call(_this2, entry);
4526
+ });
4527
+ }
4528
+ }();
4529
+
4530
+ return Promise.resolve(_temp2 && _temp2.then ? _temp2.then(function () {
4531
+ // Return the registered entry.
4532
+ return entry;
4533
+ }) : entry);
4534
+ } catch (e) {
4535
+ return Promise.reject(e);
4536
+ }
4537
+ };
4538
+ function registerEventListeners(entry) {
4539
+ // If event listeners aren't already setup.
4540
+ if (!entry.__eventListeners) {
4541
+ // Add event listeners based on event type.
4542
+ var eventType = entry.config['event']; // If the event type is hover.
3518
4543
 
3519
4544
  if (eventType === 'hover') {
3520
- // Setup event listeners object for hover
3521
- popover.__eventListeners = [{
4545
+ // Setup event listeners object for hover.
4546
+ entry.__eventListeners = [{
3522
4547
  el: ['trigger'],
3523
4548
  type: ['mouseenter', 'focus'],
3524
- listener: open.bind(this, popover)
4549
+ listener: open.bind(this, entry)
3525
4550
  }, {
3526
- el: ['trigger', 'target'],
4551
+ el: ['el', 'trigger'],
3527
4552
  type: ['mouseleave', 'focusout'],
3528
- listener: closeCheck.bind(this, popover)
3529
- }]; // Loop through listeners and apply to appropriate elements
4553
+ listener: closeCheck.bind(this, entry)
4554
+ }]; // Loop through listeners and apply to the appropriate elements.
3530
4555
 
3531
- popover.__eventListeners.forEach(function (evObj) {
4556
+ entry.__eventListeners.forEach(function (evObj) {
3532
4557
  evObj.el.forEach(function (el) {
3533
4558
  evObj.type.forEach(function (type) {
3534
- popover[el].addEventListener(type, evObj.listener, false);
4559
+ entry[el].addEventListener(type, evObj.listener, false);
3535
4560
  });
3536
4561
  });
3537
4562
  });
3538
- } else {
3539
- // Setup event listeners object for click
3540
- popover.__eventListeners = [{
4563
+ } // Else the event type is click.
4564
+ else {
4565
+ // Setup event listeners object for click.
4566
+ entry.__eventListeners = [{
3541
4567
  el: ['trigger'],
3542
4568
  type: ['click'],
3543
- listener: handlerClick.bind(this, popover)
3544
- }]; // Loop through listeners and apply to appropriate elements
4569
+ listener: handleClick.bind(this, entry)
4570
+ }]; // Loop through listeners and apply to the appropriate elements.
3545
4571
 
3546
- popover.__eventListeners.forEach(function (evObj) {
4572
+ entry.__eventListeners.forEach(function (evObj) {
3547
4573
  evObj.el.forEach(function (el) {
3548
4574
  evObj.type.forEach(function (type) {
3549
- popover[el].addEventListener(type, evObj.listener, false);
4575
+ entry[el].addEventListener(type, evObj.listener, false);
3550
4576
  });
3551
4577
  });
3552
4578
  });
3553
4579
  }
3554
- } // Return the popover object
4580
+ } // Return the entry object.
3555
4581
 
3556
4582
 
3557
- return popover;
4583
+ return entry;
3558
4584
  }
3559
- function deregisterEventListeners(popover) {
3560
- // If event listeners have been setup
3561
- if (popover.__eventListeners) {
3562
- // Loop through listeners and remove from appropriate elements
3563
- popover.__eventListeners.forEach(function (evObj) {
3564
- evObj.el.forEach(function (el) {
3565
- evObj.type.forEach(function (type) {
3566
- popover[el].removeEventListener(type, evObj.listener, false);
3567
- });
3568
- });
3569
- }); // Remove eventListeners object from collection
3570
-
3571
-
3572
- delete popover.__eventListeners;
3573
- } // Return the popover object
3574
4585
 
3575
-
3576
- return popover;
3577
- }
4586
+ var _handleKeydown = /*#__PURE__*/_classPrivateFieldLooseKey("handleKeydown");
3578
4587
 
3579
4588
  var Popover = /*#__PURE__*/function (_Collection) {
3580
4589
  _inheritsLoose(Popover, _Collection);
@@ -3583,13 +4592,14 @@ var Popover = /*#__PURE__*/function (_Collection) {
3583
4592
  var _this;
3584
4593
 
3585
4594
  _this = _Collection.call(this) || this;
4595
+ Object.defineProperty(_assertThisInitialized(_this), _handleKeydown, {
4596
+ writable: true,
4597
+ value: void 0
4598
+ });
3586
4599
  _this.defaults = defaults;
3587
- _this.settings = _extends({}, _this.defaults, options); // this.collection = [];
3588
-
3589
- _this.memory = {
3590
- trigger: null
3591
- };
3592
- _this.__handlerKeydown = handlerKeydown.bind(_assertThisInitialized(_this));
4600
+ _this.settings = _extends({}, _this.defaults, options);
4601
+ _this.trigger = null;
4602
+ _classPrivateFieldLooseBase(_assertThisInitialized(_this), _handleKeydown)[_handleKeydown] = handleKeydown.bind(_assertThisInitialized(_this));
3593
4603
  if (_this.settings.autoInit) _this.init();
3594
4604
  return _this;
3595
4605
  }
@@ -3597,55 +4607,67 @@ var Popover = /*#__PURE__*/function (_Collection) {
3597
4607
  var _proto = Popover.prototype;
3598
4608
 
3599
4609
  _proto.init = function init(options) {
3600
- if (options === void 0) {
3601
- options = null;
3602
- }
4610
+ try {
4611
+ var _this3 = this;
3603
4612
 
3604
- // Update settings with passed options
3605
- if (options) this.settings = _extends({}, this.settings, options); // Get all the popovers
4613
+ // Update settings with passed options.
4614
+ if (options) _this3.settings = _extends({}, _this3.settings, options); // Get all the popovers.
3606
4615
 
3607
- var popovers = document.querySelectorAll(this.settings.selectorPopover); // Build the collections array with popover instances
4616
+ var popovers = document.querySelectorAll(_this3.settings.selectorPopover); // Register the collections array with popover instances.
3608
4617
 
3609
- this.registerCollection(popovers); // If eventListeners is enabled
4618
+ return Promise.resolve(_this3.registerCollection(popovers)).then(function () {
4619
+ // If eventListeners are enabled, init event listeners.
4620
+ if (_this3.settings.eventListeners) {
4621
+ // Pass false to initEventListeners() since registerCollection()
4622
+ // already adds event listeners to popovers.
4623
+ _this3.initEventListeners(false);
4624
+ }
3610
4625
 
3611
- if (this.settings.eventListeners) {
3612
- // Pass false to initEventListeners() since registerCollection()
3613
- // already adds event listeners to popovers
3614
- this.initEventListeners(false);
4626
+ return _this3;
4627
+ });
4628
+ } catch (e) {
4629
+ return Promise.reject(e);
3615
4630
  }
3616
4631
  };
3617
4632
 
3618
4633
  _proto.destroy = function destroy() {
3619
- // Deregister all popovers from collection
3620
- this.deregisterCollection(); // If eventListeners is enabled
4634
+ try {
4635
+ var _this5 = this;
4636
+
4637
+ // Clear stored trigger.
4638
+ _this5.trigger = null; // Remove all entries from the collection.
4639
+
4640
+ return Promise.resolve(_this5.deregisterCollection()).then(function () {
4641
+ // If eventListeners are enabled, destroy event listeners.
4642
+ if (_this5.settings.eventListeners) {
4643
+ // Pass false to destroyEventListeners() since deregisterCollection()
4644
+ // already removes event listeners from popovers.
4645
+ _this5.destroyEventListeners(false);
4646
+ }
3621
4647
 
3622
- if (this.settings.eventListeners) {
3623
- // Pass false to destroyEventListeners() since deregisterCollection()
3624
- // already removes event listeners from popovers
3625
- this.destroyEventListeners(false);
4648
+ return _this5;
4649
+ });
4650
+ } catch (e) {
4651
+ return Promise.reject(e);
3626
4652
  }
3627
- }
3628
- /**
3629
- * Event listeners
3630
- */
3631
- ;
4653
+ };
3632
4654
 
3633
4655
  _proto.initEventListeners = function initEventListeners(processCollection) {
3634
- var _this2 = this;
4656
+ var _this6 = this;
3635
4657
 
3636
4658
  if (processCollection === void 0) {
3637
4659
  processCollection = true;
3638
4660
  }
3639
4661
 
3640
4662
  if (processCollection) {
3641
- // Loop through collection and setup event listeners
4663
+ // Loop through collection and setup event listeners.
3642
4664
  this.collection.forEach(function (popover) {
3643
- registerEventListeners.call(_this2, popover);
4665
+ registerEventListeners.call(_this6, popover);
3644
4666
  });
3645
- } // Add keydown global event listener
4667
+ } // Add keydown global event listener.
3646
4668
 
3647
4669
 
3648
- document.addEventListener('keydown', this.__handlerKeydown, false);
4670
+ document.addEventListener('keydown', _classPrivateFieldLooseBase(this, _handleKeydown)[_handleKeydown], false);
3649
4671
  };
3650
4672
 
3651
4673
  _proto.destroyEventListeners = function destroyEventListeners(processCollection) {
@@ -3654,50 +4676,33 @@ var Popover = /*#__PURE__*/function (_Collection) {
3654
4676
  }
3655
4677
 
3656
4678
  if (processCollection) {
3657
- // Loop through collection and remove event listeners
4679
+ // Loop through collection and remove event listeners.
3658
4680
  this.collection.forEach(function (popover) {
3659
4681
  deregisterEventListeners(popover);
3660
4682
  });
3661
- } // Remove keydown global event listener
4683
+ } // Remove keydown global event listener.
3662
4684
 
3663
4685
 
3664
- document.removeEventListener('keydown', this.__handlerKeydown, false);
3665
- }
3666
- /**
3667
- * Register popover functionality
3668
- */
3669
- ;
4686
+ document.removeEventListener('keydown', _classPrivateFieldLooseBase(this, _handleKeydown)[_handleKeydown], false);
4687
+ };
3670
4688
 
3671
4689
  _proto.register = function register$1(query) {
3672
4690
  var els = getPopoverElements.call(this, query);
3673
- if (!els) return false;
3674
- return register.call(this, els.trigger, els.target);
4691
+ if (els.error) return Promise.reject(els.error);
4692
+ return register.call(this, els.popover, els.trigger);
3675
4693
  };
3676
4694
 
3677
- _proto.deregister = function deregister(query) {
3678
- var popover = this.get(getPopoverID(query));
3679
- if (!popover) return false;
3680
- return _deregister.call(this, popover);
3681
- }
3682
- /**
3683
- * Change state functionality
3684
- */
3685
- ;
3686
-
3687
- _proto.open = function open(id) {
3688
- var popover = this.get(id);
3689
- if (!popover) return false;
3690
- return popover.open();
3691
- };
3692
-
3693
- _proto.close = function close(id) {
3694
- if (id) {
3695
- var popover = this.get(id);
3696
- if (!popover) return false;
3697
- return popover.close();
3698
- } else {
3699
- return closeAll.call(this);
3700
- }
4695
+ _proto.deregister = function deregister$1(query) {
4696
+ var popover = this.get(getPopoverID.call(this, query));
4697
+ return deregister.call(this, popover);
4698
+ };
4699
+
4700
+ _proto.open = function open$1(id) {
4701
+ return open.call(this, id);
4702
+ };
4703
+
4704
+ _proto.close = function close$1(id) {
4705
+ return close.call(this, id);
3701
4706
  };
3702
4707
 
3703
4708
  return Popover;