streetui 1.7.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-Cte0nf06.d.cts → compile-DqsMQVJk.d.cts} +255 -4
- package/dist/{compile-Cte0nf06.d.ts → compile-DqsMQVJk.d.ts} +255 -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-zK-fihvd.d.cts → hydration-diagnostics-4pwt6v7b.d.cts} +1 -1
- package/dist/{hydration-diagnostics-Ddgs3Puu.d.ts → hydration-diagnostics-B2FmY05M.d.ts} +1 -1
- package/dist/index.cjs +639 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +294 -18
- package/dist/index.d.ts +294 -18
- package/dist/index.js +627 -41
- package/dist/index.js.map +1 -1
- package/dist/{server-cgmCiPsz.d.ts → server-BYnmb_hR.d.ts} +1 -1
- package/dist/{server-D4A8eunr.d.cts → server-DnwqBTfE.d.cts} +1 -1
- package/dist/server.cjs +274 -31
- 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 +274 -31
- package/dist/server.js.map +1 -1
- package/dist/testing.cjs +1470 -33
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +101 -4
- package/dist/testing.d.ts +101 -4
- package/dist/testing.js +1456 -32
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
package/dist/testing.cjs
CHANGED
|
@@ -22,24 +22,46 @@ var testing_exports = {};
|
|
|
22
22
|
__export(testing_exports, {
|
|
23
23
|
VERSION: () => VERSION,
|
|
24
24
|
analyzeGraph: () => analyzeGraph,
|
|
25
|
+
blur: () => blur,
|
|
26
|
+
clickOutside: () => clickOutside,
|
|
27
|
+
closeOverlay: () => closeOverlay,
|
|
25
28
|
findAllByRole: () => findAllByRole,
|
|
29
|
+
findAllComponents: () => findAllComponents,
|
|
26
30
|
findByRole: () => findByRole,
|
|
27
31
|
findByText: () => findByText,
|
|
32
|
+
findComponent: () => findComponent,
|
|
28
33
|
flushUpdates: () => flushUpdates,
|
|
34
|
+
focus: () => focus,
|
|
29
35
|
formatInspection: () => formatInspection,
|
|
36
|
+
getComponentName: () => getComponentName,
|
|
37
|
+
hydrateComponent: () => hydrateComponent,
|
|
30
38
|
inspectCompilation: () => inspectCompilation,
|
|
39
|
+
openOverlay: () => openOverlay,
|
|
40
|
+
pressKey: () => pressKey,
|
|
31
41
|
render: () => render,
|
|
42
|
+
renderComponent: () => renderComponent,
|
|
32
43
|
renderOnce: () => renderOnce,
|
|
33
44
|
renderServerThenHydrate: () => renderServerThenHydrate,
|
|
34
|
-
|
|
45
|
+
trigger: () => trigger,
|
|
46
|
+
waitFor: () => waitFor,
|
|
47
|
+
waitForTransition: () => waitForTransition
|
|
35
48
|
});
|
|
36
49
|
module.exports = __toCommonJS(testing_exports);
|
|
37
50
|
|
|
38
51
|
// ../core/src/identity.ts
|
|
39
52
|
var _counter = 0;
|
|
53
|
+
function nextId() {
|
|
54
|
+
return ++_counter;
|
|
55
|
+
}
|
|
40
56
|
function resetIdCounter() {
|
|
41
57
|
_counter = 0;
|
|
42
58
|
}
|
|
59
|
+
function createNodeId(value) {
|
|
60
|
+
return value;
|
|
61
|
+
}
|
|
62
|
+
function generateNodeId(prefix = "node") {
|
|
63
|
+
return createNodeId(`${prefix}:${nextId()}`);
|
|
64
|
+
}
|
|
43
65
|
|
|
44
66
|
// ../core/src/lifecycle.ts
|
|
45
67
|
var CleanupRegistry = class {
|
|
@@ -784,18 +806,25 @@ function trapFocus(dom, container) {
|
|
|
784
806
|
dom.addEventListener(container, "keydown", onKeydown);
|
|
785
807
|
return () => dom.removeEventListener(container, "keydown", onKeydown);
|
|
786
808
|
}
|
|
809
|
+
var containmentStack = [];
|
|
787
810
|
function containFocus(dom, container) {
|
|
788
811
|
const body = dom.body();
|
|
789
812
|
if (body === null) return () => {
|
|
790
813
|
};
|
|
814
|
+
containmentStack.push(container);
|
|
791
815
|
const onFocusIn = (event) => {
|
|
816
|
+
if (containmentStack[containmentStack.length - 1] !== container) return;
|
|
792
817
|
const target = event.target;
|
|
793
818
|
if (target !== null && !dom.contains(container, target)) {
|
|
794
819
|
focusFirst(dom, container);
|
|
795
820
|
}
|
|
796
821
|
};
|
|
797
822
|
dom.addEventListener(body, "focusin", onFocusIn);
|
|
798
|
-
return () =>
|
|
823
|
+
return () => {
|
|
824
|
+
dom.removeEventListener(body, "focusin", onFocusIn);
|
|
825
|
+
const index = containmentStack.lastIndexOf(container);
|
|
826
|
+
if (index !== -1) containmentStack.splice(index, 1);
|
|
827
|
+
};
|
|
799
828
|
}
|
|
800
829
|
function onEscape(dom, target, handler) {
|
|
801
830
|
const onKeydown = (event) => {
|
|
@@ -804,6 +833,33 @@ function onEscape(dom, target, handler) {
|
|
|
804
833
|
dom.addEventListener(target, "keydown", onKeydown);
|
|
805
834
|
return () => dom.removeEventListener(target, "keydown", onKeydown);
|
|
806
835
|
}
|
|
836
|
+
function rovingMenu(dom, container, selector = FOCUSABLE_SELECTOR) {
|
|
837
|
+
const onKeydown = (event) => {
|
|
838
|
+
const key = event.key;
|
|
839
|
+
const isActivate = key === "Enter" || key === " " || key === "Spacebar";
|
|
840
|
+
const isMove = key === "ArrowDown" || key === "ArrowUp" || key === "Home" || key === "End";
|
|
841
|
+
if (!isActivate && !isMove) return;
|
|
842
|
+
const items = getFocusable(dom, container, selector);
|
|
843
|
+
if (items.length === 0) return;
|
|
844
|
+
const active = dom.activeElement();
|
|
845
|
+
const index = active === null ? -1 : items.indexOf(active);
|
|
846
|
+
if (isActivate) {
|
|
847
|
+
if (index < 0) return;
|
|
848
|
+
event.preventDefault();
|
|
849
|
+
items[index].click?.();
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
event.preventDefault();
|
|
853
|
+
let next;
|
|
854
|
+
if (key === "Home") next = 0;
|
|
855
|
+
else if (key === "End") next = items.length - 1;
|
|
856
|
+
else if (key === "ArrowDown") next = index < 0 ? 0 : (index + 1) % items.length;
|
|
857
|
+
else next = index <= 0 ? items.length - 1 : index - 1;
|
|
858
|
+
dom.focus(items[next]);
|
|
859
|
+
};
|
|
860
|
+
dom.addEventListener(container, "keydown", onKeydown);
|
|
861
|
+
return () => dom.removeEventListener(container, "keydown", onKeydown);
|
|
862
|
+
}
|
|
807
863
|
|
|
808
864
|
// ../renderer/src/render-context.ts
|
|
809
865
|
function createRenderContext(dom, graph, container, hydrationDiagnostics, staticHTML) {
|
|
@@ -1015,7 +1071,7 @@ function patchNode(ctx, graphNode, propKey, newValue) {
|
|
|
1015
1071
|
}
|
|
1016
1072
|
|
|
1017
1073
|
// ../renderer/src/reconciliation.ts
|
|
1018
|
-
function reconcileChildren(ctx, parentDom, oldInstances, newNodes, mountFn) {
|
|
1074
|
+
function reconcileChildren(ctx, parentDom, oldInstances, newNodes, mountFn, hooks) {
|
|
1019
1075
|
const oldByKey = /* @__PURE__ */ new Map();
|
|
1020
1076
|
for (const inst of oldInstances) {
|
|
1021
1077
|
const key = inst.graphNode.key ?? inst.graphNode.id;
|
|
@@ -1036,28 +1092,33 @@ function reconcileChildren(ctx, parentDom, oldInstances, newNodes, mountFn) {
|
|
|
1036
1092
|
}
|
|
1037
1093
|
newInstances.push(existing);
|
|
1038
1094
|
} else {
|
|
1039
|
-
const
|
|
1040
|
-
|
|
1095
|
+
const reclaimed = hooks?.takeLeaving(key);
|
|
1096
|
+
if (reclaimed !== void 0) {
|
|
1097
|
+
patchExistingInstance(ctx, reclaimed, newNode);
|
|
1098
|
+
reconcileItemChildren(ctx, reclaimed, newNode, mountFn);
|
|
1099
|
+
hooks?.onEnter(reclaimed);
|
|
1100
|
+
newInstances.push(reclaimed);
|
|
1101
|
+
} else {
|
|
1102
|
+
const inst = mountFn(newNode, parentDom);
|
|
1103
|
+
hooks?.onEnter(inst);
|
|
1104
|
+
newInstances.push(inst);
|
|
1105
|
+
}
|
|
1041
1106
|
}
|
|
1042
1107
|
}
|
|
1043
1108
|
const removed = [];
|
|
1044
1109
|
for (const inst of oldInstances) {
|
|
1045
1110
|
const key = inst.graphNode.key ?? inst.graphNode.id;
|
|
1046
|
-
if (
|
|
1047
|
-
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
for (const inst of removed) {
|
|
1111
|
+
if (usedKeys.has(key)) continue;
|
|
1112
|
+
if (hooks !== void 0 && hooks.beginLeave(inst)) continue;
|
|
1051
1113
|
const parent = ctx.dom.parentNode(inst.domNode);
|
|
1052
|
-
if (parent !== null)
|
|
1053
|
-
ctx.dom.removeChild(parent, inst.domNode);
|
|
1054
|
-
}
|
|
1114
|
+
if (parent !== null) ctx.dom.removeChild(parent, inst.domNode);
|
|
1055
1115
|
inst.dispose();
|
|
1116
|
+
removed.push(inst);
|
|
1056
1117
|
}
|
|
1057
1118
|
reorderDom(ctx, parentDom, newInstances);
|
|
1058
1119
|
return { instances: newInstances, removed };
|
|
1059
1120
|
}
|
|
1060
|
-
function reconcileChildrenByPlan(ctx, parentDom, oldInstances, plan, mountFn) {
|
|
1121
|
+
function reconcileChildrenByPlan(ctx, parentDom, oldInstances, plan, mountFn, hooks) {
|
|
1061
1122
|
const oldByKey = /* @__PURE__ */ new Map();
|
|
1062
1123
|
for (const inst of oldInstances) {
|
|
1063
1124
|
oldByKey.set(inst.graphNode.key ?? inst.graphNode.id, inst);
|
|
@@ -1084,21 +1145,34 @@ function reconcileChildrenByPlan(ctx, parentDom, oldInstances, plan, mountFn) {
|
|
|
1084
1145
|
}
|
|
1085
1146
|
newInstances.push(existing);
|
|
1086
1147
|
} else {
|
|
1087
|
-
const
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1148
|
+
const reclaimed = hooks?.takeLeaving(entry.key);
|
|
1149
|
+
if (reclaimed !== void 0) {
|
|
1150
|
+
const freshNode = entry.build();
|
|
1151
|
+
built.push(freshNode);
|
|
1152
|
+
patchExistingInstance(ctx, reclaimed, freshNode);
|
|
1153
|
+
reconcileItemChildren(ctx, reclaimed, freshNode, mountFn);
|
|
1154
|
+
reclaimed.graphNode.setProp("_sig", freshNode.getProp("_sig"));
|
|
1155
|
+
reclaimed.graphNode.setProp("_item", entry.item);
|
|
1156
|
+
hooks?.onEnter(reclaimed);
|
|
1157
|
+
newInstances.push(reclaimed);
|
|
1158
|
+
} else {
|
|
1159
|
+
const freshNode = entry.build();
|
|
1160
|
+
built.push(freshNode);
|
|
1161
|
+
const inst = mountFn(freshNode, parentDom);
|
|
1162
|
+
hooks?.onEnter(inst);
|
|
1163
|
+
newInstances.push(inst);
|
|
1164
|
+
}
|
|
1091
1165
|
}
|
|
1092
1166
|
}
|
|
1093
1167
|
const removed = [];
|
|
1094
1168
|
for (const inst of oldInstances) {
|
|
1095
1169
|
const key = inst.graphNode.key ?? inst.graphNode.id;
|
|
1096
|
-
if (
|
|
1097
|
-
|
|
1098
|
-
for (const inst of removed) {
|
|
1170
|
+
if (usedKeys.has(key)) continue;
|
|
1171
|
+
if (hooks !== void 0 && hooks.beginLeave(inst)) continue;
|
|
1099
1172
|
const parent = ctx.dom.parentNode(inst.domNode);
|
|
1100
1173
|
if (parent !== null) ctx.dom.removeChild(parent, inst.domNode);
|
|
1101
1174
|
inst.dispose();
|
|
1175
|
+
removed.push(inst);
|
|
1102
1176
|
}
|
|
1103
1177
|
reorderDomMinimal(ctx, parentDom, oldInstances, newInstances);
|
|
1104
1178
|
return { instances: newInstances, removed, built };
|
|
@@ -1224,6 +1298,176 @@ function patchExistingInstance(ctx, instance, newNode) {
|
|
|
1224
1298
|
}
|
|
1225
1299
|
}
|
|
1226
1300
|
|
|
1301
|
+
// ../renderer/src/transition.ts
|
|
1302
|
+
function getResolvedTransition(graph, nodeId) {
|
|
1303
|
+
const fn = graph.getHandler(`__transition__${nodeId}`);
|
|
1304
|
+
return fn === void 0 ? void 0 : fn();
|
|
1305
|
+
}
|
|
1306
|
+
function host() {
|
|
1307
|
+
return globalThis;
|
|
1308
|
+
}
|
|
1309
|
+
function nextFrame(cb) {
|
|
1310
|
+
const h = host();
|
|
1311
|
+
const raf = h.requestAnimationFrame;
|
|
1312
|
+
if (typeof raf === "function") {
|
|
1313
|
+
raf(() => raf(cb));
|
|
1314
|
+
} else {
|
|
1315
|
+
h.setTimeout(cb, 0);
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
function splitClass(value) {
|
|
1319
|
+
if (value === null) return [];
|
|
1320
|
+
const out = [];
|
|
1321
|
+
for (const t of value.split(/\s+/)) if (t.length > 0) out.push(t);
|
|
1322
|
+
return out;
|
|
1323
|
+
}
|
|
1324
|
+
function addClasses(dom, el, classes2) {
|
|
1325
|
+
if (classes2.length === 0) return;
|
|
1326
|
+
const current = splitClass(dom.getAttribute(el, "class"));
|
|
1327
|
+
let changed = false;
|
|
1328
|
+
for (const c of classes2) {
|
|
1329
|
+
if (!current.includes(c)) {
|
|
1330
|
+
current.push(c);
|
|
1331
|
+
changed = true;
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
if (changed) dom.setAttribute(el, "class", current.join(" "));
|
|
1335
|
+
}
|
|
1336
|
+
function removeClasses(dom, el, classes2) {
|
|
1337
|
+
if (classes2.length === 0) return;
|
|
1338
|
+
const current = splitClass(dom.getAttribute(el, "class"));
|
|
1339
|
+
const next = current.filter((c) => !classes2.includes(c));
|
|
1340
|
+
if (next.length !== current.length) {
|
|
1341
|
+
if (next.length === 0) dom.removeAttribute(el, "class");
|
|
1342
|
+
else dom.setAttribute(el, "class", next.join(" "));
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
function startRun(dom, el, active, from, to, duration, onDone) {
|
|
1346
|
+
const h = host();
|
|
1347
|
+
let finished = false;
|
|
1348
|
+
let timer = null;
|
|
1349
|
+
const onEvent = (e) => {
|
|
1350
|
+
if (e.target !== el) return;
|
|
1351
|
+
finish();
|
|
1352
|
+
};
|
|
1353
|
+
const detach = () => {
|
|
1354
|
+
dom.removeEventListener(el, "transitionend", onEvent);
|
|
1355
|
+
dom.removeEventListener(el, "animationend", onEvent);
|
|
1356
|
+
if (timer !== null) {
|
|
1357
|
+
h.clearTimeout(timer);
|
|
1358
|
+
timer = null;
|
|
1359
|
+
}
|
|
1360
|
+
};
|
|
1361
|
+
const finish = () => {
|
|
1362
|
+
if (finished) return;
|
|
1363
|
+
finished = true;
|
|
1364
|
+
detach();
|
|
1365
|
+
removeClasses(dom, el, active);
|
|
1366
|
+
removeClasses(dom, el, to);
|
|
1367
|
+
removeClasses(dom, el, from);
|
|
1368
|
+
onDone();
|
|
1369
|
+
};
|
|
1370
|
+
addClasses(dom, el, from);
|
|
1371
|
+
addClasses(dom, el, active);
|
|
1372
|
+
dom.addEventListener(el, "transitionend", onEvent);
|
|
1373
|
+
dom.addEventListener(el, "animationend", onEvent);
|
|
1374
|
+
timer = h.setTimeout(finish, duration);
|
|
1375
|
+
nextFrame(() => {
|
|
1376
|
+
if (finished) return;
|
|
1377
|
+
removeClasses(dom, el, from);
|
|
1378
|
+
addClasses(dom, el, to);
|
|
1379
|
+
});
|
|
1380
|
+
return {
|
|
1381
|
+
cancel: () => {
|
|
1382
|
+
if (finished) return;
|
|
1383
|
+
finished = true;
|
|
1384
|
+
detach();
|
|
1385
|
+
removeClasses(dom, el, active);
|
|
1386
|
+
removeClasses(dom, el, to);
|
|
1387
|
+
removeClasses(dom, el, from);
|
|
1388
|
+
}
|
|
1389
|
+
};
|
|
1390
|
+
}
|
|
1391
|
+
var TransitionController = class {
|
|
1392
|
+
constructor(dom, graph, finalize) {
|
|
1393
|
+
this.dom = dom;
|
|
1394
|
+
this.graph = graph;
|
|
1395
|
+
this.finalize = finalize;
|
|
1396
|
+
}
|
|
1397
|
+
leaving = /* @__PURE__ */ new Map();
|
|
1398
|
+
/** True only in a real DOM environment (browser). */
|
|
1399
|
+
get browser() {
|
|
1400
|
+
return this.dom.body() !== null;
|
|
1401
|
+
}
|
|
1402
|
+
keyOf(inst) {
|
|
1403
|
+
return inst.graphNode.key ?? inst.graphNode.id;
|
|
1404
|
+
}
|
|
1405
|
+
resolved(node) {
|
|
1406
|
+
return getResolvedTransition(this.graph, node.id);
|
|
1407
|
+
}
|
|
1408
|
+
/** Run the enter animation for `inst` if it carries a transition (browser only). */
|
|
1409
|
+
enter(inst) {
|
|
1410
|
+
if (!this.browser) return;
|
|
1411
|
+
const rt = this.resolved(inst.graphNode);
|
|
1412
|
+
if (rt === void 0) return;
|
|
1413
|
+
const el = inst.domNode;
|
|
1414
|
+
if (!this.dom.isElement(el)) return;
|
|
1415
|
+
startRun(this.dom, el, rt.enterActive, rt.enterFrom, rt.enterTo, rt.duration, () => {
|
|
1416
|
+
});
|
|
1417
|
+
}
|
|
1418
|
+
/**
|
|
1419
|
+
* Play `appear` for any initial child that opted into it (fresh browser mount
|
|
1420
|
+
* only — hydration must never animate appear, §22, and this is called only on
|
|
1421
|
+
* the mount path).
|
|
1422
|
+
*/
|
|
1423
|
+
appear(children) {
|
|
1424
|
+
if (!this.browser) return;
|
|
1425
|
+
for (const child of children) {
|
|
1426
|
+
const rt = this.resolved(child.graphNode);
|
|
1427
|
+
if (rt !== void 0 && rt.appear) this.enter(child);
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
hooks() {
|
|
1431
|
+
return {
|
|
1432
|
+
takeLeaving: (key) => {
|
|
1433
|
+
const entry = this.leaving.get(key);
|
|
1434
|
+
if (entry === void 0) return void 0;
|
|
1435
|
+
entry.run.cancel();
|
|
1436
|
+
this.leaving.delete(key);
|
|
1437
|
+
return entry.inst;
|
|
1438
|
+
},
|
|
1439
|
+
beginLeave: (inst) => {
|
|
1440
|
+
if (!this.browser) return false;
|
|
1441
|
+
const rt = this.resolved(inst.graphNode);
|
|
1442
|
+
if (rt === void 0) return false;
|
|
1443
|
+
const el = inst.domNode;
|
|
1444
|
+
if (!this.dom.isElement(el)) return false;
|
|
1445
|
+
const key = this.keyOf(inst);
|
|
1446
|
+
const prior = this.leaving.get(key);
|
|
1447
|
+
if (prior !== void 0) prior.run.cancel();
|
|
1448
|
+
const run = startRun(
|
|
1449
|
+
this.dom,
|
|
1450
|
+
el,
|
|
1451
|
+
rt.leaveActive,
|
|
1452
|
+
rt.leaveFrom,
|
|
1453
|
+
rt.leaveTo,
|
|
1454
|
+
rt.duration,
|
|
1455
|
+
() => {
|
|
1456
|
+
const current = this.leaving.get(key);
|
|
1457
|
+
if (current !== void 0 && current.run === run) {
|
|
1458
|
+
this.leaving.delete(key);
|
|
1459
|
+
this.finalize(inst);
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
);
|
|
1463
|
+
this.leaving.set(key, { inst, run });
|
|
1464
|
+
return true;
|
|
1465
|
+
},
|
|
1466
|
+
onEnter: (inst) => this.enter(inst)
|
|
1467
|
+
};
|
|
1468
|
+
}
|
|
1469
|
+
};
|
|
1470
|
+
|
|
1227
1471
|
// ../renderer/src/mount.ts
|
|
1228
1472
|
var SKIP_PROP_KEYS = /* @__PURE__ */ new Set([
|
|
1229
1473
|
"text",
|
|
@@ -1376,7 +1620,7 @@ function mountNode(ctx, graphNode, parentDom) {
|
|
|
1376
1620
|
instance2.addChild(childInstance);
|
|
1377
1621
|
}
|
|
1378
1622
|
dom.appendChild(parentDom, el2);
|
|
1379
|
-
wireReactiveList(ctx, graphNode, instance2, el2);
|
|
1623
|
+
wireReactiveList(ctx, graphNode, instance2, el2, true);
|
|
1380
1624
|
return instance2;
|
|
1381
1625
|
}
|
|
1382
1626
|
if (graphNode.type === "portal") {
|
|
@@ -1420,6 +1664,7 @@ function mountNode(ctx, graphNode, parentDom) {
|
|
|
1420
1664
|
instance.addChild(childInstance);
|
|
1421
1665
|
}
|
|
1422
1666
|
dom.appendChild(parentDom, el);
|
|
1667
|
+
if (graphNode.type === "component") wireComponentBehavior(ctx, graphNode, instance);
|
|
1423
1668
|
return instance;
|
|
1424
1669
|
}
|
|
1425
1670
|
function textUpdate(dom, el, textNode) {
|
|
@@ -1484,32 +1729,42 @@ function wireSignalBindings(ctx, graphNode, instance, onUpdate) {
|
|
|
1484
1729
|
instance.trackCleanup(unsub);
|
|
1485
1730
|
}
|
|
1486
1731
|
}
|
|
1487
|
-
function wireReactiveList(ctx, graphNode, instance, el) {
|
|
1732
|
+
function wireReactiveList(ctx, graphNode, instance, el, runAppear = false) {
|
|
1488
1733
|
const plan = ctx.graph.getHandler(`__listplan__${graphNode.id}`);
|
|
1489
1734
|
const build = ctx.graph.getHandler(`__listbuild__${graphNode.id}`);
|
|
1490
1735
|
if (plan === void 0 && build === void 0) return;
|
|
1736
|
+
const controller = new TransitionController(ctx.dom, ctx.graph, (leaving) => {
|
|
1737
|
+
const parent = ctx.dom.parentNode(leaving.domNode);
|
|
1738
|
+
if (parent !== null) ctx.dom.removeChild(parent, leaving.domNode);
|
|
1739
|
+
leaving.dispose();
|
|
1740
|
+
forgetInstance(ctx, leaving);
|
|
1741
|
+
ctx.graph.detachNode(leaving.graphNode);
|
|
1742
|
+
});
|
|
1743
|
+
const hooks = controller.hooks();
|
|
1744
|
+
if (runAppear) controller.appear(instance.children);
|
|
1491
1745
|
for (const stateRef of graphNode.stateRefs) {
|
|
1492
1746
|
if (stateRef.propKey !== "items") continue;
|
|
1493
1747
|
const sig = ctx.graph.getHandler(`__signal__${stateRef.signalId}`);
|
|
1494
1748
|
if (sig === void 0 || typeof sig.subscribe !== "function") continue;
|
|
1495
1749
|
const unsub = sig.subscribe((value) => {
|
|
1496
1750
|
if (plan !== void 0) {
|
|
1497
|
-
reconcileReactiveListByPlan(ctx, graphNode, instance, el, plan(value));
|
|
1751
|
+
reconcileReactiveListByPlan(ctx, graphNode, instance, el, plan(value), hooks);
|
|
1498
1752
|
} else {
|
|
1499
|
-
reconcileReactiveList(ctx, graphNode, instance, el, build(value));
|
|
1753
|
+
reconcileReactiveList(ctx, graphNode, instance, el, build(value), hooks);
|
|
1500
1754
|
}
|
|
1501
1755
|
});
|
|
1502
1756
|
instance.trackCleanup(unsub);
|
|
1503
1757
|
}
|
|
1504
1758
|
}
|
|
1505
|
-
function reconcileReactiveListByPlan(ctx, listNode, listInstance, listEl, plan) {
|
|
1759
|
+
function reconcileReactiveListByPlan(ctx, listNode, listInstance, listEl, plan, hooks) {
|
|
1506
1760
|
const oldInstances = [...listInstance.children];
|
|
1507
1761
|
const result = reconcileChildrenByPlan(
|
|
1508
1762
|
ctx,
|
|
1509
1763
|
listEl,
|
|
1510
1764
|
oldInstances,
|
|
1511
1765
|
plan,
|
|
1512
|
-
(node, parent) => mountNode(ctx, node, parent)
|
|
1766
|
+
(node, parent) => mountNode(ctx, node, parent),
|
|
1767
|
+
hooks
|
|
1513
1768
|
);
|
|
1514
1769
|
listInstance.children.length = 0;
|
|
1515
1770
|
for (const inst of result.instances) listInstance.children.push(inst);
|
|
@@ -1524,14 +1779,15 @@ function reconcileReactiveListByPlan(ctx, listNode, listInstance, listEl, plan)
|
|
|
1524
1779
|
for (const child of [...listNode.children]) listNode.removeChild(child);
|
|
1525
1780
|
for (const inst of result.instances) listNode.appendChild(inst.graphNode);
|
|
1526
1781
|
}
|
|
1527
|
-
function reconcileReactiveList(ctx, listNode, listInstance, listEl, newNodes) {
|
|
1782
|
+
function reconcileReactiveList(ctx, listNode, listInstance, listEl, newNodes, hooks) {
|
|
1528
1783
|
const oldInstances = [...listInstance.children];
|
|
1529
1784
|
const result = reconcileChildren(
|
|
1530
1785
|
ctx,
|
|
1531
1786
|
listEl,
|
|
1532
1787
|
oldInstances,
|
|
1533
1788
|
newNodes,
|
|
1534
|
-
(node, parent) => mountNode(ctx, node, parent)
|
|
1789
|
+
(node, parent) => mountNode(ctx, node, parent),
|
|
1790
|
+
hooks
|
|
1535
1791
|
);
|
|
1536
1792
|
listInstance.children.length = 0;
|
|
1537
1793
|
for (const inst of result.instances) listInstance.children.push(inst);
|
|
@@ -1567,11 +1823,14 @@ function wireOverlayBehavior(ctx, graphNode, instance, target) {
|
|
|
1567
1823
|
const onOpenChange = (isOpen) => {
|
|
1568
1824
|
if (isOpen) {
|
|
1569
1825
|
if (desc.restoreFocus) saved = saveFocus(dom);
|
|
1570
|
-
if (desc.takesFocus) focusInitial(dom, target, desc.initialFocusId);
|
|
1571
1826
|
if (desc.modal) {
|
|
1572
1827
|
active.push(trapFocus(dom, target));
|
|
1573
1828
|
active.push(containFocus(dom, target));
|
|
1574
1829
|
}
|
|
1830
|
+
if (desc.menu) {
|
|
1831
|
+
active.push(rovingMenu(dom, target));
|
|
1832
|
+
}
|
|
1833
|
+
if (desc.takesFocus) focusInitial(dom, target, desc.initialFocusId);
|
|
1575
1834
|
if (desc.closeOnEscape && desc.onClose !== void 0) {
|
|
1576
1835
|
active.push(onEscape(dom, target, desc.onClose));
|
|
1577
1836
|
}
|
|
@@ -1588,6 +1847,11 @@ function wireOverlayBehavior(ctx, graphNode, instance, target) {
|
|
|
1588
1847
|
instance.trackCleanup(teardown);
|
|
1589
1848
|
if (openSig.peek() === true) onOpenChange(true);
|
|
1590
1849
|
}
|
|
1850
|
+
function wireComponentBehavior(ctx, graphNode, instance) {
|
|
1851
|
+
const fn = ctx.graph.getHandler(`__component__${graphNode.id}`);
|
|
1852
|
+
if (fn === void 0) return;
|
|
1853
|
+
for (const cleanup of fn()) instance.trackCleanup(cleanup);
|
|
1854
|
+
}
|
|
1591
1855
|
|
|
1592
1856
|
// ../renderer/src/hydration-diagnostics.ts
|
|
1593
1857
|
function formatHydrationDiagnostic(d) {
|
|
@@ -1712,6 +1976,7 @@ function hydrateNode(ctx, graphNode, domNode, path) {
|
|
|
1712
1976
|
return instance;
|
|
1713
1977
|
}
|
|
1714
1978
|
hydrateChildren(ctx, graphNode, instance, domNode, path);
|
|
1979
|
+
if (graphNode.type === "component") wireComponentBehavior(ctx, graphNode, instance);
|
|
1715
1980
|
return instance;
|
|
1716
1981
|
}
|
|
1717
1982
|
}
|
|
@@ -1910,7 +2175,8 @@ function analyzeGraph(graph) {
|
|
|
1910
2175
|
const isList = node.type === "reactive-list";
|
|
1911
2176
|
const isConditional = node.type === "conditional";
|
|
1912
2177
|
const isPortal = node.type === "portal";
|
|
1913
|
-
const
|
|
2178
|
+
const isComponent = node.type === "component";
|
|
2179
|
+
const isStatic = node.stateRefs.length === 0 && !hasEvents && !isList && !isConditional && !isPortal && !isComponent;
|
|
1914
2180
|
const isStaticSubtree = isStatic && allChildrenStatic;
|
|
1915
2181
|
nodes.set(node.id, {
|
|
1916
2182
|
isStatic,
|
|
@@ -2241,6 +2507,37 @@ async function waitFor(check, options = {}) {
|
|
|
2241
2507
|
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
2242
2508
|
}
|
|
2243
2509
|
}
|
|
2510
|
+
function focus(el) {
|
|
2511
|
+
el.focus?.();
|
|
2512
|
+
}
|
|
2513
|
+
function blur(el) {
|
|
2514
|
+
el.blur?.();
|
|
2515
|
+
}
|
|
2516
|
+
function pressKey(key, el = document.activeElement, init = {}) {
|
|
2517
|
+
if (el === null) return;
|
|
2518
|
+
el.dispatchEvent(
|
|
2519
|
+
new KeyboardEvent("keydown", { key, bubbles: true, cancelable: true, ...init })
|
|
2520
|
+
);
|
|
2521
|
+
}
|
|
2522
|
+
function clickOutside(container, target = document.body) {
|
|
2523
|
+
if (container.contains(target)) {
|
|
2524
|
+
throw new Error("[StreetUI Testing] clickOutside: target is inside the container");
|
|
2525
|
+
}
|
|
2526
|
+
target.dispatchEvent(new MouseEvent("mousedown", { bubbles: true, cancelable: true }));
|
|
2527
|
+
target.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true }));
|
|
2528
|
+
}
|
|
2529
|
+
async function openOverlay(open) {
|
|
2530
|
+
open.set(true);
|
|
2531
|
+
await flushUpdates();
|
|
2532
|
+
}
|
|
2533
|
+
async function closeOverlay(open) {
|
|
2534
|
+
open.set(false);
|
|
2535
|
+
await flushUpdates();
|
|
2536
|
+
}
|
|
2537
|
+
async function waitForTransition(el) {
|
|
2538
|
+
el.dispatchEvent(new Event("transitionend", { bubbles: true }));
|
|
2539
|
+
await flushUpdates();
|
|
2540
|
+
}
|
|
2244
2541
|
function findByText(container, text) {
|
|
2245
2542
|
const match = Array.from(container.querySelectorAll("*")).find(
|
|
2246
2543
|
(el) => el.children.length === 0 && (el.textContent?.includes(text) ?? false)
|
|
@@ -2335,21 +2632,1161 @@ function renderServerThenHydrate(build, options = {}) {
|
|
|
2335
2632
|
};
|
|
2336
2633
|
}
|
|
2337
2634
|
|
|
2635
|
+
// ../dsl/src/transition.ts
|
|
2636
|
+
function classes(value) {
|
|
2637
|
+
if (value === void 0) return [];
|
|
2638
|
+
const out = [];
|
|
2639
|
+
for (const token of value.split(/\s+/)) {
|
|
2640
|
+
if (token.length > 0 && !out.includes(token)) out.push(token);
|
|
2641
|
+
}
|
|
2642
|
+
return out;
|
|
2643
|
+
}
|
|
2644
|
+
function merge(a, b) {
|
|
2645
|
+
const out = [...a];
|
|
2646
|
+
for (const token of b) if (!out.includes(token)) out.push(token);
|
|
2647
|
+
return out;
|
|
2648
|
+
}
|
|
2649
|
+
function resolveTransition(config) {
|
|
2650
|
+
const n = config.name;
|
|
2651
|
+
const enterActive = merge(
|
|
2652
|
+
classes(config.enter),
|
|
2653
|
+
classes(config.enterActive ?? (n !== void 0 ? `${n}-enter-active` : void 0))
|
|
2654
|
+
);
|
|
2655
|
+
const leaveActive = merge(
|
|
2656
|
+
classes(config.leave),
|
|
2657
|
+
classes(config.leaveActive ?? (n !== void 0 ? `${n}-leave-active` : void 0))
|
|
2658
|
+
);
|
|
2659
|
+
return {
|
|
2660
|
+
enterActive,
|
|
2661
|
+
enterFrom: classes(config.enterFrom ?? (n !== void 0 ? `${n}-enter-from` : void 0)),
|
|
2662
|
+
enterTo: classes(config.enterTo ?? (n !== void 0 ? `${n}-enter-to` : void 0)),
|
|
2663
|
+
leaveActive,
|
|
2664
|
+
leaveFrom: classes(config.leaveFrom ?? (n !== void 0 ? `${n}-leave-from` : void 0)),
|
|
2665
|
+
leaveTo: classes(config.leaveTo ?? (n !== void 0 ? `${n}-leave-to` : void 0)),
|
|
2666
|
+
appear: config.appear ?? false,
|
|
2667
|
+
duration: config.duration ?? 1e3
|
|
2668
|
+
};
|
|
2669
|
+
}
|
|
2670
|
+
|
|
2671
|
+
// ../state/src/signal.ts
|
|
2672
|
+
var _activeConsumer = null;
|
|
2673
|
+
function withConsumer(consumer, fn) {
|
|
2674
|
+
const prev = _activeConsumer;
|
|
2675
|
+
_activeConsumer = consumer;
|
|
2676
|
+
try {
|
|
2677
|
+
return fn();
|
|
2678
|
+
} finally {
|
|
2679
|
+
_activeConsumer = prev;
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
var _batchDepth = 0;
|
|
2683
|
+
var _pendingFlushes = /* @__PURE__ */ new Map();
|
|
2684
|
+
function _enqueueBatchFlush(sig, value) {
|
|
2685
|
+
_pendingFlushes.set(sig, { signal: sig, value });
|
|
2686
|
+
}
|
|
2687
|
+
var Signal = class {
|
|
2688
|
+
_value;
|
|
2689
|
+
_subscribers = /* @__PURE__ */ new Set();
|
|
2690
|
+
_consumers = /* @__PURE__ */ new Set();
|
|
2691
|
+
constructor(initial) {
|
|
2692
|
+
this._value = initial;
|
|
2693
|
+
}
|
|
2694
|
+
get() {
|
|
2695
|
+
if (_activeConsumer !== null) {
|
|
2696
|
+
this._consumers.add(_activeConsumer);
|
|
2697
|
+
_activeConsumer._addSource(this);
|
|
2698
|
+
}
|
|
2699
|
+
return this._value;
|
|
2700
|
+
}
|
|
2701
|
+
peek() {
|
|
2702
|
+
return this._value;
|
|
2703
|
+
}
|
|
2704
|
+
set(value) {
|
|
2705
|
+
if (Object.is(this._value, value)) return;
|
|
2706
|
+
this._value = value;
|
|
2707
|
+
if (_batchDepth > 0) {
|
|
2708
|
+
_enqueueBatchFlush(this, value);
|
|
2709
|
+
} else {
|
|
2710
|
+
this._flush(value);
|
|
2711
|
+
}
|
|
2712
|
+
}
|
|
2713
|
+
update(fn) {
|
|
2714
|
+
this.set(fn(this._value));
|
|
2715
|
+
}
|
|
2716
|
+
subscribe(fn) {
|
|
2717
|
+
this._subscribers.add(fn);
|
|
2718
|
+
return () => {
|
|
2719
|
+
this._subscribers.delete(fn);
|
|
2720
|
+
};
|
|
2721
|
+
}
|
|
2722
|
+
_removeConsumer(consumer) {
|
|
2723
|
+
this._consumers.delete(consumer);
|
|
2724
|
+
}
|
|
2725
|
+
/**
|
|
2726
|
+
* Called by the batch machinery after the batch has completed.
|
|
2727
|
+
* Notifies subscribers with the final coalesced value.
|
|
2728
|
+
*/
|
|
2729
|
+
_flushBatch(value) {
|
|
2730
|
+
this._flush(value);
|
|
2731
|
+
}
|
|
2732
|
+
_flush(value) {
|
|
2733
|
+
for (const sub of [...this._subscribers]) sub(value);
|
|
2734
|
+
for (const consumer of [...this._consumers]) consumer._invalidate();
|
|
2735
|
+
}
|
|
2736
|
+
/**
|
|
2737
|
+
* @internal DevTools inspection only. The number of live observers
|
|
2738
|
+
* (direct subscribers plus derived/effect consumers). Read-only; never
|
|
2739
|
+
* mutates reactive state.
|
|
2740
|
+
*/
|
|
2741
|
+
_observerCount() {
|
|
2742
|
+
return this._subscribers.size + this._consumers.size;
|
|
2743
|
+
}
|
|
2744
|
+
};
|
|
2745
|
+
var DerivedSignal = class {
|
|
2746
|
+
_value = void 0;
|
|
2747
|
+
_dirty = true;
|
|
2748
|
+
_disposed = false;
|
|
2749
|
+
_fn;
|
|
2750
|
+
_subscribers = /* @__PURE__ */ new Set();
|
|
2751
|
+
/** All upstream sources this derived currently reads from. */
|
|
2752
|
+
_sources = /* @__PURE__ */ new Set();
|
|
2753
|
+
/** Downstream consumers that depend on this derived. */
|
|
2754
|
+
_consumers = /* @__PURE__ */ new Set();
|
|
2755
|
+
constructor(fn) {
|
|
2756
|
+
this._fn = fn;
|
|
2757
|
+
}
|
|
2758
|
+
get() {
|
|
2759
|
+
if (_activeConsumer !== null) {
|
|
2760
|
+
this._consumers.add(_activeConsumer);
|
|
2761
|
+
_activeConsumer._addSource(this);
|
|
2762
|
+
}
|
|
2763
|
+
if (this._dirty) this._recompute();
|
|
2764
|
+
return this._value;
|
|
2765
|
+
}
|
|
2766
|
+
peek() {
|
|
2767
|
+
if (this._dirty) this._recompute();
|
|
2768
|
+
return this._value;
|
|
2769
|
+
}
|
|
2770
|
+
subscribe(fn) {
|
|
2771
|
+
if (this._dirty) this._recompute();
|
|
2772
|
+
this._subscribers.add(fn);
|
|
2773
|
+
return () => {
|
|
2774
|
+
this._subscribers.delete(fn);
|
|
2775
|
+
};
|
|
2776
|
+
}
|
|
2777
|
+
_addSource(src) {
|
|
2778
|
+
this._sources.add(src);
|
|
2779
|
+
}
|
|
2780
|
+
_removeConsumer(consumer) {
|
|
2781
|
+
this._consumers.delete(consumer);
|
|
2782
|
+
}
|
|
2783
|
+
_invalidate() {
|
|
2784
|
+
if (this._disposed) return;
|
|
2785
|
+
this._dirty = true;
|
|
2786
|
+
const newVal = this.peek();
|
|
2787
|
+
for (const sub of [...this._subscribers]) sub(newVal);
|
|
2788
|
+
for (const consumer of [...this._consumers]) consumer._invalidate();
|
|
2789
|
+
}
|
|
2790
|
+
_recompute() {
|
|
2791
|
+
for (const src of this._sources) src._removeConsumer(this);
|
|
2792
|
+
this._sources.clear();
|
|
2793
|
+
this._value = withConsumer(this, this._fn);
|
|
2794
|
+
this._dirty = false;
|
|
2795
|
+
}
|
|
2796
|
+
dispose() {
|
|
2797
|
+
this._disposed = true;
|
|
2798
|
+
for (const src of this._sources) src._removeConsumer(this);
|
|
2799
|
+
this._sources.clear();
|
|
2800
|
+
this._subscribers.clear();
|
|
2801
|
+
this._consumers.clear();
|
|
2802
|
+
}
|
|
2803
|
+
/**
|
|
2804
|
+
* @internal DevTools inspection only. Live observers (subscribers plus
|
|
2805
|
+
* downstream consumers). Read-only.
|
|
2806
|
+
*/
|
|
2807
|
+
_observerCount() {
|
|
2808
|
+
return this._subscribers.size + this._consumers.size;
|
|
2809
|
+
}
|
|
2810
|
+
};
|
|
2811
|
+
var Effect = class {
|
|
2812
|
+
_fn;
|
|
2813
|
+
_cleanup = void 0;
|
|
2814
|
+
_disposed = false;
|
|
2815
|
+
_sources = /* @__PURE__ */ new Set();
|
|
2816
|
+
constructor(fn) {
|
|
2817
|
+
this._fn = fn;
|
|
2818
|
+
this._run();
|
|
2819
|
+
}
|
|
2820
|
+
_addSource(src) {
|
|
2821
|
+
this._sources.add(src);
|
|
2822
|
+
}
|
|
2823
|
+
_invalidate() {
|
|
2824
|
+
if (this._disposed) return;
|
|
2825
|
+
this._run();
|
|
2826
|
+
}
|
|
2827
|
+
_run() {
|
|
2828
|
+
for (const src of this._sources) src._removeConsumer(this);
|
|
2829
|
+
this._sources.clear();
|
|
2830
|
+
if (typeof this._cleanup === "function") this._cleanup();
|
|
2831
|
+
const result = withConsumer(this, this._fn);
|
|
2832
|
+
this._cleanup = typeof result === "function" ? result : void 0;
|
|
2833
|
+
}
|
|
2834
|
+
dispose() {
|
|
2835
|
+
this._disposed = true;
|
|
2836
|
+
for (const src of this._sources) src._removeConsumer(this);
|
|
2837
|
+
this._sources.clear();
|
|
2838
|
+
if (typeof this._cleanup === "function") this._cleanup();
|
|
2839
|
+
this._cleanup = void 0;
|
|
2840
|
+
}
|
|
2841
|
+
};
|
|
2842
|
+
function signal(initial) {
|
|
2843
|
+
return new Signal(initial);
|
|
2844
|
+
}
|
|
2845
|
+
function derived(fn) {
|
|
2846
|
+
return new DerivedSignal(fn);
|
|
2847
|
+
}
|
|
2848
|
+
function effect(fn) {
|
|
2849
|
+
const e = new Effect(fn);
|
|
2850
|
+
return () => e.dispose();
|
|
2851
|
+
}
|
|
2852
|
+
|
|
2853
|
+
// ../dsl/src/builders.ts
|
|
2854
|
+
function isSignal(v) {
|
|
2855
|
+
return v !== null && typeof v === "object" && typeof v["get"] === "function" && typeof v["subscribe"] === "function";
|
|
2856
|
+
}
|
|
2857
|
+
function bindValue(graph, node, propKey, value) {
|
|
2858
|
+
if (isSignal(value)) {
|
|
2859
|
+
const signalId = `${node.id}:${propKey}`;
|
|
2860
|
+
node.stateRefs.push({ signalId, propKey });
|
|
2861
|
+
graph.registerHandler(`__signal__${signalId}`, value);
|
|
2862
|
+
return value.peek();
|
|
2863
|
+
}
|
|
2864
|
+
return value;
|
|
2865
|
+
}
|
|
2866
|
+
function applyA11yProps(props, options) {
|
|
2867
|
+
if (options.role !== void 0) props["role"] = options.role;
|
|
2868
|
+
if (options.tabIndex !== void 0) props["tabindex"] = String(options.tabIndex);
|
|
2869
|
+
if (options.ariaLabel !== void 0) props["aria-label"] = options.ariaLabel;
|
|
2870
|
+
if (options.ariaLabelledBy !== void 0) props["aria-labelledby"] = options.ariaLabelledBy;
|
|
2871
|
+
if (options.ariaDescribedBy !== void 0) props["aria-describedby"] = options.ariaDescribedBy;
|
|
2872
|
+
if (options.ariaExpanded !== void 0) props["aria-expanded"] = String(options.ariaExpanded);
|
|
2873
|
+
if (options.ariaControls !== void 0) props["aria-controls"] = options.ariaControls;
|
|
2874
|
+
if (options.ariaHidden !== void 0) props["aria-hidden"] = String(options.ariaHidden);
|
|
2875
|
+
if (options.ariaLive !== void 0) props["aria-live"] = options.ariaLive;
|
|
2876
|
+
if (options.ariaCurrent !== void 0) props["aria-current"] = String(options.ariaCurrent);
|
|
2877
|
+
if (options.ariaInvalid !== void 0) props["aria-invalid"] = String(options.ariaInvalid);
|
|
2878
|
+
if (options.ariaRequired !== void 0) props["aria-required"] = String(options.ariaRequired);
|
|
2879
|
+
if (options.ariaModal !== void 0) props["aria-modal"] = String(options.ariaModal);
|
|
2880
|
+
if (options.ariaOwns !== void 0) props["aria-owns"] = options.ariaOwns;
|
|
2881
|
+
if (options.ariaActiveDescendant !== void 0) props["aria-activedescendant"] = options.ariaActiveDescendant;
|
|
2882
|
+
if (options.ariaHasPopup !== void 0) props["aria-haspopup"] = String(options.ariaHasPopup);
|
|
2883
|
+
if (options.ariaSelected !== void 0) props["aria-selected"] = String(options.ariaSelected);
|
|
2884
|
+
}
|
|
2885
|
+
function registerTransition(graph, node, config) {
|
|
2886
|
+
if (config === void 0) return;
|
|
2887
|
+
const resolved = resolveTransition(config);
|
|
2888
|
+
graph.registerHandler(
|
|
2889
|
+
`__transition__${node.id}`,
|
|
2890
|
+
() => resolved
|
|
2891
|
+
);
|
|
2892
|
+
}
|
|
2893
|
+
function containerProps(options) {
|
|
2894
|
+
const props = {};
|
|
2895
|
+
if (options.class !== void 0) props["class"] = options.class;
|
|
2896
|
+
if (options.id !== void 0) props["id"] = options.id;
|
|
2897
|
+
if (options.key !== void 0) props["key"] = options.key;
|
|
2898
|
+
applyA11yProps(props, options);
|
|
2899
|
+
return props;
|
|
2900
|
+
}
|
|
2901
|
+
function itemIdentity(item, index) {
|
|
2902
|
+
if (item !== null && typeof item === "object") {
|
|
2903
|
+
const obj = item;
|
|
2904
|
+
if ("id" in obj) return `id:${String(obj["id"])}`;
|
|
2905
|
+
if ("key" in obj) return `key:${String(obj["key"])}`;
|
|
2906
|
+
return `idx:${index}`;
|
|
2907
|
+
}
|
|
2908
|
+
return `val:${String(item)}`;
|
|
2909
|
+
}
|
|
2910
|
+
function itemValueSignature(item) {
|
|
2911
|
+
try {
|
|
2912
|
+
return JSON.stringify(item) ?? String(item);
|
|
2913
|
+
} catch {
|
|
2914
|
+
return String(item);
|
|
2915
|
+
}
|
|
2916
|
+
}
|
|
2917
|
+
function reactiveListItemSignature(item) {
|
|
2918
|
+
return itemValueSignature(item);
|
|
2919
|
+
}
|
|
2920
|
+
function reactiveListItemKey(item, index) {
|
|
2921
|
+
return itemIdentity(item, index);
|
|
2922
|
+
}
|
|
2923
|
+
var OVERLAY_KINDS = {
|
|
2924
|
+
dialog: {
|
|
2925
|
+
role: "dialog",
|
|
2926
|
+
modal: true,
|
|
2927
|
+
takesFocus: true,
|
|
2928
|
+
ariaModal: true,
|
|
2929
|
+
defaultCloseOnEscape: true,
|
|
2930
|
+
defaultRestoreFocus: true
|
|
2931
|
+
},
|
|
2932
|
+
popover: {
|
|
2933
|
+
role: "dialog",
|
|
2934
|
+
modal: false,
|
|
2935
|
+
takesFocus: true,
|
|
2936
|
+
ariaModal: false,
|
|
2937
|
+
defaultCloseOnEscape: true,
|
|
2938
|
+
defaultRestoreFocus: true
|
|
2939
|
+
},
|
|
2940
|
+
tooltip: {
|
|
2941
|
+
role: "tooltip",
|
|
2942
|
+
modal: false,
|
|
2943
|
+
takesFocus: false,
|
|
2944
|
+
ariaModal: false,
|
|
2945
|
+
defaultCloseOnEscape: false,
|
|
2946
|
+
defaultRestoreFocus: false
|
|
2947
|
+
},
|
|
2948
|
+
dropdown: {
|
|
2949
|
+
role: "menu",
|
|
2950
|
+
modal: false,
|
|
2951
|
+
takesFocus: true,
|
|
2952
|
+
menu: true,
|
|
2953
|
+
ariaModal: false,
|
|
2954
|
+
defaultCloseOnEscape: true,
|
|
2955
|
+
defaultRestoreFocus: true
|
|
2956
|
+
},
|
|
2957
|
+
toast: {
|
|
2958
|
+
role: "status",
|
|
2959
|
+
modal: false,
|
|
2960
|
+
takesFocus: false,
|
|
2961
|
+
ariaModal: false,
|
|
2962
|
+
ariaLive: "polite",
|
|
2963
|
+
defaultCloseOnEscape: false,
|
|
2964
|
+
defaultRestoreFocus: false
|
|
2965
|
+
}
|
|
2966
|
+
};
|
|
2967
|
+
var ContentBuilderBase = class {
|
|
2968
|
+
constructor(_node, _graph) {
|
|
2969
|
+
this._node = _node;
|
|
2970
|
+
this._graph = _graph;
|
|
2971
|
+
}
|
|
2972
|
+
heading(text, options = {}) {
|
|
2973
|
+
const props = { level: options.level ?? 1 };
|
|
2974
|
+
if (options.class !== void 0) props["class"] = options.class;
|
|
2975
|
+
if (options.id !== void 0) props["id"] = options.id;
|
|
2976
|
+
applyA11yProps(props, options);
|
|
2977
|
+
const node = this._graph.createNode("heading", { parent: this._node, props });
|
|
2978
|
+
const resolved = bindValue(this._graph, node, "text", text);
|
|
2979
|
+
node.setProp("text", resolved);
|
|
2980
|
+
}
|
|
2981
|
+
text(content, options = {}) {
|
|
2982
|
+
const props = {};
|
|
2983
|
+
if (options.class !== void 0) props["class"] = options.class;
|
|
2984
|
+
if (options.id !== void 0) props["id"] = options.id;
|
|
2985
|
+
applyA11yProps(props, options);
|
|
2986
|
+
const node = this._graph.createNode("text", { parent: this._node, props });
|
|
2987
|
+
const resolved = bindValue(this._graph, node, "text", content);
|
|
2988
|
+
node.setProp("text", resolved);
|
|
2989
|
+
}
|
|
2990
|
+
button(label, options = {}) {
|
|
2991
|
+
const props = {};
|
|
2992
|
+
if (options.class !== void 0) props["class"] = options.class;
|
|
2993
|
+
if (options.id !== void 0) props["id"] = options.id;
|
|
2994
|
+
applyA11yProps(props, options);
|
|
2995
|
+
const node = this._graph.createNode("button", { parent: this._node, props });
|
|
2996
|
+
const resolved = bindValue(this._graph, node, "label", label);
|
|
2997
|
+
node.setProp("label", resolved);
|
|
2998
|
+
if (options.disabled !== void 0) {
|
|
2999
|
+
const resolvedDisabled = bindValue(this._graph, node, "disabled", options.disabled);
|
|
3000
|
+
node.setProp("disabled", resolvedDisabled);
|
|
3001
|
+
}
|
|
3002
|
+
if (options.onClick !== void 0) {
|
|
3003
|
+
const handlerKey = `click:${node.id}`;
|
|
3004
|
+
this._graph.registerHandler(handlerKey, options.onClick);
|
|
3005
|
+
node.addEvent({ type: "click", handlerKey });
|
|
3006
|
+
}
|
|
3007
|
+
}
|
|
3008
|
+
input(options = {}) {
|
|
3009
|
+
const props = {};
|
|
3010
|
+
props["inputType"] = options.type ?? "text";
|
|
3011
|
+
if (options.placeholder !== void 0) props["placeholder"] = options.placeholder;
|
|
3012
|
+
if (options.class !== void 0) props["class"] = options.class;
|
|
3013
|
+
if (options.id !== void 0) props["id"] = options.id;
|
|
3014
|
+
applyA11yProps(props, options);
|
|
3015
|
+
const nodeOpts = {
|
|
3016
|
+
props,
|
|
3017
|
+
parent: this._node
|
|
3018
|
+
};
|
|
3019
|
+
if (options.id !== void 0) nodeOpts.key = options.id;
|
|
3020
|
+
const node = this._graph.createNode("input", nodeOpts);
|
|
3021
|
+
const bindSignal = options.bind;
|
|
3022
|
+
const valueBindable = bindSignal !== void 0 ? bindSignal : options.value;
|
|
3023
|
+
const inputHandler = bindSignal !== void 0 ? (v) => bindSignal.set(v) : options.onInput;
|
|
3024
|
+
if (valueBindable !== void 0) {
|
|
3025
|
+
const resolved = bindValue(this._graph, node, "value", valueBindable);
|
|
3026
|
+
node.setProp("value", resolved);
|
|
3027
|
+
}
|
|
3028
|
+
if (options.disabled !== void 0) {
|
|
3029
|
+
const resolved = bindValue(this._graph, node, "disabled", options.disabled);
|
|
3030
|
+
node.setProp("disabled", resolved);
|
|
3031
|
+
}
|
|
3032
|
+
if (inputHandler !== void 0) {
|
|
3033
|
+
const handlerKey = `input:${node.id}`;
|
|
3034
|
+
this._graph.registerHandler(handlerKey, inputHandler);
|
|
3035
|
+
node.addEvent({ type: "input", handlerKey });
|
|
3036
|
+
}
|
|
3037
|
+
if (options.onChange !== void 0) {
|
|
3038
|
+
const handlerKey = `change:${node.id}`;
|
|
3039
|
+
this._graph.registerHandler(handlerKey, options.onChange);
|
|
3040
|
+
node.addEvent({ type: "change", handlerKey });
|
|
3041
|
+
}
|
|
3042
|
+
}
|
|
3043
|
+
image(options) {
|
|
3044
|
+
const props = {
|
|
3045
|
+
src: options.src,
|
|
3046
|
+
alt: options.alt
|
|
3047
|
+
};
|
|
3048
|
+
if (options.width !== void 0) props["width"] = options.width;
|
|
3049
|
+
if (options.height !== void 0) props["height"] = options.height;
|
|
3050
|
+
if (options.class !== void 0) props["class"] = options.class;
|
|
3051
|
+
if (options.id !== void 0) props["id"] = options.id;
|
|
3052
|
+
applyA11yProps(props, options);
|
|
3053
|
+
const nodeOpts = {
|
|
3054
|
+
props,
|
|
3055
|
+
parent: this._node
|
|
3056
|
+
};
|
|
3057
|
+
if (options.id !== void 0) nodeOpts.key = options.id;
|
|
3058
|
+
this._graph.createNode("image", nodeOpts);
|
|
3059
|
+
}
|
|
3060
|
+
link(label, options) {
|
|
3061
|
+
const props = {
|
|
3062
|
+
href: options.href,
|
|
3063
|
+
external: options.external ?? false
|
|
3064
|
+
};
|
|
3065
|
+
if (options.class !== void 0) props["class"] = options.class;
|
|
3066
|
+
if (options.id !== void 0) props["id"] = options.id;
|
|
3067
|
+
applyA11yProps(props, options);
|
|
3068
|
+
const node = this._graph.createNode("link", { parent: this._node, props });
|
|
3069
|
+
const resolved = bindValue(this._graph, node, "label", label);
|
|
3070
|
+
node.setProp("label", resolved);
|
|
3071
|
+
if (options.onClick !== void 0) {
|
|
3072
|
+
const handlerKey = `click:${node.id}`;
|
|
3073
|
+
this._graph.registerHandler(handlerKey, options.onClick);
|
|
3074
|
+
node.addEvent({ type: "click", handlerKey });
|
|
3075
|
+
}
|
|
3076
|
+
}
|
|
3077
|
+
};
|
|
3078
|
+
var ContainerBuilderBase = class extends ContentBuilderBase {
|
|
3079
|
+
section(key, builder, options = {}) {
|
|
3080
|
+
const node = this._graph.createNode("section", {
|
|
3081
|
+
key,
|
|
3082
|
+
parent: this._node,
|
|
3083
|
+
props: containerProps(options)
|
|
3084
|
+
});
|
|
3085
|
+
registerTransition(this._graph, node, options.transition);
|
|
3086
|
+
builder(new SectionBuilderImpl(node, this._graph));
|
|
3087
|
+
}
|
|
3088
|
+
container(key, builder, options = {}) {
|
|
3089
|
+
const node = this._graph.createNode("container", {
|
|
3090
|
+
key,
|
|
3091
|
+
parent: this._node,
|
|
3092
|
+
props: containerProps(options)
|
|
3093
|
+
});
|
|
3094
|
+
registerTransition(this._graph, node, options.transition);
|
|
3095
|
+
builder(new ContainerBuilderImpl(node, this._graph));
|
|
3096
|
+
}
|
|
3097
|
+
list(key, builder, options = {}) {
|
|
3098
|
+
const node = this._graph.createNode("list", {
|
|
3099
|
+
key,
|
|
3100
|
+
parent: this._node,
|
|
3101
|
+
props: containerProps(options)
|
|
3102
|
+
});
|
|
3103
|
+
registerTransition(this._graph, node, options.transition);
|
|
3104
|
+
builder(new ListBuilderImpl(node, this._graph));
|
|
3105
|
+
}
|
|
3106
|
+
listOf(key, items, renderItem, options = {}) {
|
|
3107
|
+
const graph = this._graph;
|
|
3108
|
+
const node = graph.createNode("reactive-list", {
|
|
3109
|
+
key,
|
|
3110
|
+
parent: this._node,
|
|
3111
|
+
props: containerProps(options)
|
|
3112
|
+
});
|
|
3113
|
+
registerTransition(graph, node, options.transition);
|
|
3114
|
+
const signalId = `${node.id}:items`;
|
|
3115
|
+
node.stateRefs.push({ signalId, propKey: "items" });
|
|
3116
|
+
graph.registerHandler(`__signal__${signalId}`, items);
|
|
3117
|
+
const buildItem = (item, index) => {
|
|
3118
|
+
const itemKey = reactiveListItemKey(item, index);
|
|
3119
|
+
const itemNode = graph.createNode("list-item", {
|
|
3120
|
+
key: itemKey,
|
|
3121
|
+
// `_item` records the source item *reference* so the reconciler can
|
|
3122
|
+
// short-circuit unchanged rows by identity (no signature hashing); `_sig`
|
|
3123
|
+
// is the content signature used to detect an in-place data change when the
|
|
3124
|
+
// reference differs. Both are internal metadata (leading `_`) and never
|
|
3125
|
+
// reach the DOM.
|
|
3126
|
+
props: {
|
|
3127
|
+
key: itemKey,
|
|
3128
|
+
_sig: reactiveListItemSignature(item),
|
|
3129
|
+
// The item reference is stored as opaque internal metadata (never
|
|
3130
|
+
// rendered); cast through `unknown` since `T` is not a `PropValue`.
|
|
3131
|
+
_item: item
|
|
3132
|
+
}
|
|
3133
|
+
});
|
|
3134
|
+
renderItem(item, index, new ContainerBuilderImpl(itemNode, graph));
|
|
3135
|
+
registerTransition(graph, itemNode, options.itemTransition);
|
|
3136
|
+
return itemNode;
|
|
3137
|
+
};
|
|
3138
|
+
const buildPlan = (raw) => {
|
|
3139
|
+
const arr = Array.isArray(raw) ? raw : [];
|
|
3140
|
+
const plan = new Array(arr.length);
|
|
3141
|
+
for (let i = 0; i < arr.length; i++) {
|
|
3142
|
+
const item = arr[i];
|
|
3143
|
+
const index = i;
|
|
3144
|
+
plan[i] = {
|
|
3145
|
+
key: reactiveListItemKey(item, index),
|
|
3146
|
+
item,
|
|
3147
|
+
sig: () => reactiveListItemSignature(item),
|
|
3148
|
+
build: () => buildItem(item, index)
|
|
3149
|
+
};
|
|
3150
|
+
}
|
|
3151
|
+
return plan;
|
|
3152
|
+
};
|
|
3153
|
+
graph.registerHandler(`__listplan__${node.id}`, buildPlan);
|
|
3154
|
+
const current = isSignal(items) ? items.peek() : items;
|
|
3155
|
+
const initial = Array.isArray(current) ? current : [];
|
|
3156
|
+
initial.forEach((item, i) => {
|
|
3157
|
+
node.appendChild(buildItem(item, i));
|
|
3158
|
+
});
|
|
3159
|
+
}
|
|
3160
|
+
form(key, builder, options = {}) {
|
|
3161
|
+
const props = containerProps(options);
|
|
3162
|
+
const node = this._graph.createNode("form", {
|
|
3163
|
+
key,
|
|
3164
|
+
parent: this._node,
|
|
3165
|
+
props
|
|
3166
|
+
});
|
|
3167
|
+
registerTransition(this._graph, node, options.transition);
|
|
3168
|
+
if (options.onSubmit !== void 0) {
|
|
3169
|
+
const handlerKey = `submit:${node.id}`;
|
|
3170
|
+
this._graph.registerHandler(handlerKey, options.onSubmit);
|
|
3171
|
+
node.addEvent({ type: "submit", handlerKey });
|
|
3172
|
+
}
|
|
3173
|
+
builder(new FormBuilderImpl(node, this._graph));
|
|
3174
|
+
}
|
|
3175
|
+
when(condition, builder, elseBuilder, options = {}) {
|
|
3176
|
+
const graph = this._graph;
|
|
3177
|
+
const node = graph.createNode("conditional", {
|
|
3178
|
+
parent: this._node,
|
|
3179
|
+
props: containerProps({})
|
|
3180
|
+
});
|
|
3181
|
+
const branchTransition = options.transition !== void 0 && options.appear === true ? { ...options.transition, appear: true } : options.transition;
|
|
3182
|
+
const buildBranch = (build, tag) => {
|
|
3183
|
+
const branchKey = `when-${tag}:${node.id}`;
|
|
3184
|
+
const branch = graph.createNode("container", {
|
|
3185
|
+
key: branchKey,
|
|
3186
|
+
props: { key: branchKey }
|
|
3187
|
+
});
|
|
3188
|
+
registerTransition(graph, branch, branchTransition);
|
|
3189
|
+
build(new ContainerBuilderImpl(branch, graph));
|
|
3190
|
+
return branch;
|
|
3191
|
+
};
|
|
3192
|
+
const buildAll = (raw) => {
|
|
3193
|
+
if (raw) return [buildBranch(builder, "then")];
|
|
3194
|
+
return elseBuilder !== void 0 ? [buildBranch(elseBuilder, "else")] : [];
|
|
3195
|
+
};
|
|
3196
|
+
if (isSignal(condition)) {
|
|
3197
|
+
const signalId = `${node.id}:items`;
|
|
3198
|
+
node.stateRefs.push({ signalId, propKey: "items" });
|
|
3199
|
+
graph.registerHandler(`__signal__${signalId}`, condition);
|
|
3200
|
+
graph.registerHandler(`__listbuild__${node.id}`, buildAll);
|
|
3201
|
+
const current = condition.peek();
|
|
3202
|
+
for (const child of buildAll(current)) node.appendChild(child);
|
|
3203
|
+
} else {
|
|
3204
|
+
for (const child of buildAll(condition)) node.appendChild(child);
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
errorBoundary(id, builder, options) {
|
|
3208
|
+
const sources = options.source === void 0 ? [] : Array.isArray(options.source) ? [...options.source] : [options.source];
|
|
3209
|
+
const localError = signal(void 0);
|
|
3210
|
+
const retryNonce = signal(0);
|
|
3211
|
+
const readError = () => {
|
|
3212
|
+
const local = localError.peek();
|
|
3213
|
+
if (local !== void 0 && local !== null) return local;
|
|
3214
|
+
for (const s of sources) {
|
|
3215
|
+
const e = s.peek();
|
|
3216
|
+
if (e !== void 0 && e !== null) return e;
|
|
3217
|
+
}
|
|
3218
|
+
return void 0;
|
|
3219
|
+
};
|
|
3220
|
+
const hasError = derived(() => {
|
|
3221
|
+
retryNonce.get();
|
|
3222
|
+
localError.get();
|
|
3223
|
+
for (const s of sources) s.get();
|
|
3224
|
+
return readError() !== void 0;
|
|
3225
|
+
});
|
|
3226
|
+
const retry = () => {
|
|
3227
|
+
localError.set(void 0);
|
|
3228
|
+
options.onRetry?.();
|
|
3229
|
+
retryNonce.update((n) => n + 1);
|
|
3230
|
+
};
|
|
3231
|
+
this.container(id, (c) => {
|
|
3232
|
+
c.when(
|
|
3233
|
+
hasError,
|
|
3234
|
+
// Error state → fallback.
|
|
3235
|
+
(fb) => options.fallback(fb, readError(), retry),
|
|
3236
|
+
// Healthy state → body, guarded against synchronous build throws.
|
|
3237
|
+
(body) => {
|
|
3238
|
+
try {
|
|
3239
|
+
builder(body);
|
|
3240
|
+
} catch (err) {
|
|
3241
|
+
queueMicrotask(() => localError.set(err));
|
|
3242
|
+
}
|
|
3243
|
+
}
|
|
3244
|
+
);
|
|
3245
|
+
}, { id });
|
|
3246
|
+
}
|
|
3247
|
+
// ── Portals & overlays ──────────────────────────────────────────────────────
|
|
3248
|
+
portal(key, builder, options = {}) {
|
|
3249
|
+
const node = this._graph.createNode("portal", {
|
|
3250
|
+
key,
|
|
3251
|
+
parent: this._node,
|
|
3252
|
+
props: containerProps(options)
|
|
3253
|
+
});
|
|
3254
|
+
builder(new ContainerBuilderImpl(node, this._graph));
|
|
3255
|
+
}
|
|
3256
|
+
/**
|
|
3257
|
+
* Shared assembly for every overlay kind: a `portal` node whose single child
|
|
3258
|
+
* is a `when(open, panel)` conditional. The panel container carries the
|
|
3259
|
+
* kind's ARIA semantics; `builder` fills it. An `__overlay__<portalId>`
|
|
3260
|
+
* descriptor is registered so the renderer wires focus/keyboard behavior to
|
|
3261
|
+
* the same `open` signal that drives the panel. Reuses existing primitives
|
|
3262
|
+
* (portal + when + container) — no new render path.
|
|
3263
|
+
*/
|
|
3264
|
+
_overlay(kind, key, options, builder) {
|
|
3265
|
+
const graph = this._graph;
|
|
3266
|
+
const portalNode = graph.createNode("portal", {
|
|
3267
|
+
key,
|
|
3268
|
+
parent: this._node,
|
|
3269
|
+
props: { key }
|
|
3270
|
+
});
|
|
3271
|
+
const openBindable = options.open;
|
|
3272
|
+
const openSignal = isSignal(openBindable) ? openBindable : signal(openBindable);
|
|
3273
|
+
const panelOptions = {
|
|
3274
|
+
role: options.role ?? kind.role,
|
|
3275
|
+
...kind.ariaModal ? { ariaModal: true } : {},
|
|
3276
|
+
...kind.ariaLive !== void 0 ? { ariaLive: kind.ariaLive } : {},
|
|
3277
|
+
...options.class !== void 0 ? { class: options.class } : {},
|
|
3278
|
+
...options.ariaLabel !== void 0 ? { ariaLabel: options.ariaLabel } : {},
|
|
3279
|
+
...options.ariaLabelledBy !== void 0 ? { ariaLabelledBy: options.ariaLabelledBy } : {},
|
|
3280
|
+
...options.ariaDescribedBy !== void 0 ? { ariaDescribedBy: options.ariaDescribedBy } : {}
|
|
3281
|
+
};
|
|
3282
|
+
const portalBuilder = new ContainerBuilderImpl(portalNode, graph);
|
|
3283
|
+
portalBuilder.when(
|
|
3284
|
+
openSignal,
|
|
3285
|
+
(panelHost) => {
|
|
3286
|
+
panelHost.container(`${key}__panel`, builder, panelOptions);
|
|
3287
|
+
},
|
|
3288
|
+
void 0,
|
|
3289
|
+
// Overlay open/close rides the panel's `when`; a transition animates the
|
|
3290
|
+
// panel in on open and — via the reconciler's deferred-leave — plays the
|
|
3291
|
+
// leave before the panel is removed (§10). Focus is restored at close-
|
|
3292
|
+
// request time (see wireOverlayBehavior), so it never stays trapped inside
|
|
3293
|
+
// a panel that is animating away.
|
|
3294
|
+
options.transition !== void 0 ? { transition: options.transition } : {}
|
|
3295
|
+
);
|
|
3296
|
+
const descriptor = {
|
|
3297
|
+
open: openSignal,
|
|
3298
|
+
modal: kind.modal,
|
|
3299
|
+
takesFocus: kind.takesFocus,
|
|
3300
|
+
menu: kind.menu ?? false,
|
|
3301
|
+
closeOnEscape: options.closeOnEscape ?? kind.defaultCloseOnEscape,
|
|
3302
|
+
restoreFocus: options.restoreFocus ?? kind.defaultRestoreFocus,
|
|
3303
|
+
...options.initialFocusId !== void 0 ? { initialFocusId: options.initialFocusId } : {},
|
|
3304
|
+
...options.onClose !== void 0 ? { onClose: options.onClose } : {}
|
|
3305
|
+
};
|
|
3306
|
+
graph.registerHandler(
|
|
3307
|
+
`__overlay__${portalNode.id}`,
|
|
3308
|
+
() => descriptor
|
|
3309
|
+
);
|
|
3310
|
+
}
|
|
3311
|
+
dialog(key, options, builder) {
|
|
3312
|
+
this._overlay(OVERLAY_KINDS.dialog, key, options, builder);
|
|
3313
|
+
}
|
|
3314
|
+
popover(key, options, builder) {
|
|
3315
|
+
this._overlay(OVERLAY_KINDS.popover, key, options, builder);
|
|
3316
|
+
}
|
|
3317
|
+
tooltip(key, options, builder) {
|
|
3318
|
+
this._overlay(OVERLAY_KINDS.tooltip, key, options, builder);
|
|
3319
|
+
}
|
|
3320
|
+
dropdown(key, options, builder) {
|
|
3321
|
+
this._overlay(OVERLAY_KINDS.dropdown, key, options, builder);
|
|
3322
|
+
}
|
|
3323
|
+
toast(key, options, builder) {
|
|
3324
|
+
this._overlay(OVERLAY_KINDS.toast, key, options, builder);
|
|
3325
|
+
}
|
|
3326
|
+
// ── Components ────────────────────────────────────────────────────────────
|
|
3327
|
+
/**
|
|
3328
|
+
* Instantiate a reusable component (§3–§9). Creates a `'component'` node
|
|
3329
|
+
* (rendered as a `<div>` wrapper — preserves the one-node/one-element
|
|
3330
|
+
* positional-hydration invariant), then runs `def.setup(props, ctx)`
|
|
3331
|
+
* synchronously to obtain the render function and fills the component's own
|
|
3332
|
+
* container scope with it — structurally identical to `container`/
|
|
3333
|
+
* `errorBoundary`. Cleanups the setup registers via `ctx.effect`/
|
|
3334
|
+
* `ctx.onCleanup` are collected into a closure and exposed to the renderer
|
|
3335
|
+
* through a `__component__<id>` handler (mirroring `__overlay__`); the mount/
|
|
3336
|
+
* hydrate paths read it and route each into `NodeInstance.trackCleanup`, so
|
|
3337
|
+
* teardown runs (children-first) when the component leaves the graph.
|
|
3338
|
+
*
|
|
3339
|
+
* `setup` runs once per instance here at build time. When this component sits
|
|
3340
|
+
* inside a keyed list / conditional, a rebuild disposes the old instance
|
|
3341
|
+
* (running its cleanups + pruning its `__component__` entry) and re-runs this
|
|
3342
|
+
* method for the new node — so re-invocation is safe and leak-free.
|
|
3343
|
+
*/
|
|
3344
|
+
component(key, def, props, children) {
|
|
3345
|
+
const graph = this._graph;
|
|
3346
|
+
const node = graph.createNode("component", {
|
|
3347
|
+
key,
|
|
3348
|
+
parent: this._node,
|
|
3349
|
+
// `data-streetui-component` is a non-underscore prop, so it reaches the
|
|
3350
|
+
// DOM as an attribute and is visible to DevTools (§21) — unlike the
|
|
3351
|
+
// internal `_`-prefixed metadata the renderer hides.
|
|
3352
|
+
props: { key, "data-streetui-component": def.name }
|
|
3353
|
+
});
|
|
3354
|
+
const cleanups = [];
|
|
3355
|
+
const ctx = {
|
|
3356
|
+
key,
|
|
3357
|
+
onCleanup(fn) {
|
|
3358
|
+
cleanups.push(fn);
|
|
3359
|
+
},
|
|
3360
|
+
effect(fn) {
|
|
3361
|
+
cleanups.push(effect(fn));
|
|
3362
|
+
},
|
|
3363
|
+
renderChildren(content) {
|
|
3364
|
+
if (children !== void 0) children(content);
|
|
3365
|
+
}
|
|
3366
|
+
};
|
|
3367
|
+
let render2;
|
|
3368
|
+
try {
|
|
3369
|
+
render2 = def.setup(props, ctx);
|
|
3370
|
+
render2(new ContainerBuilderImpl(node, graph));
|
|
3371
|
+
} catch (err) {
|
|
3372
|
+
queueMicrotask(() => {
|
|
3373
|
+
throw err;
|
|
3374
|
+
});
|
|
3375
|
+
}
|
|
3376
|
+
if (cleanups.length > 0) {
|
|
3377
|
+
graph.registerHandler(
|
|
3378
|
+
`__component__${node.id}`,
|
|
3379
|
+
() => cleanups
|
|
3380
|
+
);
|
|
3381
|
+
}
|
|
3382
|
+
}
|
|
3383
|
+
};
|
|
3384
|
+
var SectionBuilderImpl = class extends ContainerBuilderBase {
|
|
3385
|
+
};
|
|
3386
|
+
var ContainerBuilderImpl = class extends ContainerBuilderBase {
|
|
3387
|
+
};
|
|
3388
|
+
var FormBuilderImpl = class extends ContainerBuilderBase {
|
|
3389
|
+
};
|
|
3390
|
+
var ListBuilderImpl = class extends ContentBuilderBase {
|
|
3391
|
+
item(key, builder, options = {}) {
|
|
3392
|
+
const node = this._graph.createNode("list-item", {
|
|
3393
|
+
key,
|
|
3394
|
+
parent: this._node,
|
|
3395
|
+
props: containerProps(options)
|
|
3396
|
+
});
|
|
3397
|
+
registerTransition(this._graph, node, options.transition);
|
|
3398
|
+
builder(new ContainerBuilderImpl(node, this._graph));
|
|
3399
|
+
}
|
|
3400
|
+
};
|
|
3401
|
+
var PageBuilderImpl = class extends ContainerBuilderBase {
|
|
3402
|
+
};
|
|
3403
|
+
var AppBuilder = class {
|
|
3404
|
+
constructor(_graph) {
|
|
3405
|
+
this._graph = _graph;
|
|
3406
|
+
}
|
|
3407
|
+
page(key, builder) {
|
|
3408
|
+
const node = this._graph.createNode("page", {
|
|
3409
|
+
key,
|
|
3410
|
+
parent: this._graph.root,
|
|
3411
|
+
props: { key }
|
|
3412
|
+
});
|
|
3413
|
+
builder(new PageBuilderImpl(node, this._graph));
|
|
3414
|
+
}
|
|
3415
|
+
};
|
|
3416
|
+
|
|
3417
|
+
// ../graph/src/graph-node.ts
|
|
3418
|
+
var GraphNode = class _GraphNode {
|
|
3419
|
+
id;
|
|
3420
|
+
type;
|
|
3421
|
+
key;
|
|
3422
|
+
props;
|
|
3423
|
+
events;
|
|
3424
|
+
stateRefs;
|
|
3425
|
+
children;
|
|
3426
|
+
parent;
|
|
3427
|
+
constructor(type, options = {}) {
|
|
3428
|
+
this.type = type;
|
|
3429
|
+
this.id = options.id ?? generateNodeId(type);
|
|
3430
|
+
this.key = options.key;
|
|
3431
|
+
this.props = options.props ?? {};
|
|
3432
|
+
this.events = options.events ?? [];
|
|
3433
|
+
this.stateRefs = options.stateRefs ?? [];
|
|
3434
|
+
this.children = [];
|
|
3435
|
+
this.parent = null;
|
|
3436
|
+
}
|
|
3437
|
+
// ── Child management ────────────────────────────────────────────────────────
|
|
3438
|
+
appendChild(child) {
|
|
3439
|
+
if (child.parent !== null) {
|
|
3440
|
+
child.parent.removeChild(child);
|
|
3441
|
+
}
|
|
3442
|
+
child.parent = this;
|
|
3443
|
+
this.children.push(child);
|
|
3444
|
+
}
|
|
3445
|
+
insertBefore(child, reference) {
|
|
3446
|
+
const idx = this.children.indexOf(reference);
|
|
3447
|
+
if (idx === -1) {
|
|
3448
|
+
this.appendChild(child);
|
|
3449
|
+
return;
|
|
3450
|
+
}
|
|
3451
|
+
if (child.parent !== null) {
|
|
3452
|
+
child.parent.removeChild(child);
|
|
3453
|
+
}
|
|
3454
|
+
child.parent = this;
|
|
3455
|
+
this.children.splice(idx, 0, child);
|
|
3456
|
+
}
|
|
3457
|
+
removeChild(child) {
|
|
3458
|
+
const idx = this.children.indexOf(child);
|
|
3459
|
+
if (idx === -1) return;
|
|
3460
|
+
this.children.splice(idx, 1);
|
|
3461
|
+
child.parent = null;
|
|
3462
|
+
}
|
|
3463
|
+
replaceChild(newChild, oldChild) {
|
|
3464
|
+
const idx = this.children.indexOf(oldChild);
|
|
3465
|
+
if (idx === -1) {
|
|
3466
|
+
throw new Error(`GraphNode.replaceChild: oldChild is not a child of this node`);
|
|
3467
|
+
}
|
|
3468
|
+
if (newChild.parent !== null) {
|
|
3469
|
+
newChild.parent.removeChild(newChild);
|
|
3470
|
+
}
|
|
3471
|
+
oldChild.parent = null;
|
|
3472
|
+
newChild.parent = this;
|
|
3473
|
+
this.children.splice(idx, 1, newChild);
|
|
3474
|
+
}
|
|
3475
|
+
// ── Prop helpers ────────────────────────────────────────────────────────────
|
|
3476
|
+
setProp(key, value) {
|
|
3477
|
+
this.props = { ...this.props, [key]: value };
|
|
3478
|
+
}
|
|
3479
|
+
getProp(key) {
|
|
3480
|
+
return this.props[key];
|
|
3481
|
+
}
|
|
3482
|
+
// ── Event helpers ───────────────────────────────────────────────────────────
|
|
3483
|
+
addEvent(descriptor) {
|
|
3484
|
+
this.events.push(descriptor);
|
|
3485
|
+
}
|
|
3486
|
+
removeEvent(type) {
|
|
3487
|
+
this.events = this.events.filter((e) => e.type !== type);
|
|
3488
|
+
}
|
|
3489
|
+
// ── Queries ─────────────────────────────────────────────────────────────────
|
|
3490
|
+
get isLeaf() {
|
|
3491
|
+
return this.children.length === 0;
|
|
3492
|
+
}
|
|
3493
|
+
get depth() {
|
|
3494
|
+
let d = 0;
|
|
3495
|
+
let node = this.parent;
|
|
3496
|
+
while (node !== null) {
|
|
3497
|
+
d++;
|
|
3498
|
+
node = node.parent;
|
|
3499
|
+
}
|
|
3500
|
+
return d;
|
|
3501
|
+
}
|
|
3502
|
+
get root() {
|
|
3503
|
+
let node = this;
|
|
3504
|
+
while (node.parent !== null) {
|
|
3505
|
+
node = node.parent;
|
|
3506
|
+
}
|
|
3507
|
+
return node;
|
|
3508
|
+
}
|
|
3509
|
+
/** Shallow clone — does not clone children. */
|
|
3510
|
+
shallowClone() {
|
|
3511
|
+
const opts = {
|
|
3512
|
+
props: { ...this.props },
|
|
3513
|
+
events: [...this.events],
|
|
3514
|
+
stateRefs: [...this.stateRefs]
|
|
3515
|
+
};
|
|
3516
|
+
if (this.key !== void 0) opts.key = this.key;
|
|
3517
|
+
return new _GraphNode(this.type, opts);
|
|
3518
|
+
}
|
|
3519
|
+
};
|
|
3520
|
+
|
|
3521
|
+
// ../graph/src/graph.ts
|
|
3522
|
+
var ApplicationGraph = class {
|
|
3523
|
+
root;
|
|
3524
|
+
name;
|
|
3525
|
+
version;
|
|
3526
|
+
_nodeIndex = /* @__PURE__ */ new Map();
|
|
3527
|
+
/** Handler registry — maps handlerKey → actual function */
|
|
3528
|
+
handlers = /* @__PURE__ */ new Map();
|
|
3529
|
+
constructor(options) {
|
|
3530
|
+
this.name = options.name;
|
|
3531
|
+
this.version = options.version ?? "0.0.1";
|
|
3532
|
+
this.root = new GraphNode("application", { props: { name: options.name } });
|
|
3533
|
+
this._nodeIndex.set(this.root.id, this.root);
|
|
3534
|
+
}
|
|
3535
|
+
// ── Node creation & attachment ────────────────────────────────────────────
|
|
3536
|
+
createNode(type, options = {}) {
|
|
3537
|
+
const nodeOpts = {};
|
|
3538
|
+
if (options.key !== void 0) nodeOpts.key = options.key;
|
|
3539
|
+
if (options.props !== void 0) nodeOpts.props = options.props;
|
|
3540
|
+
const node = new GraphNode(type, nodeOpts);
|
|
3541
|
+
this._nodeIndex.set(node.id, node);
|
|
3542
|
+
if (options.parent !== void 0) {
|
|
3543
|
+
options.parent.appendChild(node);
|
|
3544
|
+
}
|
|
3545
|
+
return node;
|
|
3546
|
+
}
|
|
3547
|
+
attachNode(node, parent) {
|
|
3548
|
+
this._nodeIndex.set(node.id, node);
|
|
3549
|
+
parent.appendChild(node);
|
|
3550
|
+
}
|
|
3551
|
+
detachNode(node) {
|
|
3552
|
+
if (node.parent !== null) {
|
|
3553
|
+
node.parent.removeChild(node);
|
|
3554
|
+
}
|
|
3555
|
+
this._removeFromIndex(node);
|
|
3556
|
+
}
|
|
3557
|
+
_removeFromIndex(node) {
|
|
3558
|
+
this._nodeIndex.delete(node.id);
|
|
3559
|
+
this._unregisterNodeHandlers(node);
|
|
3560
|
+
for (const child of node.children) {
|
|
3561
|
+
this._removeFromIndex(child);
|
|
3562
|
+
}
|
|
3563
|
+
}
|
|
3564
|
+
/**
|
|
3565
|
+
* Remove every handler-registry entry owned by a single node. A node owns:
|
|
3566
|
+
* - one entry per event descriptor (its `handlerKey`),
|
|
3567
|
+
* - one `__signal__<signalId>` entry per state ref (signalIds are namespaced
|
|
3568
|
+
* by node id, so they are never shared between nodes), and
|
|
3569
|
+
* - a `__listbuild__<id>` entry if it is a reactive-list.
|
|
3570
|
+
* Called for every node in a detached subtree so removing list items (or
|
|
3571
|
+
* discarding freshly-built-but-unadopted item subtrees) leaves no stale
|
|
3572
|
+
* registrations behind.
|
|
3573
|
+
*/
|
|
3574
|
+
_unregisterNodeHandlers(node) {
|
|
3575
|
+
for (const event of node.events) {
|
|
3576
|
+
this.handlers.delete(event.handlerKey);
|
|
3577
|
+
}
|
|
3578
|
+
for (const ref of node.stateRefs) {
|
|
3579
|
+
this.handlers.delete(`__signal__${ref.signalId}`);
|
|
3580
|
+
}
|
|
3581
|
+
this.handlers.delete(`__listbuild__${node.id}`);
|
|
3582
|
+
this.handlers.delete(`__listplan__${node.id}`);
|
|
3583
|
+
this.handlers.delete(`__overlay__${node.id}`);
|
|
3584
|
+
this.handlers.delete(`__component__${node.id}`);
|
|
3585
|
+
this.handlers.delete(`__transition__${node.id}`);
|
|
3586
|
+
}
|
|
3587
|
+
// ── Handler registry ──────────────────────────────────────────────────────
|
|
3588
|
+
registerHandler(key, fn) {
|
|
3589
|
+
this.handlers.set(key, fn);
|
|
3590
|
+
}
|
|
3591
|
+
getHandler(key) {
|
|
3592
|
+
return this.handlers.get(key);
|
|
3593
|
+
}
|
|
3594
|
+
/** True if a handler is currently registered under `key`. Inspection helper. */
|
|
3595
|
+
hasHandler(key) {
|
|
3596
|
+
return this.handlers.has(key);
|
|
3597
|
+
}
|
|
3598
|
+
/** Number of currently-registered handlers. Inspection helper. */
|
|
3599
|
+
get handlerCount() {
|
|
3600
|
+
return this.handlers.size;
|
|
3601
|
+
}
|
|
3602
|
+
// ── Lookup ────────────────────────────────────────────────────────────────
|
|
3603
|
+
findById(id) {
|
|
3604
|
+
return this._nodeIndex.get(id);
|
|
3605
|
+
}
|
|
3606
|
+
findAll(predicate) {
|
|
3607
|
+
const results = [];
|
|
3608
|
+
this._walk(this.root, (node) => {
|
|
3609
|
+
if (predicate(node)) results.push(node);
|
|
3610
|
+
});
|
|
3611
|
+
return results;
|
|
3612
|
+
}
|
|
3613
|
+
findByType(type) {
|
|
3614
|
+
return this.findAll((n) => n.type === type);
|
|
3615
|
+
}
|
|
3616
|
+
// ── Traversal ─────────────────────────────────────────────────────────────
|
|
3617
|
+
walk(visitor) {
|
|
3618
|
+
this._walk(this.root, visitor, 0);
|
|
3619
|
+
}
|
|
3620
|
+
_walk(node, visitor, depth = 0) {
|
|
3621
|
+
visitor(node, depth);
|
|
3622
|
+
for (const child of node.children) {
|
|
3623
|
+
this._walk(child, visitor, depth + 1);
|
|
3624
|
+
}
|
|
3625
|
+
}
|
|
3626
|
+
get nodeCount() {
|
|
3627
|
+
return this._nodeIndex.size;
|
|
3628
|
+
}
|
|
3629
|
+
// ── Validation ────────────────────────────────────────────────────────────
|
|
3630
|
+
validate() {
|
|
3631
|
+
const dc = new DiagnosticCollector();
|
|
3632
|
+
this.walk((node) => {
|
|
3633
|
+
for (const event of node.events) {
|
|
3634
|
+
if (!this.handlers.has(event.handlerKey)) {
|
|
3635
|
+
dc.warn(
|
|
3636
|
+
"GRAPH_MISSING_HANDLER",
|
|
3637
|
+
`Node "${node.id}" references handler "${event.handlerKey}" which is not registered`,
|
|
3638
|
+
{ nodeId: node.id }
|
|
3639
|
+
);
|
|
3640
|
+
}
|
|
3641
|
+
}
|
|
3642
|
+
if (node.type === "page" && node.parent?.type !== "application") {
|
|
3643
|
+
dc.error(
|
|
3644
|
+
"GRAPH_PAGE_DEPTH",
|
|
3645
|
+
`Page node "${node.id}" must be a direct child of the application root`,
|
|
3646
|
+
{ nodeId: node.id }
|
|
3647
|
+
);
|
|
3648
|
+
}
|
|
3649
|
+
});
|
|
3650
|
+
return dc;
|
|
3651
|
+
}
|
|
3652
|
+
// ── Serialization ─────────────────────────────────────────────────────────
|
|
3653
|
+
serialize() {
|
|
3654
|
+
return {
|
|
3655
|
+
name: this.name,
|
|
3656
|
+
version: this.version,
|
|
3657
|
+
root: this._serializeNode(this.root)
|
|
3658
|
+
};
|
|
3659
|
+
}
|
|
3660
|
+
_serializeNode(node) {
|
|
3661
|
+
const result = {
|
|
3662
|
+
id: node.id,
|
|
3663
|
+
type: node.type,
|
|
3664
|
+
key: node.key,
|
|
3665
|
+
props: node.props,
|
|
3666
|
+
events: node.events,
|
|
3667
|
+
stateRefs: node.stateRefs,
|
|
3668
|
+
children: node.children.map((c) => this._serializeNode(c))
|
|
3669
|
+
};
|
|
3670
|
+
return result;
|
|
3671
|
+
}
|
|
3672
|
+
};
|
|
3673
|
+
|
|
3674
|
+
// ../dsl/src/dsl.ts
|
|
3675
|
+
var StreetApp = class {
|
|
3676
|
+
_graph;
|
|
3677
|
+
_builder;
|
|
3678
|
+
constructor(options) {
|
|
3679
|
+
const graphOpts = { name: options.name };
|
|
3680
|
+
if (options.version !== void 0) graphOpts.version = options.version;
|
|
3681
|
+
this._graph = new ApplicationGraph(graphOpts);
|
|
3682
|
+
this._builder = new AppBuilder(this._graph);
|
|
3683
|
+
}
|
|
3684
|
+
page(key, builder) {
|
|
3685
|
+
this._builder.page(key, builder);
|
|
3686
|
+
return this;
|
|
3687
|
+
}
|
|
3688
|
+
/** Compile to ApplicationGraph — validates and returns the graph. */
|
|
3689
|
+
build() {
|
|
3690
|
+
const dc = this._graph.validate();
|
|
3691
|
+
dc.throwIfErrors();
|
|
3692
|
+
return this._graph;
|
|
3693
|
+
}
|
|
3694
|
+
/** Access graph before building (useful for inspection). */
|
|
3695
|
+
get graph() {
|
|
3696
|
+
return this._graph;
|
|
3697
|
+
}
|
|
3698
|
+
};
|
|
3699
|
+
var streetui = {
|
|
3700
|
+
app(options) {
|
|
3701
|
+
return new StreetApp(options);
|
|
3702
|
+
}
|
|
3703
|
+
};
|
|
3704
|
+
|
|
3705
|
+
// ../testing/src/component.ts
|
|
3706
|
+
var COMPONENT_ATTR = "data-streetui-component";
|
|
3707
|
+
function renderComponent(def, props, children) {
|
|
3708
|
+
const app = streetui.app({ name: `test:${def.name}` });
|
|
3709
|
+
app.page("host", (page) => {
|
|
3710
|
+
page.component("root", def, props, children);
|
|
3711
|
+
});
|
|
3712
|
+
const result = render(app);
|
|
3713
|
+
const component = result.container.querySelector(`[${COMPONENT_ATTR}]`);
|
|
3714
|
+
if (component === null) {
|
|
3715
|
+
throw new Error(`[StreetUI Testing] renderComponent: no component element rendered for "${def.name}"`);
|
|
3716
|
+
}
|
|
3717
|
+
return { ...result, component };
|
|
3718
|
+
}
|
|
3719
|
+
function hydrateComponent(build, options = {}) {
|
|
3720
|
+
return renderServerThenHydrate(() => {
|
|
3721
|
+
const { def, props, children } = build();
|
|
3722
|
+
const app = streetui.app({ name: `test:${def.name}` });
|
|
3723
|
+
app.page("host", (page) => page.component("root", def, props, children));
|
|
3724
|
+
return app;
|
|
3725
|
+
}, options);
|
|
3726
|
+
}
|
|
3727
|
+
function findAllComponents(container, name) {
|
|
3728
|
+
const selector = name === void 0 ? `[${COMPONENT_ATTR}]` : `[${COMPONENT_ATTR}="${name}"]`;
|
|
3729
|
+
return Array.from(container.querySelectorAll(selector));
|
|
3730
|
+
}
|
|
3731
|
+
function findComponent(container, name) {
|
|
3732
|
+
const matches = findAllComponents(container, name);
|
|
3733
|
+
const named = name !== void 0 ? ` named "${name}"` : "";
|
|
3734
|
+
if (matches.length === 0) {
|
|
3735
|
+
throw new Error(`[StreetUI Testing] No component${named} found`);
|
|
3736
|
+
}
|
|
3737
|
+
if (matches.length > 1) {
|
|
3738
|
+
throw new Error(
|
|
3739
|
+
`[StreetUI Testing] Found ${matches.length} components${named} \u2014 pass a name to disambiguate`
|
|
3740
|
+
);
|
|
3741
|
+
}
|
|
3742
|
+
return matches[0];
|
|
3743
|
+
}
|
|
3744
|
+
function getComponentName(el) {
|
|
3745
|
+
return el.getAttribute(COMPONENT_ATTR);
|
|
3746
|
+
}
|
|
3747
|
+
function trigger(el, type, init = {}) {
|
|
3748
|
+
const base = { bubbles: true, cancelable: true, ...init };
|
|
3749
|
+
let event;
|
|
3750
|
+
if (type.startsWith("key")) {
|
|
3751
|
+
event = new KeyboardEvent(type, base);
|
|
3752
|
+
} else if (type.startsWith("mouse") || type === "click" || type === "dblclick") {
|
|
3753
|
+
event = new MouseEvent(type, base);
|
|
3754
|
+
} else if (type === "input" || type === "change") {
|
|
3755
|
+
event = new Event(type, base);
|
|
3756
|
+
} else {
|
|
3757
|
+
event = new Event(type, base);
|
|
3758
|
+
}
|
|
3759
|
+
el.dispatchEvent(event);
|
|
3760
|
+
}
|
|
3761
|
+
|
|
2338
3762
|
// src/version.ts
|
|
2339
|
-
var VERSION = "1.
|
|
3763
|
+
var VERSION = "1.9.0";
|
|
2340
3764
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2341
3765
|
0 && (module.exports = {
|
|
2342
3766
|
VERSION,
|
|
2343
3767
|
analyzeGraph,
|
|
3768
|
+
blur,
|
|
3769
|
+
clickOutside,
|
|
3770
|
+
closeOverlay,
|
|
2344
3771
|
findAllByRole,
|
|
3772
|
+
findAllComponents,
|
|
2345
3773
|
findByRole,
|
|
2346
3774
|
findByText,
|
|
3775
|
+
findComponent,
|
|
2347
3776
|
flushUpdates,
|
|
3777
|
+
focus,
|
|
2348
3778
|
formatInspection,
|
|
3779
|
+
getComponentName,
|
|
3780
|
+
hydrateComponent,
|
|
2349
3781
|
inspectCompilation,
|
|
3782
|
+
openOverlay,
|
|
3783
|
+
pressKey,
|
|
2350
3784
|
render,
|
|
3785
|
+
renderComponent,
|
|
2351
3786
|
renderOnce,
|
|
2352
3787
|
renderServerThenHydrate,
|
|
2353
|
-
|
|
3788
|
+
trigger,
|
|
3789
|
+
waitFor,
|
|
3790
|
+
waitForTransition
|
|
2354
3791
|
});
|
|
2355
3792
|
//# sourceMappingURL=testing.cjs.map
|