selectic 3.0.3 → 3.0.7

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.
Binary file
@@ -101,6 +101,26 @@ let closePreviousSelectic;
101
101
  let uid = 0;
102
102
  class SelecticStore {
103
103
  constructor(props = {}) {
104
+ /* Do not need reactivity */
105
+ this.requestId = 0;
106
+ this._uid = ++uid;
107
+ /* {{{ Props */
108
+ const defaultProps = {
109
+ value: null,
110
+ selectionIsExcluded: false,
111
+ disabled: false,
112
+ options: null,
113
+ childOptions: [],
114
+ groups: [],
115
+ texts: null,
116
+ params: {},
117
+ fetchCallback: null,
118
+ getItemsCallback: null,
119
+ keepOpenWithOtherSelectic: false,
120
+ };
121
+ const propsVal = assignObject(defaultProps, props);
122
+ this.props = vue.reactive(propsVal);
123
+ /* }}} */
104
124
  /* {{{ data */
105
125
  this.state = vue.reactive({
106
126
  multiple: false,
@@ -141,27 +161,6 @@ class SelecticStore {
141
161
  automaticClose: false,
142
162
  },
143
163
  });
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
164
  this.data = vue.reactive({
166
165
  labels: Object.assign({}, messages),
167
166
  itemsPerPage: 10,
@@ -275,8 +274,8 @@ class SelecticStore {
275
274
  * and ensure convertValue run with correct state */
276
275
  assignObject(this.state, {
277
276
  internalValue: this.convertTypeValue(value),
278
- selectionIsExcluded: props.selectionIsExcluded,
279
- disabled: props.disabled,
277
+ selectionIsExcluded: !!this.props.selectionIsExcluded,
278
+ disabled: !!this.props.disabled, /* XXX: !! is needed to copy value and not proxy reference */
280
279
  });
281
280
  this.checkHideFilter();
282
281
  if (this.props.texts) {
@@ -2025,15 +2024,26 @@ let Selectic = class Selectic extends vtyx.Vue {
2025
2024
  }
2026
2025
  get outsideListener() {
2027
2026
  return (evt) => {
2028
- const target = evt.target;
2029
2027
  if (!this.$refs) {
2030
2028
  /* this component should have been destroyed */
2031
2029
  this.removeListeners();
2032
2030
  this.store.commit('isOpen', false);
2033
2031
  return;
2034
2032
  }
2035
- if (!this.$refs.extendedList.$el.contains(target) && !this.$el.contains(target)) {
2036
- this.store.commit('isOpen', false);
2033
+ const store = this.store;
2034
+ const keepOpenWithOtherSelectic = this.params.keepOpenWithOtherSelectic;
2035
+ const extendedList = this.$refs.extendedList;
2036
+ if (!extendedList) {
2037
+ /* this component is not focused anymore */
2038
+ if (!keepOpenWithOtherSelectic) {
2039
+ this.removeListeners();
2040
+ this.store.commit('isOpen', false);
2041
+ }
2042
+ return;
2043
+ }
2044
+ const target = evt.target;
2045
+ if (!extendedList.$el.contains(target) && !this.$el.contains(target)) {
2046
+ store.commit('isOpen', false);
2037
2047
  }
2038
2048
  };
2039
2049
  }
@@ -2557,6 +2567,15 @@ __decorate([
2557
2567
  __decorate([
2558
2568
  vtyx.Watch('store.state.internalValue')
2559
2569
  ], Selectic.prototype, "onInternalValueChange", null);
2570
+ __decorate([
2571
+ vtyx.Emit('input'),
2572
+ vtyx.Emit('change'),
2573
+ vtyx.Emit('open'),
2574
+ vtyx.Emit('focus'),
2575
+ vtyx.Emit('close'),
2576
+ vtyx.Emit('blur'),
2577
+ vtyx.Emit('item:click')
2578
+ ], Selectic.prototype, "render", null);
2560
2579
  Selectic = __decorate([
2561
2580
  vtyx.Component
2562
2581
  ], Selectic);
@@ -1,4 +1,4 @@
1
- import { Prop, Watch, Component, Vue, h } from 'vtyx';
1
+ import { Prop, Watch, Component, Vue, h, Emit } from 'vtyx';
2
2
  import { reactive, computed, unref, watch } from 'vue';
3
3
 
4
4
  function styleInject(css, ref) {
@@ -97,6 +97,26 @@ let closePreviousSelectic;
97
97
  let uid = 0;
98
98
  class SelecticStore {
99
99
  constructor(props = {}) {
100
+ /* Do not need reactivity */
101
+ this.requestId = 0;
102
+ this._uid = ++uid;
103
+ /* {{{ Props */
104
+ const defaultProps = {
105
+ value: null,
106
+ selectionIsExcluded: false,
107
+ disabled: false,
108
+ options: null,
109
+ childOptions: [],
110
+ groups: [],
111
+ texts: null,
112
+ params: {},
113
+ fetchCallback: null,
114
+ getItemsCallback: null,
115
+ keepOpenWithOtherSelectic: false,
116
+ };
117
+ const propsVal = assignObject(defaultProps, props);
118
+ this.props = reactive(propsVal);
119
+ /* }}} */
100
120
  /* {{{ data */
101
121
  this.state = reactive({
102
122
  multiple: false,
@@ -137,27 +157,6 @@ class SelecticStore {
137
157
  automaticClose: false,
138
158
  },
139
159
  });
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
160
  this.data = reactive({
162
161
  labels: Object.assign({}, messages),
163
162
  itemsPerPage: 10,
@@ -271,8 +270,8 @@ class SelecticStore {
271
270
  * and ensure convertValue run with correct state */
272
271
  assignObject(this.state, {
273
272
  internalValue: this.convertTypeValue(value),
274
- selectionIsExcluded: props.selectionIsExcluded,
275
- disabled: props.disabled,
273
+ selectionIsExcluded: !!this.props.selectionIsExcluded,
274
+ disabled: !!this.props.disabled, /* XXX: !! is needed to copy value and not proxy reference */
276
275
  });
277
276
  this.checkHideFilter();
278
277
  if (this.props.texts) {
@@ -2021,15 +2020,26 @@ let Selectic = class Selectic extends Vue {
2021
2020
  }
2022
2021
  get outsideListener() {
2023
2022
  return (evt) => {
2024
- const target = evt.target;
2025
2023
  if (!this.$refs) {
2026
2024
  /* this component should have been destroyed */
2027
2025
  this.removeListeners();
2028
2026
  this.store.commit('isOpen', false);
2029
2027
  return;
2030
2028
  }
2031
- if (!this.$refs.extendedList.$el.contains(target) && !this.$el.contains(target)) {
2032
- this.store.commit('isOpen', false);
2029
+ const store = this.store;
2030
+ const keepOpenWithOtherSelectic = this.params.keepOpenWithOtherSelectic;
2031
+ const extendedList = this.$refs.extendedList;
2032
+ if (!extendedList) {
2033
+ /* this component is not focused anymore */
2034
+ if (!keepOpenWithOtherSelectic) {
2035
+ this.removeListeners();
2036
+ this.store.commit('isOpen', false);
2037
+ }
2038
+ return;
2039
+ }
2040
+ const target = evt.target;
2041
+ if (!extendedList.$el.contains(target) && !this.$el.contains(target)) {
2042
+ store.commit('isOpen', false);
2033
2043
  }
2034
2044
  };
2035
2045
  }
@@ -2553,6 +2563,15 @@ __decorate([
2553
2563
  __decorate([
2554
2564
  Watch('store.state.internalValue')
2555
2565
  ], Selectic.prototype, "onInternalValueChange", null);
2566
+ __decorate([
2567
+ Emit('input'),
2568
+ Emit('change'),
2569
+ Emit('open'),
2570
+ Emit('focus'),
2571
+ Emit('close'),
2572
+ Emit('blur'),
2573
+ Emit('item:click')
2574
+ ], Selectic.prototype, "render", null);
2556
2575
  Selectic = __decorate([
2557
2576
  Component
2558
2577
  ], Selectic);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "selectic",
3
- "version": "3.0.3",
3
+ "version": "3.0.7",
4
4
  "description": "Smart Select for VueJS 3.x",
5
5
  "main": "dist/selectic.common.js",
6
6
  "module": "dist/selectic.esm.js",
package/src/Store.tsx CHANGED
@@ -411,48 +411,7 @@ export default class SelecticStore {
411
411
 
412
412
  /* {{{ data */
413
413
 
414
- public state = reactive<SelecticStoreState>({
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
- });
414
+ public state: SelecticStoreState;
456
415
  public data: Data;
457
416
 
458
417
  /* Do not need reactivity */
@@ -500,6 +459,49 @@ export default class SelecticStore {
500
459
  /* }}} */
501
460
  /* {{{ data */
502
461
 
462
+ this.state = reactive<SelecticStoreState>({
463
+ multiple: false,
464
+ disabled: false,
465
+ placeholder: '',
466
+ hideFilter: false,
467
+ keepFilterOpen: false,
468
+ allowRevert: undefined,
469
+ allowClearSelection: false,
470
+ autoSelect: true,
471
+ autoDisabled: true,
472
+ strictValue: false,
473
+ selectionOverflow: 'collapsed',
474
+
475
+ internalValue: null,
476
+ isOpen: false,
477
+ searchText: '',
478
+ selectionIsExcluded: false,
479
+ allOptions: [],
480
+ dynOptions: [],
481
+ filteredOptions: [],
482
+ selectedOptions: null,
483
+ totalAllOptions: Infinity,
484
+ totalDynOptions: Infinity,
485
+ totalFilteredOptions: Infinity,
486
+ groups: new Map(),
487
+ offsetItem: 0,
488
+ activeItemIdx: -1,
489
+ pageSize: 100,
490
+ listPosition: 'auto',
491
+
492
+ optionBehaviorOperation: 'sort',
493
+ optionBehaviorOrder: ['O', 'D', 'E'],
494
+
495
+ status: {
496
+ searching: false,
497
+ errorMessage: '',
498
+ areAllSelected: false,
499
+ hasChanged: false,
500
+ automaticChange: false,
501
+ automaticClose: false,
502
+ },
503
+ });
504
+
503
505
  this.data = reactive({
504
506
  labels: Object.assign({}, messages),
505
507
  itemsPerPage: 10,
@@ -649,8 +651,8 @@ export default class SelecticStore {
649
651
  * and ensure convertValue run with correct state */
650
652
  assignObject(this.state, {
651
653
  internalValue: this.convertTypeValue(value),
652
- selectionIsExcluded: props.selectionIsExcluded,
653
- disabled: props.disabled,
654
+ selectionIsExcluded: !!this.props.selectionIsExcluded,
655
+ disabled: !!this.props.disabled, /* XXX: !! is needed to copy value and not proxy reference */
654
656
  });
655
657
 
656
658
  this.checkHideFilter();
package/src/index.tsx CHANGED
@@ -18,7 +18,7 @@
18
18
  * close [component]: triggered when the list closes.
19
19
  */
20
20
 
21
- import {Vue, Component, Prop, Watch, h} from 'vtyx';
21
+ import {Vue, Component, Emit, Prop, Watch, h} from 'vtyx';
22
22
  import './css/selectic.css';
23
23
 
24
24
  import Store, {
@@ -309,8 +309,6 @@ export default class Selectic extends Vue<Props> {
309
309
 
310
310
  get outsideListener() {
311
311
  return (evt: MouseEvent) => {
312
- const target = evt.target as Node;
313
-
314
312
  if (!this.$refs) {
315
313
  /* this component should have been destroyed */
316
314
  this.removeListeners();
@@ -318,8 +316,23 @@ export default class Selectic extends Vue<Props> {
318
316
  return;
319
317
  }
320
318
 
321
- if (!this.$refs.extendedList.$el.contains(target) && !this.$el.contains(target)) {
322
- this.store.commit('isOpen', false);
319
+ const store = this.store;
320
+ const keepOpenWithOtherSelectic = this.params.keepOpenWithOtherSelectic;
321
+ const extendedList = this.$refs.extendedList;
322
+
323
+ if (!extendedList) {
324
+ /* this component is not focused anymore */
325
+ if (!keepOpenWithOtherSelectic) {
326
+ this.removeListeners();
327
+ this.store.commit('isOpen', false);
328
+ }
329
+ return;
330
+ }
331
+
332
+ const target = evt.target as Node;
333
+
334
+ if (!extendedList.$el.contains(target) && !this.$el.contains(target)) {
335
+ store.commit('isOpen', false);
323
336
  }
324
337
  };
325
338
  }
@@ -844,6 +857,13 @@ export default class Selectic extends Vue<Props> {
844
857
 
845
858
  /* }}} */
846
859
 
860
+ @Emit('input')
861
+ @Emit('change')
862
+ @Emit('open')
863
+ @Emit('focus')
864
+ @Emit('close')
865
+ @Emit('blur')
866
+ @Emit('item:click')
847
867
  public render() {
848
868
  const id = this.id || undefined;
849
869
  const store = this.store;
@@ -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/List.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Vue, h } from 'vtyx';
2
- import Store, { OptionItem, OptionId } from './Store';
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;