streetui 1.8.0 → 1.9.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/dist/bin.cjs +1 -1
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/bin.js.map +1 -1
- package/dist/{compile-CJJQYi71.d.cts → compile-DqsMQVJk.d.cts} +120 -4
- package/dist/{compile-CJJQYi71.d.ts → compile-DqsMQVJk.d.ts} +120 -4
- package/dist/create-bin.cjs +1 -1
- package/dist/create-bin.cjs.map +1 -1
- package/dist/create-bin.js +1 -1
- package/dist/create-bin.js.map +1 -1
- package/dist/{hydration-diagnostics-BQeehq3i.d.cts → hydration-diagnostics-4pwt6v7b.d.cts} +1 -1
- package/dist/{hydration-diagnostics-DNAJumYF.d.ts → hydration-diagnostics-B2FmY05M.d.ts} +1 -1
- package/dist/index.cjs +537 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +261 -18
- package/dist/index.d.ts +261 -18
- package/dist/index.js +529 -40
- package/dist/index.js.map +1 -1
- package/dist/{server-DNlg7ou2.d.ts → server-BYnmb_hR.d.ts} +1 -1
- package/dist/{server-CnLEnlYU.d.cts → server-DnwqBTfE.d.cts} +1 -1
- package/dist/server.cjs +266 -30
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +2 -2
- package/dist/server.d.ts +2 -2
- package/dist/server.js +266 -30
- package/dist/server.js.map +1 -1
- package/dist/testing.cjs +387 -36
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +42 -4
- package/dist/testing.d.ts +42 -4
- package/dist/testing.js +379 -35
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -60,6 +60,7 @@ __export(src_exports, {
|
|
|
60
60
|
StreetFrameworkError: () => StreetFrameworkError,
|
|
61
61
|
StreetRenderHandle: () => StreetRenderHandle,
|
|
62
62
|
StreetRendererImpl: () => StreetRendererImpl,
|
|
63
|
+
TransitionController: () => TransitionController,
|
|
63
64
|
VERSION: () => VERSION,
|
|
64
65
|
a11yIds: () => a11yIds,
|
|
65
66
|
applyNodeProps: () => applyNodeProps,
|
|
@@ -74,6 +75,7 @@ __export(src_exports, {
|
|
|
74
75
|
consoleDiagnosticSink: () => consoleDiagnosticSink,
|
|
75
76
|
consoleHydrationDiagnosticSink: () => consoleHydrationDiagnosticSink,
|
|
76
77
|
containFocus: () => containFocus,
|
|
78
|
+
createAnnouncer: () => createAnnouncer,
|
|
77
79
|
createApplication: () => createApplication,
|
|
78
80
|
createBrowserHistory: () => createBrowserHistory,
|
|
79
81
|
createContext: () => createContext,
|
|
@@ -108,6 +110,7 @@ __export(src_exports, {
|
|
|
108
110
|
generateApplicationId: () => generateApplicationId,
|
|
109
111
|
generateNodeId: () => generateNodeId,
|
|
110
112
|
getFocusable: () => getFocusable,
|
|
113
|
+
getResolvedTransition: () => getResolvedTransition,
|
|
111
114
|
globalEventBus: () => globalEventBus,
|
|
112
115
|
headingUpdate: () => headingUpdate,
|
|
113
116
|
hydrateGraph: () => hydrateGraph,
|
|
@@ -118,12 +121,14 @@ __export(src_exports, {
|
|
|
118
121
|
inspectForm: () => inspectForm,
|
|
119
122
|
inspectGraph: () => inspectGraph,
|
|
120
123
|
inspectI18n: () => inspectI18n,
|
|
124
|
+
inspectInteractions: () => inspectInteractions,
|
|
121
125
|
inspectResource: () => inspectResource,
|
|
122
126
|
inspectRouter: () => inspectRouter,
|
|
123
127
|
inspectSignal: () => inspectSignal,
|
|
124
128
|
interpolate: () => interpolate,
|
|
125
129
|
isBatching: () => isBatching,
|
|
126
130
|
isComponentDefinition: () => isComponentDefinition,
|
|
131
|
+
isTransitionConfig: () => isTransitionConfig,
|
|
127
132
|
matchPattern: () => matchPattern,
|
|
128
133
|
matchRoutes: () => matchRoutes,
|
|
129
134
|
maxLength: () => maxLength,
|
|
@@ -152,9 +157,12 @@ __export(src_exports, {
|
|
|
152
157
|
required: () => required,
|
|
153
158
|
resetIdCounter: () => resetIdCounter,
|
|
154
159
|
resolveTag: () => resolveTag,
|
|
160
|
+
resolveTransition: () => resolveTransition,
|
|
155
161
|
resource: () => resource,
|
|
156
162
|
restoreFocus: () => restoreFocus,
|
|
157
163
|
routerOutlet: () => routerOutlet,
|
|
164
|
+
rovingMenu: () => rovingMenu,
|
|
165
|
+
runElementTransition: () => runElementTransition,
|
|
158
166
|
runValidators: () => runValidators,
|
|
159
167
|
saveFocus: () => saveFocus,
|
|
160
168
|
scheduleImmediate: () => scheduleImmediate,
|
|
@@ -182,7 +190,7 @@ __export(src_exports, {
|
|
|
182
190
|
module.exports = __toCommonJS(src_exports);
|
|
183
191
|
|
|
184
192
|
// src/version.ts
|
|
185
|
-
var VERSION = "1.
|
|
193
|
+
var VERSION = "1.9.0";
|
|
186
194
|
|
|
187
195
|
// ../state/src/signal.ts
|
|
188
196
|
var _activeConsumer = null;
|
|
@@ -537,6 +545,9 @@ function a11yIds(base) {
|
|
|
537
545
|
description: `${token}-description`,
|
|
538
546
|
error: `${token}-error`,
|
|
539
547
|
title: `${token}-title`,
|
|
548
|
+
trigger: `${token}-trigger`,
|
|
549
|
+
controls: `${token}-controls`,
|
|
550
|
+
owns: `${token}-owns`,
|
|
540
551
|
id: (suffix) => `${token}-${toIdToken(suffix)}`
|
|
541
552
|
};
|
|
542
553
|
}
|
|
@@ -987,6 +998,7 @@ var ApplicationGraph = class {
|
|
|
987
998
|
this.handlers.delete(`__listplan__${node.id}`);
|
|
988
999
|
this.handlers.delete(`__overlay__${node.id}`);
|
|
989
1000
|
this.handlers.delete(`__component__${node.id}`);
|
|
1001
|
+
this.handlers.delete(`__transition__${node.id}`);
|
|
990
1002
|
}
|
|
991
1003
|
// ── Handler registry ──────────────────────────────────────────────────────
|
|
992
1004
|
registerHandler(key, fn) {
|
|
@@ -1075,6 +1087,47 @@ var ApplicationGraph = class {
|
|
|
1075
1087
|
}
|
|
1076
1088
|
};
|
|
1077
1089
|
|
|
1090
|
+
// ../dsl/src/transition.ts
|
|
1091
|
+
function classes(value) {
|
|
1092
|
+
if (value === void 0) return [];
|
|
1093
|
+
const out = [];
|
|
1094
|
+
for (const token of value.split(/\s+/)) {
|
|
1095
|
+
if (token.length > 0 && !out.includes(token)) out.push(token);
|
|
1096
|
+
}
|
|
1097
|
+
return out;
|
|
1098
|
+
}
|
|
1099
|
+
function merge(a, b) {
|
|
1100
|
+
const out = [...a];
|
|
1101
|
+
for (const token of b) if (!out.includes(token)) out.push(token);
|
|
1102
|
+
return out;
|
|
1103
|
+
}
|
|
1104
|
+
function resolveTransition(config) {
|
|
1105
|
+
const n = config.name;
|
|
1106
|
+
const enterActive = merge(
|
|
1107
|
+
classes(config.enter),
|
|
1108
|
+
classes(config.enterActive ?? (n !== void 0 ? `${n}-enter-active` : void 0))
|
|
1109
|
+
);
|
|
1110
|
+
const leaveActive = merge(
|
|
1111
|
+
classes(config.leave),
|
|
1112
|
+
classes(config.leaveActive ?? (n !== void 0 ? `${n}-leave-active` : void 0))
|
|
1113
|
+
);
|
|
1114
|
+
return {
|
|
1115
|
+
enterActive,
|
|
1116
|
+
enterFrom: classes(config.enterFrom ?? (n !== void 0 ? `${n}-enter-from` : void 0)),
|
|
1117
|
+
enterTo: classes(config.enterTo ?? (n !== void 0 ? `${n}-enter-to` : void 0)),
|
|
1118
|
+
leaveActive,
|
|
1119
|
+
leaveFrom: classes(config.leaveFrom ?? (n !== void 0 ? `${n}-leave-from` : void 0)),
|
|
1120
|
+
leaveTo: classes(config.leaveTo ?? (n !== void 0 ? `${n}-leave-to` : void 0)),
|
|
1121
|
+
appear: config.appear ?? false,
|
|
1122
|
+
duration: config.duration ?? 1e3
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1125
|
+
function isTransitionConfig(value) {
|
|
1126
|
+
if (value === null || typeof value !== "object") return false;
|
|
1127
|
+
const o = value;
|
|
1128
|
+
return typeof o["name"] === "string" || typeof o["enter"] === "string" || typeof o["enterActive"] === "string" || typeof o["enterFrom"] === "string" || typeof o["leave"] === "string" || typeof o["leaveActive"] === "string" || typeof o["leaveFrom"] === "string";
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1078
1131
|
// ../dsl/src/builders.ts
|
|
1079
1132
|
function isSignal(v) {
|
|
1080
1133
|
return v !== null && typeof v === "object" && typeof v["get"] === "function" && typeof v["subscribe"] === "function";
|
|
@@ -1102,6 +1155,18 @@ function applyA11yProps(props, options) {
|
|
|
1102
1155
|
if (options.ariaInvalid !== void 0) props["aria-invalid"] = String(options.ariaInvalid);
|
|
1103
1156
|
if (options.ariaRequired !== void 0) props["aria-required"] = String(options.ariaRequired);
|
|
1104
1157
|
if (options.ariaModal !== void 0) props["aria-modal"] = String(options.ariaModal);
|
|
1158
|
+
if (options.ariaOwns !== void 0) props["aria-owns"] = options.ariaOwns;
|
|
1159
|
+
if (options.ariaActiveDescendant !== void 0) props["aria-activedescendant"] = options.ariaActiveDescendant;
|
|
1160
|
+
if (options.ariaHasPopup !== void 0) props["aria-haspopup"] = String(options.ariaHasPopup);
|
|
1161
|
+
if (options.ariaSelected !== void 0) props["aria-selected"] = String(options.ariaSelected);
|
|
1162
|
+
}
|
|
1163
|
+
function registerTransition(graph, node, config) {
|
|
1164
|
+
if (config === void 0) return;
|
|
1165
|
+
const resolved = resolveTransition(config);
|
|
1166
|
+
graph.registerHandler(
|
|
1167
|
+
`__transition__${node.id}`,
|
|
1168
|
+
() => resolved
|
|
1169
|
+
);
|
|
1105
1170
|
}
|
|
1106
1171
|
function containerProps(options) {
|
|
1107
1172
|
const props = {};
|
|
@@ -1162,6 +1227,7 @@ var OVERLAY_KINDS = {
|
|
|
1162
1227
|
role: "menu",
|
|
1163
1228
|
modal: false,
|
|
1164
1229
|
takesFocus: true,
|
|
1230
|
+
menu: true,
|
|
1165
1231
|
ariaModal: false,
|
|
1166
1232
|
defaultCloseOnEscape: true,
|
|
1167
1233
|
defaultRestoreFocus: true
|
|
@@ -1294,6 +1360,7 @@ var ContainerBuilderBase = class extends ContentBuilderBase {
|
|
|
1294
1360
|
parent: this._node,
|
|
1295
1361
|
props: containerProps(options)
|
|
1296
1362
|
});
|
|
1363
|
+
registerTransition(this._graph, node, options.transition);
|
|
1297
1364
|
builder(new SectionBuilderImpl(node, this._graph));
|
|
1298
1365
|
}
|
|
1299
1366
|
container(key, builder, options = {}) {
|
|
@@ -1302,6 +1369,7 @@ var ContainerBuilderBase = class extends ContentBuilderBase {
|
|
|
1302
1369
|
parent: this._node,
|
|
1303
1370
|
props: containerProps(options)
|
|
1304
1371
|
});
|
|
1372
|
+
registerTransition(this._graph, node, options.transition);
|
|
1305
1373
|
builder(new ContainerBuilderImpl(node, this._graph));
|
|
1306
1374
|
}
|
|
1307
1375
|
list(key, builder, options = {}) {
|
|
@@ -1310,6 +1378,7 @@ var ContainerBuilderBase = class extends ContentBuilderBase {
|
|
|
1310
1378
|
parent: this._node,
|
|
1311
1379
|
props: containerProps(options)
|
|
1312
1380
|
});
|
|
1381
|
+
registerTransition(this._graph, node, options.transition);
|
|
1313
1382
|
builder(new ListBuilderImpl(node, this._graph));
|
|
1314
1383
|
}
|
|
1315
1384
|
listOf(key, items, renderItem, options = {}) {
|
|
@@ -1319,6 +1388,7 @@ var ContainerBuilderBase = class extends ContentBuilderBase {
|
|
|
1319
1388
|
parent: this._node,
|
|
1320
1389
|
props: containerProps(options)
|
|
1321
1390
|
});
|
|
1391
|
+
registerTransition(graph, node, options.transition);
|
|
1322
1392
|
const signalId = `${node.id}:items`;
|
|
1323
1393
|
node.stateRefs.push({ signalId, propKey: "items" });
|
|
1324
1394
|
graph.registerHandler(`__signal__${signalId}`, items);
|
|
@@ -1340,6 +1410,7 @@ var ContainerBuilderBase = class extends ContentBuilderBase {
|
|
|
1340
1410
|
}
|
|
1341
1411
|
});
|
|
1342
1412
|
renderItem(item, index, new ContainerBuilderImpl(itemNode, graph));
|
|
1413
|
+
registerTransition(graph, itemNode, options.itemTransition);
|
|
1343
1414
|
return itemNode;
|
|
1344
1415
|
};
|
|
1345
1416
|
const buildPlan = (raw) => {
|
|
@@ -1371,6 +1442,7 @@ var ContainerBuilderBase = class extends ContentBuilderBase {
|
|
|
1371
1442
|
parent: this._node,
|
|
1372
1443
|
props
|
|
1373
1444
|
});
|
|
1445
|
+
registerTransition(this._graph, node, options.transition);
|
|
1374
1446
|
if (options.onSubmit !== void 0) {
|
|
1375
1447
|
const handlerKey = `submit:${node.id}`;
|
|
1376
1448
|
this._graph.registerHandler(handlerKey, options.onSubmit);
|
|
@@ -1378,18 +1450,20 @@ var ContainerBuilderBase = class extends ContentBuilderBase {
|
|
|
1378
1450
|
}
|
|
1379
1451
|
builder(new FormBuilderImpl(node, this._graph));
|
|
1380
1452
|
}
|
|
1381
|
-
when(condition, builder, elseBuilder) {
|
|
1453
|
+
when(condition, builder, elseBuilder, options = {}) {
|
|
1382
1454
|
const graph = this._graph;
|
|
1383
1455
|
const node = graph.createNode("conditional", {
|
|
1384
1456
|
parent: this._node,
|
|
1385
1457
|
props: containerProps({})
|
|
1386
1458
|
});
|
|
1459
|
+
const branchTransition = options.transition !== void 0 && options.appear === true ? { ...options.transition, appear: true } : options.transition;
|
|
1387
1460
|
const buildBranch = (build, tag) => {
|
|
1388
1461
|
const branchKey = `when-${tag}:${node.id}`;
|
|
1389
1462
|
const branch = graph.createNode("container", {
|
|
1390
1463
|
key: branchKey,
|
|
1391
1464
|
props: { key: branchKey }
|
|
1392
1465
|
});
|
|
1466
|
+
registerTransition(graph, branch, branchTransition);
|
|
1393
1467
|
build(new ContainerBuilderImpl(branch, graph));
|
|
1394
1468
|
return branch;
|
|
1395
1469
|
};
|
|
@@ -1484,13 +1558,24 @@ var ContainerBuilderBase = class extends ContentBuilderBase {
|
|
|
1484
1558
|
...options.ariaDescribedBy !== void 0 ? { ariaDescribedBy: options.ariaDescribedBy } : {}
|
|
1485
1559
|
};
|
|
1486
1560
|
const portalBuilder = new ContainerBuilderImpl(portalNode, graph);
|
|
1487
|
-
portalBuilder.when(
|
|
1488
|
-
|
|
1489
|
-
|
|
1561
|
+
portalBuilder.when(
|
|
1562
|
+
openSignal,
|
|
1563
|
+
(panelHost) => {
|
|
1564
|
+
panelHost.container(`${key}__panel`, builder, panelOptions);
|
|
1565
|
+
},
|
|
1566
|
+
void 0,
|
|
1567
|
+
// Overlay open/close rides the panel's `when`; a transition animates the
|
|
1568
|
+
// panel in on open and — via the reconciler's deferred-leave — plays the
|
|
1569
|
+
// leave before the panel is removed (§10). Focus is restored at close-
|
|
1570
|
+
// request time (see wireOverlayBehavior), so it never stays trapped inside
|
|
1571
|
+
// a panel that is animating away.
|
|
1572
|
+
options.transition !== void 0 ? { transition: options.transition } : {}
|
|
1573
|
+
);
|
|
1490
1574
|
const descriptor = {
|
|
1491
1575
|
open: openSignal,
|
|
1492
1576
|
modal: kind.modal,
|
|
1493
1577
|
takesFocus: kind.takesFocus,
|
|
1578
|
+
menu: kind.menu ?? false,
|
|
1494
1579
|
closeOnEscape: options.closeOnEscape ?? kind.defaultCloseOnEscape,
|
|
1495
1580
|
restoreFocus: options.restoreFocus ?? kind.defaultRestoreFocus,
|
|
1496
1581
|
...options.initialFocusId !== void 0 ? { initialFocusId: options.initialFocusId } : {},
|
|
@@ -1587,6 +1672,7 @@ var ListBuilderImpl = class extends ContentBuilderBase {
|
|
|
1587
1672
|
parent: this._node,
|
|
1588
1673
|
props: containerProps(options)
|
|
1589
1674
|
});
|
|
1675
|
+
registerTransition(this._graph, node, options.transition);
|
|
1590
1676
|
builder(new ContainerBuilderImpl(node, this._graph));
|
|
1591
1677
|
}
|
|
1592
1678
|
};
|
|
@@ -2681,18 +2767,25 @@ function trapFocus(dom, container) {
|
|
|
2681
2767
|
dom.addEventListener(container, "keydown", onKeydown);
|
|
2682
2768
|
return () => dom.removeEventListener(container, "keydown", onKeydown);
|
|
2683
2769
|
}
|
|
2770
|
+
var containmentStack = [];
|
|
2684
2771
|
function containFocus(dom, container) {
|
|
2685
2772
|
const body = dom.body();
|
|
2686
2773
|
if (body === null) return () => {
|
|
2687
2774
|
};
|
|
2775
|
+
containmentStack.push(container);
|
|
2688
2776
|
const onFocusIn = (event) => {
|
|
2777
|
+
if (containmentStack[containmentStack.length - 1] !== container) return;
|
|
2689
2778
|
const target = event.target;
|
|
2690
2779
|
if (target !== null && !dom.contains(container, target)) {
|
|
2691
2780
|
focusFirst(dom, container);
|
|
2692
2781
|
}
|
|
2693
2782
|
};
|
|
2694
2783
|
dom.addEventListener(body, "focusin", onFocusIn);
|
|
2695
|
-
return () =>
|
|
2784
|
+
return () => {
|
|
2785
|
+
dom.removeEventListener(body, "focusin", onFocusIn);
|
|
2786
|
+
const index = containmentStack.lastIndexOf(container);
|
|
2787
|
+
if (index !== -1) containmentStack.splice(index, 1);
|
|
2788
|
+
};
|
|
2696
2789
|
}
|
|
2697
2790
|
function onEscape(dom, target, handler) {
|
|
2698
2791
|
const onKeydown = (event) => {
|
|
@@ -2701,6 +2794,84 @@ function onEscape(dom, target, handler) {
|
|
|
2701
2794
|
dom.addEventListener(target, "keydown", onKeydown);
|
|
2702
2795
|
return () => dom.removeEventListener(target, "keydown", onKeydown);
|
|
2703
2796
|
}
|
|
2797
|
+
function rovingMenu(dom, container, selector = FOCUSABLE_SELECTOR) {
|
|
2798
|
+
const onKeydown = (event) => {
|
|
2799
|
+
const key = event.key;
|
|
2800
|
+
const isActivate = key === "Enter" || key === " " || key === "Spacebar";
|
|
2801
|
+
const isMove = key === "ArrowDown" || key === "ArrowUp" || key === "Home" || key === "End";
|
|
2802
|
+
if (!isActivate && !isMove) return;
|
|
2803
|
+
const items = getFocusable(dom, container, selector);
|
|
2804
|
+
if (items.length === 0) return;
|
|
2805
|
+
const active = dom.activeElement();
|
|
2806
|
+
const index = active === null ? -1 : items.indexOf(active);
|
|
2807
|
+
if (isActivate) {
|
|
2808
|
+
if (index < 0) return;
|
|
2809
|
+
event.preventDefault();
|
|
2810
|
+
items[index].click?.();
|
|
2811
|
+
return;
|
|
2812
|
+
}
|
|
2813
|
+
event.preventDefault();
|
|
2814
|
+
let next;
|
|
2815
|
+
if (key === "Home") next = 0;
|
|
2816
|
+
else if (key === "End") next = items.length - 1;
|
|
2817
|
+
else if (key === "ArrowDown") next = index < 0 ? 0 : (index + 1) % items.length;
|
|
2818
|
+
else next = index <= 0 ? items.length - 1 : index - 1;
|
|
2819
|
+
dom.focus(items[next]);
|
|
2820
|
+
};
|
|
2821
|
+
dom.addEventListener(container, "keydown", onKeydown);
|
|
2822
|
+
return () => dom.removeEventListener(container, "keydown", onKeydown);
|
|
2823
|
+
}
|
|
2824
|
+
|
|
2825
|
+
// ../dom/src/live-region.ts
|
|
2826
|
+
var VISUALLY_HIDDEN = "position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;";
|
|
2827
|
+
function makeRegion(dom, politeness) {
|
|
2828
|
+
const el = dom.createElement("div");
|
|
2829
|
+
dom.setAttribute(el, "aria-live", politeness);
|
|
2830
|
+
dom.setAttribute(el, "aria-atomic", "true");
|
|
2831
|
+
dom.setAttribute(el, "role", politeness === "assertive" ? "alert" : "status");
|
|
2832
|
+
dom.setAttribute(el, "data-streetui-live", politeness);
|
|
2833
|
+
dom.setAttribute(el, "style", VISUALLY_HIDDEN);
|
|
2834
|
+
return el;
|
|
2835
|
+
}
|
|
2836
|
+
function createAnnouncer(dom) {
|
|
2837
|
+
const body = dom.body();
|
|
2838
|
+
if (body === null) {
|
|
2839
|
+
return { announce() {
|
|
2840
|
+
}, clear() {
|
|
2841
|
+
}, destroy() {
|
|
2842
|
+
} };
|
|
2843
|
+
}
|
|
2844
|
+
const polite = makeRegion(dom, "polite");
|
|
2845
|
+
const assertive = makeRegion(dom, "assertive");
|
|
2846
|
+
dom.appendChild(body, polite);
|
|
2847
|
+
dom.appendChild(body, assertive);
|
|
2848
|
+
let destroyed = false;
|
|
2849
|
+
const write = (region, message) => {
|
|
2850
|
+
dom.setTextContent(region, "");
|
|
2851
|
+
void Promise.resolve().then(() => {
|
|
2852
|
+
if (!destroyed) dom.setTextContent(region, message);
|
|
2853
|
+
});
|
|
2854
|
+
};
|
|
2855
|
+
return {
|
|
2856
|
+
announce(message, options) {
|
|
2857
|
+
if (destroyed) return;
|
|
2858
|
+
write(options?.assertive === true ? assertive : polite, message);
|
|
2859
|
+
},
|
|
2860
|
+
clear() {
|
|
2861
|
+
if (destroyed) return;
|
|
2862
|
+
dom.setTextContent(polite, "");
|
|
2863
|
+
dom.setTextContent(assertive, "");
|
|
2864
|
+
},
|
|
2865
|
+
destroy() {
|
|
2866
|
+
if (destroyed) return;
|
|
2867
|
+
destroyed = true;
|
|
2868
|
+
for (const region of [polite, assertive]) {
|
|
2869
|
+
const parent = dom.parentNode(region);
|
|
2870
|
+
if (parent !== null) dom.removeChild(parent, region);
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
};
|
|
2874
|
+
}
|
|
2704
2875
|
|
|
2705
2876
|
// ../renderer/src/render-context.ts
|
|
2706
2877
|
function createRenderContext(dom, graph, container, hydrationDiagnostics, staticHTML) {
|
|
@@ -2912,7 +3083,7 @@ function patchNode(ctx, graphNode, propKey, newValue) {
|
|
|
2912
3083
|
}
|
|
2913
3084
|
|
|
2914
3085
|
// ../renderer/src/reconciliation.ts
|
|
2915
|
-
function reconcileChildren(ctx, parentDom, oldInstances, newNodes, mountFn) {
|
|
3086
|
+
function reconcileChildren(ctx, parentDom, oldInstances, newNodes, mountFn, hooks) {
|
|
2916
3087
|
const oldByKey = /* @__PURE__ */ new Map();
|
|
2917
3088
|
for (const inst of oldInstances) {
|
|
2918
3089
|
const key = inst.graphNode.key ?? inst.graphNode.id;
|
|
@@ -2933,28 +3104,33 @@ function reconcileChildren(ctx, parentDom, oldInstances, newNodes, mountFn) {
|
|
|
2933
3104
|
}
|
|
2934
3105
|
newInstances.push(existing);
|
|
2935
3106
|
} else {
|
|
2936
|
-
const
|
|
2937
|
-
|
|
3107
|
+
const reclaimed = hooks?.takeLeaving(key);
|
|
3108
|
+
if (reclaimed !== void 0) {
|
|
3109
|
+
patchExistingInstance(ctx, reclaimed, newNode);
|
|
3110
|
+
reconcileItemChildren(ctx, reclaimed, newNode, mountFn);
|
|
3111
|
+
hooks?.onEnter(reclaimed);
|
|
3112
|
+
newInstances.push(reclaimed);
|
|
3113
|
+
} else {
|
|
3114
|
+
const inst = mountFn(newNode, parentDom);
|
|
3115
|
+
hooks?.onEnter(inst);
|
|
3116
|
+
newInstances.push(inst);
|
|
3117
|
+
}
|
|
2938
3118
|
}
|
|
2939
3119
|
}
|
|
2940
3120
|
const removed = [];
|
|
2941
3121
|
for (const inst of oldInstances) {
|
|
2942
3122
|
const key = inst.graphNode.key ?? inst.graphNode.id;
|
|
2943
|
-
if (
|
|
2944
|
-
|
|
2945
|
-
}
|
|
2946
|
-
}
|
|
2947
|
-
for (const inst of removed) {
|
|
3123
|
+
if (usedKeys.has(key)) continue;
|
|
3124
|
+
if (hooks !== void 0 && hooks.beginLeave(inst)) continue;
|
|
2948
3125
|
const parent = ctx.dom.parentNode(inst.domNode);
|
|
2949
|
-
if (parent !== null)
|
|
2950
|
-
ctx.dom.removeChild(parent, inst.domNode);
|
|
2951
|
-
}
|
|
3126
|
+
if (parent !== null) ctx.dom.removeChild(parent, inst.domNode);
|
|
2952
3127
|
inst.dispose();
|
|
3128
|
+
removed.push(inst);
|
|
2953
3129
|
}
|
|
2954
3130
|
reorderDom(ctx, parentDom, newInstances);
|
|
2955
3131
|
return { instances: newInstances, removed };
|
|
2956
3132
|
}
|
|
2957
|
-
function reconcileChildrenByPlan(ctx, parentDom, oldInstances, plan, mountFn) {
|
|
3133
|
+
function reconcileChildrenByPlan(ctx, parentDom, oldInstances, plan, mountFn, hooks) {
|
|
2958
3134
|
const oldByKey = /* @__PURE__ */ new Map();
|
|
2959
3135
|
for (const inst of oldInstances) {
|
|
2960
3136
|
oldByKey.set(inst.graphNode.key ?? inst.graphNode.id, inst);
|
|
@@ -2981,21 +3157,34 @@ function reconcileChildrenByPlan(ctx, parentDom, oldInstances, plan, mountFn) {
|
|
|
2981
3157
|
}
|
|
2982
3158
|
newInstances.push(existing);
|
|
2983
3159
|
} else {
|
|
2984
|
-
const
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
3160
|
+
const reclaimed = hooks?.takeLeaving(entry.key);
|
|
3161
|
+
if (reclaimed !== void 0) {
|
|
3162
|
+
const freshNode = entry.build();
|
|
3163
|
+
built.push(freshNode);
|
|
3164
|
+
patchExistingInstance(ctx, reclaimed, freshNode);
|
|
3165
|
+
reconcileItemChildren(ctx, reclaimed, freshNode, mountFn);
|
|
3166
|
+
reclaimed.graphNode.setProp("_sig", freshNode.getProp("_sig"));
|
|
3167
|
+
reclaimed.graphNode.setProp("_item", entry.item);
|
|
3168
|
+
hooks?.onEnter(reclaimed);
|
|
3169
|
+
newInstances.push(reclaimed);
|
|
3170
|
+
} else {
|
|
3171
|
+
const freshNode = entry.build();
|
|
3172
|
+
built.push(freshNode);
|
|
3173
|
+
const inst = mountFn(freshNode, parentDom);
|
|
3174
|
+
hooks?.onEnter(inst);
|
|
3175
|
+
newInstances.push(inst);
|
|
3176
|
+
}
|
|
2988
3177
|
}
|
|
2989
3178
|
}
|
|
2990
3179
|
const removed = [];
|
|
2991
3180
|
for (const inst of oldInstances) {
|
|
2992
3181
|
const key = inst.graphNode.key ?? inst.graphNode.id;
|
|
2993
|
-
if (
|
|
2994
|
-
|
|
2995
|
-
for (const inst of removed) {
|
|
3182
|
+
if (usedKeys.has(key)) continue;
|
|
3183
|
+
if (hooks !== void 0 && hooks.beginLeave(inst)) continue;
|
|
2996
3184
|
const parent = ctx.dom.parentNode(inst.domNode);
|
|
2997
3185
|
if (parent !== null) ctx.dom.removeChild(parent, inst.domNode);
|
|
2998
3186
|
inst.dispose();
|
|
3187
|
+
removed.push(inst);
|
|
2999
3188
|
}
|
|
3000
3189
|
reorderDomMinimal(ctx, parentDom, oldInstances, newInstances);
|
|
3001
3190
|
return { instances: newInstances, removed, built };
|
|
@@ -3121,6 +3310,187 @@ function patchExistingInstance(ctx, instance, newNode) {
|
|
|
3121
3310
|
}
|
|
3122
3311
|
}
|
|
3123
3312
|
|
|
3313
|
+
// ../renderer/src/transition.ts
|
|
3314
|
+
function getResolvedTransition(graph, nodeId) {
|
|
3315
|
+
const fn = graph.getHandler(`__transition__${nodeId}`);
|
|
3316
|
+
return fn === void 0 ? void 0 : fn();
|
|
3317
|
+
}
|
|
3318
|
+
function host() {
|
|
3319
|
+
return globalThis;
|
|
3320
|
+
}
|
|
3321
|
+
function nextFrame(cb) {
|
|
3322
|
+
const h = host();
|
|
3323
|
+
const raf = h.requestAnimationFrame;
|
|
3324
|
+
if (typeof raf === "function") {
|
|
3325
|
+
raf(() => raf(cb));
|
|
3326
|
+
} else {
|
|
3327
|
+
h.setTimeout(cb, 0);
|
|
3328
|
+
}
|
|
3329
|
+
}
|
|
3330
|
+
function splitClass(value) {
|
|
3331
|
+
if (value === null) return [];
|
|
3332
|
+
const out = [];
|
|
3333
|
+
for (const t of value.split(/\s+/)) if (t.length > 0) out.push(t);
|
|
3334
|
+
return out;
|
|
3335
|
+
}
|
|
3336
|
+
function addClasses(dom, el, classes2) {
|
|
3337
|
+
if (classes2.length === 0) return;
|
|
3338
|
+
const current = splitClass(dom.getAttribute(el, "class"));
|
|
3339
|
+
let changed = false;
|
|
3340
|
+
for (const c of classes2) {
|
|
3341
|
+
if (!current.includes(c)) {
|
|
3342
|
+
current.push(c);
|
|
3343
|
+
changed = true;
|
|
3344
|
+
}
|
|
3345
|
+
}
|
|
3346
|
+
if (changed) dom.setAttribute(el, "class", current.join(" "));
|
|
3347
|
+
}
|
|
3348
|
+
function removeClasses(dom, el, classes2) {
|
|
3349
|
+
if (classes2.length === 0) return;
|
|
3350
|
+
const current = splitClass(dom.getAttribute(el, "class"));
|
|
3351
|
+
const next = current.filter((c) => !classes2.includes(c));
|
|
3352
|
+
if (next.length !== current.length) {
|
|
3353
|
+
if (next.length === 0) dom.removeAttribute(el, "class");
|
|
3354
|
+
else dom.setAttribute(el, "class", next.join(" "));
|
|
3355
|
+
}
|
|
3356
|
+
}
|
|
3357
|
+
function startRun(dom, el, active, from, to, duration, onDone) {
|
|
3358
|
+
const h = host();
|
|
3359
|
+
let finished = false;
|
|
3360
|
+
let timer = null;
|
|
3361
|
+
const onEvent = (e) => {
|
|
3362
|
+
if (e.target !== el) return;
|
|
3363
|
+
finish();
|
|
3364
|
+
};
|
|
3365
|
+
const detach = () => {
|
|
3366
|
+
dom.removeEventListener(el, "transitionend", onEvent);
|
|
3367
|
+
dom.removeEventListener(el, "animationend", onEvent);
|
|
3368
|
+
if (timer !== null) {
|
|
3369
|
+
h.clearTimeout(timer);
|
|
3370
|
+
timer = null;
|
|
3371
|
+
}
|
|
3372
|
+
};
|
|
3373
|
+
const finish = () => {
|
|
3374
|
+
if (finished) return;
|
|
3375
|
+
finished = true;
|
|
3376
|
+
detach();
|
|
3377
|
+
removeClasses(dom, el, active);
|
|
3378
|
+
removeClasses(dom, el, to);
|
|
3379
|
+
removeClasses(dom, el, from);
|
|
3380
|
+
onDone();
|
|
3381
|
+
};
|
|
3382
|
+
addClasses(dom, el, from);
|
|
3383
|
+
addClasses(dom, el, active);
|
|
3384
|
+
dom.addEventListener(el, "transitionend", onEvent);
|
|
3385
|
+
dom.addEventListener(el, "animationend", onEvent);
|
|
3386
|
+
timer = h.setTimeout(finish, duration);
|
|
3387
|
+
nextFrame(() => {
|
|
3388
|
+
if (finished) return;
|
|
3389
|
+
removeClasses(dom, el, from);
|
|
3390
|
+
addClasses(dom, el, to);
|
|
3391
|
+
});
|
|
3392
|
+
return {
|
|
3393
|
+
cancel: () => {
|
|
3394
|
+
if (finished) return;
|
|
3395
|
+
finished = true;
|
|
3396
|
+
detach();
|
|
3397
|
+
removeClasses(dom, el, active);
|
|
3398
|
+
removeClasses(dom, el, to);
|
|
3399
|
+
removeClasses(dom, el, from);
|
|
3400
|
+
}
|
|
3401
|
+
};
|
|
3402
|
+
}
|
|
3403
|
+
function runElementTransition(dom, el, rt, phase, onDone) {
|
|
3404
|
+
if (dom.body() === null || !dom.isElement(el)) {
|
|
3405
|
+
onDone();
|
|
3406
|
+
return { cancel: () => {
|
|
3407
|
+
} };
|
|
3408
|
+
}
|
|
3409
|
+
const active = phase === "enter" ? rt.enterActive : rt.leaveActive;
|
|
3410
|
+
const from = phase === "enter" ? rt.enterFrom : rt.leaveFrom;
|
|
3411
|
+
const to = phase === "enter" ? rt.enterTo : rt.leaveTo;
|
|
3412
|
+
return startRun(dom, el, active, from, to, rt.duration, onDone);
|
|
3413
|
+
}
|
|
3414
|
+
var TransitionController = class {
|
|
3415
|
+
constructor(dom, graph, finalize) {
|
|
3416
|
+
this.dom = dom;
|
|
3417
|
+
this.graph = graph;
|
|
3418
|
+
this.finalize = finalize;
|
|
3419
|
+
}
|
|
3420
|
+
leaving = /* @__PURE__ */ new Map();
|
|
3421
|
+
/** True only in a real DOM environment (browser). */
|
|
3422
|
+
get browser() {
|
|
3423
|
+
return this.dom.body() !== null;
|
|
3424
|
+
}
|
|
3425
|
+
keyOf(inst) {
|
|
3426
|
+
return inst.graphNode.key ?? inst.graphNode.id;
|
|
3427
|
+
}
|
|
3428
|
+
resolved(node) {
|
|
3429
|
+
return getResolvedTransition(this.graph, node.id);
|
|
3430
|
+
}
|
|
3431
|
+
/** Run the enter animation for `inst` if it carries a transition (browser only). */
|
|
3432
|
+
enter(inst) {
|
|
3433
|
+
if (!this.browser) return;
|
|
3434
|
+
const rt = this.resolved(inst.graphNode);
|
|
3435
|
+
if (rt === void 0) return;
|
|
3436
|
+
const el = inst.domNode;
|
|
3437
|
+
if (!this.dom.isElement(el)) return;
|
|
3438
|
+
startRun(this.dom, el, rt.enterActive, rt.enterFrom, rt.enterTo, rt.duration, () => {
|
|
3439
|
+
});
|
|
3440
|
+
}
|
|
3441
|
+
/**
|
|
3442
|
+
* Play `appear` for any initial child that opted into it (fresh browser mount
|
|
3443
|
+
* only — hydration must never animate appear, §22, and this is called only on
|
|
3444
|
+
* the mount path).
|
|
3445
|
+
*/
|
|
3446
|
+
appear(children) {
|
|
3447
|
+
if (!this.browser) return;
|
|
3448
|
+
for (const child of children) {
|
|
3449
|
+
const rt = this.resolved(child.graphNode);
|
|
3450
|
+
if (rt !== void 0 && rt.appear) this.enter(child);
|
|
3451
|
+
}
|
|
3452
|
+
}
|
|
3453
|
+
hooks() {
|
|
3454
|
+
return {
|
|
3455
|
+
takeLeaving: (key) => {
|
|
3456
|
+
const entry = this.leaving.get(key);
|
|
3457
|
+
if (entry === void 0) return void 0;
|
|
3458
|
+
entry.run.cancel();
|
|
3459
|
+
this.leaving.delete(key);
|
|
3460
|
+
return entry.inst;
|
|
3461
|
+
},
|
|
3462
|
+
beginLeave: (inst) => {
|
|
3463
|
+
if (!this.browser) return false;
|
|
3464
|
+
const rt = this.resolved(inst.graphNode);
|
|
3465
|
+
if (rt === void 0) return false;
|
|
3466
|
+
const el = inst.domNode;
|
|
3467
|
+
if (!this.dom.isElement(el)) return false;
|
|
3468
|
+
const key = this.keyOf(inst);
|
|
3469
|
+
const prior = this.leaving.get(key);
|
|
3470
|
+
if (prior !== void 0) prior.run.cancel();
|
|
3471
|
+
const run = startRun(
|
|
3472
|
+
this.dom,
|
|
3473
|
+
el,
|
|
3474
|
+
rt.leaveActive,
|
|
3475
|
+
rt.leaveFrom,
|
|
3476
|
+
rt.leaveTo,
|
|
3477
|
+
rt.duration,
|
|
3478
|
+
() => {
|
|
3479
|
+
const current = this.leaving.get(key);
|
|
3480
|
+
if (current !== void 0 && current.run === run) {
|
|
3481
|
+
this.leaving.delete(key);
|
|
3482
|
+
this.finalize(inst);
|
|
3483
|
+
}
|
|
3484
|
+
}
|
|
3485
|
+
);
|
|
3486
|
+
this.leaving.set(key, { inst, run });
|
|
3487
|
+
return true;
|
|
3488
|
+
},
|
|
3489
|
+
onEnter: (inst) => this.enter(inst)
|
|
3490
|
+
};
|
|
3491
|
+
}
|
|
3492
|
+
};
|
|
3493
|
+
|
|
3124
3494
|
// ../renderer/src/mount.ts
|
|
3125
3495
|
var SKIP_PROP_KEYS = /* @__PURE__ */ new Set([
|
|
3126
3496
|
"text",
|
|
@@ -3273,7 +3643,7 @@ function mountNode(ctx, graphNode, parentDom) {
|
|
|
3273
3643
|
instance2.addChild(childInstance);
|
|
3274
3644
|
}
|
|
3275
3645
|
dom.appendChild(parentDom, el2);
|
|
3276
|
-
wireReactiveList(ctx, graphNode, instance2, el2);
|
|
3646
|
+
wireReactiveList(ctx, graphNode, instance2, el2, true);
|
|
3277
3647
|
return instance2;
|
|
3278
3648
|
}
|
|
3279
3649
|
if (graphNode.type === "portal") {
|
|
@@ -3382,32 +3752,42 @@ function wireSignalBindings(ctx, graphNode, instance, onUpdate) {
|
|
|
3382
3752
|
instance.trackCleanup(unsub);
|
|
3383
3753
|
}
|
|
3384
3754
|
}
|
|
3385
|
-
function wireReactiveList(ctx, graphNode, instance, el) {
|
|
3755
|
+
function wireReactiveList(ctx, graphNode, instance, el, runAppear = false) {
|
|
3386
3756
|
const plan = ctx.graph.getHandler(`__listplan__${graphNode.id}`);
|
|
3387
3757
|
const build = ctx.graph.getHandler(`__listbuild__${graphNode.id}`);
|
|
3388
3758
|
if (plan === void 0 && build === void 0) return;
|
|
3759
|
+
const controller = new TransitionController(ctx.dom, ctx.graph, (leaving) => {
|
|
3760
|
+
const parent = ctx.dom.parentNode(leaving.domNode);
|
|
3761
|
+
if (parent !== null) ctx.dom.removeChild(parent, leaving.domNode);
|
|
3762
|
+
leaving.dispose();
|
|
3763
|
+
forgetInstance(ctx, leaving);
|
|
3764
|
+
ctx.graph.detachNode(leaving.graphNode);
|
|
3765
|
+
});
|
|
3766
|
+
const hooks = controller.hooks();
|
|
3767
|
+
if (runAppear) controller.appear(instance.children);
|
|
3389
3768
|
for (const stateRef of graphNode.stateRefs) {
|
|
3390
3769
|
if (stateRef.propKey !== "items") continue;
|
|
3391
3770
|
const sig = ctx.graph.getHandler(`__signal__${stateRef.signalId}`);
|
|
3392
3771
|
if (sig === void 0 || typeof sig.subscribe !== "function") continue;
|
|
3393
3772
|
const unsub = sig.subscribe((value) => {
|
|
3394
3773
|
if (plan !== void 0) {
|
|
3395
|
-
reconcileReactiveListByPlan(ctx, graphNode, instance, el, plan(value));
|
|
3774
|
+
reconcileReactiveListByPlan(ctx, graphNode, instance, el, plan(value), hooks);
|
|
3396
3775
|
} else {
|
|
3397
|
-
reconcileReactiveList(ctx, graphNode, instance, el, build(value));
|
|
3776
|
+
reconcileReactiveList(ctx, graphNode, instance, el, build(value), hooks);
|
|
3398
3777
|
}
|
|
3399
3778
|
});
|
|
3400
3779
|
instance.trackCleanup(unsub);
|
|
3401
3780
|
}
|
|
3402
3781
|
}
|
|
3403
|
-
function reconcileReactiveListByPlan(ctx, listNode, listInstance, listEl, plan) {
|
|
3782
|
+
function reconcileReactiveListByPlan(ctx, listNode, listInstance, listEl, plan, hooks) {
|
|
3404
3783
|
const oldInstances = [...listInstance.children];
|
|
3405
3784
|
const result = reconcileChildrenByPlan(
|
|
3406
3785
|
ctx,
|
|
3407
3786
|
listEl,
|
|
3408
3787
|
oldInstances,
|
|
3409
3788
|
plan,
|
|
3410
|
-
(node, parent) => mountNode(ctx, node, parent)
|
|
3789
|
+
(node, parent) => mountNode(ctx, node, parent),
|
|
3790
|
+
hooks
|
|
3411
3791
|
);
|
|
3412
3792
|
listInstance.children.length = 0;
|
|
3413
3793
|
for (const inst of result.instances) listInstance.children.push(inst);
|
|
@@ -3422,14 +3802,15 @@ function reconcileReactiveListByPlan(ctx, listNode, listInstance, listEl, plan)
|
|
|
3422
3802
|
for (const child of [...listNode.children]) listNode.removeChild(child);
|
|
3423
3803
|
for (const inst of result.instances) listNode.appendChild(inst.graphNode);
|
|
3424
3804
|
}
|
|
3425
|
-
function reconcileReactiveList(ctx, listNode, listInstance, listEl, newNodes) {
|
|
3805
|
+
function reconcileReactiveList(ctx, listNode, listInstance, listEl, newNodes, hooks) {
|
|
3426
3806
|
const oldInstances = [...listInstance.children];
|
|
3427
3807
|
const result = reconcileChildren(
|
|
3428
3808
|
ctx,
|
|
3429
3809
|
listEl,
|
|
3430
3810
|
oldInstances,
|
|
3431
3811
|
newNodes,
|
|
3432
|
-
(node, parent) => mountNode(ctx, node, parent)
|
|
3812
|
+
(node, parent) => mountNode(ctx, node, parent),
|
|
3813
|
+
hooks
|
|
3433
3814
|
);
|
|
3434
3815
|
listInstance.children.length = 0;
|
|
3435
3816
|
for (const inst of result.instances) listInstance.children.push(inst);
|
|
@@ -3465,11 +3846,14 @@ function wireOverlayBehavior(ctx, graphNode, instance, target) {
|
|
|
3465
3846
|
const onOpenChange = (isOpen) => {
|
|
3466
3847
|
if (isOpen) {
|
|
3467
3848
|
if (desc.restoreFocus) saved = saveFocus(dom);
|
|
3468
|
-
if (desc.takesFocus) focusInitial(dom, target, desc.initialFocusId);
|
|
3469
3849
|
if (desc.modal) {
|
|
3470
3850
|
active.push(trapFocus(dom, target));
|
|
3471
3851
|
active.push(containFocus(dom, target));
|
|
3472
3852
|
}
|
|
3853
|
+
if (desc.menu) {
|
|
3854
|
+
active.push(rovingMenu(dom, target));
|
|
3855
|
+
}
|
|
3856
|
+
if (desc.takesFocus) focusInitial(dom, target, desc.initialFocusId);
|
|
3473
3857
|
if (desc.closeOnEscape && desc.onClose !== void 0) {
|
|
3474
3858
|
active.push(onEscape(dom, target, desc.onClose));
|
|
3475
3859
|
}
|
|
@@ -4204,16 +4588,38 @@ function mountRouter(router, options) {
|
|
|
4204
4588
|
} else {
|
|
4205
4589
|
outlet = container;
|
|
4206
4590
|
}
|
|
4591
|
+
const routeTransition = options.transition !== void 0 ? resolveTransition(options.transition) : void 0;
|
|
4592
|
+
const txDom = routeTransition !== void 0 ? new BrowserDOMAdapter() : void 0;
|
|
4207
4593
|
let active = null;
|
|
4594
|
+
const pendingLeaves = /* @__PURE__ */ new Map();
|
|
4208
4595
|
let firstRender = hydrateMode;
|
|
4596
|
+
const teardownRoute = (route) => {
|
|
4597
|
+
route.registry.run();
|
|
4598
|
+
route.mounted.unmount();
|
|
4599
|
+
if (route.host !== null && txDom !== void 0) {
|
|
4600
|
+
const parent = txDom.parentNode(route.host);
|
|
4601
|
+
if (parent !== null) txDom.removeChild(parent, route.host);
|
|
4602
|
+
}
|
|
4603
|
+
};
|
|
4209
4604
|
const disposeActive = () => {
|
|
4210
4605
|
if (active === null) return;
|
|
4211
|
-
active
|
|
4212
|
-
active.mounted.unmount();
|
|
4606
|
+
teardownRoute(active);
|
|
4213
4607
|
active = null;
|
|
4214
4608
|
};
|
|
4215
|
-
const
|
|
4216
|
-
|
|
4609
|
+
const wrapOutletChildren = (dom) => {
|
|
4610
|
+
const host2 = dom.createElement("div");
|
|
4611
|
+
dom.setAttribute(host2, "data-streetui-route", "");
|
|
4612
|
+
const moved = [];
|
|
4613
|
+
let child = dom.firstChild(outlet);
|
|
4614
|
+
while (child !== null) {
|
|
4615
|
+
moved.push(child);
|
|
4616
|
+
child = dom.nextSibling(child);
|
|
4617
|
+
}
|
|
4618
|
+
for (const n of moved) dom.appendChild(host2, n);
|
|
4619
|
+
dom.appendChild(outlet, host2);
|
|
4620
|
+
return host2;
|
|
4621
|
+
};
|
|
4622
|
+
const buildRoute = (match, target, hydrate) => {
|
|
4217
4623
|
const registry = new CleanupRegistry();
|
|
4218
4624
|
const ctx = {
|
|
4219
4625
|
path: match.path,
|
|
@@ -4226,9 +4632,53 @@ function mountRouter(router, options) {
|
|
|
4226
4632
|
routeApp.page("route", (page) => match.route.builder(page, ctx));
|
|
4227
4633
|
const runtime = createRuntime({ renderer });
|
|
4228
4634
|
const routeCompiled = compile(routeApp);
|
|
4229
|
-
const mounted =
|
|
4635
|
+
const mounted = hydrate ? runtime.hydrate(routeCompiled, target) : runtime.mount(routeCompiled, target);
|
|
4636
|
+
return { registry, mounted, host: null, enterRun: null };
|
|
4637
|
+
};
|
|
4638
|
+
const renderRoute = (match) => {
|
|
4639
|
+
if (routeTransition === void 0 || txDom === void 0) {
|
|
4640
|
+
disposeActive();
|
|
4641
|
+
active = buildRoute(match, outlet, firstRender);
|
|
4642
|
+
firstRender = false;
|
|
4643
|
+
return;
|
|
4644
|
+
}
|
|
4645
|
+
if (active === null) {
|
|
4646
|
+
if (firstRender) {
|
|
4647
|
+
active = buildRoute(match, outlet, true);
|
|
4648
|
+
active.host = wrapOutletChildren(txDom);
|
|
4649
|
+
} else {
|
|
4650
|
+
const host2 = txDom.createElement("div");
|
|
4651
|
+
txDom.setAttribute(host2, "data-streetui-route", "");
|
|
4652
|
+
txDom.appendChild(outlet, host2);
|
|
4653
|
+
active = buildRoute(match, host2, false);
|
|
4654
|
+
active.host = host2;
|
|
4655
|
+
}
|
|
4656
|
+
firstRender = false;
|
|
4657
|
+
return;
|
|
4658
|
+
}
|
|
4230
4659
|
firstRender = false;
|
|
4231
|
-
|
|
4660
|
+
const leaving = active;
|
|
4661
|
+
leaving.enterRun?.cancel();
|
|
4662
|
+
leaving.enterRun = null;
|
|
4663
|
+
const leaveHost = leaving.host;
|
|
4664
|
+
const enterHost = txDom.createElement("div");
|
|
4665
|
+
txDom.setAttribute(enterHost, "data-streetui-route", "");
|
|
4666
|
+
txDom.appendChild(outlet, enterHost);
|
|
4667
|
+
const next = buildRoute(match, enterHost, false);
|
|
4668
|
+
next.host = enterHost;
|
|
4669
|
+
next.enterRun = runElementTransition(txDom, enterHost, routeTransition, "enter", () => {
|
|
4670
|
+
next.enterRun = null;
|
|
4671
|
+
});
|
|
4672
|
+
active = next;
|
|
4673
|
+
if (leaveHost !== null) {
|
|
4674
|
+
const run = runElementTransition(txDom, leaveHost, routeTransition, "leave", () => {
|
|
4675
|
+
pendingLeaves.delete(leaving);
|
|
4676
|
+
teardownRoute(leaving);
|
|
4677
|
+
});
|
|
4678
|
+
pendingLeaves.set(leaving, run);
|
|
4679
|
+
} else {
|
|
4680
|
+
teardownRoute(leaving);
|
|
4681
|
+
}
|
|
4232
4682
|
};
|
|
4233
4683
|
renderRoute(router.currentRoute.peek());
|
|
4234
4684
|
const stopRouteSub = router.currentRoute.subscribe((match) => renderRoute(match));
|
|
@@ -4256,6 +4706,11 @@ function mountRouter(router, options) {
|
|
|
4256
4706
|
unmount() {
|
|
4257
4707
|
if (interceptLinks) container.removeEventListener("click", onClick);
|
|
4258
4708
|
stopRouteSub();
|
|
4709
|
+
for (const [route, run] of pendingLeaves) {
|
|
4710
|
+
run.cancel();
|
|
4711
|
+
teardownRoute(route);
|
|
4712
|
+
}
|
|
4713
|
+
pendingLeaves.clear();
|
|
4259
4714
|
disposeActive();
|
|
4260
4715
|
shellMounted?.unmount();
|
|
4261
4716
|
router.destroy();
|
|
@@ -4580,6 +5035,40 @@ function inspectComponents(graph) {
|
|
|
4580
5035
|
});
|
|
4581
5036
|
return out;
|
|
4582
5037
|
}
|
|
5038
|
+
function inspectInteractions(graph) {
|
|
5039
|
+
const overlays = [];
|
|
5040
|
+
const transitions = [];
|
|
5041
|
+
graph.walk((node, depth) => {
|
|
5042
|
+
const overlayFn = graph.getHandler(`__overlay__${node.id}`);
|
|
5043
|
+
if (overlayFn !== void 0) {
|
|
5044
|
+
const d = overlayFn();
|
|
5045
|
+
overlays.push({
|
|
5046
|
+
id: node.id,
|
|
5047
|
+
key: node.key,
|
|
5048
|
+
open: d.open.peek(),
|
|
5049
|
+
modal: d.modal,
|
|
5050
|
+
takesFocus: d.takesFocus,
|
|
5051
|
+
menu: d.menu,
|
|
5052
|
+
closeOnEscape: d.closeOnEscape,
|
|
5053
|
+
restoreFocus: d.restoreFocus,
|
|
5054
|
+
depth
|
|
5055
|
+
});
|
|
5056
|
+
}
|
|
5057
|
+
const transitionFn = graph.getHandler(`__transition__${node.id}`);
|
|
5058
|
+
if (transitionFn !== void 0) {
|
|
5059
|
+
const t = transitionFn();
|
|
5060
|
+
transitions.push({
|
|
5061
|
+
id: node.id,
|
|
5062
|
+
key: node.key,
|
|
5063
|
+
nodeType: node.type,
|
|
5064
|
+
duration: t.duration,
|
|
5065
|
+
appear: t.appear,
|
|
5066
|
+
depth
|
|
5067
|
+
});
|
|
5068
|
+
}
|
|
5069
|
+
});
|
|
5070
|
+
return { overlays, transitions };
|
|
5071
|
+
}
|
|
4583
5072
|
|
|
4584
5073
|
// ../devtools/src/application.ts
|
|
4585
5074
|
function collectPerf(node, distinctSignals, acc) {
|
|
@@ -4954,6 +5443,7 @@ function defineConfig(config) {
|
|
|
4954
5443
|
StreetFrameworkError,
|
|
4955
5444
|
StreetRenderHandle,
|
|
4956
5445
|
StreetRendererImpl,
|
|
5446
|
+
TransitionController,
|
|
4957
5447
|
VERSION,
|
|
4958
5448
|
a11yIds,
|
|
4959
5449
|
applyNodeProps,
|
|
@@ -4968,6 +5458,7 @@ function defineConfig(config) {
|
|
|
4968
5458
|
consoleDiagnosticSink,
|
|
4969
5459
|
consoleHydrationDiagnosticSink,
|
|
4970
5460
|
containFocus,
|
|
5461
|
+
createAnnouncer,
|
|
4971
5462
|
createApplication,
|
|
4972
5463
|
createBrowserHistory,
|
|
4973
5464
|
createContext,
|
|
@@ -5002,6 +5493,7 @@ function defineConfig(config) {
|
|
|
5002
5493
|
generateApplicationId,
|
|
5003
5494
|
generateNodeId,
|
|
5004
5495
|
getFocusable,
|
|
5496
|
+
getResolvedTransition,
|
|
5005
5497
|
globalEventBus,
|
|
5006
5498
|
headingUpdate,
|
|
5007
5499
|
hydrateGraph,
|
|
@@ -5012,12 +5504,14 @@ function defineConfig(config) {
|
|
|
5012
5504
|
inspectForm,
|
|
5013
5505
|
inspectGraph,
|
|
5014
5506
|
inspectI18n,
|
|
5507
|
+
inspectInteractions,
|
|
5015
5508
|
inspectResource,
|
|
5016
5509
|
inspectRouter,
|
|
5017
5510
|
inspectSignal,
|
|
5018
5511
|
interpolate,
|
|
5019
5512
|
isBatching,
|
|
5020
5513
|
isComponentDefinition,
|
|
5514
|
+
isTransitionConfig,
|
|
5021
5515
|
matchPattern,
|
|
5022
5516
|
matchRoutes,
|
|
5023
5517
|
maxLength,
|
|
@@ -5046,9 +5540,12 @@ function defineConfig(config) {
|
|
|
5046
5540
|
required,
|
|
5047
5541
|
resetIdCounter,
|
|
5048
5542
|
resolveTag,
|
|
5543
|
+
resolveTransition,
|
|
5049
5544
|
resource,
|
|
5050
5545
|
restoreFocus,
|
|
5051
5546
|
routerOutlet,
|
|
5547
|
+
rovingMenu,
|
|
5548
|
+
runElementTransition,
|
|
5052
5549
|
runValidators,
|
|
5053
5550
|
saveFocus,
|
|
5054
5551
|
scheduleImmediate,
|