selectic 3.0.5 → 3.0.9
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/selectic.common.js +81 -47
- package/dist/selectic.esm.js +81 -47
- package/package.json +1 -1
- package/src/ExtendedList.tsx +2 -2
- package/src/Filter.tsx +1 -1
- package/src/List.tsx +1 -1
- package/src/MainInput.tsx +1 -1
- package/src/Store.tsx +53 -86
- package/src/index.tsx +9 -7
- package/src/tools.ts +75 -0
- package/test/Store/Store_props.spec.js +33 -0
- package/types/ExtendedList.d.ts +1 -1
- package/types/Filter.d.ts +1 -1
- package/types/List.d.ts +2 -26
- package/types/Store.d.ts +1 -135
- package/types/index.d.ts +1 -1
- package/types/tools.d.ts +21 -0
package/dist/selectic.common.js
CHANGED
|
@@ -35,13 +35,42 @@ function styleInject(css, ref) {
|
|
|
35
35
|
var css_248z = "/* {{{ Variables */\n\n:root {\n --selectic-font-size: 14px;\n --selectic-cursor-disabled: not-allowed;\n\n /* The main element */\n --selectic-color: #555555;\n --selectic-bg: #ffffff;\n\n /* The main element (when disabled) */\n --selectic-color-disabled: #787878;\n --selectic-bg-disabled: #eeeeee;\n\n /* The list */\n --selectic-panel-bg: #f0f0f0;\n --selectic-separator-bordercolor: #cccccc;\n /* --selectic-item-color: var(--selectic-color); /* Can be set in any CSS configuration */\n\n /* The current selected item */\n --selectic-selected-item-color: #428bca;\n\n /* When mouse is over items or by selecting with key arrows */\n --selectic-active-item-color: #ffffff;\n --selectic-active-item-bg: #66afe9;\n\n /* Selected values in main element */\n --selectic-value-bg: #f0f0f0;\n /* --selectic-more-items-bg: var(--selectic-info-bg); /* can be set in any CSS configuration */\n /* --selectic-more-items-color: var(--selectic-info-color); /* can be set in any CSS configuration */\n --selectic-more-items-bg-disabled: #cccccc;\n\n /* Information message */\n --selectic-info-bg: #5bc0de;\n --selectic-info-color: #ffffff;\n\n /* Error message */\n --selectic-error-bg: #b72c29;\n --selectic-error-color: #ffffff;\n\n /* XXX: Currently it is important to keep this size for a correct scroll\n * height estimation */\n --selectic-input-height: 30px;\n}\n\n/* }}} */\n/* {{{ Bootstrap equivalent style */\n\n.selectic .form-control {\n display: block;\n width: 100%;\n height: calc(var(--selectic-input-height) - 2px);\n font-size: var(--selectic-font-size);\n line-height: 1.42857143;\n color: var(--selectic-color);\n background-color: var(--selectic-bg);\n background-image: none;\n border: 1px solid var(--selectic-separator-bordercolor); /* should use a better variable */\n border-radius: 4px;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;\n}\n.selectic .has-feedback {\n position: relative;\n}\n.selectic .has-feedback .form-control {\n padding-right: calc(var(--selectic-input-height) + 4px);\n}\n\n.selectic .form-control-feedback.fa,\n.selectic .form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: calc(var(--selectic-input-height) + 4px);\n height: calc(var(--selectic-input-height) + 4px);\n line-height: var(--selectic-input-height);\n text-align: center;\n pointer-events: none;\n}\n\n.selectic .alert-info {\n background-color: var(--selectic-info-bg);\n color: var(--selectic-info-color);\n}\n\n.selectic .alert-danger {\n background-color: var(--selectic-error-bg);\n color: var(--selectic-error-color);\n}\n\n/* }}} */\n\n.selectic * {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n\n.selectic.form-control {\n display: inline-block;\n padding: 0;\n cursor: pointer;\n border: unset;\n}\n\n.has-feedback .selectic__icon-container.form-control-feedback {\n right: 0;\n}\n\n/* The input which contains the selected value\n * XXX: This input should stay hidden behind other elements, but is \"visible\"\n * (in term of DOM point of view) in order to get and to trigger the `focus`\n * DOM event. */\n.selectic__input-value {\n position: fixed;\n opacity: 0;\n z-index: -1000;\n top: -100px;\n}\n\n/* XXX: .form-control has been added to this selector to improve priority and\n * override some rules of the original .form-control */\n.selectic-input.form-control {\n display: inline-flex;\n justify-content: space-between;\n overflow: hidden;\n width: 100%;\n min-height: var(--selectic-input-height);\n padding-top: 0;\n padding-bottom: 0;\n padding-left: 5px;\n line-height: calc(var(--selectic-input-height) - 4px);\n color: var(--selectic-color);\n}\n\n.selectic-input__reverse-icon {\n align-self: center;\n margin-right: 3px;\n cursor: default;\n}\n.selectic-input__clear-icon {\n align-self: center;\n margin-left: 3px;\n cursor: pointer;\n}\n.selectic-input__clear-icon:hover {\n color: var(--selectic-selected-item-color);\n}\n\n.selectic-input.focused {\n border-bottom-left-radius: 0px;\n border-bottom-right-radius: 0px;\n}\n\n.selectic-input.disabled {\n cursor: var(--selectic-cursor-disabled);\n background-color: var(--selectic-bg-disabled);\n}\n.selectic-input.disabled .more-items {\n\tbackground-color: var(--selectic-more-items-bg-disabled);\n}\n\n.selectic-input__selected-items {\n display: inline-flex;\n flex-wrap: nowrap;\n align-items: center;\n white-space: nowrap;\n}\n\n.selectic-input__selected-items__placeholder {\n font-style: italic;\n opacity: 0.7;\n white-space: nowrap;\n}\n\n.selectic-icon {\n color: var(--selectic-color);\n text-align: center;\n vertical-align: middle;\n}\n\n.selectic__extended-list {\n position: fixed;\n z-index: 2000;\n height: auto;\n background-color: var(--selectic-bg, #ffffff);\n box-shadow: 2px 5px 12px 0px #888888;\n border-radius: 0 0 4px 4px;\n padding: 0;\n min-width: 200px;\n}\n.selectic__extended-list__list-items {\n max-height: calc(var(--selectic-input-height) * 10);\n overflow: auto;\n padding-left: 0;\n}\n\n.selectic-item {\n display: block;\n position: relative;\n box-sizing: border-box;\n padding: 2px 8px;\n color: var(--selectic-item-color, var(--selectic-color));\n min-height: calc(var(--selectic-input-height) - 3px);\n list-style-type: none;\n white-space: nowrap;\n cursor: pointer;\n}\n\n.selectic-item_text {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.selectic-item:not(.selected) .selectic-item_icon {\n opacity: 0;\n}\n\n.selectic-item_text {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.selectic-item__active {\n background-color: var(--selectic-active-item-bg);\n color: var(--selectic-active-item-color);\n}\n.selectic-item__active:not(.selected) .selectic-item_icon {\n opacity: 0.2;\n}\n\n.selectic-item__disabled {\n color: var(--selectic-color-disabled);\n background-color: var(--selectic-bg-disabled);\n}\n\n.selectic-item__is-in-group {\n padding-left: 2em;\n}\n\n.selectic-item__is-group {\n font-weight: bold;\n cursor: default;\n}\n\n.selectic-item.selected {\n color: var(--selectic-selected-item-color);\n}\n.selectic-search-scope {\n color: #e0e0e0;\n left: auto;\n right: 10px;\n}\n\n.selectic__message {\n text-align: center;\n padding: 3px;\n}\n\n.selectic .filter-panel {\n padding: 3px;\n margin-left: 0px;\n margin-right: 0px;\n background-color: var(--selectic-panel-bg);\n border-bottom: 1px solid var(--selectic-separator-bordercolor);\n}\n\n.selectic .panelclosed {\n max-height: 0px;\n transition: max-height 0.3s ease-out;\n overflow: hidden;\n}\n\n.panelopened {\n max-height: 200px;\n transition: max-height 0.3s ease-in;\n overflow: hidden;\n}\n\n.selectic .filter-panel__input {\n padding-left: 0px;\n padding-right: 0px;\n padding-bottom: 10px;\n margin-bottom: 0px;\n}\n.selectic .filter-input {\n height: calc(var(--selectic-input-height) * 0.75);\n}\n\n.selectic .checkbox-filter {\n padding: 5px;\n text-align: center;\n}\n\n.selectic .curtain-handler {\n text-align: center;\n}\n\n.selectic .toggle-selectic {\n margin: 5px;\n padding-left: 0px;\n padding-right: 0px;\n}\n\n.selectic .toggle-boolean-select-all-toggle {\n display: inline;\n margin-right: 15px;\n}\n\n.selectic .toggle-boolean-excluding-toggle {\n display: inline;\n margin-right: 15px;\n}\n\n.selectic .single-value {\n display: grid;\n grid-template: \"value icon\" 1fr / max-content max-content;\n\n padding: 2px;\n padding-left: 5px;\n margin-left: 0;\n margin-right: 5px;\n /* margin top/bottom are mainly to create a gutter in multilines */\n margin-top: 2px;\n margin-bottom: 2px;\n\n border-radius: 3px;\n background-color: var(--selectic-value-bg);\n max-height: calc(var(--selectic-input-height) - 10px);\n max-width: 100%;\n min-width: 30px;\n\n overflow: hidden;\n white-space: nowrap;\n line-height: initial;\n vertical-align: middle;\n}\n\n.selectic .more-items {\n display: inline-block;\n\n padding-left: 5px;\n padding-right: 5px;\n border-radius: 10px;\n\n background-color: var(--selectic-more-items-bg, var(--selectic-info-bg));\n color: var(--selectic-more-items-color, var(--selectic-info-color));\n cursor: help;\n}\n.selectic-input__selected-items__value {\n grid-area: value;\n align-self: center;\n justify-self: normal;\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n}\n\n.selectic-input__selected-items__icon {\n grid-area: icon;\n align-self: center;\n justify-self: center;\n margin-left: 5px;\n}\n.selectic-input__selected-items__icon:hover {\n color: var(--selectic-selected-item-color);\n}\n\n.selectic__label-disabled {\n opacity: 0.5;\n transition: opacity 400ms;\n}\n\n/* XXX: override padding of bootstrap input-sm.\n * This padding introduce a line shift. */\n.selectic.input-sm {\n padding: 0;\n}\n\n/* {{{ overflow multiline */\n\n.selectic--overflow-multiline,\n.selectic--overflow-multiline.form-control,\n.selectic--overflow-multiline .form-control {\n height: unset;\n}\n\n.selectic--overflow-multiline .selectic-input {\n overflow: unset;\n}\n\n.selectic--overflow-multiline .selectic-input__selected-items {\n flex-wrap: wrap;\n}\n\n/* }}} */\n";
|
|
36
36
|
styleInject(css_248z);
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
38
|
+
/**
|
|
39
|
+
* Clone the object and its inner properties.
|
|
40
|
+
* @param obj The object to be clone.
|
|
41
|
+
* @param refs internal reference to object to avoid cyclic references
|
|
42
|
+
* @returns a copy of obj
|
|
42
43
|
*/
|
|
43
|
-
|
|
44
|
-
/*
|
|
44
|
+
function deepClone(obj, refs = new WeakMap()) {
|
|
45
|
+
/* For circular references */
|
|
46
|
+
if (refs.has(obj)) {
|
|
47
|
+
return refs.get(obj);
|
|
48
|
+
}
|
|
49
|
+
if (typeof obj === 'object') {
|
|
50
|
+
if (Array.isArray(obj)) {
|
|
51
|
+
const ref = [];
|
|
52
|
+
refs.set(obj, ref);
|
|
53
|
+
obj.forEach((val, idx) => {
|
|
54
|
+
ref[idx] = deepClone(val, refs);
|
|
55
|
+
});
|
|
56
|
+
return ref;
|
|
57
|
+
}
|
|
58
|
+
if (obj instanceof RegExp) {
|
|
59
|
+
const ref = new RegExp(obj.source, obj.flags);
|
|
60
|
+
refs.set(obj, ref);
|
|
61
|
+
return ref;
|
|
62
|
+
}
|
|
63
|
+
/* This should be an object */
|
|
64
|
+
const ref = {};
|
|
65
|
+
refs.set(obj, ref);
|
|
66
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
67
|
+
ref[key] = deepClone(val, refs);
|
|
68
|
+
}
|
|
69
|
+
return ref;
|
|
70
|
+
}
|
|
71
|
+
/* This should be a primitive */
|
|
72
|
+
return obj;
|
|
73
|
+
}
|
|
45
74
|
/**
|
|
46
75
|
* Escape search string to consider regexp special characters as they
|
|
47
76
|
* are and not like special characters.
|
|
@@ -72,6 +101,12 @@ function assignObject(obj, ...sourceObjects) {
|
|
|
72
101
|
}
|
|
73
102
|
return result;
|
|
74
103
|
}
|
|
104
|
+
|
|
105
|
+
/* File Purpose:
|
|
106
|
+
* It keeps and computes all states at a single place.
|
|
107
|
+
* Every inner components of Selectic should communicate with this file to
|
|
108
|
+
* change or to get states.
|
|
109
|
+
*/
|
|
75
110
|
/* }}} */
|
|
76
111
|
/* {{{ Static */
|
|
77
112
|
function changeTexts$1(texts) {
|
|
@@ -101,6 +136,26 @@ let closePreviousSelectic;
|
|
|
101
136
|
let uid = 0;
|
|
102
137
|
class SelecticStore {
|
|
103
138
|
constructor(props = {}) {
|
|
139
|
+
/* Do not need reactivity */
|
|
140
|
+
this.requestId = 0;
|
|
141
|
+
this._uid = ++uid;
|
|
142
|
+
/* {{{ Props */
|
|
143
|
+
const defaultProps = {
|
|
144
|
+
value: null,
|
|
145
|
+
selectionIsExcluded: false,
|
|
146
|
+
disabled: false,
|
|
147
|
+
options: null,
|
|
148
|
+
childOptions: [],
|
|
149
|
+
groups: [],
|
|
150
|
+
texts: null,
|
|
151
|
+
params: {},
|
|
152
|
+
fetchCallback: null,
|
|
153
|
+
getItemsCallback: null,
|
|
154
|
+
keepOpenWithOtherSelectic: false,
|
|
155
|
+
};
|
|
156
|
+
const propsVal = assignObject(defaultProps, props);
|
|
157
|
+
this.props = vue.reactive(propsVal);
|
|
158
|
+
/* }}} */
|
|
104
159
|
/* {{{ data */
|
|
105
160
|
this.state = vue.reactive({
|
|
106
161
|
multiple: false,
|
|
@@ -141,27 +196,6 @@ class SelecticStore {
|
|
|
141
196
|
automaticClose: false,
|
|
142
197
|
},
|
|
143
198
|
});
|
|
144
|
-
/* Do not need reactivity */
|
|
145
|
-
this.requestId = 0;
|
|
146
|
-
this._uid = ++uid;
|
|
147
|
-
/* {{{ Props */
|
|
148
|
-
const defaultProps = {
|
|
149
|
-
value: null,
|
|
150
|
-
selectionIsExcluded: false,
|
|
151
|
-
disabled: false,
|
|
152
|
-
options: null,
|
|
153
|
-
childOptions: [],
|
|
154
|
-
groups: [],
|
|
155
|
-
texts: null,
|
|
156
|
-
params: {},
|
|
157
|
-
fetchCallback: null,
|
|
158
|
-
getItemsCallback: null,
|
|
159
|
-
keepOpenWithOtherSelectic: false,
|
|
160
|
-
};
|
|
161
|
-
const propsVal = assignObject(defaultProps, props);
|
|
162
|
-
this.props = vue.reactive(propsVal);
|
|
163
|
-
/* }}} */
|
|
164
|
-
/* {{{ data */
|
|
165
199
|
this.data = vue.reactive({
|
|
166
200
|
labels: Object.assign({}, messages),
|
|
167
201
|
itemsPerPage: 10,
|
|
@@ -212,17 +246,17 @@ class SelecticStore {
|
|
|
212
246
|
this.commit('isOpen', false);
|
|
213
247
|
this.buildAllOptions(true);
|
|
214
248
|
this.buildSelectedOptions();
|
|
215
|
-
});
|
|
249
|
+
}, { deep: true });
|
|
216
250
|
vue.watch(() => [this.listOptions, this.elementOptions], () => {
|
|
217
251
|
/* TODO: transform allOptions as a computed properties and this
|
|
218
252
|
* watcher become useless */
|
|
219
253
|
this.buildAllOptions(true);
|
|
220
|
-
});
|
|
254
|
+
}, { deep: true });
|
|
221
255
|
vue.watch(() => this.props.value, () => {
|
|
222
256
|
var _a;
|
|
223
257
|
const value = (_a = this.props.value) !== null && _a !== void 0 ? _a : null;
|
|
224
258
|
this.commit('internalValue', value);
|
|
225
|
-
});
|
|
259
|
+
}, { deep: true });
|
|
226
260
|
vue.watch(() => this.props.selectionIsExcluded, () => {
|
|
227
261
|
this.commit('selectionIsExcluded', this.props.selectionIsExcluded);
|
|
228
262
|
});
|
|
@@ -238,14 +272,14 @@ class SelecticStore {
|
|
|
238
272
|
areAllSelected = this.state.filteredOptions.every((item) => !!(+item.selected ^ selectionIsExcluded));
|
|
239
273
|
}
|
|
240
274
|
this.state.status.areAllSelected = areAllSelected;
|
|
241
|
-
});
|
|
275
|
+
}, { deep: true });
|
|
242
276
|
vue.watch(() => this.state.internalValue, () => {
|
|
243
277
|
this.buildSelectedOptions();
|
|
244
|
-
});
|
|
278
|
+
}, { deep: true });
|
|
245
279
|
vue.watch(() => this.state.allOptions, () => {
|
|
246
280
|
this.checkAutoSelect();
|
|
247
281
|
this.checkAutoDisabled();
|
|
248
|
-
});
|
|
282
|
+
}, { deep: true });
|
|
249
283
|
vue.watch(() => this.state.totalAllOptions, () => {
|
|
250
284
|
this.checkHideFilter();
|
|
251
285
|
});
|
|
@@ -275,8 +309,8 @@ class SelecticStore {
|
|
|
275
309
|
* and ensure convertValue run with correct state */
|
|
276
310
|
assignObject(this.state, {
|
|
277
311
|
internalValue: this.convertTypeValue(value),
|
|
278
|
-
selectionIsExcluded: props.selectionIsExcluded,
|
|
279
|
-
disabled: props.disabled,
|
|
312
|
+
selectionIsExcluded: !!this.props.selectionIsExcluded,
|
|
313
|
+
disabled: !!this.props.disabled, /* XXX: !! is needed to copy value and not proxy reference */
|
|
280
314
|
});
|
|
281
315
|
this.checkHideFilter();
|
|
282
316
|
if (this.props.texts) {
|
|
@@ -1394,7 +1428,7 @@ __decorate$4([
|
|
|
1394
1428
|
vtyx.Prop({ default: '' })
|
|
1395
1429
|
], MainInput.prototype, "id", void 0);
|
|
1396
1430
|
__decorate$4([
|
|
1397
|
-
vtyx.Watch('store.state.internalValue')
|
|
1431
|
+
vtyx.Watch('store.state.internalValue', { deep: true })
|
|
1398
1432
|
], MainInput.prototype, "onInternalChange", null);
|
|
1399
1433
|
MainInput = __decorate$4([
|
|
1400
1434
|
vtyx.Component
|
|
@@ -1498,7 +1532,7 @@ let FilterPanel = class FilterPanel extends vtyx.Vue {
|
|
|
1498
1532
|
document.addEventListener('keypress', this.onKeyPressed);
|
|
1499
1533
|
this.getFocus();
|
|
1500
1534
|
}
|
|
1501
|
-
|
|
1535
|
+
unmounted() {
|
|
1502
1536
|
document.removeEventListener('keypress', this.onKeyPressed);
|
|
1503
1537
|
}
|
|
1504
1538
|
/* }}} */
|
|
@@ -1758,7 +1792,7 @@ __decorate$2([
|
|
|
1758
1792
|
vtyx.Watch('store.state.offsetItem')
|
|
1759
1793
|
], List.prototype, "onOffsetChange", null);
|
|
1760
1794
|
__decorate$2([
|
|
1761
|
-
vtyx.Watch('filteredOptions')
|
|
1795
|
+
vtyx.Watch('filteredOptions', { deep: true })
|
|
1762
1796
|
], List.prototype, "onFilteredOptionsChange", null);
|
|
1763
1797
|
__decorate$2([
|
|
1764
1798
|
vtyx.Watch('groupId')
|
|
@@ -1929,7 +1963,7 @@ let ExtendedList = class ExtendedList extends vtyx.Vue {
|
|
|
1929
1963
|
document.body.addEventListener('keydown', this.onKeyDown);
|
|
1930
1964
|
this.computeListSize();
|
|
1931
1965
|
}
|
|
1932
|
-
|
|
1966
|
+
unmounted() {
|
|
1933
1967
|
document.body.removeEventListener('keydown', this.onKeyDown);
|
|
1934
1968
|
/* force the element to be removed from DOM */
|
|
1935
1969
|
if (this.$el.parentNode) {
|
|
@@ -1974,7 +2008,7 @@ __decorate$1([
|
|
|
1974
2008
|
vtyx.Prop({ default: 300 })
|
|
1975
2009
|
], ExtendedList.prototype, "width", void 0);
|
|
1976
2010
|
__decorate$1([
|
|
1977
|
-
vtyx.Watch('store.state.filteredOptions')
|
|
2011
|
+
vtyx.Watch('store.state.filteredOptions', { deep: true })
|
|
1978
2012
|
], ExtendedList.prototype, "onFilteredOptionsChange", null);
|
|
1979
2013
|
__decorate$1([
|
|
1980
2014
|
vtyx.Watch('store.state.hideFilter')
|
|
@@ -2222,7 +2256,7 @@ let Selectic = class Selectic extends vtyx.Vue {
|
|
|
2222
2256
|
this.store.props.selectionIsExcluded = this.selectionIsExcluded;
|
|
2223
2257
|
}
|
|
2224
2258
|
onOptionsChange() {
|
|
2225
|
-
this.store.props.options =
|
|
2259
|
+
this.store.props.options = deepClone(this.options);
|
|
2226
2260
|
}
|
|
2227
2261
|
onTextsChange() {
|
|
2228
2262
|
const texts = this.texts;
|
|
@@ -2463,7 +2497,7 @@ let Selectic = class Selectic extends vtyx.Vue {
|
|
|
2463
2497
|
// }
|
|
2464
2498
|
// this.store.childOptions = options;
|
|
2465
2499
|
}
|
|
2466
|
-
|
|
2500
|
+
beforeUnmount() {
|
|
2467
2501
|
this.removeListeners();
|
|
2468
2502
|
}
|
|
2469
2503
|
/* }}} */
|
|
@@ -2539,22 +2573,22 @@ __decorate([
|
|
|
2539
2573
|
vtyx.Prop()
|
|
2540
2574
|
], Selectic.prototype, "_getMethods", void 0);
|
|
2541
2575
|
__decorate([
|
|
2542
|
-
vtyx.Watch('value')
|
|
2576
|
+
vtyx.Watch('value', { deep: true })
|
|
2543
2577
|
], Selectic.prototype, "onValueChange", null);
|
|
2544
2578
|
__decorate([
|
|
2545
2579
|
vtyx.Watch('selectionIsExcluded')
|
|
2546
2580
|
], Selectic.prototype, "onExcludedChange", null);
|
|
2547
2581
|
__decorate([
|
|
2548
|
-
vtyx.Watch('options')
|
|
2582
|
+
vtyx.Watch('options', { deep: true })
|
|
2549
2583
|
], Selectic.prototype, "onOptionsChange", null);
|
|
2550
2584
|
__decorate([
|
|
2551
|
-
vtyx.Watch('texts')
|
|
2585
|
+
vtyx.Watch('texts', { deep: true })
|
|
2552
2586
|
], Selectic.prototype, "onTextsChange", null);
|
|
2553
2587
|
__decorate([
|
|
2554
2588
|
vtyx.Watch('disabled')
|
|
2555
2589
|
], Selectic.prototype, "onDisabledChange", null);
|
|
2556
2590
|
__decorate([
|
|
2557
|
-
vtyx.Watch('groups')
|
|
2591
|
+
vtyx.Watch('groups', { deep: true })
|
|
2558
2592
|
], Selectic.prototype, "onGroupsChanged", null);
|
|
2559
2593
|
__decorate([
|
|
2560
2594
|
vtyx.Watch('placeholder')
|
|
@@ -2566,7 +2600,7 @@ __decorate([
|
|
|
2566
2600
|
vtyx.Watch('isFocused')
|
|
2567
2601
|
], Selectic.prototype, "onFocusChanged", null);
|
|
2568
2602
|
__decorate([
|
|
2569
|
-
vtyx.Watch('store.state.internalValue')
|
|
2603
|
+
vtyx.Watch('store.state.internalValue', { deep: true })
|
|
2570
2604
|
], Selectic.prototype, "onInternalValueChange", null);
|
|
2571
2605
|
__decorate([
|
|
2572
2606
|
vtyx.Emit('input'),
|
package/dist/selectic.esm.js
CHANGED
|
@@ -31,13 +31,42 @@ function styleInject(css, ref) {
|
|
|
31
31
|
var css_248z = "/* {{{ Variables */\n\n:root {\n --selectic-font-size: 14px;\n --selectic-cursor-disabled: not-allowed;\n\n /* The main element */\n --selectic-color: #555555;\n --selectic-bg: #ffffff;\n\n /* The main element (when disabled) */\n --selectic-color-disabled: #787878;\n --selectic-bg-disabled: #eeeeee;\n\n /* The list */\n --selectic-panel-bg: #f0f0f0;\n --selectic-separator-bordercolor: #cccccc;\n /* --selectic-item-color: var(--selectic-color); /* Can be set in any CSS configuration */\n\n /* The current selected item */\n --selectic-selected-item-color: #428bca;\n\n /* When mouse is over items or by selecting with key arrows */\n --selectic-active-item-color: #ffffff;\n --selectic-active-item-bg: #66afe9;\n\n /* Selected values in main element */\n --selectic-value-bg: #f0f0f0;\n /* --selectic-more-items-bg: var(--selectic-info-bg); /* can be set in any CSS configuration */\n /* --selectic-more-items-color: var(--selectic-info-color); /* can be set in any CSS configuration */\n --selectic-more-items-bg-disabled: #cccccc;\n\n /* Information message */\n --selectic-info-bg: #5bc0de;\n --selectic-info-color: #ffffff;\n\n /* Error message */\n --selectic-error-bg: #b72c29;\n --selectic-error-color: #ffffff;\n\n /* XXX: Currently it is important to keep this size for a correct scroll\n * height estimation */\n --selectic-input-height: 30px;\n}\n\n/* }}} */\n/* {{{ Bootstrap equivalent style */\n\n.selectic .form-control {\n display: block;\n width: 100%;\n height: calc(var(--selectic-input-height) - 2px);\n font-size: var(--selectic-font-size);\n line-height: 1.42857143;\n color: var(--selectic-color);\n background-color: var(--selectic-bg);\n background-image: none;\n border: 1px solid var(--selectic-separator-bordercolor); /* should use a better variable */\n border-radius: 4px;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;\n}\n.selectic .has-feedback {\n position: relative;\n}\n.selectic .has-feedback .form-control {\n padding-right: calc(var(--selectic-input-height) + 4px);\n}\n\n.selectic .form-control-feedback.fa,\n.selectic .form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: calc(var(--selectic-input-height) + 4px);\n height: calc(var(--selectic-input-height) + 4px);\n line-height: var(--selectic-input-height);\n text-align: center;\n pointer-events: none;\n}\n\n.selectic .alert-info {\n background-color: var(--selectic-info-bg);\n color: var(--selectic-info-color);\n}\n\n.selectic .alert-danger {\n background-color: var(--selectic-error-bg);\n color: var(--selectic-error-color);\n}\n\n/* }}} */\n\n.selectic * {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n\n.selectic.form-control {\n display: inline-block;\n padding: 0;\n cursor: pointer;\n border: unset;\n}\n\n.has-feedback .selectic__icon-container.form-control-feedback {\n right: 0;\n}\n\n/* The input which contains the selected value\n * XXX: This input should stay hidden behind other elements, but is \"visible\"\n * (in term of DOM point of view) in order to get and to trigger the `focus`\n * DOM event. */\n.selectic__input-value {\n position: fixed;\n opacity: 0;\n z-index: -1000;\n top: -100px;\n}\n\n/* XXX: .form-control has been added to this selector to improve priority and\n * override some rules of the original .form-control */\n.selectic-input.form-control {\n display: inline-flex;\n justify-content: space-between;\n overflow: hidden;\n width: 100%;\n min-height: var(--selectic-input-height);\n padding-top: 0;\n padding-bottom: 0;\n padding-left: 5px;\n line-height: calc(var(--selectic-input-height) - 4px);\n color: var(--selectic-color);\n}\n\n.selectic-input__reverse-icon {\n align-self: center;\n margin-right: 3px;\n cursor: default;\n}\n.selectic-input__clear-icon {\n align-self: center;\n margin-left: 3px;\n cursor: pointer;\n}\n.selectic-input__clear-icon:hover {\n color: var(--selectic-selected-item-color);\n}\n\n.selectic-input.focused {\n border-bottom-left-radius: 0px;\n border-bottom-right-radius: 0px;\n}\n\n.selectic-input.disabled {\n cursor: var(--selectic-cursor-disabled);\n background-color: var(--selectic-bg-disabled);\n}\n.selectic-input.disabled .more-items {\n\tbackground-color: var(--selectic-more-items-bg-disabled);\n}\n\n.selectic-input__selected-items {\n display: inline-flex;\n flex-wrap: nowrap;\n align-items: center;\n white-space: nowrap;\n}\n\n.selectic-input__selected-items__placeholder {\n font-style: italic;\n opacity: 0.7;\n white-space: nowrap;\n}\n\n.selectic-icon {\n color: var(--selectic-color);\n text-align: center;\n vertical-align: middle;\n}\n\n.selectic__extended-list {\n position: fixed;\n z-index: 2000;\n height: auto;\n background-color: var(--selectic-bg, #ffffff);\n box-shadow: 2px 5px 12px 0px #888888;\n border-radius: 0 0 4px 4px;\n padding: 0;\n min-width: 200px;\n}\n.selectic__extended-list__list-items {\n max-height: calc(var(--selectic-input-height) * 10);\n overflow: auto;\n padding-left: 0;\n}\n\n.selectic-item {\n display: block;\n position: relative;\n box-sizing: border-box;\n padding: 2px 8px;\n color: var(--selectic-item-color, var(--selectic-color));\n min-height: calc(var(--selectic-input-height) - 3px);\n list-style-type: none;\n white-space: nowrap;\n cursor: pointer;\n}\n\n.selectic-item_text {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.selectic-item:not(.selected) .selectic-item_icon {\n opacity: 0;\n}\n\n.selectic-item_text {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n\n.selectic-item__active {\n background-color: var(--selectic-active-item-bg);\n color: var(--selectic-active-item-color);\n}\n.selectic-item__active:not(.selected) .selectic-item_icon {\n opacity: 0.2;\n}\n\n.selectic-item__disabled {\n color: var(--selectic-color-disabled);\n background-color: var(--selectic-bg-disabled);\n}\n\n.selectic-item__is-in-group {\n padding-left: 2em;\n}\n\n.selectic-item__is-group {\n font-weight: bold;\n cursor: default;\n}\n\n.selectic-item.selected {\n color: var(--selectic-selected-item-color);\n}\n.selectic-search-scope {\n color: #e0e0e0;\n left: auto;\n right: 10px;\n}\n\n.selectic__message {\n text-align: center;\n padding: 3px;\n}\n\n.selectic .filter-panel {\n padding: 3px;\n margin-left: 0px;\n margin-right: 0px;\n background-color: var(--selectic-panel-bg);\n border-bottom: 1px solid var(--selectic-separator-bordercolor);\n}\n\n.selectic .panelclosed {\n max-height: 0px;\n transition: max-height 0.3s ease-out;\n overflow: hidden;\n}\n\n.panelopened {\n max-height: 200px;\n transition: max-height 0.3s ease-in;\n overflow: hidden;\n}\n\n.selectic .filter-panel__input {\n padding-left: 0px;\n padding-right: 0px;\n padding-bottom: 10px;\n margin-bottom: 0px;\n}\n.selectic .filter-input {\n height: calc(var(--selectic-input-height) * 0.75);\n}\n\n.selectic .checkbox-filter {\n padding: 5px;\n text-align: center;\n}\n\n.selectic .curtain-handler {\n text-align: center;\n}\n\n.selectic .toggle-selectic {\n margin: 5px;\n padding-left: 0px;\n padding-right: 0px;\n}\n\n.selectic .toggle-boolean-select-all-toggle {\n display: inline;\n margin-right: 15px;\n}\n\n.selectic .toggle-boolean-excluding-toggle {\n display: inline;\n margin-right: 15px;\n}\n\n.selectic .single-value {\n display: grid;\n grid-template: \"value icon\" 1fr / max-content max-content;\n\n padding: 2px;\n padding-left: 5px;\n margin-left: 0;\n margin-right: 5px;\n /* margin top/bottom are mainly to create a gutter in multilines */\n margin-top: 2px;\n margin-bottom: 2px;\n\n border-radius: 3px;\n background-color: var(--selectic-value-bg);\n max-height: calc(var(--selectic-input-height) - 10px);\n max-width: 100%;\n min-width: 30px;\n\n overflow: hidden;\n white-space: nowrap;\n line-height: initial;\n vertical-align: middle;\n}\n\n.selectic .more-items {\n display: inline-block;\n\n padding-left: 5px;\n padding-right: 5px;\n border-radius: 10px;\n\n background-color: var(--selectic-more-items-bg, var(--selectic-info-bg));\n color: var(--selectic-more-items-color, var(--selectic-info-color));\n cursor: help;\n}\n.selectic-input__selected-items__value {\n grid-area: value;\n align-self: center;\n justify-self: normal;\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n}\n\n.selectic-input__selected-items__icon {\n grid-area: icon;\n align-self: center;\n justify-self: center;\n margin-left: 5px;\n}\n.selectic-input__selected-items__icon:hover {\n color: var(--selectic-selected-item-color);\n}\n\n.selectic__label-disabled {\n opacity: 0.5;\n transition: opacity 400ms;\n}\n\n/* XXX: override padding of bootstrap input-sm.\n * This padding introduce a line shift. */\n.selectic.input-sm {\n padding: 0;\n}\n\n/* {{{ overflow multiline */\n\n.selectic--overflow-multiline,\n.selectic--overflow-multiline.form-control,\n.selectic--overflow-multiline .form-control {\n height: unset;\n}\n\n.selectic--overflow-multiline .selectic-input {\n overflow: unset;\n}\n\n.selectic--overflow-multiline .selectic-input__selected-items {\n flex-wrap: wrap;\n}\n\n/* }}} */\n";
|
|
32
32
|
styleInject(css_248z);
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
34
|
+
/**
|
|
35
|
+
* Clone the object and its inner properties.
|
|
36
|
+
* @param obj The object to be clone.
|
|
37
|
+
* @param refs internal reference to object to avoid cyclic references
|
|
38
|
+
* @returns a copy of obj
|
|
38
39
|
*/
|
|
39
|
-
|
|
40
|
-
/*
|
|
40
|
+
function deepClone(obj, refs = new WeakMap()) {
|
|
41
|
+
/* For circular references */
|
|
42
|
+
if (refs.has(obj)) {
|
|
43
|
+
return refs.get(obj);
|
|
44
|
+
}
|
|
45
|
+
if (typeof obj === 'object') {
|
|
46
|
+
if (Array.isArray(obj)) {
|
|
47
|
+
const ref = [];
|
|
48
|
+
refs.set(obj, ref);
|
|
49
|
+
obj.forEach((val, idx) => {
|
|
50
|
+
ref[idx] = deepClone(val, refs);
|
|
51
|
+
});
|
|
52
|
+
return ref;
|
|
53
|
+
}
|
|
54
|
+
if (obj instanceof RegExp) {
|
|
55
|
+
const ref = new RegExp(obj.source, obj.flags);
|
|
56
|
+
refs.set(obj, ref);
|
|
57
|
+
return ref;
|
|
58
|
+
}
|
|
59
|
+
/* This should be an object */
|
|
60
|
+
const ref = {};
|
|
61
|
+
refs.set(obj, ref);
|
|
62
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
63
|
+
ref[key] = deepClone(val, refs);
|
|
64
|
+
}
|
|
65
|
+
return ref;
|
|
66
|
+
}
|
|
67
|
+
/* This should be a primitive */
|
|
68
|
+
return obj;
|
|
69
|
+
}
|
|
41
70
|
/**
|
|
42
71
|
* Escape search string to consider regexp special characters as they
|
|
43
72
|
* are and not like special characters.
|
|
@@ -68,6 +97,12 @@ function assignObject(obj, ...sourceObjects) {
|
|
|
68
97
|
}
|
|
69
98
|
return result;
|
|
70
99
|
}
|
|
100
|
+
|
|
101
|
+
/* File Purpose:
|
|
102
|
+
* It keeps and computes all states at a single place.
|
|
103
|
+
* Every inner components of Selectic should communicate with this file to
|
|
104
|
+
* change or to get states.
|
|
105
|
+
*/
|
|
71
106
|
/* }}} */
|
|
72
107
|
/* {{{ Static */
|
|
73
108
|
function changeTexts$1(texts) {
|
|
@@ -97,6 +132,26 @@ let closePreviousSelectic;
|
|
|
97
132
|
let uid = 0;
|
|
98
133
|
class SelecticStore {
|
|
99
134
|
constructor(props = {}) {
|
|
135
|
+
/* Do not need reactivity */
|
|
136
|
+
this.requestId = 0;
|
|
137
|
+
this._uid = ++uid;
|
|
138
|
+
/* {{{ Props */
|
|
139
|
+
const defaultProps = {
|
|
140
|
+
value: null,
|
|
141
|
+
selectionIsExcluded: false,
|
|
142
|
+
disabled: false,
|
|
143
|
+
options: null,
|
|
144
|
+
childOptions: [],
|
|
145
|
+
groups: [],
|
|
146
|
+
texts: null,
|
|
147
|
+
params: {},
|
|
148
|
+
fetchCallback: null,
|
|
149
|
+
getItemsCallback: null,
|
|
150
|
+
keepOpenWithOtherSelectic: false,
|
|
151
|
+
};
|
|
152
|
+
const propsVal = assignObject(defaultProps, props);
|
|
153
|
+
this.props = reactive(propsVal);
|
|
154
|
+
/* }}} */
|
|
100
155
|
/* {{{ data */
|
|
101
156
|
this.state = reactive({
|
|
102
157
|
multiple: false,
|
|
@@ -137,27 +192,6 @@ class SelecticStore {
|
|
|
137
192
|
automaticClose: false,
|
|
138
193
|
},
|
|
139
194
|
});
|
|
140
|
-
/* Do not need reactivity */
|
|
141
|
-
this.requestId = 0;
|
|
142
|
-
this._uid = ++uid;
|
|
143
|
-
/* {{{ Props */
|
|
144
|
-
const defaultProps = {
|
|
145
|
-
value: null,
|
|
146
|
-
selectionIsExcluded: false,
|
|
147
|
-
disabled: false,
|
|
148
|
-
options: null,
|
|
149
|
-
childOptions: [],
|
|
150
|
-
groups: [],
|
|
151
|
-
texts: null,
|
|
152
|
-
params: {},
|
|
153
|
-
fetchCallback: null,
|
|
154
|
-
getItemsCallback: null,
|
|
155
|
-
keepOpenWithOtherSelectic: false,
|
|
156
|
-
};
|
|
157
|
-
const propsVal = assignObject(defaultProps, props);
|
|
158
|
-
this.props = reactive(propsVal);
|
|
159
|
-
/* }}} */
|
|
160
|
-
/* {{{ data */
|
|
161
195
|
this.data = reactive({
|
|
162
196
|
labels: Object.assign({}, messages),
|
|
163
197
|
itemsPerPage: 10,
|
|
@@ -208,17 +242,17 @@ class SelecticStore {
|
|
|
208
242
|
this.commit('isOpen', false);
|
|
209
243
|
this.buildAllOptions(true);
|
|
210
244
|
this.buildSelectedOptions();
|
|
211
|
-
});
|
|
245
|
+
}, { deep: true });
|
|
212
246
|
watch(() => [this.listOptions, this.elementOptions], () => {
|
|
213
247
|
/* TODO: transform allOptions as a computed properties and this
|
|
214
248
|
* watcher become useless */
|
|
215
249
|
this.buildAllOptions(true);
|
|
216
|
-
});
|
|
250
|
+
}, { deep: true });
|
|
217
251
|
watch(() => this.props.value, () => {
|
|
218
252
|
var _a;
|
|
219
253
|
const value = (_a = this.props.value) !== null && _a !== void 0 ? _a : null;
|
|
220
254
|
this.commit('internalValue', value);
|
|
221
|
-
});
|
|
255
|
+
}, { deep: true });
|
|
222
256
|
watch(() => this.props.selectionIsExcluded, () => {
|
|
223
257
|
this.commit('selectionIsExcluded', this.props.selectionIsExcluded);
|
|
224
258
|
});
|
|
@@ -234,14 +268,14 @@ class SelecticStore {
|
|
|
234
268
|
areAllSelected = this.state.filteredOptions.every((item) => !!(+item.selected ^ selectionIsExcluded));
|
|
235
269
|
}
|
|
236
270
|
this.state.status.areAllSelected = areAllSelected;
|
|
237
|
-
});
|
|
271
|
+
}, { deep: true });
|
|
238
272
|
watch(() => this.state.internalValue, () => {
|
|
239
273
|
this.buildSelectedOptions();
|
|
240
|
-
});
|
|
274
|
+
}, { deep: true });
|
|
241
275
|
watch(() => this.state.allOptions, () => {
|
|
242
276
|
this.checkAutoSelect();
|
|
243
277
|
this.checkAutoDisabled();
|
|
244
|
-
});
|
|
278
|
+
}, { deep: true });
|
|
245
279
|
watch(() => this.state.totalAllOptions, () => {
|
|
246
280
|
this.checkHideFilter();
|
|
247
281
|
});
|
|
@@ -271,8 +305,8 @@ class SelecticStore {
|
|
|
271
305
|
* and ensure convertValue run with correct state */
|
|
272
306
|
assignObject(this.state, {
|
|
273
307
|
internalValue: this.convertTypeValue(value),
|
|
274
|
-
selectionIsExcluded: props.selectionIsExcluded,
|
|
275
|
-
disabled: props.disabled,
|
|
308
|
+
selectionIsExcluded: !!this.props.selectionIsExcluded,
|
|
309
|
+
disabled: !!this.props.disabled, /* XXX: !! is needed to copy value and not proxy reference */
|
|
276
310
|
});
|
|
277
311
|
this.checkHideFilter();
|
|
278
312
|
if (this.props.texts) {
|
|
@@ -1390,7 +1424,7 @@ __decorate$4([
|
|
|
1390
1424
|
Prop({ default: '' })
|
|
1391
1425
|
], MainInput.prototype, "id", void 0);
|
|
1392
1426
|
__decorate$4([
|
|
1393
|
-
Watch('store.state.internalValue')
|
|
1427
|
+
Watch('store.state.internalValue', { deep: true })
|
|
1394
1428
|
], MainInput.prototype, "onInternalChange", null);
|
|
1395
1429
|
MainInput = __decorate$4([
|
|
1396
1430
|
Component
|
|
@@ -1494,7 +1528,7 @@ let FilterPanel = class FilterPanel extends Vue {
|
|
|
1494
1528
|
document.addEventListener('keypress', this.onKeyPressed);
|
|
1495
1529
|
this.getFocus();
|
|
1496
1530
|
}
|
|
1497
|
-
|
|
1531
|
+
unmounted() {
|
|
1498
1532
|
document.removeEventListener('keypress', this.onKeyPressed);
|
|
1499
1533
|
}
|
|
1500
1534
|
/* }}} */
|
|
@@ -1754,7 +1788,7 @@ __decorate$2([
|
|
|
1754
1788
|
Watch('store.state.offsetItem')
|
|
1755
1789
|
], List.prototype, "onOffsetChange", null);
|
|
1756
1790
|
__decorate$2([
|
|
1757
|
-
Watch('filteredOptions')
|
|
1791
|
+
Watch('filteredOptions', { deep: true })
|
|
1758
1792
|
], List.prototype, "onFilteredOptionsChange", null);
|
|
1759
1793
|
__decorate$2([
|
|
1760
1794
|
Watch('groupId')
|
|
@@ -1925,7 +1959,7 @@ let ExtendedList = class ExtendedList extends Vue {
|
|
|
1925
1959
|
document.body.addEventListener('keydown', this.onKeyDown);
|
|
1926
1960
|
this.computeListSize();
|
|
1927
1961
|
}
|
|
1928
|
-
|
|
1962
|
+
unmounted() {
|
|
1929
1963
|
document.body.removeEventListener('keydown', this.onKeyDown);
|
|
1930
1964
|
/* force the element to be removed from DOM */
|
|
1931
1965
|
if (this.$el.parentNode) {
|
|
@@ -1970,7 +2004,7 @@ __decorate$1([
|
|
|
1970
2004
|
Prop({ default: 300 })
|
|
1971
2005
|
], ExtendedList.prototype, "width", void 0);
|
|
1972
2006
|
__decorate$1([
|
|
1973
|
-
Watch('store.state.filteredOptions')
|
|
2007
|
+
Watch('store.state.filteredOptions', { deep: true })
|
|
1974
2008
|
], ExtendedList.prototype, "onFilteredOptionsChange", null);
|
|
1975
2009
|
__decorate$1([
|
|
1976
2010
|
Watch('store.state.hideFilter')
|
|
@@ -2218,7 +2252,7 @@ let Selectic = class Selectic extends Vue {
|
|
|
2218
2252
|
this.store.props.selectionIsExcluded = this.selectionIsExcluded;
|
|
2219
2253
|
}
|
|
2220
2254
|
onOptionsChange() {
|
|
2221
|
-
this.store.props.options =
|
|
2255
|
+
this.store.props.options = deepClone(this.options);
|
|
2222
2256
|
}
|
|
2223
2257
|
onTextsChange() {
|
|
2224
2258
|
const texts = this.texts;
|
|
@@ -2459,7 +2493,7 @@ let Selectic = class Selectic extends Vue {
|
|
|
2459
2493
|
// }
|
|
2460
2494
|
// this.store.childOptions = options;
|
|
2461
2495
|
}
|
|
2462
|
-
|
|
2496
|
+
beforeUnmount() {
|
|
2463
2497
|
this.removeListeners();
|
|
2464
2498
|
}
|
|
2465
2499
|
/* }}} */
|
|
@@ -2535,22 +2569,22 @@ __decorate([
|
|
|
2535
2569
|
Prop()
|
|
2536
2570
|
], Selectic.prototype, "_getMethods", void 0);
|
|
2537
2571
|
__decorate([
|
|
2538
|
-
Watch('value')
|
|
2572
|
+
Watch('value', { deep: true })
|
|
2539
2573
|
], Selectic.prototype, "onValueChange", null);
|
|
2540
2574
|
__decorate([
|
|
2541
2575
|
Watch('selectionIsExcluded')
|
|
2542
2576
|
], Selectic.prototype, "onExcludedChange", null);
|
|
2543
2577
|
__decorate([
|
|
2544
|
-
Watch('options')
|
|
2578
|
+
Watch('options', { deep: true })
|
|
2545
2579
|
], Selectic.prototype, "onOptionsChange", null);
|
|
2546
2580
|
__decorate([
|
|
2547
|
-
Watch('texts')
|
|
2581
|
+
Watch('texts', { deep: true })
|
|
2548
2582
|
], Selectic.prototype, "onTextsChange", null);
|
|
2549
2583
|
__decorate([
|
|
2550
2584
|
Watch('disabled')
|
|
2551
2585
|
], Selectic.prototype, "onDisabledChange", null);
|
|
2552
2586
|
__decorate([
|
|
2553
|
-
Watch('groups')
|
|
2587
|
+
Watch('groups', { deep: true })
|
|
2554
2588
|
], Selectic.prototype, "onGroupsChanged", null);
|
|
2555
2589
|
__decorate([
|
|
2556
2590
|
Watch('placeholder')
|
|
@@ -2562,7 +2596,7 @@ __decorate([
|
|
|
2562
2596
|
Watch('isFocused')
|
|
2563
2597
|
], Selectic.prototype, "onFocusChanged", null);
|
|
2564
2598
|
__decorate([
|
|
2565
|
-
Watch('store.state.internalValue')
|
|
2599
|
+
Watch('store.state.internalValue', { deep: true })
|
|
2566
2600
|
], Selectic.prototype, "onInternalValueChange", null);
|
|
2567
2601
|
__decorate([
|
|
2568
2602
|
Emit('input'),
|
package/package.json
CHANGED
package/src/ExtendedList.tsx
CHANGED
|
@@ -192,7 +192,7 @@ export default class ExtendedList extends Vue<Props> {
|
|
|
192
192
|
/* }}} */
|
|
193
193
|
/* {{{ watch */
|
|
194
194
|
|
|
195
|
-
@Watch('store.state.filteredOptions')
|
|
195
|
+
@Watch('store.state.filteredOptions', { deep: true })
|
|
196
196
|
public onFilteredOptionsChange() {
|
|
197
197
|
this.$nextTick(this.computeListSize);
|
|
198
198
|
}
|
|
@@ -228,7 +228,7 @@ export default class ExtendedList extends Vue<Props> {
|
|
|
228
228
|
this.computeListSize();
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
-
public
|
|
231
|
+
public unmounted() {
|
|
232
232
|
document.body.removeEventListener('keydown', this.onKeyDown);
|
|
233
233
|
|
|
234
234
|
/* force the element to be removed from DOM */
|
package/src/Filter.tsx
CHANGED
package/src/List.tsx
CHANGED
package/src/MainInput.tsx
CHANGED
package/src/Store.tsx
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { reactive, watch, unref, computed, ComputedRef } from 'vue';
|
|
8
|
+
import { convertToRegExp, assignObject } from './tools';
|
|
8
9
|
|
|
9
10
|
/* {{{ Types definitions */
|
|
10
11
|
|
|
@@ -336,42 +337,6 @@ interface Messages {
|
|
|
336
337
|
|
|
337
338
|
export type PartialMessages = { [K in keyof Messages]?: Messages[K] };
|
|
338
339
|
|
|
339
|
-
/* }}} */
|
|
340
|
-
/* {{{ Helper */
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* Escape search string to consider regexp special characters as they
|
|
344
|
-
* are and not like special characters.
|
|
345
|
-
* Consider * characters as a wildcards characters (meanings 0 or
|
|
346
|
-
* more characters) and convert them to .* (the wildcard characters
|
|
347
|
-
* in Regexp)
|
|
348
|
-
*
|
|
349
|
-
* @param {String} name the original string to convert
|
|
350
|
-
* @param {String} [flag] mode to apply for regExp
|
|
351
|
-
* @return {String} the string ready to use for RegExp format
|
|
352
|
-
*/
|
|
353
|
-
function convertToRegExp(name: string, flag = 'i'): RegExp {
|
|
354
|
-
const pattern = name.replace(/[\\^$.+?(){}[\]|]/g, '\\$&')
|
|
355
|
-
.replace(/\*/g, '.*');
|
|
356
|
-
|
|
357
|
-
return new RegExp(pattern, flag);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
/** Does the same as Object.assign but does not replace if value is undefined */
|
|
361
|
-
function assignObject<T>(obj: Partial<T>, ...sourceObjects: Array<Partial<T>>): T {
|
|
362
|
-
const result = obj;
|
|
363
|
-
for (const source of sourceObjects) {
|
|
364
|
-
for (const key of Object.keys(source)) {
|
|
365
|
-
const value = source[key as keyof T];
|
|
366
|
-
if (value === undefined) {
|
|
367
|
-
continue;
|
|
368
|
-
}
|
|
369
|
-
result[key as keyof T] = value;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
return result as T;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
340
|
/* }}} */
|
|
376
341
|
/* {{{ Static */
|
|
377
342
|
|
|
@@ -411,48 +376,7 @@ export default class SelecticStore {
|
|
|
411
376
|
|
|
412
377
|
/* {{{ data */
|
|
413
378
|
|
|
414
|
-
public state
|
|
415
|
-
multiple: false,
|
|
416
|
-
disabled: false,
|
|
417
|
-
placeholder: '',
|
|
418
|
-
hideFilter: false,
|
|
419
|
-
keepFilterOpen: false,
|
|
420
|
-
allowRevert: undefined,
|
|
421
|
-
allowClearSelection: false,
|
|
422
|
-
autoSelect: true,
|
|
423
|
-
autoDisabled: true,
|
|
424
|
-
strictValue: false,
|
|
425
|
-
selectionOverflow: 'collapsed',
|
|
426
|
-
|
|
427
|
-
internalValue: null,
|
|
428
|
-
isOpen: false,
|
|
429
|
-
searchText: '',
|
|
430
|
-
selectionIsExcluded: false,
|
|
431
|
-
allOptions: [],
|
|
432
|
-
dynOptions: [],
|
|
433
|
-
filteredOptions: [],
|
|
434
|
-
selectedOptions: null,
|
|
435
|
-
totalAllOptions: Infinity,
|
|
436
|
-
totalDynOptions: Infinity,
|
|
437
|
-
totalFilteredOptions: Infinity,
|
|
438
|
-
groups: new Map(),
|
|
439
|
-
offsetItem: 0,
|
|
440
|
-
activeItemIdx: -1,
|
|
441
|
-
pageSize: 100,
|
|
442
|
-
listPosition: 'auto',
|
|
443
|
-
|
|
444
|
-
optionBehaviorOperation: 'sort',
|
|
445
|
-
optionBehaviorOrder: ['O', 'D', 'E'],
|
|
446
|
-
|
|
447
|
-
status: {
|
|
448
|
-
searching: false,
|
|
449
|
-
errorMessage: '',
|
|
450
|
-
areAllSelected: false,
|
|
451
|
-
hasChanged: false,
|
|
452
|
-
automaticChange: false,
|
|
453
|
-
automaticClose: false,
|
|
454
|
-
},
|
|
455
|
-
});
|
|
379
|
+
public state: SelecticStoreState;
|
|
456
380
|
public data: Data;
|
|
457
381
|
|
|
458
382
|
/* Do not need reactivity */
|
|
@@ -500,6 +424,49 @@ export default class SelecticStore {
|
|
|
500
424
|
/* }}} */
|
|
501
425
|
/* {{{ data */
|
|
502
426
|
|
|
427
|
+
this.state = reactive<SelecticStoreState>({
|
|
428
|
+
multiple: false,
|
|
429
|
+
disabled: false,
|
|
430
|
+
placeholder: '',
|
|
431
|
+
hideFilter: false,
|
|
432
|
+
keepFilterOpen: false,
|
|
433
|
+
allowRevert: undefined,
|
|
434
|
+
allowClearSelection: false,
|
|
435
|
+
autoSelect: true,
|
|
436
|
+
autoDisabled: true,
|
|
437
|
+
strictValue: false,
|
|
438
|
+
selectionOverflow: 'collapsed',
|
|
439
|
+
|
|
440
|
+
internalValue: null,
|
|
441
|
+
isOpen: false,
|
|
442
|
+
searchText: '',
|
|
443
|
+
selectionIsExcluded: false,
|
|
444
|
+
allOptions: [],
|
|
445
|
+
dynOptions: [],
|
|
446
|
+
filteredOptions: [],
|
|
447
|
+
selectedOptions: null,
|
|
448
|
+
totalAllOptions: Infinity,
|
|
449
|
+
totalDynOptions: Infinity,
|
|
450
|
+
totalFilteredOptions: Infinity,
|
|
451
|
+
groups: new Map(),
|
|
452
|
+
offsetItem: 0,
|
|
453
|
+
activeItemIdx: -1,
|
|
454
|
+
pageSize: 100,
|
|
455
|
+
listPosition: 'auto',
|
|
456
|
+
|
|
457
|
+
optionBehaviorOperation: 'sort',
|
|
458
|
+
optionBehaviorOrder: ['O', 'D', 'E'],
|
|
459
|
+
|
|
460
|
+
status: {
|
|
461
|
+
searching: false,
|
|
462
|
+
errorMessage: '',
|
|
463
|
+
areAllSelected: false,
|
|
464
|
+
hasChanged: false,
|
|
465
|
+
automaticChange: false,
|
|
466
|
+
automaticClose: false,
|
|
467
|
+
},
|
|
468
|
+
});
|
|
469
|
+
|
|
503
470
|
this.data = reactive({
|
|
504
471
|
labels: Object.assign({}, messages),
|
|
505
472
|
itemsPerPage: 10,
|
|
@@ -565,18 +532,18 @@ export default class SelecticStore {
|
|
|
565
532
|
this.commit('isOpen', false);
|
|
566
533
|
this.buildAllOptions(true);
|
|
567
534
|
this.buildSelectedOptions();
|
|
568
|
-
});
|
|
535
|
+
}, { deep: true });
|
|
569
536
|
|
|
570
537
|
watch(() => [this.listOptions, this.elementOptions], () => {
|
|
571
538
|
/* TODO: transform allOptions as a computed properties and this
|
|
572
539
|
* watcher become useless */
|
|
573
540
|
this.buildAllOptions(true);
|
|
574
|
-
});
|
|
541
|
+
}, { deep: true });
|
|
575
542
|
|
|
576
543
|
watch(() => this.props.value, () => {
|
|
577
544
|
const value = this.props.value ?? null;
|
|
578
545
|
this.commit('internalValue', value);
|
|
579
|
-
});
|
|
546
|
+
}, { deep: true });
|
|
580
547
|
|
|
581
548
|
watch(() => this.props.selectionIsExcluded, () => {
|
|
582
549
|
this.commit('selectionIsExcluded', this.props.selectionIsExcluded);
|
|
@@ -598,16 +565,16 @@ export default class SelecticStore {
|
|
|
598
565
|
}
|
|
599
566
|
|
|
600
567
|
this.state.status.areAllSelected = areAllSelected;
|
|
601
|
-
});
|
|
568
|
+
}, { deep: true });
|
|
602
569
|
|
|
603
570
|
watch(() => this.state.internalValue, () => {
|
|
604
571
|
this.buildSelectedOptions();
|
|
605
|
-
});
|
|
572
|
+
}, { deep: true });
|
|
606
573
|
|
|
607
574
|
watch(() => this.state.allOptions, () => {
|
|
608
575
|
this.checkAutoSelect();
|
|
609
576
|
this.checkAutoDisabled();
|
|
610
|
-
});
|
|
577
|
+
}, { deep: true });
|
|
611
578
|
|
|
612
579
|
watch(() => this.state.totalAllOptions, () => {
|
|
613
580
|
this.checkHideFilter();
|
|
@@ -649,8 +616,8 @@ export default class SelecticStore {
|
|
|
649
616
|
* and ensure convertValue run with correct state */
|
|
650
617
|
assignObject(this.state, {
|
|
651
618
|
internalValue: this.convertTypeValue(value),
|
|
652
|
-
selectionIsExcluded: props.selectionIsExcluded,
|
|
653
|
-
disabled: props.disabled,
|
|
619
|
+
selectionIsExcluded: !!this.props.selectionIsExcluded,
|
|
620
|
+
disabled: !!this.props.disabled, /* XXX: !! is needed to copy value and not proxy reference */
|
|
654
621
|
});
|
|
655
622
|
|
|
656
623
|
this.checkHideFilter();
|
package/src/index.tsx
CHANGED
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
import {Vue, Component, Emit, Prop, Watch, h} from 'vtyx';
|
|
22
22
|
import './css/selectic.css';
|
|
23
23
|
|
|
24
|
+
import { deepClone } from './tools';
|
|
25
|
+
|
|
24
26
|
import Store, {
|
|
25
27
|
changeTexts as storeChangeTexts,
|
|
26
28
|
OptionProp,
|
|
@@ -537,7 +539,7 @@ export default class Selectic extends Vue<Props> {
|
|
|
537
539
|
/* }}} */
|
|
538
540
|
/* {{{ watch */
|
|
539
541
|
|
|
540
|
-
@Watch('value')
|
|
542
|
+
@Watch('value', { deep: true })
|
|
541
543
|
public onValueChange() {
|
|
542
544
|
const currentValue = this.store.state.internalValue;
|
|
543
545
|
const newValue = this.value ?? null;
|
|
@@ -556,12 +558,12 @@ export default class Selectic extends Vue<Props> {
|
|
|
556
558
|
this.store.props.selectionIsExcluded = this.selectionIsExcluded;
|
|
557
559
|
}
|
|
558
560
|
|
|
559
|
-
@Watch('options')
|
|
561
|
+
@Watch('options', { deep: true })
|
|
560
562
|
public onOptionsChange() {
|
|
561
|
-
this.store.props.options =
|
|
563
|
+
this.store.props.options = deepClone(this.options);
|
|
562
564
|
}
|
|
563
565
|
|
|
564
|
-
@Watch('texts')
|
|
566
|
+
@Watch('texts', { deep: true })
|
|
565
567
|
public onTextsChange() {
|
|
566
568
|
const texts = this.texts;
|
|
567
569
|
|
|
@@ -575,7 +577,7 @@ export default class Selectic extends Vue<Props> {
|
|
|
575
577
|
this.store.props.disabled = this.disabled;
|
|
576
578
|
}
|
|
577
579
|
|
|
578
|
-
@Watch('groups')
|
|
580
|
+
@Watch('groups', { deep: true })
|
|
579
581
|
public onGroupsChanged() {
|
|
580
582
|
this.store.changeGroups(this.groups);
|
|
581
583
|
}
|
|
@@ -595,7 +597,7 @@ export default class Selectic extends Vue<Props> {
|
|
|
595
597
|
this.focusToggled();
|
|
596
598
|
}
|
|
597
599
|
|
|
598
|
-
@Watch('store.state.internalValue')
|
|
600
|
+
@Watch('store.state.internalValue', { deep: true })
|
|
599
601
|
public onInternalValueChange() {
|
|
600
602
|
const oldValue = this._oldValue;
|
|
601
603
|
const value = this.getValue();
|
|
@@ -851,7 +853,7 @@ export default class Selectic extends Vue<Props> {
|
|
|
851
853
|
// this.store.childOptions = options;
|
|
852
854
|
}
|
|
853
855
|
|
|
854
|
-
public
|
|
856
|
+
public beforeUnmount() {
|
|
855
857
|
this.removeListeners();
|
|
856
858
|
}
|
|
857
859
|
|
package/src/tools.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* Clone the object and its inner properties.
|
|
4
|
+
* @param obj The object to be clone.
|
|
5
|
+
* @param refs internal reference to object to avoid cyclic references
|
|
6
|
+
* @returns a copy of obj
|
|
7
|
+
*/
|
|
8
|
+
export function deepClone<T = any>(obj: T, refs: WeakMap<any, any> = new WeakMap()): T {
|
|
9
|
+
/* For circular references */
|
|
10
|
+
if (refs.has(obj)) {
|
|
11
|
+
return refs.get(obj);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (typeof obj === 'object') {
|
|
15
|
+
if (Array.isArray(obj)) {
|
|
16
|
+
const ref: any[] = [];
|
|
17
|
+
refs.set(obj, ref);
|
|
18
|
+
obj.forEach((val, idx) => {
|
|
19
|
+
ref[idx] = deepClone(val, refs);
|
|
20
|
+
});
|
|
21
|
+
return ref as unknown as T;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (obj instanceof RegExp) {
|
|
25
|
+
const ref = new RegExp(obj.source, obj.flags);
|
|
26
|
+
refs.set(obj, ref);
|
|
27
|
+
return ref as unknown as T;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* This should be an object */
|
|
31
|
+
const ref: any = {};
|
|
32
|
+
refs.set(obj, ref);
|
|
33
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
34
|
+
ref[key] = deepClone(val, refs);
|
|
35
|
+
}
|
|
36
|
+
return ref as unknown as T;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* This should be a primitive */
|
|
40
|
+
return obj;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Escape search string to consider regexp special characters as they
|
|
46
|
+
* are and not like special characters.
|
|
47
|
+
* Consider * characters as a wildcards characters (meanings 0 or
|
|
48
|
+
* more characters) and convert them to .* (the wildcard characters
|
|
49
|
+
* in Regexp)
|
|
50
|
+
*
|
|
51
|
+
* @param {String} name the original string to convert
|
|
52
|
+
* @param {String} [flag] mode to apply for regExp
|
|
53
|
+
* @return {String} the string ready to use for RegExp format
|
|
54
|
+
*/
|
|
55
|
+
export function convertToRegExp(name: string, flag = 'i'): RegExp {
|
|
56
|
+
const pattern = name.replace(/[\\^$.+?(){}[\]|]/g, '\\$&')
|
|
57
|
+
.replace(/\*/g, '.*');
|
|
58
|
+
|
|
59
|
+
return new RegExp(pattern, flag);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Does the same as Object.assign but does not replace if value is undefined */
|
|
63
|
+
export function assignObject<T>(obj: Partial<T>, ...sourceObjects: Array<Partial<T>>): T {
|
|
64
|
+
const result = obj;
|
|
65
|
+
for (const source of sourceObjects) {
|
|
66
|
+
for (const key of Object.keys(source)) {
|
|
67
|
+
const value = source[key as keyof T];
|
|
68
|
+
if (value === undefined) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
result[key as keyof T] = value;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return result as T;
|
|
75
|
+
}
|
|
@@ -223,6 +223,7 @@ tape.test('change props', (subT) => {
|
|
|
223
223
|
const store = new Store({
|
|
224
224
|
value: 2,
|
|
225
225
|
options: getOptions(5, 'alpha'),
|
|
226
|
+
disabled: false,
|
|
226
227
|
params: {
|
|
227
228
|
autoDisabled: true,
|
|
228
229
|
},
|
|
@@ -249,6 +250,7 @@ tape.test('change props', (subT) => {
|
|
|
249
250
|
const store = new Store({
|
|
250
251
|
value: 2,
|
|
251
252
|
options: getOptions(5, 'alpha'),
|
|
253
|
+
disabled: false,
|
|
252
254
|
params: {
|
|
253
255
|
autoDisabled: true,
|
|
254
256
|
strictValue: true,
|
|
@@ -298,6 +300,37 @@ tape.test('change props', (subT) => {
|
|
|
298
300
|
t.end();
|
|
299
301
|
});
|
|
300
302
|
|
|
303
|
+
sTest.test('should re-enable the select when data are loaded', async (t) => {
|
|
304
|
+
const store = new Store({
|
|
305
|
+
options: [],
|
|
306
|
+
disabled: false,
|
|
307
|
+
params: {
|
|
308
|
+
autoDisabled: true,
|
|
309
|
+
},
|
|
310
|
+
});
|
|
311
|
+
await _.nextVueTick(store);
|
|
312
|
+
|
|
313
|
+
store.commit('isOpen', true);
|
|
314
|
+
await _.nextVueTick(store);
|
|
315
|
+
|
|
316
|
+
t.is(store.state.internalValue, null);
|
|
317
|
+
t.is(store.state.disabled, true);
|
|
318
|
+
t.is(store.state.isOpen, false);
|
|
319
|
+
|
|
320
|
+
store.props.options = getOptions(0, 'alpha');
|
|
321
|
+
await _.nextVueTick(store);
|
|
322
|
+
|
|
323
|
+
t.is(store.state.internalValue, null);
|
|
324
|
+
t.is(store.state.disabled, true), 'should be disabled';
|
|
325
|
+
|
|
326
|
+
store.props.options = getOptions(5, 'beta');
|
|
327
|
+
await _.nextVueTick(store);
|
|
328
|
+
|
|
329
|
+
t.is(store.state.internalValue, 0);
|
|
330
|
+
t.is(store.state.disabled, false), 'should be enabled';
|
|
331
|
+
t.end();
|
|
332
|
+
});
|
|
333
|
+
|
|
301
334
|
sTest.test('should not re-enable the select if disable is set', async (t) => {
|
|
302
335
|
const store = new Store({
|
|
303
336
|
options: getOptions(1, 'alpha'),
|
package/types/ExtendedList.d.ts
CHANGED
package/types/Filter.d.ts
CHANGED
package/types/List.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Vue, h } from 'vtyx';
|
|
2
|
-
import Store, { OptionItem
|
|
2
|
+
import Store, { OptionItem } from './Store';
|
|
3
3
|
export interface Props {
|
|
4
4
|
store: Store;
|
|
5
5
|
options?: any[];
|
|
@@ -14,31 +14,7 @@ export default class List extends Vue<Props> {
|
|
|
14
14
|
private itemHeight;
|
|
15
15
|
private groupId;
|
|
16
16
|
private doNotScroll;
|
|
17
|
-
get filteredOptions():
|
|
18
|
-
selected: boolean;
|
|
19
|
-
disabled: boolean;
|
|
20
|
-
isGroup: boolean;
|
|
21
|
-
id: OptionId;
|
|
22
|
-
text: string;
|
|
23
|
-
title?: string | undefined;
|
|
24
|
-
group?: import("./Store").StrictOptionId | undefined;
|
|
25
|
-
className?: string | undefined;
|
|
26
|
-
style?: string | undefined;
|
|
27
|
-
icon?: string | undefined;
|
|
28
|
-
options?: {
|
|
29
|
-
id: OptionId;
|
|
30
|
-
text: string;
|
|
31
|
-
title?: string | undefined;
|
|
32
|
-
disabled?: boolean | undefined;
|
|
33
|
-
group?: import("./Store").StrictOptionId | undefined;
|
|
34
|
-
className?: string | undefined;
|
|
35
|
-
style?: string | undefined;
|
|
36
|
-
icon?: string | undefined;
|
|
37
|
-
options?: any[] | undefined;
|
|
38
|
-
data?: any;
|
|
39
|
-
}[] | undefined;
|
|
40
|
-
data?: any;
|
|
41
|
-
}[];
|
|
17
|
+
get filteredOptions(): OptionItem[];
|
|
42
18
|
get isMultiple(): boolean;
|
|
43
19
|
get itemsMargin(): number;
|
|
44
20
|
get shortOptions(): OptionItem[];
|
package/types/Store.d.ts
CHANGED
|
@@ -142,141 +142,7 @@ export declare type PartialMessages = {
|
|
|
142
142
|
export declare function changeTexts(texts: PartialMessages): void;
|
|
143
143
|
export default class SelecticStore {
|
|
144
144
|
props: InternalProps;
|
|
145
|
-
state:
|
|
146
|
-
internalValue: OptionId | StrictOptionId[];
|
|
147
|
-
selectionIsExcluded: boolean;
|
|
148
|
-
multiple: boolean;
|
|
149
|
-
disabled: boolean;
|
|
150
|
-
placeholder: string;
|
|
151
|
-
hideFilter: boolean;
|
|
152
|
-
keepFilterOpen: boolean;
|
|
153
|
-
allowRevert?: boolean | undefined;
|
|
154
|
-
allowClearSelection: boolean;
|
|
155
|
-
autoSelect: boolean;
|
|
156
|
-
autoDisabled: boolean;
|
|
157
|
-
strictValue: boolean;
|
|
158
|
-
selectionOverflow: SelectionOverflow;
|
|
159
|
-
isOpen: boolean;
|
|
160
|
-
searchText: string;
|
|
161
|
-
allOptions: {
|
|
162
|
-
id: OptionId;
|
|
163
|
-
text: string;
|
|
164
|
-
title?: string | undefined;
|
|
165
|
-
disabled?: boolean | undefined;
|
|
166
|
-
group?: StrictOptionId | undefined;
|
|
167
|
-
className?: string | undefined;
|
|
168
|
-
style?: string | undefined;
|
|
169
|
-
icon?: string | undefined;
|
|
170
|
-
options?: any[] | undefined;
|
|
171
|
-
data?: any;
|
|
172
|
-
}[];
|
|
173
|
-
dynOptions: {
|
|
174
|
-
id: OptionId;
|
|
175
|
-
text: string;
|
|
176
|
-
title?: string | undefined;
|
|
177
|
-
disabled?: boolean | undefined;
|
|
178
|
-
group?: StrictOptionId | undefined;
|
|
179
|
-
className?: string | undefined;
|
|
180
|
-
style?: string | undefined;
|
|
181
|
-
icon?: string | undefined;
|
|
182
|
-
options?: any[] | undefined;
|
|
183
|
-
data?: any;
|
|
184
|
-
}[];
|
|
185
|
-
filteredOptions: {
|
|
186
|
-
selected: boolean;
|
|
187
|
-
disabled: boolean;
|
|
188
|
-
isGroup: boolean;
|
|
189
|
-
id: OptionId;
|
|
190
|
-
text: string;
|
|
191
|
-
title?: string | undefined;
|
|
192
|
-
group?: StrictOptionId | undefined;
|
|
193
|
-
className?: string | undefined;
|
|
194
|
-
style?: string | undefined;
|
|
195
|
-
icon?: string | undefined;
|
|
196
|
-
options?: {
|
|
197
|
-
id: OptionId;
|
|
198
|
-
text: string;
|
|
199
|
-
title?: string | undefined;
|
|
200
|
-
disabled?: boolean | undefined;
|
|
201
|
-
group?: StrictOptionId | undefined;
|
|
202
|
-
className?: string | undefined;
|
|
203
|
-
style?: string | undefined;
|
|
204
|
-
icon?: string | undefined;
|
|
205
|
-
options?: any[] | undefined;
|
|
206
|
-
data?: any;
|
|
207
|
-
}[] | undefined;
|
|
208
|
-
data?: any;
|
|
209
|
-
}[];
|
|
210
|
-
selectedOptions: {
|
|
211
|
-
selected: boolean;
|
|
212
|
-
disabled: boolean;
|
|
213
|
-
isGroup: boolean;
|
|
214
|
-
id: OptionId;
|
|
215
|
-
text: string;
|
|
216
|
-
title?: string | undefined;
|
|
217
|
-
group?: StrictOptionId | undefined;
|
|
218
|
-
className?: string | undefined;
|
|
219
|
-
style?: string | undefined;
|
|
220
|
-
icon?: string | undefined;
|
|
221
|
-
options?: {
|
|
222
|
-
id: OptionId;
|
|
223
|
-
text: string;
|
|
224
|
-
title?: string | undefined;
|
|
225
|
-
disabled?: boolean | undefined;
|
|
226
|
-
group?: StrictOptionId | undefined;
|
|
227
|
-
className?: string | undefined;
|
|
228
|
-
style?: string | undefined;
|
|
229
|
-
icon?: string | undefined;
|
|
230
|
-
options?: any[] | undefined;
|
|
231
|
-
data?: any;
|
|
232
|
-
}[] | undefined;
|
|
233
|
-
data?: any;
|
|
234
|
-
} | {
|
|
235
|
-
selected: boolean;
|
|
236
|
-
disabled: boolean;
|
|
237
|
-
isGroup: boolean;
|
|
238
|
-
id: OptionId;
|
|
239
|
-
text: string;
|
|
240
|
-
title?: string | undefined;
|
|
241
|
-
group?: StrictOptionId | undefined;
|
|
242
|
-
className?: string | undefined;
|
|
243
|
-
style?: string | undefined;
|
|
244
|
-
icon?: string | undefined;
|
|
245
|
-
options?: {
|
|
246
|
-
id: OptionId;
|
|
247
|
-
text: string;
|
|
248
|
-
title?: string | undefined;
|
|
249
|
-
disabled?: boolean | undefined;
|
|
250
|
-
group?: StrictOptionId | undefined;
|
|
251
|
-
className?: string | undefined;
|
|
252
|
-
style?: string | undefined;
|
|
253
|
-
icon?: string | undefined;
|
|
254
|
-
options?: any[] | undefined;
|
|
255
|
-
data?: any;
|
|
256
|
-
}[] | undefined;
|
|
257
|
-
data?: any;
|
|
258
|
-
}[] | null;
|
|
259
|
-
totalAllOptions: number;
|
|
260
|
-
totalDynOptions: number;
|
|
261
|
-
totalFilteredOptions: number;
|
|
262
|
-
groups: Map<OptionId, string>;
|
|
263
|
-
offsetItem: number;
|
|
264
|
-
activeItemIdx: number;
|
|
265
|
-
pageSize: number;
|
|
266
|
-
formatOption?: FormatCallback | undefined;
|
|
267
|
-
formatSelection?: FormatCallback | undefined;
|
|
268
|
-
optionBehaviorOperation: OptionBehaviorOperation;
|
|
269
|
-
optionBehaviorOrder: OptionBehaviorOrder[];
|
|
270
|
-
listPosition: ListPosition;
|
|
271
|
-
status: {
|
|
272
|
-
searching: boolean;
|
|
273
|
-
errorMessage: string;
|
|
274
|
-
areAllSelected: boolean;
|
|
275
|
-
hasChanged: boolean;
|
|
276
|
-
automaticChange: boolean;
|
|
277
|
-
automaticClose: boolean;
|
|
278
|
-
};
|
|
279
|
-
};
|
|
145
|
+
state: SelecticStoreState;
|
|
280
146
|
data: Data;
|
|
281
147
|
private requestId;
|
|
282
148
|
private cacheRequest;
|
package/types/index.d.ts
CHANGED
package/types/tools.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clone the object and its inner properties.
|
|
3
|
+
* @param obj The object to be clone.
|
|
4
|
+
* @param refs internal reference to object to avoid cyclic references
|
|
5
|
+
* @returns a copy of obj
|
|
6
|
+
*/
|
|
7
|
+
export declare function deepClone<T = any>(obj: T, refs?: WeakMap<any, any>): T;
|
|
8
|
+
/**
|
|
9
|
+
* Escape search string to consider regexp special characters as they
|
|
10
|
+
* are and not like special characters.
|
|
11
|
+
* Consider * characters as a wildcards characters (meanings 0 or
|
|
12
|
+
* more characters) and convert them to .* (the wildcard characters
|
|
13
|
+
* in Regexp)
|
|
14
|
+
*
|
|
15
|
+
* @param {String} name the original string to convert
|
|
16
|
+
* @param {String} [flag] mode to apply for regExp
|
|
17
|
+
* @return {String} the string ready to use for RegExp format
|
|
18
|
+
*/
|
|
19
|
+
export declare function convertToRegExp(name: string, flag?: string): RegExp;
|
|
20
|
+
/** Does the same as Object.assign but does not replace if value is undefined */
|
|
21
|
+
export declare function assignObject<T>(obj: Partial<T>, ...sourceObjects: Array<Partial<T>>): T;
|