canvu-react 0.4.64 → 0.4.65

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/react.d.cts CHANGED
@@ -4,8 +4,8 @@ import { I as IndexedDbImageStore } from './asset-hydration-F6aM5C7x.cjs';
4
4
  export { H as HydratedSceneItemsWithAssetsResult, h as hydrateSceneItemsWithAssets } from './asset-hydration-F6aM5C7x.cjs';
5
5
  import { V as VectorViewportAssetKind, a as VectorViewportAssetStore } from './asset-store-35ysK28r.cjs';
6
6
  export { b as VectorViewportAssetHydrationRequest, c as VectorViewportAssetResolveRequest, d as VectorViewportAssetResolveResult, e as VectorViewportAssetUploadRequest, f as VectorViewportAssetUploadResult } from './asset-store-35ysK28r.cjs';
7
- import { B as BoardComponentPosition, V as VectorToolDefinition, C as CustomShapePlacementOptions, a as CanvuBeforeInteractionHook, b as CanvuAfterInteractionHook, c as CanvasPlugin, d as VectorSelectionInspector } from './types-Ce4-OZbd.cjs';
8
- export { e as CanvasPluginComponentProps, f as CanvasPluginContribution, g as CanvasPluginItemsChangeMiddlewareContext, h as CanvasPluginRenderContext, i as CanvuAfterInteractionDetail, j as CanvuBeforeInteractionResult, k as CanvuChromeActiveToolStyle, l as CanvuChromeContext, m as CanvuChromeContextValue, n as CanvuChromeSelectionStyleChange, o as CanvuInteractionDetail, p as CanvuInteractionKind, q as CanvuInteractionOutcome, r as CanvuInteractionPoint, s as CanvuPluginContext, t as CanvuPluginContextValue, u as CanvuPluginViewportSnapshot, P as PlacementPreview, S as SelectModeItemClickDetail, v as SelectModeItemClickResult, w as VectorCanvasSpacePosition, x as VectorItemsChangeInfo, y as VectorItemsChangeMotive, z as VectorSelectionInspectorProps, A as VectorViewport, D as VectorViewportHandle, E as VectorViewportProps, W as WorldPointerDownDetail, F as createCanvuPlugin, G as getBoardPositionStyle, H as useCanvuChromeContext, I as useCanvuDocumentContext, J as useCanvuPluginContext, K as useCanvuPluginContribution, L as useCanvuResolvedTools, M as useCanvuViewportContext } from './types-Ce4-OZbd.cjs';
7
+ import { B as BoardComponentPosition, V as VectorToolDefinition, C as CustomShapePlacementOptions, a as CanvuBeforeInteractionHook, b as CanvuAfterInteractionHook, c as CanvasPlugin, d as VectorSelectionInspector } from './types-Bw3REwrb.cjs';
8
+ export { e as CanvasPluginComponentProps, f as CanvasPluginContribution, g as CanvasPluginItemsChangeMiddlewareContext, h as CanvasPluginRenderContext, i as CanvuAfterInteractionDetail, j as CanvuBeforeInteractionResult, k as CanvuChromeActiveToolStyle, l as CanvuChromeContext, m as CanvuChromeContextValue, n as CanvuChromeSelectionStyleChange, o as CanvuInteractionDetail, p as CanvuInteractionKind, q as CanvuInteractionOutcome, r as CanvuInteractionPoint, s as CanvuPluginContext, t as CanvuPluginContextValue, u as CanvuPluginViewportSnapshot, P as PlacementPreview, R as ReadOnlyInteractionOptions, v as ReadOnlyItemClickCandidateDetail, w as ReadOnlyItemClickScope, S as SelectModeItemClickDetail, x as SelectModeItemClickResult, y as VectorCanvasSpacePosition, z as VectorItemsChangeInfo, A as VectorItemsChangeMotive, D as VectorSelectionInspectorProps, E as VectorViewport, F as VectorViewportHandle, G as VectorViewportProps, W as WorldPointerDownDetail, H as createCanvuPlugin, I as getBoardPositionStyle, J as useCanvuChromeContext, K as useCanvuDocumentContext, L as useCanvuPluginContext, M as useCanvuPluginContribution, N as useCanvuResolvedTools, O as useCanvuViewportContext } from './types-Bw3REwrb.cjs';
9
9
  import * as react_jsx_runtime from 'react/jsx-runtime';
10
10
  import * as react from 'react';
11
11
  import { CSSProperties, ReactNode, ReactElement, SVGProps } from 'react';
package/dist/react.d.ts CHANGED
@@ -4,8 +4,8 @@ import { I as IndexedDbImageStore } from './asset-hydration-BSjiek7Q.js';
4
4
  export { H as HydratedSceneItemsWithAssetsResult, h as hydrateSceneItemsWithAssets } from './asset-hydration-BSjiek7Q.js';
5
5
  import { V as VectorViewportAssetKind, a as VectorViewportAssetStore } from './asset-store-D_FjW_CN.js';
6
6
  export { b as VectorViewportAssetHydrationRequest, c as VectorViewportAssetResolveRequest, d as VectorViewportAssetResolveResult, e as VectorViewportAssetUploadRequest, f as VectorViewportAssetUploadResult } from './asset-store-D_FjW_CN.js';
7
- import { B as BoardComponentPosition, V as VectorToolDefinition, C as CustomShapePlacementOptions, a as CanvuBeforeInteractionHook, b as CanvuAfterInteractionHook, c as CanvasPlugin, d as VectorSelectionInspector } from './types-PsLgDGZT.js';
8
- export { e as CanvasPluginComponentProps, f as CanvasPluginContribution, g as CanvasPluginItemsChangeMiddlewareContext, h as CanvasPluginRenderContext, i as CanvuAfterInteractionDetail, j as CanvuBeforeInteractionResult, k as CanvuChromeActiveToolStyle, l as CanvuChromeContext, m as CanvuChromeContextValue, n as CanvuChromeSelectionStyleChange, o as CanvuInteractionDetail, p as CanvuInteractionKind, q as CanvuInteractionOutcome, r as CanvuInteractionPoint, s as CanvuPluginContext, t as CanvuPluginContextValue, u as CanvuPluginViewportSnapshot, P as PlacementPreview, S as SelectModeItemClickDetail, v as SelectModeItemClickResult, w as VectorCanvasSpacePosition, x as VectorItemsChangeInfo, y as VectorItemsChangeMotive, z as VectorSelectionInspectorProps, A as VectorViewport, D as VectorViewportHandle, E as VectorViewportProps, W as WorldPointerDownDetail, F as createCanvuPlugin, G as getBoardPositionStyle, H as useCanvuChromeContext, I as useCanvuDocumentContext, J as useCanvuPluginContext, K as useCanvuPluginContribution, L as useCanvuResolvedTools, M as useCanvuViewportContext } from './types-PsLgDGZT.js';
7
+ import { B as BoardComponentPosition, V as VectorToolDefinition, C as CustomShapePlacementOptions, a as CanvuBeforeInteractionHook, b as CanvuAfterInteractionHook, c as CanvasPlugin, d as VectorSelectionInspector } from './types-BZUp3LpC.js';
8
+ export { e as CanvasPluginComponentProps, f as CanvasPluginContribution, g as CanvasPluginItemsChangeMiddlewareContext, h as CanvasPluginRenderContext, i as CanvuAfterInteractionDetail, j as CanvuBeforeInteractionResult, k as CanvuChromeActiveToolStyle, l as CanvuChromeContext, m as CanvuChromeContextValue, n as CanvuChromeSelectionStyleChange, o as CanvuInteractionDetail, p as CanvuInteractionKind, q as CanvuInteractionOutcome, r as CanvuInteractionPoint, s as CanvuPluginContext, t as CanvuPluginContextValue, u as CanvuPluginViewportSnapshot, P as PlacementPreview, R as ReadOnlyInteractionOptions, v as ReadOnlyItemClickCandidateDetail, w as ReadOnlyItemClickScope, S as SelectModeItemClickDetail, x as SelectModeItemClickResult, y as VectorCanvasSpacePosition, z as VectorItemsChangeInfo, A as VectorItemsChangeMotive, D as VectorSelectionInspectorProps, E as VectorViewport, F as VectorViewportHandle, G as VectorViewportProps, W as WorldPointerDownDetail, H as createCanvuPlugin, I as getBoardPositionStyle, J as useCanvuChromeContext, K as useCanvuDocumentContext, L as useCanvuPluginContext, M as useCanvuPluginContribution, N as useCanvuResolvedTools, O as useCanvuViewportContext } from './types-BZUp3LpC.js';
9
9
  import * as react_jsx_runtime from 'react/jsx-runtime';
10
10
  import * as react from 'react';
11
11
  import { CSSProperties, ReactNode, ReactElement, SVGProps } from 'react';
package/dist/react.js CHANGED
@@ -5646,7 +5646,7 @@ function attachViewportInput(options) {
5646
5646
  if (touchMomentum) {
5647
5647
  touchMomentum.cancel();
5648
5648
  }
5649
- const panOk = allowPrimaryPointerPan();
5649
+ const panOk = allowPrimaryPointerPan(e);
5650
5650
  if (e.pointerType === "mouse" && e.button === 0) {
5651
5651
  if (!panOk) {
5652
5652
  return;
@@ -7670,6 +7670,93 @@ function PresenceRemoteLayer({
7670
7670
  );
7671
7671
  }
7672
7672
 
7673
+ // src/react/read-only-activation.ts
7674
+ function findReadOnlyItemClickPlacement(item, placements) {
7675
+ const toolId = item.customToolId;
7676
+ if (!toolId) return null;
7677
+ return [...placements].reverse().find(
7678
+ (placement) => placement.toolId === toolId && placement.onSelectModeItemClick
7679
+ ) ?? null;
7680
+ }
7681
+ function resolveReadOnlyActivationTarget(input) {
7682
+ const {
7683
+ pointer,
7684
+ camera,
7685
+ container,
7686
+ items,
7687
+ detailItems = items,
7688
+ placements,
7689
+ scope,
7690
+ selectedIds
7691
+ } = input;
7692
+ const rect = container.getBoundingClientRect();
7693
+ const world = camera.screenToWorld(
7694
+ pointer.clientX - rect.left,
7695
+ pointer.clientY - rect.top
7696
+ );
7697
+ const hit = hitTestWorldPoint(items, world.worldX, world.worldY, {
7698
+ lineHitWorld: 10 / camera.zoom,
7699
+ ignoreLocked: true
7700
+ });
7701
+ if (!hit) return null;
7702
+ const customPlacement = findReadOnlyItemClickPlacement(hit, placements);
7703
+ if (customPlacement?.onSelectModeItemClick) {
7704
+ return {
7705
+ item: hit,
7706
+ activation: "custom",
7707
+ worldX: world.worldX,
7708
+ worldY: world.worldY
7709
+ };
7710
+ }
7711
+ if (scope === "all") {
7712
+ return {
7713
+ item: hit,
7714
+ activation: "read-only",
7715
+ worldX: world.worldX,
7716
+ worldY: world.worldY
7717
+ };
7718
+ }
7719
+ if (typeof scope === "function") {
7720
+ const allowed = scope({
7721
+ item: hit,
7722
+ worldX: world.worldX,
7723
+ worldY: world.worldY,
7724
+ clientX: pointer.clientX,
7725
+ clientY: pointer.clientY,
7726
+ pointerType: pointer.pointerType,
7727
+ shiftKey: pointer.shiftKey,
7728
+ altKey: pointer.altKey,
7729
+ metaKey: pointer.metaKey,
7730
+ ctrlKey: pointer.ctrlKey,
7731
+ items: detailItems,
7732
+ selectedIds
7733
+ });
7734
+ if (allowed) {
7735
+ return {
7736
+ item: hit,
7737
+ activation: "read-only",
7738
+ worldX: world.worldX,
7739
+ worldY: world.worldY
7740
+ };
7741
+ }
7742
+ }
7743
+ return null;
7744
+ }
7745
+ function createReadOnlyActivationSession(target, pointer) {
7746
+ return {
7747
+ pointerId: pointer.pointerId,
7748
+ itemId: target.item.id,
7749
+ activation: target.activation,
7750
+ startWorld: { x: target.worldX, y: target.worldY },
7751
+ startScreen: { x: pointer.clientX, y: pointer.clientY }
7752
+ };
7753
+ }
7754
+ function didReadOnlyActivationMovePastTap(session, pointer, tapPx) {
7755
+ const dx = pointer.clientX - session.startScreen.x;
7756
+ const dy = pointer.clientY - session.startScreen.y;
7757
+ return Math.hypot(dx, dy) > tapPx;
7758
+ }
7759
+
7673
7760
  // src/react/stable-selection.ts
7674
7761
  function shallowEqualStringArray(a, b) {
7675
7762
  if (a === b) return true;
@@ -8023,13 +8110,6 @@ function isDefaultMarkerToolStyle(style) {
8023
8110
  function tagCustomPlacementItem(item, toolId) {
8024
8111
  return item.customToolId === toolId ? item : { ...item, customToolId: toolId };
8025
8112
  }
8026
- function findSelectModeItemClickPlacement(item, placements) {
8027
- const toolId = item.customToolId;
8028
- if (!toolId) return null;
8029
- return [...placements].reverse().find(
8030
- (placement) => placement.toolId === toolId && placement.onSelectModeItemClick
8031
- ) ?? null;
8032
- }
8033
8113
  function mergeToolListById(baseTools, pluginTools) {
8034
8114
  const next = [...baseTools];
8035
8115
  for (const tool of pluginTools) {
@@ -8157,6 +8237,7 @@ var VectorViewport = forwardRef(
8157
8237
  toolId = "hand",
8158
8238
  applePencilNav = false,
8159
8239
  interactive = false,
8240
+ readOnlyInteraction,
8160
8241
  selectedIds: selectedIdsProp,
8161
8242
  onSelectionChange,
8162
8243
  onItemsChange: consumerOnItemsChange,
@@ -8359,6 +8440,8 @@ var VectorViewport = forwardRef(
8359
8440
  );
8360
8441
  const toolIdRef = useRef(toolId);
8361
8442
  const interactiveRef = useRef(interactive);
8443
+ const readOnlyInteractionRef = useRef(readOnlyInteraction);
8444
+ readOnlyInteractionRef.current = readOnlyInteraction;
8362
8445
  const reducedMotionRef = useRef(false);
8363
8446
  const itemsRef = useRef(items);
8364
8447
  const onWorldPointerDownRef = useRef(onWorldPointerDown);
@@ -8372,6 +8455,7 @@ var VectorViewport = forwardRef(
8372
8455
  const allCustomPlacementsRef = useRef(allCustomPlacements);
8373
8456
  allCustomPlacementsRef.current = allCustomPlacements;
8374
8457
  const dragStateRef = useRef({ kind: "idle" });
8458
+ const readOnlyItemClickStateRef = useRef(null);
8375
8459
  const clipboardRef = useRef(null);
8376
8460
  const undoStackRef = useRef([]);
8377
8461
  const redoStackRef = useRef([]);
@@ -8549,6 +8633,31 @@ var VectorViewport = forwardRef(
8549
8633
  );
8550
8634
  const resolvedItemsRef = useRef(resolvedItems);
8551
8635
  resolvedItemsRef.current = resolvedItems;
8636
+ const readOnlyActivationResolutionCacheRef = useRef(/* @__PURE__ */ new WeakMap());
8637
+ const resolveReadOnlyActivation = useCallback(
8638
+ (pointer) => {
8639
+ const cache = readOnlyActivationResolutionCacheRef.current;
8640
+ if (cache.has(pointer)) return cache.get(pointer) ?? null;
8641
+ let target = null;
8642
+ const cam = cameraRef.current;
8643
+ const container = sceneContainerRef.current;
8644
+ if (!interactiveRef.current && toolIdRef.current === "select" && cam && container) {
8645
+ target = resolveReadOnlyActivationTarget({
8646
+ pointer,
8647
+ camera: cam,
8648
+ container,
8649
+ items: resolvedItemsRef.current,
8650
+ detailItems: itemsRef.current,
8651
+ placements: allCustomPlacementsRef.current,
8652
+ scope: readOnlyInteractionRef.current?.itemClicks ?? "custom",
8653
+ selectedIds: effectiveSelectedIdsRef.current
8654
+ });
8655
+ }
8656
+ cache.set(pointer, target);
8657
+ return target;
8658
+ },
8659
+ []
8660
+ );
8552
8661
  const liveId = useId();
8553
8662
  const reducedMotion = usePrefersReducedMotion();
8554
8663
  reducedMotionRef.current = reducedMotion;
@@ -8978,12 +9087,14 @@ var VectorViewport = forwardRef(
8978
9087
  onUpdate: renderFrame,
8979
9088
  wheelElement: wrapperRef.current ?? void 0,
8980
9089
  touchHandledElsewhere: applePencilNav,
8981
- allowPrimaryPointerPan: () => {
9090
+ allowPrimaryPointerPan: (event) => {
8982
9091
  if (interactiveRef.current) {
8983
9092
  return toolIdRef.current === "hand";
8984
9093
  }
8985
9094
  const t = toolIdRef.current;
8986
- return t === "hand" || t === "select";
9095
+ if (t === "hand") return true;
9096
+ if (t !== "select") return false;
9097
+ return resolveReadOnlyActivation(event) === null;
8987
9098
  }
8988
9099
  });
8989
9100
  let detachPencil;
@@ -9004,7 +9115,7 @@ var VectorViewport = forwardRef(
9004
9115
  cameraRef.current = null;
9005
9116
  setCameraForOverlay(null);
9006
9117
  };
9007
- }, [applePencilNav, renderFrame]);
9118
+ }, [applePencilNav, renderFrame, resolveReadOnlyActivation]);
9008
9119
  useEffect(() => {
9009
9120
  rendererRef.current?.setInteractionState({
9010
9121
  selectedIds: effectiveSelectedIds,
@@ -9518,6 +9629,29 @@ var VectorViewport = forwardRef(
9518
9629
  const rect = el.getBoundingClientRect();
9519
9630
  return cam.screenToWorld(clientX - rect.left, clientY - rect.top);
9520
9631
  }, []);
9632
+ const buildSelectModeItemClickDetail = useCallback(
9633
+ (item, world, pointer) => ({
9634
+ item,
9635
+ worldX: world.worldX,
9636
+ worldY: world.worldY,
9637
+ clientX: pointer.clientX,
9638
+ clientY: pointer.clientY,
9639
+ pointerType: pointer.pointerType,
9640
+ shiftKey: pointer.shiftKey,
9641
+ altKey: pointer.altKey,
9642
+ metaKey: pointer.metaKey,
9643
+ ctrlKey: pointer.ctrlKey,
9644
+ items: itemsRef.current,
9645
+ updateItem: (next) => {
9646
+ onItemsChangeRef.current?.(replaceItem(itemsRef.current, item.id, next), {
9647
+ motive: "custom",
9648
+ itemIds: [item.id]
9649
+ });
9650
+ },
9651
+ setSelectedIds: (ids) => setEffectiveSelectedIdsRef.current(ids)
9652
+ }),
9653
+ []
9654
+ );
9521
9655
  const handleOverlayContextMenu = useCallback(
9522
9656
  (e) => {
9523
9657
  if (!interactiveRef.current || !onItemsChangeRef.current) return;
@@ -9944,6 +10078,118 @@ var VectorViewport = forwardRef(
9944
10078
  },
9945
10079
  [screenToWorld]
9946
10080
  );
10081
+ useEffect(() => {
10082
+ const root = interactionRootRef.current;
10083
+ if (!root) return;
10084
+ const onReadOnlyPointerDownCapture = (e) => {
10085
+ if (e.button !== 0) return;
10086
+ if (readOnlyItemClickStateRef.current) return;
10087
+ const target = resolveReadOnlyActivation(e);
10088
+ if (!target) return;
10089
+ const accepted = startCanvuInteraction({
10090
+ kind: "select-mode-item-click",
10091
+ toolId: "select",
10092
+ pointerType: e.pointerType,
10093
+ button: e.button,
10094
+ worldX: target.worldX,
10095
+ worldY: target.worldY,
10096
+ clientX: e.clientX,
10097
+ clientY: e.clientY,
10098
+ shiftKey: e.shiftKey,
10099
+ altKey: e.altKey,
10100
+ metaKey: e.metaKey,
10101
+ ctrlKey: e.ctrlKey,
10102
+ itemIds: [target.item.id]
10103
+ });
10104
+ if (!accepted) {
10105
+ e.preventDefault();
10106
+ e.stopPropagation();
10107
+ return;
10108
+ }
10109
+ wrapperRef.current?.focus({ preventScroll: true });
10110
+ readOnlyItemClickStateRef.current = createReadOnlyActivationSession(
10111
+ target,
10112
+ e
10113
+ );
10114
+ e.preventDefault();
10115
+ e.stopPropagation();
10116
+ };
10117
+ root.addEventListener("pointerdown", onReadOnlyPointerDownCapture, {
10118
+ capture: true
10119
+ });
10120
+ return () => {
10121
+ root.removeEventListener("pointerdown", onReadOnlyPointerDownCapture, {
10122
+ capture: true
10123
+ });
10124
+ };
10125
+ }, [resolveReadOnlyActivation, startCanvuInteraction]);
10126
+ useEffect(() => {
10127
+ const finishReadOnlyClick = (ev) => {
10128
+ const st = readOnlyItemClickStateRef.current;
10129
+ if (!st || st.pointerId !== ev.pointerId) return;
10130
+ readOnlyItemClickStateRef.current = null;
10131
+ const world = screenToWorld(ev.clientX, ev.clientY);
10132
+ const current = {
10133
+ worldX: world.worldX,
10134
+ worldY: world.worldY,
10135
+ clientX: ev.clientX,
10136
+ clientY: ev.clientY
10137
+ };
10138
+ updateCanvuInteractionCurrent(current);
10139
+ if (ev.type === "pointercancel") {
10140
+ finishCanvuInteraction("cancelled", { current });
10141
+ return;
10142
+ }
10143
+ if (didReadOnlyActivationMovePastTap(st, ev, TAP_PX)) {
10144
+ finishCanvuInteraction("cancelled", { current });
10145
+ return;
10146
+ }
10147
+ const item = itemsRef.current.find((candidate) => candidate.id === st.itemId) ?? resolvedItemsRef.current.find((candidate) => candidate.id === st.itemId);
10148
+ if (!item) {
10149
+ finishCanvuInteraction("cancelled", { current });
10150
+ return;
10151
+ }
10152
+ const detail = buildSelectModeItemClickDetail(item, world, ev);
10153
+ if (st.activation === "custom") {
10154
+ const placement = findReadOnlyItemClickPlacement(
10155
+ item,
10156
+ allCustomPlacementsRef.current
10157
+ );
10158
+ const onSelectModeItemClick = placement?.onSelectModeItemClick;
10159
+ if (!onSelectModeItemClick) {
10160
+ finishCanvuInteraction("cancelled", { current });
10161
+ return;
10162
+ }
10163
+ onSelectModeItemClick(detail);
10164
+ finishCanvuInteraction("completed", {
10165
+ current,
10166
+ info: { motive: "custom", itemIds: [item.id], toolId: "select" }
10167
+ });
10168
+ return;
10169
+ }
10170
+ const handled = readOnlyInteractionRef.current?.onItemClick?.(detail) === "handled";
10171
+ if (!handled) {
10172
+ const cur = effectiveSelectedIdsRef.current;
10173
+ const next = ev.shiftKey ? cur.includes(item.id) ? cur.filter((id) => id !== item.id) : [...cur, item.id] : [item.id];
10174
+ setEffectiveSelectedIdsRef.current(next);
10175
+ }
10176
+ finishCanvuInteraction("completed", {
10177
+ current,
10178
+ info: { motive: "custom", itemIds: [item.id], toolId: "select" }
10179
+ });
10180
+ };
10181
+ document.addEventListener("pointerup", finishReadOnlyClick);
10182
+ document.addEventListener("pointercancel", finishReadOnlyClick);
10183
+ return () => {
10184
+ document.removeEventListener("pointerup", finishReadOnlyClick);
10185
+ document.removeEventListener("pointercancel", finishReadOnlyClick);
10186
+ };
10187
+ }, [
10188
+ buildSelectModeItemClickDetail,
10189
+ finishCanvuInteraction,
10190
+ screenToWorld,
10191
+ updateCanvuInteractionCurrent
10192
+ ]);
9947
10193
  const handleOverlayPointerDown = useCallback(
9948
10194
  (e) => {
9949
10195
  let currentDragState = dragStateRef.current;
@@ -10122,7 +10368,7 @@ var VectorViewport = forwardRef(
10122
10368
  ignoreLocked: true
10123
10369
  });
10124
10370
  if (hit) {
10125
- const selectModeClickPlacement = !e.shiftKey ? findSelectModeItemClickPlacement(hit, allCustomPlacementsRef.current) : null;
10371
+ const selectModeClickPlacement = !e.shiftKey ? findReadOnlyItemClickPlacement(hit, allCustomPlacementsRef.current) : null;
10126
10372
  if (selectModeClickPlacement) {
10127
10373
  const isAlreadySelected = cur.includes(hit.id);
10128
10374
  const moveIds = isAlreadySelected ? [...cur] : [hit.id];
@@ -11029,7 +11275,7 @@ var VectorViewport = forwardRef(
11029
11275
  });
11030
11276
  return;
11031
11277
  }
11032
- const placement = findSelectModeItemClickPlacement(
11278
+ const placement = findReadOnlyItemClickPlacement(
11033
11279
  item,
11034
11280
  allCustomPlacementsRef.current
11035
11281
  );
@@ -11040,27 +11286,9 @@ var VectorViewport = forwardRef(
11040
11286
  });
11041
11287
  return;
11042
11288
  }
11043
- const { worldX, worldY } = currentWorld;
11044
- onSelectModeItemClick({
11045
- item,
11046
- worldX,
11047
- worldY,
11048
- clientX: ev.clientX,
11049
- clientY: ev.clientY,
11050
- pointerType: ev.pointerType,
11051
- shiftKey: ev.shiftKey,
11052
- altKey: ev.altKey,
11053
- metaKey: ev.metaKey,
11054
- ctrlKey: ev.ctrlKey,
11055
- items: itemsRef.current,
11056
- updateItem: (next) => {
11057
- onItemsChangeRef.current?.(
11058
- replaceItem(itemsRef.current, item.id, next),
11059
- { motive: "custom", itemIds: [item.id] }
11060
- );
11061
- },
11062
- setSelectedIds: (ids) => setEffectiveSelectedIdsRef.current(ids)
11063
- });
11289
+ onSelectModeItemClick(
11290
+ buildSelectModeItemClickDetail(item, currentWorld, ev)
11291
+ );
11064
11292
  finishCanvuInteraction("completed", {
11065
11293
  current: currentInteractionPoint,
11066
11294
  info: { motive: "custom", itemIds: [item.id], toolId: "select" }
@@ -11430,6 +11658,7 @@ var VectorViewport = forwardRef(
11430
11658
  document.removeEventListener("pointercancel", onUp);
11431
11659
  };
11432
11660
  }, [
11661
+ buildSelectModeItemClickDetail,
11433
11662
  emitRemoteStrokePreview,
11434
11663
  emitRemoteStrokePreviewClear,
11435
11664
  interactive,