@uniweb/runtime 0.6.18 → 0.6.19
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uniweb/runtime",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.19",
|
|
4
4
|
"description": "Minimal runtime for loading Uniweb foundations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@vitejs/plugin-react": "^4.5.2",
|
|
43
43
|
"vite": "^7.3.1",
|
|
44
|
-
"@uniweb/build": "0.8.
|
|
44
|
+
"@uniweb/build": "0.8.22"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -11,9 +11,16 @@
|
|
|
11
11
|
* - Scrolls to top on new navigation (PUSH/REPLACE)
|
|
12
12
|
* - Skips when location.hash is present (defers to useLinkInterceptor)
|
|
13
13
|
* - Optionally resets block states on scroll restoration
|
|
14
|
+
*
|
|
15
|
+
* Implementation note:
|
|
16
|
+
* Uniweb scrolls `window` (not a fixed-size container). When React swaps
|
|
17
|
+
* page content, the browser may clamp scrollY and fire scroll events BEFORE
|
|
18
|
+
* useEffect runs. To prevent those events from corrupting the saved position
|
|
19
|
+
* of the page we're leaving, useLayoutEffect captures the target value and
|
|
20
|
+
* updates the location key ref synchronously — before any scroll events.
|
|
14
21
|
*/
|
|
15
22
|
|
|
16
|
-
import { useEffect, useRef, useCallback } from 'react'
|
|
23
|
+
import { useEffect, useLayoutEffect, useRef, useCallback } from 'react'
|
|
17
24
|
import { useLocation, useNavigationType } from 'react-router-dom'
|
|
18
25
|
|
|
19
26
|
/** In-memory scroll positions keyed by React Router's location.key. */
|
|
@@ -32,6 +39,7 @@ export function useRememberScroll(options = {}) {
|
|
|
32
39
|
const location = useLocation()
|
|
33
40
|
const navigationType = useNavigationType()
|
|
34
41
|
const locationKeyRef = useRef(location.key)
|
|
42
|
+
const savedScrollRef = useRef(null)
|
|
35
43
|
|
|
36
44
|
// Continuously save scroll position for the current location
|
|
37
45
|
const handleScroll = useCallback(() => {
|
|
@@ -45,13 +53,21 @@ export function useRememberScroll(options = {}) {
|
|
|
45
53
|
return () => window.removeEventListener('scroll', handleScroll)
|
|
46
54
|
}, [enabled, handleScroll])
|
|
47
55
|
|
|
56
|
+
// Synchronously capture saved scroll and update key BEFORE browser
|
|
57
|
+
// scroll events can fire (which would corrupt the previous page's value)
|
|
58
|
+
useLayoutEffect(() => {
|
|
59
|
+
if (navigationType === 'POP') {
|
|
60
|
+
savedScrollRef.current = scrollPositions.get(location.key) ?? null
|
|
61
|
+
} else {
|
|
62
|
+
savedScrollRef.current = null
|
|
63
|
+
}
|
|
64
|
+
locationKeyRef.current = location.key
|
|
65
|
+
}, [location.key, navigationType])
|
|
66
|
+
|
|
48
67
|
// On navigation: restore on POP, scroll to top on PUSH/REPLACE
|
|
49
68
|
useEffect(() => {
|
|
50
69
|
if (!enabled) return
|
|
51
70
|
|
|
52
|
-
// Update ref so the scroll listener saves under the new key
|
|
53
|
-
locationKeyRef.current = location.key
|
|
54
|
-
|
|
55
71
|
// Reset block states if requested (for animations, etc.)
|
|
56
72
|
if (resetBlockStates) {
|
|
57
73
|
const page = globalThis.uniweb?.activeWebsite?.activePage
|
|
@@ -64,7 +80,7 @@ export function useRememberScroll(options = {}) {
|
|
|
64
80
|
if (location.hash) return
|
|
65
81
|
|
|
66
82
|
if (navigationType === 'POP') {
|
|
67
|
-
const saved =
|
|
83
|
+
const saved = savedScrollRef.current
|
|
68
84
|
if (saved == null) return
|
|
69
85
|
|
|
70
86
|
// Retry scroll restoration as content may load asynchronously.
|