@drecchia/tom-select 2.5.2-virtual-scroll.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.
- package/LICENSE +202 -0
- package/README.md +104 -0
- package/dist/css/tom-select.bootstrap4.css +573 -0
- package/dist/css/tom-select.bootstrap5.css +612 -0
- package/dist/css/tom-select.css +405 -0
- package/dist/css/tom-select.default.css +497 -0
- package/dist/css/tom-select.default.css.map +1 -0
- package/dist/esm/plugins/caret_position/plugin.js +163 -0
- package/dist/esm/plugins/caret_position/plugin.js.map +1 -0
- package/dist/esm/plugins/change_listener/plugin.js +51 -0
- package/dist/esm/plugins/change_listener/plugin.js.map +1 -0
- package/dist/esm/plugins/checkbox_options/plugin.js +179 -0
- package/dist/esm/plugins/checkbox_options/plugin.js.map +1 -0
- package/dist/esm/plugins/clear_button/plugin.js +76 -0
- package/dist/esm/plugins/clear_button/plugin.js.map +1 -0
- package/dist/esm/plugins/drag_drop/plugin.js +220 -0
- package/dist/esm/plugins/drag_drop/plugin.js.map +1 -0
- package/dist/esm/plugins/dropdown_header/plugin.js +102 -0
- package/dist/esm/plugins/dropdown_header/plugin.js.map +1 -0
- package/dist/esm/plugins/dropdown_input/plugin.js +224 -0
- package/dist/esm/plugins/dropdown_input/plugin.js.map +1 -0
- package/dist/esm/plugins/input_autogrow/plugin.js +74 -0
- package/dist/esm/plugins/input_autogrow/plugin.js.map +1 -0
- package/dist/esm/plugins/local_virtual_scroll/plugin.js +305 -0
- package/dist/esm/plugins/local_virtual_scroll/plugin.js.map +1 -0
- package/dist/esm/plugins/no_active_items/plugin.js +26 -0
- package/dist/esm/plugins/no_active_items/plugin.js.map +1 -0
- package/dist/esm/plugins/no_backspace_delete/plugin.js +32 -0
- package/dist/esm/plugins/no_backspace_delete/plugin.js.map +1 -0
- package/dist/esm/plugins/optgroup_columns/plugin.js +86 -0
- package/dist/esm/plugins/optgroup_columns/plugin.js.map +1 -0
- package/dist/esm/plugins/remove_button/plugin.js +134 -0
- package/dist/esm/plugins/remove_button/plugin.js.map +1 -0
- package/dist/esm/plugins/restore_on_backspace/plugin.js +42 -0
- package/dist/esm/plugins/restore_on_backspace/plugin.js.map +1 -0
- package/dist/esm/plugins/virtual_scroll/plugin.js +272 -0
- package/dist/esm/plugins/virtual_scroll/plugin.js.map +1 -0
- package/dist/js/plugins/caret_position.js +171 -0
- package/dist/js/plugins/caret_position.js.map +1 -0
- package/dist/js/plugins/change_listener.js +59 -0
- package/dist/js/plugins/change_listener.js.map +1 -0
- package/dist/js/plugins/checkbox_options.js +187 -0
- package/dist/js/plugins/checkbox_options.js.map +1 -0
- package/dist/js/plugins/clear_button.js +84 -0
- package/dist/js/plugins/clear_button.js.map +1 -0
- package/dist/js/plugins/drag_drop.js +228 -0
- package/dist/js/plugins/drag_drop.js.map +1 -0
- package/dist/js/plugins/dropdown_header.js +110 -0
- package/dist/js/plugins/dropdown_header.js.map +1 -0
- package/dist/js/plugins/dropdown_input.js +232 -0
- package/dist/js/plugins/dropdown_input.js.map +1 -0
- package/dist/js/plugins/input_autogrow.js +82 -0
- package/dist/js/plugins/input_autogrow.js.map +1 -0
- package/dist/js/plugins/local_virtual_scroll.js +313 -0
- package/dist/js/plugins/local_virtual_scroll.js.map +1 -0
- package/dist/js/plugins/no_active_items.js +34 -0
- package/dist/js/plugins/no_active_items.js.map +1 -0
- package/dist/js/plugins/no_backspace_delete.js +40 -0
- package/dist/js/plugins/no_backspace_delete.js.map +1 -0
- package/dist/js/plugins/optgroup_columns.js +94 -0
- package/dist/js/plugins/optgroup_columns.js.map +1 -0
- package/dist/js/plugins/remove_button.js +142 -0
- package/dist/js/plugins/remove_button.js.map +1 -0
- package/dist/js/plugins/restore_on_backspace.js +50 -0
- package/dist/js/plugins/restore_on_backspace.js.map +1 -0
- package/dist/js/plugins/virtual_scroll.js +280 -0
- package/dist/js/plugins/virtual_scroll.js.map +1 -0
- package/dist/js/tom-select.base.js +4167 -0
- package/dist/js/tom-select.base.js.map +1 -0
- package/dist/js/tom-select.base.min.js +373 -0
- package/dist/js/tom-select.base.min.js.map +1 -0
- package/dist/js/tom-select.complete.js +5364 -0
- package/dist/js/tom-select.complete.js.map +1 -0
- package/dist/js/tom-select.complete.min.js +489 -0
- package/dist/js/tom-select.complete.min.js.map +1 -0
- package/dist/js/tom-select.popular.js +4436 -0
- package/dist/js/tom-select.popular.js.map +1 -0
- package/dist/js/tom-select.popular.min.js +396 -0
- package/dist/js/tom-select.popular.min.js.map +1 -0
- package/dist/types/constants.d.ts +12 -0
- package/dist/types/contrib/highlight.d.ts +13 -0
- package/dist/types/contrib/microevent.d.ts +20 -0
- package/dist/types/contrib/microplugin.d.ts +71 -0
- package/dist/types/defaults.d.ts +53 -0
- package/dist/types/getSettings.d.ts +3 -0
- package/dist/types/plugins/caret_position/plugin.d.ts +16 -0
- package/dist/types/plugins/change_listener/plugin.d.ts +16 -0
- package/dist/types/plugins/checkbox_options/plugin.d.ts +17 -0
- package/dist/types/plugins/checkbox_options/types.d.ts +14 -0
- package/dist/types/plugins/clear_button/plugin.d.ts +17 -0
- package/dist/types/plugins/clear_button/types.d.ts +7 -0
- package/dist/types/plugins/drag_drop/plugin.d.ts +16 -0
- package/dist/types/plugins/dropdown_header/plugin.d.ts +17 -0
- package/dist/types/plugins/dropdown_header/types.d.ts +8 -0
- package/dist/types/plugins/dropdown_input/plugin.d.ts +16 -0
- package/dist/types/plugins/input_autogrow/plugin.d.ts +15 -0
- package/dist/types/plugins/local_virtual_scroll/plugin.d.ts +19 -0
- package/dist/types/plugins/local_virtual_scroll/types.d.ts +14 -0
- package/dist/types/plugins/no_active_items/plugin.d.ts +15 -0
- package/dist/types/plugins/no_backspace_delete/plugin.d.ts +15 -0
- package/dist/types/plugins/optgroup_columns/plugin.d.ts +16 -0
- package/dist/types/plugins/remove_button/plugin.d.ts +17 -0
- package/dist/types/plugins/remove_button/types.d.ts +6 -0
- package/dist/types/plugins/restore_on_backspace/plugin.d.ts +21 -0
- package/dist/types/plugins/virtual_scroll/plugin.d.ts +16 -0
- package/dist/types/tom-select.complete.d.ts +2 -0
- package/dist/types/tom-select.d.ts +594 -0
- package/dist/types/tom-select.popular.d.ts +2 -0
- package/dist/types/types/core.d.ts +50 -0
- package/dist/types/types/index.d.ts +2 -0
- package/dist/types/types/settings.d.ts +81 -0
- package/dist/types/utils.d.ts +95 -0
- package/dist/types/vanilla.d.ts +76 -0
- package/package.json +156 -0
- package/src/constants.ts +13 -0
- package/src/contrib/highlight.ts +81 -0
- package/src/contrib/microevent.ts +73 -0
- package/src/contrib/microplugin.ts +137 -0
- package/src/defaults.ts +95 -0
- package/src/getSettings.ts +176 -0
- package/src/plugins/caret_position/plugin.ts +73 -0
- package/src/plugins/change_listener/plugin.ts +23 -0
- package/src/plugins/checkbox_options/plugin.scss +11 -0
- package/src/plugins/checkbox_options/plugin.ts +130 -0
- package/src/plugins/checkbox_options/types.ts +15 -0
- package/src/plugins/clear_button/plugin.scss +33 -0
- package/src/plugins/clear_button/plugin.ts +54 -0
- package/src/plugins/clear_button/types.ts +8 -0
- package/src/plugins/drag_drop/plugin.scss +10 -0
- package/src/plugins/drag_drop/plugin.ts +143 -0
- package/src/plugins/dropdown_header/plugin.scss +24 -0
- package/src/plugins/dropdown_header/plugin.ts +57 -0
- package/src/plugins/dropdown_header/types.ts +9 -0
- package/src/plugins/dropdown_input/plugin.scss +43 -0
- package/src/plugins/dropdown_input/plugin.ts +97 -0
- package/src/plugins/input_autogrow/plugin.scss +15 -0
- package/src/plugins/input_autogrow/plugin.ts +56 -0
- package/src/plugins/local_virtual_scroll/plugin.ts +309 -0
- package/src/plugins/local_virtual_scroll/types.ts +9 -0
- package/src/plugins/no_active_items/plugin.ts +20 -0
- package/src/plugins/no_backspace_delete/plugin.ts +30 -0
- package/src/plugins/optgroup_columns/plugin.scss +25 -0
- package/src/plugins/optgroup_columns/plugin.ts +59 -0
- package/src/plugins/remove_button/plugin.scss +70 -0
- package/src/plugins/remove_button/plugin.ts +78 -0
- package/src/plugins/remove_button/types.ts +7 -0
- package/src/plugins/restore_on_backspace/plugin.ts +44 -0
- package/src/plugins/virtual_scroll/plugin.ts +219 -0
- package/src/scss/-tom-select.bootstrap4.scss +4 -0
- package/src/scss/-tom-select.bootstrap5.scss +4 -0
- package/src/scss/_dropdown.scss +99 -0
- package/src/scss/_items.scss +114 -0
- package/src/scss/tom-select.bootstrap4.scss +218 -0
- package/src/scss/tom-select.bootstrap5.scss +270 -0
- package/src/scss/tom-select.default.scss +89 -0
- package/src/scss/tom-select.scss +179 -0
- package/src/tom-select.complete.ts +35 -0
- package/src/tom-select.popular.ts +15 -0
- package/src/tom-select.ts +2807 -0
- package/src/types/core.ts +68 -0
- package/src/types/index.ts +3 -0
- package/src/types/settings.ts +98 -0
- package/src/utils.ts +230 -0
- package/src/vanilla.ts +210 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
|
|
2
|
+
import type TomSelect from '../tom-select.ts';
|
|
3
|
+
import { escape_html } from '../utils.ts';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export interface TomInput extends HTMLElement{
|
|
7
|
+
tomselect ?: TomSelect;
|
|
8
|
+
disabled : boolean;
|
|
9
|
+
readOnly ?: boolean;
|
|
10
|
+
required : boolean;
|
|
11
|
+
value : string;
|
|
12
|
+
type : string;
|
|
13
|
+
validity : ValidityState;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type TomArgObject = {
|
|
17
|
+
silent?: boolean,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type TomOption = {[key:string]:any}
|
|
21
|
+
|
|
22
|
+
export type TomOptions = {[key: string]: TomOption };
|
|
23
|
+
|
|
24
|
+
export type TomCreateFilter = (input:string) => boolean;
|
|
25
|
+
|
|
26
|
+
export type TomCreateCallback = (data?:TomOption)=>void;
|
|
27
|
+
|
|
28
|
+
export type TomCreate = (input:string,create:TomCreateCallback) => boolean;
|
|
29
|
+
|
|
30
|
+
export type TomCreateOptgroup = (create:TomCreateCallback) => TomOption;
|
|
31
|
+
|
|
32
|
+
export interface TomItem extends HTMLElement{
|
|
33
|
+
dataset:{
|
|
34
|
+
value: string;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type TomLoadCallback = TomSelect['loadCallback'];
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
export type TomTemplate = (data:TomOption, escape:typeof escape_html) => string|HTMLElement;
|
|
42
|
+
export type TomTemplateNull = (data:TomOption, escape:typeof escape_html) => null|string|HTMLElement;
|
|
43
|
+
|
|
44
|
+
export type TomTemplates = {
|
|
45
|
+
'dropdown' : TomTemplate,
|
|
46
|
+
'optgroup' : TomTemplate,
|
|
47
|
+
'optgroup_header' : TomTemplate,
|
|
48
|
+
'option' : TomTemplate,
|
|
49
|
+
'item' : TomTemplate,
|
|
50
|
+
'option_create' : TomTemplate,
|
|
51
|
+
'no_results' : TomTemplate,
|
|
52
|
+
'loading' : TomTemplate,
|
|
53
|
+
'not_loading' : TomTemplateNull,
|
|
54
|
+
'loading_more' : TomTemplateNull,
|
|
55
|
+
'no_more_results' : TomTemplateNull,
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export type TomTemplateNames = keyof TomTemplates;
|
|
59
|
+
|
|
60
|
+
export type TomClearFilter = (option:TomOption,value:string) => boolean;
|
|
61
|
+
|
|
62
|
+
// https://stackoverflow.com/questions/41980195/recursive-partialt-in-typescript
|
|
63
|
+
export type RecursivePartial<T> = {
|
|
64
|
+
[P in keyof T]?:
|
|
65
|
+
T[P] extends (infer U)[] ? RecursivePartial<U>[] :
|
|
66
|
+
T[P] extends object | undefined ? RecursivePartial<T[P]> :
|
|
67
|
+
T[P];
|
|
68
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
|
|
2
|
+
import { TomCreateOptgroup, TomCreateFilter, TomCreate, TomLoadCallback, TomTemplates, TomOption } from './index.ts';
|
|
3
|
+
|
|
4
|
+
import { TPluginItem, TPluginHash } from '../contrib/microplugin.ts';
|
|
5
|
+
import { type Sort as SifterSort, type SortFn as SifterSortFn } from '@orchidjs/sifter';
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
export type TomSettings = {
|
|
10
|
+
options ?: any[],
|
|
11
|
+
optgroups ?: any[],
|
|
12
|
+
items ?: string[],
|
|
13
|
+
|
|
14
|
+
plugins : string[]|TPluginItem[]|TPluginHash,
|
|
15
|
+
delimiter : string,
|
|
16
|
+
splitOn : RegExp|string, // regexp or string for splitting up values from a paste command
|
|
17
|
+
persist : boolean,
|
|
18
|
+
diacritics : boolean,
|
|
19
|
+
create : boolean|TomCreate,
|
|
20
|
+
createOnBlur : boolean,
|
|
21
|
+
createFilter : RegExp|string|TomCreateFilter,
|
|
22
|
+
highlight : boolean,
|
|
23
|
+
openOnFocus : boolean,
|
|
24
|
+
shouldOpen : boolean,
|
|
25
|
+
maxOptions : null|number,
|
|
26
|
+
maxItems : null|number,
|
|
27
|
+
hideSelected : boolean,
|
|
28
|
+
duplicates : boolean,
|
|
29
|
+
addPrecedence : boolean,
|
|
30
|
+
selectOnTab : boolean,
|
|
31
|
+
preload : boolean|string,
|
|
32
|
+
allowEmptyOption : boolean,
|
|
33
|
+
closeAfterSelect : boolean,
|
|
34
|
+
clearAfterSelect : boolean,
|
|
35
|
+
refreshThrottle : number,
|
|
36
|
+
|
|
37
|
+
loadThrottle : number,
|
|
38
|
+
loadingClass : string,
|
|
39
|
+
|
|
40
|
+
dataAttr : string, //'data-data',
|
|
41
|
+
optgroupField : string,
|
|
42
|
+
valueField : string,
|
|
43
|
+
labelField : string,
|
|
44
|
+
disabledField : string,
|
|
45
|
+
optgroupLabelField : string,
|
|
46
|
+
optgroupValueField : string,
|
|
47
|
+
lockOptgroupOrder : boolean,
|
|
48
|
+
optionGroupRegister : TomCreateOptgroup,
|
|
49
|
+
|
|
50
|
+
sortField : string|SifterSort[]|SifterSortFn,
|
|
51
|
+
searchField : string[],
|
|
52
|
+
searchConjunction : string,
|
|
53
|
+
nesting : boolean,
|
|
54
|
+
|
|
55
|
+
mode : string,
|
|
56
|
+
wrapperClass : string,
|
|
57
|
+
controlClass : string,
|
|
58
|
+
dropdownClass : string,
|
|
59
|
+
dropdownContentClass : string,
|
|
60
|
+
itemClass : string,
|
|
61
|
+
optionClass : string,
|
|
62
|
+
|
|
63
|
+
dropdownParent : string,
|
|
64
|
+
controlInput : null|string|HTMLInputElement,
|
|
65
|
+
|
|
66
|
+
copyClassesToDropdown : boolean,
|
|
67
|
+
|
|
68
|
+
placeholder : string,
|
|
69
|
+
hidePlaceholder : boolean,
|
|
70
|
+
|
|
71
|
+
load : (value:string, callback:TomLoadCallback) => void,
|
|
72
|
+
score ?: (query:string) => () => any,
|
|
73
|
+
shouldLoad : (query:string) => boolean,
|
|
74
|
+
onInitialize : () => void,
|
|
75
|
+
onChange : (value:string|number) => void,
|
|
76
|
+
onItemAdd : (value:string|number,item:HTMLDivElement) => void,
|
|
77
|
+
onItemRemove : (value:string|number,item:HTMLDivElement) => void,
|
|
78
|
+
onClear : () => void,
|
|
79
|
+
onOptionAdd : (value:string|number,data:TomOption) => void,
|
|
80
|
+
onOptionRemove : (value:string|number) => void,
|
|
81
|
+
onOptionClear : () => void,
|
|
82
|
+
onOptionGroupAdd : (value:string|number,data:TomOption) => void,
|
|
83
|
+
onOptionGroupRemove : (value:string|number) => void,
|
|
84
|
+
onOptionGroupClear : () => void,
|
|
85
|
+
onDropdownOpen : (dropdown:HTMLDivElement) => void,
|
|
86
|
+
onDropdownClose : (dropdown:HTMLDivElement) => void,
|
|
87
|
+
onType : (str:string) => void,
|
|
88
|
+
onLoad : (options:TomOption[],optgroups:TomOption[]) => void,
|
|
89
|
+
onFocus : () => void,
|
|
90
|
+
onBlur : () => void,
|
|
91
|
+
onDelete : (values:string[], evt:KeyboardEvent|MouseEvent) => boolean,
|
|
92
|
+
|
|
93
|
+
render : TomTemplates,
|
|
94
|
+
|
|
95
|
+
// virtual scroll plugin
|
|
96
|
+
firstUrl : (query:string)=>any
|
|
97
|
+
shouldLoadMore : () => boolean,
|
|
98
|
+
};
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
|
|
2
|
+
import type TomSelect from './tom-select.ts';
|
|
3
|
+
import { TomLoadCallback } from './types/index.ts';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Converts a scalar to its best string representation
|
|
8
|
+
* for hash keys and HTML attribute values.
|
|
9
|
+
*
|
|
10
|
+
* Transformations:
|
|
11
|
+
* 'str' -> 'str'
|
|
12
|
+
* null -> ''
|
|
13
|
+
* undefined -> ''
|
|
14
|
+
* true -> '1'
|
|
15
|
+
* false -> '0'
|
|
16
|
+
* 0 -> '0'
|
|
17
|
+
* 1 -> '1'
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
export const hash_key = (value:undefined|null|boolean|string|number):string|null => {
|
|
21
|
+
if (typeof value === 'undefined' || value === null) return null;
|
|
22
|
+
return get_hash(value);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const get_hash = (value:boolean|string|number):string => {
|
|
26
|
+
if (typeof value === 'boolean') return value ? '1' : '0';
|
|
27
|
+
return value + '';
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Escapes a string for use within HTML.
|
|
32
|
+
*
|
|
33
|
+
*/
|
|
34
|
+
export const escape_html = (str:string):string => {
|
|
35
|
+
return (str + '')
|
|
36
|
+
.replace(/&/g, '&')
|
|
37
|
+
.replace(/</g, '<')
|
|
38
|
+
.replace(/>/g, '>')
|
|
39
|
+
.replace(/"/g, '"');
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* use setTimeout if timeout > 0
|
|
45
|
+
*/
|
|
46
|
+
export const timeout = (fn:()=>void,timeout:number): number | null => {
|
|
47
|
+
if( timeout > 0 ){
|
|
48
|
+
return window.setTimeout(fn,timeout);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
fn.call(null);
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Debounce the user provided load function
|
|
57
|
+
*
|
|
58
|
+
*/
|
|
59
|
+
export const loadDebounce = (fn:(value:string,callback:TomLoadCallback) => void,delay:number) => {
|
|
60
|
+
var timeout: null|ReturnType<typeof setTimeout>;
|
|
61
|
+
return function(this:TomSelect, value:string,callback:TomLoadCallback) {
|
|
62
|
+
var self = this;
|
|
63
|
+
|
|
64
|
+
if( timeout ){
|
|
65
|
+
self.loading = Math.max(self.loading - 1, 0);
|
|
66
|
+
clearTimeout(timeout);
|
|
67
|
+
}
|
|
68
|
+
timeout = setTimeout(function() {
|
|
69
|
+
timeout = null;
|
|
70
|
+
self.loadedSearches[value] = true;
|
|
71
|
+
fn.call(self, value, callback);
|
|
72
|
+
|
|
73
|
+
}, delay);
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Debounce all fired events types listed in `types`
|
|
80
|
+
* while executing the provided `fn`.
|
|
81
|
+
*
|
|
82
|
+
*/
|
|
83
|
+
export const debounce_events = ( self:TomSelect, types:string[], fn:() => void ) => {
|
|
84
|
+
var type:string;
|
|
85
|
+
var trigger = self.trigger;
|
|
86
|
+
var event_args:{ [key: string]: any } = {};
|
|
87
|
+
|
|
88
|
+
// override trigger method
|
|
89
|
+
self.trigger = function(){
|
|
90
|
+
var type = arguments[0];
|
|
91
|
+
if (types.indexOf(type) !== -1) {
|
|
92
|
+
event_args[type] = arguments;
|
|
93
|
+
} else {
|
|
94
|
+
return trigger.apply(self, arguments);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// invoke provided function
|
|
99
|
+
fn.apply(self, []);
|
|
100
|
+
self.trigger = trigger;
|
|
101
|
+
|
|
102
|
+
// trigger queued events
|
|
103
|
+
for( type of types ){
|
|
104
|
+
if( type in event_args ){
|
|
105
|
+
trigger.apply(self, event_args[type]);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Determines the current selection within a text input control.
|
|
113
|
+
* Returns an object containing:
|
|
114
|
+
* - start
|
|
115
|
+
* - length
|
|
116
|
+
*
|
|
117
|
+
* Note: "selectionStart, selectionEnd ... apply only to inputs of types text, search, URL, tel and password"
|
|
118
|
+
* - https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange
|
|
119
|
+
*/
|
|
120
|
+
export const getSelection = (input:HTMLInputElement):{ start: number; length: number } => {
|
|
121
|
+
return {
|
|
122
|
+
start : input.selectionStart || 0,
|
|
123
|
+
length : (input.selectionEnd||0) - (input.selectionStart||0),
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Prevent default
|
|
130
|
+
*
|
|
131
|
+
*/
|
|
132
|
+
export const preventDefault = (evt?:Event, stop:boolean=false):void => {
|
|
133
|
+
if( evt ){
|
|
134
|
+
evt.preventDefault();
|
|
135
|
+
if( stop ){
|
|
136
|
+
evt.stopPropagation();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Add event helper
|
|
144
|
+
*
|
|
145
|
+
*/
|
|
146
|
+
export const addEvent = (target:EventTarget, type:string, callback:EventListenerOrEventListenerObject, options?:object):void => {
|
|
147
|
+
target.addEventListener(type,callback,options);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Return true if the requested key is down
|
|
153
|
+
* Will return false if more than one control character is pressed ( when [ctrl+shift+a] != [ctrl+a] )
|
|
154
|
+
* The current evt may not always set ( eg calling advanceSelection() )
|
|
155
|
+
*
|
|
156
|
+
*/
|
|
157
|
+
export const isKeyDown = ( key_name:keyof (KeyboardEvent|MouseEvent), evt?:KeyboardEvent|MouseEvent ) => {
|
|
158
|
+
|
|
159
|
+
if( !evt ){
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if( !evt[key_name] ){
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
var count = (evt.altKey?1:0) + (evt.ctrlKey?1:0) + (evt.shiftKey?1:0) + (evt.metaKey?1:0);
|
|
168
|
+
|
|
169
|
+
if( count === 1 ){
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return false;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Get the id of an element
|
|
179
|
+
* If the id attribute is not set, set the attribute with the given id
|
|
180
|
+
*
|
|
181
|
+
*/
|
|
182
|
+
export const getId = (el:Element,id:string) => {
|
|
183
|
+
const existing_id = el.getAttribute('id');
|
|
184
|
+
if( existing_id ){
|
|
185
|
+
return existing_id;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
el.setAttribute('id',id);
|
|
189
|
+
return id;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Returns a string with backslashes added before characters that need to be escaped.
|
|
195
|
+
*/
|
|
196
|
+
export const addSlashes = (str:string):string => {
|
|
197
|
+
return str.replace(/[\\"']/g, '\\$&');
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
*
|
|
202
|
+
*/
|
|
203
|
+
export const append = ( parent:Element|DocumentFragment, node: string|Node|null|undefined ):void =>{
|
|
204
|
+
if( node ) parent.append(node);
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Iterates over arrays and hashes.
|
|
209
|
+
*
|
|
210
|
+
* ```
|
|
211
|
+
* iterate(this.items, function(item, id) {
|
|
212
|
+
* // invoked for each item
|
|
213
|
+
* });
|
|
214
|
+
* ```
|
|
215
|
+
*
|
|
216
|
+
*/
|
|
217
|
+
export const iterate = (object:[]|{[key:string]:any}, callback:(value:any,key:any)=>any) => {
|
|
218
|
+
|
|
219
|
+
if ( Array.isArray(object)) {
|
|
220
|
+
object.forEach(callback);
|
|
221
|
+
|
|
222
|
+
}else{
|
|
223
|
+
|
|
224
|
+
for (var key in object) {
|
|
225
|
+
if (object.hasOwnProperty(key)) {
|
|
226
|
+
callback(object[key], key);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
};
|
package/src/vanilla.ts
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
|
|
2
|
+
import { iterate } from './utils.ts';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Return a dom element from either a dom query string, jQuery object, a dom element or html string
|
|
6
|
+
* https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518
|
|
7
|
+
*
|
|
8
|
+
* param query should be {}
|
|
9
|
+
*/
|
|
10
|
+
export const getDom = ( query:any ):HTMLElement => {
|
|
11
|
+
|
|
12
|
+
if( query.jquery ){
|
|
13
|
+
return query[0];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if( query instanceof HTMLElement ){
|
|
17
|
+
return query;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if( isHtmlString(query) ){
|
|
21
|
+
var tpl = document.createElement('template');
|
|
22
|
+
tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result
|
|
23
|
+
return tpl.content.firstChild as HTMLElement;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return document.querySelector(query);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const isHtmlString = (arg:any): boolean => {
|
|
30
|
+
if( typeof arg === 'string' && arg.indexOf('<') > -1 ){
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const escapeQuery = (query:string):string => {
|
|
37
|
+
return query.replace(/['"\\]/g, '\\$&');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Dispatch an event
|
|
42
|
+
*
|
|
43
|
+
*/
|
|
44
|
+
export const triggerEvent = ( dom_el:HTMLElement, event_name:string ):void => {
|
|
45
|
+
var event = document.createEvent('HTMLEvents');
|
|
46
|
+
event.initEvent(event_name, true, false);
|
|
47
|
+
dom_el.dispatchEvent(event)
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Apply CSS rules to a dom element
|
|
52
|
+
*
|
|
53
|
+
*/
|
|
54
|
+
export const applyCSS = ( dom_el:HTMLElement, css:{ [key: string]: string|number }):void => {
|
|
55
|
+
Object.assign(dom_el.style, css);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Add css classes
|
|
61
|
+
*
|
|
62
|
+
*/
|
|
63
|
+
export const addClasses = ( elmts:HTMLElement|HTMLElement[], ...classes:string[]|string[][] ) => {
|
|
64
|
+
|
|
65
|
+
var norm_classes = classesArray(classes);
|
|
66
|
+
elmts = castAsArray(elmts);
|
|
67
|
+
|
|
68
|
+
elmts.map( el => {
|
|
69
|
+
norm_classes.map( cls => {
|
|
70
|
+
el.classList.add( cls );
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Remove css classes
|
|
77
|
+
*
|
|
78
|
+
*/
|
|
79
|
+
export const removeClasses = ( elmts:HTMLElement|HTMLElement[], ...classes:string[]|string[][] ) => {
|
|
80
|
+
|
|
81
|
+
var norm_classes = classesArray(classes);
|
|
82
|
+
elmts = castAsArray(elmts);
|
|
83
|
+
|
|
84
|
+
elmts.map( el => {
|
|
85
|
+
norm_classes.map(cls => {
|
|
86
|
+
el.classList.remove( cls );
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Return arguments
|
|
94
|
+
*
|
|
95
|
+
*/
|
|
96
|
+
export const classesArray = (args:string[]|string[][]):string[] => {
|
|
97
|
+
var classes:string[] = [];
|
|
98
|
+
iterate( args, (_classes) =>{
|
|
99
|
+
if( typeof _classes === 'string' ){
|
|
100
|
+
_classes = _classes.trim().split(/[\t\n\f\r\s]/);
|
|
101
|
+
}
|
|
102
|
+
if( Array.isArray(_classes) ){
|
|
103
|
+
classes = classes.concat(_classes);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
return classes.filter(Boolean);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Create an array from arg if it's not already an array
|
|
113
|
+
*
|
|
114
|
+
*/
|
|
115
|
+
export const castAsArray = (arg:any):Array<any> => {
|
|
116
|
+
if( !Array.isArray(arg) ){
|
|
117
|
+
arg = [arg];
|
|
118
|
+
}
|
|
119
|
+
return arg;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Get the closest node to the evt.target matching the selector
|
|
125
|
+
* Stops at wrapper
|
|
126
|
+
*
|
|
127
|
+
*/
|
|
128
|
+
export const parentMatch = ( target:null|HTMLElement, selector:string, wrapper?:HTMLElement ):HTMLElement|void => {
|
|
129
|
+
|
|
130
|
+
if( wrapper && !wrapper.contains(target) ){
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
while( target && target.matches ){
|
|
135
|
+
|
|
136
|
+
if( target.matches(selector) ){
|
|
137
|
+
return target;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
target = target.parentNode as HTMLElement;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Get the first or last item from an array
|
|
147
|
+
*
|
|
148
|
+
* > 0 - right (last)
|
|
149
|
+
* <= 0 - left (first)
|
|
150
|
+
*
|
|
151
|
+
*/
|
|
152
|
+
export const getTail = ( list:Array<any>|NodeList, direction:number=0 ):any => {
|
|
153
|
+
|
|
154
|
+
if( direction > 0 ){
|
|
155
|
+
return list[list.length-1];
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return list[0];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Return true if an object is empty
|
|
163
|
+
*
|
|
164
|
+
*/
|
|
165
|
+
export const isEmptyObject = (obj:object):boolean => {
|
|
166
|
+
return (Object.keys(obj).length === 0);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Get the index of an element amongst sibling nodes of the same type
|
|
172
|
+
*
|
|
173
|
+
*/
|
|
174
|
+
export const nodeIndex = ( el:null|Element, amongst?:string ):number => {
|
|
175
|
+
if (!el) return -1;
|
|
176
|
+
|
|
177
|
+
amongst = amongst || el.nodeName;
|
|
178
|
+
|
|
179
|
+
var i = 0;
|
|
180
|
+
while( el = el.previousElementSibling ){
|
|
181
|
+
|
|
182
|
+
if( el.matches(amongst) ){
|
|
183
|
+
i++;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return i;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Set attributes of an element
|
|
192
|
+
*
|
|
193
|
+
*/
|
|
194
|
+
export const setAttr = (el:Element,attrs:{ [key: string]: null|string|number }) => {
|
|
195
|
+
iterate( attrs,(val,attr) => {
|
|
196
|
+
if( val == null ){
|
|
197
|
+
el.removeAttribute(attr as string);
|
|
198
|
+
}else{
|
|
199
|
+
el.setAttribute(attr as string, ''+val);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Replace a node
|
|
207
|
+
*/
|
|
208
|
+
export const replaceNode = ( existing:Node, replacement:Node ) => {
|
|
209
|
+
if( existing.parentNode ) existing.parentNode.replaceChild(replacement, existing);
|
|
210
|
+
}
|