@vizejs/fresco 0.717.0 → 0.719.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/{accessibility-DY_alnTr.d.mts → accessibility-DwzT925M.d.mts} +11 -5
- package/dist/accessibility-DwzT925M.d.mts.map +1 -0
- package/dist/{app-B9yJzz5S.mjs → app-C_wFlWSV.mjs} +368 -123
- package/dist/app-C_wFlWSV.mjs.map +1 -0
- package/dist/app-_QmZ-PoH.d.mts +270 -0
- package/dist/app-_QmZ-PoH.d.mts.map +1 -0
- package/dist/ascii-font/index.d.mts +60 -0
- package/dist/ascii-font/index.d.mts.map +1 -0
- package/dist/ascii-font/index.mjs +68 -0
- package/dist/ascii-font/index.mjs.map +1 -0
- package/dist/components/index.d.mts +2 -2
- package/dist/components/index.mjs +2 -2
- package/dist/components-DzkL-yHj.mjs +6165 -0
- package/dist/components-DzkL-yHj.mjs.map +1 -0
- package/dist/composables/index.d.mts +3 -3
- package/dist/composables/index.mjs +4 -4
- package/dist/{composables-uj7hkBfP.mjs → composables-BJeirPSH.mjs} +116 -55
- package/dist/composables-BJeirPSH.mjs.map +1 -0
- package/dist/{index-BjK3JSNo.d.mts → index-BCxB_ZLV.d.mts} +1079 -239
- package/dist/index-BCxB_ZLV.d.mts.map +1 -0
- package/dist/{index-Dikou9bu.d.mts → index-Ddp2Txtm.d.mts} +52 -4
- package/dist/index-Ddp2Txtm.d.mts.map +1 -0
- package/dist/index.d.mts +98 -7
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +262 -5
- package/dist/index.mjs.map +1 -1
- package/dist/{protocol-D8xt3DG7.d.mts → protocol-DavoeNLn.d.mts} +14 -4
- package/dist/{protocol-D8xt3DG7.d.mts.map → protocol-DavoeNLn.d.mts.map} +1 -1
- package/dist/qr-code/index.d.mts +101 -0
- package/dist/qr-code/index.d.mts.map +1 -0
- package/dist/qr-code/index.mjs +88 -0
- package/dist/qr-code/index.mjs.map +1 -0
- package/dist/testing/index.d.mts +3 -3
- package/dist/testing/index.mjs +1 -1
- package/dist/{useApp-CVB2jNCO.d.mts → useApp-vIRJ5Th3.d.mts} +34 -8
- package/dist/useApp-vIRJ5Th3.d.mts.map +1 -0
- package/dist/{useVirtualViewport-DYuUlTxU.mjs → useBoxMetrics-lF5Myjc7.mjs} +66 -6
- package/dist/useBoxMetrics-lF5Myjc7.mjs.map +1 -0
- package/package.json +14 -6
- package/dist/accessibility-DY_alnTr.d.mts.map +0 -1
- package/dist/app-B9yJzz5S.mjs.map +0 -1
- package/dist/app-CKsTWQuP.d.mts +0 -154
- package/dist/app-CKsTWQuP.d.mts.map +0 -1
- package/dist/components-C57eT1BL.mjs +0 -3406
- package/dist/components-C57eT1BL.mjs.map +0 -1
- package/dist/composables-uj7hkBfP.mjs.map +0 -1
- package/dist/index-BjK3JSNo.d.mts.map +0 -1
- package/dist/index-Dikou9bu.d.mts.map +0 -1
- package/dist/useApp-CVB2jNCO.d.mts.map +0 -1
- package/dist/useVirtualViewport-DYuUlTxU.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { format } from "node:util";
|
|
2
|
-
import { computed, createRenderer, defineComponent, h, inject, isRef, onUnmounted, ref, shallowRef, watch } from "vue";
|
|
2
|
+
import { computed, createRenderer, defineComponent, h, inject, isRef, nextTick, onUnmounted, provide, ref, shallowRef, watch } from "vue";
|
|
3
3
|
//#region src/renderPayload.ts
|
|
4
4
|
const displays = ["flex", "none"];
|
|
5
5
|
const positions = [
|
|
@@ -89,6 +89,11 @@ function numberValue(value) {
|
|
|
89
89
|
function booleanValue(value) {
|
|
90
90
|
return typeof value === "boolean" ? value : void 0;
|
|
91
91
|
}
|
|
92
|
+
function stringLines(value) {
|
|
93
|
+
if (!Array.isArray(value)) return void 0;
|
|
94
|
+
const lines = value.filter((line) => typeof line === "string");
|
|
95
|
+
return lines.length > 0 ? lines : void 0;
|
|
96
|
+
}
|
|
92
97
|
function enabledValue(value) {
|
|
93
98
|
return value === true ? true : void 0;
|
|
94
99
|
}
|
|
@@ -199,6 +204,15 @@ function frescoNodeToRenderNode(node) {
|
|
|
199
204
|
}
|
|
200
205
|
return renderNode;
|
|
201
206
|
}
|
|
207
|
+
if (node.type === "raw") {
|
|
208
|
+
const renderNode = {
|
|
209
|
+
...common,
|
|
210
|
+
nodeType: "raw"
|
|
211
|
+
};
|
|
212
|
+
const lines = stringLines(node.props.lines);
|
|
213
|
+
if (lines) renderNode.lines = lines;
|
|
214
|
+
return renderNode;
|
|
215
|
+
}
|
|
202
216
|
const renderNode = {
|
|
203
217
|
...common,
|
|
204
218
|
nodeType: "input"
|
|
@@ -207,12 +221,16 @@ function frescoNodeToRenderNode(node) {
|
|
|
207
221
|
const placeholder = stringValue$1(node.props.placeholder);
|
|
208
222
|
const focused = booleanValue(firstValue(node.props, "focused", "focus"));
|
|
209
223
|
const cursor = numberValue(node.props.cursor);
|
|
224
|
+
const selectionStart = numberValue(firstValue(node.props, "selectionStart", "selection_start"));
|
|
225
|
+
const selectionEnd = numberValue(firstValue(node.props, "selectionEnd", "selection_end"));
|
|
210
226
|
const mask = booleanValue(node.props.mask);
|
|
211
227
|
const maskChar = stringValue$1(firstValue(node.props, "maskChar", "mask_char", "mask-char"));
|
|
212
228
|
if (value !== void 0) renderNode.value = value;
|
|
213
229
|
if (placeholder !== void 0) renderNode.placeholder = placeholder;
|
|
214
230
|
if (focused !== void 0) renderNode.focused = focused;
|
|
215
231
|
if (cursor !== void 0) renderNode.cursor = cursor;
|
|
232
|
+
if (selectionStart !== void 0) renderNode.selectionStart = selectionStart;
|
|
233
|
+
if (selectionEnd !== void 0) renderNode.selectionEnd = selectionEnd;
|
|
216
234
|
if (mask !== void 0) renderNode.mask = mask;
|
|
217
235
|
if (maskChar !== void 0) renderNode.maskChar = maskChar;
|
|
218
236
|
return renderNode;
|
|
@@ -371,6 +389,7 @@ function useApp() {
|
|
|
371
389
|
* useFocus - Focus management composable
|
|
372
390
|
*/
|
|
373
391
|
const FOCUS_KEY = Symbol("fresco-focus");
|
|
392
|
+
const FOCUS_PARENT_KEY = Symbol("fresco-focus-parent");
|
|
374
393
|
function activeFocusables(focusables) {
|
|
375
394
|
return focusables.filter((focusable) => focusable.isActive);
|
|
376
395
|
}
|
|
@@ -382,38 +401,76 @@ function createFocusManager() {
|
|
|
382
401
|
const activeId = computed(() => focusedId.value ?? void 0);
|
|
383
402
|
const focusables = ref([]);
|
|
384
403
|
const focusableIds = computed(() => activeFocusables(focusables.value).map(({ id }) => id));
|
|
404
|
+
const trapStack = ref([]);
|
|
405
|
+
const activeTrapId = computed(() => trapStack.value.at(-1));
|
|
385
406
|
const isEnabled = ref(true);
|
|
386
|
-
const
|
|
387
|
-
|
|
388
|
-
|
|
407
|
+
const findFocusable = (id) => focusables.value.find((focusable) => focusable.id === id);
|
|
408
|
+
const isWithin = (id, rootId) => {
|
|
409
|
+
let currentId = id;
|
|
410
|
+
const visited = /* @__PURE__ */ new Set();
|
|
411
|
+
while (currentId !== null) {
|
|
412
|
+
if (currentId === rootId) return true;
|
|
413
|
+
if (visited.has(currentId)) return false;
|
|
414
|
+
visited.add(currentId);
|
|
415
|
+
currentId = findFocusable(currentId)?.parentId ?? null;
|
|
416
|
+
}
|
|
417
|
+
return false;
|
|
389
418
|
};
|
|
390
|
-
const
|
|
391
|
-
const
|
|
392
|
-
|
|
393
|
-
const currentIndex = focusedId.value !== null ? focusables.value.findIndex((focusable) => focusable.id === focusedId.value) : -1;
|
|
394
|
-
focusedId.value = focusables.value.slice(currentIndex + 1).find((focusable) => focusable.isActive)?.id ?? active[0]?.id ?? null;
|
|
419
|
+
const allowedByActiveTrap = (id) => {
|
|
420
|
+
const trapId = activeTrapId.value;
|
|
421
|
+
return trapId === void 0 || isWithin(id, trapId);
|
|
395
422
|
};
|
|
396
|
-
const
|
|
397
|
-
|
|
423
|
+
const scopedFocusables = () => activeFocusables(focusables.value).filter(({ id }) => allowedByActiveTrap(id));
|
|
424
|
+
const delegatedTarget = (target) => {
|
|
425
|
+
let current = target;
|
|
426
|
+
const visited = /* @__PURE__ */ new Set();
|
|
427
|
+
while (current.delegateFocusTo !== null && !visited.has(current.id)) {
|
|
428
|
+
visited.add(current.id);
|
|
429
|
+
const delegated = findFocusable(current.delegateFocusTo);
|
|
430
|
+
if (!delegated?.isActive || !isWithin(delegated.id, current.id) || !allowedByActiveTrap(delegated.id)) break;
|
|
431
|
+
current = delegated;
|
|
432
|
+
}
|
|
433
|
+
return current;
|
|
434
|
+
};
|
|
435
|
+
const focus = (id) => {
|
|
436
|
+
const target = findFocusable(id);
|
|
437
|
+
if (isEnabled.value && target?.isActive && allowedByActiveTrap(id)) focusedId.value = delegatedTarget(target).id;
|
|
438
|
+
};
|
|
439
|
+
const moveFocus = (offset) => {
|
|
440
|
+
const active = scopedFocusables();
|
|
398
441
|
if (!isEnabled.value || active.length === 0) return;
|
|
399
|
-
const currentIndex =
|
|
400
|
-
|
|
442
|
+
const currentIndex = active.findIndex((focusable) => focusable.id === focusedId.value);
|
|
443
|
+
for (let distance = 1; distance <= active.length; distance += 1) {
|
|
444
|
+
const candidate = active[currentIndex === -1 ? offset === 1 ? distance - 1 : active.length - distance : (currentIndex + offset * distance + active.length * 2) % active.length];
|
|
445
|
+
if (!candidate) continue;
|
|
446
|
+
const resolved = delegatedTarget(candidate);
|
|
447
|
+
if (resolved.id !== focusedId.value || active.length === 1) {
|
|
448
|
+
focusedId.value = resolved.id;
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
401
452
|
};
|
|
453
|
+
const focusNext = () => moveFocus(1);
|
|
454
|
+
const focusPrevious = () => moveFocus(-1);
|
|
402
455
|
const register = (id, options = {}) => {
|
|
403
456
|
const existing = focusables.value.find((focusable) => focusable.id === id);
|
|
404
457
|
if (existing) {
|
|
405
458
|
existing.isActive = options.isActive ?? existing.isActive;
|
|
406
459
|
if ("parentId" in options) existing.parentId = options.parentId ?? null;
|
|
460
|
+
if ("delegateFocusTo" in options) existing.delegateFocusTo = options.delegateFocusTo ?? null;
|
|
407
461
|
} else focusables.value.push({
|
|
408
462
|
id,
|
|
409
463
|
isActive: options.isActive ?? true,
|
|
410
|
-
parentId: options.parentId ?? null
|
|
464
|
+
parentId: options.parentId ?? null,
|
|
465
|
+
delegateFocusTo: options.delegateFocusTo ?? null
|
|
411
466
|
});
|
|
412
467
|
if (options.autoFocus && focusedId.value === null && options.isActive !== false) focus(id);
|
|
413
468
|
};
|
|
414
469
|
const unregister = (id) => {
|
|
415
470
|
const index = focusables.value.findIndex((focusable) => focusable.id === id);
|
|
416
471
|
if (index !== -1) {
|
|
472
|
+
const trapIndex = trapStack.value.indexOf(id);
|
|
473
|
+
if (trapIndex !== -1) trapStack.value.splice(trapIndex);
|
|
417
474
|
focusables.value.splice(index, 1);
|
|
418
475
|
if (focusedId.value === id) focusedId.value = null;
|
|
419
476
|
}
|
|
@@ -422,12 +479,33 @@ function createFocusManager() {
|
|
|
422
479
|
const focusable = focusables.value.find((item) => item.id === id);
|
|
423
480
|
if (!focusable) return;
|
|
424
481
|
focusable.isActive = isActive;
|
|
482
|
+
if (!isActive) {
|
|
483
|
+
const trapIndex = trapStack.value.indexOf(id);
|
|
484
|
+
if (trapIndex !== -1) trapStack.value.splice(trapIndex);
|
|
485
|
+
}
|
|
425
486
|
if (!isActive && focusedId.value === id) focusedId.value = null;
|
|
426
487
|
};
|
|
427
488
|
const setParent = (id, parentId) => {
|
|
428
|
-
const focusable =
|
|
489
|
+
const focusable = findFocusable(id);
|
|
429
490
|
if (!focusable) return;
|
|
430
491
|
focusable.parentId = parentId ?? null;
|
|
492
|
+
if (focusedId.value !== null && !allowedByActiveTrap(focusedId.value)) focusedId.value = null;
|
|
493
|
+
};
|
|
494
|
+
const setDelegate = (id, delegateFocusTo) => {
|
|
495
|
+
const focusable = findFocusable(id);
|
|
496
|
+
if (focusable) focusable.delegateFocusTo = delegateFocusTo ?? null;
|
|
497
|
+
};
|
|
498
|
+
const trapFocus = (id) => {
|
|
499
|
+
if (!findFocusable(id)?.isActive || !allowedByActiveTrap(id)) return;
|
|
500
|
+
if (activeTrapId.value !== id) trapStack.value.push(id);
|
|
501
|
+
if (focusedId.value === null || !isWithin(focusedId.value, id)) focus(id);
|
|
502
|
+
};
|
|
503
|
+
const releaseFocusTrap = (id) => {
|
|
504
|
+
const index = trapStack.value.indexOf(id);
|
|
505
|
+
if (index === -1) return;
|
|
506
|
+
trapStack.value.splice(index);
|
|
507
|
+
const remaining = activeTrapId.value;
|
|
508
|
+
if (remaining !== void 0 && focusedId.value !== null && !isWithin(focusedId.value, remaining)) focus(remaining);
|
|
431
509
|
};
|
|
432
510
|
const hasFocusedDescendant = (id) => {
|
|
433
511
|
let currentId = focusedId.value;
|
|
@@ -436,7 +514,7 @@ function createFocusManager() {
|
|
|
436
514
|
while (true) {
|
|
437
515
|
if (visited.has(currentId)) return false;
|
|
438
516
|
visited.add(currentId);
|
|
439
|
-
const parentId =
|
|
517
|
+
const parentId = findFocusable(currentId)?.parentId ?? null;
|
|
440
518
|
if (parentId === null) return false;
|
|
441
519
|
if (parentId === id) return true;
|
|
442
520
|
currentId = parentId;
|
|
@@ -453,6 +531,7 @@ function createFocusManager() {
|
|
|
453
531
|
focusedId,
|
|
454
532
|
activeId,
|
|
455
533
|
focusableIds,
|
|
534
|
+
activeTrapId,
|
|
456
535
|
isEnabled,
|
|
457
536
|
enableFocus,
|
|
458
537
|
disableFocus,
|
|
@@ -463,23 +542,35 @@ function createFocusManager() {
|
|
|
463
542
|
unregister,
|
|
464
543
|
setActive,
|
|
465
544
|
setParent,
|
|
545
|
+
setDelegate,
|
|
546
|
+
trapFocus,
|
|
547
|
+
releaseFocusTrap,
|
|
466
548
|
hasFocusedDescendant
|
|
467
549
|
};
|
|
468
550
|
}
|
|
551
|
+
/** Make an owning focus target the default parent for nested useFocus calls. */
|
|
552
|
+
function provideFocusScope(parentId) {
|
|
553
|
+
provide(FOCUS_PARENT_KEY, parentId);
|
|
554
|
+
}
|
|
469
555
|
/**
|
|
470
556
|
* Use focus management
|
|
471
557
|
*/
|
|
472
558
|
function useFocus(options = {}) {
|
|
473
|
-
const
|
|
559
|
+
const inheritedParentId = inject(FOCUS_PARENT_KEY, null);
|
|
560
|
+
const { autoFocus = false, id = `focus-${Math.random().toString(36).slice(2)}`, isActive: isActiveOption = true, delegateFocusTo: delegateFocusToOption = null, trapFocus: trapFocusOption = false } = options;
|
|
561
|
+
const parentIdOption = "parentId" in options ? options.parentId ?? null : inheritedParentId;
|
|
474
562
|
const manager = inject(FOCUS_KEY, null);
|
|
475
563
|
const localFocused = ref(autoFocus);
|
|
476
564
|
const active = isRef(isActiveOption) ? isActiveOption : ref(isActiveOption);
|
|
477
565
|
const parentId = isRef(parentIdOption) ? parentIdOption : ref(parentIdOption);
|
|
566
|
+
const delegateFocusTo = isRef(delegateFocusToOption) ? delegateFocusToOption : ref(delegateFocusToOption);
|
|
567
|
+
const trapsFocus = isRef(trapFocusOption) ? trapFocusOption : ref(trapFocusOption);
|
|
478
568
|
const isFocused = computed(() => {
|
|
479
569
|
if (manager) return manager.isEnabled.value && manager.focusedId.value === id;
|
|
480
570
|
return active.value && localFocused.value;
|
|
481
571
|
});
|
|
482
572
|
const hasFocusedDescendant = computed(() => manager ? manager.hasFocusedDescendant(id) : false);
|
|
573
|
+
const isFocusTrapActive = computed(() => manager?.activeTrapId.value === id);
|
|
483
574
|
const focus = (targetId = id) => {
|
|
484
575
|
if (manager) manager.focus(targetId);
|
|
485
576
|
else if (targetId === id) localFocused.value = true;
|
|
@@ -493,16 +584,27 @@ function useFocus(options = {}) {
|
|
|
493
584
|
manager.register(id, {
|
|
494
585
|
isActive: active.value,
|
|
495
586
|
autoFocus,
|
|
496
|
-
parentId: parentId.value
|
|
587
|
+
parentId: parentId.value,
|
|
588
|
+
delegateFocusTo: delegateFocusTo.value
|
|
497
589
|
});
|
|
590
|
+
if (trapsFocus.value) manager.trapFocus(id);
|
|
498
591
|
watch(active, (enabled) => {
|
|
499
592
|
manager.setActive(id, enabled);
|
|
593
|
+
if (enabled && trapsFocus.value) manager.trapFocus(id);
|
|
500
594
|
if (enabled && autoFocus && !manager.focusedId.value) manager.focus(id);
|
|
501
595
|
}, { immediate: false });
|
|
502
596
|
watch(parentId, (nextParentId) => {
|
|
503
597
|
manager.setParent(id, nextParentId);
|
|
504
598
|
}, { immediate: false });
|
|
599
|
+
watch(delegateFocusTo, (nextDelegate) => {
|
|
600
|
+
manager.setDelegate(id, nextDelegate);
|
|
601
|
+
}, { immediate: false });
|
|
602
|
+
watch(trapsFocus, (trapped) => {
|
|
603
|
+
if (trapped) manager.trapFocus(id);
|
|
604
|
+
else manager.releaseFocusTrap(id);
|
|
605
|
+
}, { immediate: false });
|
|
505
606
|
onUnmounted(() => {
|
|
607
|
+
manager.releaseFocusTrap(id);
|
|
506
608
|
manager.unregister(id);
|
|
507
609
|
});
|
|
508
610
|
}
|
|
@@ -510,6 +612,7 @@ function useFocus(options = {}) {
|
|
|
510
612
|
id,
|
|
511
613
|
isFocused,
|
|
512
614
|
hasFocusedDescendant,
|
|
615
|
+
isFocusTrapActive,
|
|
513
616
|
focus,
|
|
514
617
|
blur
|
|
515
618
|
};
|
|
@@ -521,6 +624,7 @@ function useFocusManager() {
|
|
|
521
624
|
const manager = inject(FOCUS_KEY, null);
|
|
522
625
|
if (!manager) {
|
|
523
626
|
const empty = ref([]);
|
|
627
|
+
const activeId = ref(void 0);
|
|
524
628
|
return {
|
|
525
629
|
enableFocus: () => {},
|
|
526
630
|
disableFocus: () => {},
|
|
@@ -528,8 +632,12 @@ function useFocusManager() {
|
|
|
528
632
|
focusPrevious: () => {},
|
|
529
633
|
focus: (_id) => {},
|
|
530
634
|
hasFocusedDescendant: (_id) => false,
|
|
531
|
-
|
|
532
|
-
|
|
635
|
+
trapFocus: (_id) => {},
|
|
636
|
+
releaseFocusTrap: (_id) => {},
|
|
637
|
+
setDelegate: (_id, _delegateFocusTo) => {},
|
|
638
|
+
activeId,
|
|
639
|
+
focusableIds: empty,
|
|
640
|
+
activeTrapId: activeId
|
|
533
641
|
};
|
|
534
642
|
}
|
|
535
643
|
return {
|
|
@@ -539,8 +647,12 @@ function useFocusManager() {
|
|
|
539
647
|
focusPrevious: manager.focusPrevious,
|
|
540
648
|
focus: manager.focus,
|
|
541
649
|
hasFocusedDescendant: manager.hasFocusedDescendant,
|
|
650
|
+
trapFocus: manager.trapFocus,
|
|
651
|
+
releaseFocusTrap: manager.releaseFocusTrap,
|
|
652
|
+
setDelegate: manager.setDelegate,
|
|
542
653
|
activeId: manager.activeId,
|
|
543
|
-
focusableIds: manager.focusableIds
|
|
654
|
+
focusableIds: manager.focusableIds,
|
|
655
|
+
activeTrapId: manager.activeTrapId
|
|
544
656
|
};
|
|
545
657
|
}
|
|
546
658
|
//#endregion
|
|
@@ -674,6 +786,10 @@ let lastRenderLayouts = [];
|
|
|
674
786
|
function updateLastRenderLayouts(layouts) {
|
|
675
787
|
lastRenderLayouts = layouts;
|
|
676
788
|
}
|
|
789
|
+
/** Read the complete layout snapshot produced by the latest native frame. */
|
|
790
|
+
function getLastRenderLayouts() {
|
|
791
|
+
return lastRenderLayouts;
|
|
792
|
+
}
|
|
677
793
|
/** Look up the latest native layout for an element or component public instance. */
|
|
678
794
|
function getLastRenderLayout(node) {
|
|
679
795
|
const id = node?.id ?? node?.$el?.id;
|
|
@@ -689,6 +805,21 @@ function measureElement(node) {
|
|
|
689
805
|
};
|
|
690
806
|
}
|
|
691
807
|
//#endregion
|
|
808
|
+
//#region src/mouseRouting.ts
|
|
809
|
+
/** Hit-test one normalized mouse packet and route it through the host tree. */
|
|
810
|
+
function routeMouseInput(renderer, root, event, layouts) {
|
|
811
|
+
const target = renderer.hitTest(root, event.x, event.y, layouts);
|
|
812
|
+
if (target) renderer.dispatchInput(target.id, event);
|
|
813
|
+
}
|
|
814
|
+
/** Route first, then publish the packet even when a routed handler throws. */
|
|
815
|
+
function routeAndPublishMouseInput(renderer, root, event, layouts, sink) {
|
|
816
|
+
try {
|
|
817
|
+
if (root) routeMouseInput(renderer, root, event, layouts);
|
|
818
|
+
} finally {
|
|
819
|
+
sink.value = event;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
//#endregion
|
|
692
823
|
//#region src/nativeInput.ts
|
|
693
824
|
/** Accept only key event phases supported by the public Fresco protocol. */
|
|
694
825
|
function normalizeKeyEventType(value) {
|
|
@@ -719,6 +850,92 @@ function normalizeMouseEvent(event) {
|
|
|
719
850
|
} : void 0
|
|
720
851
|
};
|
|
721
852
|
}
|
|
853
|
+
/** Normalize one native input packet into the public Fresco event protocol. */
|
|
854
|
+
function normalizeInputEvent(event) {
|
|
855
|
+
switch (event.eventType) {
|
|
856
|
+
case "resize": return {
|
|
857
|
+
type: "resize",
|
|
858
|
+
width: event.width ?? 0,
|
|
859
|
+
height: event.height ?? 0
|
|
860
|
+
};
|
|
861
|
+
case "paste": return {
|
|
862
|
+
type: "paste",
|
|
863
|
+
text: event.text ?? ""
|
|
864
|
+
};
|
|
865
|
+
case "mouse": return normalizeMouseEvent(event);
|
|
866
|
+
case "focus": return {
|
|
867
|
+
type: "focus",
|
|
868
|
+
focused: event.key === "gained"
|
|
869
|
+
};
|
|
870
|
+
case "compositionstart":
|
|
871
|
+
case "compositionupdate":
|
|
872
|
+
case "compositionend": return {
|
|
873
|
+
type: event.eventType,
|
|
874
|
+
text: event.text ?? "",
|
|
875
|
+
cursor: event.cursor ?? 0
|
|
876
|
+
};
|
|
877
|
+
case "key": {
|
|
878
|
+
const modifiers = event.modifiers ?? {};
|
|
879
|
+
return {
|
|
880
|
+
type: "key",
|
|
881
|
+
key: event.key ?? void 0,
|
|
882
|
+
char: event.char ?? void 0,
|
|
883
|
+
ctrl: modifiers.ctrl ?? false,
|
|
884
|
+
alt: modifiers.alt ?? false,
|
|
885
|
+
shift: modifiers.shift ?? false,
|
|
886
|
+
meta: modifiers.meta ?? false,
|
|
887
|
+
super: modifiers.super ?? false,
|
|
888
|
+
hyper: modifiers.hyper ?? false,
|
|
889
|
+
capsLock: modifiers.capsLock ?? false,
|
|
890
|
+
numLock: modifiers.numLock ?? false,
|
|
891
|
+
eventType: normalizeKeyEventType(event.keyEventType)
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
default: return;
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
//#endregion
|
|
898
|
+
//#region src/hitTesting.ts
|
|
899
|
+
function clipsOverflow(value) {
|
|
900
|
+
return value === "hidden" || value === "scroll";
|
|
901
|
+
}
|
|
902
|
+
function clipsDescendants(node) {
|
|
903
|
+
const style = normalizeFrescoStyle(node.props.style);
|
|
904
|
+
return clipsOverflow(style?.overflow ?? style?.overflowX ?? style?.overflowY);
|
|
905
|
+
}
|
|
906
|
+
function containsPoint(layout, clip, x, y) {
|
|
907
|
+
return x >= layout.x && x < layout.x + layout.width && y >= layout.y && y < layout.y + layout.height && x >= clip.left && x < clip.right && y >= clip.top && y < clip.bottom;
|
|
908
|
+
}
|
|
909
|
+
/** Return the deepest topmost live host node under one native-layout coordinate. */
|
|
910
|
+
function hitTest(nodes, root, x, y, layouts) {
|
|
911
|
+
if (!Number.isFinite(x) || !Number.isFinite(y)) return void 0;
|
|
912
|
+
const byId = new Map(layouts.map((layout) => [layout.id, layout]));
|
|
913
|
+
const unbounded = {
|
|
914
|
+
left: Number.NEGATIVE_INFINITY,
|
|
915
|
+
top: Number.NEGATIVE_INFINITY,
|
|
916
|
+
right: Number.POSITIVE_INFINITY,
|
|
917
|
+
bottom: Number.POSITIVE_INFINITY
|
|
918
|
+
};
|
|
919
|
+
const visit = (node, ancestorClip) => {
|
|
920
|
+
const layout = byId.get(node.id);
|
|
921
|
+
const clips = clipsDescendants(node);
|
|
922
|
+
const childClip = layout ? {
|
|
923
|
+
left: clips ? Math.max(ancestorClip.left, layout.x) : ancestorClip.left,
|
|
924
|
+
top: clips ? Math.max(ancestorClip.top, layout.y) : ancestorClip.top,
|
|
925
|
+
right: clips ? Math.min(ancestorClip.right, layout.x + layout.width) : ancestorClip.right,
|
|
926
|
+
bottom: clips ? Math.min(ancestorClip.bottom, layout.y + layout.height) : ancestorClip.bottom
|
|
927
|
+
} : ancestorClip;
|
|
928
|
+
for (let index = node.children.length - 1; index >= 0; index -= 1) {
|
|
929
|
+
const child = node.children[index];
|
|
930
|
+
if (!child) continue;
|
|
931
|
+
const target = visit(child, childClip);
|
|
932
|
+
if (target) return target;
|
|
933
|
+
}
|
|
934
|
+
if (!layout || !nodes.has(node.id)) return void 0;
|
|
935
|
+
return containsPoint(layout, ancestorClip, x, y) ? node : void 0;
|
|
936
|
+
};
|
|
937
|
+
return visit(root, unbounded);
|
|
938
|
+
}
|
|
722
939
|
//#endregion
|
|
723
940
|
//#region src/renderer.ts
|
|
724
941
|
/**
|
|
@@ -891,6 +1108,9 @@ function mapElementType(type) {
|
|
|
891
1108
|
case "span": return "text";
|
|
892
1109
|
case "input":
|
|
893
1110
|
case "textinput": return "input";
|
|
1111
|
+
case "raw":
|
|
1112
|
+
case "framebuffer":
|
|
1113
|
+
case "frame-buffer": return "raw";
|
|
894
1114
|
default: return "box";
|
|
895
1115
|
}
|
|
896
1116
|
}
|
|
@@ -926,6 +1146,13 @@ function createRenderer$1(options = {}) {
|
|
|
926
1146
|
tree.onMutation();
|
|
927
1147
|
return true;
|
|
928
1148
|
},
|
|
1149
|
+
/**
|
|
1150
|
+
* Return the deepest topmost node under one native-layout coordinate.
|
|
1151
|
+
* Hidden and scroll overflow constrain descendant targeting on each axis.
|
|
1152
|
+
*/
|
|
1153
|
+
hitTest(root, x, y, layouts) {
|
|
1154
|
+
return hitTest(tree.nodes, root, x, y, layouts);
|
|
1155
|
+
},
|
|
929
1156
|
/** Route normalized input through capture, target, and bubble handlers. */
|
|
930
1157
|
dispatchInput(targetId, input) {
|
|
931
1158
|
const target = tree.nodes.get(targetId);
|
|
@@ -1037,6 +1264,43 @@ function isStaticItemNode(node) {
|
|
|
1037
1264
|
return node.props.internal_static_item === true || node.props.internalStaticItem === true;
|
|
1038
1265
|
}
|
|
1039
1266
|
//#endregion
|
|
1267
|
+
//#region src/terminalLifecycle.ts
|
|
1268
|
+
const CI_ENVIRONMENT_KEYS = [
|
|
1269
|
+
"CI",
|
|
1270
|
+
"CONTINUOUS_INTEGRATION",
|
|
1271
|
+
"BUILD_NUMBER",
|
|
1272
|
+
"RUN_ID"
|
|
1273
|
+
];
|
|
1274
|
+
function isTruthyEnvironmentValue(value) {
|
|
1275
|
+
if (!value) return false;
|
|
1276
|
+
return ![
|
|
1277
|
+
"0",
|
|
1278
|
+
"false",
|
|
1279
|
+
"no"
|
|
1280
|
+
].includes(value.toLowerCase());
|
|
1281
|
+
}
|
|
1282
|
+
function isCiEnvironment(env = process.env) {
|
|
1283
|
+
return CI_ENVIRONMENT_KEYS.some((key) => isTruthyEnvironmentValue(env[key]));
|
|
1284
|
+
}
|
|
1285
|
+
/** Resolve whether an application can own the interactive terminal lifecycle. */
|
|
1286
|
+
function detectInteractiveMode(interactive, stdout) {
|
|
1287
|
+
return interactive ?? (stdout.isTTY === true && !isCiEnvironment());
|
|
1288
|
+
}
|
|
1289
|
+
/** Initialize the native terminal modes required by an interactive application. */
|
|
1290
|
+
function initializeTerminal(native, options) {
|
|
1291
|
+
if (typeof native.initTerminalWithOptions === "function") native.initTerminalWithOptions({
|
|
1292
|
+
alternateScreen: options.alternateScreen,
|
|
1293
|
+
bracketedPaste: true,
|
|
1294
|
+
hideCursor: true,
|
|
1295
|
+
mouse: options.mouse,
|
|
1296
|
+
rawMode: true
|
|
1297
|
+
});
|
|
1298
|
+
else if (options.mouse) native.initTerminalWithMouse();
|
|
1299
|
+
else native.initTerminal();
|
|
1300
|
+
native.enableIme?.();
|
|
1301
|
+
native.initLayout();
|
|
1302
|
+
}
|
|
1303
|
+
//#endregion
|
|
1040
1304
|
//#region src/app.ts
|
|
1041
1305
|
/**
|
|
1042
1306
|
* Fresco App - Application instance management
|
|
@@ -1196,33 +1460,12 @@ function updateAppSize(context, width, height) {
|
|
|
1196
1460
|
context.width.value = width;
|
|
1197
1461
|
context.height.value = height;
|
|
1198
1462
|
}
|
|
1199
|
-
const CI_ENVIRONMENT_KEYS = [
|
|
1200
|
-
"CI",
|
|
1201
|
-
"CONTINUOUS_INTEGRATION",
|
|
1202
|
-
"BUILD_NUMBER",
|
|
1203
|
-
"RUN_ID"
|
|
1204
|
-
];
|
|
1205
|
-
function isTruthyEnvironmentValue(value) {
|
|
1206
|
-
if (!value) return false;
|
|
1207
|
-
return ![
|
|
1208
|
-
"0",
|
|
1209
|
-
"false",
|
|
1210
|
-
"no"
|
|
1211
|
-
].includes(value.toLowerCase());
|
|
1212
|
-
}
|
|
1213
|
-
function isCiEnvironment(env = process.env) {
|
|
1214
|
-
return CI_ENVIRONMENT_KEYS.some((key) => isTruthyEnvironmentValue(env[key]));
|
|
1215
|
-
}
|
|
1216
|
-
function detectInteractiveMode(options) {
|
|
1217
|
-
const stdout = options.stdout ?? process.stdout;
|
|
1218
|
-
return options.interactive ?? (stdout.isTTY === true && !isCiEnvironment());
|
|
1219
|
-
}
|
|
1220
1463
|
/**
|
|
1221
1464
|
* Create a Fresco TUI app
|
|
1222
1465
|
*/
|
|
1223
1466
|
function createApp(rootComponent, options = {}) {
|
|
1224
1467
|
const { mouse = false, exitOnCtrlC = true, onError } = options;
|
|
1225
|
-
const interactive = detectInteractiveMode(options);
|
|
1468
|
+
const interactive = detectInteractiveMode(options.interactive, options.stdout ?? process.stdout);
|
|
1226
1469
|
const screenReaderEnabled = ref(options.isScreenReaderEnabled ?? isScreenReaderEnabledByDefault());
|
|
1227
1470
|
const frameDelay = Math.max(1, Math.floor(1e3 / Math.max(1, options.maxFps ?? 30)));
|
|
1228
1471
|
let streamsContext;
|
|
@@ -1244,6 +1487,8 @@ function createApp(rootComponent, options = {}) {
|
|
|
1244
1487
|
let vueApp = null;
|
|
1245
1488
|
let rootElement = null;
|
|
1246
1489
|
let mounted = false;
|
|
1490
|
+
let pendingMount = null;
|
|
1491
|
+
let hasMountedSuccessfully = false;
|
|
1247
1492
|
let running = false;
|
|
1248
1493
|
let needsRender = true;
|
|
1249
1494
|
let appContext = null;
|
|
@@ -1255,6 +1500,8 @@ function createApp(rootComponent, options = {}) {
|
|
|
1255
1500
|
const renderedStaticItems = /* @__PURE__ */ new Map();
|
|
1256
1501
|
let cursorPosition;
|
|
1257
1502
|
let hasCursorOverride = false;
|
|
1503
|
+
let instance;
|
|
1504
|
+
const pluginInstallers = [];
|
|
1258
1505
|
let exitSettled = false;
|
|
1259
1506
|
let resolveExit = null;
|
|
1260
1507
|
let rejectExit = null;
|
|
@@ -1262,26 +1509,38 @@ function createApp(rootComponent, options = {}) {
|
|
|
1262
1509
|
resolveExit = resolve;
|
|
1263
1510
|
rejectExit = reject;
|
|
1264
1511
|
});
|
|
1265
|
-
const
|
|
1266
|
-
|
|
1512
|
+
const renderer = createRenderer$1({
|
|
1513
|
+
lifecycle: options.devtools?.lifecycle,
|
|
1514
|
+
onMutation() {
|
|
1515
|
+
needsRender = true;
|
|
1516
|
+
}
|
|
1267
1517
|
});
|
|
1268
|
-
|
|
1269
|
-
if (
|
|
1518
|
+
function publishRenderMetrics(root, layouts, start) {
|
|
1519
|
+
if (!options.devtools && !options.onRender) return;
|
|
1520
|
+
const metrics = {
|
|
1521
|
+
renderTime: performance.now() - start,
|
|
1522
|
+
nodeCount: treeToRenderNodes(root).length,
|
|
1523
|
+
layoutCount: layouts.length
|
|
1524
|
+
};
|
|
1525
|
+
options.devtools?.recordRender(root, layouts, metrics);
|
|
1526
|
+
options.onRender?.(metrics);
|
|
1527
|
+
}
|
|
1528
|
+
function mount() {
|
|
1529
|
+
if (mounted) return Promise.resolve();
|
|
1530
|
+
if (pendingMount) return pendingMount;
|
|
1531
|
+
pendingMount = Promise.resolve().then(performMount).finally(() => {
|
|
1532
|
+
pendingMount = null;
|
|
1533
|
+
});
|
|
1534
|
+
return pendingMount;
|
|
1535
|
+
}
|
|
1536
|
+
async function performMount() {
|
|
1537
|
+
const app = renderer.createApp(componentFromRoot(rootComponent));
|
|
1538
|
+
for (const install of pluginInstallers) install(app);
|
|
1270
1539
|
const n = interactive ? await loadNative() : null;
|
|
1271
|
-
if (n) {
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
hideCursor: true,
|
|
1276
|
-
mouse,
|
|
1277
|
-
rawMode: true
|
|
1278
|
-
});
|
|
1279
|
-
else if (mouse) n.initTerminalWithMouse();
|
|
1280
|
-
else n.initTerminal();
|
|
1281
|
-
n.enableIme?.();
|
|
1282
|
-
n.initLayout();
|
|
1283
|
-
}
|
|
1284
|
-
const app = createVueApp(componentFromRoot(rootComponent));
|
|
1540
|
+
if (n) initializeTerminal(n, {
|
|
1541
|
+
alternateScreen: options.alternateScreen === true,
|
|
1542
|
+
mouse
|
|
1543
|
+
});
|
|
1285
1544
|
const info = n?.getTerminalInfo() ?? {
|
|
1286
1545
|
width: streamsContext.stdout.columns ?? 80,
|
|
1287
1546
|
height: streamsContext.stdout.rows ?? 24
|
|
@@ -1289,9 +1548,7 @@ function createApp(rootComponent, options = {}) {
|
|
|
1289
1548
|
appContext = createAppContext({
|
|
1290
1549
|
width: info.width,
|
|
1291
1550
|
height: info.height,
|
|
1292
|
-
exit: (value) =>
|
|
1293
|
-
unmount(value);
|
|
1294
|
-
},
|
|
1551
|
+
exit: (value) => void unmount(value),
|
|
1295
1552
|
render,
|
|
1296
1553
|
clear,
|
|
1297
1554
|
waitUntilRenderFlush,
|
|
@@ -1317,10 +1574,18 @@ function createApp(rootComponent, options = {}) {
|
|
|
1317
1574
|
}
|
|
1318
1575
|
vueApp = app;
|
|
1319
1576
|
mounted = true;
|
|
1577
|
+
hasMountedSuccessfully = true;
|
|
1320
1578
|
running = true;
|
|
1321
1579
|
needsRender = true;
|
|
1322
1580
|
eventLoop();
|
|
1323
1581
|
}
|
|
1582
|
+
function use(plugin, ...pluginOptions) {
|
|
1583
|
+
if (pendingMount || hasMountedSuccessfully) throw new Error("Fresco plugins must be installed before the first successful mount");
|
|
1584
|
+
pluginInstallers.push((app) => {
|
|
1585
|
+
app.use(plugin, ...pluginOptions);
|
|
1586
|
+
});
|
|
1587
|
+
return instance;
|
|
1588
|
+
}
|
|
1324
1589
|
async function unmount(errorOrResult) {
|
|
1325
1590
|
if (!mounted) return;
|
|
1326
1591
|
running = false;
|
|
@@ -1357,7 +1622,11 @@ function createApp(rootComponent, options = {}) {
|
|
|
1357
1622
|
return exitPromise;
|
|
1358
1623
|
}
|
|
1359
1624
|
async function waitUntilRenderFlush() {
|
|
1360
|
-
|
|
1625
|
+
if (pendingMount) await pendingMount;
|
|
1626
|
+
await nextTick();
|
|
1627
|
+
if (!needsRender) return;
|
|
1628
|
+
needsRender = false;
|
|
1629
|
+
render();
|
|
1361
1630
|
}
|
|
1362
1631
|
function clear() {
|
|
1363
1632
|
if (!mounted) return;
|
|
@@ -1426,7 +1695,7 @@ function createApp(rootComponent, options = {}) {
|
|
|
1426
1695
|
if (!interactive) {
|
|
1427
1696
|
staticOutput = appendOutput(staticOutput, captureStaticOutput(rootElement, renderedStaticItems));
|
|
1428
1697
|
nonInteractiveOutput = renderPlainOutput(rootElement, staticOutput);
|
|
1429
|
-
|
|
1698
|
+
publishRenderMetrics(rootElement, [], start);
|
|
1430
1699
|
return;
|
|
1431
1700
|
}
|
|
1432
1701
|
if (!native) return;
|
|
@@ -1436,10 +1705,11 @@ function createApp(rootComponent, options = {}) {
|
|
|
1436
1705
|
if (renderNodes.length > 0) {
|
|
1437
1706
|
if (options.debug) streamsContext.stderr.write(`${JSON.stringify(renderNodes, null, 2)}\n`);
|
|
1438
1707
|
native.renderTree(renderNodes);
|
|
1439
|
-
|
|
1708
|
+
const layouts = "getLastRenderLayouts" in native ? native.getLastRenderLayouts() : [];
|
|
1709
|
+
updateLastRenderLayouts(layouts);
|
|
1440
1710
|
applyCursorOverride();
|
|
1441
1711
|
native.flushTerminal();
|
|
1442
|
-
|
|
1712
|
+
publishRenderMetrics(rootElement, layouts, start);
|
|
1443
1713
|
}
|
|
1444
1714
|
} catch (error) {
|
|
1445
1715
|
if (onError) onError(error);
|
|
@@ -1450,58 +1720,31 @@ function createApp(rootComponent, options = {}) {
|
|
|
1450
1720
|
return (await loadNative()).getTerminalInfo();
|
|
1451
1721
|
}
|
|
1452
1722
|
function dispatchEvent(event) {
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
};
|
|
1479
|
-
return;
|
|
1480
|
-
}
|
|
1481
|
-
if (event.eventType === "compositionstart" || event.eventType === "compositionupdate" || event.eventType === "compositionend") {
|
|
1482
|
-
lastCompositionEvent.value = {
|
|
1483
|
-
type: event.eventType,
|
|
1484
|
-
text: event.text ?? "",
|
|
1485
|
-
cursor: event.cursor ?? 0
|
|
1486
|
-
};
|
|
1487
|
-
return;
|
|
1488
|
-
}
|
|
1489
|
-
if (event.eventType === "key") {
|
|
1490
|
-
const modifiers = event.modifiers ?? {};
|
|
1491
|
-
lastKeyEvent.value = {
|
|
1492
|
-
type: "key",
|
|
1493
|
-
key: event.key ?? void 0,
|
|
1494
|
-
char: event.char ?? void 0,
|
|
1495
|
-
ctrl: modifiers.ctrl ?? false,
|
|
1496
|
-
alt: modifiers.alt ?? false,
|
|
1497
|
-
shift: modifiers.shift ?? false,
|
|
1498
|
-
meta: modifiers.meta ?? false,
|
|
1499
|
-
super: modifiers.super ?? false,
|
|
1500
|
-
hyper: modifiers.hyper ?? false,
|
|
1501
|
-
capsLock: modifiers.capsLock ?? false,
|
|
1502
|
-
numLock: modifiers.numLock ?? false,
|
|
1503
|
-
eventType: normalizeKeyEventType(event.keyEventType)
|
|
1504
|
-
};
|
|
1723
|
+
const normalized = normalizeInputEvent(event);
|
|
1724
|
+
if (!normalized) return;
|
|
1725
|
+
options.devtools?.recordInput(normalized);
|
|
1726
|
+
switch (normalized.type) {
|
|
1727
|
+
case "resize":
|
|
1728
|
+
lastResizeEvent.value = normalized;
|
|
1729
|
+
updateAppSize(appContext, normalized.width, normalized.height);
|
|
1730
|
+
break;
|
|
1731
|
+
case "paste":
|
|
1732
|
+
lastPasteEvent.value = normalized;
|
|
1733
|
+
break;
|
|
1734
|
+
case "mouse":
|
|
1735
|
+
routeAndPublishMouseInput(renderer, rootElement, normalized, getLastRenderLayouts(), lastMouseEvent);
|
|
1736
|
+
break;
|
|
1737
|
+
case "focus":
|
|
1738
|
+
lastFocusEvent.value = normalized;
|
|
1739
|
+
break;
|
|
1740
|
+
case "compositionstart":
|
|
1741
|
+
case "compositionupdate":
|
|
1742
|
+
case "compositionend":
|
|
1743
|
+
lastCompositionEvent.value = normalized;
|
|
1744
|
+
break;
|
|
1745
|
+
case "key":
|
|
1746
|
+
lastKeyEvent.value = normalized;
|
|
1747
|
+
break;
|
|
1505
1748
|
}
|
|
1506
1749
|
}
|
|
1507
1750
|
async function eventLoop() {
|
|
@@ -1538,7 +1781,8 @@ function createApp(rootComponent, options = {}) {
|
|
|
1538
1781
|
await new Promise((resolve) => setTimeout(resolve, frameDelay));
|
|
1539
1782
|
}
|
|
1540
1783
|
}
|
|
1541
|
-
|
|
1784
|
+
instance = {
|
|
1785
|
+
use,
|
|
1542
1786
|
mount,
|
|
1543
1787
|
unmount,
|
|
1544
1788
|
waitUntilExit,
|
|
@@ -1547,6 +1791,7 @@ function createApp(rootComponent, options = {}) {
|
|
|
1547
1791
|
clear,
|
|
1548
1792
|
getTerminalInfo
|
|
1549
1793
|
};
|
|
1794
|
+
return instance;
|
|
1550
1795
|
}
|
|
1551
1796
|
/**
|
|
1552
1797
|
* Ink-compatible helper that mounts immediately.
|
|
@@ -1609,6 +1854,6 @@ function renderToString(root, options = {}) {
|
|
|
1609
1854
|
return output;
|
|
1610
1855
|
}
|
|
1611
1856
|
//#endregion
|
|
1612
|
-
export {
|
|
1857
|
+
export { useFocusManager as A, useStdin as C, createFocusManager as D, FOCUS_KEY as E, isScreenReaderEnabledByDefault as F, createAppContext as M, useApp as N, provideFocusScope as O, SCREEN_READER_KEY as P, useStderr as S, useStreamsContext as T, CURSOR_KEY as _, lastMouseEvent as a, STREAMS_KEY as b, render as c, isStaticNode as d, createRenderer$1 as f, updateLastRenderLayouts as g, measureElement as h, lastKeyEvent as i, APP_KEY as j, useFocus as k, renderToString as l, getLastRenderLayout as m, lastCompositionEvent as n, lastPasteEvent as o, treeToRenderNodes as p, lastFocusEvent as r, lastResizeEvent as s, createApp as t, isStaticItemNode as u, createCursorContext as v, useStdout as w, createStreamsContext as x, useCursor as y };
|
|
1613
1858
|
|
|
1614
|
-
//# sourceMappingURL=app-
|
|
1859
|
+
//# sourceMappingURL=app-C_wFlWSV.mjs.map
|