@danielgindi/selectbox 1.0.29 → 1.0.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/DropList.js CHANGED
@@ -13,10 +13,10 @@ import {
13
13
  getElementWidth,
14
14
  setElementHeight,
15
15
  setElementWidth, getElementOffset, anchoredPosition,
16
+ parseTransition,
16
17
  } from '@danielgindi/dom-utils/lib/Css';
17
18
  import DomEventsSink from '@danielgindi/dom-utils/lib/DomEventsSink';
18
19
  import VirtualListHelper from '@danielgindi/virtual-list-helper';
19
- import parseCssTransition from 'parse-css-transition';
20
20
  import {
21
21
  VALUE_DOWN,
22
22
  VALUE_END,
@@ -27,6 +27,7 @@ import {
27
27
  VALUE_SPACE,
28
28
  VALUE_UP,
29
29
  } from 'keycode-js';
30
+ import mitt from 'mitt';
30
31
 
31
32
  const ItemSymbol = Symbol('item');
32
33
  const DestroyedSymbol = Symbol('destroyed');
@@ -122,7 +123,7 @@ let defaultOptions = {
122
123
  Emits the following events:
123
124
  ---------------------------
124
125
 
125
- 'itemfocus' {value, item}: item gained focus.
126
+ 'itemfocus' {value, item, event}: item gained focus.
126
127
  'itemblur' {value, item}: item lost focus.
127
128
  'select' {value, item}: item was selected (in single mode).
128
129
  'show:before': the drop list will show.
@@ -167,7 +168,9 @@ class DropList {
167
168
  valueProp: o.valueProp,
168
169
  renderItem: o.renderItem,
169
170
  unrenderItem: o.unrenderItem,
170
- on: o.on,
171
+ on: o.on || null,
172
+ silenceEvents: true,
173
+ mitt: mitt(),
171
174
 
172
175
  focusItemIndex: -1,
173
176
  focusItemEl: null,
@@ -306,6 +309,8 @@ class DropList {
306
309
  this._hookTouchEvents();
307
310
  this._hookFocusEvents();
308
311
  this._hookKeyEvents();
312
+
313
+ this.silenceEvents = false;
309
314
  }
310
315
 
311
316
  destroy() {
@@ -1130,7 +1135,7 @@ class DropList {
1130
1135
  el.classList.add(`${p.baseClassName}__is-hiding`);
1131
1136
 
1132
1137
  // support for hide transition in css
1133
- const maxTransitionDuration = parseCssTransition(getComputedStyle(p.el).transition)
1138
+ const maxTransitionDuration = parseTransition(getComputedStyle(p.el).transition)
1134
1139
  .reduce((p, v) => Math.max(p, v.delay + v.duration), 0);
1135
1140
 
1136
1141
  if (maxTransitionDuration > 0) {
@@ -1212,7 +1217,7 @@ class DropList {
1212
1217
  itemElement.classList.add(`${p.baseClassName}__item_focus`);
1213
1218
  p.focusItemEl = itemElement;
1214
1219
 
1215
- this._trigger('itemfocus', { value: itemElement[p.valueProp], item: itemElement[ItemSymbol] });
1220
+ this._trigger('itemfocus', { value: itemElement[p.valueProp], item: itemElement[ItemSymbol], event: null });
1216
1221
  }
1217
1222
  }
1218
1223
 
@@ -1316,6 +1321,58 @@ class DropList {
1316
1321
  return this;
1317
1322
  }
1318
1323
 
1324
+ /**
1325
+ * Register an event handler
1326
+ * @param {(string|'*')?} event
1327
+ * @param {function(any)} handler
1328
+ * @returns {DropList}
1329
+ */
1330
+ on(/**string|'*'*/event, /**Function?*/handler) {
1331
+ this._p.mitt.on(event, handler);
1332
+ return this;
1333
+ }
1334
+
1335
+ /**
1336
+ * Register a one time event handler
1337
+ * @param {(string|'*')?} event
1338
+ * @param {function(any)} handler
1339
+ * @returns {DropList}
1340
+ */
1341
+ once(/**string|'*'*/event, /**Function?*/handler) {
1342
+ let wrapped = (value) => {
1343
+ this._p.mitt.off(event, wrapped);
1344
+ handler(value);
1345
+ };
1346
+ this._p.mitt.on(event, wrapped);
1347
+ return this;
1348
+ }
1349
+
1350
+ /**
1351
+ * Remove an `handler` for `event`, all events for `event`, or all events completely.
1352
+ * @param {(string|'*')?} event
1353
+ * @param {function(any)} handler
1354
+ * @returns {DropList}
1355
+ */
1356
+ off(/**(string|'*')?*/event, /**Function?*/handler) {
1357
+ if (!event && !event) {
1358
+ this._p.mitt.all.clear();
1359
+ } else {
1360
+ this._p.mitt.off(event, handler);
1361
+ }
1362
+ return this;
1363
+ }
1364
+
1365
+ /**
1366
+ * Emit an event
1367
+ * @param {string} event
1368
+ * @param {any} value
1369
+ * @returns {DropList}
1370
+ */
1371
+ emit(/**string|'*'*/event, /**any?*/value) {
1372
+ this._p.mitt.emit(event, value);
1373
+ return this;
1374
+ }
1375
+
1319
1376
  _getItemIndex(item) {
1320
1377
  const p = this._p, labelProp = p.labelProp, valueProp = p.valueProp;
1321
1378
 
@@ -1358,6 +1415,7 @@ class DropList {
1358
1415
  const p = this._p;
1359
1416
  if (p.on)
1360
1417
  p.on(event, ...(data === undefined ? [] : [data]));
1418
+ p.mitt.emit(event, data);
1361
1419
  }
1362
1420
 
1363
1421
  _itemUpAction(event, itemEl) {
@@ -1661,7 +1719,7 @@ class DropList {
1661
1719
  p.focusItemIndex = itemIndex;
1662
1720
 
1663
1721
  const item = p.items[itemIndex];
1664
- this._trigger('itemfocus', { value: item[p.valueProp], item: item });
1722
+ this._trigger('itemfocus', { value: item[p.valueProp], item: item, event: event });
1665
1723
  }
1666
1724
  } else {
1667
1725
  // This could happen if trying to focus a grouped item
package/lib/SelectBox.js CHANGED
@@ -34,6 +34,7 @@ import {
34
34
  VALUE_TAB,
35
35
  VALUE_UP,
36
36
  } from 'keycode-js';
37
+ import mitt from 'mitt';
37
38
 
38
39
  const ItemSymbol = Symbol('item');
39
40
  const DestroyedSymbol = Symbol('destroyed');
@@ -100,7 +101,9 @@ const inputBackbufferCssProps = [
100
101
  * @property {string} [multiItemLabelProp='short_label']
101
102
  * @property {number} [maxMultiItems] maximum number of multi items. The rest will get a single item to represent.
102
103
  * @property {function(count: number, items: DropList.ItemBase[]):string} [multiItemsRestLabelProvider] label for the item representing the rest of the items.
103
- * @property {DropList.ItemBase[]|null} [items]
104
+ * @property {DropList.ItemBase[]|null} [items] initial items
105
+ * @property {*[]|null} [selectedValues] initial selected values
106
+ * @property {*|*[]|null} [value] initial selected value
104
107
  * @property {function(item: DropList.ItemBase, itemEl: Element):(*|false)} [renderSingleItem]
105
108
  * @property {function(item: DropList.ItemBase, itemEl: Element)} [unrenderSingleItem]
106
109
  * @property {function(item: DropList.ItemBase, itemEl: Element):(*|false)} [renderMultiItem]
@@ -112,6 +115,7 @@ const inputBackbufferCssProps = [
112
115
  * @property {function(items: DropList.ItemBase[], term: string):(DropList.ItemBase[]|null)} [filterFn]
113
116
  * @property {function(name: string, ...args)} [on]
114
117
  * @property {string|string[]} [additionalClasses]
118
+ * @property {boolean} [isLoadingMode]
115
119
  * */
116
120
  const defaultOptions = {
117
121
  el: null,
@@ -140,6 +144,9 @@ const defaultOptions = {
140
144
  maxMultiItems: null,
141
145
  multiItemsRestLabelProvider: null,
142
146
  items: [],
147
+ selectedValues: undefined,
148
+ value: undefined,
149
+ isLoadingMode: false,
143
150
  };
144
151
 
145
152
  /**
@@ -237,12 +244,14 @@ class SelectBox {
237
244
  renderNoResultsItem: o.renderNoResultsItem,
238
245
  unrenderNoResultsItem: o.unrenderNoResultsItem,
239
246
  filterFn: o.filterFn,
240
- on: o.on,
247
+ on: o.on || null,
248
+ silenceEvents: true,
249
+ mitt: mitt(),
241
250
  additionalClasses: o.additionalClasses,
242
251
 
243
- isLoadingMode: false,
252
+ isLoadingMode: !!o.isLoadingMode,
244
253
 
245
- items: o.items || [],
254
+ items: [],
246
255
  filteredItems: null,
247
256
  itemsChanged: true,
248
257
 
@@ -336,10 +345,18 @@ class SelectBox {
336
345
  p.sink.add(window, 'resize', () => this._resizeInput());
337
346
  p.sink.add(window, 'orientationchange', () => this._resizeInput());
338
347
 
339
- this.setItems(p.items);
348
+ this.setItems(o.items);
349
+
350
+ if (o.multi && Array.isArray(o.selectedValues)) {
351
+ this.setSelectedValues(o.selectedValues);
352
+ } else if (o.value != null) {
353
+ this.setValue(o.value);
354
+ }
340
355
 
341
356
  this._scheduleSync();
342
357
 
358
+ this.silenceEvents = false;
359
+
343
360
  return this;
344
361
  }
345
362
 
@@ -1304,13 +1321,22 @@ class SelectBox {
1304
1321
  * @returns {SelectBox}
1305
1322
  */
1306
1323
  toggleLoading(on) {
1324
+ return this.setIsLoadingMode(on === undefined ? !this.getIsLoadingMode() : !!on);
1325
+ }
1326
+
1327
+ /**
1328
+ * @param {boolean} isLoadingMode
1329
+ * @returns {SelectBox}
1330
+ */
1331
+ setIsLoadingMode(isLoadingMode) {
1307
1332
  const p = this._p;
1308
- let loading = on === undefined ? !this._p.isLoadingMode : !!on;
1309
1333
 
1310
- if (p.isLoadingMode === loading)
1334
+ isLoadingMode = isLoadingMode === undefined ? true : !!isLoadingMode;
1335
+
1336
+ if (p.isLoadingMode === isLoadingMode)
1311
1337
  return this;
1312
1338
 
1313
- p.isLoadingMode = loading;
1339
+ p.isLoadingMode = isLoadingMode;
1314
1340
 
1315
1341
  if (p.isLoadingMode && p.items.length === 0 && this.isListOpen()) {
1316
1342
  this.closeList();
@@ -1324,6 +1350,12 @@ class SelectBox {
1324
1350
  return this;
1325
1351
  }
1326
1352
 
1353
+ /**
1354
+ * @returns {boolean}
1355
+ */
1356
+ getIsLoadingMode() {
1357
+ return this._p.isLoadingMode;
1358
+ }
1327
1359
 
1328
1360
  /**
1329
1361
  * Can be called in case that the selectbox was attached to the dom late and has a weird size.
@@ -1334,6 +1366,58 @@ class SelectBox {
1334
1366
  return this;
1335
1367
  }
1336
1368
 
1369
+ /**
1370
+ * Register an event handler
1371
+ * @param {(string|'*')?} event
1372
+ * @param {function(any)} handler
1373
+ * @returns {SelectBox}
1374
+ */
1375
+ on(/**string|'*'*/event, /**Function?*/handler) {
1376
+ this._p.mitt.on(event, handler);
1377
+ return this;
1378
+ }
1379
+
1380
+ /**
1381
+ * Register a one time event handler
1382
+ * @param {(string|'*')?} event
1383
+ * @param {function(any)} handler
1384
+ * @returns {SelectBox}
1385
+ */
1386
+ once(/**string|'*'*/event, /**Function?*/handler) {
1387
+ let wrapped = (value) => {
1388
+ this._p.mitt.off(event, wrapped);
1389
+ handler(value);
1390
+ };
1391
+ this._p.mitt.on(event, wrapped);
1392
+ return this;
1393
+ }
1394
+
1395
+ /**
1396
+ * Remove an `handler` for `event`, all events for `event`, or all events completely.
1397
+ * @param {(string|'*')?} event
1398
+ * @param {function(any)} handler
1399
+ * @returns {SelectBox}
1400
+ */
1401
+ off(/**(string|'*')?*/event, /**Function?*/handler) {
1402
+ if (!event && !event) {
1403
+ this._p.mitt.all.clear();
1404
+ } else {
1405
+ this._p.mitt.off(event, handler);
1406
+ }
1407
+ return this;
1408
+ }
1409
+
1410
+ /**
1411
+ * Emit an event
1412
+ * @param {string} event
1413
+ * @param {any} value
1414
+ * @returns {SelectBox}
1415
+ */
1416
+ emit(/**string|'*'*/event, /**any?*/value) {
1417
+ this._p.mitt.emit(event, value);
1418
+ return this;
1419
+ }
1420
+
1337
1421
  /** @private */
1338
1422
  _renderBase() {
1339
1423
  const p = this._p;
@@ -2508,6 +2592,7 @@ class SelectBox {
2508
2592
  const p = this._p;
2509
2593
  if (p.on)
2510
2594
  p.on(event, ...(data === undefined ? [] : [data]));
2595
+ p.mitt.emit(event, data);
2511
2596
  }
2512
2597
 
2513
2598
  /**
@@ -3058,6 +3143,10 @@ class SelectBox {
3058
3143
 
3059
3144
  if (group === stickyGroup) {
3060
3145
  checkedGroups.push(stickyGroup);
3146
+ let sgi = uncheckedGroups.indexOf(stickyGroup);
3147
+ if (sgi !== -1) {
3148
+ uncheckedGroups.splice(sgi, 1);
3149
+ }
3061
3150
  continue;
3062
3151
  }
3063
3152
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danielgindi/selectbox",
3
- "version": "1.0.29",
3
+ "version": "1.0.33",
4
4
  "description": "A collection of dom utilities. So you can work natively with the dom without dom frameworks.",
5
5
  "main": "dist/lib.cjs.min.js",
6
6
  "module": "lib/index.js",
@@ -31,26 +31,26 @@
31
31
  "homepage": "https://github.com/danielgindi/selectbox#readme",
32
32
  "license": "MIT",
33
33
  "devDependencies": {
34
- "@babel/core": "^7.14.8",
35
- "@babel/preset-env": "^7.14.9",
36
- "@babel/runtime": "^7.14.8",
34
+ "@babel/core": "^7.15.8",
35
+ "@babel/preset-env": "^7.15.8",
36
+ "@babel/runtime": "^7.15.4",
37
37
  "@rollup/plugin-babel": "^5.3.0",
38
- "@rollup/plugin-commonjs": "^20.0.0",
39
- "@rollup/plugin-node-resolve": "^13.0.4",
40
- "core-js": "^3.16.0",
38
+ "@rollup/plugin-commonjs": "^21.0.0",
39
+ "@rollup/plugin-node-resolve": "^13.0.5",
40
+ "core-js": "^3.18.2",
41
41
  "eslint": "^7.32.0",
42
- "eslint-plugin-vue": "^7.15.1",
42
+ "eslint-plugin-vue": "^7.19.1",
43
43
  "fs-extra": "^10.0.0",
44
- "husky": "^7.0.1",
44
+ "husky": "^7.0.2",
45
45
  "pinst": "^2.1.6",
46
- "rollup": "^2.55.1",
46
+ "rollup": "^2.58.0",
47
47
  "rollup-plugin-terser": "^7.0.2",
48
- "sass": "^1.37.2"
48
+ "sass": "^1.42.1"
49
49
  },
50
50
  "dependencies": {
51
- "@danielgindi/dom-utils": "^1.0.3",
51
+ "@danielgindi/dom-utils": "^1.0.4",
52
52
  "@danielgindi/virtual-list-helper": "^1.0.3",
53
53
  "keycode-js": "^3.1.0",
54
- "parse-css-transition": "^0.1.2"
54
+ "mitt": "^3.0.0"
55
55
  }
56
56
  }
package/vue/SelectBox.vue CHANGED
@@ -226,6 +226,10 @@
226
226
  type: Boolean,
227
227
  default: false,
228
228
  },
229
+ isLoadingMode: {
230
+ type: Boolean,
231
+ default: false,
232
+ },
229
233
  },
230
234
 
231
235
  data() {
@@ -481,6 +485,11 @@
481
485
  if (this._box)
482
486
  this._box.setAdditionalClasses(this.additionalClassesList);
483
487
  },
488
+
489
+ isLoadingMode() {
490
+ if (this._box)
491
+ this._box.setIsLoadingMode(!!this.isLoadingMode);
492
+ },
484
493
  },
485
494
 
486
495
  mounted() {
@@ -652,6 +661,7 @@
652
661
  filterFn: this.filterFn,
653
662
  on: this._handleBoxEvents.bind(this),
654
663
  additionalClasses: this.additionalClassesList,
664
+ isLoadingMode: this.isLoadingMode,
655
665
  });
656
666
 
657
667
  box.setValue(this.value === null ? undefined : this.value);