selectic 3.0.7 → 3.0.11
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 +71 -28
- package/dist/selectic.esm.js +72 -29
- package/package.json +1 -1
- package/rollup.config.js +8 -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 +11 -46
- package/src/index.tsx +9 -7
- package/src/tools.ts +86 -0
- package/test/Store/Store_creation.spec.js +0 -13
- package/test/Store/commit.spec.js +0 -13
- package/test/Store/getItem.spec.js +0 -13
- package/test/Store/getItems.spec.js +0 -13
- package/test/Store/selectItem.spec.js +0 -13
- package/test/Store/toggleSelectAll.spec.js +0 -13
- package/test/Tools/tools.spec.js +404 -0
- package/types/ExtendedList.d.ts +1 -1
- package/types/Filter.d.ts +1 -1
- package/types/index.d.ts +1 -1
- package/types/tools.d.ts +21 -0
- package/.package.json.un~ +0 -0
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, deepClone } 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
|
|
|
@@ -567,18 +532,18 @@ export default class SelecticStore {
|
|
|
567
532
|
this.commit('isOpen', false);
|
|
568
533
|
this.buildAllOptions(true);
|
|
569
534
|
this.buildSelectedOptions();
|
|
570
|
-
});
|
|
535
|
+
}, { deep: true });
|
|
571
536
|
|
|
572
537
|
watch(() => [this.listOptions, this.elementOptions], () => {
|
|
573
538
|
/* TODO: transform allOptions as a computed properties and this
|
|
574
539
|
* watcher become useless */
|
|
575
540
|
this.buildAllOptions(true);
|
|
576
|
-
});
|
|
541
|
+
}, { deep: true });
|
|
577
542
|
|
|
578
543
|
watch(() => this.props.value, () => {
|
|
579
544
|
const value = this.props.value ?? null;
|
|
580
545
|
this.commit('internalValue', value);
|
|
581
|
-
});
|
|
546
|
+
}, { deep: true });
|
|
582
547
|
|
|
583
548
|
watch(() => this.props.selectionIsExcluded, () => {
|
|
584
549
|
this.commit('selectionIsExcluded', this.props.selectionIsExcluded);
|
|
@@ -600,16 +565,16 @@ export default class SelecticStore {
|
|
|
600
565
|
}
|
|
601
566
|
|
|
602
567
|
this.state.status.areAllSelected = areAllSelected;
|
|
603
|
-
});
|
|
568
|
+
}, { deep: true });
|
|
604
569
|
|
|
605
570
|
watch(() => this.state.internalValue, () => {
|
|
606
571
|
this.buildSelectedOptions();
|
|
607
|
-
});
|
|
572
|
+
}, { deep: true });
|
|
608
573
|
|
|
609
574
|
watch(() => this.state.allOptions, () => {
|
|
610
575
|
this.checkAutoSelect();
|
|
611
576
|
this.checkAutoDisabled();
|
|
612
|
-
});
|
|
577
|
+
}, { deep: true });
|
|
613
578
|
|
|
614
579
|
watch(() => this.state.totalAllOptions, () => {
|
|
615
580
|
this.checkHideFilter();
|
|
@@ -622,13 +587,13 @@ export default class SelecticStore {
|
|
|
622
587
|
this.commit('isOpen', false);
|
|
623
588
|
}
|
|
624
589
|
|
|
625
|
-
const value = this.props.value;
|
|
590
|
+
const value = deepClone(this.props.value);
|
|
626
591
|
|
|
627
592
|
/* set initial value for non reactive attribute */
|
|
628
593
|
this.cacheRequest = new Map();
|
|
629
594
|
|
|
630
595
|
const stateParam: SelecticStoreStateParams | SelecticStoreState =
|
|
631
|
-
|
|
596
|
+
deepClone(this.props.params);
|
|
632
597
|
|
|
633
598
|
if (stateParam.optionBehavior) {
|
|
634
599
|
this.buildOptionBehavior(
|
|
@@ -1095,7 +1060,7 @@ export default class SelecticStore {
|
|
|
1095
1060
|
|
|
1096
1061
|
/* This method is for the computed property listOptions */
|
|
1097
1062
|
private getListOptions(): OptionValue[] {
|
|
1098
|
-
const options = this.props.options;
|
|
1063
|
+
const options = deepClone(this.props.options, ['data']);
|
|
1099
1064
|
const listOptions: OptionValue[] = [];
|
|
1100
1065
|
|
|
1101
1066
|
if (!Array.isArray(options)) {
|
|
@@ -1141,7 +1106,7 @@ export default class SelecticStore {
|
|
|
1141
1106
|
|
|
1142
1107
|
/* This method is for the computed property elementOptions */
|
|
1143
1108
|
private getElementOptions(): OptionValue[] {
|
|
1144
|
-
const options = this.props.childOptions;
|
|
1109
|
+
const options = deepClone(this.props.childOptions, ['data']);
|
|
1145
1110
|
const childOptions: OptionValue[] = [];
|
|
1146
1111
|
|
|
1147
1112
|
if (!Array.isArray(options) || options.length === 0) {
|
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,86 @@
|
|
|
1
|
+
import { unref } from 'vue';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Clone the object and its inner properties.
|
|
5
|
+
* @param obj The object to be clone.
|
|
6
|
+
* @param refs internal reference to object to avoid cyclic references
|
|
7
|
+
* @returns a copy of obj
|
|
8
|
+
*/
|
|
9
|
+
export function deepClone<T = any>(origObject: T, ignoreAttributes: string[] = [], refs: WeakMap<any, any> = new WeakMap()): T {
|
|
10
|
+
const obj = unref(origObject);
|
|
11
|
+
|
|
12
|
+
/* For circular references */
|
|
13
|
+
if (refs.has(obj)) {
|
|
14
|
+
return refs.get(obj);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (typeof obj === 'object') {
|
|
18
|
+
if (obj === null) {
|
|
19
|
+
return obj;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (Array.isArray(obj)) {
|
|
23
|
+
const ref: any[] = [];
|
|
24
|
+
refs.set(obj, ref);
|
|
25
|
+
obj.forEach((val, idx) => {
|
|
26
|
+
ref[idx] = deepClone(val, ignoreAttributes, refs);
|
|
27
|
+
});
|
|
28
|
+
return ref as unknown as T;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (obj instanceof RegExp) {
|
|
32
|
+
const ref = new RegExp(obj.source, obj.flags);
|
|
33
|
+
refs.set(obj, ref);
|
|
34
|
+
return ref as unknown as T;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* This should be an object */
|
|
38
|
+
const ref: any = {};
|
|
39
|
+
refs.set(obj, ref);
|
|
40
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
41
|
+
if (ignoreAttributes.includes(key)) {
|
|
42
|
+
ref[key] = val;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
ref[key] = deepClone(val, ignoreAttributes, refs);
|
|
47
|
+
}
|
|
48
|
+
return ref as unknown as T;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* This should be a primitive */
|
|
52
|
+
return obj;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Escape search string to consider regexp special characters as they
|
|
57
|
+
* are and not like special characters.
|
|
58
|
+
* Consider * characters as a wildcards characters (meanings 0 or
|
|
59
|
+
* more characters) and convert them to .* (the wildcard characters
|
|
60
|
+
* in Regexp)
|
|
61
|
+
*
|
|
62
|
+
* @param {String} name the original string to convert
|
|
63
|
+
* @param {String} [flag] mode to apply for regExp
|
|
64
|
+
* @return {String} the string ready to use for RegExp format
|
|
65
|
+
*/
|
|
66
|
+
export function convertToRegExp(name: string, flag = 'i'): RegExp {
|
|
67
|
+
const pattern = name.replace(/[\\^$.+?(){}[\]|]/g, '\\$&')
|
|
68
|
+
.replace(/\*/g, '.*');
|
|
69
|
+
|
|
70
|
+
return new RegExp(pattern, flag);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Does the same as Object.assign but does not replace if value is undefined */
|
|
74
|
+
export function assignObject<T>(obj: Partial<T>, ...sourceObjects: Array<Partial<T>>): T {
|
|
75
|
+
const result = obj;
|
|
76
|
+
for (const source of sourceObjects) {
|
|
77
|
+
for (const key of Object.keys(source)) {
|
|
78
|
+
const value = source[key as keyof T];
|
|
79
|
+
if (value === undefined) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
result[key as keyof T] = value;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return result as T;
|
|
86
|
+
}
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**************************************************************************/
|
|
2
|
-
/* */
|
|
3
|
-
/* Copyright (C) INTERSEC SA */
|
|
4
|
-
/* */
|
|
5
|
-
/* Should you receive a copy of this source code, you must check you */
|
|
6
|
-
/* have a proper, written authorization of INTERSEC to hold it. If you */
|
|
7
|
-
/* don't have such an authorization, you must DELETE all source code */
|
|
8
|
-
/* files in your possession, and inform INTERSEC of the fact you obtain */
|
|
9
|
-
/* these files. Should you not comply to these terms, you can be */
|
|
10
|
-
/* prosecuted in the extent permitted by applicable law. */
|
|
11
|
-
/* */
|
|
12
|
-
/**************************************************************************/
|
|
13
|
-
|
|
14
1
|
const _ = require('../tools.js');
|
|
15
2
|
const {
|
|
16
3
|
getInitialState,
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**************************************************************************/
|
|
2
|
-
/* */
|
|
3
|
-
/* Copyright (C) INTERSEC SA */
|
|
4
|
-
/* */
|
|
5
|
-
/* Should you receive a copy of this source code, you must check you */
|
|
6
|
-
/* have a proper, written authorization of INTERSEC to hold it. If you */
|
|
7
|
-
/* don't have such an authorization, you must DELETE all source code */
|
|
8
|
-
/* files in your possession, and inform INTERSEC of the fact you obtain */
|
|
9
|
-
/* these files. Should you not comply to these terms, you can be */
|
|
10
|
-
/* prosecuted in the extent permitted by applicable law. */
|
|
11
|
-
/* */
|
|
12
|
-
/**************************************************************************/
|
|
13
|
-
|
|
14
1
|
const _ = require('../tools.js');
|
|
15
2
|
const {
|
|
16
3
|
getInitialState,
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**************************************************************************/
|
|
2
|
-
/* */
|
|
3
|
-
/* Copyright (C) INTERSEC SA */
|
|
4
|
-
/* */
|
|
5
|
-
/* Should you receive a copy of this source code, you must check you */
|
|
6
|
-
/* have a proper, written authorization of INTERSEC to hold it. If you */
|
|
7
|
-
/* don't have such an authorization, you must DELETE all source code */
|
|
8
|
-
/* files in your possession, and inform INTERSEC of the fact you obtain */
|
|
9
|
-
/* these files. Should you not comply to these terms, you can be */
|
|
10
|
-
/* prosecuted in the extent permitted by applicable law. */
|
|
11
|
-
/* */
|
|
12
|
-
/**************************************************************************/
|
|
13
|
-
|
|
14
1
|
const _ = require('../tools.js');
|
|
15
2
|
const {
|
|
16
3
|
buildFetchCb,
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**************************************************************************/
|
|
2
|
-
/* */
|
|
3
|
-
/* Copyright (C) INTERSEC SA */
|
|
4
|
-
/* */
|
|
5
|
-
/* Should you receive a copy of this source code, you must check you */
|
|
6
|
-
/* have a proper, written authorization of INTERSEC to hold it. If you */
|
|
7
|
-
/* don't have such an authorization, you must DELETE all source code */
|
|
8
|
-
/* files in your possession, and inform INTERSEC of the fact you obtain */
|
|
9
|
-
/* these files. Should you not comply to these terms, you can be */
|
|
10
|
-
/* prosecuted in the extent permitted by applicable law. */
|
|
11
|
-
/* */
|
|
12
|
-
/**************************************************************************/
|
|
13
|
-
|
|
14
1
|
const _ = require('../tools.js');
|
|
15
2
|
const {
|
|
16
3
|
getOptions,
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**************************************************************************/
|
|
2
|
-
/* */
|
|
3
|
-
/* Copyright (C) INTERSEC SA */
|
|
4
|
-
/* */
|
|
5
|
-
/* Should you receive a copy of this source code, you must check you */
|
|
6
|
-
/* have a proper, written authorization of INTERSEC to hold it. If you */
|
|
7
|
-
/* don't have such an authorization, you must DELETE all source code */
|
|
8
|
-
/* files in your possession, and inform INTERSEC of the fact you obtain */
|
|
9
|
-
/* these files. Should you not comply to these terms, you can be */
|
|
10
|
-
/* prosecuted in the extent permitted by applicable law. */
|
|
11
|
-
/* */
|
|
12
|
-
/**************************************************************************/
|
|
13
|
-
|
|
14
1
|
const _ = require('../tools.js');
|
|
15
2
|
const {
|
|
16
3
|
getOptions,
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**************************************************************************/
|
|
2
|
-
/* */
|
|
3
|
-
/* Copyright (C) INTERSEC SA */
|
|
4
|
-
/* */
|
|
5
|
-
/* Should you receive a copy of this source code, you must check you */
|
|
6
|
-
/* have a proper, written authorization of INTERSEC to hold it. If you */
|
|
7
|
-
/* don't have such an authorization, you must DELETE all source code */
|
|
8
|
-
/* files in your possession, and inform INTERSEC of the fact you obtain */
|
|
9
|
-
/* these files. Should you not comply to these terms, you can be */
|
|
10
|
-
/* prosecuted in the extent permitted by applicable law. */
|
|
11
|
-
/* */
|
|
12
|
-
/**************************************************************************/
|
|
13
|
-
|
|
14
1
|
const _ = require('../tools.js');
|
|
15
2
|
const {
|
|
16
3
|
getOptions,
|