@weasel-js/routing 1.11.0 → 1.11.1
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/{chunk-QBQQIFPI.js → chunk-KLBH7VFF.js} +172 -48
- package/dist/chunk-KLBH7VFF.js.map +1 -0
- package/dist/{index-CmfVvwWD.d.ts → index-Cb7ehEks.d.ts} +912 -766
- package/dist/index.d.ts +2 -2
- package/dist/index.js +34 -3
- package/dist/index.js.map +1 -1
- package/dist/{internal-21M1rTVo.d.ts → internal-Dcyz_cJv.d.ts} +9 -1
- package/dist/internal.d.ts +5 -5
- package/dist/react.d.ts +7 -7
- package/dist/react.js +84 -42
- package/dist/react.js.map +1 -1
- package/package.json +13 -13
- package/dist/chunk-QBQQIFPI.js.map +0 -1
package/dist/react.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createDepRegistry, createDispatcher, assembleEntries, liveScope, reportRouteConflicts, offhandKeyFor, makeToolOffhandAction, buildToolOffhandBindings, dlog, ScopeNode, tuneAction, createMenuHost, pushOwner, evaluateEnabled, tunedParams, validateActionId, validateActionDefaultBinding, isTool, depNodeOf, DepNode, buildDepsFromRequires, clientToCanvas,
|
|
1
|
+
import { createDepRegistry, createDispatchTrace, createDispatcher, assembleEntries, liveScope, reportRouteConflicts, offhandKeyFor, makeToolOffhandAction, buildToolOffhandBindings, dlog, ScopeNode, tuneAction, createMenuHost, pushOwner, evaluateEnabled, tunedParams, validateActionId, validateActionDefaultBinding, isTool, depNodeOf, DepNode, buildDepsFromRequires, clientToCanvas, LONG_PRESS_HAPTIC_MS, multiTouchGestureId, openPointerSession, addCarrySurface, carryGestureId, anyBinding, isEditableTarget, focusedControlOwnsKey, itemsFromClipboardData, itemsFromDataTransfer, itemTypesFromDataTransfer, actionCursor } from './chunk-KLBH7VFF.js';
|
|
2
2
|
import { createContext, useState, useContext, useEffect, useMemo, useRef, useCallback, useSyncExternalStore } from 'react';
|
|
3
3
|
import { isApplePlatform, heldPointers, createPointerRecognizer, isInControlWithin, longPressEvents, stylusOf } from '@weasel-js/gestures';
|
|
4
4
|
import { isDev, useLatest, useKitSettings, useStableByContent, sameList } from '@weasel-js/react';
|
|
@@ -108,7 +108,7 @@ function useDepSource(name, source) {
|
|
|
108
108
|
const registry = useDepRegistry();
|
|
109
109
|
const sourceRef = useLatest(source);
|
|
110
110
|
useEffect(() => {
|
|
111
|
-
return registry.register(name, () => sourceRef.current());
|
|
111
|
+
return registry.register(name, (below) => sourceRef.current(below));
|
|
112
112
|
}, [name, registry, sourceRef]);
|
|
113
113
|
}
|
|
114
114
|
var MenuHostContext = createContext(null);
|
|
@@ -419,6 +419,7 @@ function useToolLifecycle(opts) {
|
|
|
419
419
|
function createDispatchCore(src) {
|
|
420
420
|
const { canvas } = src;
|
|
421
421
|
let routedId = null;
|
|
422
|
+
let over = false;
|
|
422
423
|
const target = () => {
|
|
423
424
|
if (routedId === null) return src.root();
|
|
424
425
|
return src.views()?.targets().find((t) => t.id === routedId) ?? src.root();
|
|
@@ -461,12 +462,16 @@ function createDispatchCore(src) {
|
|
|
461
462
|
const [x, y] = clientToCanvas(canvas, cx, cy);
|
|
462
463
|
return { x, y };
|
|
463
464
|
},
|
|
464
|
-
dispatch: (ev, on) => {
|
|
465
|
+
dispatch: (ev, on, reach) => {
|
|
465
466
|
const d = on ?? dispatcherNow();
|
|
466
467
|
src.uses(d);
|
|
467
|
-
return d.handleInput(ev, ctxNow());
|
|
468
|
+
return d.handleInput(ev, reach ? { ...ctxNow(), keyReach: reach } : ctxNow());
|
|
468
469
|
},
|
|
469
470
|
holdsKeys: () => canvas ? src.actions().holdsKeys() : src.actions().isActive(),
|
|
471
|
+
pointerOver: () => over,
|
|
472
|
+
setPointerOver: (next) => {
|
|
473
|
+
over = canvas !== null && next;
|
|
474
|
+
},
|
|
470
475
|
activate: () => src.actions().activate(),
|
|
471
476
|
disposed: src.disposed
|
|
472
477
|
};
|
|
@@ -505,6 +510,25 @@ function dispatcherWatch(onChange) {
|
|
|
505
510
|
};
|
|
506
511
|
}
|
|
507
512
|
|
|
513
|
+
// src/interactions/dispatcher/underPointer.ts
|
|
514
|
+
function underPointer(view, mods, w) {
|
|
515
|
+
const affordance = view.affordanceAt?.(w) ?? void 0;
|
|
516
|
+
const body = view.classifyTarget?.(w);
|
|
517
|
+
return {
|
|
518
|
+
altKey: mods.altKey,
|
|
519
|
+
ctrlKey: mods.ctrlKey,
|
|
520
|
+
metaKey: mods.metaKey,
|
|
521
|
+
shiftKey: mods.shiftKey,
|
|
522
|
+
...affordance !== void 0 ? { affordance } : {},
|
|
523
|
+
...body?.body !== void 0 ? { bodyTarget: body.body } : {},
|
|
524
|
+
...body?.kind !== void 0 ? { bodyKind: body.kind } : {},
|
|
525
|
+
...body?.doubleClick !== void 0 ? { doubleClickBody: doubleClickBodyOf(body.doubleClick) } : {}
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
function doubleClickBodyOf(named) {
|
|
529
|
+
return { bodyTarget: named.body, ...named.kind !== void 0 ? { bodyKind: named.kind } : {} };
|
|
530
|
+
}
|
|
531
|
+
|
|
508
532
|
// src/interactions/dispatcher/channels/carry.ts
|
|
509
533
|
function carryInput(core) {
|
|
510
534
|
const { canvas } = core;
|
|
@@ -517,6 +541,7 @@ function carryInput(core) {
|
|
|
517
541
|
if (core.disposed()) return "unhandled";
|
|
518
542
|
const event = () => {
|
|
519
543
|
const w = core.toWorld(at.clientX, at.clientY);
|
|
544
|
+
const { affordance, bodyTarget, bodyKind } = underPointer(core.target(), at, w);
|
|
520
545
|
return {
|
|
521
546
|
kind: "carry",
|
|
522
547
|
stage,
|
|
@@ -530,7 +555,10 @@ function carryInput(core) {
|
|
|
530
555
|
altKey: at.altKey,
|
|
531
556
|
ctrlKey: at.ctrlKey,
|
|
532
557
|
metaKey: at.metaKey,
|
|
533
|
-
shiftKey: at.shiftKey
|
|
558
|
+
shiftKey: at.shiftKey,
|
|
559
|
+
...affordance !== void 0 ? { affordance } : {},
|
|
560
|
+
...bodyTarget !== void 0 ? { bodyTarget } : {},
|
|
561
|
+
...bodyKind !== void 0 ? { bodyKind } : {}
|
|
534
562
|
};
|
|
535
563
|
};
|
|
536
564
|
const routedNow = core.routedView();
|
|
@@ -541,13 +569,12 @@ function carryInput(core) {
|
|
|
541
569
|
return core.dispatch(event());
|
|
542
570
|
}
|
|
543
571
|
if (pinned.has(pointerId)) core.setRoutedView(pinned.get(pointerId));
|
|
544
|
-
if (stage
|
|
545
|
-
|
|
546
|
-
if (stage === "drop" && !core.dispatcherNow().inFlight().has(gestureIdFor(ev))) {
|
|
572
|
+
if (stage === "drop" || stage === "leave") pinned.delete(pointerId);
|
|
573
|
+
if (stage !== "leave" && !core.dispatcherNow().inFlight().has(carryGestureId(pointerId))) {
|
|
547
574
|
core.routeAt(null, at.clientX, at.clientY);
|
|
548
|
-
|
|
575
|
+
if (stage === "move") pinned.set(pointerId, core.routedView());
|
|
549
576
|
}
|
|
550
|
-
return core.dispatch(
|
|
577
|
+
return core.dispatch(event());
|
|
551
578
|
} finally {
|
|
552
579
|
core.setRoutedView(routedNow);
|
|
553
580
|
}
|
|
@@ -555,25 +582,6 @@ function carryInput(core) {
|
|
|
555
582
|
});
|
|
556
583
|
}
|
|
557
584
|
|
|
558
|
-
// src/interactions/dispatcher/underPointer.ts
|
|
559
|
-
function underPointer(view, mods, w) {
|
|
560
|
-
const affordance = view.affordanceAt?.(w) ?? void 0;
|
|
561
|
-
const body = view.classifyTarget?.(w);
|
|
562
|
-
return {
|
|
563
|
-
altKey: mods.altKey,
|
|
564
|
-
ctrlKey: mods.ctrlKey,
|
|
565
|
-
metaKey: mods.metaKey,
|
|
566
|
-
shiftKey: mods.shiftKey,
|
|
567
|
-
...affordance !== void 0 ? { affordance } : {},
|
|
568
|
-
...body?.body !== void 0 ? { bodyTarget: body.body } : {},
|
|
569
|
-
...body?.kind !== void 0 ? { bodyKind: body.kind } : {},
|
|
570
|
-
...body?.doubleClick !== void 0 ? { doubleClickBody: doubleClickBodyOf(body.doubleClick) } : {}
|
|
571
|
-
};
|
|
572
|
-
}
|
|
573
|
-
function doubleClickBodyOf(named) {
|
|
574
|
-
return { bodyTarget: named.body, ...named.kind !== void 0 ? { bodyKind: named.kind } : {} };
|
|
575
|
-
}
|
|
576
|
-
|
|
577
585
|
// src/interactions/dispatcher/channels/contextMenu.ts
|
|
578
586
|
function contextMenuInput(core, takeNativeHold) {
|
|
579
587
|
const { routeAt, toWorld, target, dispatch } = core;
|
|
@@ -618,6 +626,15 @@ function hoverCursorInput(core, paintedCursor, pointersHeld, cursorSink = () =>
|
|
|
618
626
|
};
|
|
619
627
|
let last = null;
|
|
620
628
|
let facts = null;
|
|
629
|
+
let heldHeard = null;
|
|
630
|
+
const hears = () => {
|
|
631
|
+
if (pointersHeld() === 0) {
|
|
632
|
+
heldHeard = null;
|
|
633
|
+
return true;
|
|
634
|
+
}
|
|
635
|
+
heldHeard ??= anyBinding(ctxNow(), (s) => s.kind === "hover" && s.held !== void 0);
|
|
636
|
+
return heldHeard;
|
|
637
|
+
};
|
|
621
638
|
const resolve = () => {
|
|
622
639
|
if (!canvas || !last) return;
|
|
623
640
|
if (pointersHeld() > 0 || dispatcherNow().inFlight().size > 0) {
|
|
@@ -635,7 +652,7 @@ function hoverCursorInput(core, paintedCursor, pointersHeld, cursorSink = () =>
|
|
|
635
652
|
const ctx = ctxNow();
|
|
636
653
|
const d = dispatcherNow();
|
|
637
654
|
const press = { kind: "pointerdown", x: w.x, y: w.y, clientX: h.clientX, clientY: h.clientY, ...where };
|
|
638
|
-
if (
|
|
655
|
+
if (ctx.trace?.recording()) ctx.trace.setLive(() => d.explain(press, ctx));
|
|
639
656
|
const click = { kind: "click", x: w.x, y: w.y, pressX: w.x, pressY: w.y, ...where };
|
|
640
657
|
const cursorOf = (r) => r ? actionCursor(r.action, r.params) : void 0;
|
|
641
658
|
const cursor = cursorOf(d.resolveOnly(press, ctx)) ?? cursorOf(dispatcherNow().resolveOnly(click, ctx));
|
|
@@ -657,16 +674,18 @@ function hoverCursorInput(core, paintedCursor, pointersHeld, cursorSink = () =>
|
|
|
657
674
|
const w = toWorld(at.clientX, at.clientY);
|
|
658
675
|
const where = underPointer(target(), at, w);
|
|
659
676
|
const from = facts ? { from: whereOf(facts.where) } : {};
|
|
677
|
+
const held = pointersHeld() > 0 ? { held: true } : {};
|
|
660
678
|
facts = { at, where };
|
|
661
|
-
dispatch({ kind: "hover", x: w.x, y: w.y, clientX: at.clientX, clientY: at.clientY, ...where, ...from });
|
|
679
|
+
dispatch({ kind: "hover", x: w.x, y: w.y, clientX: at.clientX, clientY: at.clientY, ...where, ...from, ...held });
|
|
662
680
|
};
|
|
663
681
|
return {
|
|
664
682
|
moved(e) {
|
|
665
683
|
last = hoverOf(e);
|
|
666
|
-
if (
|
|
684
|
+
if (hears()) hoverAt(last);
|
|
667
685
|
refresh();
|
|
668
686
|
},
|
|
669
687
|
released(e) {
|
|
688
|
+
heldHeard = null;
|
|
670
689
|
last = hoverOf(e);
|
|
671
690
|
refreshSoon();
|
|
672
691
|
},
|
|
@@ -678,7 +697,7 @@ function hoverCursorInput(core, paintedCursor, pointersHeld, cursorSink = () =>
|
|
|
678
697
|
}
|
|
679
698
|
facts = null;
|
|
680
699
|
last = null;
|
|
681
|
-
|
|
700
|
+
ctxNow().trace?.setLive(null);
|
|
682
701
|
paintedCursor()?.clearPointer();
|
|
683
702
|
override.clear();
|
|
684
703
|
},
|
|
@@ -687,7 +706,7 @@ function hoverCursorInput(core, paintedCursor, pointersHeld, cursorSink = () =>
|
|
|
687
706
|
const prev = last;
|
|
688
707
|
last = { ...last, altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey };
|
|
689
708
|
const changed = prev.altKey !== last.altKey || prev.ctrlKey !== last.ctrlKey || prev.metaKey !== last.metaKey || prev.shiftKey !== last.shiftKey;
|
|
690
|
-
if (changed &&
|
|
709
|
+
if (changed && hears()) hoverAt(last);
|
|
691
710
|
refreshSoon();
|
|
692
711
|
},
|
|
693
712
|
clear: override.clear
|
|
@@ -792,15 +811,16 @@ function keyboardInput(core) {
|
|
|
792
811
|
const physicalKey = (e) => e.code || e.key.toLowerCase();
|
|
793
812
|
const onKeyDown = (e) => {
|
|
794
813
|
if (e.defaultPrevented || isEditableTarget(e.target) || inMenu(e.target) || focusedControlOwnsKey(e)) return;
|
|
795
|
-
|
|
814
|
+
const reach = { held: core.holdsKeys(), over: core.pointerOver() };
|
|
815
|
+
if (!reach.held && !reach.over) return;
|
|
796
816
|
if (e.repeat && heldKeys.has(physicalKey(e))) {
|
|
797
817
|
e.preventDefault();
|
|
798
818
|
return;
|
|
799
819
|
}
|
|
800
|
-
if (press(e, { altKey: e.altKey, ctrlKey: e.ctrlKey })) return;
|
|
801
|
-
if (typedWithAltGraph(e)) press(e, { altKey: false, ctrlKey: false });
|
|
820
|
+
if (press(e, { altKey: e.altKey, ctrlKey: e.ctrlKey }, reach)) return;
|
|
821
|
+
if (typedWithAltGraph(e)) press(e, { altKey: false, ctrlKey: false }, reach);
|
|
802
822
|
};
|
|
803
|
-
const press = (e, mods) => {
|
|
823
|
+
const press = (e, mods, reach) => {
|
|
804
824
|
const keyEv = {
|
|
805
825
|
kind: "key",
|
|
806
826
|
key: e.key,
|
|
@@ -810,7 +830,7 @@ function keyboardInput(core) {
|
|
|
810
830
|
shiftKey: e.shiftKey,
|
|
811
831
|
repeat: e.repeat
|
|
812
832
|
};
|
|
813
|
-
const keyResult = dispatch(keyEv);
|
|
833
|
+
const keyResult = dispatch(keyEv, void 0, reach);
|
|
814
834
|
const heldEv = {
|
|
815
835
|
kind: "key-held",
|
|
816
836
|
key: e.key,
|
|
@@ -821,7 +841,7 @@ function keyboardInput(core) {
|
|
|
821
841
|
shiftKey: e.shiftKey
|
|
822
842
|
};
|
|
823
843
|
const heldOn = dispatcherNow();
|
|
824
|
-
const heldResult = dispatch(heldEv, heldOn);
|
|
844
|
+
const heldResult = dispatch(heldEv, heldOn, reach);
|
|
825
845
|
if (heldResult === "handled") {
|
|
826
846
|
heldKeys.set(physicalKey(e), { key: e.key, ...codeOf(e), on: heldOn });
|
|
827
847
|
}
|
|
@@ -887,6 +907,7 @@ var sampleOf = (e) => ({
|
|
|
887
907
|
clientX: e.clientX,
|
|
888
908
|
clientY: e.clientY,
|
|
889
909
|
target: e.target,
|
|
910
|
+
timeStamp: e.timeStamp,
|
|
890
911
|
altKey: e.altKey,
|
|
891
912
|
ctrlKey: e.ctrlKey,
|
|
892
913
|
metaKey: e.metaKey,
|
|
@@ -1184,6 +1205,12 @@ function attachInput(canvas, src, channels) {
|
|
|
1184
1205
|
listeners.on(canvas, "pointerdown", () => {
|
|
1185
1206
|
src.actions().activate();
|
|
1186
1207
|
});
|
|
1208
|
+
const setOver = (on) => () => {
|
|
1209
|
+
core.setPointerOver(on);
|
|
1210
|
+
};
|
|
1211
|
+
listeners.on(canvas, "pointerenter", setOver(true));
|
|
1212
|
+
listeners.on(canvas, "pointermove", setOver(true));
|
|
1213
|
+
listeners.on(canvas, "pointerleave", setOver(false));
|
|
1187
1214
|
if (channels.pointer) {
|
|
1188
1215
|
listeners.on(window, "keydown", hover.onKey);
|
|
1189
1216
|
listeners.on(window, "keyup", hover.onKey);
|
|
@@ -1191,6 +1218,14 @@ function attachInput(canvas, src, channels) {
|
|
|
1191
1218
|
listeners.on(canvas, "pointerdown", pointer.onPointerDown);
|
|
1192
1219
|
listeners.on(canvas, "pointermove", pointer.onHoverMove);
|
|
1193
1220
|
listeners.on(canvas, "dblclick", pointer.onNativeDoubleClick);
|
|
1221
|
+
} else if (channels.hover) {
|
|
1222
|
+
listeners.on(window, "keydown", hover.onKey);
|
|
1223
|
+
listeners.on(window, "keyup", hover.onKey);
|
|
1224
|
+
listeners.on(canvas, "pointerleave", hover.onLeave);
|
|
1225
|
+
listeners.on(canvas, "pointermove", (e) => {
|
|
1226
|
+
core.routeAt(null, e.clientX, e.clientY);
|
|
1227
|
+
hover.moved(e);
|
|
1228
|
+
});
|
|
1194
1229
|
}
|
|
1195
1230
|
if (channels.wheel) {
|
|
1196
1231
|
listeners.on(canvas, "wheel", wheelInput(core, pinch.live), { passive: false, capture: true });
|
|
@@ -1227,8 +1262,9 @@ function attachInput(canvas, src, channels) {
|
|
|
1227
1262
|
|
|
1228
1263
|
// src/interactions/dispatcher/useGestureDispatcher.tsx
|
|
1229
1264
|
function useGestureDispatcher(opts) {
|
|
1230
|
-
const { canvasRef, actions, entriesById, enabled = true, keyboard = true, affordanceAt, classifyTarget, dispatcher: dispatcherOpt, clientToWorld, clientToLocal, requestRedraw, paintedCursor, cursorSink, getRuleCtx, onClick, onDoubleClick, views, channels, longPress, claimKeys = false, hears = "scope" } = opts;
|
|
1265
|
+
const { canvasRef, actions, entriesById, enabled = true, keyboard = true, affordanceAt, classifyTarget, dispatcher: dispatcherOpt, trace: traceOpt, clientToWorld, clientToLocal, requestRedraw, paintedCursor, cursorSink, getRuleCtx, onClick, onDoubleClick, views, channels, longPress, claimKeys = false, hears = "scope" } = opts;
|
|
1231
1266
|
const pointerChannel = channels?.pointer !== false;
|
|
1267
|
+
const hoverChannel = channels?.hover ?? pointerChannel;
|
|
1232
1268
|
const wheelChannel = channels?.wheel !== false;
|
|
1233
1269
|
const pinchChannel = channels?.pinch !== false;
|
|
1234
1270
|
const contextMenuChannel = channels?.contextMenu !== false;
|
|
@@ -1239,6 +1275,9 @@ function useGestureDispatcher(opts) {
|
|
|
1239
1275
|
const activeTool = useActiveToolContext();
|
|
1240
1276
|
const depRegistry = useDepRegistry();
|
|
1241
1277
|
const [isMac] = useState(isApplePlatform);
|
|
1278
|
+
const [ownTrace] = useState(createDispatchTrace);
|
|
1279
|
+
const trace = traceOpt ?? ownTrace;
|
|
1280
|
+
useEffect(() => depRegistry.register("dispatchTrace", () => trace), [depRegistry, trace]);
|
|
1242
1281
|
const dispatcherRef = useRef(null);
|
|
1243
1282
|
if (!dispatcherRef.current) {
|
|
1244
1283
|
dispatcherRef.current = dispatcherOpt ?? createDispatcher();
|
|
@@ -1254,7 +1293,8 @@ function useGestureDispatcher(opts) {
|
|
|
1254
1293
|
activeToolId: activeTool.active,
|
|
1255
1294
|
hotkeyStack: activeTool.hotkeyStack,
|
|
1256
1295
|
entriesById,
|
|
1257
|
-
isMac
|
|
1296
|
+
isMac,
|
|
1297
|
+
trace
|
|
1258
1298
|
});
|
|
1259
1299
|
const rootTargetRef = useLatest({
|
|
1260
1300
|
id: null,
|
|
@@ -1309,6 +1349,7 @@ function useGestureDispatcher(opts) {
|
|
|
1309
1349
|
}, {
|
|
1310
1350
|
keyboard,
|
|
1311
1351
|
pointer: pointerChannel,
|
|
1352
|
+
hover: hoverChannel,
|
|
1312
1353
|
wheel: wheelChannel,
|
|
1313
1354
|
pinch: pinchChannel,
|
|
1314
1355
|
contextMenu: contextMenuChannel,
|
|
@@ -1320,6 +1361,7 @@ function useGestureDispatcher(opts) {
|
|
|
1320
1361
|
keyboard,
|
|
1321
1362
|
canvasRef,
|
|
1322
1363
|
pointerChannel,
|
|
1364
|
+
hoverChannel,
|
|
1323
1365
|
wheelChannel,
|
|
1324
1366
|
pinchChannel,
|
|
1325
1367
|
contextMenuChannel,
|