@woven-canvas/core 1.3.2 → 1.3.3
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/build/_tsup-dts-rollup.d.cts +6 -1
- package/build/_tsup-dts-rollup.d.ts +6 -1
- package/build/index.cjs +51 -12
- package/build/index.cjs.map +1 -1
- package/build/index.js +51 -12
- package/build/index.js.map +1 -1
- package/package.json +2 -2
package/build/index.js
CHANGED
|
@@ -2037,6 +2037,8 @@ var KeyboardSchema = {
|
|
|
2037
2037
|
* Uses field.buffer for zero-allocation subarray views.
|
|
2038
2038
|
*/
|
|
2039
2039
|
keysDownTrigger: field24.buffer(field24.uint8()).size(KEY_BUFFER_SIZE),
|
|
2040
|
+
/** Native key-repeat triggers, available separately from initial presses. */
|
|
2041
|
+
keysRepeatTrigger: field24.buffer(field24.uint8()).size(KEY_BUFFER_SIZE),
|
|
2040
2042
|
/**
|
|
2041
2043
|
* Buffer for key-up triggers (true for exactly 1 frame when key is released).
|
|
2042
2044
|
* Uses field.buffer for zero-allocation subarray views.
|
|
@@ -2075,6 +2077,10 @@ var KeyboardDef = class extends CanvasSingletonDef3 {
|
|
|
2075
2077
|
isKeyDownTrigger(ctx, key) {
|
|
2076
2078
|
return getBit(this.read(ctx).keysDownTrigger, key);
|
|
2077
2079
|
}
|
|
2080
|
+
/** Check whether a native key-repeat event occurred this frame. */
|
|
2081
|
+
isKeyRepeatTrigger(ctx, key) {
|
|
2082
|
+
return getBit(this.read(ctx).keysRepeatTrigger, key);
|
|
2083
|
+
}
|
|
2078
2084
|
/**
|
|
2079
2085
|
* Check if a key was just released this frame.
|
|
2080
2086
|
* @param ctx - Editor context
|
|
@@ -2091,6 +2097,7 @@ var KeyboardDef = class extends CanvasSingletonDef3 {
|
|
|
2091
2097
|
const keyboard = this.write(ctx);
|
|
2092
2098
|
clearBits(keyboard.keysDown);
|
|
2093
2099
|
clearBits(keyboard.keysDownTrigger);
|
|
2100
|
+
clearBits(keyboard.keysRepeatTrigger);
|
|
2094
2101
|
clearBits(keyboard.keysUpTrigger);
|
|
2095
2102
|
keyboard.shiftDown = false;
|
|
2096
2103
|
keyboard.altDown = false;
|
|
@@ -2555,7 +2562,14 @@ var FrameContainmentState = defineEditorState("frameContainmentState", {
|
|
|
2555
2562
|
/** Current state machine state */
|
|
2556
2563
|
state: field27.string().max(16).default(FrameContainmentStateEnum.Idle),
|
|
2557
2564
|
/** EntityId of the frame currently highlighted as a drop target, or null */
|
|
2558
|
-
highlightedFrame: field27.ref()
|
|
2565
|
+
highlightedFrame: field27.ref(),
|
|
2566
|
+
/**
|
|
2567
|
+
* The entity being dragged while Tracking (a block, or the TransformBox for a
|
|
2568
|
+
* multi-select), captured on pointerMove. The selection machine has already
|
|
2569
|
+
* left Dragging by the time our pointerUp runs, so the drop fallback can't
|
|
2570
|
+
* re-read it from SelectionState.
|
|
2571
|
+
*/
|
|
2572
|
+
draggedEntity: field27.ref()
|
|
2559
2573
|
});
|
|
2560
2574
|
|
|
2561
2575
|
// src/singletons/Grid.ts
|
|
@@ -2908,10 +2922,10 @@ function getFrameInput(ctx) {
|
|
|
2908
2922
|
}
|
|
2909
2923
|
|
|
2910
2924
|
// src/events/keyboardInputEvents.ts
|
|
2911
|
-
function getKeyboardInput(ctx, keys) {
|
|
2925
|
+
function getKeyboardInput(ctx, keys, options = {}) {
|
|
2912
2926
|
const events = [];
|
|
2913
2927
|
for (const key of keys) {
|
|
2914
|
-
if (Keyboard.isKeyDownTrigger(ctx, key)) {
|
|
2928
|
+
if (Keyboard.isKeyDownTrigger(ctx, key) || options.repeat && Keyboard.isKeyRepeatTrigger(ctx, key)) {
|
|
2915
2929
|
events.push({ type: "keyDown", key, ctx });
|
|
2916
2930
|
}
|
|
2917
2931
|
if (Keyboard.isKeyUpTrigger(ctx, key)) {
|
|
@@ -3771,8 +3785,7 @@ function clearPointerTrackingState(ctx) {
|
|
|
3771
3785
|
|
|
3772
3786
|
// src/systems/capture/captureFrameContainmentSystem.ts
|
|
3773
3787
|
var selectedQuery2 = defineQuery7((q) => q.with(Block, Selected));
|
|
3774
|
-
function spawnAssignments(ctx, targetFrame) {
|
|
3775
|
-
const draggedEntity = getDraggedEntity(ctx);
|
|
3788
|
+
function spawnAssignments(ctx, draggedEntity, targetFrame) {
|
|
3776
3789
|
if (draggedEntity === null) return;
|
|
3777
3790
|
const assignments = [];
|
|
3778
3791
|
if (hasComponent11(ctx, draggedEntity, TransformBox)) {
|
|
@@ -3820,25 +3833,44 @@ var frameContainmentMachine = setup({
|
|
|
3820
3833
|
if (targetFrame !== null) {
|
|
3821
3834
|
AddFrameHighlight.spawn(ctx, { frameId: targetFrame });
|
|
3822
3835
|
}
|
|
3823
|
-
spawnAssignments(ctx, targetFrame);
|
|
3836
|
+
spawnAssignments(ctx, getDraggedEntity(ctx), targetFrame);
|
|
3824
3837
|
}
|
|
3825
3838
|
return targetFrame;
|
|
3826
|
-
}
|
|
3839
|
+
},
|
|
3840
|
+
draggedEntity: ({ context, event }) => getDraggedEntity(event.ctx) ?? context.draggedEntity
|
|
3827
3841
|
}),
|
|
3828
3842
|
clearHighlight: ({ context, event }) => {
|
|
3829
3843
|
if (context.highlightedFrame !== null) {
|
|
3830
3844
|
RemoveFrameHighlight.spawn(event.ctx, { frameId: context.highlightedFrame });
|
|
3831
3845
|
}
|
|
3832
3846
|
},
|
|
3847
|
+
// Drop fallback. Tracking resolves the target frame from the CURSOR so the
|
|
3848
|
+
// highlight follows the hand, but a drag can release with the cursor off every
|
|
3849
|
+
// frame (the gutter between two pages, just past an edge) while the dragged
|
|
3850
|
+
// block itself still sits on one. Without this the block goes loose
|
|
3851
|
+
// (`parentId: null`) yet looks untouched — and anything that only renders a
|
|
3852
|
+
// frame's children (page captures / print) silently drops it. On pointerUp
|
|
3853
|
+
// with no cursor target, re-resolve by the dragged block's center — the same
|
|
3854
|
+
// rule paste and PlaceBlockEvent use — and parent it there.
|
|
3855
|
+
dropByCenter: ({ context, event }) => {
|
|
3856
|
+
if (context.highlightedFrame !== null) return;
|
|
3857
|
+
const ctx = event.ctx;
|
|
3858
|
+
const draggedEntity = context.draggedEntity;
|
|
3859
|
+
if (draggedEntity === null || !hasComponent11(ctx, draggedEntity, Block)) return;
|
|
3860
|
+
const targetFrame = findFrameAtPoint(ctx, Block.getCenter(ctx, draggedEntity), draggedEntity);
|
|
3861
|
+
if (targetFrame !== null) spawnAssignments(ctx, draggedEntity, targetFrame);
|
|
3862
|
+
},
|
|
3833
3863
|
resetContext: assign({
|
|
3834
|
-
highlightedFrame: () => null
|
|
3864
|
+
highlightedFrame: () => null,
|
|
3865
|
+
draggedEntity: () => null
|
|
3835
3866
|
})
|
|
3836
3867
|
}
|
|
3837
3868
|
}).createMachine({
|
|
3838
3869
|
id: "frameContainment",
|
|
3839
3870
|
initial: FrameContainmentStateEnum.Idle,
|
|
3840
3871
|
context: {
|
|
3841
|
-
highlightedFrame: null
|
|
3872
|
+
highlightedFrame: null,
|
|
3873
|
+
draggedEntity: null
|
|
3842
3874
|
},
|
|
3843
3875
|
states: {
|
|
3844
3876
|
[FrameContainmentStateEnum.Idle]: {
|
|
@@ -3857,7 +3889,7 @@ var frameContainmentMachine = setup({
|
|
|
3857
3889
|
actions: "updateHighlight"
|
|
3858
3890
|
},
|
|
3859
3891
|
pointerUp: {
|
|
3860
|
-
actions: "clearHighlight",
|
|
3892
|
+
actions: ["dropByCenter", "clearHighlight"],
|
|
3861
3893
|
target: FrameContainmentStateEnum.Idle
|
|
3862
3894
|
},
|
|
3863
3895
|
cancel: {
|
|
@@ -4236,7 +4268,10 @@ function attachKeyboardListeners(domElement) {
|
|
|
4236
4268
|
const state = {
|
|
4237
4269
|
eventsBuffer: [],
|
|
4238
4270
|
onKeyDown: (e) => {
|
|
4239
|
-
if (e.
|
|
4271
|
+
if (e.defaultPrevented) return;
|
|
4272
|
+
if (e.target instanceof Element && e.target.closest('input, textarea, select, [contenteditable]:not([contenteditable="false"]), [role="textbox"]'))
|
|
4273
|
+
return;
|
|
4274
|
+
if (e.key === "Tab" || e.key === "Alt" || e.key === " " || e.code.startsWith("Arrow")) {
|
|
4240
4275
|
e.preventDefault();
|
|
4241
4276
|
}
|
|
4242
4277
|
state.eventsBuffer.push(e);
|
|
@@ -4271,14 +4306,17 @@ var keyboardSystem = defineEditorSystem({ phase: "input" }, (ctx) => {
|
|
|
4271
4306
|
});
|
|
4272
4307
|
const hasEvents = state.eventsBuffer.length > 0;
|
|
4273
4308
|
const keyboardRead = Keyboard.read(ctx);
|
|
4274
|
-
const triggersNeedClearing = !isZeroed(keyboardRead.keysDownTrigger) || !isZeroed(keyboardRead.keysUpTrigger);
|
|
4309
|
+
const triggersNeedClearing = !isZeroed(keyboardRead.keysDownTrigger) || !isZeroed(keyboardRead.keysUpTrigger) || !isZeroed(keyboardRead.keysRepeatTrigger);
|
|
4275
4310
|
if (!hasEvents && !triggersNeedClearing) return;
|
|
4276
4311
|
const keyboard = Keyboard.write(ctx);
|
|
4277
4312
|
clearBits(keyboard.keysDownTrigger);
|
|
4313
|
+
clearBits(keyboard.keysRepeatTrigger);
|
|
4278
4314
|
clearBits(keyboard.keysUpTrigger);
|
|
4279
4315
|
for (const event of state.eventsBuffer) {
|
|
4280
4316
|
if (event.type === "blur") {
|
|
4281
4317
|
clearBits(keyboard.keysDown);
|
|
4318
|
+
clearBits(keyboard.keysDownTrigger);
|
|
4319
|
+
clearBits(keyboard.keysRepeatTrigger);
|
|
4282
4320
|
keyboard.shiftDown = false;
|
|
4283
4321
|
keyboard.altDown = false;
|
|
4284
4322
|
keyboard.modDown = false;
|
|
@@ -4291,6 +4329,7 @@ var keyboardSystem = defineEditorSystem({ phase: "input" }, (ctx) => {
|
|
|
4291
4329
|
if (!wasDown || !event.repeat) {
|
|
4292
4330
|
setBit(keyboard.keysDownTrigger, keyIndex, true);
|
|
4293
4331
|
}
|
|
4332
|
+
if (event.repeat) setBit(keyboard.keysRepeatTrigger, keyIndex, true);
|
|
4294
4333
|
setBit(keyboard.keysDown, keyIndex, true);
|
|
4295
4334
|
} else if (event.type === "keyup") {
|
|
4296
4335
|
setBit(keyboard.keysDown, keyIndex, false);
|