partforge 0.58.0 → 0.58.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "partforge",
3
- "version": "0.58.0",
3
+ "version": "0.58.1",
4
4
  "description": "Turn a declarative part definition into a parametric-CAD web app (three.js + Manifold/Replicad). Requires a Vite-based consumer.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -346,6 +346,14 @@ export function mount(part, { createWorker, elements = {}, onBuild, onPick, onDo
346
346
  if (onPick) {
347
347
  picker = attachPicker(viewer, {
348
348
  part, getContext,
349
+ // Measure mode claims canvas clicks for pinning dimensions, so while it
350
+ // is on a click must not ALSO select-and-flash (hosts turn picks into
351
+ // chat chips — one click was doing both). Same idea as the hover
352
+ // suppression above, but pull-based: checked per click, nothing to
353
+ // resync on mode changes. The ?pick/?pickserver harnesses below are
354
+ // deliberately not guarded — one is armed by an explicit dev toggle,
355
+ // the other per agent request.
356
+ suppressed: () => measureMode.isEnabled(),
349
357
  onPick: (selection) => onPick({
350
358
  selection,
351
359
  label: selection.feature?.label ?? part.parts[selection.subPart]?.label ?? selection.subPart,
@@ -6,13 +6,19 @@ import { createDragTracker } from "./drag-tracker.js";
6
6
 
7
7
  export { worldToSubPartLocal };
8
8
 
9
- export function attachPicker(viewer, { part, getContext, onPick }) {
9
+ // `suppressed` is an optional pull-based guard checked per click, for a caller
10
+ // whose suppression condition lives elsewhere (mount passes measure mode's
11
+ // isEnabled): while it returns true a click neither raycasts, flashes, nor
12
+ // picks — no resync bookkeeping the way an event-driven setActive would need.
13
+ export function attachPicker(viewer, { part, getContext, onPick, suppressed }) {
10
14
  let active = false;
11
15
  const drag = createDragTracker();
12
16
 
13
17
  function onClick(ev) {
18
+ // consumeClick() first, unconditionally — the drag tracker is stateful and
19
+ // a suppressed click must still clear its just-dragged flag.
14
20
  const wasDragged = drag.consumeClick();
15
- if (!active || wasDragged) return;
21
+ if (!active || wasDragged || suppressed?.()) return;
16
22
  const hit = raycastViewer(viewer, ev.clientX, ev.clientY);
17
23
  if (!hit) return;
18
24
  const selection = resolveSelection(part, getContext(), hit);