@adukiorg/anza 0.4.2 → 0.4.3
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/bin/anza/anza-linux-arm64 +0 -0
- package/bin/anza/anza-linux-x64 +0 -0
- package/bin/anza/anza-macos-arm64 +0 -0
- package/bin/anza/anza-macos-x64 +0 -0
- package/bin/anza/anza-windows-x64.exe +0 -0
- package/package.json +1 -1
- package/src/core/router/cascade.js +13 -3
- package/src/core/router/container.js +2 -2
- package/src/core/router/graph.js +7 -4
- package/src/core/router/intercept.js +27 -30
- package/src/core/router/transitions.js +4 -3
- package/src/core/ui/define/container.js +3 -13
- package/src/core/ui/defs/dock.js +10 -14
- package/src/styles/reset.css +0 -2
- package/src/tokens/semantic/transitions.css +8 -5
|
Binary file
|
package/bin/anza/anza-linux-x64
CHANGED
|
Binary file
|
|
Binary file
|
package/bin/anza/anza-macos-x64
CHANGED
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -59,12 +59,22 @@ export async function ensure(target, current = 'main') {
|
|
|
59
59
|
if (resolve(node.name)) continue;
|
|
60
60
|
const parentEl = node.parent?.ref?.deref() ?? null;
|
|
61
61
|
if (!parentEl || !parentEl.isConnected) throw new Error(`CascadeError: parent '${node.parent?.name}' is disconnected while mounting '${node.name}'`);
|
|
62
|
-
const tag = node.
|
|
62
|
+
const tag = node.tag;
|
|
63
63
|
if (tag.includes('-') && typeof customElements !== 'undefined' && !customElements.get(tag)) await customElements.whenDefined(tag);
|
|
64
64
|
const el = document.createElement(tag);
|
|
65
65
|
parentEl.replaceChildren(el);
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
|
|
67
|
+
// Wait for the element's connectedCallback to complete, including any
|
|
68
|
+
// async resource loading (template/style fetches). A single frame is
|
|
69
|
+
// not sufficient when preloadResources() hits the network.
|
|
70
|
+
let attempts = 0;
|
|
71
|
+
while (!resolve(node.name) && attempts < 50) {
|
|
72
|
+
await frame();
|
|
73
|
+
attempts++;
|
|
74
|
+
}
|
|
75
|
+
if (!resolve(node.name)) {
|
|
76
|
+
throw new Error(`CascadeError: container '${node.name}' failed to register after mount`);
|
|
77
|
+
}
|
|
68
78
|
}
|
|
69
79
|
|
|
70
80
|
return resolve(target);
|
|
@@ -62,8 +62,8 @@ function ensureObserver() {
|
|
|
62
62
|
* @param {string|null} [parent='main'] - parent container key in the graph.
|
|
63
63
|
* Pass null explicitly when registering the root (no parent).
|
|
64
64
|
*/
|
|
65
|
-
export function registerContainer(name, element, parent = 'main') {
|
|
66
|
-
add(name, element, parent);
|
|
65
|
+
export function registerContainer(name, element, parent = 'main', tag = null) {
|
|
66
|
+
add(name, element, parent, tag);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
/**
|
package/src/core/router/graph.js
CHANGED
|
@@ -14,8 +14,9 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
class Node {
|
|
17
|
-
constructor(name, ref, parent) {
|
|
17
|
+
constructor(name, tag, ref, parent) {
|
|
18
18
|
this.name = name; // registry key, e.g. 'main' | 'sidebar'
|
|
19
|
+
this.tag = tag; // custom element tag, e.g. 'dock-docs' | 'main'
|
|
19
20
|
this.ref = ref; // WeakRef<Element> | null (null for virtual root)
|
|
20
21
|
this.parent = parent; // Node | null
|
|
21
22
|
this.children = new Set(); // Set<Node>
|
|
@@ -33,7 +34,7 @@ const nodes = new Map();
|
|
|
33
34
|
// The permanent root node. ref is null at module-evaluation time because
|
|
34
35
|
// modules may be evaluated before the parser reaches <main id="main">.
|
|
35
36
|
// boot.js fills in the WeakRef during anchor().
|
|
36
|
-
const root = new Node('main', null, null);
|
|
37
|
+
const root = new Node('main', 'main', null, null);
|
|
37
38
|
root.depth = 0;
|
|
38
39
|
nodes.set('main', root);
|
|
39
40
|
|
|
@@ -76,9 +77,10 @@ function detach(name) {
|
|
|
76
77
|
* @param {string} name - unique registry key.
|
|
77
78
|
* @param {Element} el - the container element.
|
|
78
79
|
* @param {string} [parent='main'] - parent registry key.
|
|
80
|
+
* @param {string} [tag] - custom element tag; defaults to name.
|
|
79
81
|
* @returns {Node} the inserted node.
|
|
80
82
|
*/
|
|
81
|
-
export function add(name, el, parent = 'main') {
|
|
83
|
+
export function add(name, el, parent = 'main', tag = null) {
|
|
82
84
|
gone.delete(name);
|
|
83
85
|
|
|
84
86
|
const existing = nodes.get(name);
|
|
@@ -103,7 +105,8 @@ export function add(name, el, parent = 'main') {
|
|
|
103
105
|
}
|
|
104
106
|
|
|
105
107
|
const parentNode = nodes.get(parent) ?? root;
|
|
106
|
-
const
|
|
108
|
+
const resolvedTag = tag || name;
|
|
109
|
+
const node = new Node(name, resolvedTag, el ? new WeakRef(el) : null, parentNode);
|
|
107
110
|
parentNode.children.add(node);
|
|
108
111
|
nodes.set(name, node);
|
|
109
112
|
if (el) finalizer.register(el, name);
|
|
@@ -16,7 +16,6 @@ import { getContainer } from './container.js';
|
|
|
16
16
|
import { get as graphGet } from './graph.js';
|
|
17
17
|
import { match } from './match.js';
|
|
18
18
|
import { specRegistry } from '../ui/define/state.js';
|
|
19
|
-
import { transitions } from './transitions.js';
|
|
20
19
|
|
|
21
20
|
/**
|
|
22
21
|
* Built-in minimal 404 HTML rendered when no user notfound is configured.
|
|
@@ -241,39 +240,37 @@ async function pipe(event, precommitted) {
|
|
|
241
240
|
}
|
|
242
241
|
}
|
|
243
242
|
|
|
244
|
-
|
|
245
|
-
if (routeMatch) {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
243
|
+
if (routeMatch) {
|
|
244
|
+
if (isCallback(routeMatch.route.handler)) {
|
|
245
|
+
try {
|
|
246
|
+
await runCallback(routeMatch.route.handler, routeMatch.params, event);
|
|
247
|
+
} catch (err) {
|
|
248
|
+
emit('error', { error: err, url: destination.url, route: routeMatch.route, phase: 'handler' });
|
|
249
|
+
return;
|
|
253
250
|
}
|
|
251
|
+
}
|
|
254
252
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
253
|
+
const ctx = buildRouteContext(routeMatch.tag, routeMatch.params, destination.url);
|
|
254
|
+
emit('found', {
|
|
255
|
+
tag: routeMatch.tag,
|
|
256
|
+
params: ctx.params,
|
|
257
|
+
query: ctx.query,
|
|
258
|
+
raw: ctx.raw,
|
|
259
|
+
hash: routeMatch.hash,
|
|
260
|
+
chain: routeMatch.chain,
|
|
261
|
+
via: chain,
|
|
262
|
+
container: chain.at(-1) ?? null,
|
|
263
|
+
url: destination.url,
|
|
264
|
+
direction: event.navigationType
|
|
265
|
+
});
|
|
266
|
+
} else {
|
|
267
|
+
emit('notfound', { url: destination.url });
|
|
268
|
+
if (notFoundHandler) {
|
|
269
|
+
await notFoundHandler(event);
|
|
268
270
|
} else {
|
|
269
|
-
|
|
270
|
-
if (notFoundHandler) {
|
|
271
|
-
await notFoundHandler(event);
|
|
272
|
-
} else {
|
|
273
|
-
renderNotFound('main');
|
|
274
|
-
}
|
|
271
|
+
renderNotFound('main');
|
|
275
272
|
}
|
|
276
|
-
}
|
|
273
|
+
}
|
|
277
274
|
}
|
|
278
275
|
|
|
279
276
|
/**
|
|
@@ -21,12 +21,13 @@ function injectSheet() {
|
|
|
21
21
|
try {
|
|
22
22
|
const sheet = new CSSStyleSheet();
|
|
23
23
|
sheet.replaceSync(`
|
|
24
|
-
|
|
24
|
+
/* Dock-swap group: element-scoped content transitions */
|
|
25
|
+
::view-transition-group(dock-swap) {
|
|
25
26
|
animation-duration: var(--transition-duration);
|
|
26
27
|
animation-timing-function: var(--transition-easing);
|
|
27
28
|
}
|
|
28
|
-
::view-transition-old(
|
|
29
|
-
::view-transition-new(
|
|
29
|
+
::view-transition-old(dock-swap),
|
|
30
|
+
::view-transition-new(dock-swap) {
|
|
30
31
|
animation-duration: var(--transition-duration);
|
|
31
32
|
animation-timing-function: var(--transition-easing);
|
|
32
33
|
background: var(--transition-bg);
|
|
@@ -53,7 +53,9 @@ export function container(tag, spec, base = import.meta.url) {
|
|
|
53
53
|
delete this.dataset.transitionDirection;
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
-
//
|
|
56
|
+
// Only use element-scoped view transitions. Document-level
|
|
57
|
+
// startViewTransition() captures the entire page and causes
|
|
58
|
+
// chrome flicker — never use it as a fallback.
|
|
57
59
|
if (typeof this.startViewTransition === 'function') {
|
|
58
60
|
try {
|
|
59
61
|
const vt = this.startViewTransition(doSwap);
|
|
@@ -64,18 +66,6 @@ export function container(tag, spec, base = import.meta.url) {
|
|
|
64
66
|
return;
|
|
65
67
|
}
|
|
66
68
|
|
|
67
|
-
// Strategy 2: Document-scoped transition (Baseline Oct 2025)
|
|
68
|
-
if (typeof document.startViewTransition === 'function') {
|
|
69
|
-
try {
|
|
70
|
-
const vt = document.startViewTransition(doSwap);
|
|
71
|
-
await vt.ready;
|
|
72
|
-
} catch (err) {
|
|
73
|
-
if (err?.name !== 'AbortError') console.warn('[UI Container] Document VT aborted:', err);
|
|
74
|
-
}
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Strategy 3: Synchronous direct swap
|
|
79
69
|
doSwap();
|
|
80
70
|
};
|
|
81
71
|
}
|
package/src/core/ui/defs/dock.js
CHANGED
|
@@ -34,7 +34,7 @@ export function dock(name, config = {}, base) {
|
|
|
34
34
|
const parent = config.parent ?? 'main';
|
|
35
35
|
|
|
36
36
|
// Statically register the layout container in the graph with a null element
|
|
37
|
-
router.registerContainer(name, null, parent);
|
|
37
|
+
router.registerContainer(name, null, parent, tag);
|
|
38
38
|
|
|
39
39
|
const spec = translate(config);
|
|
40
40
|
|
|
@@ -51,7 +51,7 @@ export function dock(name, config = {}, base) {
|
|
|
51
51
|
// user-supplied connect/disconnect rather than clobbering them.
|
|
52
52
|
const userMount = spec.mount;
|
|
53
53
|
spec.mount = (ctx) => {
|
|
54
|
-
router.registerContainer(name, ctx.el, parent);
|
|
54
|
+
router.registerContainer(name, ctx.el, parent, tag);
|
|
55
55
|
return userMount?.(ctx);
|
|
56
56
|
};
|
|
57
57
|
const userUnmount = spec.unmount;
|
|
@@ -121,26 +121,22 @@ async function swap(el, options = {}) {
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
// Only use element-scoped view transitions. If the browser doesn't support
|
|
125
|
+
// this.startViewTransition (Chrome < 147), fall back to a direct synchronous
|
|
126
|
+
// swap. Document-level startViewTransition() captures the entire page and
|
|
127
|
+
// causes the sidebar/header to flicker — we never want that.
|
|
124
128
|
if (typeof this.startViewTransition === 'function') {
|
|
125
129
|
try {
|
|
130
|
+
// Assign a named view-transition so CSS can target this element's
|
|
131
|
+
// group explicitly, keeping the root group stable.
|
|
132
|
+
this.style.viewTransitionName = 'dock-swap';
|
|
126
133
|
this._tx = this.startViewTransition(go);
|
|
127
134
|
await this._tx.finished;
|
|
128
135
|
} catch (err) {
|
|
129
136
|
if (err?.name !== 'AbortError') console.warn('[Native UI] dock scoped VT aborted:', err);
|
|
130
137
|
} finally {
|
|
131
138
|
this._tx = null;
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (typeof document !== 'undefined' && typeof document.startViewTransition === 'function') {
|
|
138
|
-
try {
|
|
139
|
-
const vt = document.startViewTransition(go);
|
|
140
|
-
await vt.finished;
|
|
141
|
-
} catch (err) {
|
|
142
|
-
if (err?.name !== 'AbortError') console.warn('[Native UI] dock document VT aborted:', err);
|
|
143
|
-
} finally {
|
|
139
|
+
this.style.viewTransitionName = '';
|
|
144
140
|
restore();
|
|
145
141
|
}
|
|
146
142
|
return;
|
package/src/styles/reset.css
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
* tokens/semantic/transitions.css
|
|
3
3
|
*
|
|
4
4
|
* View Transition pseudo-element mapping and layout swap animations.
|
|
5
|
+
*
|
|
6
|
+
* Docks use element-scoped view transitions via this.startViewTransition().
|
|
7
|
+
* The transitioned element gets viewTransitionName='dock-swap'.
|
|
8
|
+
* Never target (root) — that animates the stable chrome (sidebar, header).
|
|
5
9
|
*/
|
|
6
10
|
|
|
7
11
|
:root {
|
|
@@ -14,10 +18,10 @@
|
|
|
14
18
|
--transition-bg: var(--color-surface-page);
|
|
15
19
|
}
|
|
16
20
|
|
|
17
|
-
::view-transition-old(
|
|
21
|
+
::view-transition-old(dock-swap) {
|
|
18
22
|
animation: 90ms ease-in both fade-out;
|
|
19
23
|
}
|
|
20
|
-
::view-transition-new(
|
|
24
|
+
::view-transition-new(dock-swap) {
|
|
21
25
|
animation: var(--transition-duration) var(--transition-easing) both slide-in;
|
|
22
26
|
}
|
|
23
27
|
|
|
@@ -34,9 +38,8 @@
|
|
|
34
38
|
--transition-duration: 0ms;
|
|
35
39
|
--transition-easing: linear;
|
|
36
40
|
}
|
|
37
|
-
::view-transition-old(
|
|
38
|
-
::view-transition-new(
|
|
41
|
+
::view-transition-old(dock-swap),
|
|
42
|
+
::view-transition-new(dock-swap) {
|
|
39
43
|
animation: none !important;
|
|
40
44
|
}
|
|
41
45
|
}
|
|
42
|
-
|