@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/css/selectbox.css +1 -1
- package/css/selectbox.css.map +1 -1
- package/dist/lib.cjs.js +46 -20
- package/dist/lib.cjs.js.map +1 -1
- package/dist/lib.cjs.min.js +2 -2
- package/dist/lib.cjs.min.js.map +1 -1
- package/dist/lib.es6.js +46 -20
- package/dist/lib.es6.js.map +1 -1
- package/dist/lib.es6.min.js +2 -2
- package/dist/lib.es6.min.js.map +1 -1
- package/dist/lib.umd.js +46 -20
- package/dist/lib.umd.js.map +1 -1
- package/dist/lib.umd.min.js +2 -2
- package/dist/lib.umd.min.js.map +1 -1
- package/lib/DropList.js +39 -17
- package/lib/SelectBox.js +6 -2
- package/package.json +1 -1
- package/scss/selectbox.scss +26 -39
- package/vue/DropList.vue +16 -5
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 {
|
|
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
|
-
|
|
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
|
-
|
|
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) {
|
|
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) {
|
|
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
|
-
|
|
944
|
-
|
|
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.
|
|
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', {
|
|
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 = () => {
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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', {
|
|
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) {
|
|
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) {
|
|
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
package/scss/selectbox.scss
CHANGED
|
@@ -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.
|
|
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.
|
|
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
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
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
|
-
|
|
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();
|