@real-router/svelte 0.9.0 → 0.10.1
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/README.md
CHANGED
|
@@ -425,7 +425,7 @@ Opt-in preservation of scroll position across navigations:
|
|
|
425
425
|
</RouterProvider>
|
|
426
426
|
```
|
|
427
427
|
|
|
428
|
-
Restores scroll on back/forward, scrolls to top (or `#hash`) on push. Three modes: `"restore"` (default), `"top"`, `"
|
|
428
|
+
Restores scroll on back/forward, scrolls to top (or `#hash`) on push. Three modes: `"restore"` (default), `"top"`, `"native"`. Custom containers via `scrollContainer: () => HTMLElement | null`. Lifecycle tied to the provider — created on mount, destroyed on unmount. See [Scroll Restoration guide](https://github.com/greydragon888/real-router/wiki/Scroll-Restoration) for details.
|
|
429
429
|
|
|
430
430
|
## View Transitions
|
|
431
431
|
|
|
@@ -42,16 +42,23 @@
|
|
|
42
42
|
const srEnabled = $derived(scrollRestoration !== undefined);
|
|
43
43
|
const srMode = $derived(scrollRestoration?.mode);
|
|
44
44
|
const srAnchor = $derived(scrollRestoration?.anchorScrolling);
|
|
45
|
+
const srBehavior = $derived(scrollRestoration?.behavior);
|
|
46
|
+
const srStorageKey = $derived(scrollRestoration?.storageKey);
|
|
45
47
|
|
|
46
48
|
$effect(() => {
|
|
47
49
|
if (!srEnabled) return;
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
|
|
50
|
+
// Read scrollRestoration object props via `untrack` for non-primitive
|
|
51
|
+
// refs that naturally change each render. Primitive $derived memos
|
|
52
|
+
// (mode/anchor/behavior/storageKey) drive re-runs.
|
|
53
|
+
void srMode;
|
|
54
|
+
void srAnchor;
|
|
55
|
+
void srBehavior;
|
|
56
|
+
void srStorageKey;
|
|
52
57
|
const sr = createScrollRestoration(router, {
|
|
53
58
|
mode: srMode,
|
|
54
59
|
anchorScrolling: srAnchor,
|
|
60
|
+
behavior: srBehavior,
|
|
61
|
+
storageKey: srStorageKey,
|
|
55
62
|
scrollContainer: untrack(() => scrollRestoration?.scrollContainer),
|
|
56
63
|
});
|
|
57
64
|
return () => sr.destroy();
|
|
@@ -1,9 +1,30 @@
|
|
|
1
1
|
import type { Router } from "@real-router/core";
|
|
2
|
-
export type ScrollRestorationMode = "restore" | "top" | "
|
|
2
|
+
export type ScrollRestorationMode = "restore" | "top" | "native";
|
|
3
3
|
export interface ScrollRestorationOptions {
|
|
4
4
|
mode?: ScrollRestorationMode | undefined;
|
|
5
5
|
anchorScrolling?: boolean | undefined;
|
|
6
6
|
scrollContainer?: (() => HTMLElement | null) | undefined;
|
|
7
|
+
/**
|
|
8
|
+
* Scroll behavior passed to `scrollTo({ behavior })` and
|
|
9
|
+
* `scrollIntoView({ behavior })`.
|
|
10
|
+
*
|
|
11
|
+
* - `"auto"` (default) — browser-defined, usually instant.
|
|
12
|
+
* - `"instant"` — explicit instant jump (no animation).
|
|
13
|
+
* - `"smooth"` — animated transition. Note: smooth restore on back/traverse
|
|
14
|
+
* can feel disorienting if the user expects to land at the saved position
|
|
15
|
+
* immediately. Recommended for `mode: "top"` or anchor scroll only.
|
|
16
|
+
*
|
|
17
|
+
* See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/ScrollToOptions/behavior).
|
|
18
|
+
*/
|
|
19
|
+
behavior?: ScrollBehavior | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* sessionStorage key used to persist saved scroll positions. Default:
|
|
22
|
+
* `"real-router:scroll"`. Override only when multiple independent
|
|
23
|
+
* `RouterProvider` instances share the same document and you need to
|
|
24
|
+
* isolate their scroll stores (e.g. micro-frontends, embedded widgets,
|
|
25
|
+
* or testing). For a single app with one provider the default is fine.
|
|
26
|
+
*/
|
|
27
|
+
storageKey?: string | undefined;
|
|
7
28
|
}
|
|
8
29
|
export declare function createScrollRestoration(router: Router, options?: ScrollRestorationOptions): {
|
|
9
30
|
destroy: () => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const DEFAULT_STORAGE_KEY = "real-router:scroll";
|
|
2
2
|
const NOOP_INSTANCE = Object.freeze({
|
|
3
3
|
destroy: () => {
|
|
4
4
|
/* no-op */
|
|
@@ -9,14 +9,38 @@ export function createScrollRestoration(router, options) {
|
|
|
9
9
|
return NOOP_INSTANCE;
|
|
10
10
|
}
|
|
11
11
|
const mode = options?.mode ?? "restore";
|
|
12
|
-
// mode "
|
|
13
|
-
// don't subscribe, don't register pagehide —
|
|
14
|
-
//
|
|
15
|
-
|
|
12
|
+
// mode "native" = utility does nothing. Don't flip history.scrollRestoration,
|
|
13
|
+
// don't subscribe, don't register pagehide — `history.scrollRestoration`
|
|
14
|
+
// stays at the browser default ("auto") so the browser handles scroll
|
|
15
|
+
// restore natively. (Note: this is the OPPOSITE of `history.scrollRestoration
|
|
16
|
+
// === "manual"` — utility's "native" leaves the DOM property at "auto" so
|
|
17
|
+
// the browser is in charge.)
|
|
18
|
+
if (mode === "native") {
|
|
16
19
|
return NOOP_INSTANCE;
|
|
17
20
|
}
|
|
18
21
|
const anchorEnabled = options?.anchorScrolling ?? true;
|
|
19
22
|
const getContainer = options?.scrollContainer;
|
|
23
|
+
const behavior = options?.behavior ?? "auto";
|
|
24
|
+
const storageKey = options?.storageKey ?? DEFAULT_STORAGE_KEY;
|
|
25
|
+
const loadStore = () => {
|
|
26
|
+
try {
|
|
27
|
+
const raw = sessionStorage.getItem(storageKey);
|
|
28
|
+
return raw ? JSON.parse(raw) : {};
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return {};
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const putPos = (key, pos) => {
|
|
35
|
+
try {
|
|
36
|
+
const store = loadStore();
|
|
37
|
+
store[key] = pos;
|
|
38
|
+
sessionStorage.setItem(storageKey, JSON.stringify(store));
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Ignore quota / security errors.
|
|
42
|
+
}
|
|
43
|
+
};
|
|
20
44
|
const prevScrollRestoration = history.scrollRestoration;
|
|
21
45
|
try {
|
|
22
46
|
history.scrollRestoration = "manual";
|
|
@@ -34,10 +58,10 @@ export function createScrollRestoration(router, options) {
|
|
|
34
58
|
const writePos = (top) => {
|
|
35
59
|
const element = getContainer?.();
|
|
36
60
|
if (element) {
|
|
37
|
-
element.
|
|
61
|
+
element.scrollTo({ top, left: 0, behavior });
|
|
38
62
|
}
|
|
39
63
|
else {
|
|
40
|
-
globalThis.scrollTo(0,
|
|
64
|
+
globalThis.scrollTo({ top, left: 0, behavior });
|
|
41
65
|
}
|
|
42
66
|
};
|
|
43
67
|
const scrollToHashOrTop = (route) => {
|
|
@@ -52,7 +76,7 @@ export function createScrollRestoration(router, options) {
|
|
|
52
76
|
// eslint-disable-next-line unicorn/prefer-query-selector -- ids may contain CSS-unsafe chars
|
|
53
77
|
const element = document.getElementById(ctxHash);
|
|
54
78
|
if (element) {
|
|
55
|
-
element.scrollIntoView();
|
|
79
|
+
element.scrollIntoView({ behavior });
|
|
56
80
|
return;
|
|
57
81
|
}
|
|
58
82
|
}
|
|
@@ -75,7 +99,7 @@ export function createScrollRestoration(router, options) {
|
|
|
75
99
|
// eslint-disable-next-line unicorn/prefer-query-selector -- ids may contain CSS-unsafe chars
|
|
76
100
|
const element = document.getElementById(id);
|
|
77
101
|
if (element) {
|
|
78
|
-
element.scrollIntoView();
|
|
102
|
+
element.scrollIntoView({ behavior });
|
|
79
103
|
return;
|
|
80
104
|
}
|
|
81
105
|
}
|
|
@@ -140,25 +164,6 @@ export function createScrollRestoration(router, options) {
|
|
|
140
164
|
function keyOf(state) {
|
|
141
165
|
return `${state.name}:${canonicalJson(state.params)}`;
|
|
142
166
|
}
|
|
143
|
-
function loadStore() {
|
|
144
|
-
try {
|
|
145
|
-
const raw = sessionStorage.getItem(STORAGE_KEY);
|
|
146
|
-
return raw ? JSON.parse(raw) : {};
|
|
147
|
-
}
|
|
148
|
-
catch {
|
|
149
|
-
return {};
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
function putPos(key, pos) {
|
|
153
|
-
try {
|
|
154
|
-
const store = loadStore();
|
|
155
|
-
store[key] = pos;
|
|
156
|
-
sessionStorage.setItem(STORAGE_KEY, JSON.stringify(store));
|
|
157
|
-
}
|
|
158
|
-
catch {
|
|
159
|
-
// Ignore quota / security errors.
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
167
|
function canonicalJson(value) {
|
|
163
168
|
return JSON.stringify(value, canonicalReplacer);
|
|
164
169
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@real-router/svelte",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Svelte 5 integration for Real-Router",
|
|
6
6
|
"svelte": "./dist/index.js",
|
|
@@ -44,9 +44,9 @@
|
|
|
44
44
|
"license": "MIT",
|
|
45
45
|
"sideEffects": false,
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@real-router/core": "^0.
|
|
47
|
+
"@real-router/core": "^0.52.0",
|
|
48
48
|
"@real-router/route-utils": "^0.2.2",
|
|
49
|
-
"@real-router/sources": "^0.8.
|
|
49
|
+
"@real-router/sources": "^0.8.1"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@sveltejs/package": "2.5.7",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"svelte": "5.54.0",
|
|
59
59
|
"svelte-check": "4.4.5",
|
|
60
60
|
"svelte-eslint-parser": "1.6.0",
|
|
61
|
-
"@real-router/browser-plugin": "^0.17.
|
|
61
|
+
"@real-router/browser-plugin": "^0.17.1"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
64
|
"svelte": ">=5.7.0"
|
|
@@ -42,16 +42,23 @@
|
|
|
42
42
|
const srEnabled = $derived(scrollRestoration !== undefined);
|
|
43
43
|
const srMode = $derived(scrollRestoration?.mode);
|
|
44
44
|
const srAnchor = $derived(scrollRestoration?.anchorScrolling);
|
|
45
|
+
const srBehavior = $derived(scrollRestoration?.behavior);
|
|
46
|
+
const srStorageKey = $derived(scrollRestoration?.storageKey);
|
|
45
47
|
|
|
46
48
|
$effect(() => {
|
|
47
49
|
if (!srEnabled) return;
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
|
|
50
|
+
// Read scrollRestoration object props via `untrack` for non-primitive
|
|
51
|
+
// refs that naturally change each render. Primitive $derived memos
|
|
52
|
+
// (mode/anchor/behavior/storageKey) drive re-runs.
|
|
53
|
+
void srMode;
|
|
54
|
+
void srAnchor;
|
|
55
|
+
void srBehavior;
|
|
56
|
+
void srStorageKey;
|
|
52
57
|
const sr = createScrollRestoration(router, {
|
|
53
58
|
mode: srMode,
|
|
54
59
|
anchorScrolling: srAnchor,
|
|
60
|
+
behavior: srBehavior,
|
|
61
|
+
storageKey: srStorageKey,
|
|
55
62
|
scrollContainer: untrack(() => scrollRestoration?.scrollContainer),
|
|
56
63
|
});
|
|
57
64
|
return () => sr.destroy();
|