@weasel-js/routing 1.14.2 → 1.15.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/dist/react.d.ts CHANGED
@@ -1,16 +1,17 @@
1
- import { U as UseGestureDispatcherOptions } from './internal-CaJ4viHc.js';
2
- export { D as DispatcherChannels } from './internal-CaJ4viHc.js';
1
+ import { U as UseGestureDispatcherOptions } from './internal-nqfC0td8.js';
2
+ export { D as DispatcherChannels } from './internal-nqfC0td8.js';
3
3
  import * as react from 'react';
4
4
  import { ReactNode, ReactElement } from 'react';
5
- import { D as DepRegistry, a as DepName, b as DepSource, S as ScopeNode, A as Action, c as ActionDeps, M as MenuHost, d as ActionsRegistry, e as ActionDisabledReason, B as BoundGesture, f as ActionVariant, g as MenuDef, h as DepNode, T as ToolNode, K as KeymapDescription, W as WorldPoint, N as NodeId, i as KernelOverlay, C as Contribution, j as Tool, O as OverlayPosition } from './index-DJ7SxEKS.js';
6
- export { k as ActiveToolContextProvider, l as ActiveToolContextProviderIfRoot, m as ActiveToolContextProviderProps, n as ActiveToolContextValue, u as useActiveToolContext, o as useOptionalActiveToolContext } from './index-DJ7SxEKS.js';
5
+ import { D as DepRegistry, a as DepName, b as DepSource, S as ScopeNode, L as LastOperationKeeper, A as Action, c as ActionDeps, M as MenuHost, d as ActionsRegistry, e as ActionDisabledReason, B as BoundGesture, f as ActionVariant, g as LastOperationStore, h as LastOperation, i as MenuDef, j as DepNode, T as ToolNode, K as KeymapDescription, W as WorldPoint, N as NodeId, k as KernelOverlay, C as Contribution, l as Tool, O as OverlayPosition } from './index-D-XFwx8D.js';
6
+ export { m as ActiveToolContextProvider, n as ActiveToolContextProviderIfRoot, o as ActiveToolContextProviderProps, p as ActiveToolContextValue, u as useActiveToolContext, q as useOptionalActiveToolContext } from './index-D-XFwx8D.js';
7
7
  import { IconRef } from '@weasel-js/icons';
8
8
  import { ModeRegistry } from '@weasel-js/modes';
9
9
  import '@weasel-js/gestures';
10
10
  import '@weasel-js/cursor';
11
+ import '@weasel-js/history';
12
+ import '@weasel-js/prefs';
11
13
  import '@weasel-js/geom';
12
14
  import '@weasel-js/menu';
13
- import '@weasel-js/prefs';
14
15
  import '@weasel-js/registry';
15
16
  import '@weasel-js/select';
16
17
 
@@ -60,12 +61,17 @@ declare class ActionsNode extends ScopeNode<ActionsNode> {
60
61
  private host;
61
62
  /** Called on `activate`, so a scope's dep and tool nodes move with it. */
62
63
  readonly onActivate: (() => void)[];
64
+ /** The tree's last operation, kept at its root. */
65
+ readonly lastOperation: LastOperationKeeper;
66
+ private opHost;
63
67
  constructor(parent: ActionsNode | null, descends: boolean, contextDeps: () => DepRegistry | null);
64
68
  private resolve;
65
69
  /** Every tuning for `id` from the root down to here, root first. */
66
70
  private tuningsOf;
67
71
  /** `a` under every tuning for its id from the root down to here. */
68
72
  private tuned;
73
+ /** How the last operation reads and reruns what ran in this scope. */
74
+ private lastOperationHost;
69
75
  /** Every binding override from the root down to here, read into specs. */
70
76
  private overridesHere;
71
77
  private snapshot;
@@ -113,6 +119,8 @@ interface CommandOptions {
113
119
  keys?: BoundGesture | readonly BoundGesture[];
114
120
  /** Shown beside the label. */
115
121
  icon?: IconRef;
122
+ /** The registry group a bar drawing one group gathers it under. */
123
+ group?: string;
116
124
  /** Words a palette finds it by and a tagged bar or menu gathers it under. */
117
125
  tags?: readonly string[];
118
126
  /** One entry each in a bar, menu or palette; `run` receives the chosen one's params. */
@@ -123,10 +131,18 @@ interface CommandOptions {
123
131
  * for the calling component's lifetime, so a menu, toolbar, palette or key
124
132
  * can run it. Callbacks and option functions may be new on every render: the
125
133
  * latest are read when used, and the action is replaced only when `id`,
126
- * `label`, `icon`, `keys`, `tags` or `variants` change by value.
134
+ * `label`, `icon`, `group`, `keys`, `tags` or `variants` change by value.
127
135
  */
128
136
  declare function useCommand(id: string, label: string, run: (params?: Readonly<Record<string, unknown>>) => void, options?: CommandOptions): void;
129
137
 
138
+ /** The last operation store of the actions tree `registry` belongs to, or `null` for a registry that is not one
139
+ * of the kit's. */
140
+ declare function lastOperationOf(registry: ActionsRegistry | null): LastOperationStore | null;
141
+ /** The last operation store of the actions tree in scope, or `null` outside an `<ActionsProvider>`. */
142
+ declare function useLastOperationStore(): LastOperationStore | null;
143
+ /** What `store` holds now, rerendering as it changes; `store` defaults to the one in scope. */
144
+ declare function useLastOperation(store?: LastOperationStore | null): LastOperation | null;
145
+
130
146
  /** The menu host in scope: the nearest `<ActionsProvider>`'s, else the one a
131
147
  * canvas with no provider above it makes. Null outside both. */
132
148
  declare function useMenuHost(): MenuHost | null;
@@ -329,8 +345,10 @@ interface UseToolsOptions<TOverlay = KernelOverlay> {
329
345
  /** Always-on entries — tools or other contributions, live regardless of
330
346
  * the active slot. */
331
347
  ambient?: readonly Contribution<TOverlay>[];
332
- /** The modes the canvas can be in, read by the dev-time route-conflict
333
- * check; without a registry it checks against the kit's `DEFAULT_MODES`. */
348
+ /** The modes the canvas can be in. A mode's `defaultTool` becomes active
349
+ * as the mode is entered, and the tool it replaced comes back as the mode
350
+ * is left. The dev-time route-conflict check reads them too; without a
351
+ * registry it checks against the kit's `DEFAULT_MODES`. */
334
352
  modes?: ModeRegistry;
335
353
  }
336
354
  /** The tool registry's runtime surface: which tool is active, which is
@@ -419,4 +437,4 @@ declare function useContributions<TOverlay = KernelOverlay>(opts: UseContributio
419
437
  */
420
438
  declare function useOffhandAction(entries: readonly Contribution<unknown>[]): void;
421
439
 
422
- export { ActionsProvider, type CommandOptions, type ContributionsApi, DepRegistry, DepRegistryProvider, InputScope, type InputScopeProps, type OngoingAction, PointerContextProvider, type PointerContextValue, type PointerWorldPos, SelectionContextProvider, SelectionContextProviderIfRoot, type SelectionContextValue, type ToolsApi, type UseContributionsOptions, UseGestureDispatcherOptions, type UseToolsOptions, Yoke, type YokeProps, createPointerStore, useAction, useActionsRegistry, useCommand, useContributions, useDepRegistry, useDepSource, useGestureDispatcher, useMenuHost, useMenus, useOffhandAction, useOngoingAction, useOpenKeymap, useOptionalDepRegistry, usePointerContext, usePointerPosition, usePublishSelection, useSelectionContext, useTools, useYoke };
440
+ export { ActionsProvider, type CommandOptions, type ContributionsApi, DepRegistry, DepRegistryProvider, InputScope, type InputScopeProps, type OngoingAction, PointerContextProvider, type PointerContextValue, type PointerWorldPos, SelectionContextProvider, SelectionContextProviderIfRoot, type SelectionContextValue, type ToolsApi, type UseContributionsOptions, UseGestureDispatcherOptions, type UseToolsOptions, Yoke, type YokeProps, createPointerStore, lastOperationOf, useAction, useActionsRegistry, useCommand, useContributions, useDepRegistry, useDepSource, useGestureDispatcher, useLastOperation, useLastOperationStore, useMenuHost, useMenus, useOffhandAction, useOngoingAction, useOpenKeymap, useOptionalDepRegistry, usePointerContext, usePointerPosition, usePublishSelection, useSelectionContext, useTools, useYoke };
package/dist/react.js CHANGED
@@ -1,14 +1,14 @@
1
- import { createKeymapStack, createDispatchTrace, createDispatcher, describeKeymap, assembleEntries, liveScope, offhandKeyFor, makeToolOffhandAction, buildToolOffhandBindings, dlog, reportRouteConflicts, isTool, clientToCanvas, LONG_PRESS_HAPTIC_MS, multiTouchGestureId, openPointerSession, addCarrySurface, carryGestureId, anyBinding, isEditableTarget, focusedControlOwnsKey, itemsFromClipboardData, itemsFromDataTransfer, itemTypesFromDataTransfer, immediateParams } from './chunk-HR5F4LBX.js';
2
- import { useDepRegistry, actionsNodeOf, useAction, useActionsRegistry, useOptionalDepRegistry, ActionsNode, MenuHostContext, DepRegistryContext, ActionsContext } from './chunk-INZ63QGX.js';
3
- export { ActionsProvider, DepRegistryProvider, useAction, useActionsRegistry, useDepRegistry, useDepSource, useMenuHost, useMenus, useOptionalDepRegistry } from './chunk-INZ63QGX.js';
4
- import { NO_OVERRIDES, ScopeNode, depNodeOf, DepNode, actionCursor, buildDepsFromRequires } from './chunk-EUCNVGJV.js';
1
+ import { createKeymapStack, createDispatchTrace, createDispatcher, describeKeymap, assembleEntries, liveScope, offhandKeyFor, makeToolOffhandAction, buildToolOffhandBindings, dlog, reportRouteConflicts, isTool, clientToCanvas, LONG_PRESS_HAPTIC_MS, multiTouchGestureId, openPointerSession, addCarrySurface, carryGestureId, anyBinding, isEditableTarget, itemsFromClipboardData, itemsFromDataTransfer, itemTypesFromDataTransfer, immediateParams, focusedControlOwnsKey } from './chunk-ZUAFANMN.js';
2
+ import { useDepRegistry, actionsNodeOf, useAction, useActionsRegistry, useOptionalDepRegistry, ActionsNode, MenuHostContext, DepRegistryContext, ActionsContext } from './chunk-VAUJJODS.js';
3
+ export { ActionsProvider, DepRegistryProvider, useAction, useActionsRegistry, useDepRegistry, useDepSource, useMenuHost, useMenus, useOptionalDepRegistry } from './chunk-VAUJJODS.js';
4
+ import { NO_OVERRIDES, ScopeNode, depNodeOf, DepNode, actionCursor, buildDepsFromRequires } from './chunk-Z2BZBJ7W.js';
5
5
  import { createContext, useState, useContext, useEffect, useRef, useMemo, useCallback, useSyncExternalStore } from 'react';
6
6
  import { isApplePlatform, heldPointers, createPointerRecognizer, isInControlWithin, longPressEvents, stylusOf } from '@weasel-js/gestures';
7
7
  import { useLatest, useKitSettings, useStableByContent, sameList, isDev } from '@weasel-js/react';
8
8
  import { jsx, Fragment } from 'react/jsx-runtime';
9
9
  import { createCursorSink, resolveCursorTier } from '@weasel-js/cursor';
10
10
  import { deepEqual, createEmitter } from '@weasel-js/registry';
11
- import { activeModeOf } from '@weasel-js/modes';
11
+ import { activeModeOf, defaultToolOf } from '@weasel-js/modes';
12
12
 
13
13
  var ToolNode = class extends ScopeNode {
14
14
  state;
@@ -187,7 +187,10 @@ function createDispatchCore(src) {
187
187
  }),
188
188
  batch,
189
189
  keymaps: () => src.context().keymaps,
190
- holdsKeys: () => canvas ? src.actions().holdsKeys() : src.actions().isActive(),
190
+ holdsKeys: () => {
191
+ const a = src.actions();
192
+ return canvas ? a.holdsKeys() : a.isActive() && !(src.yieldKeys === true && a.holdsKeys());
193
+ },
191
194
  pointerOver: () => over,
192
195
  setPointerOver: (next) => {
193
196
  over = canvas !== null && next;
@@ -596,6 +599,46 @@ function keymapKeys(stack) {
596
599
  };
597
600
  }
598
601
 
602
+ // src/interactions/dispatcher/channels/overKeys.ts
603
+ var OVER_ONLY = { held: false, over: true };
604
+ function followPointer(core, down, held) {
605
+ const arrive = (e) => {
606
+ for (const [physical, { key, code }] of down) {
607
+ if (held.has(physical)) continue;
608
+ core.routeAt(null, e.clientX, e.clientY);
609
+ const on = core.dispatcherNow();
610
+ const codeField = code !== void 0 ? { code } : {};
611
+ const ev = {
612
+ kind: "key-held",
613
+ key,
614
+ ...codeField,
615
+ phase: "down",
616
+ altKey: e.altKey,
617
+ ctrlKey: e.ctrlKey,
618
+ metaKey: e.metaKey,
619
+ shiftKey: e.shiftKey
620
+ };
621
+ if (core.dispatch(ev, on, OVER_ONLY) === "handled") held.set(physical, { key, ...codeField, on });
622
+ }
623
+ };
624
+ const leave = () => {
625
+ for (const [physical, { key, code, on }] of [...held]) {
626
+ const ev = {
627
+ kind: "key-held",
628
+ key,
629
+ ...code !== void 0 ? { code } : {},
630
+ phase: "up",
631
+ altKey: false,
632
+ ctrlKey: false,
633
+ metaKey: false,
634
+ shiftKey: false
635
+ };
636
+ if (core.dispatch(ev, on, OVER_ONLY) === "handled") held.delete(physical);
637
+ }
638
+ };
639
+ return { arrive, leave };
640
+ }
641
+
599
642
  // src/interactions/dispatcher/channels/keyboard.ts
600
643
  function typedWithAltGraph(e) {
601
644
  if (!e.ctrlKey || !e.altKey || e.key.length !== 1 || !e.getModifierState?.("AltGraph")) return false;
@@ -613,10 +656,12 @@ var inMenu = (t) => t instanceof Element && t.closest('[role="menu"]') !== null;
613
656
  function keyboardInput(core) {
614
657
  const { dispatch, dispatcherNow } = core;
615
658
  const heldKeys = /* @__PURE__ */ new Map();
659
+ const downKeys = /* @__PURE__ */ new Map();
616
660
  const keymaps = keymapKeys(core.keymaps);
617
661
  const codeOf = (e) => e.code ? { code: e.code } : {};
618
662
  const physicalKey = (e) => e.code || e.key.toLowerCase();
619
663
  const onKeyDown = (e) => {
664
+ downKeys.set(physicalKey(e), { key: e.key, ...codeOf(e) });
620
665
  if (e.defaultPrevented || isEditableTarget(e.target) || inMenu(e.target) || focusedControlOwnsKey(e)) return;
621
666
  const reach = { held: core.holdsKeys(), over: core.pointerOver() };
622
667
  if (!reach.held && !reach.over) return;
@@ -642,6 +687,7 @@ function keyboardInput(core) {
642
687
  };
643
688
  const onKeyUp = (e) => {
644
689
  const physical = physicalKey(e);
690
+ downKeys.delete(physical);
645
691
  keymaps.up(e, physical);
646
692
  const down = heldKeys.get(physical);
647
693
  if (down === void 0) return;
@@ -659,6 +705,7 @@ function keyboardInput(core) {
659
705
  dispatch(ev, down.on);
660
706
  };
661
707
  const releaseAll = () => {
708
+ downKeys.clear();
662
709
  keymaps.clear();
663
710
  const releasing = [...heldKeys.values()];
664
711
  heldKeys.clear();
@@ -676,7 +723,7 @@ function keyboardInput(core) {
676
723
  dispatch(ev, on);
677
724
  }
678
725
  };
679
- return { onKeyDown, onKeyUp, releaseAll };
726
+ return { onKeyDown, onKeyUp, releaseAll, ...followPointer(core, downKeys, heldKeys) };
680
727
  }
681
728
 
682
729
  // src/interactions/dispatcher/channels/listeners.ts
@@ -967,6 +1014,7 @@ function attachInput(canvas, src, channels) {
967
1014
  clientToLocal: src.clientToLocal,
968
1015
  context: src.context,
969
1016
  actions: src.actions,
1017
+ yieldKeys: src.yieldKeys,
970
1018
  uses: () => {
971
1019
  redraw.sync(src.dispatchers());
972
1020
  },
@@ -1001,12 +1049,7 @@ function attachInput(canvas, src, channels) {
1001
1049
  listeners.on(canvas, "pointerdown", () => {
1002
1050
  src.actions().activate();
1003
1051
  });
1004
- const setOver = (on) => () => {
1005
- core.setPointerOver(on);
1006
- };
1007
- listeners.on(canvas, "pointerenter", setOver(true));
1008
- listeners.on(canvas, "pointermove", setOver(true));
1009
- listeners.on(canvas, "pointerleave", setOver(false));
1052
+ trackPointerOver(listeners, canvas, core, keys);
1010
1053
  if (channels.pointer) {
1011
1054
  listeners.on(window, "keydown", hover.onKey);
1012
1055
  listeners.on(window, "keyup", hover.onKey);
@@ -1057,10 +1100,23 @@ function attachInput(canvas, src, channels) {
1057
1100
  src.context().keymaps?.closeAll();
1058
1101
  };
1059
1102
  }
1103
+ function trackPointerOver(listeners, canvas, core, keys) {
1104
+ const onOver = (e) => {
1105
+ if (core.pointerOver()) return;
1106
+ core.setPointerOver(true);
1107
+ keys.arrive(e);
1108
+ };
1109
+ listeners.on(canvas, "pointerenter", onOver);
1110
+ listeners.on(canvas, "pointermove", onOver);
1111
+ listeners.on(canvas, "pointerleave", () => {
1112
+ core.setPointerOver(false);
1113
+ keys.leave();
1114
+ });
1115
+ }
1060
1116
 
1061
1117
  // src/interactions/dispatcher/useGestureDispatcher.tsx
1062
1118
  function useGestureDispatcher(opts) {
1063
- const { canvasRef, actions, entriesById, enabled = true, keyboard = true, affordanceAt, classifyTarget, dispatcher: dispatcherOpt, trace: traceOpt, clientToWorld, clientToLocal, requestRedraw, paintedCursor, cursorSink, getRuleCtx, onClick, onDoubleClick, views, channels, longPress, claimKeys = false, hears = "scope" } = opts;
1119
+ const { canvasRef, actions, entriesById, enabled = true, keyboard = true, affordanceAt, classifyTarget, dispatcher: dispatcherOpt, trace: traceOpt, clientToWorld, clientToLocal, requestRedraw, paintedCursor, cursorSink, getRuleCtx, onClick, onDoubleClick, views, channels, longPress, claimKeys = false, hears = "scope", yieldKeys = false } = opts;
1064
1120
  const pointerChannel = channels?.pointer !== false;
1065
1121
  const hoverChannel = channels?.hover ?? pointerChannel;
1066
1122
  const wheelChannel = channels?.wheel !== false;
@@ -1149,7 +1205,8 @@ function useGestureDispatcher(opts) {
1149
1205
  kitSettings: () => kitSettingsRef.current,
1150
1206
  onClick: () => onClickRef.current,
1151
1207
  onDoubleClick: () => onDoubleClickRef.current,
1152
- clicks: clicksRef.current
1208
+ clicks: clicksRef.current,
1209
+ yieldKeys
1153
1210
  }, {
1154
1211
  keyboard,
1155
1212
  pointer: pointerChannel,
@@ -1163,6 +1220,7 @@ function useGestureDispatcher(opts) {
1163
1220
  }, [
1164
1221
  enabled,
1165
1222
  keyboard,
1223
+ yieldKeys,
1166
1224
  canvasRef,
1167
1225
  pointerChannel,
1168
1226
  hoverChannel,
@@ -1193,6 +1251,7 @@ function useCommand(id, label, run, options) {
1193
1251
  const hasEnabled = options?.enabled !== void 0;
1194
1252
  const hasActive = options?.active !== void 0;
1195
1253
  const icon = options?.icon;
1254
+ const group = options?.group;
1196
1255
  const action = useMemo(() => {
1197
1256
  const read = () => latest.current.options;
1198
1257
  const a = {
@@ -1206,8 +1265,9 @@ function useCommand(id, label, run, options) {
1206
1265
  if (hasEnabled) a.enabled = () => read()?.enabled?.() ?? true;
1207
1266
  if (hasActive) a.active = () => read()?.active?.() ?? false;
1208
1267
  if (icon !== void 0) a.icon = icon;
1268
+ if (group !== void 0) a.group = group;
1209
1269
  return a;
1210
- }, [id, label, icon, keys, tags, variants, hasEnabled, hasActive, latest]);
1270
+ }, [id, label, icon, group, keys, tags, variants, hasEnabled, hasActive, latest]);
1211
1271
  useAction(action);
1212
1272
  }
1213
1273
  function bindingOf(keys) {
@@ -1215,6 +1275,20 @@ function bindingOf(keys) {
1215
1275
  return "spec" in keys ? [keys] : keys;
1216
1276
  }
1217
1277
  var isList = (keys) => Array.isArray(keys);
1278
+ var NO_STORE = () => null;
1279
+ var NO_SUBSCRIBE2 = () => () => {
1280
+ };
1281
+ function lastOperationOf(registry) {
1282
+ return actionsNodeOf(registry)?.lastOperation ?? null;
1283
+ }
1284
+ function useLastOperationStore() {
1285
+ return lastOperationOf(useActionsRegistry());
1286
+ }
1287
+ function useLastOperation(store) {
1288
+ const inScope = useLastOperationStore();
1289
+ const s = store === void 0 ? inScope : store;
1290
+ return useSyncExternalStore(s?.subscribe ?? NO_SUBSCRIBE2, s?.get ?? NO_STORE, s?.get ?? NO_STORE);
1291
+ }
1218
1292
  function useNodes(descends, ownsTool, parent) {
1219
1293
  const parentActions = useActionsRegistry();
1220
1294
  const parentDeps = useOptionalDepRegistry();
@@ -1411,7 +1485,7 @@ function usePublishSelection(ids, kinds) {
1411
1485
  }
1412
1486
  }, [ctxRef, serializedRef]);
1413
1487
  }
1414
- var NO_SUBSCRIBE2 = () => () => {
1488
+ var NO_SUBSCRIBE3 = () => () => {
1415
1489
  };
1416
1490
  function useContributions(opts) {
1417
1491
  const ctx = useActiveToolContext();
@@ -1433,7 +1507,7 @@ function useContributions(opts) {
1433
1507
  }, [ctx]);
1434
1508
  const modes = opts.modes;
1435
1509
  const modeVersion = useSyncExternalStore(
1436
- modes ? modes.subscribe : NO_SUBSCRIBE2,
1510
+ modes ? modes.subscribe : NO_SUBSCRIBE3,
1437
1511
  () => modes?.getVersion() ?? 0
1438
1512
  );
1439
1513
  const openKeymap = useInnermostKeymap()?.id ?? null;
@@ -1505,6 +1579,32 @@ function useOffhandAction(entries) {
1505
1579
  return actionsRegistry.register(makeToolOffhandAction(buildToolOffhandBindings(specs)));
1506
1580
  }, [actionsRegistry, offhandSig]);
1507
1581
  }
1582
+ function useModeDefaultTool(modes, tools) {
1583
+ const toolsRef = useLatest(tools);
1584
+ const entered = useRef(null);
1585
+ useEffect(() => {
1586
+ if (!modes) return;
1587
+ const enter = (next, from) => {
1588
+ const target = defaultToolOf(next, toolsRef.current.has);
1589
+ entered.current = { mode: next, restore: target === null ? void 0 : from };
1590
+ const want = target ?? from;
1591
+ if (want !== toolsRef.current.active) toolsRef.current.setActive(want);
1592
+ };
1593
+ const follow = () => {
1594
+ const next = modes.current();
1595
+ const prior = entered.current;
1596
+ if (prior?.mode === next) return;
1597
+ const restore = prior?.restore;
1598
+ const back = restore !== void 0 && (restore === null || toolsRef.current.has(restore));
1599
+ enter(next, back ? restore : toolsRef.current.active);
1600
+ };
1601
+ if (entered.current === null) enter(modes.current(), toolsRef.current.active ?? toolsRef.current.initial);
1602
+ follow();
1603
+ return modes.subscribe(follow);
1604
+ }, [modes, toolsRef]);
1605
+ }
1606
+
1607
+ // src/tools/useTools.ts
1508
1608
  function declareSlot(tool, slot) {
1509
1609
  const hotkey = tool.def?.hotkey;
1510
1610
  const eligibility = {
@@ -1591,6 +1691,7 @@ function useTools(opts) {
1591
1691
  (id) => id in slotted.registry || slotted.ambient.some((t) => t.id === id),
1592
1692
  [slotted]
1593
1693
  );
1694
+ useModeDefaultTool(opts.modes, { active: contributions.focused, initial: initialActive, setActive, has });
1594
1695
  const active = contributions.focused;
1595
1696
  const getActiveOverlays = contributions.overlays;
1596
1697
  return useMemo(
@@ -1609,6 +1710,6 @@ function useTools(opts) {
1609
1710
  );
1610
1711
  }
1611
1712
 
1612
- export { ActiveToolContextProvider, ActiveToolContextProviderIfRoot, InputScope, PointerContextProvider, SelectionContextProvider, SelectionContextProviderIfRoot, Yoke, createPointerStore, useActiveToolContext, useCommand, useContributions, useGestureDispatcher, useOffhandAction, useOngoingAction, useOpenKeymap, useOptionalActiveToolContext, usePointerContext, usePointerPosition, usePublishSelection, useSelectionContext, useTools, useYoke };
1713
+ export { ActiveToolContextProvider, ActiveToolContextProviderIfRoot, InputScope, PointerContextProvider, SelectionContextProvider, SelectionContextProviderIfRoot, Yoke, createPointerStore, lastOperationOf, useActiveToolContext, useCommand, useContributions, useGestureDispatcher, useLastOperation, useLastOperationStore, useOffhandAction, useOngoingAction, useOpenKeymap, useOptionalActiveToolContext, usePointerContext, usePointerPosition, usePublishSelection, useSelectionContext, useTools, useYoke };
1613
1714
  //# sourceMappingURL=react.js.map
1614
1715
  //# sourceMappingURL=react.js.map