@danielgindi/selectbox 2.0.0 → 2.0.2
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/dist/lib.cjs.js +187 -62
- 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 +188 -63
- 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 +187 -62
- 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 +156 -28
- package/lib/SelectBox.js +1 -2
- package/package.json +2 -2
- package/vue/DropList.vue +25 -2
package/dist/lib.es6.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @danielgindi/selectbox 2.0.
|
|
2
|
+
* @danielgindi/selectbox 2.0.2
|
|
3
3
|
* git://github.com/danielgindi/selectbox.git
|
|
4
4
|
*/
|
|
5
5
|
import { createElement, closestUntil, setElementAttrs, next, prev } from '@danielgindi/dom-utils/lib/Dom';
|
|
@@ -7,7 +7,7 @@ import { remove, toggleClass, before, append, getRootNode } from '@danielgindi/d
|
|
|
7
7
|
import { setCssProps, getElementOffset, getElementHeight, getElementWidth, anchoredPosition, setElementHeight, parseTransition, setElementWidth, getPseudoElementWidth, getCssProps } from '@danielgindi/dom-utils/lib/Css';
|
|
8
8
|
import DomEventsSink from '@danielgindi/dom-utils/lib/DomEventsSink';
|
|
9
9
|
import VirtualListHelper from '@danielgindi/virtual-list-helper';
|
|
10
|
-
import { VALUE_ESCAPE, VALUE_SPACE, VALUE_ENTER, VALUE_RIGHT, VALUE_LEFT, VALUE_DOWN, VALUE_UP, VALUE_END, VALUE_HOME, VALUE_PAGE_DOWN, VALUE_PAGE_UP, VALUE_TAB, VALUE_DELETE
|
|
10
|
+
import { VALUE_BACK_SPACE, VALUE_ESCAPE, VALUE_SPACE, VALUE_ENTER, VALUE_RIGHT, VALUE_LEFT, VALUE_DOWN, VALUE_UP, VALUE_END, VALUE_HOME, VALUE_PAGE_DOWN, VALUE_PAGE_UP, VALUE_TAB, VALUE_DELETE } from 'keycode-js';
|
|
11
11
|
import mitt from 'mitt';
|
|
12
12
|
|
|
13
13
|
var escapeRegex = value => value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
|
|
@@ -59,7 +59,7 @@ const throttle = (func, wait, options) => {
|
|
|
59
59
|
return throttled;
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
-
const ItemSymbol
|
|
62
|
+
const ItemSymbol = Symbol('item');
|
|
63
63
|
const DestroyedSymbol$1 = Symbol('destroyed');
|
|
64
64
|
const GhostSymbol = Symbol('ghost');
|
|
65
65
|
const NoResultsItemSymbol = Symbol('no_results_items');
|
|
@@ -91,6 +91,7 @@ const hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
|
91
91
|
* @property {function(item: DropList.ItemBase, itemEl: Element):(*|false)} [renderNoResultsItem]
|
|
92
92
|
* @property {function(item: DropList.ItemBase, itemEl: Element)} [unrenderNoResultsItem]
|
|
93
93
|
* @property {function(name: string, data: *)} [on]
|
|
94
|
+
* @property {boolean} [isHeaderVisible=false] show header element
|
|
94
95
|
* @property {boolean} [searchable=false] include inline search box
|
|
95
96
|
* @property {string} [noResultsText='No matching results'] text for no results (empty for none)
|
|
96
97
|
* @property {number} [filterThrottleWindow=300] throttle time (milliseconds) for filtering
|
|
@@ -163,6 +164,7 @@ let defaultOptions$1 = {
|
|
|
163
164
|
|
|
164
165
|
on: null,
|
|
165
166
|
|
|
167
|
+
isHeaderVisible: false,
|
|
166
168
|
searchable: false,
|
|
167
169
|
noResultsText: 'No matching results',
|
|
168
170
|
filterThrottleWindow: 300,
|
|
@@ -235,6 +237,7 @@ class DropList {
|
|
|
235
237
|
positionOptionsProvider: o.positionOptionsProvider ?? null,
|
|
236
238
|
|
|
237
239
|
searchable: o.searchable,
|
|
240
|
+
isHeaderVisible: o.isHeaderVisible,
|
|
238
241
|
|
|
239
242
|
silenceEvents: true,
|
|
240
243
|
mitt: mitt(),
|
|
@@ -282,33 +285,24 @@ class DropList {
|
|
|
282
285
|
});
|
|
283
286
|
}
|
|
284
287
|
|
|
288
|
+
p.el = wrapperEl;
|
|
289
|
+
|
|
285
290
|
let menuEl = createElement('ul');
|
|
286
291
|
menuEl.role = 'menu';
|
|
292
|
+
p.menuEl = menuEl;
|
|
287
293
|
|
|
288
|
-
|
|
289
|
-
p.
|
|
290
|
-
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
p.searchInput = createElement('input', {
|
|
294
|
-
type: 'search',
|
|
295
|
-
role: 'searchbox',
|
|
296
|
-
tabindex: '0',
|
|
297
|
-
autocorrect: 'off',
|
|
298
|
-
autocomplete: 'off',
|
|
299
|
-
autocapitalize: 'off',
|
|
300
|
-
spellcheck: 'false',
|
|
301
|
-
'aria-autocomplete': 'list',
|
|
302
|
-
});
|
|
294
|
+
p.headerEl = createElement('div', {
|
|
295
|
+
class: p.baseClassName + '_header',
|
|
296
|
+
});
|
|
303
297
|
|
|
304
|
-
|
|
305
|
-
|
|
298
|
+
if (o.searchable) {
|
|
299
|
+
this.setSearchable(true);
|
|
306
300
|
}
|
|
307
301
|
|
|
308
|
-
|
|
302
|
+
if (o.isHeaderVisible)
|
|
303
|
+
this.setHeaderVisible(o.isHeaderVisible);
|
|
309
304
|
|
|
310
|
-
|
|
311
|
-
p.menuEl = menuEl;
|
|
305
|
+
wrapperEl.appendChild(menuEl);
|
|
312
306
|
|
|
313
307
|
p.items = [];
|
|
314
308
|
p.groupCount = 0; // This will keep state of how many `group` items we have
|
|
@@ -335,7 +329,7 @@ class DropList {
|
|
|
335
329
|
label: p.lastMeasureLongestLabelText,
|
|
336
330
|
value: 'Measure',
|
|
337
331
|
|
|
338
|
-
[ItemSymbol
|
|
332
|
+
[ItemSymbol]: {
|
|
339
333
|
[p.labelProp]: p.lastMeasureLongestLabelText,
|
|
340
334
|
[p.valueProp]: 'Measure',
|
|
341
335
|
},
|
|
@@ -350,7 +344,7 @@ class DropList {
|
|
|
350
344
|
_nointeraction: true,
|
|
351
345
|
_nocheck: true,
|
|
352
346
|
|
|
353
|
-
[ItemSymbol
|
|
347
|
+
[ItemSymbol]: NoResultsItemSymbol,
|
|
354
348
|
};
|
|
355
349
|
} else {
|
|
356
350
|
item = items[index];
|
|
@@ -396,7 +390,7 @@ class DropList {
|
|
|
396
390
|
|
|
397
391
|
this._renderItemContent(item, itemEl);
|
|
398
392
|
|
|
399
|
-
itemEl[ItemSymbol
|
|
393
|
+
itemEl[ItemSymbol] = item;
|
|
400
394
|
},
|
|
401
395
|
});
|
|
402
396
|
|
|
@@ -576,7 +570,7 @@ class DropList {
|
|
|
576
570
|
const fn = p.unrenderItem;
|
|
577
571
|
const fnNoResults = p.unrenderNoResultsItem;
|
|
578
572
|
p.virtualListHelper.setOnItemUnrender(el => {
|
|
579
|
-
const item = el[ItemSymbol
|
|
573
|
+
const item = el[ItemSymbol];
|
|
580
574
|
if (item === NoResultsItemSymbol) {
|
|
581
575
|
try {
|
|
582
576
|
fnNoResults(item, el);
|
|
@@ -585,19 +579,19 @@ class DropList {
|
|
|
585
579
|
}
|
|
586
580
|
} else {
|
|
587
581
|
try {
|
|
588
|
-
fn(item[ItemSymbol
|
|
582
|
+
fn(item[ItemSymbol], el);
|
|
589
583
|
} catch (err) {
|
|
590
584
|
console.error(err); // eslint-disable-line no-console
|
|
591
585
|
}
|
|
592
586
|
}
|
|
593
|
-
delete el[ItemSymbol
|
|
587
|
+
delete el[ItemSymbol];
|
|
594
588
|
|
|
595
589
|
if (p.focusItemEl === el)
|
|
596
590
|
p.focusItemEl = null;
|
|
597
591
|
});
|
|
598
592
|
} else {
|
|
599
593
|
p.virtualListHelper.setOnItemUnrender(el => {
|
|
600
|
-
delete el[ItemSymbol
|
|
594
|
+
delete el[ItemSymbol];
|
|
601
595
|
|
|
602
596
|
if (p.focusItemEl === el)
|
|
603
597
|
p.focusItemEl = null;
|
|
@@ -663,7 +657,7 @@ class DropList {
|
|
|
663
657
|
this._hideSublist();
|
|
664
658
|
}
|
|
665
659
|
|
|
666
|
-
this._trigger('itemblur', { value: item.value, item: item[ItemSymbol
|
|
660
|
+
this._trigger('itemblur', { value: item.value, item: item[ItemSymbol] ?? item });
|
|
667
661
|
}
|
|
668
662
|
|
|
669
663
|
nextPage(event) {
|
|
@@ -695,7 +689,7 @@ class DropList {
|
|
|
695
689
|
}
|
|
696
690
|
this._trigger('check', {
|
|
697
691
|
value: item.value,
|
|
698
|
-
item: item[ItemSymbol
|
|
692
|
+
item: item[ItemSymbol] ?? item,
|
|
699
693
|
checked: item._checked,
|
|
700
694
|
isGroup: item._group,
|
|
701
695
|
isCheckingGroup: false,
|
|
@@ -715,7 +709,7 @@ class DropList {
|
|
|
715
709
|
if (p.focusItemIndex === undefined)
|
|
716
710
|
p.focusItemIndex = -1;
|
|
717
711
|
|
|
718
|
-
item = item ?? p.focusItemEl[ItemSymbol
|
|
712
|
+
item = item ?? p.focusItemEl[ItemSymbol];
|
|
719
713
|
if (item._nointeraction) {
|
|
720
714
|
return false;
|
|
721
715
|
}
|
|
@@ -726,7 +720,7 @@ class DropList {
|
|
|
726
720
|
|
|
727
721
|
this._trigger('select', {
|
|
728
722
|
value: item ? item.value : undefined,
|
|
729
|
-
item: item[ItemSymbol
|
|
723
|
+
item: item[ItemSymbol] ?? item,
|
|
730
724
|
event: event,
|
|
731
725
|
el: p.focusItemEl,
|
|
732
726
|
});
|
|
@@ -767,7 +761,7 @@ class DropList {
|
|
|
767
761
|
let oitem = itemsToAdd[i];
|
|
768
762
|
//noinspection PointlessBooleanExpressionJS
|
|
769
763
|
let item = {
|
|
770
|
-
[ItemSymbol
|
|
764
|
+
[ItemSymbol]: oitem,
|
|
771
765
|
label: oitem[labelProp],
|
|
772
766
|
value: oitem[valueProp],
|
|
773
767
|
_nocheck: !!oitem._nocheck,
|
|
@@ -854,7 +848,7 @@ class DropList {
|
|
|
854
848
|
if (itemIndex === -1) return this;
|
|
855
849
|
|
|
856
850
|
let item = this.itemAtIndex(itemIndex);
|
|
857
|
-
item[ItemSymbol
|
|
851
|
+
item[ItemSymbol] = newItem;
|
|
858
852
|
|
|
859
853
|
if (hasOwnProperty.call(newItem, p.labelProp))
|
|
860
854
|
item.label = newItem[p.labelProp];
|
|
@@ -980,7 +974,7 @@ class DropList {
|
|
|
980
974
|
for (let i = 0, count = p.items.length; i < count; i++) {
|
|
981
975
|
let item = p.items[i];
|
|
982
976
|
if (item.value === value) {
|
|
983
|
-
return item[ItemSymbol
|
|
977
|
+
return item[ItemSymbol];
|
|
984
978
|
}
|
|
985
979
|
}
|
|
986
980
|
|
|
@@ -1050,7 +1044,7 @@ class DropList {
|
|
|
1050
1044
|
|
|
1051
1045
|
for (let i = 0, count = items.length; i < count; i++) {
|
|
1052
1046
|
let it = items[i];
|
|
1053
|
-
if (it[ItemSymbol
|
|
1047
|
+
if (it[ItemSymbol] === item) {
|
|
1054
1048
|
return i;
|
|
1055
1049
|
}
|
|
1056
1050
|
}
|
|
@@ -1065,7 +1059,7 @@ class DropList {
|
|
|
1065
1059
|
|
|
1066
1060
|
for (let i = 0, count = items.length; i < count; i++) {
|
|
1067
1061
|
let it = items[i];
|
|
1068
|
-
if (it[ItemSymbol
|
|
1062
|
+
if (it[ItemSymbol] === item) {
|
|
1069
1063
|
return i;
|
|
1070
1064
|
}
|
|
1071
1065
|
}
|
|
@@ -1074,7 +1068,7 @@ class DropList {
|
|
|
1074
1068
|
}
|
|
1075
1069
|
|
|
1076
1070
|
items() {
|
|
1077
|
-
return this._p.items.map(x => x[ItemSymbol
|
|
1071
|
+
return this._p.items.map(x => x[ItemSymbol]);
|
|
1078
1072
|
}
|
|
1079
1073
|
|
|
1080
1074
|
itemsReference() {
|
|
@@ -1086,13 +1080,42 @@ class DropList {
|
|
|
1086
1080
|
}
|
|
1087
1081
|
|
|
1088
1082
|
itemAtIndex(index) {
|
|
1089
|
-
return this._p.items[index]?.[ItemSymbol
|
|
1083
|
+
return this._p.items[index]?.[ItemSymbol];
|
|
1090
1084
|
}
|
|
1091
1085
|
|
|
1092
1086
|
filteredItemAtIndex(index) {
|
|
1093
1087
|
const p = this._p;
|
|
1094
1088
|
const items = p.filteredItems ?? p.items;
|
|
1095
|
-
return items[index]?.[ItemSymbol
|
|
1089
|
+
return items[index]?.[ItemSymbol];
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
/**
|
|
1093
|
+
* Return the item element at the given original index, if it exists.
|
|
1094
|
+
* The item may not be currently rendered, and null will be returned
|
|
1095
|
+
* @param index
|
|
1096
|
+
* @returns {HTMLElement|null}
|
|
1097
|
+
*/
|
|
1098
|
+
itemElementAtIndex(index) {
|
|
1099
|
+
const p = this._p;
|
|
1100
|
+
if (!p.filteredItems)
|
|
1101
|
+
return this.filteredElementItemAtIndex(index);
|
|
1102
|
+
|
|
1103
|
+
index = p.filteredItems.indexOf(this._p.items[index]);
|
|
1104
|
+
|
|
1105
|
+
const li = p.virtualListHelper.getItemElementAt(index);
|
|
1106
|
+
return li ?? null;
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
/**
|
|
1110
|
+
* Return the item element at the given index, if it exists.
|
|
1111
|
+
* The item may not be currently rendered, and null will be returned
|
|
1112
|
+
* @param index
|
|
1113
|
+
* @returns {HTMLElement|null}
|
|
1114
|
+
*/
|
|
1115
|
+
filteredElementItemAtIndex(index) {
|
|
1116
|
+
const p = this._p;
|
|
1117
|
+
const li = p.virtualListHelper.getItemElementAt(index);
|
|
1118
|
+
return li ?? null;
|
|
1096
1119
|
}
|
|
1097
1120
|
|
|
1098
1121
|
/**
|
|
@@ -1160,7 +1183,30 @@ class DropList {
|
|
|
1160
1183
|
let filteredItems;
|
|
1161
1184
|
|
|
1162
1185
|
if (typeof fn === 'function') {
|
|
1163
|
-
|
|
1186
|
+
// Send the original items to the filter function
|
|
1187
|
+
filteredItems = p.filterFn(
|
|
1188
|
+
p.items.map(x => x[ItemSymbol] ?? x),
|
|
1189
|
+
term);
|
|
1190
|
+
|
|
1191
|
+
if (Array.isArray(filteredItems)) {
|
|
1192
|
+
// And back
|
|
1193
|
+
filteredItems = filteredItems.map(oitem => {
|
|
1194
|
+
let our = oitem[ItemSymbol];
|
|
1195
|
+
if (!our) {
|
|
1196
|
+
our = {
|
|
1197
|
+
[ItemSymbol]: oitem,
|
|
1198
|
+
label: oitem[p.labelProp],
|
|
1199
|
+
value: oitem[p.valueProp],
|
|
1200
|
+
_nocheck: !!oitem._nocheck,
|
|
1201
|
+
_nointeraction: !!oitem._nointeraction,
|
|
1202
|
+
_subitems: oitem._subitems,
|
|
1203
|
+
_group: !!oitem._group,
|
|
1204
|
+
_checked: !!oitem._checked,
|
|
1205
|
+
};
|
|
1206
|
+
}
|
|
1207
|
+
return our;
|
|
1208
|
+
});
|
|
1209
|
+
}
|
|
1164
1210
|
}
|
|
1165
1211
|
|
|
1166
1212
|
// If there was no filter function, or it gave up on filtering.
|
|
@@ -1659,7 +1705,7 @@ class DropList {
|
|
|
1659
1705
|
let li = p.virtualListHelper.getItemElementAt(index);
|
|
1660
1706
|
if (!li) return this;
|
|
1661
1707
|
|
|
1662
|
-
let item = li[ItemSymbol
|
|
1708
|
+
let item = li[ItemSymbol];
|
|
1663
1709
|
|
|
1664
1710
|
checked = checked && !item._nocheck;
|
|
1665
1711
|
|
|
@@ -1752,7 +1798,7 @@ class DropList {
|
|
|
1752
1798
|
let item = p.items[i];
|
|
1753
1799
|
if (!item._checked) continue;
|
|
1754
1800
|
if (excludeGroups && item._group) continue;
|
|
1755
|
-
items.push(item[ItemSymbol
|
|
1801
|
+
items.push(item[ItemSymbol]);
|
|
1756
1802
|
}
|
|
1757
1803
|
|
|
1758
1804
|
return items;
|
|
@@ -1918,6 +1964,72 @@ class DropList {
|
|
|
1918
1964
|
return p.el.parentNode && getComputedStyle(p.el).display !== 'none';
|
|
1919
1965
|
}
|
|
1920
1966
|
|
|
1967
|
+
/**
|
|
1968
|
+
* Change visibility of the header element
|
|
1969
|
+
* You should probably call `relayout()` after this.
|
|
1970
|
+
* @param {boolean} visible
|
|
1971
|
+
*/
|
|
1972
|
+
setHeaderVisible(visible) {
|
|
1973
|
+
let isVisible = this.isHeaderVisible();
|
|
1974
|
+
if (isVisible === !!visible)
|
|
1975
|
+
return;
|
|
1976
|
+
|
|
1977
|
+
if (visible) {
|
|
1978
|
+
this._p.el.insertBefore(this._p.headerEl, this._p.el.firstChild ?? null);
|
|
1979
|
+
} else {
|
|
1980
|
+
this._p.headerEl.remove();
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1983
|
+
|
|
1984
|
+
/**
|
|
1985
|
+
* Is the header element visible?
|
|
1986
|
+
* @returns {boolean}
|
|
1987
|
+
*/
|
|
1988
|
+
isHeaderVisible() {
|
|
1989
|
+
return !!this._p.headerEl.parentNode;
|
|
1990
|
+
}
|
|
1991
|
+
|
|
1992
|
+
/**
|
|
1993
|
+
* Get a reference to the header element in order to add custom content.
|
|
1994
|
+
* @returns {Element}
|
|
1995
|
+
*/
|
|
1996
|
+
getHeaderElement() {
|
|
1997
|
+
return this._p.headerEl;
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
/**
|
|
2001
|
+
* Set inline search visibility
|
|
2002
|
+
* You should probably call `relayout()` after this.
|
|
2003
|
+
* @param {boolean} searchable
|
|
2004
|
+
*/
|
|
2005
|
+
setSearchable(searchable) {
|
|
2006
|
+
const p = this._p;
|
|
2007
|
+
|
|
2008
|
+
if (!!p.searchInput === !!searchable)
|
|
2009
|
+
return;
|
|
2010
|
+
|
|
2011
|
+
if (searchable) {
|
|
2012
|
+
p.searchInput = createElement('input', {
|
|
2013
|
+
type: 'search',
|
|
2014
|
+
role: 'searchbox',
|
|
2015
|
+
tabindex: '0',
|
|
2016
|
+
autocorrect: 'off',
|
|
2017
|
+
autocomplete: 'off',
|
|
2018
|
+
autocapitalize: 'off',
|
|
2019
|
+
spellcheck: 'false',
|
|
2020
|
+
'aria-autocomplete': 'list',
|
|
2021
|
+
});
|
|
2022
|
+
|
|
2023
|
+
p.headerEl.appendChild(p.searchInput);
|
|
2024
|
+
} else {
|
|
2025
|
+
if (p.searchInput.parentNode)
|
|
2026
|
+
p.searchInput.remove();
|
|
2027
|
+
p.searchInput = null;
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
this.setHeaderVisible(searchable);
|
|
2031
|
+
}
|
|
2032
|
+
|
|
1921
2033
|
hasFocusedItem() {
|
|
1922
2034
|
return this._p.focusItemIndex > -1;
|
|
1923
2035
|
}
|
|
@@ -1960,11 +2072,11 @@ class DropList {
|
|
|
1960
2072
|
itemElement.classList.add(`${p.baseClassName}__item_focus`);
|
|
1961
2073
|
p.focusItemEl = itemElement;
|
|
1962
2074
|
|
|
1963
|
-
const item = itemElement[ItemSymbol
|
|
2075
|
+
const item = itemElement[ItemSymbol];
|
|
1964
2076
|
|
|
1965
2077
|
this._trigger('itemfocus', {
|
|
1966
2078
|
value: item.value,
|
|
1967
|
-
item: item[ItemSymbol
|
|
2079
|
+
item: item[ItemSymbol] ?? item,
|
|
1968
2080
|
event: null,
|
|
1969
2081
|
el: itemElement,
|
|
1970
2082
|
});
|
|
@@ -2031,7 +2143,7 @@ class DropList {
|
|
|
2031
2143
|
|
|
2032
2144
|
this._trigger('show_subitems', {
|
|
2033
2145
|
value: item.value,
|
|
2034
|
-
item: item[ItemSymbol
|
|
2146
|
+
item: item[ItemSymbol] ?? item,
|
|
2035
2147
|
el: itemElement,
|
|
2036
2148
|
droplist: droplist,
|
|
2037
2149
|
});
|
|
@@ -2203,7 +2315,7 @@ class DropList {
|
|
|
2203
2315
|
const p = this._p;
|
|
2204
2316
|
|
|
2205
2317
|
if (this._hasScroll()) {
|
|
2206
|
-
const
|
|
2318
|
+
const menuEl = p.menuEl, scrollTop = menuEl.scrollTop;
|
|
2207
2319
|
|
|
2208
2320
|
let itemPos, previousPos = -1;
|
|
2209
2321
|
let maxIterations = 30; // Some zoom/scroll issues can make it so that it takes almost forever
|
|
@@ -2218,12 +2330,12 @@ class DropList {
|
|
|
2218
2330
|
|
|
2219
2331
|
let itemSize = p.virtualListHelper.getItemSize(itemIndex);
|
|
2220
2332
|
|
|
2221
|
-
let listHeight =
|
|
2333
|
+
let listHeight = menuEl.clientHeight;
|
|
2222
2334
|
|
|
2223
2335
|
if (itemPos < scrollTop) {
|
|
2224
|
-
|
|
2336
|
+
menuEl.scrollTop = itemPos;
|
|
2225
2337
|
} else if (itemPos + itemSize > scrollTop + listHeight) {
|
|
2226
|
-
|
|
2338
|
+
menuEl.scrollTop = itemPos + itemSize - listHeight;
|
|
2227
2339
|
}
|
|
2228
2340
|
|
|
2229
2341
|
// force update items, until the positions and sizes are final
|
|
@@ -2508,6 +2620,8 @@ class DropList {
|
|
|
2508
2620
|
case VALUE_END:
|
|
2509
2621
|
case VALUE_UP:
|
|
2510
2622
|
case VALUE_DOWN:
|
|
2623
|
+
p.lastKeyWasChar = false;
|
|
2624
|
+
|
|
2511
2625
|
event.preventDefault();
|
|
2512
2626
|
|
|
2513
2627
|
switch (event.key) {
|
|
@@ -2534,6 +2648,7 @@ class DropList {
|
|
|
2534
2648
|
|
|
2535
2649
|
case VALUE_LEFT:
|
|
2536
2650
|
case VALUE_RIGHT:
|
|
2651
|
+
p.lastKeyWasChar = false;
|
|
2537
2652
|
if (event.key === VALUE_RIGHT && getComputedStyle(event.target).direction !== 'rtl' ||
|
|
2538
2653
|
event.key === VALUE_LEFT && getComputedStyle(event.target).direction === 'rtl') {
|
|
2539
2654
|
const items = p.filteredItems ?? p.items;
|
|
@@ -2551,22 +2666,31 @@ class DropList {
|
|
|
2551
2666
|
break;
|
|
2552
2667
|
|
|
2553
2668
|
case VALUE_ENTER:
|
|
2669
|
+
p.lastKeyWasChar = false;
|
|
2554
2670
|
this.triggerItemSelection(null, event);
|
|
2555
2671
|
event.preventDefault();
|
|
2556
2672
|
break;
|
|
2557
2673
|
|
|
2558
2674
|
case VALUE_SPACE:
|
|
2675
|
+
if (event.target.tagName === 'BUTTON' ||
|
|
2676
|
+
event.target.tagName === 'INPUT' && p.lastKeyWasChar) return;
|
|
2677
|
+
|
|
2559
2678
|
this.toggleFocusedItem();
|
|
2560
2679
|
event.preventDefault();
|
|
2561
2680
|
break;
|
|
2562
2681
|
|
|
2563
2682
|
case VALUE_ESCAPE:
|
|
2683
|
+
p.lastKeyWasChar = false;
|
|
2564
2684
|
event.preventDefault();
|
|
2565
2685
|
this.hide();
|
|
2566
2686
|
break;
|
|
2567
2687
|
|
|
2568
2688
|
default: {
|
|
2569
|
-
if (event.
|
|
2689
|
+
if (event.target.tagName === 'INPUT' ||
|
|
2690
|
+
event.target.tagName === 'TEXTAREA') {
|
|
2691
|
+
const character = event.key || String.fromCharCode(event.keyCode);
|
|
2692
|
+
p.lastKeyWasChar = character.length === 1 || event.key === VALUE_BACK_SPACE;
|
|
2693
|
+
}
|
|
2570
2694
|
|
|
2571
2695
|
// Inline search box not available, then support typing to focus by first letters
|
|
2572
2696
|
if (!p.searchable)
|
|
@@ -2581,8 +2705,10 @@ class DropList {
|
|
|
2581
2705
|
const p = this._p;
|
|
2582
2706
|
|
|
2583
2707
|
// noinspection JSDeprecatedSymbols
|
|
2584
|
-
|
|
2585
|
-
|
|
2708
|
+
const character = evt.key || String.fromCharCode(evt.keyCode);
|
|
2709
|
+
const isChar = character.length === 1;
|
|
2710
|
+
p.lastKeyWasChar = isChar || evt.key === VALUE_BACK_SPACE;
|
|
2711
|
+
if (!isChar) return;
|
|
2586
2712
|
|
|
2587
2713
|
clearTimeout(p.filterTimer);
|
|
2588
2714
|
|
|
@@ -2662,7 +2788,7 @@ class DropList {
|
|
|
2662
2788
|
itemIndex = p.virtualListHelper.getItemIndexFromElement(itemEl);
|
|
2663
2789
|
}
|
|
2664
2790
|
|
|
2665
|
-
if (itemIndex > -1 && itemEl?.[ItemSymbol
|
|
2791
|
+
if (itemIndex > -1 && itemEl?.[ItemSymbol]?.[ItemSymbol] === NoResultsItemSymbol) {
|
|
2666
2792
|
itemIndex = undefined;
|
|
2667
2793
|
}
|
|
2668
2794
|
|
|
@@ -2673,7 +2799,7 @@ class DropList {
|
|
|
2673
2799
|
}
|
|
2674
2800
|
|
|
2675
2801
|
let focusItemEl = itemEl || p.virtualListHelper.getItemElementAt(itemIndex);
|
|
2676
|
-
if (!focusItemEl || focusItemEl[ItemSymbol
|
|
2802
|
+
if (!focusItemEl || focusItemEl[ItemSymbol]._nointeraction) {
|
|
2677
2803
|
p._isFocusingItem = false;
|
|
2678
2804
|
this.blurFocusedItem();
|
|
2679
2805
|
return;
|
|
@@ -2695,7 +2821,7 @@ class DropList {
|
|
|
2695
2821
|
const item = items[itemIndex];
|
|
2696
2822
|
this._trigger('itemfocus', {
|
|
2697
2823
|
value: item.value,
|
|
2698
|
-
item: item[ItemSymbol
|
|
2824
|
+
item: item[ItemSymbol] ?? item,
|
|
2699
2825
|
event: event,
|
|
2700
2826
|
el: focusItemEl,
|
|
2701
2827
|
});
|
|
@@ -2901,7 +3027,7 @@ class DropList {
|
|
|
2901
3027
|
// Fire event
|
|
2902
3028
|
this._trigger('check', {
|
|
2903
3029
|
value: next.value,
|
|
2904
|
-
item: next[ItemSymbol
|
|
3030
|
+
item: next[ItemSymbol] ?? next,
|
|
2905
3031
|
checked: next._checked,
|
|
2906
3032
|
isGroup: next._group,
|
|
2907
3033
|
isCheckingGroup: true,
|
|
@@ -2912,7 +3038,7 @@ class DropList {
|
|
|
2912
3038
|
// Fire event
|
|
2913
3039
|
this._trigger('groupcheck', {
|
|
2914
3040
|
value: item.value,
|
|
2915
|
-
item: item[ItemSymbol
|
|
3041
|
+
item: item[ItemSymbol] ?? item,
|
|
2916
3042
|
affectedItems: affectedItems,
|
|
2917
3043
|
});
|
|
2918
3044
|
} else if (p.groupCount > 0 && p.autoCheckGroupChildren) {
|
|
@@ -2983,7 +3109,7 @@ class DropList {
|
|
|
2983
3109
|
// Fire event
|
|
2984
3110
|
this._trigger('check', {
|
|
2985
3111
|
value: groupItem.value,
|
|
2986
|
-
item: groupItem[ItemSymbol
|
|
3112
|
+
item: groupItem[ItemSymbol] ?? groupItem,
|
|
2987
3113
|
checked: groupItem._checked,
|
|
2988
3114
|
isGroup: groupItem._group,
|
|
2989
3115
|
isCheckingGroup: false,
|
|
@@ -3088,7 +3214,7 @@ class DropList {
|
|
|
3088
3214
|
// NOTE: a "measure" item will not have full data of original item.
|
|
3089
3215
|
// so for a custom renderer - we try to send original item, and fallback to our private list item.
|
|
3090
3216
|
|
|
3091
|
-
const originalItem = item[ItemSymbol
|
|
3217
|
+
const originalItem = item[ItemSymbol];
|
|
3092
3218
|
|
|
3093
3219
|
if (originalItem === NoResultsItemSymbol) {
|
|
3094
3220
|
if (p.renderNoResultsItem && p.renderNoResultsItem(item, itemEl) !== false) {
|
|
@@ -3171,7 +3297,6 @@ class DropList {
|
|
|
3171
3297
|
}
|
|
3172
3298
|
}
|
|
3173
3299
|
|
|
3174
|
-
const ItemSymbol = Symbol('item');
|
|
3175
3300
|
const DestroyedSymbol = Symbol('destroyed');
|
|
3176
3301
|
const RestMultiItemsSymbol = Symbol('rest_multi_items');
|
|
3177
3302
|
|