@inflector/keeno-router 0.2.0 → 0.3.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/dist/index.d.ts +12 -0
- package/dist/index.js +43 -13
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -65,6 +65,11 @@ export interface NavigateOptions {
|
|
|
65
65
|
state?: unknown;
|
|
66
66
|
/** Scroll to the top after navigating (default true, unless the URL has a hash). */
|
|
67
67
|
scroll?: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Animate the change with the View Transitions API, where the browser supports it (default:
|
|
70
|
+
* the `viewTransition` prop of `<Router>`). The new page renders inside the transition.
|
|
71
|
+
*/
|
|
72
|
+
transition?: boolean;
|
|
68
73
|
}
|
|
69
74
|
/** Go to an app path (`/users/1`, prefixed with `base`) or a relative URL (`?tab=2`). */
|
|
70
75
|
export declare function navigate(to: string, options?: NavigateOptions): void;
|
|
@@ -85,6 +90,11 @@ export interface RouterProps {
|
|
|
85
90
|
url?: string;
|
|
86
91
|
/** Rendered when no route matches. */
|
|
87
92
|
fallback?: () => unknown;
|
|
93
|
+
/**
|
|
94
|
+
* Animate navigations (links, `navigate()`, back and forward) with the View Transitions API,
|
|
95
|
+
* where the browser supports it. A navigation can opt out with `transition: false`.
|
|
96
|
+
*/
|
|
97
|
+
viewTransition?: boolean;
|
|
88
98
|
}
|
|
89
99
|
/**
|
|
90
100
|
* Render the component of the first route matching the URL. The component is kept when only
|
|
@@ -98,6 +108,8 @@ export interface LinkProps {
|
|
|
98
108
|
href: string;
|
|
99
109
|
/** Replace the current history entry. */
|
|
100
110
|
replace?: boolean;
|
|
111
|
+
/** Animate the navigation with the View Transitions API (default: `<Router viewTransition>`). */
|
|
112
|
+
transition?: boolean;
|
|
101
113
|
/** Class added while the link's path is active (default `active`). */
|
|
102
114
|
activeClass?: string;
|
|
103
115
|
/** Only active on exactly this path, not below it. */
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// ../../../../../../../tmp/keeno-build/_inflector_keeno-router/src/index.ts
|
|
2
|
-
import { ErrorBoundary, State, createContext, derived, inject, lazy, provide, untrack } from "@inflector/keeno";
|
|
2
|
+
import { ErrorBoundary, State, createContext, derived, flush, inject, lazy, provide, untrack } from "@inflector/keeno";
|
|
3
3
|
import { attr, callerScope, createComponent, insert, on, template } from "@inflector/keeno/internal";
|
|
4
4
|
|
|
5
5
|
class HttpError extends Error {
|
|
@@ -58,6 +58,21 @@ function restoreScroll(l) {
|
|
|
58
58
|
else
|
|
59
59
|
setTimeout(run, 0);
|
|
60
60
|
}
|
|
61
|
+
var transitionsDefault = false;
|
|
62
|
+
function withTransition(enabled, update) {
|
|
63
|
+
const start = enabled && hasWindow ? document.startViewTransition : undefined;
|
|
64
|
+
if (typeof start !== "function")
|
|
65
|
+
return update();
|
|
66
|
+
start.call(document, () => {
|
|
67
|
+
update();
|
|
68
|
+
flush();
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
function scrollTo(x, y) {
|
|
72
|
+
try {
|
|
73
|
+
window.scrollTo(x, y);
|
|
74
|
+
} catch {}
|
|
75
|
+
}
|
|
61
76
|
function sync() {
|
|
62
77
|
if (!hasWindow)
|
|
63
78
|
return;
|
|
@@ -68,6 +83,18 @@ function sync() {
|
|
|
68
83
|
window.addEventListener("popstate", () => {
|
|
69
84
|
saveScroll(current.peek());
|
|
70
85
|
const next = readLocation();
|
|
86
|
+
if (transitionsDefault && typeof document.startViewTransition === "function") {
|
|
87
|
+
withTransition(true, () => {
|
|
88
|
+
current.set(next);
|
|
89
|
+
flush();
|
|
90
|
+
const saved = scrollPositions.get(locKey(next));
|
|
91
|
+
if (!saved && next.hash)
|
|
92
|
+
scrollToHash(next.hash);
|
|
93
|
+
else
|
|
94
|
+
scrollTo(saved?.[0] ?? 0, saved?.[1] ?? 0);
|
|
95
|
+
});
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
71
98
|
current.set(next);
|
|
72
99
|
restoreScroll(next);
|
|
73
100
|
});
|
|
@@ -122,16 +149,15 @@ function navigate(to, options = {}) {
|
|
|
122
149
|
else
|
|
123
150
|
history.pushState(options.state ?? null, "", url);
|
|
124
151
|
window.dispatchEvent(new CustomEvent("keeno:navigate", { detail: { url: url.href, state: options.state ?? null } }));
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
152
|
+
withTransition(options.transition ?? transitionsDefault, () => {
|
|
153
|
+
current.set(readLocation());
|
|
154
|
+
if (options.scroll === false)
|
|
155
|
+
return;
|
|
156
|
+
if (url.hash)
|
|
157
|
+
scrollToHash(url.hash);
|
|
158
|
+
else if (typeof window.scrollTo === "function")
|
|
159
|
+
scrollTo(0, 0);
|
|
160
|
+
});
|
|
135
161
|
}
|
|
136
162
|
function isExternalClick(e, a) {
|
|
137
163
|
if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey)
|
|
@@ -149,7 +175,10 @@ function link(e) {
|
|
|
149
175
|
if (!underBase(url.pathname, base.peek()))
|
|
150
176
|
return;
|
|
151
177
|
e.preventDefault();
|
|
152
|
-
navigate(stripBase(url.pathname, base.peek()) + url.search + url.hash, {
|
|
178
|
+
navigate(stripBase(url.pathname, base.peek()) + url.search + url.hash, {
|
|
179
|
+
replace: a.hasAttribute("data-replace"),
|
|
180
|
+
transition: a.hasAttribute("data-transition") ? a.getAttribute("data-transition") !== "false" : undefined
|
|
181
|
+
});
|
|
153
182
|
}
|
|
154
183
|
var compiled = new WeakMap;
|
|
155
184
|
function compile(route) {
|
|
@@ -208,6 +237,7 @@ function Router(props) {
|
|
|
208
237
|
const loc = url != null ? new State(parseUrl(url)) : current;
|
|
209
238
|
if (url == null) {
|
|
210
239
|
base.set(routerBase);
|
|
240
|
+
transitionsDefault = !!untrack(() => props.viewTransition);
|
|
211
241
|
sync();
|
|
212
242
|
}
|
|
213
243
|
const outside = (l) => !underBase(l.pathname, routerBase);
|
|
@@ -323,7 +353,7 @@ function Link(props) {
|
|
|
323
353
|
if (isExternalClick(e, a))
|
|
324
354
|
return;
|
|
325
355
|
e.preventDefault();
|
|
326
|
-
navigate(props.href, { replace: props.replace });
|
|
356
|
+
navigate(props.href, { replace: props.replace, transition: props.transition });
|
|
327
357
|
});
|
|
328
358
|
insert(a, () => props.children?.());
|
|
329
359
|
return a;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inflector/keeno-router",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Client-side router for Keeno (.kn) apps",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"prepack": "bun run build"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"@inflector/keeno": ">=0.
|
|
42
|
+
"@inflector/keeno": ">=0.5.0 <1.0.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@inflector/keeno": "0.
|
|
45
|
+
"@inflector/keeno": "0.5.0"
|
|
46
46
|
},
|
|
47
47
|
"publishConfig": {
|
|
48
48
|
"access": "public"
|