selectic 3.1.1 → 3.1.3

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/src/index.tsx CHANGED
@@ -206,11 +206,11 @@ export interface Props {
206
206
  iconFamily?: IconFamily;
207
207
 
208
208
  /** If enabled, it resets the dynamic cache when selectic opens */
209
- noCache?: Boolean;
209
+ noCache?: boolean;
210
210
 
211
211
  /** If true, the component opens (at start or if it is closed).
212
212
  * If false, the components closes (if it is opened). */
213
- open?: Boolean;
213
+ open?: boolean;
214
214
 
215
215
  /** Props which is not expected to change during the life time of the
216
216
  * component.
@@ -243,7 +243,7 @@ export function changeIcons(icons: PartialIcons, iconFamily?: IconFamily) {
243
243
  export default class Selectic extends Vue<Props> {
244
244
  public $refs: {
245
245
  mainInput: MainInput;
246
- extendedList: ExtendedList;
246
+ extendedList?: ExtendedList;
247
247
  };
248
248
 
249
249
  /* {{{ props */
@@ -349,19 +349,21 @@ export default class Selectic extends Vue<Props> {
349
349
  const store = this.store;
350
350
  const keepOpenWithOtherSelectic = this.params.keepOpenWithOtherSelectic;
351
351
  const extendedList = this.$refs.extendedList;
352
+ const extendedListEl: HTMLElement | undefined = extendedList?.$el;
352
353
 
353
- if (!extendedList) {
354
+ if (!extendedListEl) {
354
355
  /* this component is not focused anymore */
355
356
  if (!keepOpenWithOtherSelectic) {
356
357
  this.removeListeners();
357
358
  this.store.commit('isOpen', false);
358
359
  }
360
+
359
361
  return;
360
362
  }
361
363
 
362
364
  const target = evt.target as Node;
363
365
 
364
- if (!extendedList.$el.contains(target) && !this.$el.contains(target)) {
366
+ if (!extendedListEl.contains(target) && !this.$el.contains(target)) {
365
367
  store.commit('isOpen', false);
366
368
  }
367
369
  };
@@ -477,18 +479,27 @@ export default class Selectic extends Vue<Props> {
477
479
  /* {{{ private methods */
478
480
 
479
481
  private computeWidth() {
480
- const el = this.$refs.mainInput.$el as HTMLElement;
482
+ const mainInput = this.$refs?.mainInput;
483
+
484
+ const mainEl: HTMLElement | undefined = mainInput?.$el;
481
485
 
482
- this.width = el.offsetWidth;
486
+ if (!mainEl) {
487
+ /* This method has been called too soon (before render function)
488
+ * or too late (after unmount) */
489
+ return;
490
+ }
491
+
492
+ this.width = mainEl.offsetWidth;
483
493
  }
484
494
 
485
495
  private computeOffset(doNotAddListener = false) {
486
- const mainInput = this.$refs.mainInput;
496
+ const mainInput = this.$refs?.mainInput;
487
497
 
488
- const mainEl = mainInput?.$el as HTMLElement;
498
+ const mainEl: HTMLElement | undefined = mainInput?.$el;
489
499
 
490
500
  if (!mainEl) {
491
- /* This method has been called too soon (before render function) */
501
+ /* This method has been called too soon (before render function)
502
+ * or too late (after unmount) */
492
503
  return;
493
504
  }
494
505
 
@@ -669,13 +680,13 @@ export default class Selectic extends Vue<Props> {
669
680
  /* Await that focused element becomes active */
670
681
  setTimeout(() => {
671
682
  const focusedEl = document.activeElement;
672
- const extendedList = this.$refs.extendedList;
683
+ const extendedList = this.$refs?.extendedList;
673
684
 
674
685
  /* check if there is a focused element (if none the body is
675
686
  * selected) and if it is inside current Selectic */
676
687
  if (focusedEl === document.body
677
688
  || this.$el.contains(focusedEl)
678
- || (extendedList && extendedList.$el.contains(focusedEl)))
689
+ || extendedList?.$el.contains(focusedEl))
679
690
  {
680
691
  return;
681
692
  }
package/src/tools.ts CHANGED
@@ -117,3 +117,16 @@ export function compareOptions(oldOptions: OptionValue[], newOptions: OptionValu
117
117
  });
118
118
  });
119
119
  }
120
+
121
+ let displayLog = false;
122
+ export function debug(fName: string, step: string, ...args: any[]) {
123
+ if (!displayLog) {
124
+ return;
125
+ }
126
+
127
+ console.log('--%s-- [%s]', fName, step, ...args);
128
+ }
129
+ /** Enable logs for debugging */
130
+ debug.enable = (display: boolean) => {
131
+ displayLog = display;
132
+ };
@@ -699,6 +699,80 @@ tape.test('Store creation', (subT) => {
699
699
  t.end();
700
700
  });
701
701
 
702
+ sTest.test('should disable multiple select with the only enabled value selected', async (t) => {
703
+ const options = getOptions(3);
704
+ options[0].disabled = true;
705
+ options[1].disabled = true;
706
+
707
+ const store = new Store({
708
+ options: options,
709
+ disabled: false,
710
+ value: [2],
711
+ params: {
712
+ multiple: true,
713
+ autoDisabled: true,
714
+ allowClearSelection: false,
715
+ },
716
+ });
717
+
718
+ await sleep(0);
719
+
720
+ t.is(store.state.disabled, true);
721
+ t.deepEqual(store.state.internalValue, [2]);
722
+
723
+ t.end();
724
+ });
725
+
726
+ sTest.test('should not disable multiple select when it is possible to remove selected value', async (t) => {
727
+ const options = getOptions(3);
728
+ options[0].disabled = true;
729
+ options[1].disabled = true;
730
+
731
+ const store = new Store({
732
+ options: options,
733
+ disabled: false,
734
+ value: [1, 2],
735
+ params: {
736
+ multiple: true,
737
+ autoDisabled: true,
738
+ allowClearSelection: false,
739
+ },
740
+ });
741
+
742
+ await sleep(0);
743
+
744
+ /* It is possible to remove the item "2" because there is another value */
745
+ t.is(store.state.disabled, false);
746
+ t.deepEqual(store.state.internalValue, [1, 2]);
747
+
748
+ t.end();
749
+ });
750
+
751
+ sTest.test('should disable multiple select when exclusive disabled item is selected', async (t) => {
752
+ const options = getOptions(3);
753
+ options[1].disabled = true;
754
+ options[1].exclusive = true;
755
+
756
+ const store = new Store({
757
+ options: options,
758
+ disabled: false,
759
+ value: [1],
760
+ params: {
761
+ multiple: true,
762
+ autoDisabled: true,
763
+ allowClearSelection: false,
764
+ },
765
+ });
766
+
767
+ await sleep(0);
768
+
769
+ /* It is not possible to change the value */
770
+ t.is(store.state.disabled, true);
771
+ t.deepEqual(store.state.internalValue, [1]);
772
+
773
+ t.end();
774
+ });
775
+
702
776
  sTest.test('should not disable select without autoDisabled', async (t) => {
703
777
  const store = new Store({
704
778
  options: getOptions(1),
@@ -788,7 +862,7 @@ tape.test('Store creation', (subT) => {
788
862
 
789
863
  /* Load data */
790
864
  store.commit('isOpen', true);
791
- await _.nextVueTick(store, spy.promise);
865
+ await _.nextVueTick(store, spy.promise, sleep(0) /* await request resolution */);
792
866
  store.commit('isOpen', false);
793
867
  await sleep(0);
794
868
 
@@ -1343,7 +1417,7 @@ tape.test('Store creation', (subT) => {
1343
1417
  await sleep(0);
1344
1418
  t.is(store1.state.filteredOptions.length, 0);
1345
1419
  command1.fetch();
1346
- await _.nextVueTick(store1, spy1.promise);
1420
+ await _.nextVueTick(store1, spy1.promise, sleep(0) /* await request resolution */);
1347
1421
 
1348
1422
  t.is(store1.state.filteredOptions.length, 4);
1349
1423
 
@@ -1385,7 +1459,7 @@ tape.test('Store creation', (subT) => {
1385
1459
  store1.commit('isOpen', true);
1386
1460
  await sleep(0);
1387
1461
  command1.fetch();
1388
- await _.nextVueTick(store1, spy1.promise);
1462
+ await _.nextVueTick(store1, spy1.promise, sleep(0) /* await request resolution */);
1389
1463
 
1390
1464
  t.is(store1.state.filteredOptions.length, 3, 'should contain the groups');
1391
1465
 
@@ -1405,7 +1479,7 @@ tape.test('Store creation', (subT) => {
1405
1479
  store2.commit('isOpen', true);
1406
1480
  await sleep(0);
1407
1481
  command2.fetch();
1408
- await _.nextVueTick(store2, spy2.promise);
1482
+ await _.nextVueTick(store2, spy2.promise, sleep(0) /* await request resolution */);
1409
1483
 
1410
1484
  t.is(store2.state.filteredOptions.length, 4);
1411
1485
 
@@ -1425,7 +1499,7 @@ tape.test('Store creation', (subT) => {
1425
1499
  store3.commit('isOpen', true);
1426
1500
  await sleep(0);
1427
1501
  command3.fetch();
1428
- await _.nextVueTick(store3, spy3.promise);
1502
+ await _.nextVueTick(store3, spy3.promise, sleep(0) /* await request resolution */);
1429
1503
 
1430
1504
  t.is(store3.state.filteredOptions.length, 2);
1431
1505
  t.end();
@@ -1449,7 +1523,7 @@ tape.test('Store creation', (subT) => {
1449
1523
  store1.commit('isOpen', true);
1450
1524
  await sleep(0);
1451
1525
  command1.fetch();
1452
- await _.nextVueTick(store1, spy1.promise);
1526
+ await _.nextVueTick(store1, spy1.promise, sleep(0) /* await request resolution */);
1453
1527
 
1454
1528
  t.is(store1.state.filteredOptions.length, 3);
1455
1529
 
@@ -1470,7 +1544,7 @@ tape.test('Store creation', (subT) => {
1470
1544
  store2.commit('isOpen', true);
1471
1545
  await sleep(0);
1472
1546
  command2.fetch();
1473
- await _.nextVueTick(store2, spy2.promise);
1547
+ await _.nextVueTick(store2, spy2.promise, sleep(0) /* await request resolution */);
1474
1548
 
1475
1549
  t.is(store2.state.filteredOptions.length, 4);
1476
1550
 
@@ -1491,7 +1565,7 @@ tape.test('Store creation', (subT) => {
1491
1565
  store3.commit('isOpen', true);
1492
1566
  await sleep(0);
1493
1567
  command3.fetch();
1494
- await _.nextVueTick(store3, spy3.promise);
1568
+ await _.nextVueTick(store3, spy3.promise, sleep(0) /* await request resolution */);
1495
1569
 
1496
1570
  t.is(store3.state.filteredOptions.length, 2);
1497
1571
  t.end();
@@ -1540,7 +1614,7 @@ tape.test('Store creation', (subT) => {
1540
1614
  await sleep(0);
1541
1615
  t.is(store1.state.filteredOptions.length, 0);
1542
1616
  command1.fetch();
1543
- await _.nextVueTick(store1, spy1.promise);
1617
+ await _.nextVueTick(store1, spy1.promise, sleep(0) /* await request resolution */);
1544
1618
 
1545
1619
  t.is(store1.state.filteredOptions.length, 9);
1546
1620
  t.end();
@@ -1565,7 +1639,7 @@ tape.test('Store creation', (subT) => {
1565
1639
  t.is(store.state.filteredOptions.length, 5); // previous options should be displayed
1566
1640
  t.true(toHaveBeenCalledWith(spy, ['', 0, 100])); // dynamic index should always start at 0
1567
1641
  command.fetch();
1568
- await _.nextVueTick(store, spy.promise);
1642
+ await _.nextVueTick(store, spy.promise, sleep(0) /* await request resolution */);
1569
1643
 
1570
1644
  t.is(store.state.filteredOptions.length, 9); // finally all options should be displayed
1571
1645
  t.end();
@@ -1590,7 +1664,7 @@ tape.test('Store creation', (subT) => {
1590
1664
  t.true(toHaveBeenCalledWith(spy1, ['', 0, 100]));
1591
1665
 
1592
1666
  command1.fetch();
1593
- await _.nextVueTick(store1, spy1.promise);
1667
+ await _.nextVueTick(store1, spy1.promise, sleep(0) /* await request resolution */);
1594
1668
 
1595
1669
  t.is(store1.state.allOptions.length, 104);
1596
1670
  t.is(store1.state.filteredOptions.length, 104);
@@ -1675,7 +1749,7 @@ tape.test('Store creation', (subT) => {
1675
1749
  t.true(toHaveBeenCalled(spy));
1676
1750
 
1677
1751
  command.fetch();
1678
- await _.nextVueTick(store, spy.promise);
1752
+ await _.nextVueTick(store, spy.promise, sleep(0) /* await request resolution */);
1679
1753
 
1680
1754
  t.is(store.state.isOpen, true);
1681
1755
  t.is(store.state.filteredOptions.length, 4);