@real-router/solid 0.10.0 → 0.11.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/README.md +1 -1
- package/dist/cjs/index.d.ts +22 -1
- package/dist/cjs/index.js +43 -26
- package/dist/esm/index.d.mts +22 -1
- package/dist/esm/index.mjs +43 -26
- package/dist/types/dom-utils/scroll-restore.d.ts +22 -1
- package/dist/types/dom-utils/scroll-restore.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -372,7 +372,7 @@ Opt-in preservation of scroll position across navigations:
|
|
|
372
372
|
</RouterProvider>
|
|
373
373
|
```
|
|
374
374
|
|
|
375
|
-
Restores scroll on back/forward, scrolls to top (or `#hash`) on push. Three modes: `"restore"` (default), `"top"`, `"
|
|
375
|
+
Restores scroll on back/forward, scrolls to top (or `#hash`) on push. Three modes: `"restore"` (default), `"top"`, `"native"`. Custom containers via `scrollContainer: () => HTMLElement | null`. Options are read once on mount — changing the prop at runtime does not reconfigure the utility (Solid `onMount` is non-reactive). See [Scroll Restoration guide](https://github.com/greydragon888/real-router/wiki/Scroll-Restoration) for details.
|
|
376
376
|
|
|
377
377
|
## View Transitions
|
|
378
378
|
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -273,11 +273,32 @@ interface UseRouteEnterOptions {
|
|
|
273
273
|
*/
|
|
274
274
|
declare function useRouteEnter(handler: RouteEnterHandler, options?: UseRouteEnterOptions): void;
|
|
275
275
|
|
|
276
|
-
type ScrollRestorationMode = "restore" | "top" | "
|
|
276
|
+
type ScrollRestorationMode = "restore" | "top" | "native";
|
|
277
277
|
interface ScrollRestorationOptions {
|
|
278
278
|
mode?: ScrollRestorationMode | undefined;
|
|
279
279
|
anchorScrolling?: boolean | undefined;
|
|
280
280
|
scrollContainer?: (() => HTMLElement | null) | undefined;
|
|
281
|
+
/**
|
|
282
|
+
* Scroll behavior passed to `scrollTo({ behavior })` and
|
|
283
|
+
* `scrollIntoView({ behavior })`.
|
|
284
|
+
*
|
|
285
|
+
* - `"auto"` (default) — browser-defined, usually instant.
|
|
286
|
+
* - `"instant"` — explicit instant jump (no animation).
|
|
287
|
+
* - `"smooth"` — animated transition. Note: smooth restore on back/traverse
|
|
288
|
+
* can feel disorienting if the user expects to land at the saved position
|
|
289
|
+
* immediately. Recommended for `mode: "top"` or anchor scroll only.
|
|
290
|
+
*
|
|
291
|
+
* See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/ScrollToOptions/behavior).
|
|
292
|
+
*/
|
|
293
|
+
behavior?: ScrollBehavior | undefined;
|
|
294
|
+
/**
|
|
295
|
+
* sessionStorage key used to persist saved scroll positions. Default:
|
|
296
|
+
* `"real-router:scroll"`. Override only when multiple independent
|
|
297
|
+
* `RouterProvider` instances share the same document and you need to
|
|
298
|
+
* isolate their scroll stores (e.g. micro-frontends, embedded widgets,
|
|
299
|
+
* or testing). For a single app with one provider the default is fine.
|
|
300
|
+
*/
|
|
301
|
+
storageKey?: string | undefined;
|
|
281
302
|
}
|
|
282
303
|
|
|
283
304
|
interface RouteProviderProps {
|
package/dist/cjs/index.js
CHANGED
|
@@ -336,7 +336,7 @@ function manageFocus(h1) {
|
|
|
336
336
|
});
|
|
337
337
|
}
|
|
338
338
|
|
|
339
|
-
const
|
|
339
|
+
const DEFAULT_STORAGE_KEY = "real-router:scroll";
|
|
340
340
|
const NOOP_INSTANCE$1 = Object.freeze({
|
|
341
341
|
destroy: () => {
|
|
342
342
|
/* no-op */
|
|
@@ -348,14 +348,36 @@ function createScrollRestoration(router, options) {
|
|
|
348
348
|
}
|
|
349
349
|
const mode = options?.mode ?? "restore";
|
|
350
350
|
|
|
351
|
-
// mode "
|
|
352
|
-
// don't subscribe, don't register pagehide —
|
|
353
|
-
//
|
|
354
|
-
|
|
351
|
+
// mode "native" = utility does nothing. Don't flip history.scrollRestoration,
|
|
352
|
+
// don't subscribe, don't register pagehide — `history.scrollRestoration`
|
|
353
|
+
// stays at the browser default ("auto") so the browser handles scroll
|
|
354
|
+
// restore natively. (Note: this is the OPPOSITE of `history.scrollRestoration
|
|
355
|
+
// === "manual"` — utility's "native" leaves the DOM property at "auto" so
|
|
356
|
+
// the browser is in charge.)
|
|
357
|
+
if (mode === "native") {
|
|
355
358
|
return NOOP_INSTANCE$1;
|
|
356
359
|
}
|
|
357
360
|
const anchorEnabled = options?.anchorScrolling ?? true;
|
|
358
361
|
const getContainer = options?.scrollContainer;
|
|
362
|
+
const behavior = options?.behavior ?? "auto";
|
|
363
|
+
const storageKey = options?.storageKey ?? DEFAULT_STORAGE_KEY;
|
|
364
|
+
const loadStore = () => {
|
|
365
|
+
try {
|
|
366
|
+
const raw = sessionStorage.getItem(storageKey);
|
|
367
|
+
return raw ? JSON.parse(raw) : {};
|
|
368
|
+
} catch {
|
|
369
|
+
return {};
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
const putPos = (key, pos) => {
|
|
373
|
+
try {
|
|
374
|
+
const store = loadStore();
|
|
375
|
+
store[key] = pos;
|
|
376
|
+
sessionStorage.setItem(storageKey, JSON.stringify(store));
|
|
377
|
+
} catch {
|
|
378
|
+
// Ignore quota / security errors.
|
|
379
|
+
}
|
|
380
|
+
};
|
|
359
381
|
const prevScrollRestoration = history.scrollRestoration;
|
|
360
382
|
try {
|
|
361
383
|
history.scrollRestoration = "manual";
|
|
@@ -373,9 +395,17 @@ function createScrollRestoration(router, options) {
|
|
|
373
395
|
const writePos = top => {
|
|
374
396
|
const element = getContainer?.();
|
|
375
397
|
if (element) {
|
|
376
|
-
element.
|
|
398
|
+
element.scrollTo({
|
|
399
|
+
top,
|
|
400
|
+
left: 0,
|
|
401
|
+
behavior
|
|
402
|
+
});
|
|
377
403
|
} else {
|
|
378
|
-
globalThis.scrollTo(
|
|
404
|
+
globalThis.scrollTo({
|
|
405
|
+
top,
|
|
406
|
+
left: 0,
|
|
407
|
+
behavior
|
|
408
|
+
});
|
|
379
409
|
}
|
|
380
410
|
};
|
|
381
411
|
const scrollToHashOrTop = route => {
|
|
@@ -389,7 +419,9 @@ function createScrollRestoration(router, options) {
|
|
|
389
419
|
// eslint-disable-next-line unicorn/prefer-query-selector -- ids may contain CSS-unsafe chars
|
|
390
420
|
const element = document.getElementById(ctxHash);
|
|
391
421
|
if (element) {
|
|
392
|
-
element.scrollIntoView(
|
|
422
|
+
element.scrollIntoView({
|
|
423
|
+
behavior
|
|
424
|
+
});
|
|
393
425
|
return;
|
|
394
426
|
}
|
|
395
427
|
}
|
|
@@ -413,7 +445,9 @@ function createScrollRestoration(router, options) {
|
|
|
413
445
|
// eslint-disable-next-line unicorn/prefer-query-selector -- ids may contain CSS-unsafe chars
|
|
414
446
|
const element = document.getElementById(id);
|
|
415
447
|
if (element) {
|
|
416
|
-
element.scrollIntoView(
|
|
448
|
+
element.scrollIntoView({
|
|
449
|
+
behavior
|
|
450
|
+
});
|
|
417
451
|
return;
|
|
418
452
|
}
|
|
419
453
|
}
|
|
@@ -479,23 +513,6 @@ function createScrollRestoration(router, options) {
|
|
|
479
513
|
function keyOf(state) {
|
|
480
514
|
return `${state.name}:${canonicalJson(state.params)}`;
|
|
481
515
|
}
|
|
482
|
-
function loadStore() {
|
|
483
|
-
try {
|
|
484
|
-
const raw = sessionStorage.getItem(STORAGE_KEY);
|
|
485
|
-
return raw ? JSON.parse(raw) : {};
|
|
486
|
-
} catch {
|
|
487
|
-
return {};
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
function putPos(key, pos) {
|
|
491
|
-
try {
|
|
492
|
-
const store = loadStore();
|
|
493
|
-
store[key] = pos;
|
|
494
|
-
sessionStorage.setItem(STORAGE_KEY, JSON.stringify(store));
|
|
495
|
-
} catch {
|
|
496
|
-
// Ignore quota / security errors.
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
516
|
function canonicalJson(value) {
|
|
500
517
|
return JSON.stringify(value, canonicalReplacer);
|
|
501
518
|
}
|
package/dist/esm/index.d.mts
CHANGED
|
@@ -273,11 +273,32 @@ interface UseRouteEnterOptions {
|
|
|
273
273
|
*/
|
|
274
274
|
declare function useRouteEnter(handler: RouteEnterHandler, options?: UseRouteEnterOptions): void;
|
|
275
275
|
|
|
276
|
-
type ScrollRestorationMode = "restore" | "top" | "
|
|
276
|
+
type ScrollRestorationMode = "restore" | "top" | "native";
|
|
277
277
|
interface ScrollRestorationOptions {
|
|
278
278
|
mode?: ScrollRestorationMode | undefined;
|
|
279
279
|
anchorScrolling?: boolean | undefined;
|
|
280
280
|
scrollContainer?: (() => HTMLElement | null) | undefined;
|
|
281
|
+
/**
|
|
282
|
+
* Scroll behavior passed to `scrollTo({ behavior })` and
|
|
283
|
+
* `scrollIntoView({ behavior })`.
|
|
284
|
+
*
|
|
285
|
+
* - `"auto"` (default) — browser-defined, usually instant.
|
|
286
|
+
* - `"instant"` — explicit instant jump (no animation).
|
|
287
|
+
* - `"smooth"` — animated transition. Note: smooth restore on back/traverse
|
|
288
|
+
* can feel disorienting if the user expects to land at the saved position
|
|
289
|
+
* immediately. Recommended for `mode: "top"` or anchor scroll only.
|
|
290
|
+
*
|
|
291
|
+
* See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/ScrollToOptions/behavior).
|
|
292
|
+
*/
|
|
293
|
+
behavior?: ScrollBehavior | undefined;
|
|
294
|
+
/**
|
|
295
|
+
* sessionStorage key used to persist saved scroll positions. Default:
|
|
296
|
+
* `"real-router:scroll"`. Override only when multiple independent
|
|
297
|
+
* `RouterProvider` instances share the same document and you need to
|
|
298
|
+
* isolate their scroll stores (e.g. micro-frontends, embedded widgets,
|
|
299
|
+
* or testing). For a single app with one provider the default is fine.
|
|
300
|
+
*/
|
|
301
|
+
storageKey?: string | undefined;
|
|
281
302
|
}
|
|
282
303
|
|
|
283
304
|
interface RouteProviderProps {
|
package/dist/esm/index.mjs
CHANGED
|
@@ -334,7 +334,7 @@ function manageFocus(h1) {
|
|
|
334
334
|
});
|
|
335
335
|
}
|
|
336
336
|
|
|
337
|
-
const
|
|
337
|
+
const DEFAULT_STORAGE_KEY = "real-router:scroll";
|
|
338
338
|
const NOOP_INSTANCE$1 = Object.freeze({
|
|
339
339
|
destroy: () => {
|
|
340
340
|
/* no-op */
|
|
@@ -346,14 +346,36 @@ function createScrollRestoration(router, options) {
|
|
|
346
346
|
}
|
|
347
347
|
const mode = options?.mode ?? "restore";
|
|
348
348
|
|
|
349
|
-
// mode "
|
|
350
|
-
// don't subscribe, don't register pagehide —
|
|
351
|
-
//
|
|
352
|
-
|
|
349
|
+
// mode "native" = utility does nothing. Don't flip history.scrollRestoration,
|
|
350
|
+
// don't subscribe, don't register pagehide — `history.scrollRestoration`
|
|
351
|
+
// stays at the browser default ("auto") so the browser handles scroll
|
|
352
|
+
// restore natively. (Note: this is the OPPOSITE of `history.scrollRestoration
|
|
353
|
+
// === "manual"` — utility's "native" leaves the DOM property at "auto" so
|
|
354
|
+
// the browser is in charge.)
|
|
355
|
+
if (mode === "native") {
|
|
353
356
|
return NOOP_INSTANCE$1;
|
|
354
357
|
}
|
|
355
358
|
const anchorEnabled = options?.anchorScrolling ?? true;
|
|
356
359
|
const getContainer = options?.scrollContainer;
|
|
360
|
+
const behavior = options?.behavior ?? "auto";
|
|
361
|
+
const storageKey = options?.storageKey ?? DEFAULT_STORAGE_KEY;
|
|
362
|
+
const loadStore = () => {
|
|
363
|
+
try {
|
|
364
|
+
const raw = sessionStorage.getItem(storageKey);
|
|
365
|
+
return raw ? JSON.parse(raw) : {};
|
|
366
|
+
} catch {
|
|
367
|
+
return {};
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
const putPos = (key, pos) => {
|
|
371
|
+
try {
|
|
372
|
+
const store = loadStore();
|
|
373
|
+
store[key] = pos;
|
|
374
|
+
sessionStorage.setItem(storageKey, JSON.stringify(store));
|
|
375
|
+
} catch {
|
|
376
|
+
// Ignore quota / security errors.
|
|
377
|
+
}
|
|
378
|
+
};
|
|
357
379
|
const prevScrollRestoration = history.scrollRestoration;
|
|
358
380
|
try {
|
|
359
381
|
history.scrollRestoration = "manual";
|
|
@@ -371,9 +393,17 @@ function createScrollRestoration(router, options) {
|
|
|
371
393
|
const writePos = top => {
|
|
372
394
|
const element = getContainer?.();
|
|
373
395
|
if (element) {
|
|
374
|
-
element.
|
|
396
|
+
element.scrollTo({
|
|
397
|
+
top,
|
|
398
|
+
left: 0,
|
|
399
|
+
behavior
|
|
400
|
+
});
|
|
375
401
|
} else {
|
|
376
|
-
globalThis.scrollTo(
|
|
402
|
+
globalThis.scrollTo({
|
|
403
|
+
top,
|
|
404
|
+
left: 0,
|
|
405
|
+
behavior
|
|
406
|
+
});
|
|
377
407
|
}
|
|
378
408
|
};
|
|
379
409
|
const scrollToHashOrTop = route => {
|
|
@@ -387,7 +417,9 @@ function createScrollRestoration(router, options) {
|
|
|
387
417
|
// eslint-disable-next-line unicorn/prefer-query-selector -- ids may contain CSS-unsafe chars
|
|
388
418
|
const element = document.getElementById(ctxHash);
|
|
389
419
|
if (element) {
|
|
390
|
-
element.scrollIntoView(
|
|
420
|
+
element.scrollIntoView({
|
|
421
|
+
behavior
|
|
422
|
+
});
|
|
391
423
|
return;
|
|
392
424
|
}
|
|
393
425
|
}
|
|
@@ -411,7 +443,9 @@ function createScrollRestoration(router, options) {
|
|
|
411
443
|
// eslint-disable-next-line unicorn/prefer-query-selector -- ids may contain CSS-unsafe chars
|
|
412
444
|
const element = document.getElementById(id);
|
|
413
445
|
if (element) {
|
|
414
|
-
element.scrollIntoView(
|
|
446
|
+
element.scrollIntoView({
|
|
447
|
+
behavior
|
|
448
|
+
});
|
|
415
449
|
return;
|
|
416
450
|
}
|
|
417
451
|
}
|
|
@@ -477,23 +511,6 @@ function createScrollRestoration(router, options) {
|
|
|
477
511
|
function keyOf(state) {
|
|
478
512
|
return `${state.name}:${canonicalJson(state.params)}`;
|
|
479
513
|
}
|
|
480
|
-
function loadStore() {
|
|
481
|
-
try {
|
|
482
|
-
const raw = sessionStorage.getItem(STORAGE_KEY);
|
|
483
|
-
return raw ? JSON.parse(raw) : {};
|
|
484
|
-
} catch {
|
|
485
|
-
return {};
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
function putPos(key, pos) {
|
|
489
|
-
try {
|
|
490
|
-
const store = loadStore();
|
|
491
|
-
store[key] = pos;
|
|
492
|
-
sessionStorage.setItem(STORAGE_KEY, JSON.stringify(store));
|
|
493
|
-
} catch {
|
|
494
|
-
// Ignore quota / security errors.
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
514
|
function canonicalJson(value) {
|
|
498
515
|
return JSON.stringify(value, canonicalReplacer);
|
|
499
516
|
}
|
|
@@ -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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scroll-restore.d.ts","sourceRoot":"","sources":["../../../src/dom-utils/scroll-restore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAS,MAAM,mBAAmB,CAAC;AAUvD,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,CAAC;AAEjE,MAAM,WAAW,wBAAwB;IACvC,IAAI,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACzC,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,eAAe,CAAC,EAAE,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"scroll-restore.d.ts","sourceRoot":"","sources":["../../../src/dom-utils/scroll-restore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAS,MAAM,mBAAmB,CAAC;AAUvD,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,CAAC;AAEjE,MAAM,WAAW,wBAAwB;IACvC,IAAI,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACzC,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,eAAe,CAAC,EAAE,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC;IACzD;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACtC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAOD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,wBAAwB,GACjC;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAkMzB"}
|