@furystack/shades 11.0.35 → 12.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/CHANGELOG.md +337 -0
- package/README.md +99 -13
- package/esm/compile-route.spec.d.ts +2 -0
- package/esm/compile-route.spec.d.ts.map +1 -0
- package/esm/compile-route.spec.js +34 -0
- package/esm/compile-route.spec.js.map +1 -0
- package/esm/component-factory.spec.js +13 -5
- package/esm/component-factory.spec.js.map +1 -1
- package/esm/components/index.d.ts +4 -1
- package/esm/components/index.d.ts.map +1 -1
- package/esm/components/index.js +4 -1
- package/esm/components/index.js.map +1 -1
- package/esm/components/lazy-load.d.ts +2 -4
- package/esm/components/lazy-load.d.ts.map +1 -1
- package/esm/components/lazy-load.js +40 -24
- package/esm/components/lazy-load.js.map +1 -1
- package/esm/components/lazy-load.spec.js +57 -50
- package/esm/components/lazy-load.spec.js.map +1 -1
- package/esm/components/link-to-route.d.ts +2 -0
- package/esm/components/link-to-route.d.ts.map +1 -1
- package/esm/components/link-to-route.js +3 -2
- package/esm/components/link-to-route.js.map +1 -1
- package/esm/components/link-to-route.spec.js +13 -9
- package/esm/components/link-to-route.spec.js.map +1 -1
- package/esm/components/nested-route-link.d.ts +62 -0
- package/esm/components/nested-route-link.d.ts.map +1 -0
- package/esm/components/nested-route-link.js +66 -0
- package/esm/components/nested-route-link.js.map +1 -0
- package/esm/components/nested-route-link.spec.d.ts +2 -0
- package/esm/components/nested-route-link.spec.d.ts.map +1 -0
- package/esm/components/nested-route-link.spec.js +179 -0
- package/esm/components/nested-route-link.spec.js.map +1 -0
- package/esm/components/nested-route-types.d.ts +37 -0
- package/esm/components/nested-route-types.d.ts.map +1 -0
- package/esm/components/nested-route-types.js +2 -0
- package/esm/components/nested-route-types.js.map +1 -0
- package/esm/components/nested-router.d.ts +103 -0
- package/esm/components/nested-router.d.ts.map +1 -0
- package/esm/components/nested-router.js +178 -0
- package/esm/components/nested-router.js.map +1 -0
- package/esm/components/nested-router.spec.d.ts +2 -0
- package/esm/components/nested-router.spec.d.ts.map +1 -0
- package/esm/components/nested-router.spec.js +659 -0
- package/esm/components/nested-router.spec.js.map +1 -0
- package/esm/components/route-link.d.ts +4 -0
- package/esm/components/route-link.d.ts.map +1 -1
- package/esm/components/route-link.js +9 -10
- package/esm/components/route-link.js.map +1 -1
- package/esm/components/route-link.spec.js +16 -12
- package/esm/components/route-link.spec.js.map +1 -1
- package/esm/components/router.d.ts +20 -2
- package/esm/components/router.d.ts.map +1 -1
- package/esm/components/router.js +3 -0
- package/esm/components/router.js.map +1 -1
- package/esm/components/router.spec.js +75 -74
- package/esm/components/router.spec.js.map +1 -1
- package/esm/css-generator.d.ts +50 -0
- package/esm/css-generator.d.ts.map +1 -0
- package/esm/css-generator.js +107 -0
- package/esm/css-generator.js.map +1 -0
- package/esm/css-generator.spec.d.ts +2 -0
- package/esm/css-generator.spec.d.ts.map +1 -0
- package/esm/css-generator.spec.js +162 -0
- package/esm/css-generator.spec.js.map +1 -0
- package/esm/index.d.ts +2 -0
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +2 -0
- package/esm/index.js.map +1 -1
- package/esm/initialize.d.ts +11 -0
- package/esm/initialize.d.ts.map +1 -1
- package/esm/initialize.js +5 -0
- package/esm/initialize.js.map +1 -1
- package/esm/jsx.d.ts +83 -2
- package/esm/jsx.d.ts.map +1 -1
- package/esm/models/children-list.d.ts +5 -1
- package/esm/models/children-list.d.ts.map +1 -1
- package/esm/models/css-object.d.ts +33 -0
- package/esm/models/css-object.d.ts.map +1 -0
- package/esm/models/css-object.js +2 -0
- package/esm/models/css-object.js.map +1 -0
- package/esm/models/index.d.ts +1 -0
- package/esm/models/index.d.ts.map +1 -1
- package/esm/models/index.js +1 -0
- package/esm/models/index.js.map +1 -1
- package/esm/models/partial-element.d.ts +12 -2
- package/esm/models/partial-element.d.ts.map +1 -1
- package/esm/models/render-options.d.ts +89 -3
- package/esm/models/render-options.d.ts.map +1 -1
- package/esm/models/selection-state.d.ts +4 -0
- package/esm/models/selection-state.d.ts.map +1 -1
- package/esm/services/location-service.d.ts +11 -0
- package/esm/services/location-service.d.ts.map +1 -1
- package/esm/services/location-service.js +11 -0
- package/esm/services/location-service.js.map +1 -1
- package/esm/services/resource-manager.d.ts +24 -0
- package/esm/services/resource-manager.d.ts.map +1 -1
- package/esm/services/resource-manager.js +30 -0
- package/esm/services/resource-manager.js.map +1 -1
- package/esm/services/resource-manager.spec.js +93 -0
- package/esm/services/resource-manager.spec.js.map +1 -1
- package/esm/services/screen-service.d.ts +81 -4
- package/esm/services/screen-service.d.ts.map +1 -1
- package/esm/services/screen-service.js +75 -4
- package/esm/services/screen-service.js.map +1 -1
- package/esm/services/screen-service.spec.js +91 -7
- package/esm/services/screen-service.spec.js.map +1 -1
- package/esm/shade-component.d.ts +17 -4
- package/esm/shade-component.d.ts.map +1 -1
- package/esm/shade-component.js +67 -5
- package/esm/shade-component.js.map +1 -1
- package/esm/shade-host-props-ref.integration.spec.d.ts +2 -0
- package/esm/shade-host-props-ref.integration.spec.d.ts.map +1 -0
- package/esm/shade-host-props-ref.integration.spec.js +381 -0
- package/esm/shade-host-props-ref.integration.spec.js.map +1 -0
- package/esm/shade-resources.integration.spec.js +208 -39
- package/esm/shade-resources.integration.spec.js.map +1 -1
- package/esm/shade.d.ts +34 -15
- package/esm/shade.d.ts.map +1 -1
- package/esm/shade.js +180 -33
- package/esm/shade.js.map +1 -1
- package/esm/shade.spec.d.ts +2 -0
- package/esm/shade.spec.d.ts.map +1 -0
- package/esm/shade.spec.js +198 -0
- package/esm/shade.spec.js.map +1 -0
- package/esm/shades.integration.spec.js +135 -72
- package/esm/shades.integration.spec.js.map +1 -1
- package/esm/style-manager.d.ts +65 -0
- package/esm/style-manager.d.ts.map +1 -0
- package/esm/style-manager.js +95 -0
- package/esm/style-manager.js.map +1 -0
- package/esm/style-manager.spec.d.ts +2 -0
- package/esm/style-manager.spec.d.ts.map +1 -0
- package/esm/style-manager.spec.js +179 -0
- package/esm/style-manager.spec.js.map +1 -0
- package/esm/styled-element.spec.d.ts +2 -0
- package/esm/styled-element.spec.d.ts.map +1 -0
- package/esm/styled-element.spec.js +86 -0
- package/esm/styled-element.spec.js.map +1 -0
- package/esm/styled-shade.spec.d.ts +2 -0
- package/esm/styled-shade.spec.d.ts.map +1 -0
- package/esm/styled-shade.spec.js +66 -0
- package/esm/styled-shade.spec.js.map +1 -0
- package/esm/svg-types.d.ts +389 -0
- package/esm/svg-types.d.ts.map +1 -0
- package/esm/svg-types.js +9 -0
- package/esm/svg-types.js.map +1 -0
- package/esm/svg.d.ts +15 -0
- package/esm/svg.d.ts.map +1 -0
- package/esm/svg.js +76 -0
- package/esm/svg.js.map +1 -0
- package/esm/svg.spec.d.ts +2 -0
- package/esm/svg.spec.d.ts.map +1 -0
- package/esm/svg.spec.js +80 -0
- package/esm/svg.spec.js.map +1 -0
- package/esm/vnode.d.ts +103 -0
- package/esm/vnode.d.ts.map +1 -0
- package/esm/vnode.integration.spec.d.ts +2 -0
- package/esm/vnode.integration.spec.d.ts.map +1 -0
- package/esm/vnode.integration.spec.js +494 -0
- package/esm/vnode.integration.spec.js.map +1 -0
- package/esm/vnode.js +453 -0
- package/esm/vnode.js.map +1 -0
- package/esm/vnode.spec.d.ts +2 -0
- package/esm/vnode.spec.d.ts.map +1 -0
- package/esm/vnode.spec.js +473 -0
- package/esm/vnode.spec.js.map +1 -0
- package/package.json +3 -3
- package/src/compile-route.spec.ts +39 -0
- package/src/component-factory.spec.tsx +18 -5
- package/src/components/index.ts +4 -1
- package/src/components/lazy-load.spec.tsx +82 -75
- package/src/components/lazy-load.tsx +49 -27
- package/src/components/link-to-route.spec.tsx +25 -21
- package/src/components/link-to-route.tsx +4 -2
- package/src/components/nested-route-link.spec.tsx +303 -0
- package/src/components/nested-route-link.tsx +100 -0
- package/src/components/nested-route-types.ts +42 -0
- package/src/components/nested-router.spec.tsx +817 -0
- package/src/components/nested-router.tsx +256 -0
- package/src/components/route-link.spec.tsx +22 -18
- package/src/components/route-link.tsx +10 -10
- package/src/components/router.spec.tsx +109 -108
- package/src/components/router.tsx +15 -2
- package/src/css-generator.spec.ts +183 -0
- package/src/css-generator.ts +117 -0
- package/src/index.ts +2 -0
- package/src/initialize.ts +12 -0
- package/src/jsx.ts +129 -2
- package/src/models/children-list.ts +7 -1
- package/src/models/css-object.ts +34 -0
- package/src/models/index.ts +1 -0
- package/src/models/partial-element.ts +13 -2
- package/src/models/render-options.ts +90 -3
- package/src/models/selection-state.ts +4 -0
- package/src/services/location-service.tsx +11 -0
- package/src/services/resource-manager.spec.ts +116 -0
- package/src/services/resource-manager.ts +30 -0
- package/src/services/screen-service.spec.ts +109 -7
- package/src/services/screen-service.ts +81 -4
- package/src/shade-component.ts +72 -6
- package/src/shade-host-props-ref.integration.spec.tsx +460 -0
- package/src/shade-resources.integration.spec.tsx +276 -52
- package/src/shade.spec.tsx +239 -0
- package/src/shade.ts +211 -56
- package/src/shades.integration.spec.tsx +154 -80
- package/src/style-manager.spec.ts +229 -0
- package/src/style-manager.ts +104 -0
- package/src/styled-element.spec.tsx +117 -0
- package/src/styled-shade.spec.ts +86 -0
- package/src/svg-types.ts +437 -0
- package/src/svg.spec.ts +89 -0
- package/src/svg.ts +78 -0
- package/src/vnode.integration.spec.tsx +657 -0
- package/src/vnode.spec.ts +579 -0
- package/src/vnode.ts +508 -0
|
@@ -1,39 +1,55 @@
|
|
|
1
1
|
import { Shade } from '../shade.js';
|
|
2
2
|
export const LazyLoad = Shade({
|
|
3
3
|
shadowDomName: 'lazy-load',
|
|
4
|
-
|
|
5
|
-
const [_component, setComponent] = useState('component', undefined);
|
|
6
|
-
const [_errorState, setErrorState] = useState('error', undefined);
|
|
7
|
-
try {
|
|
8
|
-
const loaded = await props.component();
|
|
9
|
-
if (element.isConnected) {
|
|
10
|
-
setComponent(loaded);
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
catch (error) {
|
|
14
|
-
if (props.error) {
|
|
15
|
-
if (element.isConnected) {
|
|
16
|
-
setErrorState(error);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
throw error;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
render: ({ props, useState }) => {
|
|
4
|
+
render: ({ props, useState, useDisposable }) => {
|
|
25
5
|
const [error, setError] = useState('error', undefined);
|
|
26
6
|
const [component, setComponent] = useState('component', undefined);
|
|
7
|
+
const tracker = useDisposable('loadTracker', () => {
|
|
8
|
+
const state = {
|
|
9
|
+
factory: null,
|
|
10
|
+
active: true,
|
|
11
|
+
[Symbol.dispose]() {
|
|
12
|
+
state.active = false;
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
return state;
|
|
16
|
+
});
|
|
17
|
+
const isNewFactory = tracker.factory !== props.component;
|
|
18
|
+
if (isNewFactory) {
|
|
19
|
+
tracker.factory = props.component;
|
|
20
|
+
const factory = props.component;
|
|
21
|
+
factory()
|
|
22
|
+
.then((loaded) => {
|
|
23
|
+
if (tracker.active && tracker.factory === factory) {
|
|
24
|
+
setError(undefined);
|
|
25
|
+
setComponent(loaded);
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
.catch((err) => {
|
|
29
|
+
if (tracker.active && tracker.factory === factory) {
|
|
30
|
+
setComponent(undefined);
|
|
31
|
+
if (props.error) {
|
|
32
|
+
setError(err);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
return props.loader;
|
|
37
|
+
}
|
|
27
38
|
if (error && props.error) {
|
|
28
39
|
return props.error(error, async () => {
|
|
40
|
+
const factory = props.component;
|
|
29
41
|
try {
|
|
30
42
|
setError(undefined);
|
|
31
43
|
setComponent(undefined);
|
|
32
|
-
const loaded = await
|
|
33
|
-
|
|
44
|
+
const loaded = await factory();
|
|
45
|
+
if (tracker.active && tracker.factory === factory) {
|
|
46
|
+
setComponent(loaded);
|
|
47
|
+
}
|
|
34
48
|
}
|
|
35
49
|
catch (e) {
|
|
36
|
-
|
|
50
|
+
if (tracker.active && tracker.factory === factory) {
|
|
51
|
+
setError(e);
|
|
52
|
+
}
|
|
37
53
|
}
|
|
38
54
|
});
|
|
39
55
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lazy-load.js","sourceRoot":"","sources":["../../src/components/lazy-load.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"lazy-load.js","sourceRoot":"","sources":["../../src/components/lazy-load.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAQnC,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAgB;IAC3C,aAAa,EAAE,WAAW;IAC1B,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,EAAE,EAAE;QAC7C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAU,OAAO,EAAE,SAAS,CAAC,CAAA;QAC/D,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAA0B,WAAW,EAAE,SAAS,CAAC,CAAA;QAE3F,MAAM,OAAO,GAAG,aAAa,CAAC,aAAa,EAAE,GAAG,EAAE;YAChD,MAAM,KAAK,GAIP;gBACF,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,IAAI;gBACZ,CAAC,MAAM,CAAC,OAAO,CAAC;oBACd,KAAK,CAAC,MAAM,GAAG,KAAK,CAAA;gBACtB,CAAC;aACF,CAAA;YACD,OAAO,KAAK,CAAA;QACd,CAAC,CAAC,CAAA;QAEF,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,KAAK,KAAK,CAAC,SAAS,CAAA;QAExD,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC,SAAS,CAAA;YACjC,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAA;YAE/B,OAAO,EAAE;iBACN,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;gBACf,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;oBAClD,QAAQ,CAAC,SAAS,CAAC,CAAA;oBACnB,YAAY,CAAC,MAAM,CAAC,CAAA;gBACtB,CAAC;YACH,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;gBACtB,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;oBAClD,YAAY,CAAC,SAAS,CAAC,CAAA;oBACvB,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;wBAChB,QAAQ,CAAC,GAAG,CAAC,CAAA;oBACf,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAA;YAEJ,OAAO,KAAK,CAAC,MAAM,CAAA;QACrB,CAAC;QAED,IAAI,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;gBACnC,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAA;gBAC/B,IAAI,CAAC;oBACH,QAAQ,CAAC,SAAS,CAAC,CAAA;oBACnB,YAAY,CAAC,SAAS,CAAC,CAAA;oBACvB,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAA;oBAC9B,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;wBAClD,YAAY,CAAC,MAAM,CAAC,CAAA;oBACtB,CAAC;gBACH,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;wBAClD,QAAQ,CAAC,CAAC,CAAC,CAAA;oBACb,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,OAAO,KAAK,CAAC,MAAM,CAAA;IACrB,CAAC;CACF,CAAC,CAAA"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Injector } from '@furystack/inject';
|
|
2
|
-
import { sleepAsync } from '@furystack/utils';
|
|
2
|
+
import { sleepAsync, usingAsync } from '@furystack/utils';
|
|
3
3
|
import { LazyLoad } from './lazy-load.js';
|
|
4
4
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
5
5
|
import { initializeShadeRoot } from '../initialize.js';
|
|
6
6
|
import { createComponent } from '../shade-component.js';
|
|
7
|
+
import { flushUpdates } from '../shade.js';
|
|
7
8
|
describe('Lazy Load', () => {
|
|
8
9
|
beforeEach(() => {
|
|
9
10
|
document.body.innerHTML = '<div id="root"></div>';
|
|
@@ -12,62 +13,68 @@ describe('Lazy Load', () => {
|
|
|
12
13
|
document.body.innerHTML = '';
|
|
13
14
|
});
|
|
14
15
|
it('Shuld display the loader and completed state', async () => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
16
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
17
|
+
const rootElement = document.getElementById('root');
|
|
18
|
+
initializeShadeRoot({
|
|
19
|
+
injector,
|
|
20
|
+
rootElement,
|
|
21
|
+
jsxElement: (createComponent(LazyLoad, { loader: createComponent("div", null, "Loading..."), component: async () => {
|
|
22
|
+
await sleepAsync(100);
|
|
23
|
+
return createComponent("div", null, "Loaded");
|
|
24
|
+
} })),
|
|
25
|
+
});
|
|
26
|
+
await flushUpdates();
|
|
27
|
+
expect(document.body.innerHTML).toBe('<div id="root"><lazy-load><div>Loading...</div></lazy-load></div>');
|
|
28
|
+
await sleepAsync(150);
|
|
29
|
+
expect(document.body.innerHTML).toBe('<div id="root"><lazy-load><div>Loaded</div></lazy-load></div>');
|
|
24
30
|
});
|
|
25
|
-
expect(document.body.innerHTML).toBe('<div id="root"><lazy-load><div>Loading...</div></lazy-load></div>');
|
|
26
|
-
await sleepAsync(150);
|
|
27
|
-
expect(document.body.innerHTML).toBe('<div id="root"><lazy-load><div>Loaded</div></lazy-load></div>');
|
|
28
31
|
});
|
|
29
32
|
it('Shuld display the failed state with a retryer', async () => {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
34
|
+
const rootElement = document.getElementById('root');
|
|
35
|
+
const load = vi.fn(async () => {
|
|
36
|
+
throw Error(':(');
|
|
37
|
+
});
|
|
38
|
+
initializeShadeRoot({
|
|
39
|
+
injector,
|
|
40
|
+
rootElement,
|
|
41
|
+
jsxElement: (createComponent(LazyLoad, { loader: createComponent("div", null, "Loading..."), component: load, error: (e, retry) => (createComponent("button", { id: "retry", onclick: retry }, e.message)) })),
|
|
42
|
+
});
|
|
43
|
+
await flushUpdates();
|
|
44
|
+
expect(document.body.innerHTML).toBe('<div id="root"><lazy-load><div>Loading...</div></lazy-load></div>');
|
|
45
|
+
await sleepAsync(1);
|
|
46
|
+
expect(load).toBeCalledTimes(1);
|
|
47
|
+
expect(document.body.innerHTML).toBe('<div id="root"><lazy-load><button id="retry">:(</button></lazy-load></div>');
|
|
48
|
+
document.getElementById('retry')?.click();
|
|
49
|
+
expect(load).toBeCalledTimes(2);
|
|
39
50
|
});
|
|
40
|
-
expect(document.body.innerHTML).toBe('<div id="root"><lazy-load><div>Loading...</div></lazy-load></div>');
|
|
41
|
-
await sleepAsync(1);
|
|
42
|
-
expect(load).toBeCalledTimes(1);
|
|
43
|
-
expect(document.body.innerHTML).toBe('<div id="root"><lazy-load><button id="retry">:(</button></lazy-load></div>');
|
|
44
|
-
document.getElementById('retry')?.click();
|
|
45
|
-
expect(load).toBeCalledTimes(2);
|
|
46
51
|
});
|
|
47
52
|
it('Shuld display the failed state with a retryer', async () => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
54
|
+
const rootElement = document.getElementById('root');
|
|
55
|
+
let counter = 0;
|
|
56
|
+
const load = vi.fn(async () => {
|
|
57
|
+
if (!counter) {
|
|
58
|
+
counter += 1;
|
|
59
|
+
throw Error(':(');
|
|
60
|
+
}
|
|
61
|
+
return createComponent("div", null, "success");
|
|
62
|
+
});
|
|
63
|
+
initializeShadeRoot({
|
|
64
|
+
injector,
|
|
65
|
+
rootElement,
|
|
66
|
+
jsxElement: (createComponent(LazyLoad, { loader: createComponent("div", null, "Loading..."), component: load, error: (e, retry) => (createComponent("button", { id: "retry", onclick: retry }, e.message)) })),
|
|
67
|
+
});
|
|
68
|
+
await flushUpdates();
|
|
69
|
+
expect(document.body.innerHTML).toBe('<div id="root"><lazy-load><div>Loading...</div></lazy-load></div>');
|
|
70
|
+
await sleepAsync(1);
|
|
71
|
+
expect(load).toBeCalledTimes(1);
|
|
72
|
+
expect(document.body.innerHTML).toBe('<div id="root"><lazy-load><button id="retry">:(</button></lazy-load></div>');
|
|
73
|
+
document.getElementById('retry')?.click();
|
|
74
|
+
expect(load).toBeCalledTimes(2);
|
|
75
|
+
await sleepAsync(1);
|
|
76
|
+
expect(document.body.innerHTML).toBe('<div id="root"><lazy-load><div>success</div></lazy-load></div>');
|
|
62
77
|
});
|
|
63
|
-
expect(document.body.innerHTML).toBe('<div id="root"><lazy-load><div>Loading...</div></lazy-load></div>');
|
|
64
|
-
await sleepAsync(1);
|
|
65
|
-
expect(load).toBeCalledTimes(1);
|
|
66
|
-
expect(document.body.innerHTML).toBe('<div id="root"><lazy-load><button id="retry">:(</button></lazy-load></div>');
|
|
67
|
-
document.getElementById('retry')?.click();
|
|
68
|
-
expect(load).toBeCalledTimes(2);
|
|
69
|
-
await sleepAsync(1);
|
|
70
|
-
expect(document.body.innerHTML).toBe('<div id="root"><lazy-load><div>success</div></lazy-load></div>');
|
|
71
78
|
});
|
|
72
79
|
});
|
|
73
80
|
//# sourceMappingURL=lazy-load.spec.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lazy-load.spec.js","sourceRoot":"","sources":["../../src/components/lazy-load.spec.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"lazy-load.spec.js","sourceRoot":"","sources":["../../src/components/lazy-load.spec.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { ChildrenList } from '../models/children-list.js';
|
|
2
2
|
import type { Route } from './router.js';
|
|
3
|
+
/** @deprecated Use `NestedRouteLinkProps` from `nested-route-link` instead */
|
|
3
4
|
export type LinkToRouteProps<T extends object> = {
|
|
4
5
|
route: Route<T>;
|
|
5
6
|
params: T;
|
|
6
7
|
} & Omit<JSX.IntrinsicElements['a'], 'href'>;
|
|
8
|
+
/** @deprecated Use `NestedRouteLink` from `nested-route-link` instead */
|
|
7
9
|
export declare const LinkToRoute: <T extends object>(props: LinkToRouteProps<T>, children?: ChildrenList) => JSX.Element;
|
|
8
10
|
//# sourceMappingURL=link-to-route.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link-to-route.d.ts","sourceRoot":"","sources":["../../src/components/link-to-route.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAG9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAExC,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,MAAM,IAAI;IAC/C,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;IACf,MAAM,EAAE,CAAC,CAAA;CACV,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAA;AAE5C,eAAO,MAAM,WAAW,EAAE,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,YAAY,KAAK,GAAG,CAAC,OAYrG,CAAA"}
|
|
1
|
+
{"version":3,"file":"link-to-route.d.ts","sourceRoot":"","sources":["../../src/components/link-to-route.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAG9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAExC,8EAA8E;AAC9E,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,MAAM,IAAI;IAC/C,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;IACf,MAAM,EAAE,CAAC,CAAA;CACV,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAA;AAE5C,yEAAyE;AACzE,eAAO,MAAM,WAAW,EAAE,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,YAAY,KAAK,GAAG,CAAC,OAYrG,CAAA"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { compileRoute } from '../compile-route.js';
|
|
2
2
|
import { createComponent } from '../shade-component.js';
|
|
3
3
|
import { Shade } from '../shade.js';
|
|
4
|
+
/** @deprecated Use `NestedRouteLink` from `nested-route-link` instead */
|
|
4
5
|
export const LinkToRoute = Shade({
|
|
5
6
|
shadowDomName: 'link-to-route',
|
|
6
7
|
elementBase: HTMLAnchorElement,
|
|
7
8
|
elementBaseName: 'a',
|
|
8
|
-
render: ({ props,
|
|
9
|
+
render: ({ props, useHostProps, children }) => {
|
|
9
10
|
const { route, params } = props;
|
|
10
11
|
const url = compileRoute(route.url, params);
|
|
11
|
-
|
|
12
|
+
useHostProps({ href: url });
|
|
12
13
|
return createComponent(createComponent, null, children);
|
|
13
14
|
},
|
|
14
15
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link-to-route.js","sourceRoot":"","sources":["../../src/components/link-to-route.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"link-to-route.js","sourceRoot":"","sources":["../../src/components/link-to-route.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AASnC,yEAAyE;AACzE,MAAM,CAAC,MAAM,WAAW,GACtB,KAAK,CAAC;IACJ,aAAa,EAAE,eAAe;IAC9B,WAAW,EAAE,iBAAiB;IAC9B,eAAe,EAAE,GAAG;IACpB,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC5C,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;QAE/B,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QAC3C,YAAY,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAA;QAC3B,OAAO,uCAAG,QAAQ,CAAI,CAAA;IACxB,CAAC;CACF,CAAC,CAAA"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Injector } from '@furystack/inject';
|
|
2
|
+
import { usingAsync } from '@furystack/utils';
|
|
2
3
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
3
4
|
import { initializeShadeRoot } from '../initialize.js';
|
|
4
5
|
import { createComponent } from '../shade-component.js';
|
|
6
|
+
import { flushUpdates } from '../shade.js';
|
|
5
7
|
import { LinkToRoute } from './link-to-route.js';
|
|
6
8
|
describe('LinkToRoute', () => {
|
|
7
9
|
beforeEach(() => {
|
|
@@ -11,16 +13,18 @@ describe('LinkToRoute', () => {
|
|
|
11
13
|
document.body.innerHTML = '';
|
|
12
14
|
});
|
|
13
15
|
it('Shuld display the loader and completed state', async () => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
17
|
+
const rootElement = document.getElementById('root');
|
|
18
|
+
initializeShadeRoot({
|
|
19
|
+
injector,
|
|
20
|
+
rootElement,
|
|
21
|
+
jsxElement: (createComponent(LinkToRoute, { route: {
|
|
22
|
+
url: '/subroute/:id',
|
|
23
|
+
}, params: { id: 123 }, id: "route" }, "Link")),
|
|
24
|
+
});
|
|
25
|
+
await flushUpdates();
|
|
26
|
+
expect(document.body.innerHTML).toBe('<div id="root"><a is="link-to-route" id="route" href="/subroute/123">Link</a></div>');
|
|
22
27
|
});
|
|
23
|
-
expect(document.body.innerHTML).toBe('<div id="root"><a is="link-to-route" id="route" href="/subroute/123">Link</a></div>');
|
|
24
28
|
});
|
|
25
29
|
});
|
|
26
30
|
//# sourceMappingURL=link-to-route.spec.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link-to-route.spec.js","sourceRoot":"","sources":["../../src/components/link-to-route.spec.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGhD,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,UAAU,CAAC,GAAG,EAAE;QACd,QAAQ,CAAC,IAAI,CAAC,SAAS,GAAG,uBAAuB,CAAA;IACnD,CAAC,CAAC,CAAA;IACF,SAAS,CAAC,GAAG,EAAE;QACb,QAAQ,CAAC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAA;IAC9B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,
|
|
1
|
+
{"version":3,"file":"link-to-route.spec.js","sourceRoot":"","sources":["../../src/components/link-to-route.spec.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGhD,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,UAAU,CAAC,GAAG,EAAE;QACd,QAAQ,CAAC,IAAI,CAAC,SAAS,GAAG,uBAAuB,CAAA;IACnD,CAAC,CAAC,CAAA;IACF,SAAS,CAAC,GAAG,EAAE;QACb,QAAQ,CAAC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAA;IAC9B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,UAAU,CAAC,IAAI,QAAQ,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;YAClD,MAAM,WAAW,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAmB,CAAA;YAErE,mBAAmB,CAAC;gBAClB,QAAQ;gBACR,WAAW;gBACX,UAAU,EAAE,CACV,gBAAC,WAAW,IACV,KAAK,EACH;wBACE,GAAG,EAAE,eAAe;qBACI,EAE5B,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EACnB,EAAE,EAAC,OAAO,WAGE,CACf;aACF,CAAC,CAAA;YACF,MAAM,YAAY,EAAE,CAAA;YACpB,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAClC,qFAAqF,CACtF,CAAA;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { ChildrenList } from '../models/children-list.js';
|
|
2
|
+
import type { PartialElement } from '../models/partial-element.js';
|
|
3
|
+
import type { ExtractRouteParams, ExtractRoutePaths } from './nested-route-types.js';
|
|
4
|
+
import type { NestedRoute } from './nested-router.js';
|
|
5
|
+
/**
|
|
6
|
+
* Props for the NestedRouteLink component.
|
|
7
|
+
* Combines SPA navigation from RouteLink with parameter compilation from LinkToRoute.
|
|
8
|
+
*/
|
|
9
|
+
export type NestedRouteLinkProps = {
|
|
10
|
+
href: string;
|
|
11
|
+
params?: Record<string, string>;
|
|
12
|
+
} & PartialElement<Omit<HTMLAnchorElement, 'onclick' | 'href'>>;
|
|
13
|
+
/**
|
|
14
|
+
* Props for a type-safe nested route link.
|
|
15
|
+
* When the path contains parameters (e.g. `:id`), the `params` prop becomes required.
|
|
16
|
+
* @typeParam TPath - A specific route path string
|
|
17
|
+
*/
|
|
18
|
+
export type TypedNestedRouteLinkProps<TPath extends string> = {
|
|
19
|
+
href: TPath;
|
|
20
|
+
} & (string extends keyof ExtractRouteParams<TPath> ? {
|
|
21
|
+
params?: Record<string, string>;
|
|
22
|
+
} : {
|
|
23
|
+
params: ExtractRouteParams<TPath>;
|
|
24
|
+
}) & PartialElement<Omit<HTMLAnchorElement, 'onclick' | 'href'>>;
|
|
25
|
+
/**
|
|
26
|
+
* A link component for NestedRouter that supports SPA navigation with
|
|
27
|
+
* type-safe route parameter compilation.
|
|
28
|
+
*
|
|
29
|
+
* Intercepts click events to use `history.pushState` for client-side navigation,
|
|
30
|
+
* and compiles parameterized routes (e.g. `/users/:id`) when `params` is provided.
|
|
31
|
+
*
|
|
32
|
+
* Route parameters are automatically inferred from the `href` pattern:
|
|
33
|
+
* - `href="/buttons"` — `params` is optional
|
|
34
|
+
* - `href="/users/:id"` — `params: { id: string }` is required
|
|
35
|
+
*
|
|
36
|
+
* For additional URL validation against a route tree, use {@link createNestedRouteLink}.
|
|
37
|
+
*/
|
|
38
|
+
export declare const NestedRouteLink: <TPath extends string = string>(props: TypedNestedRouteLinkProps<TPath>, children?: ChildrenList) => JSX.Element;
|
|
39
|
+
/**
|
|
40
|
+
* Creates a type-safe wrapper around NestedRouteLink constrained to a specific route tree.
|
|
41
|
+
* The returned component has the same runtime behavior but narrows `href` to only accept
|
|
42
|
+
* valid route paths, and requires `params` when the route has parameters.
|
|
43
|
+
*
|
|
44
|
+
* @typeParam TRoutes - The route tree type (use `typeof yourRoutes`)
|
|
45
|
+
* @returns A narrowed NestedRouteLink component
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const AppLink = createNestedRouteLink<typeof appRoutes>()
|
|
50
|
+
*
|
|
51
|
+
* // Type-safe: only valid paths accepted
|
|
52
|
+
* <AppLink href="/buttons">Buttons</AppLink>
|
|
53
|
+
*
|
|
54
|
+
* // TypeScript error: invalid path
|
|
55
|
+
* <AppLink href="/nonexistent">Error!</AppLink>
|
|
56
|
+
*
|
|
57
|
+
* // Params required for parameterized routes
|
|
58
|
+
* <AppLink href="/users/:id" params={{ id: '123' }}>User</AppLink>
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare const createNestedRouteLink: <TRoutes extends Record<string, NestedRoute<unknown>>>() => <TPath extends ExtractRoutePaths<TRoutes>>(props: TypedNestedRouteLinkProps<TPath>, children?: ChildrenList) => JSX.Element;
|
|
62
|
+
//# sourceMappingURL=nested-route-link.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nested-route-link.d.ts","sourceRoot":"","sources":["../../src/components/nested-route-link.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAIlE,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AACpF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC,GAAG,cAAc,CAAC,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,MAAM,CAAC,CAAC,CAAA;AAE/D;;;;GAIG;AACH,MAAM,MAAM,yBAAyB,CAAC,KAAK,SAAS,MAAM,IAAI;IAC5D,IAAI,EAAE,KAAK,CAAA;CACZ,GAAG,CAAC,MAAM,SAAS,MAAM,kBAAkB,CAAC,KAAK,CAAC,GAC/C;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GACnC;IAAE,MAAM,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAA;CAAE,CAAC,GACxC,cAAc,CAAC,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,MAAM,CAAC,CAAC,CAAA;AA0B7D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,EAAkC,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,EAC1F,KAAK,EAAE,yBAAyB,CAAC,KAAK,CAAC,EACvC,QAAQ,CAAC,EAAE,YAAY,KACpB,GAAG,CAAC,OAAO,CAAA;AAEhB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,qBAAqB,GAAI,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,OAClD,CAAC,KAAK,SAAS,iBAAiB,CAAC,OAAO,CAAC,EAC7E,KAAK,EAAE,yBAAyB,CAAC,KAAK,CAAC,EACvC,QAAQ,CAAC,EAAE,YAAY,KACpB,GAAG,CAAC,OACV,CAAA"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { compileRoute } from '../compile-route.js';
|
|
2
|
+
import { LocationService } from '../services/location-service.js';
|
|
3
|
+
import { createComponent } from '../shade-component.js';
|
|
4
|
+
import { Shade } from '../shade.js';
|
|
5
|
+
const _NestedRouteLink = Shade({
|
|
6
|
+
shadowDomName: 'nested-route-link',
|
|
7
|
+
elementBase: HTMLAnchorElement,
|
|
8
|
+
elementBaseName: 'a',
|
|
9
|
+
css: {
|
|
10
|
+
color: 'inherit',
|
|
11
|
+
textDecoration: 'inherit',
|
|
12
|
+
},
|
|
13
|
+
render: ({ children, props, injector, useHostProps }) => {
|
|
14
|
+
const { href, params } = props;
|
|
15
|
+
const resolvedUrl = params ? compileRoute(href, params) : href;
|
|
16
|
+
useHostProps({
|
|
17
|
+
href: resolvedUrl,
|
|
18
|
+
onclick: (ev) => {
|
|
19
|
+
ev.preventDefault();
|
|
20
|
+
history.pushState('', props.title || '', resolvedUrl);
|
|
21
|
+
injector.getInstance(LocationService).updateState();
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
return createComponent(createComponent, null, children);
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
/**
|
|
28
|
+
* A link component for NestedRouter that supports SPA navigation with
|
|
29
|
+
* type-safe route parameter compilation.
|
|
30
|
+
*
|
|
31
|
+
* Intercepts click events to use `history.pushState` for client-side navigation,
|
|
32
|
+
* and compiles parameterized routes (e.g. `/users/:id`) when `params` is provided.
|
|
33
|
+
*
|
|
34
|
+
* Route parameters are automatically inferred from the `href` pattern:
|
|
35
|
+
* - `href="/buttons"` — `params` is optional
|
|
36
|
+
* - `href="/users/:id"` — `params: { id: string }` is required
|
|
37
|
+
*
|
|
38
|
+
* For additional URL validation against a route tree, use {@link createNestedRouteLink}.
|
|
39
|
+
*/
|
|
40
|
+
export const NestedRouteLink = _NestedRouteLink;
|
|
41
|
+
/**
|
|
42
|
+
* Creates a type-safe wrapper around NestedRouteLink constrained to a specific route tree.
|
|
43
|
+
* The returned component has the same runtime behavior but narrows `href` to only accept
|
|
44
|
+
* valid route paths, and requires `params` when the route has parameters.
|
|
45
|
+
*
|
|
46
|
+
* @typeParam TRoutes - The route tree type (use `typeof yourRoutes`)
|
|
47
|
+
* @returns A narrowed NestedRouteLink component
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* const AppLink = createNestedRouteLink<typeof appRoutes>()
|
|
52
|
+
*
|
|
53
|
+
* // Type-safe: only valid paths accepted
|
|
54
|
+
* <AppLink href="/buttons">Buttons</AppLink>
|
|
55
|
+
*
|
|
56
|
+
* // TypeScript error: invalid path
|
|
57
|
+
* <AppLink href="/nonexistent">Error!</AppLink>
|
|
58
|
+
*
|
|
59
|
+
* // Params required for parameterized routes
|
|
60
|
+
* <AppLink href="/users/:id" params={{ id: '123' }}>User</AppLink>
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export const createNestedRouteLink = () => {
|
|
64
|
+
return _NestedRouteLink;
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=nested-route-link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nested-route-link.js","sourceRoot":"","sources":["../../src/components/nested-route-link.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAA;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAyBnC,MAAM,gBAAgB,GAAG,KAAK,CAAuB;IACnD,aAAa,EAAE,mBAAmB;IAClC,WAAW,EAAE,iBAAiB;IAC9B,eAAe,EAAE,GAAG;IACpB,GAAG,EAAE;QACH,KAAK,EAAE,SAAS;QAChB,cAAc,EAAE,SAAS;KAC1B;IACD,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE;QACtD,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;QAC9B,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAE9D,YAAY,CAAC;YACX,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,CAAC,EAAc,EAAE,EAAE;gBAC1B,EAAE,CAAC,cAAc,EAAE,CAAA;gBACnB,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE,WAAW,CAAC,CAAA;gBACrD,QAAQ,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,WAAW,EAAE,CAAA;YACrD,CAAC;SACF,CAAC,CAAA;QACF,OAAO,uCAAG,QAAQ,CAAI,CAAA;IACxB,CAAC;CACF,CAAC,CAAA;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,gBAGf,CAAA;AAEhB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAyD,EAAE;IAC9F,OAAO,gBAGS,CAAA;AAClB,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nested-route-link.spec.d.ts","sourceRoot":"","sources":["../../src/components/nested-route-link.spec.tsx"],"names":[],"mappings":""}
|