@vanilla-bean/components 1.1.0 → 2.0.0
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/Component/Component.js +226 -40
- package/Component/Component.scenarios.js +2 -2
- package/Component/Component.test.js +427 -40
- package/Component/README.md +480 -0
- package/Component/observeElementConnection.js +1 -1
- package/Elem/README.md +373 -0
- package/README.md +2 -2
- package/components/BottomSheet/BottomSheet.js +8 -16
- package/components/BottomSheet/README.md +1 -1
- package/components/Button/Button.js +12 -18
- package/components/Button/Button.lld.md +1 -1
- package/components/Calendar/Calendar.js +139 -59
- package/components/Calendar/CalendarEvent.js +9 -4
- package/components/Calendar/Toolbar.js +28 -20
- package/components/Calendar/index.js +1 -0
- package/components/Code/Code.js +26 -30
- package/components/Code/Code.lld.md +1 -1
- package/components/ColorPicker/ColorPicker.js +58 -58
- package/components/Dialog/Dialog.js +79 -73
- package/components/Dialog/Dialog.lld.md +1 -1
- package/components/Dialog/README.md +10 -10
- package/components/Form/Form.js +21 -17
- package/components/Form/Form.lld.md +2 -2
- package/components/Form/README.md +3 -3
- package/components/Icon/Icon.js +19 -11
- package/components/Input/Input.js +85 -67
- package/components/Input/README.md +7 -9
- package/components/Keyboard/Key.js +7 -10
- package/components/Keyboard/Keyboard.js +38 -46
- package/components/Keyboard/Keyboard.lld.md +1 -1
- package/components/Label/Label.js +52 -50
- package/components/Link/Link.js +14 -20
- package/components/List/List.js +28 -30
- package/components/Menu/Menu.js +19 -10
- package/components/Menu/Menu.lld.md +2 -2
- package/components/Notify/Notify.js +29 -19
- package/components/Notify/Notify.lld.md +2 -2
- package/components/Page/Page.lld.md +1 -1
- package/components/Popover/Popover.js +49 -44
- package/components/RadioButton/RadioButton.js +33 -29
- package/components/RadioButton/RadioButton.lld.md +1 -1
- package/components/Router/README.md +12 -12
- package/components/Router/Router.js +19 -21
- package/components/Select/README.md +5 -5
- package/components/Select/Select.js +25 -31
- package/components/Table/README.md +4 -4
- package/components/Table/Table.js +55 -36
- package/components/Table/Table.lld.md +1 -1
- package/components/TagList/Tag.js +16 -14
- package/components/TagList/TagList.js +15 -8
- package/components/TagList/TagList.lld.md +1 -1
- package/components/Tooltip/Tooltip.js +12 -25
- package/components/TooltipWrapper/TooltipWrapper.js +55 -49
- package/components/TooltipWrapper/TooltipWrapper.lld.md +2 -2
- package/components/Whiteboard/Whiteboard.js +45 -43
- package/components/Whiteboard/Whiteboard.lld.md +1 -1
- package/devTools/build.js +43 -0
- package/devTools/buildTypes.js +322 -0
- package/devTools/createComponent.js +155 -0
- package/devTools/extractJSDoc.js +395 -0
- package/devTools/processTemplate.js +500 -0
- package/devTools/updateComponentIndex.js +16 -0
- package/devTools/updateDemoViewIndex.js +90 -0
- package/eslint.config.cjs +5 -2
- package/index.d.ts +120 -62
- package/package.json +23 -22
- package/spellcheck.config.cjs +3 -0
- package/styled/README.md +329 -0
- package/theme/.test.js +2 -2
- package/theme/README.md +8 -8
- package/theme/colors.js +16 -13
- package/theme/colors.test.js +28 -0
- package/utils/browser.js +1 -1
- package/utils/element.js +2 -2
- package/FontWithASyntaxHighlighter-Regular.woff2 +0 -0
|
@@ -532,96 +532,483 @@ describe('Component', () => {
|
|
|
532
532
|
});
|
|
533
533
|
});
|
|
534
534
|
|
|
535
|
-
describe('static
|
|
536
|
-
test('
|
|
537
|
-
|
|
535
|
+
describe('static schema', () => {
|
|
536
|
+
test('schema defaults are merged automatically', () => {
|
|
537
|
+
class TestComp extends Component {
|
|
538
|
+
static schema = {
|
|
539
|
+
label: { default: 'default label' },
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
const comp = new TestComp();
|
|
544
|
+
expect(comp.options.label).toBe('default label');
|
|
545
|
+
comp.destroy();
|
|
546
|
+
});
|
|
538
547
|
|
|
548
|
+
test('instance options override schema defaults', () => {
|
|
539
549
|
class TestComp extends Component {
|
|
540
|
-
static
|
|
541
|
-
label
|
|
542
|
-
called.push(value);
|
|
543
|
-
},
|
|
550
|
+
static schema = {
|
|
551
|
+
label: { default: 'default label' },
|
|
544
552
|
};
|
|
545
553
|
}
|
|
546
554
|
|
|
547
|
-
const comp = new TestComp({ label: '
|
|
548
|
-
expect(
|
|
555
|
+
const comp = new TestComp({ label: 'custom' });
|
|
556
|
+
expect(comp.options.label).toBe('custom');
|
|
549
557
|
comp.destroy();
|
|
550
558
|
});
|
|
551
559
|
|
|
552
|
-
test('
|
|
560
|
+
test('child class schema defaults override parent defaults per-key', () => {
|
|
561
|
+
class Parent extends Component {
|
|
562
|
+
static schema = {
|
|
563
|
+
label: { default: 'parent' },
|
|
564
|
+
size: { default: 'small' },
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
class Child extends Parent {
|
|
569
|
+
static schema = {
|
|
570
|
+
label: { default: 'child' },
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
const comp = new Child();
|
|
575
|
+
expect(comp.options.label).toBe('child');
|
|
576
|
+
expect(comp.options.size).toBe('small');
|
|
577
|
+
comp.destroy();
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
test('getter defaults evaluate fresh per instance', () => {
|
|
581
|
+
let evaluations = 0;
|
|
582
|
+
|
|
583
|
+
class TestComp extends Component {
|
|
584
|
+
static schema = {
|
|
585
|
+
stamp: {
|
|
586
|
+
get default() {
|
|
587
|
+
return ++evaluations;
|
|
588
|
+
},
|
|
589
|
+
},
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
const first = new TestComp();
|
|
594
|
+
const second = new TestComp();
|
|
595
|
+
expect(first.options.stamp).toBe(1);
|
|
596
|
+
expect(second.options.stamp).toBe(2);
|
|
597
|
+
first.destroy();
|
|
598
|
+
second.destroy();
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
test('set runs on render and reactive update', () => {
|
|
553
602
|
const called = [];
|
|
554
603
|
|
|
555
604
|
class TestComp extends Component {
|
|
556
|
-
static
|
|
557
|
-
label
|
|
558
|
-
|
|
605
|
+
static schema = {
|
|
606
|
+
label: {
|
|
607
|
+
default: 'first',
|
|
608
|
+
set(value) {
|
|
609
|
+
called.push(value);
|
|
610
|
+
},
|
|
559
611
|
},
|
|
560
612
|
};
|
|
561
613
|
}
|
|
562
614
|
|
|
563
|
-
const comp = new TestComp(
|
|
615
|
+
const comp = new TestComp();
|
|
564
616
|
comp.options.label = 'second';
|
|
565
|
-
expect(called).
|
|
617
|
+
expect(called).toEqual(['first', 'second']);
|
|
618
|
+
comp.destroy();
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
test('declared keys with no DOM match are stored silently', () => {
|
|
622
|
+
class TestComp extends Component {
|
|
623
|
+
static schema = {
|
|
624
|
+
gameState: {},
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
const comp = new TestComp({ gameState: { score: 0 } });
|
|
629
|
+
comp.options.gameState = { score: 5 };
|
|
630
|
+
expect(comp.options.gameState).toEqual({ score: 5 });
|
|
631
|
+
expect(comp.elem.gameState).toBeUndefined();
|
|
632
|
+
comp.destroy();
|
|
633
|
+
});
|
|
634
|
+
|
|
635
|
+
test('declared callback options are stored without event registration or warning', () => {
|
|
636
|
+
const warnings = [];
|
|
637
|
+
const originalWarn = console.warn;
|
|
638
|
+
console.warn = (...args) => warnings.push(args.join(' '));
|
|
639
|
+
|
|
640
|
+
class TestComp extends Component {
|
|
641
|
+
static schema = {
|
|
642
|
+
onCustomAction: {},
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
const callback = () => {};
|
|
647
|
+
const comp = new TestComp({ onCustomAction: callback });
|
|
648
|
+
console.warn = originalWarn;
|
|
649
|
+
|
|
650
|
+
expect(comp.options.onCustomAction).toBe(callback);
|
|
651
|
+
expect(comp.onCustomAction).toBeUndefined();
|
|
652
|
+
expect(warnings.filter(warning => warning.includes('onCustomAction'))).toEqual([]);
|
|
566
653
|
comp.destroy();
|
|
567
654
|
});
|
|
568
655
|
|
|
569
|
-
test('
|
|
570
|
-
|
|
571
|
-
|
|
656
|
+
test('data: true forces store-only routing for DOM-colliding names', () => {
|
|
657
|
+
class TestComp extends Component {
|
|
658
|
+
static schema = {
|
|
659
|
+
title: { data: true },
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
const comp = new TestComp({ title: 'component data' });
|
|
664
|
+
expect(comp.options.title).toBe('component data');
|
|
665
|
+
expect(comp.elem.title).toBe('');
|
|
666
|
+
comp.destroy();
|
|
667
|
+
});
|
|
668
|
+
|
|
669
|
+
test('subclass set shadows parent set when next is not called', () => {
|
|
670
|
+
const order = [];
|
|
572
671
|
|
|
573
672
|
class Parent extends Component {
|
|
574
|
-
static
|
|
575
|
-
label
|
|
576
|
-
|
|
673
|
+
static schema = {
|
|
674
|
+
label: {
|
|
675
|
+
set(value) {
|
|
676
|
+
order.push(`parent:${value}`);
|
|
677
|
+
},
|
|
577
678
|
},
|
|
578
679
|
};
|
|
579
680
|
}
|
|
580
681
|
|
|
581
682
|
class Child extends Parent {
|
|
582
|
-
static
|
|
583
|
-
label
|
|
584
|
-
|
|
683
|
+
static schema = {
|
|
684
|
+
label: {
|
|
685
|
+
set(value) {
|
|
686
|
+
order.push(`child:${value}`);
|
|
687
|
+
},
|
|
585
688
|
},
|
|
586
689
|
};
|
|
587
690
|
}
|
|
588
691
|
|
|
589
692
|
const comp = new Child({ label: 'test' });
|
|
590
|
-
expect(
|
|
591
|
-
expect(parentCalls).not.toContain('test');
|
|
693
|
+
expect(order).toEqual(['child:test']);
|
|
592
694
|
comp.destroy();
|
|
593
695
|
});
|
|
594
696
|
|
|
595
|
-
test('
|
|
596
|
-
const
|
|
597
|
-
const childCalls = [];
|
|
697
|
+
test('subclass set chains into parent set via next', () => {
|
|
698
|
+
const order = [];
|
|
598
699
|
|
|
599
700
|
class Parent extends Component {
|
|
600
|
-
static
|
|
601
|
-
label
|
|
602
|
-
|
|
701
|
+
static schema = {
|
|
702
|
+
label: {
|
|
703
|
+
set(value) {
|
|
704
|
+
order.push(`parent:${value}`);
|
|
705
|
+
},
|
|
603
706
|
},
|
|
604
707
|
};
|
|
605
708
|
}
|
|
606
709
|
|
|
607
710
|
class Child extends Parent {
|
|
608
|
-
static
|
|
609
|
-
label
|
|
610
|
-
|
|
611
|
-
|
|
711
|
+
static schema = {
|
|
712
|
+
label: {
|
|
713
|
+
set(value, next) {
|
|
714
|
+
order.push(`child:${value}`);
|
|
715
|
+
next(value);
|
|
716
|
+
},
|
|
612
717
|
},
|
|
613
718
|
};
|
|
614
719
|
}
|
|
615
720
|
|
|
616
721
|
const comp = new Child({ label: 'test' });
|
|
617
|
-
expect(
|
|
618
|
-
|
|
722
|
+
expect(order).toEqual(['child:test', 'parent:test']);
|
|
723
|
+
comp.destroy();
|
|
724
|
+
});
|
|
725
|
+
|
|
726
|
+
test('defaultOptions getter reflects merged schema defaults', () => {
|
|
727
|
+
class TestComp extends Component {
|
|
728
|
+
static schema = {
|
|
729
|
+
label: { default: 'from schema' },
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
const comp = new TestComp();
|
|
734
|
+
expect(comp.defaultOptions.label).toBe('from schema');
|
|
735
|
+
expect(comp.defaultOptions.tag).toBe('div');
|
|
736
|
+
comp.destroy();
|
|
737
|
+
});
|
|
738
|
+
|
|
739
|
+
test('attribute: true routes the key through setAttribute', () => {
|
|
740
|
+
class TestComp extends Component {
|
|
741
|
+
static schema = {
|
|
742
|
+
colspan: { attribute: true },
|
|
743
|
+
};
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
const comp = new TestComp({ colspan: '2' });
|
|
747
|
+
expect(comp.elem.getAttribute('colspan')).toBe('2');
|
|
748
|
+
comp.destroy();
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
test('priority: true keys process before other keys', () => {
|
|
752
|
+
const order = [];
|
|
753
|
+
|
|
754
|
+
class TestComp extends Component {
|
|
755
|
+
static schema = {
|
|
756
|
+
first: {
|
|
757
|
+
priority: true,
|
|
758
|
+
set() {
|
|
759
|
+
order.push('first');
|
|
760
|
+
},
|
|
761
|
+
},
|
|
762
|
+
second: {
|
|
763
|
+
set() {
|
|
764
|
+
order.push('second');
|
|
765
|
+
},
|
|
766
|
+
},
|
|
767
|
+
};
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
const comp = new TestComp({ second: 'b', first: 'a' });
|
|
771
|
+
expect(order).toEqual(['first', 'second']);
|
|
772
|
+
comp.destroy();
|
|
773
|
+
});
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
describe('schema field inheritance', () => {
|
|
777
|
+
test('subclass can opt out of a parent data flag with data: false', () => {
|
|
778
|
+
class Parent extends Component {
|
|
779
|
+
static schema = {
|
|
780
|
+
title: { data: true },
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
class Child extends Parent {
|
|
785
|
+
static schema = {
|
|
786
|
+
title: { data: false },
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
const parent = new Parent({ title: 'stored-only' });
|
|
791
|
+
const child = new Child({ title: 'routed' });
|
|
792
|
+
expect(parent.elem.title).toBe('');
|
|
793
|
+
expect(child.elem.title).toBe('routed');
|
|
794
|
+
parent.destroy();
|
|
795
|
+
child.destroy();
|
|
796
|
+
});
|
|
797
|
+
|
|
798
|
+
test('subclass set without a data field keeps the parent data flag', () => {
|
|
799
|
+
const seen = [];
|
|
800
|
+
|
|
801
|
+
class Parent extends Component {
|
|
802
|
+
static schema = {
|
|
803
|
+
title: { data: true },
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
class Child extends Parent {
|
|
808
|
+
static schema = {
|
|
809
|
+
title: {
|
|
810
|
+
set(value, next) {
|
|
811
|
+
seen.push(value);
|
|
812
|
+
next(value);
|
|
813
|
+
},
|
|
814
|
+
},
|
|
815
|
+
};
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
const child = new Child({ title: 'stored-only' });
|
|
819
|
+
expect(seen).toEqual(['stored-only']);
|
|
820
|
+
expect(child.elem.title).toBe('');
|
|
821
|
+
child.destroy();
|
|
822
|
+
});
|
|
823
|
+
|
|
824
|
+
test('subclass can lift a parent enum with enum: null', () => {
|
|
825
|
+
class Parent extends Component {
|
|
826
|
+
static schema = {
|
|
827
|
+
variant: { enum: ['plain'], data: true },
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
class Child extends Parent {
|
|
832
|
+
static schema = {
|
|
833
|
+
variant: { enum: null },
|
|
834
|
+
};
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
expect(() => new Parent({ variant: 'wild' })).toThrow();
|
|
838
|
+
const child = new Child({ variant: 'wild' });
|
|
839
|
+
expect(child.options.variant).toBe('wild');
|
|
840
|
+
child.destroy();
|
|
841
|
+
});
|
|
842
|
+
});
|
|
843
|
+
|
|
844
|
+
describe('schema enum', () => {
|
|
845
|
+
class EnumComp extends Component {
|
|
846
|
+
static schema = {
|
|
847
|
+
variant: { default: 'plain', enum: ['plain', 'fancy'] },
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
test('valid values pass on construction and reactive update', () => {
|
|
852
|
+
const comp = new EnumComp({ variant: 'fancy' });
|
|
853
|
+
comp.options.variant = 'plain';
|
|
854
|
+
expect(comp.options.variant).toBe('plain');
|
|
855
|
+
comp.destroy();
|
|
856
|
+
});
|
|
857
|
+
|
|
858
|
+
test('invalid values throw with the valid values listed', () => {
|
|
859
|
+
expect(() => new EnumComp({ variant: 'bogus' })).toThrow(
|
|
860
|
+
'"bogus" is not a valid variant. The variant must be one of the following values: plain, fancy',
|
|
861
|
+
);
|
|
862
|
+
});
|
|
863
|
+
|
|
864
|
+
test('invalid reactive assignment throws', () => {
|
|
865
|
+
const comp = new EnumComp();
|
|
866
|
+
expect(() => (comp.options.variant = 'bogus')).toThrow();
|
|
867
|
+
comp.destroy();
|
|
868
|
+
});
|
|
869
|
+
|
|
870
|
+
test('null and undefined bypass enum validation', () => {
|
|
871
|
+
class OptionalEnumComp extends Component {
|
|
872
|
+
static schema = {
|
|
873
|
+
variant: { enum: ['plain', 'fancy'] },
|
|
874
|
+
};
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
const comp = new OptionalEnumComp({ variant: undefined });
|
|
878
|
+
comp.options.variant = null;
|
|
879
|
+
comp.destroy();
|
|
880
|
+
});
|
|
881
|
+
|
|
882
|
+
test('optionEnum exposes the declared values, nearest class first', () => {
|
|
883
|
+
class Wider extends EnumComp {
|
|
884
|
+
static schema = {
|
|
885
|
+
variant: { enum: ['plain', 'fancy', 'wild'] },
|
|
886
|
+
};
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
const base = new EnumComp();
|
|
890
|
+
const wider = new Wider({ variant: 'wild' });
|
|
891
|
+
expect(base.optionEnum('variant')).toEqual(['plain', 'fancy']);
|
|
892
|
+
expect(wider.optionEnum('variant')).toEqual(['plain', 'fancy', 'wild']);
|
|
893
|
+
expect(base.optionEnum('missing')).toBeUndefined();
|
|
894
|
+
base.destroy();
|
|
895
|
+
wider.destroy();
|
|
896
|
+
});
|
|
897
|
+
});
|
|
898
|
+
|
|
899
|
+
describe('static events', () => {
|
|
900
|
+
test('declared events register via on() and fire via emit()', () => {
|
|
901
|
+
const received = [];
|
|
902
|
+
|
|
903
|
+
class TestComp extends Component {
|
|
904
|
+
static events = ['activate'];
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
const comp = new TestComp({ onActivate: event => received.push(event.detail) });
|
|
908
|
+
comp.emit('activate', 'payload');
|
|
909
|
+
expect(received).toEqual(['payload']);
|
|
910
|
+
comp.destroy();
|
|
911
|
+
});
|
|
912
|
+
|
|
913
|
+
test('subclass events union with parent events instead of replacing', () => {
|
|
914
|
+
class Parent extends Component {
|
|
915
|
+
static events = ['open'];
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
class Child extends Parent {
|
|
919
|
+
static events = ['close'];
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
const received = [];
|
|
923
|
+
const comp = new Child({
|
|
924
|
+
onOpen: () => received.push('open'),
|
|
925
|
+
onClose: () => received.push('close'),
|
|
926
|
+
});
|
|
927
|
+
comp.emit('open');
|
|
928
|
+
comp.emit('close');
|
|
929
|
+
expect(received).toEqual(['open', 'close']);
|
|
930
|
+
comp.destroy();
|
|
931
|
+
});
|
|
932
|
+
});
|
|
933
|
+
|
|
934
|
+
describe('static prepareOptions', () => {
|
|
935
|
+
test('transforms merged options before processing', () => {
|
|
936
|
+
class TestComp extends Component {
|
|
937
|
+
static schema = {
|
|
938
|
+
label: { default: 'raw' },
|
|
939
|
+
};
|
|
940
|
+
|
|
941
|
+
static prepareOptions(options) {
|
|
942
|
+
return { ...options, textContent: `prepared:${options.label}` };
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
const comp = new TestComp();
|
|
947
|
+
expect(comp.elem.textContent).toBe('prepared:raw');
|
|
948
|
+
comp.destroy();
|
|
949
|
+
});
|
|
950
|
+
|
|
951
|
+
test('sees schema defaults from child classes (merged view)', () => {
|
|
952
|
+
const seen = [];
|
|
953
|
+
|
|
954
|
+
class Parent extends Component {
|
|
955
|
+
static prepareOptions(options) {
|
|
956
|
+
seen.push(options.mode);
|
|
957
|
+
return options;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
class Child extends Parent {
|
|
962
|
+
static schema = {
|
|
963
|
+
mode: { default: 'child-mode', data: true },
|
|
964
|
+
};
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
const comp = new Child();
|
|
968
|
+
expect(seen).toEqual(['child-mode']);
|
|
969
|
+
comp.destroy();
|
|
970
|
+
});
|
|
971
|
+
|
|
972
|
+
test('runs leaf-first so child transforms feed parent hooks', () => {
|
|
973
|
+
const order = [];
|
|
974
|
+
|
|
975
|
+
class Parent extends Component {
|
|
976
|
+
static prepareOptions(options) {
|
|
977
|
+
order.push(`parent:${options.stage}`);
|
|
978
|
+
return options;
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
class Child extends Parent {
|
|
983
|
+
static prepareOptions(options) {
|
|
984
|
+
order.push(`child:${options.stage}`);
|
|
985
|
+
return { ...options, stage: 'transformed' };
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
const comp = new Child({ stage: 'raw', 'data-stage': 'x' });
|
|
990
|
+
expect(order).toEqual(['child:raw', 'parent:transformed']);
|
|
991
|
+
comp.destroy();
|
|
992
|
+
});
|
|
993
|
+
|
|
994
|
+
test('receives constructor children', () => {
|
|
995
|
+
let receivedChildren;
|
|
996
|
+
|
|
997
|
+
class TestComp extends Component {
|
|
998
|
+
static prepareOptions(options, children) {
|
|
999
|
+
receivedChildren = children;
|
|
1000
|
+
return options;
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
const comp = new TestComp({}, 'child content');
|
|
1005
|
+
expect(receivedChildren).toEqual(['child content']);
|
|
619
1006
|
comp.destroy();
|
|
620
1007
|
});
|
|
621
1008
|
});
|
|
622
1009
|
|
|
623
1010
|
describe('cleanup system', () => {
|
|
624
|
-
test('addCleanup chains
|
|
1011
|
+
test('addCleanup chains - both functions run on processCleanup', () => {
|
|
625
1012
|
const comp = new Component({ autoRender: false });
|
|
626
1013
|
const calls = [];
|
|
627
1014
|
|
|
@@ -695,7 +1082,7 @@ describe('Component', () => {
|
|
|
695
1082
|
expect(handler).toHaveBeenCalled();
|
|
696
1083
|
});
|
|
697
1084
|
|
|
698
|
-
test('on* method route
|
|
1085
|
+
test('on* method route - onPointerPress calls the component method', () => {
|
|
699
1086
|
const handler = mock();
|
|
700
1087
|
component = new Component({ tag: 'button', onPointerPress: handler, appendTo: document.body });
|
|
701
1088
|
|