@grida/svg-editor 1.0.0-alpha.3 → 1.0.0-alpha.5

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.
@@ -158,6 +158,17 @@ type EditorState = {
158
158
  * `structure_version` so a drag doesn't invalidate the tree view.
159
159
  */
160
160
  readonly structure_version: number;
161
+ /**
162
+ * Bumps once per `editor.load(svg)` call. Distinct from
163
+ * `structure_version` (which bumps on edits too). Starts at 0; the
164
+ * constructor's initial SVG does NOT count as a load. Use this when
165
+ * you want to react to "a new document was loaded" — e.g. refit
166
+ * camera to the new root, reset host-side UI state, clear per-file
167
+ * scratch — without firing on text edits, reorders, or deletes.
168
+ *
169
+ * Monotonic, never resets.
170
+ */
171
+ readonly load_version: number;
161
172
  };
162
173
  type Unsubscribe = () => void;
163
174
  type ReorderDirection = "bring_forward" | "send_backward" | "bring_to_front" | "send_to_back";
@@ -186,6 +197,22 @@ type CameraOptions = {
186
197
  resolve_bounds: BoundsResolver;
187
198
  initial?: cmath.Transform;
188
199
  };
200
+ /**
201
+ * Camera viewport constraint. Discriminated union with `type` so future
202
+ * variants (`'contain'`, `'pan-region'`) can be added without breaking
203
+ * existing call sites — each future variant has its own payload shape.
204
+ *
205
+ * v1.1 ships only `'cover'`. CSS analogy: `object-fit: cover` — the
206
+ * bounds rect covers the viewport edge-to-edge. Zoom is lower-bounded
207
+ * at fit-with-padding; pan is clamped so the bounds always covers the
208
+ * viewport. Use for slide / page / kiosk UX where the user should
209
+ * never see past the artwork.
210
+ */
211
+ type CameraConstraints = {
212
+ /** Bounds cover viewport (viewport ⊆ bounds). Keynote / slide UX. */type: "cover"; /** World-space rect, or `"<root>"` to resolve via BoundsResolver. */
213
+ bounds: Rect | "<root>"; /** Screen-pixel breathing room between bounds and viewport edge. */
214
+ padding?: number;
215
+ };
189
216
  /**
190
217
  * Surface-scoped pan/zoom state.
191
218
  *
@@ -199,7 +226,19 @@ declare class Camera {
199
226
  private viewport_h;
200
227
  private listeners;
201
228
  private resolve_bounds;
229
+ private _constraints;
202
230
  constructor(opts: CameraOptions);
231
+ /**
232
+ * Current viewport constraint, or `null` for free pan/zoom. Set with
233
+ * `camera.constraints = { type: 'cover', bounds: '<root>', padding: 80 }`
234
+ * to clamp zoom + pan; assign `null` to clear.
235
+ *
236
+ * Constraints are applied synchronously inside `set_transform` (and
237
+ * `_set_viewport_size`), so every public mutation respects them
238
+ * automatically — the host never needs to subscribe-and-clamp itself.
239
+ */
240
+ get constraints(): CameraConstraints | null;
241
+ set constraints(c: CameraConstraints | null);
203
242
  /** Underlying 2D affine. World→screen. */
204
243
  get transform(): cmath.Transform;
205
244
  /** Uniform scale factor. 1 = 100 %. */
@@ -227,6 +266,10 @@ declare class Camera {
227
266
  * makes external constraint loops (e.g. "subscribe → compute clamped →
228
267
  * set_transform") terminate: the clamp re-emits the same transform on
229
268
  * the second pass, set_transform short-circuits, no recursion.
269
+ *
270
+ * When `camera.constraints` is non-null, the input transform is clamped
271
+ * synchronously before being stored — every public mutation respects the
272
+ * constraint automatically.
230
273
  */
231
274
  set_transform(t: cmath.Transform): void;
232
275
  /** Viewport size in screen pixels. Read by host code computing constraints. */
@@ -262,114 +305,20 @@ declare class Camera {
262
305
  screen_to_world(p: Vec2): Vec2;
263
306
  /** Convert a world-space point to screen-space. */
264
307
  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
308
  /**
301
- * Register a command. Returns an unregister function. Re-registering
302
- * the same id replaces the previous handler (last writer wins).
309
+ * Apply the current constraint (if any) to a candidate transform.
310
+ * Pure: returns the clamped result, never mutates state. Returns the
311
+ * input unchanged when constraints are null / bounds are unresolvable /
312
+ * viewport is 0.
303
313
  */
304
- register(id: CommandId, handler: CommandHandler): () => void;
314
+ private apply_constraints;
305
315
  /**
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`).
316
+ * Re-clamp the stored transform against the current constraint. Called
317
+ * from the `constraints` setter; `_set_viewport_size` has its own
318
+ * notify-inclusive path.
309
319
  */
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;
320
+ private reenforce;
321
+ private notify;
373
322
  }
374
323
  //#endregion
375
324
  //#region src/core/parser.d.ts
@@ -501,6 +450,19 @@ declare class SvgDocument implements DocumentEvents {
501
450
  property: string;
502
451
  value: string;
503
452
  }>;
453
+ /**
454
+ * Whether `id` can be opened in the flat-string text editor.
455
+ *
456
+ * v1 contract: the editor only operates on a *single flat text run*. That
457
+ * means the target must be a `<text>` or `<tspan>` whose direct children
458
+ * are all text nodes (or it has no children). A `<text>` containing a
459
+ * `<tspan>` is *not* honestly editable — `text_of` would drop the tspan
460
+ * content from the editor's view, and a flat-text write would leave the
461
+ * tspan dangling. Tspan-as-target is fine and well-defined when it's a
462
+ * leaf; only the host decides whether to route double-click to a tspan
463
+ * or its parent text.
464
+ */
465
+ is_text_edit_target(id: NodeId): boolean;
504
466
  text_of(id: NodeId): string;
505
467
  /** Replace all direct text children with a single text node carrying `value`. */
506
468
  set_text(id: NodeId, value: string): void;
@@ -530,6 +492,113 @@ type Defs = {
530
492
  gradients: GradientsApi;
531
493
  };
532
494
  //#endregion
495
+ //#region src/commands/registry.d.ts
496
+ /**
497
+ * Command registry.
498
+ *
499
+ * A passive id-keyed registry of handlers. Built so that:
500
+ *
501
+ * - keybindings (in `src/keymap`) can address commands by stable id;
502
+ * - new commands can be added in ONE place (`src/commands/defaults.ts`)
503
+ * without growing the public surface of the editor;
504
+ * - "one key, many meanings" can be expressed via chain semantics: a
505
+ * handler returns `true` if it consumed, `false`/`void` otherwise,
506
+ * and the dispatcher tries the next candidate in the chain.
507
+ *
508
+ * Handlers are plain closures — they capture whatever editor reference
509
+ * they need. The registry itself stays unaware of the editor's type,
510
+ * which avoids a circular type dependency between editor and registry.
511
+ */
512
+ /** Stable, dotted id for a command, e.g. `"history.undo"`. */
513
+ type CommandId = string;
514
+ /**
515
+ * A command handler.
516
+ *
517
+ * Return `true` if the handler consumed the invocation. Return `false`
518
+ * or `undefined` to signal "did not apply" — the dispatcher will try
519
+ * the next candidate registered for the same key.
520
+ *
521
+ * Handlers are closures: they capture their editor reference. No
522
+ * editor parameter is passed — keep handlers self-contained.
523
+ */
524
+ type CommandHandler = (args?: unknown) => boolean | void;
525
+ declare class CommandRegistry {
526
+ private readonly map;
527
+ /**
528
+ * Register a command. Returns an unregister function. Re-registering
529
+ * the same id replaces the previous handler (last writer wins).
530
+ */
531
+ register(id: CommandId, handler: CommandHandler): () => void;
532
+ /**
533
+ * Invoke a command by id. Returns `true` if the handler consumed,
534
+ * `false` otherwise (including unknown ids and handlers that returned
535
+ * `false`/`undefined`).
536
+ */
537
+ invoke(id: CommandId, args?: unknown): boolean;
538
+ has(id: CommandId): boolean;
539
+ /** All registered ids, for debugging / introspection. */
540
+ ids(): readonly CommandId[];
541
+ }
542
+ //#endregion
543
+ //#region src/keymap/keymap.d.ts
544
+ type KeymapBinding = {
545
+ /** Declarative key combination. Build with `kb()` / `c()` / `seq()`. */keybinding: Keybinding; /** Command id to invoke on match. */
546
+ command: CommandId; /** Forwarded as the `args` parameter to the command handler. */
547
+ args?: unknown; /** Higher priorities run first in the chain. Default 0. */
548
+ priority?: number;
549
+ /**
550
+ * Reserved for V2; not honored by the V1 dispatcher. When added, this
551
+ * will be evaluated before the handler runs; if false, the binding is
552
+ * skipped without invoking the handler.
553
+ */
554
+ when?: (ctx: unknown) => boolean;
555
+ };
556
+ declare class Keymap {
557
+ private readonly commands;
558
+ private readonly platformGetter;
559
+ /**
560
+ * Bindings bucketed by canonical chunk-key hash, computed per
561
+ * `@grida/keybinding`'s `chunkKey`. Each list is the chain for that
562
+ * key, sorted in dispatch order (priority desc, then registration
563
+ * order).
564
+ */
565
+ private readonly buckets;
566
+ /** Insert order, so ties on priority are deterministic. */
567
+ private seq;
568
+ constructor(commands: CommandRegistry, platformGetter?: () => Platform);
569
+ /**
570
+ * Bind a key combination to a command. Returns an unbind function.
571
+ * The same `Keybinding` can be bound to multiple commands — they will
572
+ * all be tried in chain order on dispatch.
573
+ */
574
+ bind(binding: KeymapBinding): () => void;
575
+ /**
576
+ * Remove bindings matching the spec. If both filters are passed, only
577
+ * bindings that match BOTH are removed.
578
+ */
579
+ unbind(spec: {
580
+ keybinding?: Keybinding;
581
+ command?: CommandId;
582
+ }): void;
583
+ /** All registered bindings, for introspection. Order is not guaranteed. */
584
+ bindings(): readonly KeymapBinding[];
585
+ /**
586
+ * Match the event against bound chunks, then run candidates in chain
587
+ * order. Returns `true` and calls `preventDefault()` on the first
588
+ * handler that consumes; returns `false` if nothing matched or all
589
+ * matches fell through.
590
+ */
591
+ dispatch(event: KeyboardEvent): boolean;
592
+ /**
593
+ * Compute the set of canonical hashes a `Keybinding` lights up. A
594
+ * binding with aliases (multiple sequences) contributes one hash per
595
+ * single-chunk alias; multi-chunk sequences (chords) are skipped in
596
+ * V1.
597
+ */
598
+ private chunkKeysFor;
599
+ private has_safe_mod;
600
+ }
601
+ //#endregion
533
602
  //#region src/core/properties.d.ts
534
603
  declare function read_property(doc: SvgDocument, id: NodeId, property: string): PropertyValue;
535
604
  //#endregion
@@ -619,9 +688,18 @@ type Surface = {
619
688
  type SurfaceHandle = {
620
689
  detach(): void;
621
690
  };
691
+ /**
692
+ * Mode for `commands.select`. Matches the HUD's `SelectMode` vocabulary so
693
+ * intents can be threaded through without lossy collapsing.
694
+ *
695
+ * - `"replace"` (default) — set selection to `ids`, discarding the previous set.
696
+ * - `"add"` — union: each id in `ids` is added; existing members stay.
697
+ * - `"toggle"` — flip each id's membership (present → removed; absent → added).
698
+ */
699
+ type SelectMode = "replace" | "add" | "toggle";
622
700
  type Commands = {
623
701
  select(target: NodeId | ReadonlyArray<NodeId>, opts?: {
624
- additive?: boolean;
702
+ mode?: SelectMode;
625
703
  }): void;
626
704
  deselect(): void;
627
705
  enter_scope(group: NodeId): void;
@@ -759,4 +837,4 @@ declare function createSvgEditor(opts: CreateSvgEditorOptions): {
759
837
  keymap: Keymap;
760
838
  };
761
839
  //#endregion
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 };
840
+ export { InvalidComputedValue as A, Provenance as B, EditorState as C, GradientDefinition as D, FontResolver as E, PaintFallback as F, Unsubscribe as G, RadialGradientDefinition as H, PaintPreviewSession as I, Vec2 as K, PaintValue as L, Mode as M, NodeId as N, GradientEntry as O, Paint as P, PreviewSession as R, DEFAULT_STYLE as S, FileIOProvider as T, Rect as U, Providers as V, ReorderDirection as W, Camera as _, SelectMode as a, ClipboardProvider as b, createSvgEditor as c, GestureId as d, Gestures as f, BoundsResolver as g, CommandId as h, DomComputedResolver as i, LinearGradientDefinition as j, GradientStop as k, GestureBinding as l, CommandHandler as m, CreateSvgEditorOptions as n, SurfaceHandle as o, KeymapBinding as p, DomComputedPaint as r, SvgEditor as s, Commands as t, GestureContext as u, CameraConstraints as v, EditorStyle as w, Color as x, CameraOptions as y, PropertyValue as z };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1 @@
1
+ export { };
package/dist/index.d.mts CHANGED
@@ -1,2 +1,2 @@
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 };
1
+ import { A as InvalidComputedValue, B as Provenance, C as EditorState, D as GradientDefinition, E as FontResolver, F as PaintFallback, G as Unsubscribe, H as RadialGradientDefinition, I as PaintPreviewSession, K as Vec2, L as PaintValue, M as Mode, N as NodeId, O as GradientEntry, P as Paint, R as PreviewSession, S as DEFAULT_STYLE, T as FileIOProvider, U as Rect, V as Providers, W as ReorderDirection, _ as Camera, a as SelectMode, b as ClipboardProvider, c as createSvgEditor, d as GestureId, f as Gestures, g as BoundsResolver, h as CommandId, i as DomComputedResolver, j as LinearGradientDefinition, k as GradientStop, l as GestureBinding, m as CommandHandler, n as CreateSvgEditorOptions, o as SurfaceHandle, p as KeymapBinding, r as DomComputedPaint, s as SvgEditor, t as Commands, u as GestureContext, v as CameraConstraints, w as EditorStyle, x as Color, y as CameraOptions, z as PropertyValue } from "./editor-KRAmUodY.mjs";
2
+ export { BoundsResolver, Camera, CameraConstraints, CameraOptions, ClipboardProvider, Color, CommandHandler, CommandId, Commands, CreateSvgEditorOptions, DEFAULT_STYLE, DomComputedPaint, DomComputedResolver, EditorState, EditorStyle, FileIOProvider, FontResolver, GestureBinding, GestureContext, GestureId, Gestures, GradientDefinition, GradientEntry, GradientStop, InvalidComputedValue, KeymapBinding, LinearGradientDefinition, Mode, NodeId, Paint, PaintFallback, PaintPreviewSession, PaintValue, PreviewSession, PropertyValue, Provenance, Providers, RadialGradientDefinition, Rect, ReorderDirection, SelectMode, SurfaceHandle, SvgEditor, Unsubscribe, Vec2, createSvgEditor };
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
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 };
1
+ import { A as InvalidComputedValue, B as Provenance, C as EditorState, D as GradientDefinition, E as FontResolver, F as PaintFallback, G as Unsubscribe, H as RadialGradientDefinition, I as PaintPreviewSession, K as Vec2, L as PaintValue, M as Mode, N as NodeId, O as GradientEntry, P as Paint, R as PreviewSession, S as DEFAULT_STYLE, T as FileIOProvider, U as Rect, V as Providers, W as ReorderDirection, _ as Camera, a as SelectMode, b as ClipboardProvider, c as createSvgEditor, d as GestureId, f as Gestures, g as BoundsResolver, h as CommandId, i as DomComputedResolver, j as LinearGradientDefinition, k as GradientStop, l as GestureBinding, m as CommandHandler, n as CreateSvgEditorOptions, o as SurfaceHandle, p as KeymapBinding, r as DomComputedPaint, s as SvgEditor, t as Commands, u as GestureContext, v as CameraConstraints, w as EditorStyle, x as Color, y as CameraOptions, z as PropertyValue } from "./editor-DdgqLDC9.js";
2
+ export { BoundsResolver, Camera, CameraConstraints, CameraOptions, ClipboardProvider, Color, CommandHandler, CommandId, Commands, CreateSvgEditorOptions, DEFAULT_STYLE, DomComputedPaint, DomComputedResolver, EditorState, EditorStyle, FileIOProvider, FontResolver, GestureBinding, GestureContext, GestureId, Gestures, GradientDefinition, GradientEntry, GradientStop, InvalidComputedValue, KeymapBinding, LinearGradientDefinition, Mode, NodeId, Paint, PaintFallback, PaintPreviewSession, PaintValue, PreviewSession, PropertyValue, Provenance, Providers, RadialGradientDefinition, Rect, ReorderDirection, SelectMode, SurfaceHandle, SvgEditor, Unsubscribe, 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-Eon0043Z.js");
2
+ const require_editor = require("./editor-Ds47eN37.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-DP36h-SE.mjs";
1
+ import { n as DEFAULT_STYLE, t as createSvgEditor } from "./editor-CRflVqEz.mjs";
2
2
  export { DEFAULT_STYLE, createSvgEditor };
@@ -1,4 +1,4 @@
1
- require("./dom-BlJZWpR_.js");
1
+ require("./dom-DyJy1H6Q.js");
2
2
  let svg_pathdata = require("svg-pathdata");
3
3
  //#region src/util/dom.ts
4
4
  /**
@@ -0,0 +1,46 @@
1
+ import { s as SvgEditor } from "./editor-KRAmUodY.mjs";
2
+ import { n as DomSurfaceOptions, t as DomSurfaceHandle } from "./dom-CMXNUMjP.mjs";
3
+ declare namespace keynote_d_exports {
4
+ export { KeynoteAttachOptions, KeynoteSurfaceHandle, attach };
5
+ }
6
+ type KeynoteAttachOptions = {
7
+ /** Container to mount the SVG into. */container: HTMLElement;
8
+ /**
9
+ * Screen-pixel breathing room between the slide and the viewport edge.
10
+ * Used for both initial fit and the cover-constraint clamp. Default 80.
11
+ */
12
+ padding?: number;
13
+ /**
14
+ * Forward additional surface options (e.g. `gestures: false`). `container`,
15
+ * `fit`, and `initial_camera` are owned by the preset.
16
+ */
17
+ surface?: Omit<DomSurfaceOptions, "container" | "fit" | "initial_camera">;
18
+ };
19
+ /**
20
+ * Surface handle returned by `keynote.attach`. Extends `DomSurfaceHandle`
21
+ * with `set_padding` so hosts can vary the slide breathing room at runtime
22
+ * (e.g. on a "present mode" toggle that wants margin: 0 vs the default 80).
23
+ */
24
+ type KeynoteSurfaceHandle = DomSurfaceHandle & {
25
+ /**
26
+ * Update the slide padding and re-fit. Mutates the live constraint AND
27
+ * the captured padding used by load-triggered refits.
28
+ */
29
+ set_padding(p: number): void;
30
+ };
31
+ /**
32
+ * Attach a keynote-shaped DOM surface:
33
+ * - Mounts via `attach_dom_surface` with `fit: true` (slide is visible on
34
+ * first frame).
35
+ * - Installs a `'cover'` camera constraint bound to the document root, so
36
+ * the user can't zoom out past the slide or pan past its edges.
37
+ * - Subscribes to `editor.state.load_version` so every `editor.load(svg)`
38
+ * re-fits the camera to the new document.
39
+ *
40
+ * Returns a `KeynoteSurfaceHandle` — same shape as `DomSurfaceHandle` plus
41
+ * `set_padding` for present-mode toggles. The returned `detach()`
42
+ * additionally tears down the load subscription.
43
+ */
44
+ declare function attach(editor: SvgEditor, opts: KeynoteAttachOptions): KeynoteSurfaceHandle;
45
+ //#endregion
46
+ export { type KeynoteAttachOptions, type KeynoteSurfaceHandle, keynote_d_exports as keynote };
@@ -0,0 +1,46 @@
1
+ import { s as SvgEditor } from "./editor-DdgqLDC9.js";
2
+ import { n as DomSurfaceOptions, t as DomSurfaceHandle } from "./dom-eIgcZ4JC.js";
3
+ declare namespace keynote_d_exports {
4
+ export { KeynoteAttachOptions, KeynoteSurfaceHandle, attach };
5
+ }
6
+ type KeynoteAttachOptions = {
7
+ /** Container to mount the SVG into. */container: HTMLElement;
8
+ /**
9
+ * Screen-pixel breathing room between the slide and the viewport edge.
10
+ * Used for both initial fit and the cover-constraint clamp. Default 80.
11
+ */
12
+ padding?: number;
13
+ /**
14
+ * Forward additional surface options (e.g. `gestures: false`). `container`,
15
+ * `fit`, and `initial_camera` are owned by the preset.
16
+ */
17
+ surface?: Omit<DomSurfaceOptions, "container" | "fit" | "initial_camera">;
18
+ };
19
+ /**
20
+ * Surface handle returned by `keynote.attach`. Extends `DomSurfaceHandle`
21
+ * with `set_padding` so hosts can vary the slide breathing room at runtime
22
+ * (e.g. on a "present mode" toggle that wants margin: 0 vs the default 80).
23
+ */
24
+ type KeynoteSurfaceHandle = DomSurfaceHandle & {
25
+ /**
26
+ * Update the slide padding and re-fit. Mutates the live constraint AND
27
+ * the captured padding used by load-triggered refits.
28
+ */
29
+ set_padding(p: number): void;
30
+ };
31
+ /**
32
+ * Attach a keynote-shaped DOM surface:
33
+ * - Mounts via `attach_dom_surface` with `fit: true` (slide is visible on
34
+ * first frame).
35
+ * - Installs a `'cover'` camera constraint bound to the document root, so
36
+ * the user can't zoom out past the slide or pan past its edges.
37
+ * - Subscribes to `editor.state.load_version` so every `editor.load(svg)`
38
+ * re-fits the camera to the new document.
39
+ *
40
+ * Returns a `KeynoteSurfaceHandle` — same shape as `DomSurfaceHandle` plus
41
+ * `set_padding` for present-mode toggles. The returned `detach()`
42
+ * additionally tears down the load subscription.
43
+ */
44
+ declare function attach(editor: SvgEditor, opts: KeynoteAttachOptions): KeynoteSurfaceHandle;
45
+ //#endregion
46
+ export { type KeynoteAttachOptions, type KeynoteSurfaceHandle, keynote_d_exports as keynote };
@@ -0,0 +1,52 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_dom = require("./dom-DyJy1H6Q.js");
3
+ //#region src/presets/keynote.ts
4
+ var keynote_exports = /* @__PURE__ */ require_dom.__exportAll({ attach: () => attach });
5
+ /**
6
+ * Attach a keynote-shaped DOM surface:
7
+ * - Mounts via `attach_dom_surface` with `fit: true` (slide is visible on
8
+ * first frame).
9
+ * - Installs a `'cover'` camera constraint bound to the document root, so
10
+ * the user can't zoom out past the slide or pan past its edges.
11
+ * - Subscribes to `editor.state.load_version` so every `editor.load(svg)`
12
+ * re-fits the camera to the new document.
13
+ *
14
+ * Returns a `KeynoteSurfaceHandle` — same shape as `DomSurfaceHandle` plus
15
+ * `set_padding` for present-mode toggles. The returned `detach()`
16
+ * additionally tears down the load subscription.
17
+ */
18
+ function attach(editor, opts) {
19
+ const inner = require_dom.attach_dom_surface(editor, {
20
+ ...opts.surface,
21
+ container: opts.container,
22
+ fit: true
23
+ });
24
+ const apply = (p) => {
25
+ inner.camera.constraints = {
26
+ type: "cover",
27
+ bounds: "<root>",
28
+ padding: p
29
+ };
30
+ };
31
+ apply(opts.padding ?? 80);
32
+ const unsub_load = editor.subscribe_with_selector((s) => s.load_version, () => inner.camera.fit("<root>", { margin: inner.camera.constraints?.padding ?? 0 }));
33
+ return {
34
+ camera: inner.camera,
35
+ gestures: inner.gestures,
36
+ set_padding(p) {
37
+ apply(p);
38
+ inner.camera.fit("<root>", { margin: p });
39
+ },
40
+ detach: () => {
41
+ unsub_load();
42
+ inner.detach();
43
+ }
44
+ };
45
+ }
46
+ //#endregion
47
+ Object.defineProperty(exports, "keynote", {
48
+ enumerable: true,
49
+ get: function() {
50
+ return keynote_exports;
51
+ }
52
+ });
@@ -0,0 +1,47 @@
1
+ import { t as __exportAll } from "./chunk-CfYAbeIz.mjs";
2
+ import { t as attach_dom_surface } from "./dom-l5Y1Wf8C.mjs";
3
+ //#region src/presets/keynote.ts
4
+ var keynote_exports = /* @__PURE__ */ __exportAll({ attach: () => attach });
5
+ /**
6
+ * Attach a keynote-shaped DOM surface:
7
+ * - Mounts via `attach_dom_surface` with `fit: true` (slide is visible on
8
+ * first frame).
9
+ * - Installs a `'cover'` camera constraint bound to the document root, so
10
+ * the user can't zoom out past the slide or pan past its edges.
11
+ * - Subscribes to `editor.state.load_version` so every `editor.load(svg)`
12
+ * re-fits the camera to the new document.
13
+ *
14
+ * Returns a `KeynoteSurfaceHandle` — same shape as `DomSurfaceHandle` plus
15
+ * `set_padding` for present-mode toggles. The returned `detach()`
16
+ * additionally tears down the load subscription.
17
+ */
18
+ function attach(editor, opts) {
19
+ const inner = attach_dom_surface(editor, {
20
+ ...opts.surface,
21
+ container: opts.container,
22
+ fit: true
23
+ });
24
+ const apply = (p) => {
25
+ inner.camera.constraints = {
26
+ type: "cover",
27
+ bounds: "<root>",
28
+ padding: p
29
+ };
30
+ };
31
+ apply(opts.padding ?? 80);
32
+ const unsub_load = editor.subscribe_with_selector((s) => s.load_version, () => inner.camera.fit("<root>", { margin: inner.camera.constraints?.padding ?? 0 }));
33
+ return {
34
+ camera: inner.camera,
35
+ gestures: inner.gestures,
36
+ set_padding(p) {
37
+ apply(p);
38
+ inner.camera.fit("<root>", { margin: p });
39
+ },
40
+ detach: () => {
41
+ unsub_load();
42
+ inner.detach();
43
+ }
44
+ };
45
+ }
46
+ //#endregion
47
+ export { keynote_exports as keynote };
package/dist/react.d.mts CHANGED
@@ -1,5 +1,5 @@
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";
1
+ import { C as EditorState, V as Providers, s as SvgEditor, t as Commands, w as EditorStyle } from "./editor-KRAmUodY.mjs";
2
+ import { t as DomSurfaceHandle } from "./dom-CMXNUMjP.mjs";
3
3
  import cmath from "@grida/cmath";
4
4
  import { ReactNode } from "react";
5
5
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
package/dist/react.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as EditorStyle, o as SvgEditor, t as Commands, x as EditorState, z as Providers } from "./editor-Da446SPO.js";
2
- import { DomSurfaceHandle } from "./dom.js";
1
+ import { C as EditorState, V as Providers, s as SvgEditor, t as Commands, w as EditorStyle } from "./editor-DdgqLDC9.js";
2
+ import { t as DomSurfaceHandle } from "./dom-eIgcZ4JC.js";
3
3
  import cmath from "@grida/cmath";
4
4
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
5
5
  import { ReactNode } from "react";
package/dist/react.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const require_dom = require("./dom-BlJZWpR_.js");
4
- const require_editor = require("./editor-Eon0043Z.js");
3
+ const require_dom = require("./dom-DyJy1H6Q.js");
4
+ const require_editor = require("./editor-Ds47eN37.js");
5
5
  let react = require("react");
6
6
  let react_jsx_runtime = require("react/jsx-runtime");
7
7
  //#region src/react.tsx
package/dist/react.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { t as createSvgEditor } from "./editor-DP36h-SE.mjs";
3
- import { t as attach_dom_surface } from "./dom-D-5D_3o0.mjs";
2
+ import { t as createSvgEditor } from "./editor-CRflVqEz.mjs";
3
+ import { t as attach_dom_surface } from "./dom-l5Y1Wf8C.mjs";
4
4
  import { createContext, useContext, useEffect, useMemo, useRef, useSyncExternalStore } from "react";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  //#region src/react.tsx