@weasel-js/routing 1.8.0 → 1.8.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.
@@ -4,6 +4,7 @@ import { ReactNode } from 'react';
4
4
  import { CursorSpec } from '@weasel-js/cursor';
5
5
  import { ClaimableGesture, GestureSpec, InputEvent, TargetSpec, KeySpec, ParsedModifiers, GestureName, IngestItem } from '@weasel-js/gestures';
6
6
  import { Op } from '@weasel-js/history';
7
+ import '@weasel-js/select';
7
8
 
8
9
  /**
9
10
  * The primitives the routing surface is typed in.
@@ -14,7 +15,8 @@ import { Op } from '@weasel-js/history';
14
15
  * interfaces with no dependencies, and `@weasel-js/core` re-exports each from
15
16
  * the path its own call sites have always used. Same arrangement as `Op`,
16
17
  * which is declared in `@weasel-js/history` and re-exported by
17
- * `core/ops/types`.
18
+ * `core/ops/types`. The selection click policy's own vocabulary comes from
19
+ * `@weasel-js/select`, where the rules that read it live.
18
20
  *
19
21
  * Authority for the *behavior* behind each of these stays in core: `View` is
20
22
  * what `core/viewport` maintains, `SelectionApi` is what `useSelection`
@@ -22,6 +24,7 @@ import { Op } from '@weasel-js/history';
22
24
  * one of these shapes is a change to core's contract that happens to be
23
25
  * spelled here.
24
26
  */
27
+
25
28
  /** An opaque scene-node identifier. Branded so a bare string cannot stand in. */
26
29
  type NodeId = string & {
27
30
  readonly __brand: 'NodeId';
@@ -54,11 +57,6 @@ interface Bounds {
54
57
  height: number;
55
58
  rotation?: number;
56
59
  }
57
- /** Selection click policy. `single` always replaces; `multi` toggles when the
58
- * configured extend key is held, otherwise replaces. */
59
- type SelectionMode = 'single' | 'multi';
60
- /** Modifier key used to extend the selection in `multi` mode. */
61
- type SelectionExtendKey = 'shift' | 'meta' | 'ctrl';
62
60
  /** The selection as routing reads and writes it. */
63
61
  interface SelectionApi {
64
62
  /** Current selection. Re-renders trigger when this reference changes. */
@@ -605,7 +603,7 @@ interface InvocationCtx {
605
603
  rotation: number;
606
604
  };
607
605
  multiTouch?: {
608
- /** Canvas-local CSS pixels — see `MultitouchEvent.centroid`. Neither
606
+ /** Canvas-local CSS pixels — see `MultiTouchEvent.centroid`. Neither
609
607
  * `world` nor `screen`: it is the space `zoomAt` anchors in, so passing
610
608
  * it through `clientToWorld` removes the canvas origin twice. */
611
609
  centroid: Point2;
@@ -2929,4 +2927,4 @@ type KernelOverlay = OverlaySchema extends {
2929
2927
  overlay: infer O;
2930
2928
  } ? O : unknown;
2931
2929
 
2932
- export { type GestureBinding as $, type ActionsRegistry as A, type BindingOpts as B, type Contribution as C, type DepRegistry as D, COARSE_TARGET_SCALE as E, type Condition as F, type Conflict as G, type ContributionChrome as H, type ContributionDeps as I, type ContributionRouting as J, type KernelOverlay as K, type LongPressOptions as L, DEFAULT_ALLOWED_CAPABILITIES as M, DEFAULT_DEVICE_PROFILE as N, type OverlayPosition as O, type DebugSink as P, type DetectedDeviceFacts as Q, type RuleCtx as R, ScopeNode as S, type DeviceProfile as T, type DispatchRecord as U, type DispatchRecordInput as V, type DispatcherContext as W, type DragSample as X, type DroppedCandidate as Y, type Eligibility as Z, type EligibilityState as _, type DepName as a, actionItems as a$, type HandleKind as a0, type HitShape as a1, type HotkeyTrigger as a2, INGEST_STRING_MIMES as a3, type ImmediateInvoker as a4, type InvocationCtx as a5, type Invoker as a6, type KeyBinding as a7, LONG_PRESS_MS as a8, type LongPressState as a9, type ResolveOnlyResult as aA, type ResolvedCandidate as aB, type Rule as aC, type ScratchKey as aD, type ScratchStore as aE, type SelectionApi as aF, type SelectionExtendKey as aG, type SelectionMode as aH, type Selector as aI, type SpecificityPart as aJ, TOOL_OFFHAND_ID as aK, type Tool as aL, type ToolBounds as aM, type ToolCtx as aN, type ToolDef as aO, type ToolKeybinding as aP, type ToolLifecycleCtx as aQ, type ToolModifiers as aR, type ToolOffhandBindingSpec as aS, type ToolPresentation as aT, type ToolSlot as aU, type TraceLogEntry as aV, type UiOngoingControl as aW, type View as aX, type ViewportGestureKind as aY, type WalkStep as aZ, actionBindings as a_, type LongPressStore as aa, type MatchOutcome as ab, type MatchResult as ac, type ModeShortcutHandlers as ad, type ModeSwitchLogEntry as ae, type ModifierState as af, NEVER as ag, type NodeId as ah, type OngoingHandle as ai, type OngoingInvoker as aj, type OngoingOverlay as ak, type OverlayRole as al, type OverlaySchema as am, PREDICATE_TARGET as an, type PendingLongPress as ao, type PlacedBy as ap, type Point2 as aq, type PointerSession as ar, type PointerSessionCallbacks as as, type PointerSessionCancelReason as at, type PointerSessionOptions as au, type RankedCandidate as av, type RecordCandidate as aw, type RegistryEntry as ax, type ResizeAnchor as ay, type ResolveAllOptions as az, type DepSchema as b, buildDepsFromRequires as b0, buildRouteRegistry as b1, buildRuleCtx as b2, buildToolOffhandBindings as b3, clientToCanvas as b4, clientToCanvasRect as b5, createDepRegistry as b6, createDispatcher as b7, createLongPressStore as b8, defineTool as b9, matchesKeyBinding as bA, mergeContributions as bB, modeShortcutSpec as bC, modeShortcuts as bD, offhandKeyFor as bE, openPointerSession as bF, pointerGestureId as bG, recordModeSwitch as bH, reportRouteConflicts as bI, resolveDeviceProfile as bJ, resolveParams as bK, routesForSpec as bL, ruleCanHoldIn as bM, rulesExclusive as bN, scopeBindings as bO, scratchKey as bP, setScratch as bQ, targetConsultsAffordance as bR, validateActionDefaultBinding as bS, validateActionId as bT, deleteScratch as ba, describeRule as bb, dlog as bc, evaluate as bd, evaluateEnabled as be, findConflicts as bf, getScratch as bg, isAnchor as bh, isAnchorOrControl as bi, isBody as bj, isControlHandle as bk, isEditableTarget as bl, isEmpty as bm, isResizeHandle as bn, isRotateHandle as bo, isSelectedBody as bp, isTool as bq, isUnselectedBody as br, itemsFromClipboardData as bs, itemsFromDataTransfer as bt, itemsFromFiles as bu, liveScope as bv, makeToolOffhandAction as bw, matchBest as bx, matchSorted as by, matchSortedWithBarred as bz, type Action as c, DepNode as d, type AnyToolOf as e, type ScopedBinding as f, type Dispatcher as g, type AffordanceHit as h, ALWAYS as i, type ActionDeps as j, ActionDisabledReason as k, type ActionDispatch as l, type ActionEnabledResult as m, type ActionEntry as n, type ActionItem as o, type ActionPresentation as p, type ActionSource as q, type ActionVariant as r, type ActionsProp as s, type AnyTool as t, type BindingScope as u, type BindingSource as v, type BodyPredicate as w, type BoundGesture as x, type Bounds as y, type BuildRuleCtxArgs as z };
2930
+ export { type GestureBinding as $, type ActionsRegistry as A, type BindingOpts as B, type Contribution as C, type DepRegistry as D, COARSE_TARGET_SCALE as E, type Condition as F, type Conflict as G, type ContributionChrome as H, type ContributionDeps as I, type ContributionRouting as J, type KernelOverlay as K, type LongPressOptions as L, DEFAULT_ALLOWED_CAPABILITIES as M, DEFAULT_DEVICE_PROFILE as N, type OverlayPosition as O, type DebugSink as P, type DetectedDeviceFacts as Q, type RuleCtx as R, ScopeNode as S, type DeviceProfile as T, type DispatchRecord as U, type DispatchRecordInput as V, type DispatcherContext as W, type DragSample as X, type DroppedCandidate as Y, type Eligibility as Z, type EligibilityState as _, type DepName as a, buildRouteRegistry as a$, type HandleKind as a0, type HitShape as a1, type HotkeyTrigger as a2, INGEST_STRING_MIMES as a3, type ImmediateInvoker as a4, type InvocationCtx as a5, type Invoker as a6, type KeyBinding as a7, LONG_PRESS_MS as a8, type LongPressState as a9, type ResolveOnlyResult as aA, type ResolvedCandidate as aB, type Rule as aC, type ScratchKey as aD, type ScratchStore as aE, type SelectionApi as aF, type Selector as aG, type SpecificityPart as aH, TOOL_OFFHAND_ID as aI, type Tool as aJ, type ToolBounds as aK, type ToolCtx as aL, type ToolDef as aM, type ToolKeybinding as aN, type ToolLifecycleCtx as aO, type ToolModifiers as aP, type ToolOffhandBindingSpec as aQ, type ToolPresentation as aR, type ToolSlot as aS, type TraceLogEntry as aT, type UiOngoingControl as aU, type View as aV, type ViewportGestureKind as aW, type WalkStep as aX, actionBindings as aY, actionItems as aZ, buildDepsFromRequires as a_, type LongPressStore as aa, type MatchOutcome as ab, type MatchResult as ac, type ModeShortcutHandlers as ad, type ModeSwitchLogEntry as ae, type ModifierState as af, NEVER as ag, type NodeId as ah, type OngoingHandle as ai, type OngoingInvoker as aj, type OngoingOverlay as ak, type OverlayRole as al, type OverlaySchema as am, PREDICATE_TARGET as an, type PendingLongPress as ao, type PlacedBy as ap, type Point2 as aq, type PointerSession as ar, type PointerSessionCallbacks as as, type PointerSessionCancelReason as at, type PointerSessionOptions as au, type RankedCandidate as av, type RecordCandidate as aw, type RegistryEntry as ax, type ResizeAnchor as ay, type ResolveAllOptions as az, type DepSchema as b, buildRuleCtx as b0, buildToolOffhandBindings as b1, clientToCanvas as b2, clientToCanvasRect as b3, createDepRegistry as b4, createDispatcher as b5, createLongPressStore as b6, defineTool as b7, deleteScratch as b8, describeRule as b9, modeShortcutSpec as bA, modeShortcuts as bB, offhandKeyFor as bC, openPointerSession as bD, pointerGestureId as bE, recordModeSwitch as bF, reportRouteConflicts as bG, resolveDeviceProfile as bH, resolveParams as bI, routesForSpec as bJ, ruleCanHoldIn as bK, rulesExclusive as bL, scopeBindings as bM, scratchKey as bN, setScratch as bO, targetConsultsAffordance as bP, validateActionDefaultBinding as bQ, validateActionId as bR, dlog as ba, evaluate as bb, evaluateEnabled as bc, findConflicts as bd, getScratch as be, isAnchor as bf, isAnchorOrControl as bg, isBody as bh, isControlHandle as bi, isEditableTarget as bj, isEmpty as bk, isResizeHandle as bl, isRotateHandle as bm, isSelectedBody as bn, isTool as bo, isUnselectedBody as bp, itemsFromClipboardData as bq, itemsFromDataTransfer as br, itemsFromFiles as bs, liveScope as bt, makeToolOffhandAction as bu, matchBest as bv, matchSorted as bw, matchSortedWithBarred as bx, matchesKeyBinding as by, mergeContributions as bz, type Action as c, DepNode as d, type AnyToolOf as e, type ScopedBinding as f, type Dispatcher as g, type AffordanceHit as h, ALWAYS as i, type ActionDeps as j, ActionDisabledReason as k, type ActionDispatch as l, type ActionEnabledResult as m, type ActionEntry as n, type ActionItem as o, type ActionPresentation as p, type ActionSource as q, type ActionVariant as r, type ActionsProp as s, type AnyTool as t, type BindingScope as u, type BindingSource as v, type BodyPredicate as w, type BoundGesture as x, type Bounds as y, type BuildRuleCtxArgs as z };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- export { i as ALWAYS, c as Action, j as ActionDeps, k as ActionDisabledReason, k as ActionDisabledReasonValue, l as ActionDispatch, m as ActionEnabledResult, n as ActionEntry, o as ActionItem, p as ActionPresentation, q as ActionSource, r as ActionVariant, s as ActionsProp, A as ActionsRegistry, h as AffordanceHit, t as AnyTool, e as AnyToolOf, B as BindingOpts, u as BindingScope, v as BindingSource, w as BodyPredicate, x as BoundGesture, y as Bounds, z as BuildRuleCtxArgs, E as COARSE_TARGET_SCALE, F as Condition, G as Conflict, C as Contribution, H as ContributionChrome, I as ContributionDeps, J as ContributionRouting, M as DEFAULT_ALLOWED_CAPABILITIES, N as DEFAULT_DEVICE_PROFILE, P as DebugSink, a as DepName, D as DepRegistry, b as DepSchema, Q as DetectedDeviceFacts, T as DeviceProfile, U as DispatchRecord, V as DispatchRecordInput, g as Dispatcher, W as DispatcherContext, X as DragSample, Y as DroppedCandidate, Z as Eligibility, _ as EligibilityState, $ as GestureBinding, a0 as HandleKind, a1 as HitShape, a2 as HotkeyTrigger, a3 as INGEST_STRING_MIMES, a4 as ImmediateInvoker, a5 as InvocationCtx, a6 as Invoker, K as KernelOverlay, a7 as KeyBinding, a8 as LONG_PRESS_MS, L as LongPressOptions, a9 as LongPressState, aa as LongPressStore, ab as MatchOutcome, ac as MatchResult, ad as ModeShortcutHandlers, ae as ModeSwitchLogEntry, af as ModifierState, ag as NEVER, ah as NodeId, ai as OngoingHandle, aj as OngoingInvoker, ak as OngoingOverlay, O as OverlayPosition, al as OverlayRole, am as OverlaySchema, an as PREDICATE_TARGET, ao as PendingLongPress, ap as PlacedBy, aq as Point2, ar as PointerSession, as as PointerSessionCallbacks, at as PointerSessionCancelReason, au as PointerSessionOptions, av as RankedCandidate, aw as RecordCandidate, ax as RegistryEntry, ay as ResizeAnchor, az as ResolveAllOptions, aA as ResolveOnlyResult, aB as ResolvedCandidate, aC as Rule, R as RuleCtx, f as ScopedBinding, aD as ScratchKey, aE as ScratchStore, aF as SelectionApi, aG as SelectionExtendKey, aH as SelectionMode, aI as Selector, aJ as SpecificityPart, aK as TOOL_OFFHAND_ID, aL as Tool, aM as ToolBounds, aN as ToolCtx, aO as ToolDef, aP as ToolKeybinding, aQ as ToolLifecycleCtx, aR as ToolModifiers, aS as ToolOffhandBindingSpec, aT as ToolPresentation, aU as ToolSlot, aV as TraceLogEntry, aW as UiOngoingControl, aX as View, aY as ViewportGestureKind, aZ as WalkStep, a_ as actionBindings, a$ as actionItems, b0 as buildDepsFromRequires, b1 as buildRouteRegistry, b2 as buildRuleCtx, b3 as buildToolOffhandBindings, b4 as clientToCanvas, b5 as clientToCanvasRect, b6 as createDepRegistry, b7 as createDispatcher, b8 as createLongPressStore, b9 as defineTool, ba as deleteScratch, bb as describeRule, bc as dlog, bd as evaluate, be as evaluateEnabled, bf as findConflicts, bg as getScratch, bh as isAnchor, bi as isAnchorOrControl, bj as isBody, bk as isControlHandle, bl as isEditableTarget, bm as isEmpty, bn as isResizeHandle, bo as isRotateHandle, bp as isSelectedBody, bq as isTool, br as isUnselectedBody, bs as itemsFromClipboardData, bt as itemsFromDataTransfer, bu as itemsFromFiles, bv as liveScope, bw as makeToolOffhandAction, bx as matchBest, by as matchSorted, bz as matchSortedWithBarred, bA as matchesKeyBinding, bB as mergeContributions, bC as modeShortcutSpec, bD as modeShortcuts, bE as offhandKeyFor, bF as openPointerSession, bG as pointerGestureId, bH as recordModeSwitch, bI as reportRouteConflicts, bJ as resolveDeviceProfile, bK as resolveParams, bL as routesForSpec, bM as ruleCanHoldIn, bN as rulesExclusive, bO as scopeBindings, bP as scratchKey, bQ as setScratch, bR as targetConsultsAffordance, bS as validateActionDefaultBinding, bT as validateActionId } from './index-BV53gfyB.js';
2
- export { ChannelRef, DRAG_THRESHOLD_PX, DescribeRouteOptions, GESTURE_DESCRIPTORS, GestureArgSpec, GestureDescriptor, GestureName, IngestItem, InputEvent, ModRequirement, ModifierKey, ParsedModifiers, ParsedRoute, PhaseAtom, PhaseContext, RESERVED_ID_NAMES, RESERVED_ID_PREFIXES, ROUTE_FIELD_DEFINITIONS, ROUTE_TERMS, RouteDescriptionPart, RouteFieldName, RouteTermLabel, canonicalModifiers, collapseShiftPairs, describeRoute, describeRouteParts, formatPhaseAtom, formatRoute, getGestureDescriptor, isKnownGestureName, matchKey, matchModifiers, matchPhase, matchSpec, matchTarget, parseRoute, pastDragThreshold, routeGestureForSpecKind, specKindForRouteGesture, specificity } from '@weasel-js/gestures';
1
+ export { i as ALWAYS, c as Action, j as ActionDeps, k as ActionDisabledReason, k as ActionDisabledReasonValue, l as ActionDispatch, m as ActionEnabledResult, n as ActionEntry, o as ActionItem, p as ActionPresentation, q as ActionSource, r as ActionVariant, s as ActionsProp, A as ActionsRegistry, h as AffordanceHit, t as AnyTool, e as AnyToolOf, B as BindingOpts, u as BindingScope, v as BindingSource, w as BodyPredicate, x as BoundGesture, y as Bounds, z as BuildRuleCtxArgs, E as COARSE_TARGET_SCALE, F as Condition, G as Conflict, C as Contribution, H as ContributionChrome, I as ContributionDeps, J as ContributionRouting, M as DEFAULT_ALLOWED_CAPABILITIES, N as DEFAULT_DEVICE_PROFILE, P as DebugSink, a as DepName, D as DepRegistry, b as DepSchema, Q as DetectedDeviceFacts, T as DeviceProfile, U as DispatchRecord, V as DispatchRecordInput, g as Dispatcher, W as DispatcherContext, X as DragSample, Y as DroppedCandidate, Z as Eligibility, _ as EligibilityState, $ as GestureBinding, a0 as HandleKind, a1 as HitShape, a2 as HotkeyTrigger, a3 as INGEST_STRING_MIMES, a4 as ImmediateInvoker, a5 as InvocationCtx, a6 as Invoker, K as KernelOverlay, a7 as KeyBinding, a8 as LONG_PRESS_MS, L as LongPressOptions, a9 as LongPressState, aa as LongPressStore, ab as MatchOutcome, ac as MatchResult, ad as ModeShortcutHandlers, ae as ModeSwitchLogEntry, af as ModifierState, ag as NEVER, ah as NodeId, ai as OngoingHandle, aj as OngoingInvoker, ak as OngoingOverlay, O as OverlayPosition, al as OverlayRole, am as OverlaySchema, an as PREDICATE_TARGET, ao as PendingLongPress, ap as PlacedBy, aq as Point2, ar as PointerSession, as as PointerSessionCallbacks, at as PointerSessionCancelReason, au as PointerSessionOptions, av as RankedCandidate, aw as RecordCandidate, ax as RegistryEntry, ay as ResizeAnchor, az as ResolveAllOptions, aA as ResolveOnlyResult, aB as ResolvedCandidate, aC as Rule, R as RuleCtx, f as ScopedBinding, aD as ScratchKey, aE as ScratchStore, aF as SelectionApi, aG as Selector, aH as SpecificityPart, aI as TOOL_OFFHAND_ID, aJ as Tool, aK as ToolBounds, aL as ToolCtx, aM as ToolDef, aN as ToolKeybinding, aO as ToolLifecycleCtx, aP as ToolModifiers, aQ as ToolOffhandBindingSpec, aR as ToolPresentation, aS as ToolSlot, aT as TraceLogEntry, aU as UiOngoingControl, aV as View, aW as ViewportGestureKind, aX as WalkStep, aY as actionBindings, aZ as actionItems, a_ as buildDepsFromRequires, a$ as buildRouteRegistry, b0 as buildRuleCtx, b1 as buildToolOffhandBindings, b2 as clientToCanvas, b3 as clientToCanvasRect, b4 as createDepRegistry, b5 as createDispatcher, b6 as createLongPressStore, b7 as defineTool, b8 as deleteScratch, b9 as describeRule, ba as dlog, bb as evaluate, bc as evaluateEnabled, bd as findConflicts, be as getScratch, bf as isAnchor, bg as isAnchorOrControl, bh as isBody, bi as isControlHandle, bj as isEditableTarget, bk as isEmpty, bl as isResizeHandle, bm as isRotateHandle, bn as isSelectedBody, bo as isTool, bp as isUnselectedBody, bq as itemsFromClipboardData, br as itemsFromDataTransfer, bs as itemsFromFiles, bt as liveScope, bu as makeToolOffhandAction, bv as matchBest, bw as matchSorted, bx as matchSortedWithBarred, by as matchesKeyBinding, bz as mergeContributions, bA as modeShortcutSpec, bB as modeShortcuts, bC as offhandKeyFor, bD as openPointerSession, bE as pointerGestureId, bF as recordModeSwitch, bG as reportRouteConflicts, bH as resolveDeviceProfile, bI as resolveParams, bJ as routesForSpec, bK as ruleCanHoldIn, bL as rulesExclusive, bM as scopeBindings, bN as scratchKey, bO as setScratch, bP as targetConsultsAffordance, bQ as validateActionDefaultBinding, bR as validateActionId } from './index-D6U36wJH.js';
2
+ export { CONTROL_SELECTOR, ChannelRef, DRAG_THRESHOLD_PX, DescribeRouteOptions, GESTURE_DESCRIPTORS, GestureArgSpec, GestureDescriptor, GestureName, IngestItem, InputEvent, ModRequirement, ModifierKey, ParsedModifiers, ParsedRoute, PhaseAtom, PhaseContext, RESERVED_ID_NAMES, RESERVED_ID_PREFIXES, ROUTE_FIELD_DEFINITIONS, ROUTE_TERMS, RouteDescriptionPart, RouteFieldName, RouteTermLabel, canonicalModifiers, collapseShiftPairs, describeRoute, describeRouteParts, formatPhaseAtom, formatRoute, getGestureDescriptor, isInControlWithin, isKnownGestureName, matchKey, matchModifiers, matchPhase, matchSpec, matchTarget, parseRoute, pastDragThreshold, routeGestureForSpecKind, specKindForRouteGesture, specificity } from '@weasel-js/gestures';
3
+ export { SelectionExtendKey, SelectionMode } from '@weasel-js/select';
3
4
  import '@weasel-js/modes';
4
5
  import 'react';
5
6
  import '@weasel-js/cursor';
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { isDev } from './chunk-ZGKJWZ4S.js';
2
- export { ALWAYS, COARSE_TARGET_SCALE, DEFAULT_ALLOWED_CAPABILITIES, DEFAULT_DEVICE_PROFILE, GESTURE_DESCRIPTORS, INGEST_STRING_MIMES, LONG_PRESS_MS, NEVER, PREDICATE_TARGET, RESERVED_ID_NAMES, RESERVED_ID_PREFIXES, ROUTE_FIELD_DEFINITIONS, ROUTE_TERMS, TOOL_OFFHAND_ID, actionBindings, buildDepsFromRequires, buildRouteRegistry, buildRuleCtx, buildToolOffhandBindings, canonicalModifiers, clientToCanvas, clientToCanvasRect, collapseShiftPairs, createDepRegistry, createDispatcher, createLongPressStore, describeRoute, describeRouteParts, describeRule, dlog, evaluate, findConflicts, formatPhaseAtom, formatRoute, getGestureDescriptor, isEditableTarget, isKnownGestureName, isTool, itemsFromClipboardData, itemsFromDataTransfer, itemsFromFiles, liveScope, makeToolOffhandAction, matchBest, matchKey, matchModifiers, matchPhase, matchSorted, matchSortedWithBarred, matchSpec, matchTarget, matchesKeyBinding, offhandKeyFor, openPointerSession, parseRoute, pointerGestureId, recordModeSwitch, reportRouteConflicts, resolveDeviceProfile, resolveParams, routeGestureForSpecKind, routesForSpec, ruleCanHoldIn, rulesExclusive, scopeBindings, specKindForRouteGesture, specificity, targetConsultsAffordance, validateActionDefaultBinding, validateActionId } from './chunk-ZGKJWZ4S.js';
1
+ import { isDev } from './chunk-ZBTQQN33.js';
2
+ export { ALWAYS, COARSE_TARGET_SCALE, DEFAULT_ALLOWED_CAPABILITIES, DEFAULT_DEVICE_PROFILE, GESTURE_DESCRIPTORS, INGEST_STRING_MIMES, LONG_PRESS_MS, NEVER, PREDICATE_TARGET, RESERVED_ID_NAMES, RESERVED_ID_PREFIXES, ROUTE_FIELD_DEFINITIONS, ROUTE_TERMS, TOOL_OFFHAND_ID, actionBindings, buildDepsFromRequires, buildRouteRegistry, buildRuleCtx, buildToolOffhandBindings, canonicalModifiers, clientToCanvas, clientToCanvasRect, collapseShiftPairs, createDepRegistry, createDispatcher, createLongPressStore, describeRoute, describeRouteParts, describeRule, dlog, evaluate, findConflicts, formatPhaseAtom, formatRoute, getGestureDescriptor, isEditableTarget, isKnownGestureName, isTool, itemsFromClipboardData, itemsFromDataTransfer, itemsFromFiles, liveScope, makeToolOffhandAction, matchBest, matchKey, matchModifiers, matchPhase, matchSorted, matchSortedWithBarred, matchSpec, matchTarget, matchesKeyBinding, offhandKeyFor, openPointerSession, parseRoute, pointerGestureId, recordModeSwitch, reportRouteConflicts, resolveDeviceProfile, resolveParams, routeGestureForSpecKind, routesForSpec, ruleCanHoldIn, rulesExclusive, scopeBindings, specKindForRouteGesture, specificity, targetConsultsAffordance, validateActionDefaultBinding, validateActionId } from './chunk-ZBTQQN33.js';
3
3
  import { RESERVED_ID_PREFIXES, RESERVED_ID_NAMES } from '@weasel-js/gestures';
4
- export { DRAG_THRESHOLD_PX, pastDragThreshold } from '@weasel-js/gestures';
4
+ export { CONTROL_SELECTOR, DRAG_THRESHOLD_PX, isInControlWithin, pastDragThreshold } from '@weasel-js/gestures';
5
5
  import { modeLabel } from '@weasel-js/modes';
6
6
 
7
7
  // src/interactions/actions/actionItems.ts
@@ -1,4 +1,4 @@
1
- import { g as Dispatcher, A as ActionsRegistry, C as Contribution, h as AffordanceHit, L as LongPressOptions, R as RuleCtx, b as DepSchema } from './index-BV53gfyB.js';
1
+ import { g as Dispatcher, A as ActionsRegistry, C as Contribution, h as AffordanceHit, L as LongPressOptions, R as RuleCtx, b as DepSchema } from './index-D6U36wJH.js';
2
2
  import { RefObject } from 'react';
3
3
  import { BodyClassification } from '@weasel-js/gestures';
4
4
  import { PaintedCursorState } from '@weasel-js/cursor';
@@ -1,7 +1,8 @@
1
- export { a as DispatcherViewTarget, V as ViewIdResolver } from './internal--mYnGecm.js';
2
- import './index-BV53gfyB.js';
1
+ export { a as DispatcherViewTarget, V as ViewIdResolver } from './internal-ii-f6VZs.js';
2
+ import './index-D6U36wJH.js';
3
3
  import '@weasel-js/modes';
4
4
  import 'react';
5
5
  import '@weasel-js/cursor';
6
6
  import '@weasel-js/gestures';
7
7
  import '@weasel-js/history';
8
+ import '@weasel-js/select';
package/dist/react.d.ts CHANGED
@@ -1,11 +1,12 @@
1
- export { D as DispatcherChannels, U as UseGestureDispatcherOptions, u as useGestureDispatcher } from './internal--mYnGecm.js';
1
+ export { D as DispatcherChannels, U as UseGestureDispatcherOptions, u as useGestureDispatcher } from './internal-ii-f6VZs.js';
2
2
  import * as react from 'react';
3
3
  import { ReactNode, ReactElement } from 'react';
4
- import { D as DepRegistry, a as DepName, b as DepSchema, S as ScopeNode, A as ActionsRegistry, c as Action, d as DepNode, K as KernelOverlay, C as Contribution, e as AnyToolOf, O as OverlayPosition, f as ScopedBinding } from './index-BV53gfyB.js';
4
+ import { D as DepRegistry, a as DepName, b as DepSchema, S as ScopeNode, A as ActionsRegistry, c as Action, d as DepNode, K as KernelOverlay, C as Contribution, e as AnyToolOf, O as OverlayPosition, f as ScopedBinding } from './index-D6U36wJH.js';
5
5
  import { ModeRegistry } from '@weasel-js/modes';
6
6
  import '@weasel-js/gestures';
7
7
  import '@weasel-js/cursor';
8
8
  import '@weasel-js/history';
9
+ import '@weasel-js/select';
9
10
 
10
11
  /** Provides the dep registry for a canvas. `<SceneCanvas>` mounts one; a
11
12
  * consumer registering its own dep sources must be inside it. */
package/dist/react.js CHANGED
@@ -1,8 +1,8 @@
1
- import { createDepRegistry, createDispatcher, isTool, scopeBindings, liveScope, isDev, reportRouteConflicts, offhandKeyFor, makeToolOffhandAction, buildToolOffhandBindings, dlog, isEditableTarget, clientToCanvasRect, openPointerSession, LONG_PRESS_MS, publishLiveDispatch, pointerGestureId, itemsFromDataTransfer, itemsFromClipboardData, ScopeNode, pushOwner, validateActionId, validateActionDefaultBinding, depNodeOf, DepNode, buildDepsFromRequires } from './chunk-ZGKJWZ4S.js';
1
+ import { createDepRegistry, createDispatcher, isTool, scopeBindings, liveScope, isDev, reportRouteConflicts, offhandKeyFor, makeToolOffhandAction, buildToolOffhandBindings, dlog, isEditableTarget, clientToCanvasRect, openPointerSession, LONG_PRESS_MS, publishLiveDispatch, pointerGestureId, itemsFromDataTransfer, itemsFromClipboardData, ScopeNode, pushOwner, validateActionId, validateActionDefaultBinding, depNodeOf, DepNode, buildDepsFromRequires } from './chunk-ZBTQQN33.js';
2
2
  import { createContext, useState, useContext, useMemo, useEffect, useRef, useCallback, useSyncExternalStore } from 'react';
3
3
  import { useLatest, useStableByContent, sameList } from '@weasel-js/react';
4
4
  import { jsx, Fragment } from 'react/jsx-runtime';
5
- import { pastDragThreshold } from '@weasel-js/gestures';
5
+ import { isInControlWithin, pastDragThreshold } from '@weasel-js/gestures';
6
6
  import { resolveCursorTier } from '@weasel-js/cursor';
7
7
  import { activeModeOf } from '@weasel-js/modes';
8
8
 
@@ -443,7 +443,7 @@ function useGestureDispatcher(opts) {
443
443
  const result = dispatch(ev);
444
444
  if (result === "handled") {
445
445
  e.preventDefault();
446
- e.stopPropagation();
446
+ e.stopImmediatePropagation();
447
447
  }
448
448
  };
449
449
  const pinchEventOf = (e, scale, rotation) => {
@@ -497,10 +497,18 @@ function useGestureDispatcher(opts) {
497
497
  if (pinchLive) e.preventDefault();
498
498
  endPinch();
499
499
  };
500
+ let claimedDoubleClick = false;
501
+ const onNativeDoubleClick = (e) => {
502
+ if (!claimedDoubleClick) return;
503
+ claimedDoubleClick = false;
504
+ e.preventDefault();
505
+ };
500
506
  const onPointerDown = (e) => {
507
+ claimedDoubleClick = false;
501
508
  registryRef.current.activate();
502
509
  if ((e.button ?? 0) !== 0) return;
503
510
  if (!canvas) return;
511
+ if (isInControlWithin(e.target, canvas)) return;
504
512
  routeDown(e.pointerId, e.clientX, e.clientY);
505
513
  const w = toWorld(e.clientX, e.clientY);
506
514
  const affordance = target().affordanceAt?.(w) ?? void 0;
@@ -849,7 +857,8 @@ function useGestureDispatcher(opts) {
849
857
  ...down.bodyKind !== void 0 ? { bodyKind: down.bodyKind } : {}
850
858
  };
851
859
  onDoubleClickRef.current?.({ x: wClick.x, y: wClick.y });
852
- dispatch(dblEv);
860
+ const handled = dispatch(dblEv) === "handled";
861
+ claimedDoubleClick = handled || onDoubleClickRef.current !== void 0;
853
862
  lastClickRef.current = null;
854
863
  } else {
855
864
  lastClickRef.current = { t: now, clientX: e.clientX, clientY: e.clientY };
@@ -976,8 +985,9 @@ function useGestureDispatcher(opts) {
976
985
  canvas?.addEventListener("pointerleave", onHoverPointerLeave);
977
986
  canvas?.addEventListener("pointerdown", onPointerDown);
978
987
  canvas?.addEventListener("pointermove", onHoverMove);
988
+ canvas?.addEventListener("dblclick", onNativeDoubleClick);
979
989
  }
980
- if (wheelChannel) canvas?.addEventListener("wheel", onWheel, { passive: false });
990
+ if (wheelChannel) canvas?.addEventListener("wheel", onWheel, { passive: false, capture: true });
981
991
  if (pinchChannel) {
982
992
  canvas?.addEventListener("gesturestart", onGestureStart);
983
993
  canvas?.addEventListener("gesturechange", onGestureChange);
@@ -1000,12 +1010,13 @@ function useGestureDispatcher(opts) {
1000
1010
  window.removeEventListener("keydown", scheduleHoverCursorRefresh);
1001
1011
  window.removeEventListener("keyup", scheduleHoverCursorRefresh);
1002
1012
  canvas?.removeEventListener("pointerleave", onHoverPointerLeave);
1003
- canvas?.removeEventListener("wheel", onWheel);
1013
+ canvas?.removeEventListener("wheel", onWheel, { capture: true });
1004
1014
  canvas?.removeEventListener("gesturestart", onGestureStart);
1005
1015
  canvas?.removeEventListener("gesturechange", onGestureChange);
1006
1016
  canvas?.removeEventListener("gestureend", onGestureEnd);
1007
1017
  canvas?.removeEventListener("pointerdown", onPointerDown);
1008
1018
  canvas?.removeEventListener("pointermove", onHoverMove);
1019
+ canvas?.removeEventListener("dblclick", onNativeDoubleClick);
1009
1020
  canvas?.removeEventListener("contextmenu", onContextMenu);
1010
1021
  canvas?.removeEventListener("dragenter", onDragOver);
1011
1022
  canvas?.removeEventListener("dragover", onDragOver);