@grida/svg-editor 1.0.0-alpha.2 → 1.0.0-alpha.3
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 +215 -5
- package/dist/{dom-CfP_ZURh.js → dom-BlJZWpR_.js} +614 -7
- package/dist/{dom-kA8NDuVh.mjs → dom-D-5D_3o0.mjs} +614 -7
- package/dist/dom.d.mts +37 -5
- package/dist/dom.d.ts +37 -5
- package/dist/dom.js +1 -1
- package/dist/dom.mjs +1 -1
- package/dist/{editor-M6j8XGO5.mjs → editor-DP36h-SE.mjs} +1 -10
- package/dist/{editor-BryibVvr.d.mts → editor-DSADZszj.d.mts} +258 -108
- package/dist/{editor-klT8wu-x.d.ts → editor-Da446SPO.d.ts} +258 -108
- package/dist/{editor-DllAMsDu.js → editor-Eon0043Z.js} +3 -12
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{paint-DuCg6Y-K.mjs → paint-BTKvRItP.mjs} +17 -1
- package/dist/{paint-DHq_3iwU.js → paint-CVLZazOa.js} +23 -1
- package/dist/react.d.mts +49 -6
- package/dist/react.d.ts +49 -6
- package/dist/react.js +49 -9
- package/dist/react.mjs +49 -10
- package/package.json +4 -4
|
@@ -1,113 +1,7 @@
|
|
|
1
|
+
import cmath from "@grida/cmath";
|
|
1
2
|
import * as _$_grida_history0 from "@grida/history";
|
|
2
3
|
import { Keybinding, Platform } from "@grida/keybinding";
|
|
3
4
|
|
|
4
|
-
//#region src/commands/registry.d.ts
|
|
5
|
-
/**
|
|
6
|
-
* Command registry.
|
|
7
|
-
*
|
|
8
|
-
* A passive id-keyed registry of handlers. Built so that:
|
|
9
|
-
*
|
|
10
|
-
* - keybindings (in `src/keymap`) can address commands by stable id;
|
|
11
|
-
* - new commands can be added in ONE place (`src/commands/defaults.ts`)
|
|
12
|
-
* without growing the public surface of the editor;
|
|
13
|
-
* - "one key, many meanings" can be expressed via chain semantics: a
|
|
14
|
-
* handler returns `true` if it consumed, `false`/`void` otherwise,
|
|
15
|
-
* and the dispatcher tries the next candidate in the chain.
|
|
16
|
-
*
|
|
17
|
-
* Handlers are plain closures — they capture whatever editor reference
|
|
18
|
-
* they need. The registry itself stays unaware of the editor's type,
|
|
19
|
-
* which avoids a circular type dependency between editor and registry.
|
|
20
|
-
*/
|
|
21
|
-
/** Stable, dotted id for a command, e.g. `"history.undo"`. */
|
|
22
|
-
type CommandId = string;
|
|
23
|
-
/**
|
|
24
|
-
* A command handler.
|
|
25
|
-
*
|
|
26
|
-
* Return `true` if the handler consumed the invocation. Return `false`
|
|
27
|
-
* or `undefined` to signal "did not apply" — the dispatcher will try
|
|
28
|
-
* the next candidate registered for the same key.
|
|
29
|
-
*
|
|
30
|
-
* Handlers are closures: they capture their editor reference. No
|
|
31
|
-
* editor parameter is passed — keep handlers self-contained.
|
|
32
|
-
*/
|
|
33
|
-
type CommandHandler = (args?: unknown) => boolean | void;
|
|
34
|
-
declare class CommandRegistry {
|
|
35
|
-
private readonly map;
|
|
36
|
-
/**
|
|
37
|
-
* Register a command. Returns an unregister function. Re-registering
|
|
38
|
-
* the same id replaces the previous handler (last writer wins).
|
|
39
|
-
*/
|
|
40
|
-
register(id: CommandId, handler: CommandHandler): () => void;
|
|
41
|
-
/**
|
|
42
|
-
* Invoke a command by id. Returns `true` if the handler consumed,
|
|
43
|
-
* `false` otherwise (including unknown ids and handlers that returned
|
|
44
|
-
* `false`/`undefined`).
|
|
45
|
-
*/
|
|
46
|
-
invoke(id: CommandId, args?: unknown): boolean;
|
|
47
|
-
has(id: CommandId): boolean;
|
|
48
|
-
/** All registered ids, for debugging / introspection. */
|
|
49
|
-
ids(): readonly CommandId[];
|
|
50
|
-
}
|
|
51
|
-
//#endregion
|
|
52
|
-
//#region src/keymap/keymap.d.ts
|
|
53
|
-
type KeymapBinding = {
|
|
54
|
-
/** Declarative key combination. Build with `kb()` / `c()` / `seq()`. */keybinding: Keybinding; /** Command id to invoke on match. */
|
|
55
|
-
command: CommandId; /** Forwarded as the `args` parameter to the command handler. */
|
|
56
|
-
args?: unknown; /** Higher priorities run first in the chain. Default 0. */
|
|
57
|
-
priority?: number;
|
|
58
|
-
/**
|
|
59
|
-
* Reserved for V2; not honored by the V1 dispatcher. When added, this
|
|
60
|
-
* will be evaluated before the handler runs; if false, the binding is
|
|
61
|
-
* skipped without invoking the handler.
|
|
62
|
-
*/
|
|
63
|
-
when?: (ctx: unknown) => boolean;
|
|
64
|
-
};
|
|
65
|
-
declare class Keymap {
|
|
66
|
-
private readonly commands;
|
|
67
|
-
private readonly platformGetter;
|
|
68
|
-
/**
|
|
69
|
-
* Bindings bucketed by canonical chunk-key hash, computed per
|
|
70
|
-
* `@grida/keybinding`'s `chunkKey`. Each list is the chain for that
|
|
71
|
-
* key, sorted in dispatch order (priority desc, then registration
|
|
72
|
-
* order).
|
|
73
|
-
*/
|
|
74
|
-
private readonly buckets;
|
|
75
|
-
/** Insert order, so ties on priority are deterministic. */
|
|
76
|
-
private seq;
|
|
77
|
-
constructor(commands: CommandRegistry, platformGetter?: () => Platform);
|
|
78
|
-
/**
|
|
79
|
-
* Bind a key combination to a command. Returns an unbind function.
|
|
80
|
-
* The same `Keybinding` can be bound to multiple commands — they will
|
|
81
|
-
* all be tried in chain order on dispatch.
|
|
82
|
-
*/
|
|
83
|
-
bind(binding: KeymapBinding): () => void;
|
|
84
|
-
/**
|
|
85
|
-
* Remove bindings matching the spec. If both filters are passed, only
|
|
86
|
-
* bindings that match BOTH are removed.
|
|
87
|
-
*/
|
|
88
|
-
unbind(spec: {
|
|
89
|
-
keybinding?: Keybinding;
|
|
90
|
-
command?: CommandId;
|
|
91
|
-
}): void;
|
|
92
|
-
/** All registered bindings, for introspection. Order is not guaranteed. */
|
|
93
|
-
bindings(): readonly KeymapBinding[];
|
|
94
|
-
/**
|
|
95
|
-
* Match the event against bound chunks, then run candidates in chain
|
|
96
|
-
* order. Returns `true` and calls `preventDefault()` on the first
|
|
97
|
-
* handler that consumes; returns `false` if nothing matched or all
|
|
98
|
-
* matches fell through.
|
|
99
|
-
*/
|
|
100
|
-
dispatch(event: KeyboardEvent): boolean;
|
|
101
|
-
/**
|
|
102
|
-
* Compute the set of canonical hashes a `Keybinding` lights up. A
|
|
103
|
-
* binding with aliases (multiple sequences) contributes one hash per
|
|
104
|
-
* single-chunk alias; multi-chunk sequences (chords) are skipped in
|
|
105
|
-
* V1.
|
|
106
|
-
*/
|
|
107
|
-
private chunkKeysFor;
|
|
108
|
-
private has_safe_mod;
|
|
109
|
-
}
|
|
110
|
-
//#endregion
|
|
111
5
|
//#region src/types.d.ts
|
|
112
6
|
/**
|
|
113
7
|
* Stable identifier for a node in the editor's document model.
|
|
@@ -278,6 +172,206 @@ type PaintPreviewSession = {
|
|
|
278
172
|
discard(): void;
|
|
279
173
|
};
|
|
280
174
|
//#endregion
|
|
175
|
+
//#region src/core/camera.d.ts
|
|
176
|
+
/**
|
|
177
|
+
* Returns world-space bounds for the given target, or `null` when
|
|
178
|
+
* unresolvable (e.g. empty selection, unknown node id). Implemented by the
|
|
179
|
+
* surface — the camera itself has no view into the document.
|
|
180
|
+
*
|
|
181
|
+
* Only string targets are passed to the resolver — `Rect` targets are
|
|
182
|
+
* handled by the camera as identity (the rect IS its own bounds).
|
|
183
|
+
*/
|
|
184
|
+
type BoundsResolver = (target: "<root>" | "<selection>" | NodeId) => Rect | null;
|
|
185
|
+
type CameraOptions = {
|
|
186
|
+
resolve_bounds: BoundsResolver;
|
|
187
|
+
initial?: cmath.Transform;
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* Surface-scoped pan/zoom state.
|
|
191
|
+
*
|
|
192
|
+
* The public shape leads with the peer convention (`center` / `zoom` /
|
|
193
|
+
* `bounds`) and keeps the matrix as an advanced read. Methods mirror
|
|
194
|
+
* Figma/Penpot where they overlap.
|
|
195
|
+
*/
|
|
196
|
+
declare class Camera {
|
|
197
|
+
private _transform;
|
|
198
|
+
private viewport_w;
|
|
199
|
+
private viewport_h;
|
|
200
|
+
private listeners;
|
|
201
|
+
private resolve_bounds;
|
|
202
|
+
constructor(opts: CameraOptions);
|
|
203
|
+
/** Underlying 2D affine. World→screen. */
|
|
204
|
+
get transform(): cmath.Transform;
|
|
205
|
+
/** Uniform scale factor. 1 = 100 %. */
|
|
206
|
+
get zoom(): number;
|
|
207
|
+
/** World-space point currently at viewport center. */
|
|
208
|
+
get center(): Vec2;
|
|
209
|
+
/** World-space rectangle visible in the viewport. */
|
|
210
|
+
get bounds(): Rect;
|
|
211
|
+
/** Translate the camera by a screen-space delta. */
|
|
212
|
+
pan(delta_screen: Vec2): void;
|
|
213
|
+
/**
|
|
214
|
+
* Multiply zoom by `factor` keeping `origin_screen` fixed in world space.
|
|
215
|
+
* Used by wheel-zoom-at-cursor and pinch-zoom.
|
|
216
|
+
*/
|
|
217
|
+
zoom_at(factor: number, origin_screen: Vec2): void;
|
|
218
|
+
/** Pan so `c` lands at the viewport center. Zoom unchanged. */
|
|
219
|
+
set_center(c: Vec2): void;
|
|
220
|
+
/** Set zoom directly; pivot defaults to viewport center. */
|
|
221
|
+
set_zoom(z: number, pivot_screen?: Vec2): void;
|
|
222
|
+
/**
|
|
223
|
+
* Replace the entire transform.
|
|
224
|
+
*
|
|
225
|
+
* Idempotent: when the new transform is element-wise equal to the current
|
|
226
|
+
* one, this is a no-op (no notification fires). This is the seam that
|
|
227
|
+
* makes external constraint loops (e.g. "subscribe → compute clamped →
|
|
228
|
+
* set_transform") terminate: the clamp re-emits the same transform on
|
|
229
|
+
* the second pass, set_transform short-circuits, no recursion.
|
|
230
|
+
*/
|
|
231
|
+
set_transform(t: cmath.Transform): void;
|
|
232
|
+
/** Viewport size in screen pixels. Read by host code computing constraints. */
|
|
233
|
+
get viewport_size(): {
|
|
234
|
+
width: number;
|
|
235
|
+
height: number;
|
|
236
|
+
};
|
|
237
|
+
/**
|
|
238
|
+
* Fit a target into the viewport.
|
|
239
|
+
*
|
|
240
|
+
* - `"<root>"` — the document root's content bounds (host-resolved).
|
|
241
|
+
* - `"<selection>"` — current editor.state.selection's union bounds.
|
|
242
|
+
* - `NodeId` — that node's content bounds.
|
|
243
|
+
* - `Rect` — an explicit world-space rectangle.
|
|
244
|
+
*
|
|
245
|
+
* No-ops if the target resolves to `null` (e.g. empty selection) or if
|
|
246
|
+
* the viewport size is 0 (no container).
|
|
247
|
+
*/
|
|
248
|
+
fit(target: "<root>" | "<selection>" | NodeId | Rect, opts?: {
|
|
249
|
+
margin?: number;
|
|
250
|
+
}): void;
|
|
251
|
+
/** Snap back to identity. */
|
|
252
|
+
reset(): void;
|
|
253
|
+
/**
|
|
254
|
+
* Subscribe to camera changes. Fires on every mutation. Cheap channel —
|
|
255
|
+
* does NOT bump `editor.state.version`. Same pattern as
|
|
256
|
+
* `editor.subscribe_surface_hover`.
|
|
257
|
+
*/
|
|
258
|
+
subscribe(cb: () => void): Unsubscribe;
|
|
259
|
+
/** @internal Surface drives this on container resize. */
|
|
260
|
+
_set_viewport_size(w: number, h: number): void;
|
|
261
|
+
/** Convert a screen-space point to world-space. */
|
|
262
|
+
screen_to_world(p: Vec2): Vec2;
|
|
263
|
+
/** Convert a world-space point to screen-space. */
|
|
264
|
+
world_to_screen(p: Vec2): Vec2;
|
|
265
|
+
private notify;
|
|
266
|
+
}
|
|
267
|
+
//#endregion
|
|
268
|
+
//#region src/commands/registry.d.ts
|
|
269
|
+
/**
|
|
270
|
+
* Command registry.
|
|
271
|
+
*
|
|
272
|
+
* A passive id-keyed registry of handlers. Built so that:
|
|
273
|
+
*
|
|
274
|
+
* - keybindings (in `src/keymap`) can address commands by stable id;
|
|
275
|
+
* - new commands can be added in ONE place (`src/commands/defaults.ts`)
|
|
276
|
+
* without growing the public surface of the editor;
|
|
277
|
+
* - "one key, many meanings" can be expressed via chain semantics: a
|
|
278
|
+
* handler returns `true` if it consumed, `false`/`void` otherwise,
|
|
279
|
+
* and the dispatcher tries the next candidate in the chain.
|
|
280
|
+
*
|
|
281
|
+
* Handlers are plain closures — they capture whatever editor reference
|
|
282
|
+
* they need. The registry itself stays unaware of the editor's type,
|
|
283
|
+
* which avoids a circular type dependency between editor and registry.
|
|
284
|
+
*/
|
|
285
|
+
/** Stable, dotted id for a command, e.g. `"history.undo"`. */
|
|
286
|
+
type CommandId = string;
|
|
287
|
+
/**
|
|
288
|
+
* A command handler.
|
|
289
|
+
*
|
|
290
|
+
* Return `true` if the handler consumed the invocation. Return `false`
|
|
291
|
+
* or `undefined` to signal "did not apply" — the dispatcher will try
|
|
292
|
+
* the next candidate registered for the same key.
|
|
293
|
+
*
|
|
294
|
+
* Handlers are closures: they capture their editor reference. No
|
|
295
|
+
* editor parameter is passed — keep handlers self-contained.
|
|
296
|
+
*/
|
|
297
|
+
type CommandHandler = (args?: unknown) => boolean | void;
|
|
298
|
+
declare class CommandRegistry {
|
|
299
|
+
private readonly map;
|
|
300
|
+
/**
|
|
301
|
+
* Register a command. Returns an unregister function. Re-registering
|
|
302
|
+
* the same id replaces the previous handler (last writer wins).
|
|
303
|
+
*/
|
|
304
|
+
register(id: CommandId, handler: CommandHandler): () => void;
|
|
305
|
+
/**
|
|
306
|
+
* Invoke a command by id. Returns `true` if the handler consumed,
|
|
307
|
+
* `false` otherwise (including unknown ids and handlers that returned
|
|
308
|
+
* `false`/`undefined`).
|
|
309
|
+
*/
|
|
310
|
+
invoke(id: CommandId, args?: unknown): boolean;
|
|
311
|
+
has(id: CommandId): boolean;
|
|
312
|
+
/** All registered ids, for debugging / introspection. */
|
|
313
|
+
ids(): readonly CommandId[];
|
|
314
|
+
}
|
|
315
|
+
//#endregion
|
|
316
|
+
//#region src/keymap/keymap.d.ts
|
|
317
|
+
type KeymapBinding = {
|
|
318
|
+
/** Declarative key combination. Build with `kb()` / `c()` / `seq()`. */keybinding: Keybinding; /** Command id to invoke on match. */
|
|
319
|
+
command: CommandId; /** Forwarded as the `args` parameter to the command handler. */
|
|
320
|
+
args?: unknown; /** Higher priorities run first in the chain. Default 0. */
|
|
321
|
+
priority?: number;
|
|
322
|
+
/**
|
|
323
|
+
* Reserved for V2; not honored by the V1 dispatcher. When added, this
|
|
324
|
+
* will be evaluated before the handler runs; if false, the binding is
|
|
325
|
+
* skipped without invoking the handler.
|
|
326
|
+
*/
|
|
327
|
+
when?: (ctx: unknown) => boolean;
|
|
328
|
+
};
|
|
329
|
+
declare class Keymap {
|
|
330
|
+
private readonly commands;
|
|
331
|
+
private readonly platformGetter;
|
|
332
|
+
/**
|
|
333
|
+
* Bindings bucketed by canonical chunk-key hash, computed per
|
|
334
|
+
* `@grida/keybinding`'s `chunkKey`. Each list is the chain for that
|
|
335
|
+
* key, sorted in dispatch order (priority desc, then registration
|
|
336
|
+
* order).
|
|
337
|
+
*/
|
|
338
|
+
private readonly buckets;
|
|
339
|
+
/** Insert order, so ties on priority are deterministic. */
|
|
340
|
+
private seq;
|
|
341
|
+
constructor(commands: CommandRegistry, platformGetter?: () => Platform);
|
|
342
|
+
/**
|
|
343
|
+
* Bind a key combination to a command. Returns an unbind function.
|
|
344
|
+
* The same `Keybinding` can be bound to multiple commands — they will
|
|
345
|
+
* all be tried in chain order on dispatch.
|
|
346
|
+
*/
|
|
347
|
+
bind(binding: KeymapBinding): () => void;
|
|
348
|
+
/**
|
|
349
|
+
* Remove bindings matching the spec. If both filters are passed, only
|
|
350
|
+
* bindings that match BOTH are removed.
|
|
351
|
+
*/
|
|
352
|
+
unbind(spec: {
|
|
353
|
+
keybinding?: Keybinding;
|
|
354
|
+
command?: CommandId;
|
|
355
|
+
}): void;
|
|
356
|
+
/** All registered bindings, for introspection. Order is not guaranteed. */
|
|
357
|
+
bindings(): readonly KeymapBinding[];
|
|
358
|
+
/**
|
|
359
|
+
* Match the event against bound chunks, then run candidates in chain
|
|
360
|
+
* order. Returns `true` and calls `preventDefault()` on the first
|
|
361
|
+
* handler that consumes; returns `false` if nothing matched or all
|
|
362
|
+
* matches fell through.
|
|
363
|
+
*/
|
|
364
|
+
dispatch(event: KeyboardEvent): boolean;
|
|
365
|
+
/**
|
|
366
|
+
* Compute the set of canonical hashes a `Keybinding` lights up. A
|
|
367
|
+
* binding with aliases (multiple sequences) contributes one hash per
|
|
368
|
+
* single-chunk alias; multi-chunk sequences (chords) are skipped in
|
|
369
|
+
* V1.
|
|
370
|
+
*/
|
|
371
|
+
private chunkKeysFor;
|
|
372
|
+
private has_safe_mod;
|
|
373
|
+
}
|
|
374
|
+
//#endregion
|
|
281
375
|
//#region src/core/parser.d.ts
|
|
282
376
|
type AttrToken = {
|
|
283
377
|
/** Verbatim source name including any prefix, e.g. "xlink:href". */raw_name: string; /** Prefix or null. */
|
|
@@ -439,6 +533,62 @@ type Defs = {
|
|
|
439
533
|
//#region src/core/properties.d.ts
|
|
440
534
|
declare function read_property(doc: SvgDocument, id: NodeId, property: string): PropertyValue;
|
|
441
535
|
//#endregion
|
|
536
|
+
//#region src/gestures/gestures.d.ts
|
|
537
|
+
/** Stable identifier for a gesture binding. Used by `unbind({ id })`. */
|
|
538
|
+
type GestureId = string;
|
|
539
|
+
/**
|
|
540
|
+
* Context passed to every installer. Exposes the seams a gesture needs:
|
|
541
|
+
* the container element to listen on, the camera to mutate, and the
|
|
542
|
+
* editor for keymap dispatch / state reads.
|
|
543
|
+
*
|
|
544
|
+
* Surface authors construct this once at attach; bindings receive it on
|
|
545
|
+
* every `install(...)` call.
|
|
546
|
+
*/
|
|
547
|
+
type GestureContext = {
|
|
548
|
+
/** Container element listeners attach to. */container: HTMLElement; /** SVG element being framed by the camera. Useful for hit-testing. */
|
|
549
|
+
svg_root: () => SVGSVGElement | null; /** HUD canvas overlay; sits on top of the SVG. */
|
|
550
|
+
hud_canvas: HTMLCanvasElement; /** Camera the binding mutates. */
|
|
551
|
+
camera: Camera; /** Editor for keymap dispatch / state reads. */
|
|
552
|
+
editor: SvgEditor; /** Handle for advanced bindings (e.g. wanting `camera.fit("<selection>")`). */
|
|
553
|
+
handle: SurfaceHandle;
|
|
554
|
+
};
|
|
555
|
+
type GestureBinding = {
|
|
556
|
+
/** Stable id used by `unbind` / `bindings()`. */id: GestureId;
|
|
557
|
+
/**
|
|
558
|
+
* Wire DOM listeners (or any side-effect) needed for this gesture.
|
|
559
|
+
* Returns the uninstaller — called on `unbind` or surface detach.
|
|
560
|
+
*/
|
|
561
|
+
install(ctx: GestureContext): () => void;
|
|
562
|
+
};
|
|
563
|
+
/**
|
|
564
|
+
* Sibling to `Keymap`. Owns a list of installed gesture bindings; each
|
|
565
|
+
* binding's `install(ctx)` is called eagerly when bound and uninstalled
|
|
566
|
+
* on `unbind` or surface detach.
|
|
567
|
+
*/
|
|
568
|
+
declare class Gestures {
|
|
569
|
+
private readonly ctx;
|
|
570
|
+
private entries;
|
|
571
|
+
constructor(ctx: GestureContext);
|
|
572
|
+
/**
|
|
573
|
+
* Install a gesture binding. Returns an unbind function.
|
|
574
|
+
* Re-binding the same `id` does NOT replace — both will be active.
|
|
575
|
+
* Use `unbind({ id })` first if you want a clean swap.
|
|
576
|
+
*/
|
|
577
|
+
bind(binding: GestureBinding): () => void;
|
|
578
|
+
/**
|
|
579
|
+
* Remove bindings matching the spec. With `{ id }`, all bindings with
|
|
580
|
+
* that id are uninstalled. With no spec, this is a no-op (use
|
|
581
|
+
* `dispose()` to nuke everything).
|
|
582
|
+
*/
|
|
583
|
+
unbind(spec: {
|
|
584
|
+
id?: GestureId;
|
|
585
|
+
}): void;
|
|
586
|
+
/** All currently installed bindings. Order is registration order. */
|
|
587
|
+
bindings(): readonly GestureBinding[];
|
|
588
|
+
/** @internal Uninstall every binding. Surface calls on detach. */
|
|
589
|
+
_dispose(): void;
|
|
590
|
+
}
|
|
591
|
+
//#endregion
|
|
442
592
|
//#region src/core/editor.d.ts
|
|
443
593
|
/** Resolved paint from the DOM-attached cascade. `resolved_paint` mirrors the
|
|
444
594
|
* shape of `PaintValue.computed` so consumers can treat it uniformly with
|
|
@@ -609,4 +759,4 @@ declare function createSvgEditor(opts: CreateSvgEditorOptions): {
|
|
|
609
759
|
keymap: Keymap;
|
|
610
760
|
};
|
|
611
761
|
//#endregion
|
|
612
|
-
export {
|
|
762
|
+
export { Mode as A, RadialGradientDefinition as B, FileIOProvider as C, GradientStop as D, GradientEntry as E, PaintValue as F, ReorderDirection as H, PreviewSession as I, PropertyValue as L, Paint as M, PaintFallback as N, InvalidComputedValue as O, PaintPreviewSession as P, Provenance as R, EditorStyle as S, GradientDefinition as T, Unsubscribe as U, Rect as V, Vec2 as W, CameraOptions as _, SurfaceHandle as a, DEFAULT_STYLE as b, GestureBinding as c, Gestures as d, KeymapBinding as f, Camera as g, BoundsResolver as h, DomComputedResolver as i, NodeId as j, LinearGradientDefinition as k, GestureContext as l, CommandId as m, CreateSvgEditorOptions as n, SvgEditor as o, CommandHandler as p, DomComputedPaint as r, createSvgEditor as s, Commands as t, GestureId as u, ClipboardProvider as v, FontResolver as w, EditorState as x, Color as y, Providers as z };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
require("./dom-
|
|
2
|
-
const require_paint = require("./paint-
|
|
1
|
+
require("./dom-BlJZWpR_.js");
|
|
2
|
+
const require_paint = require("./paint-CVLZazOa.js");
|
|
3
3
|
let _grida_history = require("@grida/history");
|
|
4
4
|
let _grida_keybinding = require("@grida/keybinding");
|
|
5
5
|
//#region src/commands/registry.ts
|
|
@@ -112,15 +112,6 @@ const TEXT_INPUT_SAFE_MODS = new Set([
|
|
|
112
112
|
_grida_keybinding.KeyCode.Ctrl,
|
|
113
113
|
_grida_keybinding.KeyCode.Alt
|
|
114
114
|
]);
|
|
115
|
-
function is_text_input_focused() {
|
|
116
|
-
if (typeof document === "undefined") return false;
|
|
117
|
-
const el = document.activeElement;
|
|
118
|
-
if (!el) return false;
|
|
119
|
-
const tag = el.tagName;
|
|
120
|
-
if (tag === "INPUT" || tag === "TEXTAREA") return true;
|
|
121
|
-
if (el.isContentEditable) return true;
|
|
122
|
-
return false;
|
|
123
|
-
}
|
|
124
115
|
var Keymap = class {
|
|
125
116
|
constructor(commands, platformGetter = _grida_keybinding.getKeyboardOS) {
|
|
126
117
|
this.commands = commands;
|
|
@@ -189,7 +180,7 @@ var Keymap = class {
|
|
|
189
180
|
const hash = (0, _grida_keybinding.chunkKey)(chunk);
|
|
190
181
|
const list = this.buckets.get(hash);
|
|
191
182
|
if (!list || list.length === 0) return false;
|
|
192
|
-
const text_focused = is_text_input_focused();
|
|
183
|
+
const text_focused = require_paint.is_text_input_focused();
|
|
193
184
|
for (const { binding } of list) {
|
|
194
185
|
if (text_focused && !this.has_safe_mod(chunk.mods)) continue;
|
|
195
186
|
if (this.commands.invoke(binding.command, binding.args)) {
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as RadialGradientDefinition, C as
|
|
2
|
-
export { type ClipboardProvider, type Color, type CommandHandler, type CommandId, type Commands, type CreateSvgEditorOptions, DEFAULT_STYLE, type DomComputedPaint, type DomComputedResolver, type EditorState, type EditorStyle, type FileIOProvider, type FontResolver, type GradientDefinition, type GradientEntry, type GradientStop, type InvalidComputedValue, type KeymapBinding, type LinearGradientDefinition, type Mode, type NodeId, type Paint, type PaintFallback, type PaintPreviewSession, type PaintValue, type PreviewSession, type PropertyValue, type Provenance, type Providers, type RadialGradientDefinition, type Rect, type ReorderDirection, type SurfaceHandle, type SvgEditor, type Unsubscribe, type Vec2, createSvgEditor };
|
|
1
|
+
import { A as Mode, B as RadialGradientDefinition, C as FileIOProvider, D as GradientStop, E as GradientEntry, F as PaintValue, H as ReorderDirection, I as PreviewSession, L as PropertyValue, M as Paint, N as PaintFallback, O as InvalidComputedValue, P as PaintPreviewSession, R as Provenance, S as EditorStyle, T as GradientDefinition, U as Unsubscribe, V as Rect, W as Vec2, _ as CameraOptions, a as SurfaceHandle, b as DEFAULT_STYLE, c as GestureBinding, d as Gestures, f as KeymapBinding, g as Camera, h as BoundsResolver, i as DomComputedResolver, j as NodeId, k as LinearGradientDefinition, l as GestureContext, m as CommandId, n as CreateSvgEditorOptions, o as SvgEditor, p as CommandHandler, r as DomComputedPaint, s as createSvgEditor, t as Commands, u as GestureId, v as ClipboardProvider, w as FontResolver, x as EditorState, y as Color, z as Providers } from "./editor-DSADZszj.mjs";
|
|
2
|
+
export { type BoundsResolver, type Camera, type CameraOptions, type ClipboardProvider, type Color, type CommandHandler, type CommandId, type Commands, type CreateSvgEditorOptions, DEFAULT_STYLE, type DomComputedPaint, type DomComputedResolver, type EditorState, type EditorStyle, type FileIOProvider, type FontResolver, type GestureBinding, type GestureContext, type GestureId, type Gestures, type GradientDefinition, type GradientEntry, type GradientStop, type InvalidComputedValue, type KeymapBinding, type LinearGradientDefinition, type Mode, type NodeId, type Paint, type PaintFallback, type PaintPreviewSession, type PaintValue, type PreviewSession, type PropertyValue, type Provenance, type Providers, type RadialGradientDefinition, type Rect, type ReorderDirection, type SurfaceHandle, type SvgEditor, type Unsubscribe, type Vec2, createSvgEditor };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as RadialGradientDefinition, C as
|
|
2
|
-
export { type ClipboardProvider, type Color, type CommandHandler, type CommandId, type Commands, type CreateSvgEditorOptions, DEFAULT_STYLE, type DomComputedPaint, type DomComputedResolver, type EditorState, type EditorStyle, type FileIOProvider, type FontResolver, type GradientDefinition, type GradientEntry, type GradientStop, type InvalidComputedValue, type KeymapBinding, type LinearGradientDefinition, type Mode, type NodeId, type Paint, type PaintFallback, type PaintPreviewSession, type PaintValue, type PreviewSession, type PropertyValue, type Provenance, type Providers, type RadialGradientDefinition, type Rect, type ReorderDirection, type SurfaceHandle, type SvgEditor, type Unsubscribe, type Vec2, createSvgEditor };
|
|
1
|
+
import { A as Mode, B as RadialGradientDefinition, C as FileIOProvider, D as GradientStop, E as GradientEntry, F as PaintValue, H as ReorderDirection, I as PreviewSession, L as PropertyValue, M as Paint, N as PaintFallback, O as InvalidComputedValue, P as PaintPreviewSession, R as Provenance, S as EditorStyle, T as GradientDefinition, U as Unsubscribe, V as Rect, W as Vec2, _ as CameraOptions, a as SurfaceHandle, b as DEFAULT_STYLE, c as GestureBinding, d as Gestures, f as KeymapBinding, g as Camera, h as BoundsResolver, i as DomComputedResolver, j as NodeId, k as LinearGradientDefinition, l as GestureContext, m as CommandId, n as CreateSvgEditorOptions, o as SvgEditor, p as CommandHandler, r as DomComputedPaint, s as createSvgEditor, t as Commands, u as GestureId, v as ClipboardProvider, w as FontResolver, x as EditorState, y as Color, z as Providers } from "./editor-Da446SPO.js";
|
|
2
|
+
export { type BoundsResolver, type Camera, type CameraOptions, type ClipboardProvider, type Color, type CommandHandler, type CommandId, type Commands, type CreateSvgEditorOptions, DEFAULT_STYLE, type DomComputedPaint, type DomComputedResolver, type EditorState, type EditorStyle, type FileIOProvider, type FontResolver, type GestureBinding, type GestureContext, type GestureId, type Gestures, type GradientDefinition, type GradientEntry, type GradientStop, type InvalidComputedValue, type KeymapBinding, type LinearGradientDefinition, type Mode, type NodeId, type Paint, type PaintFallback, type PaintPreviewSession, type PaintValue, type PreviewSession, type PropertyValue, type Provenance, type Providers, type RadialGradientDefinition, type Rect, type ReorderDirection, type SurfaceHandle, type SvgEditor, type Unsubscribe, type Vec2, createSvgEditor };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_editor = require("./editor-
|
|
2
|
+
const require_editor = require("./editor-Eon0043Z.js");
|
|
3
3
|
exports.DEFAULT_STYLE = require_editor.DEFAULT_STYLE;
|
|
4
4
|
exports.createSvgEditor = require_editor.createSvgEditor;
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as DEFAULT_STYLE, t as createSvgEditor } from "./editor-
|
|
1
|
+
import { n as DEFAULT_STYLE, t as createSvgEditor } from "./editor-DP36h-SE.mjs";
|
|
2
2
|
export { DEFAULT_STYLE, createSvgEditor };
|
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
import { SVGPathData, SVGPathDataTransformer } from "svg-pathdata";
|
|
2
|
+
//#region src/util/dom.ts
|
|
3
|
+
/**
|
|
4
|
+
* `true` when the document's active element is a text-input-like control
|
|
5
|
+
* (input / textarea / contentEditable). Used by keymap + gesture defaults
|
|
6
|
+
* to avoid hijacking keystrokes while the user is typing.
|
|
7
|
+
*/
|
|
8
|
+
function is_text_input_focused() {
|
|
9
|
+
if (typeof document === "undefined") return false;
|
|
10
|
+
const el = document.activeElement;
|
|
11
|
+
if (!el) return false;
|
|
12
|
+
const tag = el.tagName;
|
|
13
|
+
if (tag === "INPUT" || tag === "TEXTAREA") return true;
|
|
14
|
+
if (el.isContentEditable) return true;
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
2
18
|
//#region src/core/intents.ts
|
|
3
19
|
function num(doc, id, name, fallback = 0) {
|
|
4
20
|
const v = doc.get_attr(id, name);
|
|
@@ -458,4 +474,4 @@ function serialize_paint(paint) {
|
|
|
458
474
|
}
|
|
459
475
|
}
|
|
460
476
|
//#endregion
|
|
461
|
-
export { capture_resize_baseline as a, is_resizable as c, apply_translate as i, serialize_paint as n, capture_translate_baseline as o, apply_resize as r, compute_resize_factors as s, parse_paint as t };
|
|
477
|
+
export { capture_resize_baseline as a, is_resizable as c, apply_translate as i, is_text_input_focused as l, serialize_paint as n, capture_translate_baseline as o, apply_resize as r, compute_resize_factors as s, parse_paint as t };
|
|
@@ -1,5 +1,21 @@
|
|
|
1
|
-
require("./dom-
|
|
1
|
+
require("./dom-BlJZWpR_.js");
|
|
2
2
|
let svg_pathdata = require("svg-pathdata");
|
|
3
|
+
//#region src/util/dom.ts
|
|
4
|
+
/**
|
|
5
|
+
* `true` when the document's active element is a text-input-like control
|
|
6
|
+
* (input / textarea / contentEditable). Used by keymap + gesture defaults
|
|
7
|
+
* to avoid hijacking keystrokes while the user is typing.
|
|
8
|
+
*/
|
|
9
|
+
function is_text_input_focused() {
|
|
10
|
+
if (typeof document === "undefined") return false;
|
|
11
|
+
const el = document.activeElement;
|
|
12
|
+
if (!el) return false;
|
|
13
|
+
const tag = el.tagName;
|
|
14
|
+
if (tag === "INPUT" || tag === "TEXTAREA") return true;
|
|
15
|
+
if (el.isContentEditable) return true;
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
3
19
|
//#region src/core/intents.ts
|
|
4
20
|
function num(doc, id, name, fallback = 0) {
|
|
5
21
|
const v = doc.get_attr(id, name);
|
|
@@ -495,6 +511,12 @@ Object.defineProperty(exports, "is_resizable", {
|
|
|
495
511
|
return is_resizable;
|
|
496
512
|
}
|
|
497
513
|
});
|
|
514
|
+
Object.defineProperty(exports, "is_text_input_focused", {
|
|
515
|
+
enumerable: true,
|
|
516
|
+
get: function() {
|
|
517
|
+
return is_text_input_focused;
|
|
518
|
+
}
|
|
519
|
+
});
|
|
498
520
|
Object.defineProperty(exports, "parse_paint", {
|
|
499
521
|
enumerable: true,
|
|
500
522
|
get: function() {
|
package/dist/react.d.mts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { S as EditorStyle, o as SvgEditor, t as Commands, x as EditorState, z as Providers } from "./editor-DSADZszj.mjs";
|
|
2
|
+
import { DomSurfaceHandle } from "./dom.mjs";
|
|
3
|
+
import cmath from "@grida/cmath";
|
|
2
4
|
import { ReactNode } from "react";
|
|
3
5
|
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
4
6
|
|
|
@@ -22,17 +24,40 @@ declare function SvgEditorProvider({
|
|
|
22
24
|
type SvgEditorCanvasProps = {
|
|
23
25
|
className?: string;
|
|
24
26
|
style?: React.CSSProperties;
|
|
27
|
+
/**
|
|
28
|
+
* Install the default gesture set. Default `true`. See
|
|
29
|
+
* `DomSurfaceOptions.gestures`.
|
|
30
|
+
*/
|
|
31
|
+
gestures?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Auto-fit the document on initial attach. Default `false`. See
|
|
34
|
+
* `DomSurfaceOptions.fit`.
|
|
35
|
+
*/
|
|
36
|
+
fit?: boolean; /** Initial camera transform. Default identity. */
|
|
37
|
+
initial_camera?: cmath.Transform;
|
|
38
|
+
/**
|
|
39
|
+
* Receives the `DomSurfaceHandle` once the surface is attached, and
|
|
40
|
+
* `null` on unmount/detach. Use this to thread `handle.camera` /
|
|
41
|
+
* `handle.gestures` into surrounding chrome (toolbars, badges, etc.).
|
|
42
|
+
*/
|
|
43
|
+
onAttach?: (handle: DomSurfaceHandle | null) => void;
|
|
25
44
|
};
|
|
26
45
|
/**
|
|
27
46
|
* Renders the editor's SVG into a `div` and wires it to the DOM surface.
|
|
28
47
|
*
|
|
29
|
-
* Internally calls `attach_dom_surface(editor, { container })` on
|
|
30
|
-
* `handle.detach()` on unmount.
|
|
31
|
-
*
|
|
48
|
+
* Internally calls `attach_dom_surface(editor, { container, ... })` on
|
|
49
|
+
* mount and `handle.detach()` on unmount. Surface-scoped concerns (camera,
|
|
50
|
+
* gestures) are reached via the `onAttach` callback — there is no global
|
|
51
|
+
* context for them, because a host may mount multiple canvases in the
|
|
52
|
+
* same editor session.
|
|
32
53
|
*/
|
|
33
54
|
declare function SvgEditorCanvas({
|
|
34
55
|
className,
|
|
35
|
-
style
|
|
56
|
+
style,
|
|
57
|
+
gestures,
|
|
58
|
+
fit,
|
|
59
|
+
initial_camera,
|
|
60
|
+
onAttach
|
|
36
61
|
}: SvgEditorCanvasProps): _$react_jsx_runtime0.JSX.Element;
|
|
37
62
|
declare function useSvgEditor(): SvgEditor;
|
|
38
63
|
/**
|
|
@@ -45,5 +70,23 @@ declare function useEditorState<T>(selector: (state: EditorState) => T, equals?:
|
|
|
45
70
|
* re-renders (commands themselves don't change identity).
|
|
46
71
|
*/
|
|
47
72
|
declare function useCommands(): Commands;
|
|
73
|
+
/**
|
|
74
|
+
* Subscribe to a slice of `handle.camera` from a `DomSurfaceHandle`. Pass
|
|
75
|
+
* the handle (or null if it isn't attached yet) and a selector that reads
|
|
76
|
+
* what you need from the camera. The returned value updates on every
|
|
77
|
+
* camera mutation — does NOT bump `editor.state.version`.
|
|
78
|
+
*
|
|
79
|
+
* Typical use: zoom badge in a toolbar.
|
|
80
|
+
*
|
|
81
|
+
* ```tsx
|
|
82
|
+
* const zoom = useCameraSnapshot(handle, (c) => c.zoom, 1);
|
|
83
|
+
* return <div>{Math.round(zoom * 100)}%</div>;
|
|
84
|
+
* ```
|
|
85
|
+
*
|
|
86
|
+
* The `fallback` is what's returned when `handle` is `null` (before mount /
|
|
87
|
+
* after detach). It's also the SSR snapshot value — anything that won't
|
|
88
|
+
* mismatch with the first client render.
|
|
89
|
+
*/
|
|
90
|
+
declare function useCameraSnapshot<T>(handle: DomSurfaceHandle | null, selector: (camera: DomSurfaceHandle["camera"]) => T, fallback: T): T;
|
|
48
91
|
//#endregion
|
|
49
|
-
export { SvgEditorCanvas, SvgEditorCanvasProps, SvgEditorProvider, SvgEditorProviderProps, useCommands, useEditorState, useSvgEditor };
|
|
92
|
+
export { SvgEditorCanvas, SvgEditorCanvasProps, SvgEditorProvider, SvgEditorProviderProps, useCameraSnapshot, useCommands, useEditorState, useSvgEditor };
|