mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-27 14:14:11 +01:00
Add Tom-Select lib
This commit is contained in:
73
node_modules/tom-select/src/plugins/caret_position/plugin.ts
generated
vendored
Normal file
73
node_modules/tom-select/src/plugins/caret_position/plugin.ts
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Plugin: "dropdown_input" (Tom Select)
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import type TomSelect from '../../tom-select.ts';
|
||||
import { nodeIndex, removeClasses } from '../../vanilla.ts';
|
||||
|
||||
|
||||
export default function(this:TomSelect) {
|
||||
var self = this;
|
||||
|
||||
/**
|
||||
* Moves the caret to the specified index.
|
||||
*
|
||||
* The input must be moved by leaving it in place and moving the
|
||||
* siblings, due to the fact that focus cannot be restored once lost
|
||||
* on mobile webkit devices
|
||||
*
|
||||
*/
|
||||
self.hook('instead','setCaret',(new_pos:number) => {
|
||||
|
||||
if( self.settings.mode === 'single' || !self.control.contains(self.control_input) ) {
|
||||
new_pos = self.items.length;
|
||||
} else {
|
||||
new_pos = Math.max(0, Math.min(self.items.length, new_pos));
|
||||
|
||||
if( new_pos != self.caretPos && !self.isPending ){
|
||||
|
||||
self.controlChildren().forEach((child,j) => {
|
||||
if( j < new_pos ){
|
||||
self.control_input.insertAdjacentElement('beforebegin', child );
|
||||
} else {
|
||||
self.control.appendChild( child );
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
self.caretPos = new_pos;
|
||||
});
|
||||
|
||||
self.hook('instead','moveCaret',(direction:number) => {
|
||||
|
||||
if( !self.isFocused ) return;
|
||||
|
||||
// move caret before or after selected items
|
||||
const last_active = self.getLastActive(direction);
|
||||
if( last_active ){
|
||||
const idx = nodeIndex(last_active);
|
||||
self.setCaret(direction > 0 ? idx + 1: idx);
|
||||
self.setActiveItem();
|
||||
removeClasses(last_active as HTMLElement,'last-active');
|
||||
|
||||
// move caret left or right of current position
|
||||
}else{
|
||||
self.setCaret(self.caretPos + direction);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
23
node_modules/tom-select/src/plugins/change_listener/plugin.ts
generated
vendored
Normal file
23
node_modules/tom-select/src/plugins/change_listener/plugin.ts
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Plugin: "change_listener" (Tom Select)
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import type TomSelect from '../../tom-select.ts';
|
||||
import { addEvent } from '../../utils.ts';
|
||||
|
||||
export default function(this:TomSelect) {
|
||||
addEvent(this.input,'change',()=>{
|
||||
this.sync();
|
||||
});
|
||||
};
|
||||
11
node_modules/tom-select/src/plugins/checkbox_options/plugin.scss
generated
vendored
Normal file
11
node_modules/tom-select/src/plugins/checkbox_options/plugin.scss
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
.plugin-checkbox_options:not(.rtl) {
|
||||
.option input {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.plugin-checkbox_options.rtl {
|
||||
.option input {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
}
|
||||
130
node_modules/tom-select/src/plugins/checkbox_options/plugin.ts
generated
vendored
Normal file
130
node_modules/tom-select/src/plugins/checkbox_options/plugin.ts
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* Plugin: "checkbox_options" (Tom Select)
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import type TomSelect from '../../tom-select.ts';
|
||||
import { TomTemplate } from '../../types/index.ts';
|
||||
import { preventDefault, hash_key } from '../../utils.ts';
|
||||
import { getDom } from '../../vanilla.ts';
|
||||
import { CBOptions } from './types.ts';
|
||||
|
||||
|
||||
export default function(this:TomSelect, userOptions:CBOptions) {
|
||||
var self = this;
|
||||
var orig_onOptionSelect = self.onOptionSelect;
|
||||
|
||||
self.settings.hideSelected = false;
|
||||
|
||||
const cbOptions : CBOptions = Object.assign({
|
||||
// so that the user may add different ones as well
|
||||
className : "tomselect-checkbox",
|
||||
|
||||
// the following default to the historic plugin's values
|
||||
checkedClassNames : undefined,
|
||||
uncheckedClassNames : undefined,
|
||||
}, userOptions);
|
||||
|
||||
|
||||
var UpdateChecked = function(checkbox:HTMLInputElement, toCheck : boolean) {
|
||||
if( toCheck ){
|
||||
checkbox.checked = true;
|
||||
if (cbOptions.uncheckedClassNames) {
|
||||
checkbox.classList.remove(...cbOptions.uncheckedClassNames);
|
||||
}
|
||||
if (cbOptions.checkedClassNames) {
|
||||
checkbox.classList.add(...cbOptions.checkedClassNames);
|
||||
}
|
||||
}else{
|
||||
checkbox.checked = false;
|
||||
if (cbOptions.checkedClassNames) {
|
||||
checkbox.classList.remove(...cbOptions.checkedClassNames);
|
||||
}
|
||||
if (cbOptions.uncheckedClassNames) {
|
||||
checkbox.classList.add(...cbOptions.uncheckedClassNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update the checkbox for an option
|
||||
var UpdateCheckbox = function(option:HTMLElement){
|
||||
setTimeout(()=>{
|
||||
var checkbox = option.querySelector('input.' + cbOptions.className);
|
||||
if( checkbox instanceof HTMLInputElement ){
|
||||
UpdateChecked(checkbox, option.classList.contains('selected'));
|
||||
}
|
||||
},1);
|
||||
};
|
||||
|
||||
// add checkbox to option template
|
||||
self.hook('after','setupTemplates',() => {
|
||||
|
||||
var orig_render_option = self.settings.render.option;
|
||||
|
||||
self.settings.render.option = ((data, escape_html) => {
|
||||
var rendered = getDom(orig_render_option.call(self, data, escape_html));
|
||||
var checkbox = document.createElement('input');
|
||||
if (cbOptions.className) {
|
||||
checkbox.classList.add(cbOptions.className);
|
||||
}
|
||||
checkbox.addEventListener('click',function(evt){
|
||||
preventDefault(evt);
|
||||
});
|
||||
|
||||
checkbox.type = 'checkbox';
|
||||
const hashed = hash_key(data[self.settings.valueField]);
|
||||
|
||||
UpdateChecked(checkbox, !!(hashed && self.items.indexOf(hashed) > -1) );
|
||||
|
||||
rendered.prepend(checkbox);
|
||||
return rendered;
|
||||
}) satisfies TomTemplate;
|
||||
});
|
||||
|
||||
// uncheck when item removed
|
||||
self.on('item_remove',(value:string) => {
|
||||
var option = self.getOption(value);
|
||||
|
||||
if( option ){ // if dropdown hasn't been opened yet, the option won't exist
|
||||
option.classList.remove('selected'); // selected class won't be removed yet
|
||||
UpdateCheckbox(option);
|
||||
}
|
||||
});
|
||||
|
||||
// check when item added
|
||||
self.on('item_add',(value:string) => {
|
||||
var option = self.getOption(value);
|
||||
|
||||
if( option ){ // if dropdown hasn't been opened yet, the option won't exist
|
||||
UpdateCheckbox(option);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// remove items when selected option is clicked
|
||||
self.hook('instead','onOptionSelect',( evt:KeyboardEvent, option:HTMLElement )=>{
|
||||
|
||||
if( option.classList.contains('selected') ){
|
||||
option.classList.remove('selected')
|
||||
self.removeItem(option.dataset.value);
|
||||
self.refreshOptions();
|
||||
preventDefault(evt,true);
|
||||
return;
|
||||
}
|
||||
|
||||
orig_onOptionSelect.call(self, evt, option);
|
||||
|
||||
UpdateCheckbox(option);
|
||||
});
|
||||
|
||||
};
|
||||
15
node_modules/tom-select/src/plugins/checkbox_options/types.ts
generated
vendored
Normal file
15
node_modules/tom-select/src/plugins/checkbox_options/types.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
export type CBOptions = {
|
||||
/**
|
||||
* a unique class name for the checkbox to find the input
|
||||
*/
|
||||
className ?: string;
|
||||
/**
|
||||
* class name to add if checkbox is checked and remove otherwise
|
||||
*/
|
||||
checkedClassNames ?: string[],
|
||||
/**
|
||||
* class name to add if checkbox was not checked and remove otherwise
|
||||
*/
|
||||
uncheckedClassNames ?: string[],
|
||||
};
|
||||
33
node_modules/tom-select/src/plugins/clear_button/plugin.scss
generated
vendored
Normal file
33
node_modules/tom-select/src/plugins/clear_button/plugin.scss
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/* stylelint-disable function-name-case */
|
||||
|
||||
.plugin-clear_button {
|
||||
--ts-pr-clear-button: 1em;
|
||||
|
||||
.clear-button{
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
right: calc(#{$select-padding-x} - #{$select-padding-item-x});
|
||||
margin-right: 0 !important;
|
||||
background: transparent !important;
|
||||
transition: opacity 0.5s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.form-select .clear-button,
|
||||
&.single .clear-button {
|
||||
|
||||
@if variable-exists(select-padding-dropdown-item-x) {
|
||||
right: Max(var(--ts-pr-caret), #{$select-padding-dropdown-item-x});
|
||||
}
|
||||
@else{
|
||||
right: Max(var(--ts-pr-caret), calc(#{$select-padding-x} - #{$select-padding-item-x}));
|
||||
}
|
||||
}
|
||||
|
||||
&.focus.has-items .clear-button,
|
||||
&:not(.disabled):hover.has-items .clear-button{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
49
node_modules/tom-select/src/plugins/clear_button/plugin.ts
generated
vendored
Normal file
49
node_modules/tom-select/src/plugins/clear_button/plugin.ts
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Plugin: "dropdown_header" (Tom Select)
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import type TomSelect from '../../tom-select.ts';
|
||||
import { getDom } from '../../vanilla.ts';
|
||||
import { CBOptions } from './types.ts';
|
||||
|
||||
export default function(this:TomSelect, userOptions:CBOptions) {
|
||||
const self = this;
|
||||
|
||||
const options = Object.assign({
|
||||
className: 'clear-button',
|
||||
title: 'Clear All',
|
||||
html: (data:CBOptions) => {
|
||||
return `<div class="${data.className}" title="${data.title}">⨯</div>`;
|
||||
}
|
||||
}, userOptions);
|
||||
|
||||
self.on('initialize',()=>{
|
||||
var button = getDom(options.html(options));
|
||||
button.addEventListener('click',(evt)=>{
|
||||
|
||||
if( self.isLocked ) return;
|
||||
|
||||
self.clear();
|
||||
|
||||
if( self.settings.mode === 'single' && self.settings.allowEmptyOption ){
|
||||
self.addItem('');
|
||||
}
|
||||
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
});
|
||||
self.control.appendChild(button);
|
||||
});
|
||||
|
||||
};
|
||||
6
node_modules/tom-select/src/plugins/clear_button/types.ts
generated
vendored
Normal file
6
node_modules/tom-select/src/plugins/clear_button/types.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
export type CBOptions = {
|
||||
className ?:string,
|
||||
title ?:string,
|
||||
html ?: (data:CBOptions) => string,
|
||||
}
|
||||
10
node_modules/tom-select/src/plugins/drag_drop/plugin.scss
generated
vendored
Normal file
10
node_modules/tom-select/src/plugins/drag_drop/plugin.scss
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
.#{$select-ns}-wrapper.plugin-drag_drop {
|
||||
.ts-dragging{
|
||||
color:transparent !important;
|
||||
}
|
||||
|
||||
.ts-dragging > * {
|
||||
visibility:hidden !important;
|
||||
}
|
||||
|
||||
}
|
||||
143
node_modules/tom-select/src/plugins/drag_drop/plugin.ts
generated
vendored
Normal file
143
node_modules/tom-select/src/plugins/drag_drop/plugin.ts
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* Plugin: "drag_drop" (Tom Select)
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import type TomSelect from '../../tom-select.ts';
|
||||
import { TomOption, TomItem } from '../../types/index.ts';
|
||||
import { escape_html, preventDefault, addEvent } from '../../utils.ts';
|
||||
import { getDom, setAttr } from '../../vanilla.ts';
|
||||
|
||||
|
||||
const insertAfter = (referenceNode:Element, newNode:Element) => {
|
||||
referenceNode.parentNode?.insertBefore(newNode, referenceNode.nextSibling);
|
||||
}
|
||||
|
||||
const insertBefore = (referenceNode:Element, newNode:Element) => {
|
||||
referenceNode.parentNode?.insertBefore(newNode, referenceNode);
|
||||
}
|
||||
|
||||
const isBefore = (referenceNode:Element|undefined|null, newNode:Element|undefined|null) =>{
|
||||
|
||||
do{
|
||||
newNode = newNode?.previousElementSibling;
|
||||
|
||||
if( referenceNode == newNode ){
|
||||
return true;
|
||||
}
|
||||
|
||||
}while( newNode && newNode.previousElementSibling );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export default function(this:TomSelect) {
|
||||
var self = this;
|
||||
if (self.settings.mode !== 'multi') return;
|
||||
|
||||
var orig_lock = self.lock;
|
||||
var orig_unlock = self.unlock;
|
||||
let sortable = true;
|
||||
let drag_item:TomItem|undefined;
|
||||
|
||||
|
||||
/**
|
||||
* Add draggable attribute to item
|
||||
*/
|
||||
self.hook('after','setupTemplates',() => {
|
||||
|
||||
var orig_render_item = self.settings.render.item;
|
||||
|
||||
self.settings.render.item = (data:TomOption, escape:typeof escape_html) => {
|
||||
const item = getDom(orig_render_item.call(self, data, escape)) as TomItem;
|
||||
setAttr(item,{'draggable':'true'});
|
||||
|
||||
|
||||
// prevent doc_mousedown (see tom-select.ts)
|
||||
const mousedown = (evt:Event) => {
|
||||
if( !sortable ) preventDefault(evt);
|
||||
evt.stopPropagation();
|
||||
}
|
||||
|
||||
const dragStart = (evt:Event) => {
|
||||
drag_item = item;
|
||||
|
||||
setTimeout(() => {
|
||||
item.classList.add('ts-dragging');
|
||||
}, 0);
|
||||
|
||||
}
|
||||
|
||||
const dragOver = (evt:Event) =>{
|
||||
evt.preventDefault();
|
||||
item.classList.add('ts-drag-over');
|
||||
moveitem(item,drag_item);
|
||||
}
|
||||
|
||||
const dragLeave = () => {
|
||||
item.classList.remove('ts-drag-over');
|
||||
}
|
||||
|
||||
const moveitem = (targetitem:TomItem, dragitem:TomItem|undefined) => {
|
||||
if( dragitem === undefined ) return;
|
||||
|
||||
if( isBefore(dragitem,item) ){
|
||||
insertAfter(targetitem,dragitem);
|
||||
}else{
|
||||
insertBefore(targetitem,dragitem);
|
||||
}
|
||||
}
|
||||
|
||||
const dragend = () => {
|
||||
document.querySelectorAll('.ts-drag-over').forEach(el=> el.classList.remove('ts-drag-over'));
|
||||
drag_item?.classList.remove('ts-dragging');
|
||||
drag_item = undefined;
|
||||
|
||||
var values:string[] = [];
|
||||
self.control.querySelectorAll(`[data-value]`).forEach((el:Element)=> {
|
||||
if( (<HTMLOptionElement>el).dataset.value ){
|
||||
let value = (<HTMLOptionElement>el).dataset.value;
|
||||
if( value ){
|
||||
values.push(value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
self.setValue(values);
|
||||
}
|
||||
|
||||
|
||||
addEvent(item,'mousedown', mousedown);
|
||||
addEvent(item,'dragstart', dragStart);
|
||||
addEvent(item,'dragenter', dragOver)
|
||||
addEvent(item,'dragover', dragOver);
|
||||
addEvent(item,'dragleave', dragLeave);
|
||||
addEvent(item,'dragend', dragend);
|
||||
|
||||
return item;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
self.hook('instead','lock',()=>{
|
||||
sortable = false;
|
||||
return orig_lock.call(self);
|
||||
});
|
||||
|
||||
self.hook('instead','unlock',()=>{
|
||||
sortable = true;
|
||||
return orig_unlock.call(self);
|
||||
});
|
||||
|
||||
};
|
||||
24
node_modules/tom-select/src/plugins/dropdown_header/plugin.scss
generated
vendored
Normal file
24
node_modules/tom-select/src/plugins/dropdown_header/plugin.scss
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
.#{$select-ns}-wrapper{
|
||||
.dropdown-header {
|
||||
position: relative;
|
||||
padding: ($select-padding-dropdown-item-y * 2) $select-padding-dropdown-item-x;
|
||||
border-bottom: 1px solid $select-color-border;
|
||||
background: color-mix($select-color-dropdown, $select-color-border, 85%);
|
||||
border-radius: $select-border-radius $select-border-radius 0 0;
|
||||
}
|
||||
|
||||
.dropdown-header-close {
|
||||
position: absolute;
|
||||
right: $select-padding-dropdown-item-x;
|
||||
top: 50%;
|
||||
color: $select-color-text;
|
||||
opacity: 0.4;
|
||||
margin-top: -12px;
|
||||
line-height: 20px;
|
||||
font-size: 20px !important;
|
||||
}
|
||||
|
||||
.dropdown-header-close:hover {
|
||||
color: darken($select-color-text, 25%);
|
||||
}
|
||||
}
|
||||
57
node_modules/tom-select/src/plugins/dropdown_header/plugin.ts
generated
vendored
Normal file
57
node_modules/tom-select/src/plugins/dropdown_header/plugin.ts
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Plugin: "dropdown_header" (Tom Select)
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import type TomSelect from '../../tom-select.ts';
|
||||
import { getDom } from '../../vanilla.ts';
|
||||
import { preventDefault } from '../../utils.ts';
|
||||
import { DHOptions } from './types.ts';
|
||||
|
||||
export default function(this:TomSelect, userOptions:DHOptions) {
|
||||
const self = this;
|
||||
|
||||
const options = Object.assign({
|
||||
title : 'Untitled',
|
||||
headerClass : 'dropdown-header',
|
||||
titleRowClass : 'dropdown-header-title',
|
||||
labelClass : 'dropdown-header-label',
|
||||
closeClass : 'dropdown-header-close',
|
||||
|
||||
html: (data:DHOptions) => {
|
||||
return (
|
||||
'<div class="' + data.headerClass + '">' +
|
||||
'<div class="' + data.titleRowClass + '">' +
|
||||
'<span class="' + data.labelClass + '">' + data.title + '</span>' +
|
||||
'<a class="' + data.closeClass + '">×</a>' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
}, userOptions);
|
||||
|
||||
self.on('initialize',()=>{
|
||||
var header = getDom(options.html(options));
|
||||
|
||||
var close_link = header.querySelector('.'+options.closeClass);
|
||||
if( close_link ){
|
||||
close_link.addEventListener('click',(evt)=>{
|
||||
preventDefault(evt,true);
|
||||
self.close();
|
||||
});
|
||||
}
|
||||
|
||||
self.dropdown.insertBefore(header, self.dropdown.firstChild);
|
||||
});
|
||||
|
||||
};
|
||||
9
node_modules/tom-select/src/plugins/dropdown_header/types.ts
generated
vendored
Normal file
9
node_modules/tom-select/src/plugins/dropdown_header/types.ts
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
export type DHOptions = {
|
||||
title ?: string,
|
||||
headerClass ?: string,
|
||||
titleRowClass ?: string,
|
||||
labelClass ?: string,
|
||||
closeClass ?: string,
|
||||
html ?: (data:DHOptions) => string,
|
||||
};
|
||||
43
node_modules/tom-select/src/plugins/dropdown_input/plugin.scss
generated
vendored
Normal file
43
node_modules/tom-select/src/plugins/dropdown_input/plugin.scss
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
.plugin-dropdown_input{
|
||||
|
||||
&.focus.dropdown-active .#{$select-ns}-control{
|
||||
box-shadow: none;
|
||||
border: $select-border;
|
||||
@if variable-exists(input-box-shadow) {
|
||||
box-shadow: $input-box-shadow;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-input {
|
||||
border: 1px solid $select-color-border;
|
||||
border-width: 0 0 1px;
|
||||
display: block;
|
||||
padding: $select-padding-y $select-padding-x;
|
||||
box-shadow: $select-shadow-input;
|
||||
width: 100%;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&.focus .#{$select-ns}-dropdown .dropdown-input{
|
||||
@if variable-exists(input-focus-border-color) {
|
||||
border-color: $input-focus-border-color;
|
||||
outline: 0;
|
||||
@if $enable-shadows {
|
||||
box-shadow: $input-box-shadow, $input-focus-box-shadow;
|
||||
} @else {
|
||||
box-shadow: $input-focus-box-shadow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.items-placeholder{
|
||||
border: 0 none !important;
|
||||
box-shadow: none !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&.has-items .items-placeholder,
|
||||
&.dropdown-active .items-placeholder{
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
92
node_modules/tom-select/src/plugins/dropdown_input/plugin.ts
generated
vendored
Normal file
92
node_modules/tom-select/src/plugins/dropdown_input/plugin.ts
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Plugin: "dropdown_input" (Tom Select)
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import type TomSelect from '../../tom-select.ts';
|
||||
import * as constants from '../../constants.ts';
|
||||
import { getDom, addClasses } from '../../vanilla.ts';
|
||||
import { addEvent, preventDefault } from '../../utils.ts';
|
||||
|
||||
|
||||
export default function(this:TomSelect) {
|
||||
const self = this;
|
||||
|
||||
self.settings.shouldOpen = true; // make sure the input is shown even if there are no options to display in the dropdown
|
||||
|
||||
self.hook('before','setup',()=>{
|
||||
self.focus_node = self.control;
|
||||
|
||||
addClasses( self.control_input, 'dropdown-input');
|
||||
|
||||
const div = getDom('<div class="dropdown-input-wrap">');
|
||||
div.append(self.control_input);
|
||||
self.dropdown.insertBefore(div, self.dropdown.firstChild);
|
||||
|
||||
// set a placeholder in the select control
|
||||
const placeholder = getDom('<input class="items-placeholder" tabindex="-1" />') as HTMLInputElement;
|
||||
placeholder.placeholder = self.settings.placeholder ||'';
|
||||
self.control.append(placeholder);
|
||||
|
||||
});
|
||||
|
||||
|
||||
self.on('initialize',()=>{
|
||||
|
||||
// set tabIndex on control to -1, otherwise [shift+tab] will put focus right back on control_input
|
||||
self.control_input.addEventListener('keydown',(evt:KeyboardEvent) =>{
|
||||
//addEvent(self.control_input,'keydown' as const,(evt:KeyboardEvent) =>{
|
||||
switch( evt.keyCode ){
|
||||
case constants.KEY_ESC:
|
||||
if (self.isOpen) {
|
||||
preventDefault(evt,true);
|
||||
self.close();
|
||||
}
|
||||
self.clearActiveItems();
|
||||
return;
|
||||
case constants.KEY_TAB:
|
||||
self.focus_node.tabIndex = -1;
|
||||
break;
|
||||
}
|
||||
return self.onKeyDown.call(self,evt);
|
||||
});
|
||||
|
||||
self.on('blur',()=>{
|
||||
self.focus_node.tabIndex = self.isDisabled ? -1 : self.tabIndex;
|
||||
});
|
||||
|
||||
|
||||
// give the control_input focus when the dropdown is open
|
||||
self.on('dropdown_open',() =>{
|
||||
self.control_input.focus();
|
||||
});
|
||||
|
||||
// prevent onBlur from closing when focus is on the control_input
|
||||
const orig_onBlur = self.onBlur;
|
||||
self.hook('instead','onBlur',(evt?:FocusEvent)=>{
|
||||
if( evt && evt.relatedTarget == self.control_input ) return;
|
||||
return orig_onBlur.call(self);
|
||||
});
|
||||
|
||||
addEvent(self.control_input,'blur', () => self.onBlur() );
|
||||
|
||||
// return focus to control to allow further keyboard input
|
||||
self.hook('before','close',() =>{
|
||||
|
||||
if( !self.isOpen ) return;
|
||||
self.focus_node.focus({preventScroll: true});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
15
node_modules/tom-select/src/plugins/input_autogrow/plugin.scss
generated
vendored
Normal file
15
node_modules/tom-select/src/plugins/input_autogrow/plugin.scss
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
.#{$select-ns}-wrapper.plugin-input_autogrow{
|
||||
|
||||
&.has-items .#{$select-ns}-control > input {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
&.has-items.focus .#{$select-ns}-control > input {
|
||||
flex: none;
|
||||
min-width: 4px;
|
||||
|
||||
&::placeholder {
|
||||
color:transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
56
node_modules/tom-select/src/plugins/input_autogrow/plugin.ts
generated
vendored
Normal file
56
node_modules/tom-select/src/plugins/input_autogrow/plugin.ts
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Plugin: "input_autogrow" (Tom Select)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import type TomSelect from '../../tom-select.ts';
|
||||
import { addEvent } from '../../utils.ts';
|
||||
|
||||
export default function(this:TomSelect) {
|
||||
var self = this;
|
||||
|
||||
self.on('initialize',()=>{
|
||||
|
||||
|
||||
var test_input = document.createElement('span');
|
||||
var control = self.control_input;
|
||||
test_input.style.cssText = 'position:absolute; top:-99999px; left:-99999px; width:auto; padding:0; white-space:pre; ';
|
||||
|
||||
self.wrapper.appendChild(test_input);
|
||||
|
||||
|
||||
var transfer_styles = [ 'letterSpacing', 'fontSize', 'fontFamily', 'fontWeight', 'textTransform' ];
|
||||
|
||||
for( const style_name of transfer_styles ){
|
||||
// @ts-ignore TS7015 https://stackoverflow.com/a/50506154/697576
|
||||
test_input.style[style_name] = control.style[style_name];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the control width
|
||||
*
|
||||
*/
|
||||
var resize = ()=>{
|
||||
test_input.textContent = control.value;
|
||||
control.style.width = test_input.clientWidth+'px';
|
||||
};
|
||||
|
||||
resize();
|
||||
self.on('update item_add item_remove',resize);
|
||||
addEvent(control,'input', resize );
|
||||
addEvent(control,'keyup', resize );
|
||||
addEvent(control,'blur', resize );
|
||||
addEvent(control,'update', resize );
|
||||
});
|
||||
|
||||
};
|
||||
20
node_modules/tom-select/src/plugins/no_active_items/plugin.ts
generated
vendored
Normal file
20
node_modules/tom-select/src/plugins/no_active_items/plugin.ts
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Plugin: "no_active_items" (Tom Select)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import type TomSelect from '../../tom-select.ts';
|
||||
|
||||
export default function(this:TomSelect) {
|
||||
this.hook('instead','setActiveItem',() => {});
|
||||
this.hook('instead','selectAll',() => {});
|
||||
};
|
||||
30
node_modules/tom-select/src/plugins/no_backspace_delete/plugin.ts
generated
vendored
Normal file
30
node_modules/tom-select/src/plugins/no_backspace_delete/plugin.ts
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Plugin: "input_autogrow" (Tom Select)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import type TomSelect from '../../tom-select.ts';
|
||||
|
||||
export default function(this:TomSelect) {
|
||||
var self = this;
|
||||
var orig_deleteSelection = self.deleteSelection;
|
||||
|
||||
this.hook('instead','deleteSelection',(evt:KeyboardEvent) => {
|
||||
|
||||
if( self.activeItems.length ){
|
||||
return orig_deleteSelection.call(self, evt);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
};
|
||||
25
node_modules/tom-select/src/plugins/optgroup_columns/plugin.scss
generated
vendored
Normal file
25
node_modules/tom-select/src/plugins/optgroup_columns/plugin.scss
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
.#{$select-ns}-dropdown.plugin-optgroup_columns {
|
||||
.ts-dropdown-content{
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.optgroup {
|
||||
border-right: 1px solid #f2f2f2;
|
||||
border-top: 0 none;
|
||||
flex-grow: 1;
|
||||
flex-basis: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.optgroup:last-child {
|
||||
border-right: 0 none;
|
||||
}
|
||||
|
||||
.optgroup::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.optgroup-header {
|
||||
border-top: 0 none;
|
||||
}
|
||||
}
|
||||
59
node_modules/tom-select/src/plugins/optgroup_columns/plugin.ts
generated
vendored
Normal file
59
node_modules/tom-select/src/plugins/optgroup_columns/plugin.ts
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Plugin: "optgroup_columns" (Tom Select.js)
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import type TomSelect from '../../tom-select.ts';
|
||||
import * as constants from '../../constants.ts';
|
||||
import { parentMatch, nodeIndex } from '../../vanilla.ts';
|
||||
|
||||
export default function(this:TomSelect) {
|
||||
var self = this;
|
||||
|
||||
var orig_keydown = self.onKeyDown;
|
||||
|
||||
self.hook('instead','onKeyDown',(evt:KeyboardEvent)=>{
|
||||
var index, option, options, optgroup;
|
||||
|
||||
if( !self.isOpen || !(evt.keyCode === constants.KEY_LEFT || evt.keyCode === constants.KEY_RIGHT)) {
|
||||
return orig_keydown.call(self,evt);
|
||||
}
|
||||
|
||||
self.ignoreHover = true;
|
||||
optgroup = parentMatch(self.activeOption,'[data-group]');
|
||||
index = nodeIndex(self.activeOption,'[data-selectable]');
|
||||
|
||||
if( !optgroup ){
|
||||
return;
|
||||
}
|
||||
|
||||
if( evt.keyCode === constants.KEY_LEFT ){
|
||||
optgroup = optgroup.previousSibling;
|
||||
} else {
|
||||
optgroup = optgroup.nextSibling;
|
||||
}
|
||||
|
||||
if( !optgroup ){
|
||||
return;
|
||||
}
|
||||
|
||||
options = (<HTMLOptGroupElement>optgroup).querySelectorAll('[data-selectable]');
|
||||
option = options[ Math.min(options.length - 1, index) ] as HTMLElement;
|
||||
|
||||
if( option ){
|
||||
self.setActiveOption(option);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
70
node_modules/tom-select/src/plugins/remove_button/plugin.scss
generated
vendored
Normal file
70
node_modules/tom-select/src/plugins/remove_button/plugin.scss
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
.#{$select-ns}-wrapper.plugin-remove_button{
|
||||
.item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.item .remove {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
padding: 0 $select-padding-item-x;
|
||||
border-radius: 0 2px 2px 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.item .remove:hover {
|
||||
background: rgba(0, 0, 0, 5%);
|
||||
}
|
||||
|
||||
&.disabled .item .remove:hover {
|
||||
background: none;
|
||||
}
|
||||
|
||||
|
||||
.remove-single {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
font-size: 23px;
|
||||
}
|
||||
}
|
||||
|
||||
.#{$select-ns}-wrapper.plugin-remove_button:not(.rtl){
|
||||
.item {
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
.item .remove {
|
||||
border-left: 1px solid $select-color-item-border;
|
||||
margin-left: $select-padding-item-x;
|
||||
}
|
||||
|
||||
.item.active .remove {
|
||||
border-left-color: $select-color-item-active-border;
|
||||
}
|
||||
|
||||
&.disabled .item .remove {
|
||||
border-left-color: lighten(desaturate($select-color-item-border, 100%), $select-lighten-disabled-item-border);
|
||||
}
|
||||
}
|
||||
|
||||
.#{$select-ns}-wrapper.plugin-remove_button.rtl {
|
||||
.item {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
.item .remove {
|
||||
border-right: 1px solid $select-color-item-border;
|
||||
margin-right: $select-padding-item-x;
|
||||
}
|
||||
|
||||
.item.active .remove {
|
||||
border-right-color: $select-color-item-active-border;
|
||||
}
|
||||
|
||||
&.disabled .item .remove {
|
||||
border-right-color: lighten(desaturate($select-color-item-border, 100%), $select-lighten-disabled-item-border);
|
||||
}
|
||||
}
|
||||
78
node_modules/tom-select/src/plugins/remove_button/plugin.ts
generated
vendored
Normal file
78
node_modules/tom-select/src/plugins/remove_button/plugin.ts
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Plugin: "remove_button" (Tom Select)
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import type TomSelect from '../../tom-select.ts';
|
||||
import { getDom } from '../../vanilla.ts';
|
||||
import { escape_html, preventDefault, addEvent } from '../../utils.ts';
|
||||
import { TomOption, TomItem } from '../../types/index.ts';
|
||||
import { RBOptions } from './types.ts';
|
||||
|
||||
export default function(this:TomSelect, userOptions:RBOptions) {
|
||||
|
||||
const options = Object.assign({
|
||||
label : '×',
|
||||
title : 'Remove',
|
||||
className : 'remove',
|
||||
append : true
|
||||
}, userOptions);
|
||||
|
||||
|
||||
//options.className = 'remove-single';
|
||||
var self = this;
|
||||
|
||||
// override the render method to add remove button to each item
|
||||
if( !options.append ){
|
||||
return;
|
||||
}
|
||||
|
||||
var html = '<a href="javascript:void(0)" class="' + options.className + '" tabindex="-1" title="' + escape_html(options.title) + '">' + options.label + '</a>';
|
||||
|
||||
self.hook('after','setupTemplates',() => {
|
||||
|
||||
var orig_render_item = self.settings.render.item;
|
||||
|
||||
self.settings.render.item = (data:TomOption, escape:typeof escape_html) => {
|
||||
|
||||
var item = getDom(orig_render_item.call(self, data, escape)) as TomItem;
|
||||
|
||||
var close_button = getDom(html);
|
||||
item.appendChild(close_button);
|
||||
|
||||
addEvent(close_button,'mousedown',(evt) => {
|
||||
preventDefault(evt,true);
|
||||
});
|
||||
|
||||
addEvent(close_button,'click',(evt) => {
|
||||
|
||||
if( self.isLocked ) return;
|
||||
|
||||
// propagating will trigger the dropdown to show for single mode
|
||||
preventDefault(evt,true);
|
||||
|
||||
if( self.isLocked ) return;
|
||||
if( !self.shouldDelete([item],evt as MouseEvent) ) return;
|
||||
|
||||
self.removeItem(item);
|
||||
self.refreshOptions(false);
|
||||
self.inputState();
|
||||
});
|
||||
|
||||
return item;
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
7
node_modules/tom-select/src/plugins/remove_button/types.ts
generated
vendored
Normal file
7
node_modules/tom-select/src/plugins/remove_button/types.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
export type RBOptions = {
|
||||
label ?: string,
|
||||
title ?: string,
|
||||
className ?: string,
|
||||
append ?: boolean
|
||||
};
|
||||
44
node_modules/tom-select/src/plugins/restore_on_backspace/plugin.ts
generated
vendored
Normal file
44
node_modules/tom-select/src/plugins/restore_on_backspace/plugin.ts
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Plugin: "restore_on_backspace" (Tom Select)
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
import type TomSelect from '../../tom-select.ts';
|
||||
import { TomOption } from '../../types/index.ts';
|
||||
|
||||
type TPluginOptions = {
|
||||
text?:(option:TomOption)=>string,
|
||||
};
|
||||
|
||||
export default function(this:TomSelect, userOptions:TPluginOptions) {
|
||||
const self = this;
|
||||
|
||||
const options = Object.assign({
|
||||
text: (option:TomOption) => {
|
||||
return option[self.settings.labelField];
|
||||
}
|
||||
},userOptions);
|
||||
|
||||
self.on('item_remove',function(value:string){
|
||||
if( !self.isFocused ){
|
||||
return;
|
||||
}
|
||||
|
||||
if( self.control_input.value.trim() === '' ){
|
||||
var option = self.options[value];
|
||||
if( option ){
|
||||
self.setTextboxValue(options.text.call(self, option));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
219
node_modules/tom-select/src/plugins/virtual_scroll/plugin.ts
generated
vendored
Normal file
219
node_modules/tom-select/src/plugins/virtual_scroll/plugin.ts
generated
vendored
Normal file
@@ -0,0 +1,219 @@
|
||||
/**
|
||||
* Plugin: "restore_on_backspace" (Tom Select)
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import type TomSelect from '../../tom-select.ts';
|
||||
import { TomOption } from '../../types/index.ts';
|
||||
import { addClasses } from '../../vanilla.ts';
|
||||
|
||||
export default function(this:TomSelect) {
|
||||
const self = this;
|
||||
const orig_canLoad = self.canLoad;
|
||||
const orig_clearActiveOption = self.clearActiveOption;
|
||||
const orig_loadCallback = self.loadCallback;
|
||||
|
||||
var pagination:{[key:string]:any} = {};
|
||||
var dropdown_content:HTMLElement;
|
||||
var loading_more = false;
|
||||
var load_more_opt:HTMLElement;
|
||||
var default_values: string[] = [];
|
||||
|
||||
if( !self.settings.shouldLoadMore ){
|
||||
|
||||
// return true if additional results should be loaded
|
||||
self.settings.shouldLoadMore = ():boolean=>{
|
||||
|
||||
const scroll_percent = dropdown_content.clientHeight / (dropdown_content.scrollHeight - dropdown_content.scrollTop);
|
||||
if( scroll_percent > 0.9 ){
|
||||
return true;
|
||||
}
|
||||
|
||||
if( self.activeOption ){
|
||||
var selectable = self.selectable();
|
||||
var index = Array.from(selectable).indexOf(self.activeOption);
|
||||
if( index >= (selectable.length-2) ){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( !self.settings.firstUrl ){
|
||||
throw 'virtual_scroll plugin requires a firstUrl() method';
|
||||
}
|
||||
|
||||
|
||||
// in order for virtual scrolling to work,
|
||||
// options need to be ordered the same way they're returned from the remote data source
|
||||
self.settings.sortField = [{field:'$order'},{field:'$score'}];
|
||||
|
||||
|
||||
// can we load more results for given query?
|
||||
const canLoadMore = (query:string):boolean => {
|
||||
|
||||
if( typeof self.settings.maxOptions === 'number' && dropdown_content.children.length >= self.settings.maxOptions ){
|
||||
return false;
|
||||
}
|
||||
|
||||
if( (query in pagination) && pagination[query] ){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
const clearFilter = (option:TomOption, value:string):boolean => {
|
||||
if( self.items.indexOf(value) >= 0 || default_values.indexOf(value) >= 0 ){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
// set the next url that will be
|
||||
self.setNextUrl = (value:string,next_url:any):void => {
|
||||
pagination[value] = next_url;
|
||||
};
|
||||
|
||||
// getUrl() to be used in settings.load()
|
||||
self.getUrl = (query:string):any =>{
|
||||
|
||||
if( query in pagination ){
|
||||
const next_url = pagination[query];
|
||||
pagination[query] = false;
|
||||
return next_url;
|
||||
}
|
||||
|
||||
// if the user goes back to a previous query
|
||||
// we need to load the first page again
|
||||
self.clearPagination();
|
||||
|
||||
return self.settings.firstUrl.call(self,query);
|
||||
};
|
||||
|
||||
// clear pagination
|
||||
self.clearPagination = ():void =>{
|
||||
pagination = {};
|
||||
};
|
||||
|
||||
// don't clear the active option (and cause unwanted dropdown scroll)
|
||||
// while loading more results
|
||||
self.hook('instead','clearActiveOption',()=>{
|
||||
|
||||
if( loading_more ){
|
||||
return;
|
||||
}
|
||||
|
||||
return orig_clearActiveOption.call(self);
|
||||
});
|
||||
|
||||
// override the canLoad method
|
||||
self.hook('instead','canLoad',(query:string)=>{
|
||||
|
||||
// first time the query has been seen
|
||||
if( !(query in pagination) ){
|
||||
return orig_canLoad.call(self,query);
|
||||
}
|
||||
|
||||
return canLoadMore(query);
|
||||
});
|
||||
|
||||
|
||||
// wrap the load
|
||||
self.hook('instead','loadCallback',( options:TomOption[], optgroups:TomOption[])=>{
|
||||
|
||||
if( !loading_more ){
|
||||
self.clearOptions(clearFilter);
|
||||
}else if( load_more_opt ){
|
||||
const first_option = options[0];
|
||||
if( first_option !== undefined ){
|
||||
load_more_opt.dataset.value = first_option[self.settings.valueField];
|
||||
}
|
||||
}
|
||||
|
||||
orig_loadCallback.call( self, options, optgroups);
|
||||
|
||||
loading_more = false;
|
||||
});
|
||||
|
||||
|
||||
// add templates to dropdown
|
||||
// loading_more if we have another url in the queue
|
||||
// no_more_results if we don't have another url in the queue
|
||||
self.hook('after','refreshOptions',()=>{
|
||||
|
||||
const query = self.lastValue;
|
||||
var option;
|
||||
|
||||
if( canLoadMore(query) ){
|
||||
|
||||
option = self.render('loading_more',{query:query});
|
||||
if( option ){
|
||||
option.setAttribute('data-selectable',''); // so that navigating dropdown with [down] keypresses can navigate to this node
|
||||
load_more_opt = option;
|
||||
}
|
||||
|
||||
}else if( (query in pagination) && !dropdown_content.querySelector('.no-results') ){
|
||||
option = self.render('no_more_results',{query:query});
|
||||
}
|
||||
|
||||
if( option ){
|
||||
addClasses(option,self.settings.optionClass);
|
||||
dropdown_content.append( option );
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
// add scroll listener and default templates
|
||||
self.on('initialize',()=>{
|
||||
default_values = Object.keys(self.options);
|
||||
dropdown_content = self.dropdown_content;
|
||||
|
||||
// default templates
|
||||
self.settings.render = Object.assign({}, {
|
||||
loading_more:() => {
|
||||
return `<div class="loading-more-results">Loading more results ... </div>`;
|
||||
},
|
||||
no_more_results:() =>{
|
||||
return `<div class="no-more-results">No more results</div>`;
|
||||
}
|
||||
},self.settings.render);
|
||||
|
||||
|
||||
// watch dropdown content scroll position
|
||||
dropdown_content.addEventListener('scroll',()=>{
|
||||
|
||||
if( !self.settings.shouldLoadMore.call(self) ){
|
||||
return;
|
||||
}
|
||||
|
||||
// !important: this will get checked again in load() but we still need to check here otherwise loading_more will be set to true
|
||||
if( !canLoadMore(self.lastValue) ){
|
||||
return;
|
||||
}
|
||||
|
||||
// don't call load() too much
|
||||
if( loading_more ) return;
|
||||
|
||||
|
||||
loading_more = true;
|
||||
self.load.call(self,self.lastValue);
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user