vrembem 1.40.2 → 1.42.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.
@@ -34,10 +34,9 @@ const setTabindex = selector => {
34
34
  };
35
35
 
36
36
  /**
37
- * Adds a class or classes to an element or NodeList
38
- * ---
39
- * @param {Node || NodeList} el - Element(s) to add class(es) to
40
- * @param {String || Array} cl - Class(es) to add
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.
41
40
  */
42
41
  const addClass = (el, ...cl) => {
43
42
  el = el.forEach ? el : [el];
@@ -47,10 +46,9 @@ const addClass = (el, ...cl) => {
47
46
  };
48
47
 
49
48
  /**
50
- * Takes a hyphen cased string and converts it to camel case
51
- * ---
52
- * @param {String } str - the string to convert to camel case
53
- * @returns {Boolean} - returns a camel cased string
49
+ * Takes a hyphen cased string and converts it to camel case.
50
+ * @param {String } str - the string to convert to camel case.
51
+ * @returns {Boolean} - returns a camel cased string.
54
52
  */
55
53
  const camelCase = str => {
56
54
  return str.replace(/-([a-z])/g, function (g) {
@@ -169,23 +167,21 @@ class FocusTrap {
169
167
  }
170
168
 
171
169
  /**
172
- * Get an element(s) from a selector or return value if not a string
173
- * ---
174
- * @param {String} selector - Selector to query
175
- * @param {Boolean} single - Whether to return a single or all matches
170
+ * Get an element(s) from a selector or return value if not a string.
171
+ * @param {String} selector - Selector to query.
172
+ * @param {Boolean} single - Whether to return a single or all matches.
176
173
  */
177
174
  const getElement = function getElement(selector, single = 0) {
178
- if (typeof selector != 'string') return selector;
175
+ if (typeof selector !== 'string') return selector;
179
176
  return single ? document.querySelector(selector) : document.querySelectorAll(selector);
180
177
  };
181
178
 
182
179
  /**
183
- * Checks an element or NodeList whether they contain a class or classes
180
+ * Checks an element or NodeList whether they contain a class or classes.
184
181
  * Ref: https://davidwalsh.name/nodelist-array
185
- * ---
186
- * @param {Node} el - Element(s) to check class(es) on
187
- * @param {String || Array} c - Class(es) to check
188
- * @returns {Boolean} - Returns true if class exists, otherwise false
182
+ * @param {Node} el - Element(s) to check class(es) on.
183
+ * @param {String || Array} c - Class(es) to check.
184
+ * @returns {Boolean} - Returns true if class exists, otherwise false.
189
185
  */
190
186
  const hasClass = (el, ...cl) => {
191
187
  el = el.forEach ? el : [el];
@@ -198,10 +194,9 @@ const hasClass = (el, ...cl) => {
198
194
  };
199
195
 
200
196
  /**
201
- * Takes a camel cased string and converts it to hyphen case
202
- * ---
203
- * @param {String } str - the string to convert to hyphen case
204
- * @returns {Boolean} - returns a hyphen cased string
197
+ * Takes a camel cased string and converts it to hyphen case.
198
+ * @param {String } str - the string to convert to hyphen case.
199
+ * @returns {Boolean} - returns a hyphen cased string.
205
200
  */
206
201
  const hyphenCase = str => {
207
202
  return str.replace(/([a-z][A-Z])/g, function (g) {
@@ -210,11 +205,10 @@ const hyphenCase = str => {
210
205
  };
211
206
 
212
207
  /**
213
- * Moves element(s) in the DOM based on a reference and move type
214
- * ---
215
- * @param {String} target - The element(s) to move
216
- * @param {String} type - Move type can be 'after', 'before', 'append' or 'prepend'
217
- * @param {String} reference - The reference element the move is relative to
208
+ * Moves element(s) in the DOM based on a reference and move type.
209
+ * @param {String} target - The element(s) to move.
210
+ * @param {String} type - Move type can be 'after', 'before', 'append' or 'prepend'.
211
+ * @param {String} reference - The reference element the move is relative to.
218
212
  */
219
213
 
220
214
  function moveElement(target, type, reference = false) {
@@ -265,10 +259,9 @@ function moveElement(target, type, reference = false) {
265
259
  }
266
260
 
267
261
  /**
268
- * Remove a class or classes from an element or NodeList
269
- * ---
270
- * @param {Node || NodeList} el - Element(s) to remove class(es) from
271
- * @param {String || Array} cl - Class(es) to remove
262
+ * Remove a class or classes from an element or NodeList.
263
+ * @param {Node || NodeList} el - Element(s) to remove class(es) from.
264
+ * @param {String || Array} cl - Class(es) to remove.
272
265
  */
273
266
  const removeClass = (el, ...cl) => {
274
267
  el = el.forEach ? el : [el];
@@ -278,10 +271,9 @@ const removeClass = (el, ...cl) => {
278
271
  };
279
272
 
280
273
  /**
281
- * Toggle a class or classes on an element or NodeList
282
- * ---
283
- * @param {Node || NodeList} el - Element(s) to toggle class(es) on
284
- * @param {String || Array} cl - Class(es) to toggle
274
+ * Toggle a class or classes on an element or NodeList.
275
+ * @param {Node || NodeList} el - Element(s) to toggle class(es) on.
276
+ * @param {String || Array} cl - Class(es) to toggle.
285
277
  */
286
278
  const toggleClass = (el, ...cl) => {
287
279
  el = el.forEach ? el : [el];
@@ -367,13 +359,15 @@ function _extends() {
367
359
  return _extends.apply(this, arguments);
368
360
  }
369
361
 
362
+ var defaults$3 = {
363
+ autoInit: false,
364
+ stateAttr: 'aria-checked',
365
+ stateValue: 'mixed'
366
+ };
367
+
370
368
  class Checkbox {
371
369
  constructor(options) {
372
- this.defaults = {
373
- autoInit: false,
374
- stateAttr: 'aria-checked',
375
- stateValue: 'mixed'
376
- };
370
+ this.defaults = defaults$3;
377
371
  this.settings = _extends({}, this.defaults, options);
378
372
  this.__handlerClick = this.handlerClick.bind(this);
379
373
  if (this.settings.autoInit) this.init();
@@ -467,12 +461,21 @@ class Breakpoint {
467
461
  init() {
468
462
  const drawers = document.querySelectorAll(`[data-${this.parent.settings.dataBreakpoint}]`);
469
463
  drawers.forEach(drawer => {
464
+ // Setup mediaQueryList object
470
465
  const id = drawer.getAttribute(`data-${this.parent.settings.dataDrawer}`);
471
466
  const key = drawer.getAttribute(`data-${this.parent.settings.dataBreakpoint}`);
472
467
  const bp = this.getBreakpoint(key);
473
- const mql = window.matchMedia('(min-width:' + bp + ')');
474
- this.match(mql, drawer);
475
- mql.addEventListener('change', this.__check);
468
+ const mql = window.matchMedia('(min-width:' + bp + ')'); // Run match check
469
+
470
+ this.match(mql, drawer); // Conditionally use addListner() for IE11 support
471
+
472
+ if (typeof mql.addEventListener === 'function') {
473
+ mql.addEventListener('change', this.__check);
474
+ } else {
475
+ mql.addListener(this.__check);
476
+ } // Push to mediaQueryLists array along with drawer ID
477
+
478
+
476
479
  this.mediaQueryLists.push({
477
480
  'mql': mql,
478
481
  'drawer': id
@@ -1108,39 +1111,87 @@ class Modal {
1108
1111
 
1109
1112
  }
1110
1113
 
1114
+ class Collection {
1115
+ constructor() {
1116
+ this.collection = [];
1117
+ }
1118
+
1119
+ register(item) {
1120
+ this.deregister(item);
1121
+ this.collection.push(item);
1122
+ return this.collection;
1123
+ }
1124
+
1125
+ deregister(ref) {
1126
+ const index = this.collection.findIndex(entry => {
1127
+ return entry === ref;
1128
+ });
1129
+
1130
+ if (index >= 0) {
1131
+ const entry = this.collection[index];
1132
+ Object.getOwnPropertyNames(entry).forEach(prop => {
1133
+ delete entry[prop];
1134
+ });
1135
+ this.collection.splice(index, 1);
1136
+ }
1137
+
1138
+ return this.collection;
1139
+ }
1140
+
1141
+ registerCollection(items) {
1142
+ items.forEach(item => {
1143
+ this.register(item);
1144
+ });
1145
+ return this.collection;
1146
+ }
1147
+
1148
+ deregisterCollection() {
1149
+ while (this.collection.length > 0) {
1150
+ this.deregister(this.collection[0]);
1151
+ }
1152
+
1153
+ return this.collection;
1154
+ }
1155
+
1156
+ get(query, key = 'id') {
1157
+ const result = this.collection.find(item => {
1158
+ return item[key] === query;
1159
+ });
1160
+ return result || null;
1161
+ }
1162
+
1163
+ }
1164
+
1111
1165
  var defaults = {
1112
1166
  autoInit: false,
1113
- // Data attributes
1114
- dataPopover: 'popover',
1115
- dataTrigger: 'popover-trigger',
1116
- dataArrow: 'popover-arrow',
1117
- dataEventType: 'popover-event',
1118
- dataPlacement: 'popover-placement',
1167
+ // Selectors
1168
+ selectorPopover: '.popover',
1169
+ selectorArrow: '.popover__arrow',
1119
1170
  // State classes
1120
1171
  stateActive: 'is-active',
1121
1172
  // Feature toggles
1122
- eventType: 'click',
1123
1173
  eventListeners: true,
1124
- placement: 'bottom-start'
1174
+ eventType: 'click',
1175
+ placement: 'bottom'
1125
1176
  };
1126
1177
 
1127
1178
  function close(popover) {
1128
1179
  // Update state class
1129
1180
  popover.target.classList.remove(this.settings.stateActive); // Update a11y attributes
1130
1181
 
1131
- popover.trigger.setAttribute('aria-expanded', 'false'); // Disable popper event listeners
1182
+ if (popover.trigger.hasAttribute('aria-controls')) {
1183
+ popover.trigger.setAttribute('aria-expanded', 'false');
1184
+ } // Disable popper event listeners
1185
+
1132
1186
 
1133
1187
  popover.popper.setOptions({
1134
1188
  modifiers: [{
1135
1189
  name: 'eventListeners',
1136
1190
  enabled: false
1137
1191
  }]
1138
- }); // Update collection status with new state
1192
+ }); // Update popover state
1139
1193
 
1140
- const index = this.collection.findIndex(item => {
1141
- return item.target === popover.target;
1142
- });
1143
- this.collection[index].state = 'closed'; // Clear the memory if popover trigger matches the ones saved in memory
1194
+ popover.state = 'closed'; // Clear memory if popover trigger matches the one saved in memory
1144
1195
 
1145
1196
  if (popover.trigger === this.memory.trigger) {
1146
1197
  this.memory.trigger = null;
@@ -1152,7 +1203,7 @@ function close(popover) {
1152
1203
  function closeAll() {
1153
1204
  this.collection.forEach(popover => {
1154
1205
  if (popover.state === 'opened') {
1155
- this.close(popover);
1206
+ popover.close();
1156
1207
  }
1157
1208
  }); // Return the collection
1158
1209
 
@@ -1166,10 +1217,10 @@ function closeCheck(popover) {
1166
1217
  // Check if trigger or target are being hovered
1167
1218
  const isHovered = popover.target.closest(':hover') === popover.target || popover.trigger.closest(':hover') === popover.trigger; // Check if trigger or target are being focused
1168
1219
 
1169
- const isFocused = document.activeElement.closest(`[data-${this.settings.dataPopover}]`) === popover.target || document.activeElement.closest(`[data-${this.settings.dataTrigger}]`) === popover.trigger; // Close if the trigger and target are not currently hovered or focused
1220
+ const isFocused = document.activeElement.closest(`#${popover.id}, [aria-controls="${popover.id}"]`); // Close if the trigger and target are not currently hovered or focused
1170
1221
 
1171
1222
  if (!isHovered && !isFocused) {
1172
- this.close(popover);
1223
+ popover.close();
1173
1224
  } // Return the popover
1174
1225
 
1175
1226
 
@@ -1179,10 +1230,10 @@ function closeCheck(popover) {
1179
1230
 
1180
1231
  function handlerClick(popover) {
1181
1232
  if (popover.target.classList.contains(this.settings.stateActive)) {
1182
- this.close(popover);
1233
+ popover.close();
1183
1234
  } else {
1184
1235
  this.memory.trigger = popover.trigger;
1185
- this.open(popover);
1236
+ popover.open();
1186
1237
  documentClick.call(this, popover);
1187
1238
  }
1188
1239
  }
@@ -1193,7 +1244,7 @@ function handlerKeydown(event) {
1193
1244
  this.memory.trigger.focus();
1194
1245
  }
1195
1246
 
1196
- this.closeAll();
1247
+ closeAll.call(this);
1197
1248
  return;
1198
1249
 
1199
1250
  case 'Tab':
@@ -1207,19 +1258,21 @@ function handlerKeydown(event) {
1207
1258
  }
1208
1259
  }
1209
1260
  function documentClick(popover) {
1210
- const obj = this;
1261
+ const root = this;
1211
1262
  document.addEventListener('click', function _f(event) {
1212
- const result = event.target.closest(`[data-${obj.settings.dataPopover}], [data-${obj.settings.dataTrigger}]`);
1213
- const match = result === popover.target || result === popover.trigger;
1263
+ // Check if a popover was clicked
1264
+ const result = event.target.closest(`#${popover.id}, [aria-controls="${popover.id}"]`);
1214
1265
 
1215
- if (!match) {
1216
- if (popover.target.classList.contains(obj.settings.stateActive)) {
1217
- obj.close(popover);
1266
+ if (!result) {
1267
+ // If it doesn't match and popover is open, close it and remove event listener
1268
+ if (popover.target && popover.target.classList.contains(root.settings.stateActive)) {
1269
+ popover.close();
1218
1270
  }
1219
1271
 
1220
1272
  this.removeEventListener('click', _f);
1221
1273
  } else {
1222
- if (!popover.target.classList.contains(obj.settings.stateActive)) {
1274
+ // If it does match and popover isn't currently active, remove event listener
1275
+ if (popover.target && !popover.target.classList.contains(root.settings.stateActive)) {
1223
1276
  this.removeEventListener('click', _f);
1224
1277
  }
1225
1278
  }
@@ -1236,26 +1289,23 @@ function getConfig(el, settings) {
1236
1289
  'offset': 0,
1237
1290
  'overflow-padding': 0,
1238
1291
  'flip-padding': 0,
1239
- 'arrow-element': `[data-${settings.dataArrow}]`,
1292
+ 'arrow-element': settings.selectorArrow,
1240
1293
  'arrow-padding': 0
1241
1294
  }; // Loop through config obj
1242
1295
 
1243
1296
  for (const prop in config) {
1244
1297
  // Get the CSS variable property values
1245
1298
  const prefix = getComputedStyle(document.body).getPropertyValue('--vrembem-variable-prefix');
1246
- const val = styles.getPropertyValue(`--${prefix}popover-${prop}`).trim(); // If a value was found, replace the default in config obj
1299
+ const value = styles.getPropertyValue(`--${prefix}popover-${prop}`).trim(); // If a value was found, replace the default in config obj
1247
1300
 
1248
- if (val) {
1249
- config[prop] = val;
1301
+ if (value) {
1302
+ config[prop] = value;
1250
1303
  }
1251
1304
  } // Return the config obj
1252
1305
 
1253
1306
 
1254
1307
  return config;
1255
1308
  }
1256
- function getData(el, attr, fallback = false) {
1257
- return el.hasAttribute(`data-${attr}`) ? el.getAttribute(`data-${attr}`) : fallback;
1258
- }
1259
1309
  function getPadding(value) {
1260
1310
  let padding; // Split the value by spaces if it's a string
1261
1311
 
@@ -1329,49 +1379,58 @@ function getModifiers(options) {
1329
1379
  }
1330
1380
  }];
1331
1381
  }
1332
- function getPopover(trigger, settings) {
1333
- // Get the value of the popover trigger attribute
1334
- const id = trigger.getAttribute(`data-${settings.dataTrigger}`).trim();
1382
+ function getPopoverID(obj) {
1383
+ // If it's a string
1384
+ if (typeof obj === 'string') {
1385
+ return obj;
1386
+ } // If it's an HTML element
1387
+ else if (typeof obj.hasAttribute === 'function') {
1388
+ // If it's a popover trigger
1389
+ if (obj.hasAttribute('aria-controls')) {
1390
+ return obj.getAttribute('aria-controls');
1391
+ } // If it's a popover tooltip trigger
1392
+ else if (obj.hasAttribute('aria-describedby')) {
1393
+ return obj.getAttribute('aria-describedby');
1394
+ } // If it's a popover target
1395
+ else if (obj.closest(this.settings.selectorPopover)) {
1396
+ return obj.id;
1397
+ } // Return false if no id was found
1398
+ else return false;
1399
+ } // If it has an ID property
1400
+ else if (obj.id) {
1401
+ return obj.id;
1402
+ } // Return false if no id was found
1403
+ else return false;
1404
+ }
1405
+ function getPopoverElements(query) {
1406
+ const id = getPopoverID.call(this, query);
1335
1407
 
1336
1408
  if (id) {
1337
- // If trigger attribute value exists, return the querySelector element using
1338
- // the provided popover trigger attribute's value
1339
- return document.querySelector(`[data-${settings.dataPopover}="${id}"]`);
1409
+ const trigger = document.querySelector(`[aria-controls="${id}"]`) || document.querySelector(`[aria-describedby="${id}"]`);
1410
+ const target = document.querySelector(`#${id}`);
1411
+
1412
+ if (!trigger && !target) {
1413
+ console.error('No popover elements found using the provided ID:', id);
1414
+ } else if (!trigger) {
1415
+ console.error('No popover trigger associated with the provided popover:', target);
1416
+ } else if (!target) {
1417
+ console.error('No popover associated with the provided popover trigger:', trigger);
1418
+ }
1419
+
1420
+ if (!trigger || !target) {
1421
+ return false;
1422
+ } else {
1423
+ return {
1424
+ trigger,
1425
+ target
1426
+ };
1427
+ }
1340
1428
  } else {
1341
- // If trigger attribute value doesn't exist, check if
1342
- // - There is a nextElementSibling relative to the trigger
1343
- // - And it has the popover data attribute.
1344
- return trigger.nextElementSibling && trigger.nextElementSibling.hasAttribute(`data-${settings.dataPopover}`) ? // Return the element or false if the two checks fail
1345
- trigger.nextElementSibling : false;
1429
+ console.error('Could not resolve the popover ID:', query);
1430
+ return false;
1346
1431
  }
1347
1432
  }
1348
1433
 
1349
- function open(popover) {
1350
- // Update state class
1351
- popover.target.classList.add(this.settings.stateActive); // Update a11y attributes
1352
-
1353
- popover.trigger.setAttribute('aria-expanded', 'true'); // Update popover config
1354
-
1355
- popover.config = getConfig(popover.target, this.settings); // Enable popper event listeners and set placement/modifiers
1356
-
1357
- popover.popper.setOptions({
1358
- placement: getData(popover.target, this.settings.dataPlacement, popover.config['placement']),
1359
- modifiers: [{
1360
- name: 'eventListeners',
1361
- enabled: true
1362
- }, ...getModifiers(popover.config)]
1363
- }); // Update popover's position
1364
-
1365
- popover.popper.update(); // Update collection status with new state
1366
-
1367
- const index = this.collection.findIndex(item => {
1368
- return item.target === popover.target;
1369
- });
1370
- this.collection[index].state = 'opened'; // Return the popover
1371
-
1372
- return popover;
1373
- }
1374
-
1375
1434
  var top = 'top';
1376
1435
  var bottom = 'bottom';
1377
1436
  var right = 'right';
@@ -3155,72 +3214,100 @@ var createPopper = /*#__PURE__*/popperGenerator({
3155
3214
  defaultModifiers: defaultModifiers
3156
3215
  }); // eslint-disable-next-line import/no-unused-modules
3157
3216
 
3158
- function register(trigger, target) {
3159
- // If no target is passed
3160
- if (!target) {
3161
- // Try and get the target
3162
- target = getPopover(trigger, this.settings); // If still no target is returned, log an error and return false
3217
+ function open(popover) {
3218
+ // Update state class
3219
+ popover.target.classList.add(this.settings.stateActive); // Update a11y attribute
3163
3220
 
3164
- if (!target) {
3165
- console.error('No popover associated with the provided trigger:', trigger);
3166
- return false;
3167
- }
3168
- } // Check if this item has already been registered in the collection
3221
+ if (popover.trigger.hasAttribute('aria-controls')) {
3222
+ popover.trigger.setAttribute('aria-expanded', 'true');
3223
+ } // Update popover config
3224
+
3225
+
3226
+ popover.config = getConfig(popover.target, this.settings); // Enable popper event listeners and set placement/modifiers
3169
3227
 
3228
+ popover.popper.setOptions({
3229
+ placement: popover.config['placement'],
3230
+ modifiers: [{
3231
+ name: 'eventListeners',
3232
+ enabled: true
3233
+ }, ...getModifiers(popover.config)]
3234
+ }); // Update popover position
3170
3235
 
3171
- const index = this.collection.findIndex(item => {
3172
- return item.trigger === trigger && item.target === target;
3173
- }); // Initiate popover variable
3236
+ popover.popper.update(); // Update popover state
3174
3237
 
3175
- let popover; // Check if it already exists in collection
3238
+ popover.state = 'opened'; // Return the popover
3176
3239
 
3177
- if (index >= 0) {
3178
- // Set popover as item from collection
3179
- popover = this.collection[index];
3180
- } else {
3181
- // Create popper instance
3182
- const popperInstance = createPopper(trigger, target); // Build popover object and push to collection array
3240
+ return popover;
3241
+ }
3183
3242
 
3184
- popover = {
3185
- state: 'closed',
3186
- trigger: trigger,
3187
- target: target,
3188
- popper: popperInstance,
3189
- config: getConfig(target, this.settings)
3190
- }; // Add item to collection
3243
+ function register(trigger, target) {
3244
+ // Deregister popover if it already exists in the collection
3245
+ this.deregister(target.id); // Create popper instance
3191
3246
 
3192
- this.collection.push(popover);
3193
- } // Setup event listeners
3247
+ const popperInstance = createPopper(trigger, target); // Save root this for use inside object & create methods API
3248
+
3249
+ const root = this;
3250
+ const methods = {
3251
+ open() {
3252
+ open.call(root, this);
3253
+ },
3254
+
3255
+ close() {
3256
+ close.call(root, this);
3257
+ },
3258
+
3259
+ deregister() {
3260
+ deregister.call(root, this);
3261
+ }
3262
+
3263
+ }; // Build popover object and push to collection array
3264
+
3265
+ const popover = _extends({
3266
+ id: target.id,
3267
+ state: 'closed',
3268
+ trigger: trigger,
3269
+ target: target,
3270
+ popper: popperInstance,
3271
+ config: getConfig(target, this.settings)
3272
+ }, methods); // Setup event listeners
3194
3273
 
3195
3274
 
3196
3275
  registerEventListeners.call(this, popover); // Set initial state of popover
3197
3276
 
3198
3277
  if (popover.target.classList.contains(this.settings.stateActive)) {
3199
- this.open(popover);
3278
+ popover.open();
3200
3279
  documentClick.call(this, popover);
3201
3280
  } else {
3202
- this.close(popover);
3203
- } // Return the popover object
3281
+ popover.close();
3282
+ } // Add item to collection
3283
+
3204
3284
 
3285
+ this.collection.push(popover); // Return the popover object
3205
3286
 
3206
3287
  return popover;
3207
3288
  }
3208
3289
  function deregister(popover) {
3209
3290
  // Check if this item has been registered in the collection
3210
- const index = this.collection.findIndex(item => {
3211
- return item.trigger === popover.trigger && item.target === popover.target;
3212
- }); // If the item exists in the collection
3291
+ const index = this.collection.findIndex(entry => {
3292
+ return entry.id === popover.id;
3293
+ }); // If the entry exists in the collection
3213
3294
 
3214
3295
  if (index >= 0) {
3215
- // Close the popover
3216
- if (popover.state === 'opened') {
3217
- this.close(popover);
3296
+ // Get the collection entry
3297
+ const entry = this.collection[index]; // Close the collection entry if it's open
3298
+
3299
+ if (entry.state === 'opened') {
3300
+ entry.close();
3218
3301
  } // Clean up the popper instance
3219
3302
 
3220
3303
 
3221
- popover.popper.destroy(); // Remove event listeners
3304
+ entry.popper.destroy(); // Remove event listeners
3222
3305
 
3223
- deregisterEventListeners(popover); // Remove item from collection
3306
+ deregisterEventListeners(entry); // Delete properties from collection entry
3307
+
3308
+ Object.getOwnPropertyNames(entry).forEach(prop => {
3309
+ delete entry[prop];
3310
+ }); // Remove entry from collection
3224
3311
 
3225
3312
  this.collection.splice(index, 1);
3226
3313
  } // Return the new collection
@@ -3232,7 +3319,7 @@ function registerEventListeners(popover) {
3232
3319
  // If event listeners aren't already setup
3233
3320
  if (!popover.__eventListeners) {
3234
3321
  // Add event listeners based on event type
3235
- const eventType = getData(popover.target, this.settings.dataEventType, popover.config['event']);
3322
+ const eventType = popover.config['event'];
3236
3323
 
3237
3324
  if (eventType === 'hover') {
3238
3325
  // Setup event listeners object for hover
@@ -3293,31 +3380,13 @@ function deregisterEventListeners(popover) {
3293
3380
 
3294
3381
  return popover;
3295
3382
  }
3296
- function registerCollection() {
3297
- // Get all the triggers
3298
- const triggers = document.querySelectorAll(`[data-${this.settings.dataTrigger}]`);
3299
- triggers.forEach(trigger => {
3300
- // Register the popover and save to collection array
3301
- this.register(trigger, false);
3302
- }); // Return the popover collection
3303
-
3304
- return this.collection;
3305
- }
3306
- function deregisterCollection() {
3307
- // Loop through all items within the collection and pass them to deregister()
3308
- while (this.collection.length > 0) {
3309
- this.deregister(this.collection[0]);
3310
- } // Return the popover collection
3311
3383
 
3312
-
3313
- return this.collection;
3314
- }
3315
-
3316
- class Popover {
3384
+ class Popover extends Collection {
3317
3385
  constructor(options) {
3386
+ super();
3318
3387
  this.defaults = defaults;
3319
- this.settings = _extends({}, this.defaults, options);
3320
- this.collection = [];
3388
+ this.settings = _extends({}, this.defaults, options); // this.collection = [];
3389
+
3321
3390
  this.memory = {
3322
3391
  trigger: null
3323
3392
  };
@@ -3327,9 +3396,11 @@ class Popover {
3327
3396
 
3328
3397
  init(options = null) {
3329
3398
  // Update settings with passed options
3330
- if (options) this.settings = _extends({}, this.settings, options); // Build the collections array with popover instances
3399
+ if (options) this.settings = _extends({}, this.settings, options); // Get all the popovers
3331
3400
 
3332
- this.registerCollection(); // If eventListeners is enabled
3401
+ const popovers = document.querySelectorAll(this.settings.selectorPopover); // Build the collections array with popover instances
3402
+
3403
+ this.registerCollection(popovers); // If eventListeners is enabled
3333
3404
 
3334
3405
  if (this.settings.eventListeners) {
3335
3406
  // Pass false to initEventListeners() since registerCollection()
@@ -3381,36 +3452,36 @@ class Popover {
3381
3452
  */
3382
3453
 
3383
3454
 
3384
- register(trigger, target = false) {
3385
- return register.call(this, trigger, target);
3455
+ register(query) {
3456
+ const els = getPopoverElements.call(this, query);
3457
+ if (!els) return false;
3458
+ return register.call(this, els.trigger, els.target);
3386
3459
  }
3387
3460
 
3388
- deregister(popover) {
3461
+ deregister(query) {
3462
+ const popover = this.get(getPopoverID(query));
3463
+ if (!popover) return false;
3389
3464
  return deregister.call(this, popover);
3390
3465
  }
3391
-
3392
- registerCollection() {
3393
- return registerCollection.call(this);
3394
- }
3395
-
3396
- deregisterCollection() {
3397
- return deregisterCollection.call(this);
3398
- }
3399
3466
  /**
3400
3467
  * Change state functionality
3401
3468
  */
3402
3469
 
3403
3470
 
3404
- open(popover) {
3405
- return open.call(this, popover);
3471
+ open(id) {
3472
+ const popover = this.get(id);
3473
+ if (!popover) return false;
3474
+ return popover.open();
3406
3475
  }
3407
3476
 
3408
- close(popover) {
3409
- return close.call(this, popover);
3410
- }
3411
-
3412
- closeAll() {
3413
- return closeAll.call(this);
3477
+ close(id) {
3478
+ if (id) {
3479
+ const popover = this.get(id);
3480
+ if (!popover) return false;
3481
+ return popover.close();
3482
+ } else {
3483
+ return closeAll.call(this);
3484
+ }
3414
3485
  }
3415
3486
 
3416
3487
  }