@danielgindi/selectbox 1.0.57 → 1.0.60

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
@@ -40,7 +40,8 @@ const hasOwnProperty = Object.prototype.hasOwnProperty;
40
40
  * @property {Element} [el] An element to attach to, instead of creating a new one
41
41
  * @property {string} [baseClassName='droplist'] class name for the menu root element
42
42
  * @property {string|string[]} [additionalClasses]
43
- * @property {number} [itemBlurDelay=300] How long to wait before deciding to blur the focused item?
43
+ * @property {boolean} [autoItemBlur=true] Should we automatically blur the focused item when the droplist loses focus?
44
+ * @property {number} [autoItemBlurDelay=300] How long to wait before deciding to blur the focused item (when the droplist loses focus)?
44
45
  * @property {boolean} [capturesFocus=true] Should this DropList be added to the TAB-key stack?
45
46
  * @property {boolean} [multi=false] Does this DropList show checkboxes for multiple item selection?
46
47
  * @property {function} [keyDownHandler=null] An alternative "keydown" event handler. Return true to prevent default behaviour.
@@ -100,7 +101,8 @@ const hasOwnProperty = Object.prototype.hasOwnProperty;
100
101
  let defaultOptions = {
101
102
  baseClassName: 'droplist',
102
103
 
103
- itemBlurDelay: 300,
104
+ autoItemBlur: true,
105
+ autoItemBlurDelay: 300,
104
106
  capturesFocus: true,
105
107
  multi: false,
106
108
  keyDownHandler: null,
@@ -123,9 +125,9 @@ let defaultOptions = {
123
125
  Emits the following events:
124
126
  ---------------------------
125
127
 
126
- 'itemfocus' {value, item, event}: item gained focus.
128
+ 'itemfocus' {value, item, event?, el}: item gained focus.
127
129
  'itemblur' {value, item}: item lost focus.
128
- 'select' {value, item}: item was selected (in single mode).
130
+ 'select' {value, item, event?, el}: item was selected (in single mode).
129
131
  'show:before': the drop list will show.
130
132
  'show': the drop list has been shown.
131
133
  'hide:before': the drop list will hide.
@@ -154,7 +156,8 @@ class DropList {
154
156
 
155
157
  baseClassName: o.baseClassName,
156
158
  additionalClasses: o.additionalClasses,
157
- itemBlurDelay: o.itemBlurDelay,
159
+ autoItemBlur: o.autoItemBlur,
160
+ autoItemBlurDelay: o.autoItemBlurDelay,
158
161
  capturesFocus: o.capturesFocus,
159
162
  multi: o.multi,
160
163
  keyDownHandler: o.keyDownHandler,
@@ -291,7 +294,9 @@ class DropList {
291
294
  p.virtualListHelper.setOnItemUnrender(el => {
292
295
  try {
293
296
  fn(el[ItemSymbol][ItemSymbol], el);
294
- } catch (err) { console.error(err); } // eslint-disable-line no-console
297
+ } catch (err) {
298
+ console.error(err); // eslint-disable-line no-console
299
+ }
295
300
  delete el[ItemSymbol];
296
301
 
297
302
  if (p.focusItemEl === el)
@@ -410,7 +415,9 @@ class DropList {
410
415
  p.virtualListHelper.setOnItemUnrender(el => {
411
416
  try {
412
417
  fn(el[ItemSymbol][ItemSymbol], el);
413
- } catch (err) { console.error(err); } // eslint-disable-line no-console
418
+ } catch (err) {
419
+ console.error(err); // eslint-disable-line no-console
420
+ }
414
421
  delete el[ItemSymbol];
415
422
 
416
423
  if (p.focusItemEl === el)
@@ -531,6 +538,7 @@ class DropList {
531
538
  value: item ? item.value : undefined,
532
539
  item: item[ItemSymbol] ?? item,
533
540
  event: event,
541
+ el: p.focusItemEl,
534
542
  });
535
543
 
536
544
  return true;
@@ -940,8 +948,8 @@ class DropList {
940
948
 
941
949
  if (p.autoFlipDirection) {
942
950
  if ((position.specX === 'right' &&
943
- viewCss.left < minX &&
944
- (Math.max(viewCss.left, minX) + viewSize.width - targetBox.left) / targetBox.width > 0.5) ||
951
+ viewCss.left < minX &&
952
+ (Math.max(viewCss.left, minX) + viewSize.width - targetBox.left) / targetBox.width > 0.5) ||
945
953
  (position.specX === 'left' &&
946
954
  viewCss.left > maxX &&
947
955
  (Math.min(viewCss.left, maxX) - targetBox.left) / targetBox.width < 0.5)) {
@@ -1125,7 +1133,7 @@ class DropList {
1125
1133
  // Detect mouse tap outside of the droplist, to blur the focused item
1126
1134
  p.sink.add(document, 'mousedown', p.onDocumentMouseDown = (event) => {
1127
1135
  if (!p.el.contains(event.target))
1128
- this._delayBlur();
1136
+ this._delayBlurItemOnBlur();
1129
1137
  });
1130
1138
  }
1131
1139
  });
@@ -1274,7 +1282,12 @@ class DropList {
1274
1282
  itemElement.classList.add(`${p.baseClassName}__item_focus`);
1275
1283
  p.focusItemEl = itemElement;
1276
1284
 
1277
- this._trigger('itemfocus', { value: itemElement.value, item: itemElement[ItemSymbol], event: null });
1285
+ this._trigger('itemfocus', {
1286
+ value: itemElement.value,
1287
+ item: itemElement[ItemSymbol],
1288
+ event: null,
1289
+ el: itemElement,
1290
+ });
1278
1291
  }
1279
1292
  }
1280
1293
 
@@ -1549,7 +1562,9 @@ class DropList {
1549
1562
 
1550
1563
  // Track scrolling
1551
1564
  let didScroll = false;
1552
- let onScroll = () => { didScroll = true; };
1565
+ let onScroll = () => {
1566
+ didScroll = true;
1567
+ };
1553
1568
  let onTouchCancel = () => {
1554
1569
  currentTouchId = null;
1555
1570
  p.sink.remove(null, '.dropdown_touchextra');
@@ -1598,7 +1613,7 @@ class DropList {
1598
1613
  if (this[DestroyedSymbol]) return;
1599
1614
 
1600
1615
  if (!p.el.contains(document.activeElement)) {
1601
- this._delayBlur();
1616
+ this._delayBlurItemOnBlur();
1602
1617
  }
1603
1618
  });
1604
1619
  });
@@ -1781,21 +1796,24 @@ class DropList {
1781
1796
  p.focusItemIndex = itemIndex;
1782
1797
 
1783
1798
  const item = p.items[itemIndex];
1784
- this._trigger('itemfocus', { value: item.value, item: item[ItemSymbol] ?? item, event: event });
1799
+ this._trigger('itemfocus', { value: item.value, item: item[ItemSymbol] ?? item, event: event, el: focusItemEl });
1785
1800
  }
1786
1801
 
1787
- _delayBlur() {
1802
+ _delayBlurItemOnBlur() {
1788
1803
  if (this[DestroyedSymbol])
1789
1804
  return;
1790
1805
 
1791
1806
  const p = this._p;
1792
1807
 
1808
+ if (!p.autoItemBlur)
1809
+ return;
1810
+
1793
1811
  clearTimeout(p.blurTimer);
1794
1812
 
1795
1813
  p.blurTimer = setTimeout(() => {
1796
1814
  if (this[DestroyedSymbol]) return;
1797
1815
  this.blurFocusedItem();
1798
- }, p.itemBlurDelay);
1816
+ }, p.autoItemBlurDelay);
1799
1817
  }
1800
1818
 
1801
1819
  _move(direction, event) {
@@ -1981,7 +1999,11 @@ class DropList {
1981
1999
  }
1982
2000
 
1983
2001
  // Fire event
1984
- this._trigger('groupcheck', { value: item.value, item: item[ItemSymbol] ?? item, affectedItems: affectedItems });
2002
+ this._trigger('groupcheck', {
2003
+ value: item.value,
2004
+ item: item[ItemSymbol] ?? item,
2005
+ affectedItems: affectedItems,
2006
+ });
1985
2007
  } else if (p.groupCount > 0) {
1986
2008
  items = p.items;
1987
2009
  itemIndex = items.indexOf(item);
package/lib/SelectBox.js CHANGED
@@ -2402,7 +2402,9 @@ class SelectBox {
2402
2402
  if (p.unrenderSingleItem && p.singleWrapper.childNodes.length > 0) {
2403
2403
  try {
2404
2404
  p.unrenderSingleItem(p.singleWrapper[ItemSymbol], p.singleWrapper);
2405
- } catch (err) { console.error(err); } // eslint-disable-line no-console
2405
+ } catch (err) {
2406
+ console.error(err); // eslint-disable-line no-console
2407
+ }
2406
2408
  }
2407
2409
 
2408
2410
  delete p.singleWrapper[ItemSymbol];
@@ -2427,7 +2429,9 @@ class SelectBox {
2427
2429
  if (unrender && itemEl.childNodes.length > 0) {
2428
2430
  try {
2429
2431
  unrender(item, itemEl);
2430
- } catch (err) { console.error(err); } // eslint-disable-line no-console
2432
+ } catch (err) {
2433
+ console.error(err); // eslint-disable-line no-console
2434
+ }
2431
2435
  }
2432
2436
  remove(itemEl);
2433
2437
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danielgindi/selectbox",
3
- "version": "1.0.57",
3
+ "version": "1.0.60",
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",
@@ -176,6 +176,8 @@ $spinner-transition-duration: .15s;
176
176
  .selectbox__open_indicator {
177
177
  position: absolute;
178
178
  right: 4px;
179
+ top: 50%;
180
+ transform: translateY(-50%);
179
181
  z-index: 2;
180
182
  font-size: 1em;
181
183
  width: 1em;
@@ -188,11 +190,11 @@ $spinner-transition-duration: .15s;
188
190
  &::before {
189
191
  border-style: solid;
190
192
  border-color: #9d9d9d;
191
- border-width: 0.25em 0.25em 0 0;
193
+ border-width: 0.2em 0.2em 0 0;
192
194
  content: '';
193
195
  display: inline-block;
194
196
  height: 0.45em;
195
- left: 0.15em;
197
+ left: 0.2em;
196
198
  position: relative;
197
199
  top: -0.18em;
198
200
  transform: rotate(135deg);
@@ -213,19 +215,13 @@ $spinner-transition-duration: .15s;
213
215
  right: auto;
214
216
  left: 4px;
215
217
  }
216
-
217
- .selectbox__multi & {
218
- top: 11px;
219
- }
220
-
221
- .selectbox__single & {
222
- top: 8px;
223
- }
224
218
  }
225
219
 
226
220
  .selectbox__clear {
227
221
  position: absolute;
228
222
  right: 2px;
223
+ top: 50%;
224
+ transform: translateY(-50%);
229
225
  z-index: 2;
230
226
 
231
227
  > button {
@@ -257,14 +253,6 @@ $spinner-transition-duration: .15s;
257
253
  left: 2px;
258
254
  }
259
255
 
260
- .selectbox__multi & {
261
- top: 5px;
262
- }
263
-
264
- .selectbox__single & {
265
- top: 4px;
266
- }
267
-
268
256
  .selectbox__has_open_indicator.selectbox__has_clear & {
269
257
  right: 14px;
270
258
 
@@ -278,34 +266,33 @@ $spinner-transition-duration: .15s;
278
266
  .selectbox__spinner {
279
267
  position: absolute;
280
268
  right: 2px;
269
+ top: 50%;
270
+ transform: translateY(-50%);
281
271
  z-index: 2;
282
- font-size: 1em;
283
- width: 1em;
284
- height: 1em;
285
- text-indent: -9999em;
286
- overflow: hidden;
287
- border-top: 0.3em solid rgba(100, 100, 100, 0.1);
288
- border-right: 0.3em solid rgba(100, 100, 100, 0.1);
289
- border-bottom: 0.3em solid rgba(100, 100, 100, 0.1);
290
- border-left: 0.3em solid rgba(60, 60, 60, 0.45);
291
- border-radius: 50%;
292
- transform: translateZ(0);
293
- animation: selectbox__spinner_anim 1.1s infinite linear;
294
- transition: opacity .1s;
272
+
273
+ &::before {
274
+ content: '';
275
+ display: block;
276
+ font-size: 1em;
277
+ width: 1em;
278
+ height: 1em;
279
+ text-indent: -9999em;
280
+ overflow: hidden;
281
+ border-top: 0.3em solid rgba(100, 100, 100, 0.1);
282
+ border-right: 0.3em solid rgba(100, 100, 100, 0.1);
283
+ border-bottom: 0.3em solid rgba(100, 100, 100, 0.1);
284
+ border-left: 0.3em solid rgba(60, 60, 60, 0.45);
285
+ border-radius: 50%;
286
+ transform: translateZ(0);
287
+ animation: selectbox__spinner_anim 1.1s infinite linear;
288
+ transition: opacity .1s;
289
+ }
295
290
 
296
291
  [dir=rtl] & {
297
292
  right: auto;
298
293
  left: 2px;
299
294
  }
300
295
 
301
- .selectbox__multi & {
302
- top: 4px;
303
- }
304
-
305
- .selectbox__single & {
306
- top: 3px;
307
- }
308
-
309
296
  .selectbox__has_spinner.selectbox__has_open_indicator & {
310
297
  right: 22px;
311
298
 
package/vue/DropList.vue CHANGED
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <span v-show="false" />
2
+ <span v-show="false" />
3
3
  </template>
4
4
 
5
5
  <script>
@@ -7,6 +7,8 @@ import DropList from '../lib/DropList';
7
7
  import DomEventsSink from '@danielgindi/dom-utils/lib/DomEventsSink';
8
8
  import { createSlotBasedRenderFunc, createSlotBasedUnrenderFunc } from './utils/slots.js';
9
9
 
10
+ const AllListEvents = ['itemfocus', 'itemblur', 'select', 'show:before', 'show', 'hide:before', 'hide', 'hide:after', 'check', 'groupcheck'];
11
+
10
12
  export default {
11
13
  props: {
12
14
  baseClassName: {
@@ -19,6 +21,14 @@ export default {
19
21
  type: Boolean,
20
22
  default: true,
21
23
  },
24
+ autoItemBlur: {
25
+ type: Boolean,
26
+ default: true,
27
+ },
28
+ autoItemBlurDelay: {
29
+ type: Number,
30
+ default: 300,
31
+ },
22
32
  capturesFocus: {
23
33
  type: Boolean,
24
34
  default: true,
@@ -105,7 +115,7 @@ export default {
105
115
  opts.additionalClasses = this.additionalClassesList;
106
116
  }
107
117
 
108
- for (let key of ['capturesFocus', 'multi',
118
+ for (let key of ['autoItemBlur', 'capturesFocus', 'multi',
109
119
  'autoCheckGroupChildren', 'useExactTargetWidth', 'constrainToWindow',
110
120
  'autoFlipDirection', 'estimateWidth']) {
111
121
  if (typeof this[key] === 'boolean') {
@@ -113,7 +123,7 @@ export default {
113
123
  }
114
124
  }
115
125
 
116
- for (let key of ['estimatedItemHeight', 'virtualMinItems']) {
126
+ for (let key of ['autoItemBlurDelay', 'estimatedItemHeight', 'virtualMinItems']) {
117
127
  if (typeof this[key] === 'number') {
118
128
  opts[key] = this[key];
119
129
  }
@@ -214,6 +224,8 @@ export default {
214
224
 
215
225
  if (this._list?.el) {
216
226
  for (let [key, fn] of Object.entries(this.$listeners)) {
227
+ if (AllListEvents.includes(key))
228
+ continue;
217
229
  this.sink.add(this._list.el, key + '.vue', fn);
218
230
  }
219
231
  }
@@ -261,6 +273,7 @@ export default {
261
273
 
262
274
  let list = new DropList(this.computedOptions);
263
275
  this.el = list.el;
276
+ this._list = list;
264
277
  this._rebindVueListeners();
265
278
 
266
279
  if (Array.isArray(this.items))
@@ -272,8 +285,6 @@ export default {
272
285
  list.setSingleSelectedItemByValue(this.value === null ? undefined : this.value);
273
286
  }
274
287
 
275
- this._list = list;
276
-
277
288
  list.show(this.positionOptions);
278
289
 
279
290
  this._setupAutoRelayout();