@fieldnotes/core 0.11.0 → 0.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/index.cjs CHANGED
@@ -398,7 +398,13 @@ function exportState(elements, camera, layers = []) {
398
398
  position: { ...camera.position },
399
399
  zoom: camera.zoom
400
400
  },
401
- elements: elements.map((el) => structuredClone(el)),
401
+ elements: elements.map((el) => {
402
+ const clone = structuredClone(el);
403
+ if (clone.type === "arrow") {
404
+ delete clone.cachedControlPoint;
405
+ }
406
+ return clone;
407
+ }),
402
408
  layers: layers.map((l) => ({ ...l }))
403
409
  };
404
410
  }
@@ -861,6 +867,7 @@ var InputHandler = class {
861
867
  historyRecorder;
862
868
  historyStack;
863
869
  isToolActive = false;
870
+ lastPointerEvent = null;
864
871
  abortController = new AbortController();
865
872
  setToolManager(toolManager, toolContext) {
866
873
  this.toolManager = toolManager;
@@ -868,6 +875,7 @@ var InputHandler = class {
868
875
  }
869
876
  destroy() {
870
877
  this.abortController.abort();
878
+ this.lastPointerEvent = null;
871
879
  }
872
880
  bind() {
873
881
  const opts = { signal: this.abortController.signal };
@@ -903,11 +911,12 @@ var InputHandler = class {
903
911
  this.lastPointer = { x: e.clientX, y: e.clientY };
904
912
  return;
905
913
  }
906
- if (this.activePointers.size === 1 && e.button === 0) {
914
+ if (this.activePointers.size === 1 && (e.button === 0 || e.pointerType === "touch" || e.pointerType === "pen")) {
907
915
  this.dispatchToolDown(e);
908
916
  }
909
917
  };
910
918
  onPointerMove = (e) => {
919
+ this.lastPointerEvent = e;
911
920
  if (this.activePointers.has(e.pointerId)) {
912
921
  this.activePointers.set(e.pointerId, { x: e.clientX, y: e.clientY });
913
922
  }
@@ -929,6 +938,10 @@ var InputHandler = class {
929
938
  }
930
939
  };
931
940
  onPointerUp = (e) => {
941
+ try {
942
+ this.element.releasePointerCapture(e.pointerId);
943
+ } catch {
944
+ }
932
945
  this.activePointers.delete(e.pointerId);
933
946
  if (this.activePointers.size < 2) {
934
947
  this.lastPinchDistance = 0;
@@ -961,6 +974,13 @@ var InputHandler = class {
961
974
  onKeyUp = (e) => {
962
975
  if (e.key === " ") {
963
976
  this.spaceHeld = false;
977
+ if (this.activePointers.size === 0) {
978
+ if (this.lastPointerEvent) {
979
+ this.dispatchToolHover(this.lastPointerEvent);
980
+ } else {
981
+ this.toolContext?.setCursor?.("default");
982
+ }
983
+ }
964
984
  }
965
985
  };
966
986
  startPinch() {
@@ -4561,7 +4581,10 @@ var Viewport = class {
4561
4581
  position: "relative",
4562
4582
  width: "100%",
4563
4583
  height: "100%",
4564
- overflow: "hidden"
4584
+ overflow: "hidden",
4585
+ overscrollBehavior: "none",
4586
+ userSelect: "none",
4587
+ webkitUserSelect: "none"
4565
4588
  });
4566
4589
  return el;
4567
4590
  }
package/dist/index.d.cts CHANGED
@@ -423,6 +423,7 @@ declare class InputHandler {
423
423
  private historyRecorder;
424
424
  private historyStack;
425
425
  private isToolActive;
426
+ private lastPointerEvent;
426
427
  private readonly abortController;
427
428
  constructor(element: HTMLElement, camera: Camera, options?: InputHandlerOptions);
428
429
  setToolManager(toolManager: ToolManager, toolContext: ToolContext): void;
package/dist/index.d.ts CHANGED
@@ -423,6 +423,7 @@ declare class InputHandler {
423
423
  private historyRecorder;
424
424
  private historyStack;
425
425
  private isToolActive;
426
+ private lastPointerEvent;
426
427
  private readonly abortController;
427
428
  constructor(element: HTMLElement, camera: Camera, options?: InputHandlerOptions);
428
429
  setToolManager(toolManager: ToolManager, toolContext: ToolContext): void;
package/dist/index.js CHANGED
@@ -292,7 +292,13 @@ function exportState(elements, camera, layers = []) {
292
292
  position: { ...camera.position },
293
293
  zoom: camera.zoom
294
294
  },
295
- elements: elements.map((el) => structuredClone(el)),
295
+ elements: elements.map((el) => {
296
+ const clone = structuredClone(el);
297
+ if (clone.type === "arrow") {
298
+ delete clone.cachedControlPoint;
299
+ }
300
+ return clone;
301
+ }),
296
302
  layers: layers.map((l) => ({ ...l }))
297
303
  };
298
304
  }
@@ -755,6 +761,7 @@ var InputHandler = class {
755
761
  historyRecorder;
756
762
  historyStack;
757
763
  isToolActive = false;
764
+ lastPointerEvent = null;
758
765
  abortController = new AbortController();
759
766
  setToolManager(toolManager, toolContext) {
760
767
  this.toolManager = toolManager;
@@ -762,6 +769,7 @@ var InputHandler = class {
762
769
  }
763
770
  destroy() {
764
771
  this.abortController.abort();
772
+ this.lastPointerEvent = null;
765
773
  }
766
774
  bind() {
767
775
  const opts = { signal: this.abortController.signal };
@@ -797,11 +805,12 @@ var InputHandler = class {
797
805
  this.lastPointer = { x: e.clientX, y: e.clientY };
798
806
  return;
799
807
  }
800
- if (this.activePointers.size === 1 && e.button === 0) {
808
+ if (this.activePointers.size === 1 && (e.button === 0 || e.pointerType === "touch" || e.pointerType === "pen")) {
801
809
  this.dispatchToolDown(e);
802
810
  }
803
811
  };
804
812
  onPointerMove = (e) => {
813
+ this.lastPointerEvent = e;
805
814
  if (this.activePointers.has(e.pointerId)) {
806
815
  this.activePointers.set(e.pointerId, { x: e.clientX, y: e.clientY });
807
816
  }
@@ -823,6 +832,10 @@ var InputHandler = class {
823
832
  }
824
833
  };
825
834
  onPointerUp = (e) => {
835
+ try {
836
+ this.element.releasePointerCapture(e.pointerId);
837
+ } catch {
838
+ }
826
839
  this.activePointers.delete(e.pointerId);
827
840
  if (this.activePointers.size < 2) {
828
841
  this.lastPinchDistance = 0;
@@ -855,6 +868,13 @@ var InputHandler = class {
855
868
  onKeyUp = (e) => {
856
869
  if (e.key === " ") {
857
870
  this.spaceHeld = false;
871
+ if (this.activePointers.size === 0) {
872
+ if (this.lastPointerEvent) {
873
+ this.dispatchToolHover(this.lastPointerEvent);
874
+ } else {
875
+ this.toolContext?.setCursor?.("default");
876
+ }
877
+ }
858
878
  }
859
879
  };
860
880
  startPinch() {
@@ -4455,7 +4475,10 @@ var Viewport = class {
4455
4475
  position: "relative",
4456
4476
  width: "100%",
4457
4477
  height: "100%",
4458
- overflow: "hidden"
4478
+ overflow: "hidden",
4479
+ overscrollBehavior: "none",
4480
+ userSelect: "none",
4481
+ webkitUserSelect: "none"
4459
4482
  });
4460
4483
  return el;
4461
4484
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fieldnotes/core",
3
- "version": "0.11.0",
3
+ "version": "0.11.1",
4
4
  "description": "Vanilla TypeScript infinite canvas engine",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -21,11 +21,6 @@
21
21
  "files": [
22
22
  "dist"
23
23
  ],
24
- "scripts": {
25
- "build": "tsup",
26
- "test": "vitest run",
27
- "test:watch": "vitest"
28
- },
29
24
  "license": "MIT",
30
25
  "repository": {
31
26
  "type": "git",
@@ -45,9 +40,19 @@
45
40
  "sdk"
46
41
  ],
47
42
  "devDependencies": {
43
+ "@playwright/test": "^1.60.0",
48
44
  "@vitest/coverage-v8": "^4.1.0",
49
45
  "jsdom": "^29.0.0",
50
46
  "tsup": "^8.5.1",
51
47
  "vitest": "^4.1.0"
48
+ },
49
+ "scripts": {
50
+ "build": "tsup",
51
+ "test": "vitest run",
52
+ "test:watch": "vitest",
53
+ "test:coverage": "vitest run --coverage",
54
+ "test:all": "vitest run --coverage",
55
+ "e2e": "playwright test --config e2e/playwright.config.ts",
56
+ "e2e:update": "playwright test --config e2e/playwright.config.ts --update-snapshots"
52
57
  }
53
- }
58
+ }