@esmx/router-vue 3.0.0-rc.74 → 3.0.0-rc.76
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/router-link.mjs +7 -7
- package/dist/router-link.test.mjs +148 -1
- package/package.json +3 -3
- package/src/router-link.test.ts +181 -1
- package/src/router-link.ts +7 -7
package/dist/router-link.mjs
CHANGED
|
@@ -82,16 +82,16 @@ export const RouterLink = defineComponent({
|
|
|
82
82
|
}
|
|
83
83
|
},
|
|
84
84
|
setup(props, context) {
|
|
85
|
-
const link = useLink(props)
|
|
85
|
+
const link = useLink(props);
|
|
86
86
|
if (isVue3) {
|
|
87
87
|
return () => {
|
|
88
88
|
var _a, _b;
|
|
89
89
|
return h(
|
|
90
|
-
link.tag,
|
|
90
|
+
link.value.tag,
|
|
91
91
|
{
|
|
92
|
-
...link.attributes,
|
|
92
|
+
...link.value.attributes,
|
|
93
93
|
...context.attrs,
|
|
94
|
-
...link.createEventHandlers(
|
|
94
|
+
...link.value.createEventHandlers(
|
|
95
95
|
(name) => "on".concat(name.charAt(0).toUpperCase()).concat(name.slice(1))
|
|
96
96
|
)
|
|
97
97
|
},
|
|
@@ -101,16 +101,16 @@ export const RouterLink = defineComponent({
|
|
|
101
101
|
}
|
|
102
102
|
return () => {
|
|
103
103
|
var _a, _b;
|
|
104
|
-
const { class: className, ...attributes } = link.attributes;
|
|
104
|
+
const { class: className, ...attributes } = link.value.attributes;
|
|
105
105
|
return h(
|
|
106
|
-
link.tag,
|
|
106
|
+
link.value.tag,
|
|
107
107
|
{
|
|
108
108
|
attrs: {
|
|
109
109
|
...attributes,
|
|
110
110
|
...context.attrs
|
|
111
111
|
},
|
|
112
112
|
class: className,
|
|
113
|
-
on: link.createEventHandlers()
|
|
113
|
+
on: link.value.createEventHandlers()
|
|
114
114
|
},
|
|
115
115
|
(_b = (_a = context.slots).default) == null ? void 0 : _b.call(_a)
|
|
116
116
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Router, RouterMode } from "@esmx/router";
|
|
2
2
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
3
|
-
import { createApp, defineComponent, h, nextTick } from "vue";
|
|
3
|
+
import { createApp, defineComponent, h, nextTick, ref } from "vue";
|
|
4
4
|
import { RouterLink } from "./router-link.mjs";
|
|
5
5
|
import { useProvideRouter } from "./use.mjs";
|
|
6
6
|
describe("router-link.ts - RouterLink Component", () => {
|
|
@@ -513,4 +513,151 @@ describe("router-link.ts - RouterLink Component", () => {
|
|
|
513
513
|
);
|
|
514
514
|
});
|
|
515
515
|
});
|
|
516
|
+
describe("Reactivity", () => {
|
|
517
|
+
it("should update active class when route changes", async () => {
|
|
518
|
+
await router.replace("/");
|
|
519
|
+
await nextTick();
|
|
520
|
+
const TestApp = defineComponent({
|
|
521
|
+
setup() {
|
|
522
|
+
useProvideRouter(router);
|
|
523
|
+
return () => h(
|
|
524
|
+
RouterLink,
|
|
525
|
+
{
|
|
526
|
+
to: "/about",
|
|
527
|
+
activeClass: "active-link"
|
|
528
|
+
},
|
|
529
|
+
() => "About"
|
|
530
|
+
);
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
app = createApp(TestApp);
|
|
534
|
+
app.mount(container);
|
|
535
|
+
await nextTick();
|
|
536
|
+
const linkElement = container.querySelector("a");
|
|
537
|
+
expect(linkElement == null ? void 0 : linkElement.classList.contains("active-link")).toBe(false);
|
|
538
|
+
const toAbout = new Promise((resolve) => {
|
|
539
|
+
router.afterEach(() => resolve());
|
|
540
|
+
});
|
|
541
|
+
await router.push("/about");
|
|
542
|
+
await toAbout;
|
|
543
|
+
await nextTick();
|
|
544
|
+
expect(linkElement == null ? void 0 : linkElement.classList.contains("active-link")).toBe(true);
|
|
545
|
+
const toContact = new Promise((resolve) => {
|
|
546
|
+
router.afterEach(() => resolve());
|
|
547
|
+
});
|
|
548
|
+
await router.push("/contact");
|
|
549
|
+
await toContact;
|
|
550
|
+
await nextTick();
|
|
551
|
+
expect(linkElement == null ? void 0 : linkElement.classList.contains("active-link")).toBe(false);
|
|
552
|
+
});
|
|
553
|
+
it("should update rendering when props.to changes", async () => {
|
|
554
|
+
await router.replace("/about");
|
|
555
|
+
await nextTick();
|
|
556
|
+
const toProp = ref("/about");
|
|
557
|
+
const TestApp = defineComponent({
|
|
558
|
+
setup() {
|
|
559
|
+
useProvideRouter(router);
|
|
560
|
+
return () => h(
|
|
561
|
+
RouterLink,
|
|
562
|
+
{
|
|
563
|
+
to: toProp.value,
|
|
564
|
+
activeClass: "active-link"
|
|
565
|
+
},
|
|
566
|
+
() => "Dynamic To"
|
|
567
|
+
);
|
|
568
|
+
}
|
|
569
|
+
});
|
|
570
|
+
app = createApp(TestApp);
|
|
571
|
+
app.mount(container);
|
|
572
|
+
await nextTick();
|
|
573
|
+
const linkElement = container.querySelector("a");
|
|
574
|
+
expect(linkElement == null ? void 0 : linkElement.classList.contains("active-link")).toBe(true);
|
|
575
|
+
toProp.value = "/contact";
|
|
576
|
+
await nextTick();
|
|
577
|
+
expect(linkElement == null ? void 0 : linkElement.classList.contains("active-link")).toBe(false);
|
|
578
|
+
const toContact = new Promise((resolve) => {
|
|
579
|
+
router.afterEach(() => resolve());
|
|
580
|
+
});
|
|
581
|
+
await router.push("/contact");
|
|
582
|
+
await toContact;
|
|
583
|
+
await nextTick();
|
|
584
|
+
expect(linkElement == null ? void 0 : linkElement.classList.contains("active-link")).toBe(true);
|
|
585
|
+
});
|
|
586
|
+
it("should update event handlers when props.event changes", async () => {
|
|
587
|
+
await router.replace("/");
|
|
588
|
+
await nextTick();
|
|
589
|
+
const eventProp = ref("click");
|
|
590
|
+
const TestApp = defineComponent({
|
|
591
|
+
setup() {
|
|
592
|
+
useProvideRouter(router);
|
|
593
|
+
return () => h(
|
|
594
|
+
RouterLink,
|
|
595
|
+
{
|
|
596
|
+
to: "/about",
|
|
597
|
+
event: eventProp.value
|
|
598
|
+
},
|
|
599
|
+
() => "Event Link"
|
|
600
|
+
);
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
app = createApp(TestApp);
|
|
604
|
+
app.mount(container);
|
|
605
|
+
await nextTick();
|
|
606
|
+
const linkElement = container.querySelector("a");
|
|
607
|
+
expect(linkElement).toBeTruthy();
|
|
608
|
+
const clickNav = new Promise((resolve) => {
|
|
609
|
+
router.afterEach(() => resolve());
|
|
610
|
+
});
|
|
611
|
+
linkElement == null ? void 0 : linkElement.click();
|
|
612
|
+
await clickNav;
|
|
613
|
+
await nextTick();
|
|
614
|
+
expect(router.route.path).toBe("/about");
|
|
615
|
+
const backNav = new Promise((resolve) => {
|
|
616
|
+
router.afterEach(() => resolve());
|
|
617
|
+
});
|
|
618
|
+
await router.replace("/");
|
|
619
|
+
await backNav;
|
|
620
|
+
await nextTick();
|
|
621
|
+
eventProp.value = "mouseenter";
|
|
622
|
+
await nextTick();
|
|
623
|
+
linkElement == null ? void 0 : linkElement.click();
|
|
624
|
+
await nextTick();
|
|
625
|
+
expect(router.route.path).toBe("/");
|
|
626
|
+
const hoverNav = new Promise((resolve) => {
|
|
627
|
+
router.afterEach(() => resolve());
|
|
628
|
+
});
|
|
629
|
+
const event = new MouseEvent("mouseenter", { bubbles: true });
|
|
630
|
+
linkElement == null ? void 0 : linkElement.dispatchEvent(event);
|
|
631
|
+
await hoverNav;
|
|
632
|
+
await nextTick();
|
|
633
|
+
expect(router.route.path).toBe("/about");
|
|
634
|
+
});
|
|
635
|
+
it("should re-render when tag prop changes", async () => {
|
|
636
|
+
const tagProp = ref("a");
|
|
637
|
+
const TestApp = defineComponent({
|
|
638
|
+
setup() {
|
|
639
|
+
useProvideRouter(router);
|
|
640
|
+
return () => h(
|
|
641
|
+
RouterLink,
|
|
642
|
+
{
|
|
643
|
+
to: "/about",
|
|
644
|
+
tag: tagProp.value
|
|
645
|
+
},
|
|
646
|
+
() => "Tag Link"
|
|
647
|
+
);
|
|
648
|
+
}
|
|
649
|
+
});
|
|
650
|
+
app = createApp(TestApp);
|
|
651
|
+
app.mount(container);
|
|
652
|
+
await nextTick();
|
|
653
|
+
const anchorElement = container.querySelector("a");
|
|
654
|
+
expect(anchorElement).toBeTruthy();
|
|
655
|
+
tagProp.value = "button";
|
|
656
|
+
await nextTick();
|
|
657
|
+
const buttonElement = container.querySelector("button");
|
|
658
|
+
const oldAnchor = container.querySelector("a");
|
|
659
|
+
expect(buttonElement).toBeTruthy();
|
|
660
|
+
expect(oldAnchor).toBeFalsy();
|
|
661
|
+
});
|
|
662
|
+
});
|
|
516
663
|
});
|
package/package.json
CHANGED
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"vue": "^3.5.0 || ^2.7.0"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@esmx/router": "3.0.0-rc.
|
|
53
|
+
"@esmx/router": "3.0.0-rc.76"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@biomejs/biome": "1.9.4",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"vue": "3.5.23",
|
|
63
63
|
"vue2": "npm:vue@2.7.16"
|
|
64
64
|
},
|
|
65
|
-
"version": "3.0.0-rc.
|
|
65
|
+
"version": "3.0.0-rc.76",
|
|
66
66
|
"type": "module",
|
|
67
67
|
"private": false,
|
|
68
68
|
"exports": {
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
"template",
|
|
82
82
|
"public"
|
|
83
83
|
],
|
|
84
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "8377e5ae2c59cc2b334272d674deb7a01b7e8fa5"
|
|
85
85
|
}
|
package/src/router-link.test.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { Router, RouterMode } from '@esmx/router';
|
|
|
4
4
|
* @vitest-environment happy-dom
|
|
5
5
|
*/
|
|
6
6
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
7
|
-
import { createApp, defineComponent, h, nextTick } from 'vue';
|
|
7
|
+
import { createApp, defineComponent, h, nextTick, ref } from 'vue';
|
|
8
8
|
import { RouterLink } from './router-link';
|
|
9
9
|
import { useProvideRouter } from './use';
|
|
10
10
|
|
|
@@ -647,4 +647,184 @@ describe('router-link.ts - RouterLink Component', () => {
|
|
|
647
647
|
);
|
|
648
648
|
});
|
|
649
649
|
});
|
|
650
|
+
|
|
651
|
+
describe('Reactivity', () => {
|
|
652
|
+
it('should update active class when route changes', async () => {
|
|
653
|
+
await router.replace('/');
|
|
654
|
+
await nextTick();
|
|
655
|
+
|
|
656
|
+
const TestApp = defineComponent({
|
|
657
|
+
setup() {
|
|
658
|
+
useProvideRouter(router);
|
|
659
|
+
return () =>
|
|
660
|
+
h(
|
|
661
|
+
RouterLink,
|
|
662
|
+
{
|
|
663
|
+
to: '/about',
|
|
664
|
+
activeClass: 'active-link'
|
|
665
|
+
},
|
|
666
|
+
() => 'About'
|
|
667
|
+
);
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
app = createApp(TestApp);
|
|
672
|
+
app.mount(container);
|
|
673
|
+
await nextTick();
|
|
674
|
+
|
|
675
|
+
const linkElement = container.querySelector('a');
|
|
676
|
+
expect(linkElement?.classList.contains('active-link')).toBe(false);
|
|
677
|
+
|
|
678
|
+
const toAbout = new Promise<void>((resolve) => {
|
|
679
|
+
router.afterEach(() => resolve());
|
|
680
|
+
});
|
|
681
|
+
await router.push('/about');
|
|
682
|
+
await toAbout;
|
|
683
|
+
await nextTick();
|
|
684
|
+
expect(linkElement?.classList.contains('active-link')).toBe(true);
|
|
685
|
+
|
|
686
|
+
const toContact = new Promise<void>((resolve) => {
|
|
687
|
+
router.afterEach(() => resolve());
|
|
688
|
+
});
|
|
689
|
+
await router.push('/contact');
|
|
690
|
+
await toContact;
|
|
691
|
+
await nextTick();
|
|
692
|
+
expect(linkElement?.classList.contains('active-link')).toBe(false);
|
|
693
|
+
});
|
|
694
|
+
|
|
695
|
+
it('should update rendering when props.to changes', async () => {
|
|
696
|
+
await router.replace('/about');
|
|
697
|
+
await nextTick();
|
|
698
|
+
|
|
699
|
+
const toProp = ref('/about');
|
|
700
|
+
|
|
701
|
+
const TestApp = defineComponent({
|
|
702
|
+
setup() {
|
|
703
|
+
useProvideRouter(router);
|
|
704
|
+
return () =>
|
|
705
|
+
h(
|
|
706
|
+
RouterLink,
|
|
707
|
+
{
|
|
708
|
+
to: toProp.value,
|
|
709
|
+
activeClass: 'active-link'
|
|
710
|
+
},
|
|
711
|
+
() => 'Dynamic To'
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
app = createApp(TestApp);
|
|
717
|
+
app.mount(container);
|
|
718
|
+
await nextTick();
|
|
719
|
+
|
|
720
|
+
const linkElement = container.querySelector('a');
|
|
721
|
+
expect(linkElement?.classList.contains('active-link')).toBe(true);
|
|
722
|
+
|
|
723
|
+
toProp.value = '/contact';
|
|
724
|
+
await nextTick();
|
|
725
|
+
expect(linkElement?.classList.contains('active-link')).toBe(false);
|
|
726
|
+
|
|
727
|
+
const toContact = new Promise<void>((resolve) => {
|
|
728
|
+
router.afterEach(() => resolve());
|
|
729
|
+
});
|
|
730
|
+
await router.push('/contact');
|
|
731
|
+
await toContact;
|
|
732
|
+
await nextTick();
|
|
733
|
+
expect(linkElement?.classList.contains('active-link')).toBe(true);
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
it('should update event handlers when props.event changes', async () => {
|
|
737
|
+
await router.replace('/');
|
|
738
|
+
await nextTick();
|
|
739
|
+
|
|
740
|
+
const eventProp = ref<'click' | 'mouseenter'>('click');
|
|
741
|
+
|
|
742
|
+
const TestApp = defineComponent({
|
|
743
|
+
setup() {
|
|
744
|
+
useProvideRouter(router);
|
|
745
|
+
return () =>
|
|
746
|
+
h(
|
|
747
|
+
RouterLink,
|
|
748
|
+
{
|
|
749
|
+
to: '/about',
|
|
750
|
+
event: eventProp.value
|
|
751
|
+
},
|
|
752
|
+
() => 'Event Link'
|
|
753
|
+
);
|
|
754
|
+
}
|
|
755
|
+
});
|
|
756
|
+
|
|
757
|
+
app = createApp(TestApp);
|
|
758
|
+
app.mount(container);
|
|
759
|
+
await nextTick();
|
|
760
|
+
|
|
761
|
+
const linkElement = container.querySelector('a');
|
|
762
|
+
expect(linkElement).toBeTruthy();
|
|
763
|
+
|
|
764
|
+
const clickNav = new Promise<void>((resolve) => {
|
|
765
|
+
router.afterEach(() => resolve());
|
|
766
|
+
});
|
|
767
|
+
linkElement?.click();
|
|
768
|
+
await clickNav;
|
|
769
|
+
await nextTick();
|
|
770
|
+
expect(router.route.path).toBe('/about');
|
|
771
|
+
|
|
772
|
+
const backNav = new Promise<void>((resolve) => {
|
|
773
|
+
router.afterEach(() => resolve());
|
|
774
|
+
});
|
|
775
|
+
await router.replace('/');
|
|
776
|
+
await backNav;
|
|
777
|
+
await nextTick();
|
|
778
|
+
|
|
779
|
+
eventProp.value = 'mouseenter';
|
|
780
|
+
await nextTick();
|
|
781
|
+
|
|
782
|
+
linkElement?.click();
|
|
783
|
+
await nextTick();
|
|
784
|
+
expect(router.route.path).toBe('/');
|
|
785
|
+
|
|
786
|
+
const hoverNav = new Promise<void>((resolve) => {
|
|
787
|
+
router.afterEach(() => resolve());
|
|
788
|
+
});
|
|
789
|
+
const event = new MouseEvent('mouseenter', { bubbles: true });
|
|
790
|
+
linkElement?.dispatchEvent(event);
|
|
791
|
+
await hoverNav;
|
|
792
|
+
await nextTick();
|
|
793
|
+
expect(router.route.path).toBe('/about');
|
|
794
|
+
});
|
|
795
|
+
|
|
796
|
+
it('should re-render when tag prop changes', async () => {
|
|
797
|
+
const tagProp = ref<'a' | 'button'>('a');
|
|
798
|
+
|
|
799
|
+
const TestApp = defineComponent({
|
|
800
|
+
setup() {
|
|
801
|
+
useProvideRouter(router);
|
|
802
|
+
return () =>
|
|
803
|
+
h(
|
|
804
|
+
RouterLink,
|
|
805
|
+
{
|
|
806
|
+
to: '/about',
|
|
807
|
+
tag: tagProp.value
|
|
808
|
+
},
|
|
809
|
+
() => 'Tag Link'
|
|
810
|
+
);
|
|
811
|
+
}
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
app = createApp(TestApp);
|
|
815
|
+
app.mount(container);
|
|
816
|
+
await nextTick();
|
|
817
|
+
|
|
818
|
+
const anchorElement = container.querySelector('a');
|
|
819
|
+
expect(anchorElement).toBeTruthy();
|
|
820
|
+
|
|
821
|
+
tagProp.value = 'button';
|
|
822
|
+
await nextTick();
|
|
823
|
+
|
|
824
|
+
const buttonElement = container.querySelector('button');
|
|
825
|
+
const oldAnchor = container.querySelector('a');
|
|
826
|
+
expect(buttonElement).toBeTruthy();
|
|
827
|
+
expect(oldAnchor).toBeFalsy();
|
|
828
|
+
});
|
|
829
|
+
});
|
|
650
830
|
});
|
package/src/router-link.ts
CHANGED
|
@@ -134,16 +134,16 @@ export const RouterLink = defineComponent({
|
|
|
134
134
|
},
|
|
135
135
|
|
|
136
136
|
setup(props, context) {
|
|
137
|
-
const link = useLink(props)
|
|
137
|
+
const link = useLink(props);
|
|
138
138
|
|
|
139
139
|
if (isVue3) {
|
|
140
140
|
return () => {
|
|
141
141
|
return h(
|
|
142
|
-
link.tag,
|
|
142
|
+
link.value.tag,
|
|
143
143
|
{
|
|
144
|
-
...link.attributes,
|
|
144
|
+
...link.value.attributes,
|
|
145
145
|
...context.attrs,
|
|
146
|
-
...link.createEventHandlers(
|
|
146
|
+
...link.value.createEventHandlers(
|
|
147
147
|
(name) =>
|
|
148
148
|
`on${name.charAt(0).toUpperCase()}${name.slice(1)}`
|
|
149
149
|
)
|
|
@@ -153,16 +153,16 @@ export const RouterLink = defineComponent({
|
|
|
153
153
|
};
|
|
154
154
|
}
|
|
155
155
|
return () => {
|
|
156
|
-
const { class: className, ...attributes } = link.attributes;
|
|
156
|
+
const { class: className, ...attributes } = link.value.attributes;
|
|
157
157
|
return h(
|
|
158
|
-
link.tag,
|
|
158
|
+
link.value.tag,
|
|
159
159
|
{
|
|
160
160
|
attrs: {
|
|
161
161
|
...attributes,
|
|
162
162
|
...context.attrs
|
|
163
163
|
},
|
|
164
164
|
class: className,
|
|
165
|
-
on: link.createEventHandlers()
|
|
165
|
+
on: link.value.createEventHandlers()
|
|
166
166
|
},
|
|
167
167
|
context.slots.default?.()
|
|
168
168
|
);
|