@bwp-web/canvas 0.14.0 → 0.14.2

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.
@@ -14,6 +14,12 @@ export interface CanvasTooltipState<T> {
14
14
  x: number;
15
15
  y: number;
16
16
  };
17
+ /**
18
+ * Ref to attach to the tooltip container element. When attached, position
19
+ * updates during pan/zoom are applied directly to the DOM — no React
20
+ * re-renders. The element should use `position: absolute`.
21
+ */
22
+ ref: RefObject<HTMLDivElement | null>;
17
23
  }
18
24
  /**
19
25
  * Track mouse hover over canvas objects and return tooltip state, using the
@@ -36,6 +42,9 @@ export declare function useCanvasTooltip<T>(options: UseCanvasTooltipOptions<T>)
36
42
  * coordinates relative to the canvas container element — suitable for absolute
37
43
  * positioning of a tooltip component.
38
44
  *
45
+ * Attach {@link CanvasTooltipState.ref | tooltip.ref} to the tooltip container
46
+ * for smooth, re-render-free position updates during pan and zoom.
47
+ *
39
48
  * @example
40
49
  * ```tsx
41
50
  * const tooltip = useCanvasTooltip(view.canvasRef, {
@@ -46,7 +55,10 @@ export declare function useCanvasTooltip<T>(options: UseCanvasTooltipOptions<T>)
46
55
  * <>
47
56
  * <Canvas onReady={view.onReady} />
48
57
  * {tooltip.visible && (
49
- * <div style={{ position: 'absolute', left: tooltip.position.x, top: tooltip.position.y }}>
58
+ * <div
59
+ * ref={tooltip.ref}
60
+ * style={{ position: 'absolute', left: tooltip.position.x, top: tooltip.position.y }}
61
+ * >
50
62
  * {tooltip.content?.id}
51
63
  * </div>
52
64
  * )}
@@ -1 +1 @@
1
- {"version":3,"file":"useCanvasTooltip.d.ts","sourceRoot":"","sources":["../../src/hooks/useCanvasTooltip.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACpE,OAAO,KAAK,EACV,MAAM,IAAI,YAAY,EAEtB,YAAY,EACb,MAAM,QAAQ,CAAC;AAGhB,MAAM,WAAW,uBAAuB,CAAC,CAAC;IACxC,wFAAwF;IACxF,UAAU,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,CAAC,GAAG,IAAI,CAAC;CAC7C;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACnC,gDAAgD;IAChD,OAAO,EAAE,OAAO,CAAC;IACjB,4EAA4E;IAC5E,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC;IAClB,gFAAgF;IAChF,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACpC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,OAAO,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAClC,kBAAkB,CAAC,CAAC,CAAC,CAAC;AACzB;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,SAAS,EAAE,SAAS,CAAC,YAAY,GAAG,IAAI,CAAC,EACzC,OAAO,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAClC,kBAAkB,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"useCanvasTooltip.d.ts","sourceRoot":"","sources":["../../src/hooks/useCanvasTooltip.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACpE,OAAO,KAAK,EACV,MAAM,IAAI,YAAY,EAEtB,YAAY,EACb,MAAM,QAAQ,CAAC;AAGhB,MAAM,WAAW,uBAAuB,CAAC,CAAC;IACxC,wFAAwF;IACxF,UAAU,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,CAAC,GAAG,IAAI,CAAC;CAC7C;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACnC,gDAAgD;IAChD,OAAO,EAAE,OAAO,CAAC;IACjB,4EAA4E;IAC5E,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC;IAClB,gFAAgF;IAChF,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC;;;;OAIG;IACH,GAAG,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CACvC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,OAAO,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAClC,kBAAkB,CAAC,CAAC,CAAC,CAAC;AACzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,SAAS,EAAE,SAAS,CAAC,YAAY,GAAG,IAAI,CAAC,EACzC,OAAO,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAClC,kBAAkB,CAAC,CAAC,CAAC,CAAC"}
package/dist/index.cjs CHANGED
@@ -258,6 +258,7 @@ function setupMousePan(canvas, getMode, isEnabled) {
258
258
  const isModifiedSelect = e instanceof MouseEvent && mode === "select" && (e.metaKey || e.ctrlKey);
259
259
  const shouldPan = mode === "pan" || isMiddleButton || isModifiedSelect || mode === "select" && !opt.target;
260
260
  if (shouldPan) {
261
+ e.preventDefault();
261
262
  isPanning = true;
262
263
  lastPanX = pos.x;
263
264
  lastPanY = pos.y;
@@ -1920,10 +1921,11 @@ function enableDrawToCreate(canvas, options) {
1920
1921
  const finalize = () => {
1921
1922
  removePreviewElements();
1922
1923
  snapping.clearSnapResult();
1923
- const obj = options?.factory ? options.factory(canvas, [...points]) : createPolygonFromVertices(canvas, points, options?.style);
1924
- if (options?.data) {
1925
- obj.data = options.data;
1926
- }
1924
+ const styleWithData = {
1925
+ ...options?.style,
1926
+ ...options?.data != null && { data: options.data }
1927
+ };
1928
+ const obj = options?.factory ? options.factory(canvas, [...points]) : createPolygonFromVertices(canvas, points, styleWithData);
1927
1929
  canvas.selection = previousSelection;
1928
1930
  canvas.requestRenderAll();
1929
1931
  restoreViewport(options?.viewport);
@@ -2083,6 +2085,10 @@ function enableDrawToCreate(canvas, options) {
2083
2085
  placeVertex(dragStartX, dragStartY);
2084
2086
  return;
2085
2087
  }
2088
+ const dragStyleWithData = {
2089
+ ...options?.style,
2090
+ ...options?.data != null && { data: options.data }
2091
+ };
2086
2092
  const obj = createPolygonFromVertices(
2087
2093
  canvas,
2088
2094
  [
@@ -2091,11 +2097,8 @@ function enableDrawToCreate(canvas, options) {
2091
2097
  { x: dragStartX + width, y: dragStartY + height },
2092
2098
  { x: dragStartX, y: dragStartY + height }
2093
2099
  ],
2094
- options?.style
2100
+ dragStyleWithData
2095
2101
  );
2096
- if (options?.data) {
2097
- obj.data = options.data;
2098
- }
2099
2102
  canvas.selection = previousSelection;
2100
2103
  canvas.requestRenderAll();
2101
2104
  restoreViewport(options?.viewport);
@@ -3258,8 +3261,10 @@ function useCanvasTooltip(canvasRefOrOptions, maybeOptions) {
3258
3261
  const [state, setState] = (0, import_react7.useState)({
3259
3262
  visible: false,
3260
3263
  content: null,
3261
- position: { x: 0, y: 0 }
3264
+ position: { x: 0, y: 0 },
3265
+ ref: { current: null }
3262
3266
  });
3267
+ const tooltipElRef = (0, import_react7.useRef)(null);
3263
3268
  const hoveredObjectRef = (0, import_react7.useRef)(null);
3264
3269
  const optionsRef = (0, import_react7.useRef)(options);
3265
3270
  optionsRef.current = options;
@@ -3276,6 +3281,12 @@ function useCanvasTooltip(canvasRefOrOptions, maybeOptions) {
3276
3281
  y: bounds.top * zoom + vt[5] - 10
3277
3282
  };
3278
3283
  }
3284
+ function applyPositionToDOM(position) {
3285
+ const el = tooltipElRef.current;
3286
+ if (!el) return;
3287
+ el.style.left = `${position.x}px`;
3288
+ el.style.top = `${position.y}px`;
3289
+ }
3279
3290
  const handleMouseOver = (e) => {
3280
3291
  const target = e.target;
3281
3292
  if (!target) return;
@@ -3285,7 +3296,7 @@ function useCanvasTooltip(canvasRefOrOptions, maybeOptions) {
3285
3296
  hoveredObjectRef.current = target;
3286
3297
  const position = calculatePosition(target);
3287
3298
  if (position) {
3288
- setState({ visible: true, content, position });
3299
+ setState({ visible: true, content, position, ref: tooltipElRef });
3289
3300
  }
3290
3301
  }
3291
3302
  };
@@ -3299,7 +3310,7 @@ function useCanvasTooltip(canvasRefOrOptions, maybeOptions) {
3299
3310
  if (!hoveredObjectRef.current) return;
3300
3311
  const position = calculatePosition(hoveredObjectRef.current);
3301
3312
  if (position) {
3302
- setState((prev) => prev.visible ? { ...prev, position } : prev);
3313
+ applyPositionToDOM(position);
3303
3314
  }
3304
3315
  };
3305
3316
  canvas.on("mouse:over", handleMouseOver);