streetui 1.6.0 → 1.7.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-CEom4hkp.d.cts → compile-Cte0nf06.d.cts} +80 -3
- package/dist/{compile-CEom4hkp.d.ts → compile-Cte0nf06.d.ts} +80 -3
- 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-YrG-OJJe.d.ts → hydration-diagnostics-Ddgs3Puu.d.ts} +1 -1
- package/dist/{hydration-diagnostics-D286jpZZ.d.cts → hydration-diagnostics-zK-fihvd.d.cts} +1 -1
- package/dist/index.cjs +439 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +93 -10
- package/dist/index.d.ts +93 -10
- package/dist/index.js +430 -5
- package/dist/index.js.map +1 -1
- package/dist/{server-C2xovHHb.d.cts → server-D4A8eunr.d.cts} +43 -1
- package/dist/{server-xU-BEwAj.d.ts → server-cgmCiPsz.d.ts} +43 -1
- package/dist/server.cjs +1126 -839
- 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 +1126 -839
- package/dist/server.js.map +1 -1
- package/dist/testing.cjs +375 -111
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +3 -3
- package/dist/testing.d.ts +3 -3
- package/dist/testing.js +375 -111
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -51,6 +51,7 @@ __export(src_exports, {
|
|
|
51
51
|
ServerDOMAdapter: () => ServerDOMAdapter,
|
|
52
52
|
ServerElement: () => ServerElement,
|
|
53
53
|
ServerFragment: () => ServerFragment,
|
|
54
|
+
ServerRawHTML: () => ServerRawHTML,
|
|
54
55
|
ServerStyle: () => ServerStyle,
|
|
55
56
|
ServerText: () => ServerText,
|
|
56
57
|
Signal: () => Signal,
|
|
@@ -71,6 +72,7 @@ __export(src_exports, {
|
|
|
71
72
|
compileGraph: () => compileGraph,
|
|
72
73
|
consoleDiagnosticSink: () => consoleDiagnosticSink,
|
|
73
74
|
consoleHydrationDiagnosticSink: () => consoleHydrationDiagnosticSink,
|
|
75
|
+
containFocus: () => containFocus,
|
|
74
76
|
createApplication: () => createApplication,
|
|
75
77
|
createBrowserHistory: () => createBrowserHistory,
|
|
76
78
|
createContext: () => createContext,
|
|
@@ -97,12 +99,14 @@ __export(src_exports, {
|
|
|
97
99
|
flushSync: () => flushSync,
|
|
98
100
|
focusById: () => focusById,
|
|
99
101
|
focusFirst: () => focusFirst,
|
|
102
|
+
focusInitial: () => focusInitial,
|
|
100
103
|
formatDiagnostic: () => formatDiagnostic,
|
|
101
104
|
formatDiagnosticContext: () => formatDiagnosticContext,
|
|
102
105
|
formatHydrationDiagnostic: () => formatHydrationDiagnostic,
|
|
103
106
|
frameworkError: () => frameworkError,
|
|
104
107
|
generateApplicationId: () => generateApplicationId,
|
|
105
108
|
generateNodeId: () => generateNodeId,
|
|
109
|
+
getFocusable: () => getFocusable,
|
|
106
110
|
globalEventBus: () => globalEventBus,
|
|
107
111
|
headingUpdate: () => headingUpdate,
|
|
108
112
|
hydrateGraph: () => hydrateGraph,
|
|
@@ -129,6 +133,7 @@ __export(src_exports, {
|
|
|
129
133
|
nodeTypeStats: () => nodeTypeStats,
|
|
130
134
|
normalizePath: () => normalizePath,
|
|
131
135
|
observerCount: () => observerCount,
|
|
136
|
+
onEscape: () => onEscape,
|
|
132
137
|
patchNode: () => patchNode,
|
|
133
138
|
patchProp: () => patchProp,
|
|
134
139
|
pattern: () => pattern,
|
|
@@ -145,8 +150,10 @@ __export(src_exports, {
|
|
|
145
150
|
resetIdCounter: () => resetIdCounter,
|
|
146
151
|
resolveTag: () => resolveTag,
|
|
147
152
|
resource: () => resource,
|
|
153
|
+
restoreFocus: () => restoreFocus,
|
|
148
154
|
routerOutlet: () => routerOutlet,
|
|
149
155
|
runValidators: () => runValidators,
|
|
156
|
+
saveFocus: () => saveFocus,
|
|
150
157
|
scheduleImmediate: () => scheduleImmediate,
|
|
151
158
|
scheduleUpdate: () => scheduleUpdate,
|
|
152
159
|
scheduler: () => scheduler,
|
|
@@ -161,15 +168,17 @@ __export(src_exports, {
|
|
|
161
168
|
textUpdate: () => textUpdate,
|
|
162
169
|
toIdToken: () => toIdToken,
|
|
163
170
|
transformGraph: () => transformGraph,
|
|
171
|
+
trapFocus: () => trapFocus,
|
|
164
172
|
validateGraph: () => validateGraph,
|
|
165
173
|
wireEvents: () => wireEvents,
|
|
174
|
+
wireOverlayBehavior: () => wireOverlayBehavior,
|
|
166
175
|
wireReactiveList: () => wireReactiveList,
|
|
167
176
|
wireSignalBindings: () => wireSignalBindings
|
|
168
177
|
});
|
|
169
178
|
module.exports = __toCommonJS(src_exports);
|
|
170
179
|
|
|
171
180
|
// src/version.ts
|
|
172
|
-
var VERSION = "1.
|
|
181
|
+
var VERSION = "1.7.0";
|
|
173
182
|
|
|
174
183
|
// ../state/src/signal.ts
|
|
175
184
|
var _activeConsumer = null;
|
|
@@ -972,6 +981,7 @@ var ApplicationGraph = class {
|
|
|
972
981
|
}
|
|
973
982
|
this.handlers.delete(`__listbuild__${node.id}`);
|
|
974
983
|
this.handlers.delete(`__listplan__${node.id}`);
|
|
984
|
+
this.handlers.delete(`__overlay__${node.id}`);
|
|
975
985
|
}
|
|
976
986
|
// ── Handler registry ──────────────────────────────────────────────────────
|
|
977
987
|
registerHandler(key, fn) {
|
|
@@ -1086,6 +1096,7 @@ function applyA11yProps(props, options) {
|
|
|
1086
1096
|
if (options.ariaCurrent !== void 0) props["aria-current"] = String(options.ariaCurrent);
|
|
1087
1097
|
if (options.ariaInvalid !== void 0) props["aria-invalid"] = String(options.ariaInvalid);
|
|
1088
1098
|
if (options.ariaRequired !== void 0) props["aria-required"] = String(options.ariaRequired);
|
|
1099
|
+
if (options.ariaModal !== void 0) props["aria-modal"] = String(options.ariaModal);
|
|
1089
1100
|
}
|
|
1090
1101
|
function containerProps(options) {
|
|
1091
1102
|
const props = {};
|
|
@@ -1117,6 +1128,49 @@ function reactiveListItemSignature(item) {
|
|
|
1117
1128
|
function reactiveListItemKey(item, index) {
|
|
1118
1129
|
return itemIdentity(item, index);
|
|
1119
1130
|
}
|
|
1131
|
+
var OVERLAY_KINDS = {
|
|
1132
|
+
dialog: {
|
|
1133
|
+
role: "dialog",
|
|
1134
|
+
modal: true,
|
|
1135
|
+
takesFocus: true,
|
|
1136
|
+
ariaModal: true,
|
|
1137
|
+
defaultCloseOnEscape: true,
|
|
1138
|
+
defaultRestoreFocus: true
|
|
1139
|
+
},
|
|
1140
|
+
popover: {
|
|
1141
|
+
role: "dialog",
|
|
1142
|
+
modal: false,
|
|
1143
|
+
takesFocus: true,
|
|
1144
|
+
ariaModal: false,
|
|
1145
|
+
defaultCloseOnEscape: true,
|
|
1146
|
+
defaultRestoreFocus: true
|
|
1147
|
+
},
|
|
1148
|
+
tooltip: {
|
|
1149
|
+
role: "tooltip",
|
|
1150
|
+
modal: false,
|
|
1151
|
+
takesFocus: false,
|
|
1152
|
+
ariaModal: false,
|
|
1153
|
+
defaultCloseOnEscape: false,
|
|
1154
|
+
defaultRestoreFocus: false
|
|
1155
|
+
},
|
|
1156
|
+
dropdown: {
|
|
1157
|
+
role: "menu",
|
|
1158
|
+
modal: false,
|
|
1159
|
+
takesFocus: true,
|
|
1160
|
+
ariaModal: false,
|
|
1161
|
+
defaultCloseOnEscape: true,
|
|
1162
|
+
defaultRestoreFocus: true
|
|
1163
|
+
},
|
|
1164
|
+
toast: {
|
|
1165
|
+
role: "status",
|
|
1166
|
+
modal: false,
|
|
1167
|
+
takesFocus: false,
|
|
1168
|
+
ariaModal: false,
|
|
1169
|
+
ariaLive: "polite",
|
|
1170
|
+
defaultCloseOnEscape: false,
|
|
1171
|
+
defaultRestoreFocus: false
|
|
1172
|
+
}
|
|
1173
|
+
};
|
|
1120
1174
|
var ContentBuilderBase = class {
|
|
1121
1175
|
constructor(_node, _graph) {
|
|
1122
1176
|
this._node = _node;
|
|
@@ -1389,6 +1443,74 @@ var ContainerBuilderBase = class extends ContentBuilderBase {
|
|
|
1389
1443
|
);
|
|
1390
1444
|
}, { id });
|
|
1391
1445
|
}
|
|
1446
|
+
// ── Portals & overlays ──────────────────────────────────────────────────────
|
|
1447
|
+
portal(key, builder, options = {}) {
|
|
1448
|
+
const node = this._graph.createNode("portal", {
|
|
1449
|
+
key,
|
|
1450
|
+
parent: this._node,
|
|
1451
|
+
props: containerProps(options)
|
|
1452
|
+
});
|
|
1453
|
+
builder(new ContainerBuilderImpl(node, this._graph));
|
|
1454
|
+
}
|
|
1455
|
+
/**
|
|
1456
|
+
* Shared assembly for every overlay kind: a `portal` node whose single child
|
|
1457
|
+
* is a `when(open, panel)` conditional. The panel container carries the
|
|
1458
|
+
* kind's ARIA semantics; `builder` fills it. An `__overlay__<portalId>`
|
|
1459
|
+
* descriptor is registered so the renderer wires focus/keyboard behavior to
|
|
1460
|
+
* the same `open` signal that drives the panel. Reuses existing primitives
|
|
1461
|
+
* (portal + when + container) — no new render path.
|
|
1462
|
+
*/
|
|
1463
|
+
_overlay(kind, key, options, builder) {
|
|
1464
|
+
const graph = this._graph;
|
|
1465
|
+
const portalNode = graph.createNode("portal", {
|
|
1466
|
+
key,
|
|
1467
|
+
parent: this._node,
|
|
1468
|
+
props: { key }
|
|
1469
|
+
});
|
|
1470
|
+
const openBindable = options.open;
|
|
1471
|
+
const openSignal = isSignal(openBindable) ? openBindable : signal(openBindable);
|
|
1472
|
+
const panelOptions = {
|
|
1473
|
+
role: options.role ?? kind.role,
|
|
1474
|
+
...kind.ariaModal ? { ariaModal: true } : {},
|
|
1475
|
+
...kind.ariaLive !== void 0 ? { ariaLive: kind.ariaLive } : {},
|
|
1476
|
+
...options.class !== void 0 ? { class: options.class } : {},
|
|
1477
|
+
...options.ariaLabel !== void 0 ? { ariaLabel: options.ariaLabel } : {},
|
|
1478
|
+
...options.ariaLabelledBy !== void 0 ? { ariaLabelledBy: options.ariaLabelledBy } : {},
|
|
1479
|
+
...options.ariaDescribedBy !== void 0 ? { ariaDescribedBy: options.ariaDescribedBy } : {}
|
|
1480
|
+
};
|
|
1481
|
+
const portalBuilder = new ContainerBuilderImpl(portalNode, graph);
|
|
1482
|
+
portalBuilder.when(openSignal, (panelHost) => {
|
|
1483
|
+
panelHost.container(`${key}__panel`, builder, panelOptions);
|
|
1484
|
+
});
|
|
1485
|
+
const descriptor = {
|
|
1486
|
+
open: openSignal,
|
|
1487
|
+
modal: kind.modal,
|
|
1488
|
+
takesFocus: kind.takesFocus,
|
|
1489
|
+
closeOnEscape: options.closeOnEscape ?? kind.defaultCloseOnEscape,
|
|
1490
|
+
restoreFocus: options.restoreFocus ?? kind.defaultRestoreFocus,
|
|
1491
|
+
...options.initialFocusId !== void 0 ? { initialFocusId: options.initialFocusId } : {},
|
|
1492
|
+
...options.onClose !== void 0 ? { onClose: options.onClose } : {}
|
|
1493
|
+
};
|
|
1494
|
+
graph.registerHandler(
|
|
1495
|
+
`__overlay__${portalNode.id}`,
|
|
1496
|
+
() => descriptor
|
|
1497
|
+
);
|
|
1498
|
+
}
|
|
1499
|
+
dialog(key, options, builder) {
|
|
1500
|
+
this._overlay(OVERLAY_KINDS.dialog, key, options, builder);
|
|
1501
|
+
}
|
|
1502
|
+
popover(key, options, builder) {
|
|
1503
|
+
this._overlay(OVERLAY_KINDS.popover, key, options, builder);
|
|
1504
|
+
}
|
|
1505
|
+
tooltip(key, options, builder) {
|
|
1506
|
+
this._overlay(OVERLAY_KINDS.tooltip, key, options, builder);
|
|
1507
|
+
}
|
|
1508
|
+
dropdown(key, options, builder) {
|
|
1509
|
+
this._overlay(OVERLAY_KINDS.dropdown, key, options, builder);
|
|
1510
|
+
}
|
|
1511
|
+
toast(key, options, builder) {
|
|
1512
|
+
this._overlay(OVERLAY_KINDS.toast, key, options, builder);
|
|
1513
|
+
}
|
|
1392
1514
|
};
|
|
1393
1515
|
var SectionBuilderImpl = class extends ContainerBuilderBase {
|
|
1394
1516
|
};
|
|
@@ -1989,6 +2111,18 @@ var BrowserDOMAdapter = class {
|
|
|
1989
2111
|
focus(element) {
|
|
1990
2112
|
element.focus?.();
|
|
1991
2113
|
}
|
|
2114
|
+
body() {
|
|
2115
|
+
return document.body ?? null;
|
|
2116
|
+
}
|
|
2117
|
+
activeElement() {
|
|
2118
|
+
return document.activeElement ?? null;
|
|
2119
|
+
}
|
|
2120
|
+
contains(ancestor, node) {
|
|
2121
|
+
return ancestor.contains(node);
|
|
2122
|
+
}
|
|
2123
|
+
matches(element, selector) {
|
|
2124
|
+
return typeof element.matches === "function" && element.matches(selector);
|
|
2125
|
+
}
|
|
1992
2126
|
isElement(node) {
|
|
1993
2127
|
return node.nodeType === Node.ELEMENT_NODE;
|
|
1994
2128
|
}
|
|
@@ -2047,6 +2181,14 @@ var ServerFragment = class {
|
|
|
2047
2181
|
parent = null;
|
|
2048
2182
|
children = [];
|
|
2049
2183
|
};
|
|
2184
|
+
var ServerRawHTML = class {
|
|
2185
|
+
kind = "raw";
|
|
2186
|
+
parent = null;
|
|
2187
|
+
html;
|
|
2188
|
+
constructor(html) {
|
|
2189
|
+
this.html = html;
|
|
2190
|
+
}
|
|
2191
|
+
};
|
|
2050
2192
|
var ServerElement = class {
|
|
2051
2193
|
kind = "element";
|
|
2052
2194
|
parent = null;
|
|
@@ -2197,6 +2339,8 @@ function serializeServerNode(node) {
|
|
|
2197
2339
|
return `<!--${node.data}-->`;
|
|
2198
2340
|
case "fragment":
|
|
2199
2341
|
return serializeChildren(node);
|
|
2342
|
+
case "raw":
|
|
2343
|
+
return node.html;
|
|
2200
2344
|
case "element": {
|
|
2201
2345
|
const el = node;
|
|
2202
2346
|
const tag = el.tagName;
|
|
@@ -2236,6 +2380,15 @@ var ServerDOMAdapter = class {
|
|
|
2236
2380
|
createFragment() {
|
|
2237
2381
|
return new ServerFragment();
|
|
2238
2382
|
}
|
|
2383
|
+
/**
|
|
2384
|
+
* Create a verbatim pre-serialized HTML node (v1.7 static SSR plan, §6).
|
|
2385
|
+
* Server-only: the browser adapter does not implement this, and the renderer
|
|
2386
|
+
* fast path only invokes it when a static SSR plan is present (SSR). The
|
|
2387
|
+
* stored HTML was produced by this same serializer, so it is emitted as-is.
|
|
2388
|
+
*/
|
|
2389
|
+
createRawHTML(html) {
|
|
2390
|
+
return new ServerRawHTML(html);
|
|
2391
|
+
}
|
|
2239
2392
|
appendChild(parent, child) {
|
|
2240
2393
|
const p = asParent(parent);
|
|
2241
2394
|
const c = asServer(child);
|
|
@@ -2337,6 +2490,18 @@ var ServerDOMAdapter = class {
|
|
|
2337
2490
|
}
|
|
2338
2491
|
focus() {
|
|
2339
2492
|
}
|
|
2493
|
+
body() {
|
|
2494
|
+
return null;
|
|
2495
|
+
}
|
|
2496
|
+
activeElement() {
|
|
2497
|
+
return null;
|
|
2498
|
+
}
|
|
2499
|
+
contains(_ancestor, _node) {
|
|
2500
|
+
return false;
|
|
2501
|
+
}
|
|
2502
|
+
matches(_element, _selector) {
|
|
2503
|
+
return false;
|
|
2504
|
+
}
|
|
2340
2505
|
isElement(node) {
|
|
2341
2506
|
return asServer(node).kind === "element";
|
|
2342
2507
|
}
|
|
@@ -2402,15 +2567,76 @@ function focusFirst(dom, container, selector = FOCUSABLE_SELECTOR) {
|
|
|
2402
2567
|
dom.focus(el);
|
|
2403
2568
|
return true;
|
|
2404
2569
|
}
|
|
2570
|
+
function getFocusable(dom, container, selector = FOCUSABLE_SELECTOR) {
|
|
2571
|
+
return Array.from(dom.querySelectorAll(container, selector)).filter(
|
|
2572
|
+
(el) => dom.matches(el, selector)
|
|
2573
|
+
);
|
|
2574
|
+
}
|
|
2575
|
+
function saveFocus(dom) {
|
|
2576
|
+
return dom.activeElement();
|
|
2577
|
+
}
|
|
2578
|
+
function restoreFocus(dom, saved) {
|
|
2579
|
+
if (saved !== null) dom.focus(saved);
|
|
2580
|
+
}
|
|
2581
|
+
function focusInitial(dom, container, initialFocusId) {
|
|
2582
|
+
if (initialFocusId !== void 0 && focusById(dom, container, initialFocusId)) return;
|
|
2583
|
+
focusFirst(dom, container);
|
|
2584
|
+
}
|
|
2585
|
+
function trapFocus(dom, container) {
|
|
2586
|
+
const onKeydown = (event) => {
|
|
2587
|
+
if (event.key !== "Tab") return;
|
|
2588
|
+
const items = getFocusable(dom, container);
|
|
2589
|
+
if (items.length === 0) {
|
|
2590
|
+
event.preventDefault();
|
|
2591
|
+
return;
|
|
2592
|
+
}
|
|
2593
|
+
const first = items[0];
|
|
2594
|
+
const last = items[items.length - 1];
|
|
2595
|
+
const active = dom.activeElement();
|
|
2596
|
+
if (active === null || !dom.contains(container, active)) {
|
|
2597
|
+
event.preventDefault();
|
|
2598
|
+
dom.focus(first);
|
|
2599
|
+
} else if (event.shiftKey && active === first) {
|
|
2600
|
+
event.preventDefault();
|
|
2601
|
+
dom.focus(last);
|
|
2602
|
+
} else if (!event.shiftKey && active === last) {
|
|
2603
|
+
event.preventDefault();
|
|
2604
|
+
dom.focus(first);
|
|
2605
|
+
}
|
|
2606
|
+
};
|
|
2607
|
+
dom.addEventListener(container, "keydown", onKeydown);
|
|
2608
|
+
return () => dom.removeEventListener(container, "keydown", onKeydown);
|
|
2609
|
+
}
|
|
2610
|
+
function containFocus(dom, container) {
|
|
2611
|
+
const body = dom.body();
|
|
2612
|
+
if (body === null) return () => {
|
|
2613
|
+
};
|
|
2614
|
+
const onFocusIn = (event) => {
|
|
2615
|
+
const target = event.target;
|
|
2616
|
+
if (target !== null && !dom.contains(container, target)) {
|
|
2617
|
+
focusFirst(dom, container);
|
|
2618
|
+
}
|
|
2619
|
+
};
|
|
2620
|
+
dom.addEventListener(body, "focusin", onFocusIn);
|
|
2621
|
+
return () => dom.removeEventListener(body, "focusin", onFocusIn);
|
|
2622
|
+
}
|
|
2623
|
+
function onEscape(dom, target, handler) {
|
|
2624
|
+
const onKeydown = (event) => {
|
|
2625
|
+
if (event.key === "Escape") handler();
|
|
2626
|
+
};
|
|
2627
|
+
dom.addEventListener(target, "keydown", onKeydown);
|
|
2628
|
+
return () => dom.removeEventListener(target, "keydown", onKeydown);
|
|
2629
|
+
}
|
|
2405
2630
|
|
|
2406
2631
|
// ../renderer/src/render-context.ts
|
|
2407
|
-
function createRenderContext(dom, graph, container, hydrationDiagnostics) {
|
|
2632
|
+
function createRenderContext(dom, graph, container, hydrationDiagnostics, staticHTML) {
|
|
2408
2633
|
return {
|
|
2409
2634
|
dom,
|
|
2410
2635
|
graph,
|
|
2411
2636
|
instances: /* @__PURE__ */ new Map(),
|
|
2412
2637
|
container,
|
|
2413
|
-
...hydrationDiagnostics !== void 0 ? { hydrationDiagnostics } : {}
|
|
2638
|
+
...hydrationDiagnostics !== void 0 ? { hydrationDiagnostics } : {},
|
|
2639
|
+
...staticHTML !== void 0 ? { staticHTML } : {}
|
|
2414
2640
|
};
|
|
2415
2641
|
}
|
|
2416
2642
|
|
|
@@ -2559,7 +2785,12 @@ var TAG_MAP = {
|
|
|
2559
2785
|
component: "div",
|
|
2560
2786
|
slot: "div",
|
|
2561
2787
|
fragment: "div",
|
|
2562
|
-
"reactive-list": "ul"
|
|
2788
|
+
"reactive-list": "ul",
|
|
2789
|
+
// A portal renders as a neutral inline anchor <div> at its declaration site;
|
|
2790
|
+
// its children are relocated to a document.body container on the browser
|
|
2791
|
+
// (see the portal branch in mount.ts). On the server (no body) it renders
|
|
2792
|
+
// inline, so the anchor tag is what SSR/hydration positionally match on.
|
|
2793
|
+
portal: "div"
|
|
2563
2794
|
};
|
|
2564
2795
|
function resolveTag(type) {
|
|
2565
2796
|
return TAG_MAP[type] ?? "div";
|
|
@@ -2838,6 +3069,17 @@ function mountGraph(ctx) {
|
|
|
2838
3069
|
}
|
|
2839
3070
|
function mountNode(ctx, graphNode, parentDom) {
|
|
2840
3071
|
const { dom, graph } = ctx;
|
|
3072
|
+
const staticHTML = ctx.staticHTML;
|
|
3073
|
+
if (staticHTML !== void 0 && dom.createRawHTML !== void 0) {
|
|
3074
|
+
const precomputed = staticHTML.get(graphNode.id);
|
|
3075
|
+
if (precomputed !== void 0) {
|
|
3076
|
+
const raw = dom.createRawHTML(precomputed);
|
|
3077
|
+
dom.appendChild(parentDom, raw);
|
|
3078
|
+
const instance2 = new NodeInstance(graphNode, raw);
|
|
3079
|
+
ctx.instances.set(graphNode.id, instance2);
|
|
3080
|
+
return instance2;
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
2841
3083
|
if (graphNode.type === "application") {
|
|
2842
3084
|
const instance2 = new NodeInstance(graphNode, parentDom);
|
|
2843
3085
|
ctx.instances.set(graphNode.id, instance2);
|
|
@@ -2960,6 +3202,28 @@ function mountNode(ctx, graphNode, parentDom) {
|
|
|
2960
3202
|
wireReactiveList(ctx, graphNode, instance2, el2);
|
|
2961
3203
|
return instance2;
|
|
2962
3204
|
}
|
|
3205
|
+
if (graphNode.type === "portal") {
|
|
3206
|
+
const anchor = dom.createElement(resolveTag("portal"));
|
|
3207
|
+
dom.setAttribute(anchor, "data-streetui-portal", "");
|
|
3208
|
+
applyNodeProps(ctx, graphNode, anchor);
|
|
3209
|
+
const instance2 = new NodeInstance(graphNode, anchor);
|
|
3210
|
+
ctx.instances.set(graphNode.id, instance2);
|
|
3211
|
+
const body = dom.body();
|
|
3212
|
+
let target = anchor;
|
|
3213
|
+
if (body !== null) {
|
|
3214
|
+
const portalContainer = dom.createElement("div");
|
|
3215
|
+
dom.setAttribute(portalContainer, "data-streetui-portal-container", "");
|
|
3216
|
+
dom.appendChild(body, portalContainer);
|
|
3217
|
+
instance2.trackCleanup(() => dom.removeChild(body, portalContainer));
|
|
3218
|
+
target = portalContainer;
|
|
3219
|
+
}
|
|
3220
|
+
for (const child of graphNode.children) {
|
|
3221
|
+
instance2.addChild(mountNode(ctx, child, target));
|
|
3222
|
+
}
|
|
3223
|
+
dom.appendChild(parentDom, anchor);
|
|
3224
|
+
wireOverlayBehavior(ctx, graphNode, instance2, target);
|
|
3225
|
+
return instance2;
|
|
3226
|
+
}
|
|
2963
3227
|
const tag = resolveTag(graphNode.type);
|
|
2964
3228
|
const el = dom.createElement(tag);
|
|
2965
3229
|
applyNodeProps(ctx, graphNode, el);
|
|
@@ -3109,6 +3373,44 @@ function forgetInstance(ctx, instance) {
|
|
|
3109
3373
|
ctx.instances.delete(instance.graphNode.id);
|
|
3110
3374
|
for (const child of instance.children) forgetInstance(ctx, child);
|
|
3111
3375
|
}
|
|
3376
|
+
function wireOverlayBehavior(ctx, graphNode, instance, target) {
|
|
3377
|
+
const { dom, graph } = ctx;
|
|
3378
|
+
if (dom.body() === null) return;
|
|
3379
|
+
const descFn = graph.getHandler(`__overlay__${graphNode.id}`);
|
|
3380
|
+
if (descFn === void 0) return;
|
|
3381
|
+
const desc = descFn();
|
|
3382
|
+
const openSig = desc.open;
|
|
3383
|
+
if (openSig === void 0 || typeof openSig.subscribe !== "function") return;
|
|
3384
|
+
let active = [];
|
|
3385
|
+
let saved = null;
|
|
3386
|
+
const teardown = () => {
|
|
3387
|
+
for (const fn of active) fn();
|
|
3388
|
+
active = [];
|
|
3389
|
+
};
|
|
3390
|
+
const onOpenChange = (isOpen) => {
|
|
3391
|
+
if (isOpen) {
|
|
3392
|
+
if (desc.restoreFocus) saved = saveFocus(dom);
|
|
3393
|
+
if (desc.takesFocus) focusInitial(dom, target, desc.initialFocusId);
|
|
3394
|
+
if (desc.modal) {
|
|
3395
|
+
active.push(trapFocus(dom, target));
|
|
3396
|
+
active.push(containFocus(dom, target));
|
|
3397
|
+
}
|
|
3398
|
+
if (desc.closeOnEscape && desc.onClose !== void 0) {
|
|
3399
|
+
active.push(onEscape(dom, target, desc.onClose));
|
|
3400
|
+
}
|
|
3401
|
+
} else {
|
|
3402
|
+
teardown();
|
|
3403
|
+
if (desc.restoreFocus && saved !== null) {
|
|
3404
|
+
restoreFocus(dom, saved);
|
|
3405
|
+
saved = null;
|
|
3406
|
+
}
|
|
3407
|
+
}
|
|
3408
|
+
};
|
|
3409
|
+
const unsub = openSig.subscribe(onOpenChange);
|
|
3410
|
+
instance.trackCleanup(unsub);
|
|
3411
|
+
instance.trackCleanup(teardown);
|
|
3412
|
+
if (openSig.peek() === true) onOpenChange(true);
|
|
3413
|
+
}
|
|
3112
3414
|
|
|
3113
3415
|
// ../renderer/src/hydration-diagnostics.ts
|
|
3114
3416
|
function formatHydrationDiagnostic(d) {
|
|
@@ -3211,6 +3513,25 @@ function hydrateNode(ctx, graphNode, domNode, path) {
|
|
|
3211
3513
|
wireReactiveList(ctx, graphNode, instance, domNode);
|
|
3212
3514
|
return instance;
|
|
3213
3515
|
}
|
|
3516
|
+
case "portal": {
|
|
3517
|
+
const instance = new NodeInstance(graphNode, domNode);
|
|
3518
|
+
ctx.instances.set(graphNode.id, instance);
|
|
3519
|
+
const body = dom.body();
|
|
3520
|
+
let target = domNode;
|
|
3521
|
+
if (body !== null) {
|
|
3522
|
+
const portalContainer = dom.createElement("div");
|
|
3523
|
+
dom.setAttribute(portalContainer, "data-streetui-portal-container", "");
|
|
3524
|
+
for (const child of dom.childNodes(domNode)) {
|
|
3525
|
+
dom.appendChild(portalContainer, child);
|
|
3526
|
+
}
|
|
3527
|
+
dom.appendChild(body, portalContainer);
|
|
3528
|
+
instance.trackCleanup(() => dom.removeChild(body, portalContainer));
|
|
3529
|
+
target = portalContainer;
|
|
3530
|
+
}
|
|
3531
|
+
hydrateChildren(ctx, graphNode, instance, target, path);
|
|
3532
|
+
wireOverlayBehavior(ctx, graphNode, instance, target);
|
|
3533
|
+
return instance;
|
|
3534
|
+
}
|
|
3214
3535
|
default: {
|
|
3215
3536
|
const instance = new NodeInstance(graphNode, domNode);
|
|
3216
3537
|
ctx.instances.set(graphNode.id, instance);
|
|
@@ -3425,11 +3746,115 @@ function readState(dom, root) {
|
|
|
3425
3746
|
}
|
|
3426
3747
|
}
|
|
3427
3748
|
|
|
3749
|
+
// ../compiler/dist/diagnostics.js
|
|
3750
|
+
var TEXT_PROP_KEYS = /* @__PURE__ */ new Set(["text", "label", "value"]);
|
|
3751
|
+
function analyzeGraph(graph) {
|
|
3752
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
3753
|
+
const summary = {
|
|
3754
|
+
totalNodes: 0,
|
|
3755
|
+
staticNodes: 0,
|
|
3756
|
+
staticSubtrees: 0,
|
|
3757
|
+
dynamicTextNodes: 0,
|
|
3758
|
+
dynamicAttrNodes: 0,
|
|
3759
|
+
eventNodes: 0,
|
|
3760
|
+
lists: 0,
|
|
3761
|
+
conditionals: 0
|
|
3762
|
+
};
|
|
3763
|
+
const visit = (node) => {
|
|
3764
|
+
let allChildrenStatic = true;
|
|
3765
|
+
for (const child of node.children) {
|
|
3766
|
+
const childSubtreeStatic = visit(child);
|
|
3767
|
+
if (!childSubtreeStatic) allChildrenStatic = false;
|
|
3768
|
+
}
|
|
3769
|
+
let hasDynamicText = false;
|
|
3770
|
+
let hasDynamicAttr = false;
|
|
3771
|
+
for (const ref of node.stateRefs) {
|
|
3772
|
+
if (TEXT_PROP_KEYS.has(ref.propKey)) hasDynamicText = true;
|
|
3773
|
+
else hasDynamicAttr = true;
|
|
3774
|
+
}
|
|
3775
|
+
const hasEvents = node.events.length > 0;
|
|
3776
|
+
const isList = node.type === "reactive-list";
|
|
3777
|
+
const isConditional = node.type === "conditional";
|
|
3778
|
+
const isPortal = node.type === "portal";
|
|
3779
|
+
const isStatic = node.stateRefs.length === 0 && !hasEvents && !isList && !isConditional && !isPortal;
|
|
3780
|
+
const isStaticSubtree = isStatic && allChildrenStatic;
|
|
3781
|
+
nodes.set(node.id, {
|
|
3782
|
+
isStatic,
|
|
3783
|
+
isStaticSubtree,
|
|
3784
|
+
hasDynamicText,
|
|
3785
|
+
hasDynamicAttr,
|
|
3786
|
+
hasEvents,
|
|
3787
|
+
isList,
|
|
3788
|
+
isConditional
|
|
3789
|
+
});
|
|
3790
|
+
summary.totalNodes += 1;
|
|
3791
|
+
if (isStatic) summary.staticNodes += 1;
|
|
3792
|
+
if (isStaticSubtree) summary.staticSubtrees += 1;
|
|
3793
|
+
if (hasDynamicText) summary.dynamicTextNodes += 1;
|
|
3794
|
+
if (hasDynamicAttr) summary.dynamicAttrNodes += 1;
|
|
3795
|
+
if (hasEvents) summary.eventNodes += 1;
|
|
3796
|
+
if (isList) summary.lists += 1;
|
|
3797
|
+
if (isConditional) summary.conditionals += 1;
|
|
3798
|
+
return isStaticSubtree;
|
|
3799
|
+
};
|
|
3800
|
+
visit(graph.root);
|
|
3801
|
+
return { nodes, summary };
|
|
3802
|
+
}
|
|
3803
|
+
|
|
3804
|
+
// ../renderer/src/static-ssr-plan.ts
|
|
3805
|
+
function collectMaximalStaticRoots(graph) {
|
|
3806
|
+
const analysis = analyzeGraph(graph);
|
|
3807
|
+
const roots = [];
|
|
3808
|
+
const walk = (node) => {
|
|
3809
|
+
if (node.type !== "application") {
|
|
3810
|
+
const a = analysis.nodes.get(node.id);
|
|
3811
|
+
if (a !== void 0 && a.isStaticSubtree) {
|
|
3812
|
+
roots.push(node);
|
|
3813
|
+
return;
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3816
|
+
for (const child of node.children) walk(child);
|
|
3817
|
+
};
|
|
3818
|
+
walk(graph.root);
|
|
3819
|
+
return roots;
|
|
3820
|
+
}
|
|
3821
|
+
function serializeStaticSubtree(dom, graph, root) {
|
|
3822
|
+
const container = dom.createElement("div");
|
|
3823
|
+
const ctx = createRenderContext(dom, graph, container);
|
|
3824
|
+
const instance = mountNode(ctx, root, container);
|
|
3825
|
+
const html = dom.serializeInner(container);
|
|
3826
|
+
instance.dispose();
|
|
3827
|
+
ctx.instances.clear();
|
|
3828
|
+
return html;
|
|
3829
|
+
}
|
|
3830
|
+
function buildStaticSSRPlan(compiled) {
|
|
3831
|
+
const graph = compiled.graph;
|
|
3832
|
+
const roots = collectMaximalStaticRoots(graph);
|
|
3833
|
+
const plan = /* @__PURE__ */ new Map();
|
|
3834
|
+
if (roots.length === 0) return plan;
|
|
3835
|
+
const dom = new ServerDOMAdapter();
|
|
3836
|
+
for (const root of roots) {
|
|
3837
|
+
plan.set(root.id, serializeStaticSubtree(dom, graph, root));
|
|
3838
|
+
}
|
|
3839
|
+
return plan;
|
|
3840
|
+
}
|
|
3841
|
+
var PLAN_CACHE = /* @__PURE__ */ new WeakMap();
|
|
3842
|
+
function getStaticSSRPlan(compiled) {
|
|
3843
|
+
let plan = PLAN_CACHE.get(compiled);
|
|
3844
|
+
if (plan === void 0) {
|
|
3845
|
+
plan = buildStaticSSRPlan(compiled);
|
|
3846
|
+
PLAN_CACHE.set(compiled, plan);
|
|
3847
|
+
}
|
|
3848
|
+
return plan;
|
|
3849
|
+
}
|
|
3850
|
+
|
|
3428
3851
|
// ../renderer/src/ssr.ts
|
|
3429
3852
|
function renderToString(compiled, options = {}) {
|
|
3430
3853
|
const dom = options.domAdapter ?? new ServerDOMAdapter();
|
|
3854
|
+
const plan = options.staticPlan === null ? void 0 : options.staticPlan ?? getStaticSSRPlan(compiled);
|
|
3855
|
+
const staticHTML = plan !== void 0 && plan.size > 0 ? plan : void 0;
|
|
3431
3856
|
const container = dom.createElement("div");
|
|
3432
|
-
const ctx = createRenderContext(dom, compiled.graph, container);
|
|
3857
|
+
const ctx = createRenderContext(dom, compiled.graph, container, void 0, staticHTML);
|
|
3433
3858
|
const rootInstance = mountGraph(ctx);
|
|
3434
3859
|
const html = dom.serializeInner(container);
|
|
3435
3860
|
rootInstance.dispose();
|
|
@@ -4423,6 +4848,7 @@ function defineConfig(config) {
|
|
|
4423
4848
|
ServerDOMAdapter,
|
|
4424
4849
|
ServerElement,
|
|
4425
4850
|
ServerFragment,
|
|
4851
|
+
ServerRawHTML,
|
|
4426
4852
|
ServerStyle,
|
|
4427
4853
|
ServerText,
|
|
4428
4854
|
Signal,
|
|
@@ -4443,6 +4869,7 @@ function defineConfig(config) {
|
|
|
4443
4869
|
compileGraph,
|
|
4444
4870
|
consoleDiagnosticSink,
|
|
4445
4871
|
consoleHydrationDiagnosticSink,
|
|
4872
|
+
containFocus,
|
|
4446
4873
|
createApplication,
|
|
4447
4874
|
createBrowserHistory,
|
|
4448
4875
|
createContext,
|
|
@@ -4469,12 +4896,14 @@ function defineConfig(config) {
|
|
|
4469
4896
|
flushSync,
|
|
4470
4897
|
focusById,
|
|
4471
4898
|
focusFirst,
|
|
4899
|
+
focusInitial,
|
|
4472
4900
|
formatDiagnostic,
|
|
4473
4901
|
formatDiagnosticContext,
|
|
4474
4902
|
formatHydrationDiagnostic,
|
|
4475
4903
|
frameworkError,
|
|
4476
4904
|
generateApplicationId,
|
|
4477
4905
|
generateNodeId,
|
|
4906
|
+
getFocusable,
|
|
4478
4907
|
globalEventBus,
|
|
4479
4908
|
headingUpdate,
|
|
4480
4909
|
hydrateGraph,
|
|
@@ -4501,6 +4930,7 @@ function defineConfig(config) {
|
|
|
4501
4930
|
nodeTypeStats,
|
|
4502
4931
|
normalizePath,
|
|
4503
4932
|
observerCount,
|
|
4933
|
+
onEscape,
|
|
4504
4934
|
patchNode,
|
|
4505
4935
|
patchProp,
|
|
4506
4936
|
pattern,
|
|
@@ -4517,8 +4947,10 @@ function defineConfig(config) {
|
|
|
4517
4947
|
resetIdCounter,
|
|
4518
4948
|
resolveTag,
|
|
4519
4949
|
resource,
|
|
4950
|
+
restoreFocus,
|
|
4520
4951
|
routerOutlet,
|
|
4521
4952
|
runValidators,
|
|
4953
|
+
saveFocus,
|
|
4522
4954
|
scheduleImmediate,
|
|
4523
4955
|
scheduleUpdate,
|
|
4524
4956
|
scheduler,
|
|
@@ -4533,8 +4965,10 @@ function defineConfig(config) {
|
|
|
4533
4965
|
textUpdate,
|
|
4534
4966
|
toIdToken,
|
|
4535
4967
|
transformGraph,
|
|
4968
|
+
trapFocus,
|
|
4536
4969
|
validateGraph,
|
|
4537
4970
|
wireEvents,
|
|
4971
|
+
wireOverlayBehavior,
|
|
4538
4972
|
wireReactiveList,
|
|
4539
4973
|
wireSignalBindings
|
|
4540
4974
|
});
|