@uniweb/runtime 1.3.12 → 1.3.14
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/ssr.js.map +1 -1
- package/package.json +2 -2
- package/src/area-wrappers.js +3 -1
- package/src/navigation.js +25 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uniweb/runtime",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.14",
|
|
4
4
|
"description": "Minimal runtime for loading Uniweb foundations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"esbuild": "^0.21.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.27.0 || ^0.28.0",
|
|
45
45
|
"vite": "^7.3.1",
|
|
46
46
|
"vitest": "^4.1.7",
|
|
47
|
-
"@uniweb/build": "1.14.
|
|
47
|
+
"@uniweb/build": "1.14.3"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"react": "^19.0.0",
|
package/src/area-wrappers.js
CHANGED
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
* each layout area a `view-transition-name` so the browser animates it on its
|
|
6
6
|
* own — persistent chrome (header, sidebar, footer) morphs in place while
|
|
7
7
|
* everything else, the body included, crossfades as the page. With no names the
|
|
8
|
-
* whole layout (chrome included) would flicker on every navigation.
|
|
8
|
+
* whole layout (chrome included) would flicker on every navigation. An area with
|
|
9
|
+
* no height has nothing to capture, so a navigation folds it back into the page
|
|
10
|
+
* (`foldEmptyAreas`, `navigation.js`).
|
|
9
11
|
*
|
|
10
12
|
* ⛔ **The body takes no name by default, which is what keeps a phone usable.** A
|
|
11
13
|
* named element is captured as one image. WebKit captures it whole, off-screen part
|
package/src/navigation.js
CHANGED
|
@@ -74,6 +74,29 @@ function pageAt(to) {
|
|
|
74
74
|
return website.getPage(route.split(/[?#]/)[0]) || null
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Folds an area with no height back into the page's crossfade, as a `null` in a layout's `transitions`
|
|
79
|
+
* would.
|
|
80
|
+
*
|
|
81
|
+
* ⛔ A named element is captured at its own size, so a box with no height is captured as nothing,
|
|
82
|
+
* whatever overflows it. A bar that overlays the page is that box: `fixed`, or `absolute` in a sticky
|
|
83
|
+
* box it doesn't fill. Its name took it out of the page's capture and its own capture drew nothing,
|
|
84
|
+
* so the bar was gone for the length of every transition and came back at the end. Measured
|
|
85
|
+
* 2026-11-02 in Chromium and WebKit.
|
|
86
|
+
*
|
|
87
|
+
* An area with nothing in it keeps its name, since a sidebar that fills on the next page should still
|
|
88
|
+
* move on its own. A folded name stays folded: React wrote it and has no reason to write it again,
|
|
89
|
+
* except on a new element, so this runs again once a page has committed, for a layout change.
|
|
90
|
+
*/
|
|
91
|
+
function foldEmptyAreas() {
|
|
92
|
+
for (const area of document.querySelectorAll('[style*="view-transition-name"]')) {
|
|
93
|
+
const box = area.getClientRects()[0]
|
|
94
|
+
if (box && !box.height && [...area.querySelectorAll('*')].some((el) => el.getBoundingClientRect().height)) {
|
|
95
|
+
area.style.viewTransitionName = 'none'
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
77
100
|
/** Whether `page`'s content can be shown now: `PageRenderer`'s own test. */
|
|
78
101
|
function isReady(page) {
|
|
79
102
|
return !page || !page.hasContent() || page.isContentLoaded()
|
|
@@ -206,11 +229,12 @@ export function navigateInApp(navigate, to, options) {
|
|
|
206
229
|
navigate(to, options)
|
|
207
230
|
return
|
|
208
231
|
}
|
|
232
|
+
foldEmptyAreas()
|
|
209
233
|
const transition = document.startViewTransition(() => {
|
|
210
234
|
// Asked before navigating: a router that commits synchronously settles it from inside `navigate`.
|
|
211
235
|
const committed = nextPageCommit()
|
|
212
236
|
navigate(to, options)
|
|
213
|
-
return committed
|
|
237
|
+
return committed.then(foldEmptyAreas)
|
|
214
238
|
})
|
|
215
239
|
// A transition the browser skips, for a duplicate `view-transition-name` or a newer
|
|
216
240
|
// transition, still runs its callback, so the page is swapped all the same. The browser
|