@weasel-js/routing 1.9.3 → 1.10.0
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/README.md +6 -5
- package/dist/{chunk-LOP2JTTA.js → chunk-4DR6AJMN.js} +1093 -922
- package/dist/chunk-4DR6AJMN.js.map +1 -0
- package/dist/{index-CrbDNXT_.d.ts → index-Bm2QEV09.d.ts} +576 -706
- package/dist/index.d.ts +5 -4
- package/dist/index.js +27 -74
- package/dist/index.js.map +1 -1
- package/dist/{internal-B1B6gfOS.d.ts → internal-D0rDmi7t.d.ts} +46 -78
- package/dist/internal.d.ts +5 -4
- package/dist/react.d.ts +140 -98
- package/dist/react.js +870 -896
- package/dist/react.js.map +1 -1
- package/package.json +9 -7
- package/dist/chunk-LOP2JTTA.js.map +0 -1
package/dist/react.d.ts
CHANGED
|
@@ -1,13 +1,26 @@
|
|
|
1
|
-
|
|
1
|
+
import { U as UseGestureDispatcherOptions } from './internal-D0rDmi7t.js';
|
|
2
|
+
export { D as DispatcherChannels } from './internal-D0rDmi7t.js';
|
|
2
3
|
import * as react from 'react';
|
|
3
4
|
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
|
|
5
|
+
import { D as DepRegistry, a as DepName, b as DepSchema, S as ScopeNode, A as ActionsRegistry, c as Action, d as DepNode, T as ToolNode, N as NodeId, K as KernelOverlay, C as Contribution, e as Tool, O as OverlayPosition } from './index-Bm2QEV09.js';
|
|
6
|
+
export { f as ActiveToolContextProvider, g as ActiveToolContextProviderIfRoot, h as ActiveToolContextProviderProps, i as ActiveToolContextValue, u as useActiveToolContext, j as useOptionalActiveToolContext } from './index-Bm2QEV09.js';
|
|
5
7
|
import { ModeRegistry } from '@weasel-js/modes';
|
|
6
8
|
import '@weasel-js/gestures';
|
|
7
9
|
import '@weasel-js/cursor';
|
|
8
|
-
import '@weasel-js/
|
|
10
|
+
import '@weasel-js/geom';
|
|
11
|
+
import '@weasel-js/registry';
|
|
9
12
|
import '@weasel-js/select';
|
|
10
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Attach the input pipeline to a canvas: DOM pointer, wheel, keyboard, and
|
|
16
|
+
* multitouch listeners in, normalized input events out, routed through the
|
|
17
|
+
* dispatcher to whichever action a binding names.
|
|
18
|
+
*
|
|
19
|
+
* The active tool and the dep registry come from context, so it must be
|
|
20
|
+
* mounted inside `<SceneCanvas>`'s providers.
|
|
21
|
+
*/
|
|
22
|
+
declare function useGestureDispatcher(opts: UseGestureDispatcherOptions): void;
|
|
23
|
+
|
|
11
24
|
/** Provides the dep registry for a canvas. `<SceneCanvas>` mounts one; a
|
|
12
25
|
* consumer registering its own dep sources must be inside it. */
|
|
13
26
|
declare function DepRegistryProvider({ children }: {
|
|
@@ -71,72 +84,9 @@ declare function useActionsRegistry(): ActionsRegistry | null;
|
|
|
71
84
|
*/
|
|
72
85
|
declare function useAction(action: Action): void;
|
|
73
86
|
|
|
74
|
-
/** Which tool is active, plus the stack of tools temporarily held active by a
|
|
75
|
-
* hotkey (space-for-hand and the like). The dispatcher reads this to decide
|
|
76
|
-
* whose bindings are in scope. */
|
|
77
|
-
interface ActiveToolContextValue {
|
|
78
|
-
/** The focused tool's id, or `null` when no tool holds the active slot —
|
|
79
|
-
* a canvas can run on ambient bindings alone. */
|
|
80
|
-
active: string | null;
|
|
81
|
-
hotkeyStack: string[];
|
|
82
|
-
setActive(id: string | null): void;
|
|
83
|
-
pushHotkey(id: string): void;
|
|
84
|
-
/**
|
|
85
|
-
* Disengage a hotkey-held tool. With `id`, removes that tool's own entry
|
|
86
|
-
* wherever it now sits — holds do not have to come up in the order they went
|
|
87
|
-
* down, and popping the top would disengage a tool whose key is still held.
|
|
88
|
-
* With no id, pops the top.
|
|
89
|
-
*/
|
|
90
|
-
popHotkey(id?: string): void;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* One node of the tool tree. A node that `owns` a tool holds its state; one
|
|
94
|
-
* that does not — a scope inside a yoke — reads and writes its yoke's.
|
|
95
|
-
*/
|
|
96
|
-
declare class ToolNode extends ScopeNode<ToolNode> {
|
|
97
|
-
private state;
|
|
98
|
-
private value;
|
|
99
|
-
constructor(parent: ToolNode | null, descends: boolean, owns: boolean, initialActive: string | null);
|
|
100
|
-
/** The node whose tool a read here resolves to. */
|
|
101
|
-
owner(): ToolNode;
|
|
102
|
-
private update;
|
|
103
|
-
/** A stable value per owner and state, for `useSyncExternalStore`. */
|
|
104
|
-
snapshot(): ActiveToolContextValue;
|
|
105
|
-
subscribe: (listener: () => void) => (() => void);
|
|
106
|
-
}
|
|
107
|
-
/** Props for `<ActiveToolContextProvider>`. */
|
|
108
|
-
interface ActiveToolContextProviderProps {
|
|
109
|
-
children: ReactNode;
|
|
110
|
-
/** Seeds the active slot, and wins over the first `useTools` call's
|
|
111
|
-
* `active`. Omitted, the slot starts empty and that call seeds it. */
|
|
112
|
-
initialActive?: string | null;
|
|
113
|
-
}
|
|
114
|
-
/** Provides root active-tool state. Every canvas below has a tool of its own;
|
|
115
|
-
* reads and writes here reach the one last used. */
|
|
116
|
-
declare function ActiveToolContextProvider({ children, initialActive, }: ActiveToolContextProviderProps): react.JSX.Element;
|
|
117
|
-
/** The active-tool state in scope. Throws outside a provider; use
|
|
118
|
-
* `useOptionalActiveToolContext` where one is not guaranteed. */
|
|
119
|
-
declare function useActiveToolContext(): ActiveToolContextValue;
|
|
120
|
-
/**
|
|
121
|
-
* Like `useActiveToolContext`, but returns `null` when no
|
|
122
|
-
* `<ActiveToolContextProvider>` is in scope instead of throwing. Used by
|
|
123
|
-
* `useStandardActions` to preserve its silent-no-op contract when no provider
|
|
124
|
-
* is present.
|
|
125
|
-
*/
|
|
126
|
-
declare function useOptionalActiveToolContext(): ActiveToolContextValue | null;
|
|
127
|
-
/**
|
|
128
|
-
* Conditional `<ActiveToolContextProvider>` wrapper. Mounts a provider only
|
|
129
|
-
* when no parent provider is in scope — otherwise renders children unwrapped
|
|
130
|
-
* so `<WeaselProvider>` defers to the host's existing scope.
|
|
131
|
-
*/
|
|
132
|
-
declare function ActiveToolContextProviderIfRoot({ children, }: {
|
|
133
|
-
children: ReactNode;
|
|
134
|
-
}): react.JSX.Element;
|
|
135
|
-
|
|
136
87
|
/**
|
|
137
88
|
* @experimental
|
|
138
89
|
* Input scopes and yokes: the tiers between a root registry and a canvas.
|
|
139
|
-
* Design: docs/proposals/2026-09-27-input-scopes.md.
|
|
140
90
|
*/
|
|
141
91
|
|
|
142
92
|
/** Props for `<InputScope>`. */
|
|
@@ -155,7 +105,9 @@ interface InputScopeProps {
|
|
|
155
105
|
*
|
|
156
106
|
* Chrome above calls `trigger` / `begin` / `useActiveToolContext` on its own
|
|
157
107
|
* registries, and those reach the active scope: the one last activated — by a
|
|
158
|
-
* pointerdown or wheel — or the newest where none has been.
|
|
108
|
+
* pointerdown or wheel — or the newest where none has been. Keys are stricter:
|
|
109
|
+
* one that reaches the page goes to the canvas last pressed or scrolled in,
|
|
110
|
+
* across every root on the page, and to none before the first.
|
|
159
111
|
*/
|
|
160
112
|
declare function InputScope({ yoke, children }: InputScopeProps): ReactElement;
|
|
161
113
|
/**
|
|
@@ -172,11 +124,10 @@ interface YokeProps {
|
|
|
172
124
|
/**
|
|
173
125
|
* @experimental
|
|
174
126
|
* Canvases that share input on purpose: the active tool, the gesture in
|
|
175
|
-
* flight, history and yoke-wide actions. Made once with `useYoke()
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
* toolbar, say. The members can sit anywhere in the tree
|
|
179
|
-
* tree, says who shares.
|
|
127
|
+
* flight, history, and yoke-wide actions. Made once with `useYoke()`, and
|
|
128
|
+
* passed to each canvas that joins it (`yoke={yoke}`) and to
|
|
129
|
+
* `<Yoke value={yoke}>` around anything else that should reach it — a
|
|
130
|
+
* toolbar, say. The members can sit anywhere in the tree.
|
|
180
131
|
*/
|
|
181
132
|
interface Yoke {
|
|
182
133
|
/** @internal */
|
|
@@ -206,6 +157,10 @@ declare function Yoke({ value, children }: YokeProps): ReactElement;
|
|
|
206
157
|
* on its own — a click on a swatch, a switch of paint kind.
|
|
207
158
|
* - `cancel()` ends an open edit without keeping it.
|
|
208
159
|
*
|
|
160
|
+
* An edit the dispatcher ended first — a tool switch, Escape, another control
|
|
161
|
+
* committing the same action — counts as not open: the next `input` opens a
|
|
162
|
+
* new one.
|
|
163
|
+
*
|
|
209
164
|
* All three are no-ops when no action is reachable, so a control renders the
|
|
210
165
|
* same with or without a canvas in scope.
|
|
211
166
|
*/
|
|
@@ -223,6 +178,101 @@ interface OngoingAction {
|
|
|
223
178
|
*/
|
|
224
179
|
declare function useOngoingAction(actionId: string): OngoingAction;
|
|
225
180
|
|
|
181
|
+
/** @experimental World-space pointer position and the view it is over — a
|
|
182
|
+
* view id, or `null` for a surface's own camera. `null` as a whole when the
|
|
183
|
+
* pointer is over no publishing surface. */
|
|
184
|
+
type PointerWorldPos = {
|
|
185
|
+
worldX: number;
|
|
186
|
+
worldY: number;
|
|
187
|
+
viewId: string | null;
|
|
188
|
+
} | null;
|
|
189
|
+
/** @experimental */
|
|
190
|
+
interface PointerContextValue {
|
|
191
|
+
/** The latest position. */
|
|
192
|
+
get(): PointerWorldPos;
|
|
193
|
+
/** Publish a position. Subscribers hear only a changed value. */
|
|
194
|
+
set(next: PointerWorldPos): void;
|
|
195
|
+
/** Called after every change; returns the unsubscribe. */
|
|
196
|
+
subscribe(fn: () => void): () => void;
|
|
197
|
+
/** Bumps on every change. */
|
|
198
|
+
getVersion(): number;
|
|
199
|
+
/** `get()` as a stable thunk, for hooks taking a drop-point option. */
|
|
200
|
+
readonly getDropPoint: () => PointerWorldPos;
|
|
201
|
+
}
|
|
202
|
+
/** @experimental A pointer store with no provider around it. */
|
|
203
|
+
declare function createPointerStore(): PointerContextValue;
|
|
204
|
+
/**
|
|
205
|
+
* @experimental
|
|
206
|
+
* Wrap the part of the React tree that should share one pointer.
|
|
207
|
+
* `<SceneCanvas>` mounts one when none is in scope, so mount it yourself only
|
|
208
|
+
* when two surfaces should share a pointer. Pass `store` to publish into one
|
|
209
|
+
* you hold elsewhere (`createPointerStore()`).
|
|
210
|
+
*/
|
|
211
|
+
declare function PointerContextProvider({ children, store }: {
|
|
212
|
+
children: ReactNode;
|
|
213
|
+
store?: PointerContextValue;
|
|
214
|
+
}): ReactNode;
|
|
215
|
+
/** @experimental The surrounding pointer store, or `null` when no provider is
|
|
216
|
+
* in scope. */
|
|
217
|
+
declare function usePointerContext(): PointerContextValue | null;
|
|
218
|
+
/** @experimental The pointer, re-rendering the caller whenever it changes.
|
|
219
|
+
* `null` outside a provider. */
|
|
220
|
+
declare function usePointerPosition(): PointerWorldPos;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* @experimental
|
|
224
|
+
* SelectionContext — an ambient context that publishes "what's currently
|
|
225
|
+
* selected" so non-canvas UI (command palette, status bar) can read it without
|
|
226
|
+
* threading a selection prop through the tree.
|
|
227
|
+
*
|
|
228
|
+
* **Single slot:** the context holds one selection array. Whichever publisher
|
|
229
|
+
* calls `publishSelection` most recently owns it, so a multi-canvas page gets
|
|
230
|
+
* last-writer-wins. `<SceneCanvas>` publishes automatically.
|
|
231
|
+
*/
|
|
232
|
+
|
|
233
|
+
/** @experimental */
|
|
234
|
+
interface SelectionContextValue {
|
|
235
|
+
/** The most-recently-published selection. Empty array when no canvas
|
|
236
|
+
* has published or when the active canvas's selection is empty. */
|
|
237
|
+
readonly selection: readonly NodeId[];
|
|
238
|
+
/** Optional per-id kind label, parallel to `selection` (e.g. `'rectangle'`,
|
|
239
|
+
* `'path'`, `'group'`). Sparse entries (`undefined`) are allowed; treat it
|
|
240
|
+
* as best-effort. */
|
|
241
|
+
readonly kinds?: readonly (string | undefined)[];
|
|
242
|
+
/** Publish the calling canvas's selection. Calling with the same content
|
|
243
|
+
* does not re-render the consumer tree. */
|
|
244
|
+
publishSelection(ids: readonly NodeId[], kinds?: readonly (string | undefined)[]): void;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* @experimental
|
|
248
|
+
* Wrap the part of the React tree that should share a selection context.
|
|
249
|
+
* Usually placed at the demo / app root, alongside `<ActionsProvider>`.
|
|
250
|
+
*/
|
|
251
|
+
declare function SelectionContextProvider({ children }: {
|
|
252
|
+
children: ReactNode;
|
|
253
|
+
}): ReactNode;
|
|
254
|
+
/**
|
|
255
|
+
* @experimental
|
|
256
|
+
* The current selection-context value, or `null` when no
|
|
257
|
+
* `<SelectionContextProvider>` is in scope.
|
|
258
|
+
*/
|
|
259
|
+
declare function useSelectionContext(): SelectionContextValue | null;
|
|
260
|
+
/**
|
|
261
|
+
* @experimental
|
|
262
|
+
* Mounts a `<SelectionContextProvider>` only when no parent provider is in
|
|
263
|
+
* scope; otherwise renders children unwrapped.
|
|
264
|
+
*/
|
|
265
|
+
declare function SelectionContextProviderIfRoot({ children, }: {
|
|
266
|
+
children: ReactNode;
|
|
267
|
+
}): ReactNode;
|
|
268
|
+
/**
|
|
269
|
+
* @experimental
|
|
270
|
+
* Publishes `ids` into the surrounding `<SelectionContextProvider>` whenever
|
|
271
|
+
* their content changes, and clears the slot on unmount unless another
|
|
272
|
+
* publisher has written it since. No-op when there's no provider in scope.
|
|
273
|
+
*/
|
|
274
|
+
declare function usePublishSelection(ids: readonly NodeId[], kinds?: readonly (string | undefined)[]): void;
|
|
275
|
+
|
|
226
276
|
/** Options for `useTools`: which tools exist, which one starts active, and
|
|
227
277
|
* which run continuously regardless of the active one. */
|
|
228
278
|
interface UseToolsOptions<TOverlay = KernelOverlay> {
|
|
@@ -232,7 +282,7 @@ interface UseToolsOptions<TOverlay = KernelOverlay> {
|
|
|
232
282
|
/** Tools eligible for the active slot or hotkey slot. The keys are the
|
|
233
283
|
* tool ids; the values are the tool records. A tool with `hotkey` set
|
|
234
284
|
* is wired into the hotkey slot whenever the engagement state matches. */
|
|
235
|
-
registry: Record<string,
|
|
285
|
+
registry: Record<string, Tool<TOverlay>>;
|
|
236
286
|
/** Always-on entries — tools or other contributions, live regardless of
|
|
237
287
|
* the active slot. */
|
|
238
288
|
ambient?: readonly Contribution<TOverlay>[];
|
|
@@ -248,8 +298,7 @@ interface ToolsApi<TOverlay = KernelOverlay> {
|
|
|
248
298
|
/** Set the active-slot tool, or `null` to clear it. The gesture dispatcher
|
|
249
299
|
* watches the active tool and cancels any in-flight handle itself. */
|
|
250
300
|
setActive: (id: string | null) => void;
|
|
251
|
-
/** Currently hotkey-engaged tool id (or `null`)
|
|
252
|
-
* the hotkey stack for backwards compat with the pre-stack API. */
|
|
301
|
+
/** Currently hotkey-engaged tool id (or `null`): the top of the hotkey stack. */
|
|
253
302
|
hotkeyEngaged: string | null;
|
|
254
303
|
/** Engage a hotkey-slot tool by id. */
|
|
255
304
|
engageHotkey: (id: string) => void;
|
|
@@ -258,31 +307,24 @@ interface ToolsApi<TOverlay = KernelOverlay> {
|
|
|
258
307
|
/** All always-on entries, in registration order. */
|
|
259
308
|
ambient: readonly Contribution<TOverlay>[];
|
|
260
309
|
/** Full registry — for userland UI (palette buttons, etc.). */
|
|
261
|
-
registry: Readonly<Record<string,
|
|
310
|
+
registry: Readonly<Record<string, Tool<TOverlay>>>;
|
|
262
311
|
/** Returns true if a tool with the given id is in the registry or ambient list. */
|
|
263
312
|
has(id: string): boolean;
|
|
264
|
-
/**
|
|
265
|
-
*
|
|
266
|
-
* Filters out tools with no `overlay` field. Order: active, then hotkey
|
|
267
|
-
* (if engaged), then ambient (registration order). */
|
|
313
|
+
/** Overlay layers from currently-engaged tools that declare `position`.
|
|
314
|
+
* Order: active, then hotkey (if engaged), then ambient (registration order). */
|
|
268
315
|
getActiveOverlays(position?: OverlayPosition): TOverlay[];
|
|
269
316
|
}
|
|
270
317
|
/**
|
|
271
|
-
* Manages the active tool and hotkey slot
|
|
272
|
-
*
|
|
273
|
-
* A thin shim over {@link useContributions}: the `registry` / `ambient`
|
|
274
|
-
* arguments are restated as declared eligibility (`focus` / `always`), and
|
|
275
|
-
* assembly happens in one place for tools and non-tool contributions alike.
|
|
318
|
+
* Manages the active tool and hotkey slot; a thin shim over
|
|
319
|
+
* {@link useContributions}.
|
|
276
320
|
*
|
|
277
321
|
* Requires `<ActiveToolContextProvider>` (or `<WeaselProvider>` /
|
|
278
322
|
* `<SceneCanvas>`, which mount one internally) in scope: active/hotkey state
|
|
279
|
-
* lives in the context
|
|
280
|
-
* `useTools` calls all read the same source of truth.
|
|
323
|
+
* lives in the context.
|
|
281
324
|
*
|
|
282
|
-
* **First
|
|
283
|
-
* `
|
|
284
|
-
*
|
|
285
|
-
* context currently holds (the first caller wins).
|
|
325
|
+
* **First mount wins**: if the context's slot is unseeded on first mount,
|
|
326
|
+
* `useTools` pushes `opts.active` to the context. Subsequent mounts respect
|
|
327
|
+
* whatever the context currently holds.
|
|
286
328
|
*/
|
|
287
329
|
declare function useTools<TOverlay = KernelOverlay>(opts: UseToolsOptions<TOverlay>): ToolsApi<TOverlay>;
|
|
288
330
|
|
|
@@ -294,9 +336,10 @@ interface UseContributionsOptions<TOverlay = KernelOverlay> {
|
|
|
294
336
|
/** Desired focused entry id, or `null` for none. First-mount-wins against
|
|
295
337
|
* the shared `ActiveToolContext` — see `useTools` for the full semantics. */
|
|
296
338
|
focused: string | null;
|
|
297
|
-
/** The modes the canvas can be in. The
|
|
298
|
-
*
|
|
299
|
-
*
|
|
339
|
+
/** The modes the canvas can be in. The active one decides which tagged
|
|
340
|
+
* entries draw their overlays, and the dev-time route-conflict check reads
|
|
341
|
+
* them all to decide whether two gated actions can ever compete; without a
|
|
342
|
+
* registry nothing is barred and the check uses the kit's `DEFAULT_MODES`. */
|
|
300
343
|
modes?: ModeRegistry;
|
|
301
344
|
}
|
|
302
345
|
/** The assembled registry {@link useContributions} returns. */
|
|
@@ -308,10 +351,9 @@ interface ContributionsApi<TOverlay = KernelOverlay> {
|
|
|
308
351
|
/** Focus an entry, or pass `null` to focus none. Writes through to the
|
|
309
352
|
* shared `ActiveToolContext`. */
|
|
310
353
|
setFocused: (id: string | null) => void;
|
|
311
|
-
/** Every live binding, tiered by the declaring entry's eligibility. */
|
|
312
|
-
scopedBindings(): ScopedBinding[];
|
|
313
354
|
/** Overlays of every live entry declaring `position`, ordered active, then
|
|
314
|
-
* hotkey, then ambient.
|
|
355
|
+
* hotkey, then ambient. Live is what the dispatcher routes to: an entry the
|
|
356
|
+
* active mode bars draws nothing. */
|
|
315
357
|
overlays(position?: OverlayPosition): TOverlay[];
|
|
316
358
|
}
|
|
317
359
|
/**
|
|
@@ -334,4 +376,4 @@ declare function useContributions<TOverlay = KernelOverlay>(opts: UseContributio
|
|
|
334
376
|
*/
|
|
335
377
|
declare function useOffhandAction(entries: readonly Contribution<unknown>[]): void;
|
|
336
378
|
|
|
337
|
-
export { ActionsProvider,
|
|
379
|
+
export { ActionsProvider, 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, useContributions, useDepRegistry, useDepSource, useGestureDispatcher, useOffhandAction, useOngoingAction, useOptionalDepRegistry, usePointerContext, usePointerPosition, usePublishSelection, useSelectionContext, useTools, useYoke };
|