@grida/svg-editor 1.0.0-alpha.17 → 1.0.0-alpha.18

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.
@@ -1,4 +1,4 @@
1
- const require_model = require("./model-GpysNbOv.js");
1
+ const require_model = require("./model-BLhMJZKJ.js");
2
2
  let _grida_cmath = require("@grida/cmath");
3
3
  _grida_cmath = require_model.__toESM(_grida_cmath);
4
4
  let _grida_svg_parse = require("@grida/svg/parse");
@@ -1,4 +1,4 @@
1
- import { S as is_text_input_focused, a as paint, c as hit_shape_svg, d as NudgeDwellWatcher, f as TranslateOrchestrator, h as transform, i as TOOL_CURSOR, l as RotateOrchestrator, m as group, n as insertions, o as ResizeOrchestrator, s as resize_pipeline, t as PathModel, x as array_shallow_equal } from "./model-DMaN5GnH.mjs";
1
+ import { S as is_text_input_focused, a as paint, c as hit_shape_svg, d as NudgeDwellWatcher, f as TranslateOrchestrator, h as transform, i as TOOL_CURSOR, l as RotateOrchestrator, m as group, n as insertions, o as ResizeOrchestrator, s as resize_pipeline, t as PathModel, x as array_shallow_equal } from "./model-DU0GOMwM.mjs";
2
2
  import cmath from "@grida/cmath";
3
3
  import { svg_parse } from "@grida/svg/parse";
4
4
  import { SVGShapes } from "@grida/svg/pathdata";
package/dist/dom.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_dom = require("./dom-CaByuo6C.js");
2
+ const require_dom = require("./dom-DKQ4Vt3z.js");
3
3
  exports.Camera = require_dom.Camera;
4
4
  exports.DEFAULT_SNAP_OPTIONS = require_dom.DEFAULT_SNAP_OPTIONS;
5
5
  exports.Gestures = require_dom.Gestures;
package/dist/dom.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { a as project_point_through_ctm, c as MemoizedGeometryProvider, i as project_delta_inverse_ctm, l as Camera, n as install_font_load_geometry_bump, o as Gestures, r as inverse_project_rect, s as DEFAULT_SNAP_OPTIONS, t as attach_dom_surface } from "./dom-Bjj9xySE.mjs";
1
+ import { a as project_point_through_ctm, c as MemoizedGeometryProvider, i as project_delta_inverse_ctm, l as Camera, n as install_font_load_geometry_bump, o as Gestures, r as inverse_project_rect, s as DEFAULT_SNAP_OPTIONS, t as attach_dom_surface } from "./dom-OP-kmK8k.mjs";
2
2
  export { Camera, DEFAULT_SNAP_OPTIONS, Gestures, MemoizedGeometryProvider, attach_dom_surface, install_font_load_geometry_bump, inverse_project_rect, project_delta_inverse_ctm, project_point_through_ctm };
@@ -1,4 +1,4 @@
1
- const require_model = require("./model-GpysNbOv.js");
1
+ const require_model = require("./model-BLhMJZKJ.js");
2
2
  let _grida_history = require("@grida/history");
3
3
  let _grida_keybinding = require("@grida/keybinding");
4
4
  let _grida_cmath = require("@grida/cmath");
@@ -1681,7 +1681,6 @@ function _create_svg_editor_internal(opts) {
1681
1681
  members.push({
1682
1682
  id,
1683
1683
  rz: require_model.resize_pipeline.intent.capture_baseline(doc, id, bbox),
1684
- transform_pre: doc.get_attr(id, "transform"),
1685
1684
  bbox
1686
1685
  });
1687
1686
  }
@@ -1716,10 +1715,7 @@ function _create_svg_editor_internal(opts) {
1716
1715
  emit();
1717
1716
  };
1718
1717
  const revert = () => {
1719
- for (const { m, origin } of ops) {
1720
- require_model.resize_pipeline.intent.apply(doc, m.id, m.rz, 1, 1, origin);
1721
- doc.set_attr(m.id, "transform", m.transform_pre);
1722
- }
1718
+ for (const { m } of ops) require_model.resize_pipeline.intent.restore(doc, m.id, m.rz);
1723
1719
  emit();
1724
1720
  };
1725
1721
  apply();
@@ -1,4 +1,4 @@
1
- import { S as is_text_input_focused, _ as SVG_NS, a as paint, b as XMLNS_NS, g as subtree, h as transform, i as TOOL_CURSOR, m as group, n as insertions, p as translate_pipeline, r as DEFAULT_STYLE, s as resize_pipeline, u as rotate_pipeline, v as SvgDocument, x as array_shallow_equal, y as WELL_KNOWN_NS_PREFIXES } from "./model-DMaN5GnH.mjs";
1
+ import { S as is_text_input_focused, _ as SVG_NS, a as paint, b as XMLNS_NS, g as subtree, h as transform, i as TOOL_CURSOR, m as group, n as insertions, p as translate_pipeline, r as DEFAULT_STYLE, s as resize_pipeline, u as rotate_pipeline, v as SvgDocument, x as array_shallow_equal, y as WELL_KNOWN_NS_PREFIXES } from "./model-DU0GOMwM.mjs";
2
2
  import { HistoryImpl } from "@grida/history";
3
3
  import { KeyCode, M, chunkKey, eventToChunk, getKeyboardOS, kb, keybindingsToKeyCodes } from "@grida/keybinding";
4
4
  import cmath from "@grida/cmath";
@@ -1680,7 +1680,6 @@ function _create_svg_editor_internal(opts) {
1680
1680
  members.push({
1681
1681
  id,
1682
1682
  rz: resize_pipeline.intent.capture_baseline(doc, id, bbox),
1683
- transform_pre: doc.get_attr(id, "transform"),
1684
1683
  bbox
1685
1684
  });
1686
1685
  }
@@ -1715,10 +1714,7 @@ function _create_svg_editor_internal(opts) {
1715
1714
  emit();
1716
1715
  };
1717
1716
  const revert = () => {
1718
- for (const { m, origin } of ops) {
1719
- resize_pipeline.intent.apply(doc, m.id, m.rz, 1, 1, origin);
1720
- doc.set_attr(m.id, "transform", m.transform_pre);
1721
- }
1717
+ for (const { m } of ops) resize_pipeline.intent.restore(doc, m.id, m.rz);
1722
1718
  emit();
1723
1719
  };
1724
1720
  apply();
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_model = require("./model-GpysNbOv.js");
3
- const require_editor = require("./editor-N9af0JD2.js");
2
+ const require_model = require("./model-BLhMJZKJ.js");
3
+ const require_editor = require("./editor-Be6UrMeV.js");
4
4
  exports.DEFAULT_STYLE = require_model.DEFAULT_STYLE;
5
5
  exports.PathModel = require_model.PathModel;
6
6
  exports.TOOL_CURSOR = require_model.TOOL_CURSOR;
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { t as createSvgEditor } from "./editor-BLsELHSZ.mjs";
2
- import { i as TOOL_CURSOR, r as DEFAULT_STYLE, t as PathModel } from "./model-DMaN5GnH.mjs";
1
+ import { t as createSvgEditor } from "./editor-BkCbYCz2.mjs";
2
+ import { i as TOOL_CURSOR, r as DEFAULT_STYLE, t as PathModel } from "./model-DU0GOMwM.mjs";
3
3
  export { DEFAULT_STYLE, PathModel, TOOL_CURSOR, createSvgEditor };
@@ -3034,6 +3034,60 @@ function scale_path_d(d, origin, sx, sy) {
3034
3034
  }
3035
3035
  }
3036
3036
  /**
3037
+ * `dispatch_resize`'s write surface as data: the attribute names each
3038
+ * handler may write, by tag. Capture-side snapshots (the resize
3039
+ * pipeline's `baseline.raw`) are built from this list so revert can
3040
+ * restore exactly what a handler may touch — when a handler starts
3041
+ * writing a new attribute, extend this table or undo will silently
3042
+ * miss it. Cross-checked against the live handlers by
3043
+ * `__tests__/resize-snapshot-coverage.test.ts`.
3044
+ */
3045
+ const RESIZE_WRITE_ATTRS = {
3046
+ rect: [
3047
+ "x",
3048
+ "y",
3049
+ "width",
3050
+ "height"
3051
+ ],
3052
+ image: [
3053
+ "x",
3054
+ "y",
3055
+ "width",
3056
+ "height"
3057
+ ],
3058
+ use: [
3059
+ "x",
3060
+ "y",
3061
+ "width",
3062
+ "height"
3063
+ ],
3064
+ circle: [
3065
+ "cx",
3066
+ "cy",
3067
+ "r"
3068
+ ],
3069
+ ellipse: [
3070
+ "cx",
3071
+ "cy",
3072
+ "rx",
3073
+ "ry"
3074
+ ],
3075
+ line: [
3076
+ "x1",
3077
+ "y1",
3078
+ "x2",
3079
+ "y2"
3080
+ ],
3081
+ polyline: ["points"],
3082
+ polygon: ["points"],
3083
+ path: ["d"],
3084
+ text: [
3085
+ "x",
3086
+ "y",
3087
+ "font-size"
3088
+ ]
3089
+ };
3090
+ /**
3037
3091
  * VertexChain × resize — vertex transport in local space.
3038
3092
  * Line carries its own (x1, y1, x2, y2); polyline / polygon share `points`.
3039
3093
  * Result type is preserved.
@@ -3340,6 +3394,15 @@ let resize_pipeline;
3340
3394
  function num(doc, id, name, fallback = 0) {
3341
3395
  return _grida_svg_parse.svg_parse.parse_number(doc.get_attr(id, name), fallback);
3342
3396
  }
3397
+ /** Attribute names a resize gesture may write for `tag`: the
3398
+ * handler write surface (`RESIZE_WRITE_ATTRS`, owned next to the
3399
+ * handlers) plus `transform` — the pipeline's own write
3400
+ * (commit-phase `renormalize_rotate_pivot`). Drives the
3401
+ * `baseline.raw` snapshot that `restore` writes back. */
3402
+ function writable_attrs(tag) {
3403
+ const handler_writes = RESIZE_WRITE_ATTRS[tag];
3404
+ return handler_writes ? [...handler_writes, "transform"] : [];
3405
+ }
3343
3406
  function is_resizable(tag) {
3344
3407
  switch (tag) {
3345
3408
  case "rect":
@@ -3441,12 +3504,21 @@ let resize_pipeline;
3441
3504
  break;
3442
3505
  default: attrs = { kind: "unsupported" };
3443
3506
  }
3507
+ const raw = writable_attrs(tag).map((name) => ({
3508
+ name,
3509
+ value: doc.get_attr(id, name)
3510
+ }));
3444
3511
  return {
3445
3512
  bbox,
3446
- attrs
3513
+ attrs,
3514
+ raw
3447
3515
  };
3448
3516
  }
3449
3517
  _intent.capture_baseline = capture_baseline;
3518
+ function restore(doc, id, baseline) {
3519
+ for (const a of baseline.raw) doc.set_attr(id, a.name, a.value);
3520
+ }
3521
+ _intent.restore = restore;
3450
3522
  function compute_factors(baseline, dir, dx, dy, shift) {
3451
3523
  const b = baseline.bbox;
3452
3524
  let anchorX = 0;
@@ -3849,12 +3921,11 @@ let resize_pipeline;
3849
3921
  }
3850
3922
  _resize_pipeline.apply = apply;
3851
3923
  function revert(doc, plan) {
3852
- const f = intent.compute_factors(plan.baseline, plan.direction, 0, 0, false);
3853
3924
  const members = plan.members ?? [{
3854
3925
  id: plan.id,
3855
3926
  baseline: plan.baseline
3856
3927
  }];
3857
- for (const m of members) intent.apply(doc, m.id, m.baseline, 1, 1, f.origin, "preview");
3928
+ for (const m of members) intent.restore(doc, m.id, m.baseline);
3858
3929
  }
3859
3930
  _resize_pipeline.revert = revert;
3860
3931
  function synthesize_group_baseline(union) {
@@ -3871,7 +3942,8 @@ let resize_pipeline;
3871
3942
  y: union.y,
3872
3943
  w: union.width,
3873
3944
  h: union.height
3874
- }
3945
+ },
3946
+ raw: []
3875
3947
  };
3876
3948
  }
3877
3949
  _resize_pipeline.synthesize_group_baseline = synthesize_group_baseline;
@@ -3001,6 +3001,60 @@ function scale_path_d(d, origin, sx, sy) {
3001
3001
  }
3002
3002
  }
3003
3003
  /**
3004
+ * `dispatch_resize`'s write surface as data: the attribute names each
3005
+ * handler may write, by tag. Capture-side snapshots (the resize
3006
+ * pipeline's `baseline.raw`) are built from this list so revert can
3007
+ * restore exactly what a handler may touch — when a handler starts
3008
+ * writing a new attribute, extend this table or undo will silently
3009
+ * miss it. Cross-checked against the live handlers by
3010
+ * `__tests__/resize-snapshot-coverage.test.ts`.
3011
+ */
3012
+ const RESIZE_WRITE_ATTRS = {
3013
+ rect: [
3014
+ "x",
3015
+ "y",
3016
+ "width",
3017
+ "height"
3018
+ ],
3019
+ image: [
3020
+ "x",
3021
+ "y",
3022
+ "width",
3023
+ "height"
3024
+ ],
3025
+ use: [
3026
+ "x",
3027
+ "y",
3028
+ "width",
3029
+ "height"
3030
+ ],
3031
+ circle: [
3032
+ "cx",
3033
+ "cy",
3034
+ "r"
3035
+ ],
3036
+ ellipse: [
3037
+ "cx",
3038
+ "cy",
3039
+ "rx",
3040
+ "ry"
3041
+ ],
3042
+ line: [
3043
+ "x1",
3044
+ "y1",
3045
+ "x2",
3046
+ "y2"
3047
+ ],
3048
+ polyline: ["points"],
3049
+ polygon: ["points"],
3050
+ path: ["d"],
3051
+ text: [
3052
+ "x",
3053
+ "y",
3054
+ "font-size"
3055
+ ]
3056
+ };
3057
+ /**
3004
3058
  * VertexChain × resize — vertex transport in local space.
3005
3059
  * Line carries its own (x1, y1, x2, y2); polyline / polygon share `points`.
3006
3060
  * Result type is preserved.
@@ -3307,6 +3361,15 @@ let resize_pipeline;
3307
3361
  function num(doc, id, name, fallback = 0) {
3308
3362
  return svg_parse.parse_number(doc.get_attr(id, name), fallback);
3309
3363
  }
3364
+ /** Attribute names a resize gesture may write for `tag`: the
3365
+ * handler write surface (`RESIZE_WRITE_ATTRS`, owned next to the
3366
+ * handlers) plus `transform` — the pipeline's own write
3367
+ * (commit-phase `renormalize_rotate_pivot`). Drives the
3368
+ * `baseline.raw` snapshot that `restore` writes back. */
3369
+ function writable_attrs(tag) {
3370
+ const handler_writes = RESIZE_WRITE_ATTRS[tag];
3371
+ return handler_writes ? [...handler_writes, "transform"] : [];
3372
+ }
3310
3373
  function is_resizable(tag) {
3311
3374
  switch (tag) {
3312
3375
  case "rect":
@@ -3408,12 +3471,21 @@ let resize_pipeline;
3408
3471
  break;
3409
3472
  default: attrs = { kind: "unsupported" };
3410
3473
  }
3474
+ const raw = writable_attrs(tag).map((name) => ({
3475
+ name,
3476
+ value: doc.get_attr(id, name)
3477
+ }));
3411
3478
  return {
3412
3479
  bbox,
3413
- attrs
3480
+ attrs,
3481
+ raw
3414
3482
  };
3415
3483
  }
3416
3484
  _intent.capture_baseline = capture_baseline;
3485
+ function restore(doc, id, baseline) {
3486
+ for (const a of baseline.raw) doc.set_attr(id, a.name, a.value);
3487
+ }
3488
+ _intent.restore = restore;
3417
3489
  function compute_factors(baseline, dir, dx, dy, shift) {
3418
3490
  const b = baseline.bbox;
3419
3491
  let anchorX = 0;
@@ -3816,12 +3888,11 @@ let resize_pipeline;
3816
3888
  }
3817
3889
  _resize_pipeline.apply = apply;
3818
3890
  function revert(doc, plan) {
3819
- const f = intent.compute_factors(plan.baseline, plan.direction, 0, 0, false);
3820
3891
  const members = plan.members ?? [{
3821
3892
  id: plan.id,
3822
3893
  baseline: plan.baseline
3823
3894
  }];
3824
- for (const m of members) intent.apply(doc, m.id, m.baseline, 1, 1, f.origin, "preview");
3895
+ for (const m of members) intent.restore(doc, m.id, m.baseline);
3825
3896
  }
3826
3897
  _resize_pipeline.revert = revert;
3827
3898
  function synthesize_group_baseline(union) {
@@ -3838,7 +3909,8 @@ let resize_pipeline;
3838
3909
  y: union.y,
3839
3910
  w: union.width,
3840
3911
  h: union.height
3841
- }
3912
+ },
3913
+ raw: []
3842
3914
  };
3843
3915
  }
3844
3916
  _resize_pipeline.synthesize_group_baseline = synthesize_group_baseline;
package/dist/presets.js CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_model = require("./model-GpysNbOv.js");
3
- const require_dom = require("./dom-CaByuo6C.js");
2
+ const require_model = require("./model-BLhMJZKJ.js");
3
+ const require_dom = require("./dom-DKQ4Vt3z.js");
4
4
  //#region src/presets/keynote.ts
5
5
  var keynote_exports = /* @__PURE__ */ require_model.__exportAll({ attach: () => attach });
6
6
  /**
package/dist/presets.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./chunk-D7D4PA-g.mjs";
2
- import { t as attach_dom_surface } from "./dom-Bjj9xySE.mjs";
2
+ import { t as attach_dom_surface } from "./dom-OP-kmK8k.mjs";
3
3
  //#region src/presets/keynote.ts
4
4
  var keynote_exports = /* @__PURE__ */ __exportAll({ attach: () => attach });
5
5
  /**
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_editor = require("./editor-N9af0JD2.js");
4
- const require_dom = require("./dom-CaByuo6C.js");
3
+ const require_editor = require("./editor-Be6UrMeV.js");
4
+ const require_dom = require("./dom-DKQ4Vt3z.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-BLsELHSZ.mjs";
3
- import { t as attach_dom_surface } from "./dom-Bjj9xySE.mjs";
2
+ import { t as createSvgEditor } from "./editor-BkCbYCz2.mjs";
3
+ import { t as attach_dom_surface } from "./dom-OP-kmK8k.mjs";
4
4
  import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useSyncExternalStore } from "react";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  //#region src/react.tsx
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grida/svg-editor",
3
- "version": "1.0.0-alpha.17",
3
+ "version": "1.0.0-alpha.18",
4
4
  "description": "Headless SVG editor (experimental).",
5
5
  "keywords": [
6
6
  "bezier",
@@ -58,13 +58,13 @@
58
58
  "tag": "alpha"
59
59
  },
60
60
  "dependencies": {
61
- "@grida/cmath": "0.2.3",
62
- "@grida/hud": "0.2.2",
61
+ "@grida/history": "0.1.1",
63
62
  "@grida/keybinding": "0.2.1",
63
+ "@grida/hud": "0.2.2",
64
64
  "@grida/svg": "0.2.0",
65
- "@grida/history": "0.1.1",
66
- "@grida/vn": "0.1.0",
67
- "@grida/text-editor": "0.1.2"
65
+ "@grida/text-editor": "0.1.2",
66
+ "@grida/cmath": "0.2.3",
67
+ "@grida/vn": "0.1.0"
68
68
  },
69
69
  "devDependencies": {
70
70
  "@types/react": "^19",