@woven-canvas/core 1.3.1 → 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 +86 -29
- package/build/index.cjs.map +1 -1
- package/build/index.js +86 -29
- package/build/index.js.map +1 -1
- package/package.json +2 -2
package/build/index.js
CHANGED
|
@@ -1723,26 +1723,38 @@ var CursorKind = /* @__PURE__ */ ((CursorKind2) => {
|
|
|
1723
1723
|
})(CursorKind || {});
|
|
1724
1724
|
var DRAG_SVG = `
|
|
1725
1725
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 33.94 33.94">
|
|
1726
|
-
<
|
|
1727
|
-
<
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1726
|
+
<defs>
|
|
1727
|
+
<g id="a">
|
|
1728
|
+
<path d="M25.46,14.14l2.83,2.83-2.83,2.83"/>
|
|
1729
|
+
<path d="M19.8,16.97h8.49"/>
|
|
1730
|
+
<path d="M8.49,19.8l-2.83-2.83,2.83-2.83"/>
|
|
1731
|
+
<path d="M5.66,16.97h14.57"/>
|
|
1732
|
+
<path d="M14.14,25.46l2.83,2.83,2.83-2.83"/>
|
|
1733
|
+
<path d="M16.97,19.8v8.49"/>
|
|
1734
|
+
<path d="M19.8,8.49l-2.83-2.83-2.83,2.83"/>
|
|
1735
|
+
<path d="M16.97,5.66v15.14"/>
|
|
1736
|
+
</g>
|
|
1737
|
+
</defs>
|
|
1738
|
+
<g fill="none" stroke-linecap="round" stroke-linejoin="round">
|
|
1739
|
+
<use href="#a" stroke="#fff" stroke-width="4.5"/>
|
|
1740
|
+
<use href="#a" stroke="#000" stroke-width="2"/>
|
|
1735
1741
|
</g>
|
|
1736
1742
|
</svg>`;
|
|
1737
1743
|
function makeResizeSvg(rotateZ) {
|
|
1738
1744
|
const degrees = rotateZ * 180 / Math.PI;
|
|
1739
1745
|
return `
|
|
1740
1746
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
|
1741
|
-
fill="none" stroke
|
|
1747
|
+
fill="none" stroke-linecap="round" stroke-linejoin="round">
|
|
1748
|
+
<defs>
|
|
1749
|
+
<g id="a">
|
|
1750
|
+
<path d="M8 7l4 -4l4 4"/>
|
|
1751
|
+
<path d="M8 17l4 4l4 -4"/>
|
|
1752
|
+
<path d="M12 3l0 18"/>
|
|
1753
|
+
</g>
|
|
1754
|
+
</defs>
|
|
1742
1755
|
<g transform="rotate(${degrees} 12 12)">
|
|
1743
|
-
<
|
|
1744
|
-
<
|
|
1745
|
-
<path d="M12 3l0 18"/>
|
|
1756
|
+
<use href="#a" stroke="#fff" stroke-width="4.5"/>
|
|
1757
|
+
<use href="#a" stroke="#000" stroke-width="2"/>
|
|
1746
1758
|
</g>
|
|
1747
1759
|
</svg>`;
|
|
1748
1760
|
}
|
|
@@ -1750,11 +1762,17 @@ function makeRotateSvg(rotateZ) {
|
|
|
1750
1762
|
const degrees = rotateZ * 180 / Math.PI;
|
|
1751
1763
|
return `
|
|
1752
1764
|
<svg xmlns="http://www.w3.org/2000/svg" width="34" height="34" viewBox="-10 -10 34 34"
|
|
1753
|
-
fill="none" stroke
|
|
1765
|
+
fill="none" stroke-linecap="round" stroke-linejoin="round">
|
|
1766
|
+
<defs>
|
|
1767
|
+
<g id="a">
|
|
1768
|
+
<path d="M1,14.76l4,4,4-4"/>
|
|
1769
|
+
<path d="M14.61,1l4,4-4,4"/>
|
|
1770
|
+
<path d="M18.61,5h-6.02c-4.19,0-7.59,3.4-7.59,7.59v6.17"/>
|
|
1771
|
+
</g>
|
|
1772
|
+
</defs>
|
|
1754
1773
|
<g transform="rotate(${degrees} 8 8)">
|
|
1755
|
-
<
|
|
1756
|
-
<
|
|
1757
|
-
<path d="M18.61,5h-6.02c-4.19,0-7.59,3.4-7.59,7.59v6.17"/>
|
|
1774
|
+
<use href="#a" stroke="#fff" stroke-width="4.5"/>
|
|
1775
|
+
<use href="#a" stroke="#000" stroke-width="2"/>
|
|
1758
1776
|
</g>
|
|
1759
1777
|
</svg>`;
|
|
1760
1778
|
}
|
|
@@ -2019,6 +2037,8 @@ var KeyboardSchema = {
|
|
|
2019
2037
|
* Uses field.buffer for zero-allocation subarray views.
|
|
2020
2038
|
*/
|
|
2021
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),
|
|
2022
2042
|
/**
|
|
2023
2043
|
* Buffer for key-up triggers (true for exactly 1 frame when key is released).
|
|
2024
2044
|
* Uses field.buffer for zero-allocation subarray views.
|
|
@@ -2057,6 +2077,10 @@ var KeyboardDef = class extends CanvasSingletonDef3 {
|
|
|
2057
2077
|
isKeyDownTrigger(ctx, key) {
|
|
2058
2078
|
return getBit(this.read(ctx).keysDownTrigger, key);
|
|
2059
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
|
+
}
|
|
2060
2084
|
/**
|
|
2061
2085
|
* Check if a key was just released this frame.
|
|
2062
2086
|
* @param ctx - Editor context
|
|
@@ -2073,6 +2097,7 @@ var KeyboardDef = class extends CanvasSingletonDef3 {
|
|
|
2073
2097
|
const keyboard = this.write(ctx);
|
|
2074
2098
|
clearBits(keyboard.keysDown);
|
|
2075
2099
|
clearBits(keyboard.keysDownTrigger);
|
|
2100
|
+
clearBits(keyboard.keysRepeatTrigger);
|
|
2076
2101
|
clearBits(keyboard.keysUpTrigger);
|
|
2077
2102
|
keyboard.shiftDown = false;
|
|
2078
2103
|
keyboard.altDown = false;
|
|
@@ -2537,7 +2562,14 @@ var FrameContainmentState = defineEditorState("frameContainmentState", {
|
|
|
2537
2562
|
/** Current state machine state */
|
|
2538
2563
|
state: field27.string().max(16).default(FrameContainmentStateEnum.Idle),
|
|
2539
2564
|
/** EntityId of the frame currently highlighted as a drop target, or null */
|
|
2540
|
-
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()
|
|
2541
2573
|
});
|
|
2542
2574
|
|
|
2543
2575
|
// src/singletons/Grid.ts
|
|
@@ -2890,10 +2922,10 @@ function getFrameInput(ctx) {
|
|
|
2890
2922
|
}
|
|
2891
2923
|
|
|
2892
2924
|
// src/events/keyboardInputEvents.ts
|
|
2893
|
-
function getKeyboardInput(ctx, keys) {
|
|
2925
|
+
function getKeyboardInput(ctx, keys, options = {}) {
|
|
2894
2926
|
const events = [];
|
|
2895
2927
|
for (const key of keys) {
|
|
2896
|
-
if (Keyboard.isKeyDownTrigger(ctx, key)) {
|
|
2928
|
+
if (Keyboard.isKeyDownTrigger(ctx, key) || options.repeat && Keyboard.isKeyRepeatTrigger(ctx, key)) {
|
|
2897
2929
|
events.push({ type: "keyDown", key, ctx });
|
|
2898
2930
|
}
|
|
2899
2931
|
if (Keyboard.isKeyUpTrigger(ctx, key)) {
|
|
@@ -3753,8 +3785,7 @@ function clearPointerTrackingState(ctx) {
|
|
|
3753
3785
|
|
|
3754
3786
|
// src/systems/capture/captureFrameContainmentSystem.ts
|
|
3755
3787
|
var selectedQuery2 = defineQuery7((q) => q.with(Block, Selected));
|
|
3756
|
-
function spawnAssignments(ctx, targetFrame) {
|
|
3757
|
-
const draggedEntity = getDraggedEntity(ctx);
|
|
3788
|
+
function spawnAssignments(ctx, draggedEntity, targetFrame) {
|
|
3758
3789
|
if (draggedEntity === null) return;
|
|
3759
3790
|
const assignments = [];
|
|
3760
3791
|
if (hasComponent11(ctx, draggedEntity, TransformBox)) {
|
|
@@ -3802,25 +3833,44 @@ var frameContainmentMachine = setup({
|
|
|
3802
3833
|
if (targetFrame !== null) {
|
|
3803
3834
|
AddFrameHighlight.spawn(ctx, { frameId: targetFrame });
|
|
3804
3835
|
}
|
|
3805
|
-
spawnAssignments(ctx, targetFrame);
|
|
3836
|
+
spawnAssignments(ctx, getDraggedEntity(ctx), targetFrame);
|
|
3806
3837
|
}
|
|
3807
3838
|
return targetFrame;
|
|
3808
|
-
}
|
|
3839
|
+
},
|
|
3840
|
+
draggedEntity: ({ context, event }) => getDraggedEntity(event.ctx) ?? context.draggedEntity
|
|
3809
3841
|
}),
|
|
3810
3842
|
clearHighlight: ({ context, event }) => {
|
|
3811
3843
|
if (context.highlightedFrame !== null) {
|
|
3812
3844
|
RemoveFrameHighlight.spawn(event.ctx, { frameId: context.highlightedFrame });
|
|
3813
3845
|
}
|
|
3814
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
|
+
},
|
|
3815
3863
|
resetContext: assign({
|
|
3816
|
-
highlightedFrame: () => null
|
|
3864
|
+
highlightedFrame: () => null,
|
|
3865
|
+
draggedEntity: () => null
|
|
3817
3866
|
})
|
|
3818
3867
|
}
|
|
3819
3868
|
}).createMachine({
|
|
3820
3869
|
id: "frameContainment",
|
|
3821
3870
|
initial: FrameContainmentStateEnum.Idle,
|
|
3822
3871
|
context: {
|
|
3823
|
-
highlightedFrame: null
|
|
3872
|
+
highlightedFrame: null,
|
|
3873
|
+
draggedEntity: null
|
|
3824
3874
|
},
|
|
3825
3875
|
states: {
|
|
3826
3876
|
[FrameContainmentStateEnum.Idle]: {
|
|
@@ -3839,7 +3889,7 @@ var frameContainmentMachine = setup({
|
|
|
3839
3889
|
actions: "updateHighlight"
|
|
3840
3890
|
},
|
|
3841
3891
|
pointerUp: {
|
|
3842
|
-
actions: "clearHighlight",
|
|
3892
|
+
actions: ["dropByCenter", "clearHighlight"],
|
|
3843
3893
|
target: FrameContainmentStateEnum.Idle
|
|
3844
3894
|
},
|
|
3845
3895
|
cancel: {
|
|
@@ -4218,7 +4268,10 @@ function attachKeyboardListeners(domElement) {
|
|
|
4218
4268
|
const state = {
|
|
4219
4269
|
eventsBuffer: [],
|
|
4220
4270
|
onKeyDown: (e) => {
|
|
4221
|
-
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")) {
|
|
4222
4275
|
e.preventDefault();
|
|
4223
4276
|
}
|
|
4224
4277
|
state.eventsBuffer.push(e);
|
|
@@ -4253,14 +4306,17 @@ var keyboardSystem = defineEditorSystem({ phase: "input" }, (ctx) => {
|
|
|
4253
4306
|
});
|
|
4254
4307
|
const hasEvents = state.eventsBuffer.length > 0;
|
|
4255
4308
|
const keyboardRead = Keyboard.read(ctx);
|
|
4256
|
-
const triggersNeedClearing = !isZeroed(keyboardRead.keysDownTrigger) || !isZeroed(keyboardRead.keysUpTrigger);
|
|
4309
|
+
const triggersNeedClearing = !isZeroed(keyboardRead.keysDownTrigger) || !isZeroed(keyboardRead.keysUpTrigger) || !isZeroed(keyboardRead.keysRepeatTrigger);
|
|
4257
4310
|
if (!hasEvents && !triggersNeedClearing) return;
|
|
4258
4311
|
const keyboard = Keyboard.write(ctx);
|
|
4259
4312
|
clearBits(keyboard.keysDownTrigger);
|
|
4313
|
+
clearBits(keyboard.keysRepeatTrigger);
|
|
4260
4314
|
clearBits(keyboard.keysUpTrigger);
|
|
4261
4315
|
for (const event of state.eventsBuffer) {
|
|
4262
4316
|
if (event.type === "blur") {
|
|
4263
4317
|
clearBits(keyboard.keysDown);
|
|
4318
|
+
clearBits(keyboard.keysDownTrigger);
|
|
4319
|
+
clearBits(keyboard.keysRepeatTrigger);
|
|
4264
4320
|
keyboard.shiftDown = false;
|
|
4265
4321
|
keyboard.altDown = false;
|
|
4266
4322
|
keyboard.modDown = false;
|
|
@@ -4273,6 +4329,7 @@ var keyboardSystem = defineEditorSystem({ phase: "input" }, (ctx) => {
|
|
|
4273
4329
|
if (!wasDown || !event.repeat) {
|
|
4274
4330
|
setBit(keyboard.keysDownTrigger, keyIndex, true);
|
|
4275
4331
|
}
|
|
4332
|
+
if (event.repeat) setBit(keyboard.keysRepeatTrigger, keyIndex, true);
|
|
4276
4333
|
setBit(keyboard.keysDown, keyIndex, true);
|
|
4277
4334
|
} else if (event.type === "keyup") {
|
|
4278
4335
|
setBit(keyboard.keysDown, keyIndex, false);
|