@vectojs/core 1.6.0 → 1.6.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/README.md CHANGED
@@ -112,6 +112,11 @@ This projection is intentionally thin. Applications still own accessible names,
112
112
  focus order, contrast, and correct control semantics. See the
113
113
  [accessibility guide](https://vectojs.org/learn/accessibility/).
114
114
 
115
+ Interactive projected nodes capture the active pointer on `pointerdown` and route
116
+ `pointermove`, `pointerup`, and `pointercancel` through normal VMT capture/bubble propagation.
117
+ Treat `pointercancel` as rollback: discard transient gesture state and do not create durable
118
+ history. Pointer capture is released safely on both completion paths.
119
+
115
120
  ## Static content projection
116
121
 
117
122
  Canvas-rendered text can opt into browser-native find, translation, selection, and copy without
package/dist/index.js CHANGED
@@ -816,15 +816,29 @@ var Scene = (_class2 = class _Scene {
816
816
  node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("pointerleave", node, e, false));
817
817
  });
818
818
  const capEl = el;
819
+ const releasePointer = (event) => {
820
+ if (typeof capEl.releasePointerCapture !== "function") return;
821
+ if (typeof capEl.hasPointerCapture === "function" && !capEl.hasPointerCapture(event.pointerId)) {
822
+ return;
823
+ }
824
+ try {
825
+ capEl.releasePointerCapture(event.pointerId);
826
+ } catch (error) {
827
+ if (!(error instanceof DOMException) || error.name !== "NotFoundError") throw error;
828
+ }
829
+ };
819
830
  el.addEventListener("pointerdown", (e) => {
820
831
  if (typeof capEl.setPointerCapture === "function") capEl.setPointerCapture(e.pointerId);
821
832
  node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("pointerdown", node, e));
822
833
  });
823
834
  el.addEventListener("pointerup", (e) => {
824
- if (typeof capEl.releasePointerCapture === "function")
825
- capEl.releasePointerCapture(e.pointerId);
835
+ releasePointer(e);
826
836
  node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("pointerup", node, e));
827
837
  });
838
+ el.addEventListener("pointercancel", (e) => {
839
+ releasePointer(e);
840
+ node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("pointercancel", node, e));
841
+ });
828
842
  el.addEventListener(
829
843
  "pointermove",
830
844
  (e) => node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("pointermove", node, e))
@@ -2513,7 +2527,14 @@ var DOMPortalEntity = (_class7 = class extends _chunkDFNK6OV6js.Entity {
2513
2527
  });
2514
2528
  this.resizeObserver.observe(this.domElement);
2515
2529
  }
2516
- const events = ["click", "pointerdown", "pointerup", "pointermove", "wheel"];
2530
+ const events = [
2531
+ "click",
2532
+ "pointerdown",
2533
+ "pointerup",
2534
+ "pointercancel",
2535
+ "pointermove",
2536
+ "wheel"
2537
+ ];
2517
2538
  for (const type of events) {
2518
2539
  const handler = (e) => {
2519
2540
  this.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)(type, this, e));
package/dist/index.mjs CHANGED
@@ -816,15 +816,29 @@ var Scene = class _Scene {
816
816
  node.dispatchEvent(new VectoJSEvent("pointerleave", node, e, false));
817
817
  });
818
818
  const capEl = el;
819
+ const releasePointer = (event) => {
820
+ if (typeof capEl.releasePointerCapture !== "function") return;
821
+ if (typeof capEl.hasPointerCapture === "function" && !capEl.hasPointerCapture(event.pointerId)) {
822
+ return;
823
+ }
824
+ try {
825
+ capEl.releasePointerCapture(event.pointerId);
826
+ } catch (error) {
827
+ if (!(error instanceof DOMException) || error.name !== "NotFoundError") throw error;
828
+ }
829
+ };
819
830
  el.addEventListener("pointerdown", (e) => {
820
831
  if (typeof capEl.setPointerCapture === "function") capEl.setPointerCapture(e.pointerId);
821
832
  node.dispatchEvent(new VectoJSEvent("pointerdown", node, e));
822
833
  });
823
834
  el.addEventListener("pointerup", (e) => {
824
- if (typeof capEl.releasePointerCapture === "function")
825
- capEl.releasePointerCapture(e.pointerId);
835
+ releasePointer(e);
826
836
  node.dispatchEvent(new VectoJSEvent("pointerup", node, e));
827
837
  });
838
+ el.addEventListener("pointercancel", (e) => {
839
+ releasePointer(e);
840
+ node.dispatchEvent(new VectoJSEvent("pointercancel", node, e));
841
+ });
828
842
  el.addEventListener(
829
843
  "pointermove",
830
844
  (e) => node.dispatchEvent(new VectoJSEvent("pointermove", node, e))
@@ -2513,7 +2527,14 @@ var DOMPortalEntity = class extends Entity {
2513
2527
  });
2514
2528
  this.resizeObserver.observe(this.domElement);
2515
2529
  }
2516
- const events = ["click", "pointerdown", "pointerup", "pointermove", "wheel"];
2530
+ const events = [
2531
+ "click",
2532
+ "pointerdown",
2533
+ "pointerup",
2534
+ "pointercancel",
2535
+ "pointermove",
2536
+ "wheel"
2537
+ ];
2517
2538
  for (const type of events) {
2518
2539
  const handler = (e) => {
2519
2540
  this.dispatchEvent(new VectoJSEvent(type, this, e));
@@ -162,7 +162,7 @@ export interface A11yAttributes {
162
162
  /**
163
163
  * Union of all pointer/interaction events that can be emitted by an {@link Entity}.
164
164
  */
165
- export type VectoEvent = 'click' | 'hover' | 'pointerdown' | 'pointerup' | 'pointermove' | 'pointerleave' | 'change' | 'focus' | 'blur' | 'wheel' | 'keydown' | 'keyup';
165
+ export type VectoEvent = 'click' | 'hover' | 'pointerdown' | 'pointerup' | 'pointercancel' | 'pointermove' | 'pointerleave' | 'change' | 'focus' | 'blur' | 'wheel' | 'keydown' | 'keyup';
166
166
  /** Options for {@link Entity.on} / {@link Entity.off}. */
167
167
  export interface ListenerOptions {
168
168
  /** Register the listener for the capture phase (root→target) instead of bubble. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vectojs/core",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },