@oh-just-another/editor 0.58.2 → 0.60.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +156 -0
  2. package/README.md +40 -6
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/Diagram.d.ts +19 -1
  5. package/dist/Diagram.d.ts.map +1 -1
  6. package/dist/Diagram.js +173 -180
  7. package/dist/Diagram.js.map +1 -1
  8. package/dist/capabilities.d.ts.map +1 -1
  9. package/dist/capabilities.js +1 -8
  10. package/dist/capabilities.js.map +1 -1
  11. package/dist/constants.d.ts +17 -0
  12. package/dist/constants.d.ts.map +1 -0
  13. package/dist/constants.js +17 -0
  14. package/dist/constants.js.map +1 -0
  15. package/dist/define-shape.d.ts +71 -0
  16. package/dist/define-shape.d.ts.map +1 -0
  17. package/dist/define-shape.js +41 -0
  18. package/dist/define-shape.js.map +1 -0
  19. package/dist/dom-focus.d.ts +7 -4
  20. package/dist/dom-focus.d.ts.map +1 -1
  21. package/dist/dom-focus.js +7 -9
  22. package/dist/dom-focus.js.map +1 -1
  23. package/dist/file-actions.d.ts +52 -0
  24. package/dist/file-actions.d.ts.map +1 -0
  25. package/dist/file-actions.js +201 -0
  26. package/dist/file-actions.js.map +1 -0
  27. package/dist/gif-animation.d.ts +7 -0
  28. package/dist/gif-animation.d.ts.map +1 -0
  29. package/dist/gif-animation.js +99 -0
  30. package/dist/gif-animation.js.map +1 -0
  31. package/dist/index.d.ts +12 -2
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +15 -1
  34. package/dist/index.js.map +1 -1
  35. package/dist/png-export.d.ts +3 -9
  36. package/dist/png-export.d.ts.map +1 -1
  37. package/dist/png-export.js +5 -13
  38. package/dist/png-export.js.map +1 -1
  39. package/dist/themed-portal-container.d.ts +25 -0
  40. package/dist/themed-portal-container.d.ts.map +1 -0
  41. package/dist/themed-portal-container.js +47 -0
  42. package/dist/themed-portal-container.js.map +1 -0
  43. package/package.json +20 -18
package/CHANGELOG.md CHANGED
@@ -1,5 +1,161 @@
1
1
  # @oh-just-another/editor
2
2
 
3
+ ## 0.60.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 179bad8: Add a built-in `minimap` prop to `<Diagram>`/`<Editor>`. When set, the minimap docks bottom-right above the zoom controls and is hidden in zen mode along with the rest of the chrome (it reads the editor from context). Previously hosts had to mount `<Minimap>` themselves, which sat outside the zen-gated chrome and overlapped the zoom pill. Off by default.
8
+ - 1c4941e: New `<DrawingPanel>` — a floating tool-options panel that appears while the brush or eraser is active. It edits `editor.brushSettings` (via the new `useBrushSettings` hook): line colour, enclosed-fill colour, opacity and width for the brush; only the width (which doubles as the eraser radius) for the eraser. `<Diagram>` mounts it automatically top-right, hidden in zen mode; opt out with the new `hideDrawingPanel` prop. This is a functional scaffold intended for restyling.
9
+ - 6d184ad: Add `defineShape()` — one-call facade for registering a custom shape type (bounder, renderer, optional interactive hit-tester and rotate anchor). Re-export `registerInteractiveHitTester` / `registerRotateAnchor` and plugin types (`ElementBase`, `ElementBounder`, `ElementRenderer`, `RenderTarget`, `InteractiveHitTester`, `AnchorRef`).
10
+ - 2fbc079: Add editor file operations as registry actions + hotkeys: Save as JSON (`⌘S`), Open… (`⌘O`), Export PNG (`⌘⇧E`) and Copy as image to the system clipboard (`⇧⌥C`, PNG blob via the async Clipboard API). Exposed via `registerFileActions()` / `fileActions` and the `downloadScene` / `openSceneFile` / `downloadPng` / `downloadSvg` / `copySceneAsImage` helpers (`setFileActionNotifier` routes errors to a host toast). `<Editor>` registers them on mount and adds a "Copy as image" File-menu item with shortcut hints. All built on the existing serialization + exporter pipelines.
11
+ - bdc847e: Add four editor tools:
12
+ - **Eyedropper** — new `eyedropper` mode (toolbar button, `Alt+I`). Click a
13
+ shape to sample its fill/stroke and apply it to the selection.
14
+ `Editor.pickColorAt` / `applyEyedropperAt` + pure `pickColorAt`.
15
+ - **Convert element type** — `Editor.convertSelection(target)` and pure
16
+ `computeConvertType` switch rectangle ↔ ellipse ↔ diamond (polygon) in place,
17
+ preserving position/size/style. New "Shape type" property-panel control.
18
+ - **Image crop** — optional normalised `crop` rect on `ImageElement` (additive,
19
+ serialised). New `crop` mode entered by double-clicking an image or the
20
+ property-panel Crop button: drag a frame, `Enter` to apply, `Esc` to cancel.
21
+ Canvas2D renders the cropped source region (`RenderTarget.drawImage` gains an
22
+ optional `crop` arg). `Editor.beginImageCrop` / `commitImageCrop` /
23
+ `cancelImageCrop` + pure `computeSetImageCrop` / `cropRectFromWorldDrag`.
24
+ - **Flowchart auto-generate** — `Cmd/Ctrl+Alt+Arrow` spawns a connected node
25
+ from the selected node in that direction. `Editor.spawnConnectedNode` + pure
26
+ `computeSpawnConnectedNode`.
27
+
28
+ Also exposes `worldToLocal` from `@oh-just-another/scene`.
29
+
30
+ - a9558d9: Reworked flowchart keyboard model. Arrow-key bindings are reworked and disambiguated by modifier: `Arrow` nudges (unchanged); `Cmd/Ctrl+Arrow` grows a flowchart CREATE session (each press adds a pending connected sibling, previewed on the overlay, committed as one undo step when Cmd/Ctrl is released, cancelled on Escape); `Alt+Arrow` navigates to the adjacent node (graph neighbour, else spatially nearest); `Cmd/Ctrl+Shift+Arrow` aligns (moved off the old plain `Alt+Arrow`). The old `Cmd/Ctrl+Alt+Arrow` spawn binding is retired.
31
+
32
+ New API: `editor.growFlowchart` / `commitFlowchart` / `cancelFlowchart` / `navigateFlowchart` / `flowchartPreview`, the pure `computeSpawnConnectedNodes`, and `endpointElementId` (scene). `<Diagram>` wires the keyup-commit / Escape-cancel lifecycle for you.
33
+
34
+ ### Patch Changes
35
+
36
+ - Updated dependencies [783749e]
37
+ - Updated dependencies [c189261]
38
+ - Updated dependencies [c189261]
39
+ - Updated dependencies [c189261]
40
+ - Updated dependencies [641842b]
41
+ - Updated dependencies [c189261]
42
+ - Updated dependencies [c58054b]
43
+ - Updated dependencies [b156869]
44
+ - Updated dependencies [0d3934e]
45
+ - Updated dependencies [1c4941e]
46
+ - Updated dependencies [0d3934e]
47
+ - Updated dependencies [b0a9f3b]
48
+ - Updated dependencies [571f13b]
49
+ - Updated dependencies [ca48e8a]
50
+ - Updated dependencies [1975a9b]
51
+ - Updated dependencies [1975a9b]
52
+ - Updated dependencies [bdc847e]
53
+ - Updated dependencies [511a22a]
54
+ - Updated dependencies [a9558d9]
55
+ - Updated dependencies [22b90f9]
56
+ - Updated dependencies [99b5bee]
57
+ - Updated dependencies [dda2e56]
58
+ - Updated dependencies [34ddb22]
59
+ - Updated dependencies [f381039]
60
+ - Updated dependencies [394d3ce]
61
+ - Updated dependencies [295f38b]
62
+ - Updated dependencies [70a08d8]
63
+ - Updated dependencies [bd2e26c]
64
+ - Updated dependencies [97de2fd]
65
+ - Updated dependencies [407f203]
66
+ - Updated dependencies [744f4b8]
67
+ - Updated dependencies [5d8a282]
68
+ - Updated dependencies [71a6c8b]
69
+ - Updated dependencies [71a6c8b]
70
+ - Updated dependencies [7f69f29]
71
+ - Updated dependencies [672b557]
72
+ - Updated dependencies [dde8279]
73
+ - Updated dependencies [cec8f83]
74
+ - Updated dependencies [1975a9b]
75
+ - Updated dependencies [1975a9b]
76
+ - Updated dependencies [1975a9b]
77
+ - Updated dependencies [1975a9b]
78
+ - Updated dependencies [cf8b735]
79
+ - Updated dependencies [571f13b]
80
+ - Updated dependencies [f8302c3]
81
+ - @oh-just-another/scene@0.60.0
82
+ - @oh-just-another/serialization@0.59.0
83
+ - @oh-just-another/state@0.60.0
84
+ - @oh-just-another/renderer-core@0.59.0
85
+ - @oh-just-another/react-ui@0.59.0
86
+ - @oh-just-another/renderer-canvas@0.60.0
87
+ - @oh-just-another/renderer-svg@0.57.3
88
+ - @oh-just-another/raster-wasm@0.57.3
89
+ - @oh-just-another/templates@0.57.3
90
+ - @oh-just-another/text-wasm@0.57.3
91
+
92
+ ## 0.59.0
93
+
94
+ ### Minor Changes
95
+
96
+ - 1c7cc6c: New package `@oh-just-another/fonts` bundles the editor's fonts (Roboto, PT Serif, Roboto Mono) as web fonts, and the Canvas2D / offscreen backends now draw with them via `resolveBundledFamily`. Text is consistent across renderers instead of WebGL2 using the embedded font while Canvas2D fell back to a system font. `<Editor>` loads the fonts on mount and redraws once they're ready.
97
+ - 86c5b61: `<Editor>` accepts granular scene-settings props — `grid` (`{ enabled, style }`)
98
+ and `snap` — merged over the defaults. A persisted `initialScene` still wins over
99
+ them (user data over host config).
100
+ - 34fc660: `<Editor>` now registers a built-in GIF animation adapter by default, so dropped / pasted animated GIFs play out of the box (previously the host had to wire up a decoder). The `gifuct-js` decoder is lazy-loaded on first GIF decode, so apps that never show a GIF don't pay for it. A host `animationAdapters` entry with `kind: "gif"` still overrides the built-in. Also exports `installGifAnimationAdapter` for explicit / component-free use.
101
+ - 9673846: Grid model rework. The viewport's `gridSize` (spacing that doubled as a hidden/
102
+ shown toggle) is replaced by an explicit `gridEnabled` boolean; spacing is fixed
103
+ at `DEFAULT_GRID_SPACING`. The runtime `gridVisible` flag is removed — grid
104
+ on/off now lives on the scene viewport and persists with it. Scene documents
105
+ migrate v1 → v2 automatically (`gridSize > 0` → `gridEnabled: true`). `<Editor>`
106
+ ships gridless by default; hosts enable the grid per scene.
107
+ - edde5d0: Add `bindEditorHotkeys(editor, options?)` — a reusable, framework-agnostic keyboard-shortcut binding driven by the action registry. Returns an unbind function, leaves text fields alone (except `Escape`), and reads `composedPath()[0]` so the editable-target check stays correct across a shadow-root boundary. Re-exported from `@oh-just-another/editor`.
108
+ - c5be6e5: Transform modifier keys during pointer gestures: hold **Alt** to resize symmetrically about the element's centre, **Shift** to lock the aspect ratio while resizing, and **Shift** to constrain a move to a single axis (Cmd/Ctrl already pulls a shape off the grid for one gesture). `<Editor>` mirrors the modifiers from keyboard events automatically; headless hosts can drive them via `Editor.setTransformModifiers({ alt, shift })`. Applies to single shapes, multi-selection / group resizes, and text.
109
+
110
+ ### Patch Changes
111
+
112
+ - 60e315e: Fix floating chrome ignoring the app theme. The selection / property panel,
113
+ popovers, tooltips and the right-click context menu portal out of the editor
114
+ root, which also escaped the `data-theme` set there — so under an OS dark
115
+ preference they showed a dark surface even when the app was set to light (and
116
+ vice-versa). They now portal into a wrapper that mirrors the editor's theme, so
117
+ they always match the app. The context menu additionally portals into that
118
+ wrapper and its colours forward to the `--du-*` theme variables (no more
119
+ hard-coded dark fallbacks / hover).
120
+ - Updated dependencies [b4b252b]
121
+ - Updated dependencies [1c7cc6c]
122
+ - Updated dependencies [7217cac]
123
+ - Updated dependencies [578e728]
124
+ - Updated dependencies [d20d50a]
125
+ - Updated dependencies [0152ed6]
126
+ - Updated dependencies [938e7c8]
127
+ - Updated dependencies [9673846]
128
+ - Updated dependencies [60e315e]
129
+ - Updated dependencies [f370dba]
130
+ - Updated dependencies [1c7cc6c]
131
+ - Updated dependencies [e1fd495]
132
+ - Updated dependencies [8f00738]
133
+ - Updated dependencies [09a096c]
134
+ - Updated dependencies [1c7cc6c]
135
+ - Updated dependencies [ff90a95]
136
+ - Updated dependencies [da91d59]
137
+ - Updated dependencies [3152317]
138
+ - Updated dependencies [fc47ecc]
139
+ - Updated dependencies [8fc6b69]
140
+ - Updated dependencies [f98730f]
141
+ - Updated dependencies [904cc09]
142
+ - Updated dependencies [d44348a]
143
+ - Updated dependencies [edde5d0]
144
+ - Updated dependencies [1c7cc6c]
145
+ - Updated dependencies [60e315e]
146
+ - Updated dependencies [c5be6e5]
147
+ - @oh-just-another/state@0.59.0
148
+ - @oh-just-another/react-ui@0.58.0
149
+ - @oh-just-another/fonts@0.1.0
150
+ - @oh-just-another/renderer-canvas@0.59.0
151
+ - @oh-just-another/scene@0.59.0
152
+ - @oh-just-another/serialization@0.58.0
153
+ - @oh-just-another/renderer-core@0.58.0
154
+ - @oh-just-another/raster-wasm@0.57.2
155
+ - @oh-just-another/renderer-svg@0.57.2
156
+ - @oh-just-another/templates@0.57.2
157
+ - @oh-just-another/text-wasm@0.57.2
158
+
3
159
  ## 0.58.2
4
160
 
5
161
  ### Patch Changes
package/README.md CHANGED
@@ -1,11 +1,13 @@
1
1
  # @oh-just-another/editor
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@oh-just-another/editor.svg)](https://www.npmjs.com/package/@oh-just-another/editor)
4
+
3
5
  Drop-in diagram editor as a single React component. Auto-detects the best
4
6
  renderer (WebGL2 / Canvas2D / OffscreenCanvas), opt-in WASM text-shaping and
5
7
  rasterisation, and worker offloading — then exposes one `<Editor>` component
6
8
  plus a programmatic handle for driving it from code.
7
9
 
8
- This is the umbrella package: it composes `@oh-just-another/react-ui`,
10
+ The umbrella package (L6): it composes `@oh-just-another/react-ui`,
9
11
  `@oh-just-another/state`, the renderers, serialization and templates into a
10
12
  ready-to-mount editor. For lower-level building blocks, depend on those
11
13
  packages directly.
@@ -34,13 +36,13 @@ export function App() {
34
36
  > set — light and dark, plus a `prefers-color-scheme` fallback for "system" —
35
37
  > so the import above is all you need. The editor toggles `data-theme` on its
36
38
  > own root element (not the global `<html>`, so multiple editors theme
37
- > independently) via the `theme` prop; override any `--du-*` (or legacy `--bg` /
38
- > `--accent` / …) variable in your own stylesheet to re-skin.
39
+ > independently) via the `theme` prop; override any `--du-*` variable in your
40
+ > own stylesheet to re-skin.
39
41
 
40
42
  ## Driving it from code
41
43
 
42
- Pass a `ref` to get an imperative handle the escape hatch for programmatic
43
- control (the live `editor` exposes undo/redo, zoom, selection, mutations, …):
44
+ Pass a `ref` to get an imperative handle for programmatic control undo/redo,
45
+ zoom, selection, mutations:
44
46
 
45
47
  ```tsx
46
48
  import { useRef } from "react";
@@ -124,6 +126,36 @@ bundlers that don't (esbuild, Parcel, no bundler), either:
124
126
 
125
127
  The worker is an optimisation; the editor renders fine without it.
126
128
 
129
+ ## Custom shapes
130
+
131
+ `defineShape` registers a custom element type in one call — bounds (spatial
132
+ index / hit-test / culling), rendering (all backends), and optional
133
+ interaction hooks. Serialization is automatic (unknown types pass through).
134
+
135
+ ```ts
136
+ import { defineShape, type ElementBase } from "@oh-just-another/editor";
137
+
138
+ interface Sticker extends ElementBase {
139
+ readonly type: "sticker";
140
+ readonly size: number;
141
+ }
142
+
143
+ defineShape<Sticker>({
144
+ type: "sticker",
145
+ bounds: (s) => ({ x: 0, y: 0, width: s.size, height: s.size }),
146
+ render: (s, target) => {
147
+ target.setFill(s.style.fill ?? "#facc15");
148
+ target.beginPath();
149
+ target.rect(0, 0, s.size, s.size);
150
+ target.fill();
151
+ },
152
+ // Optional: interactiveHitTest, rotateAnchor.
153
+ });
154
+ ```
155
+
156
+ Returns `{ dispose() }` — currently a no-op (registries are append-only),
157
+ reserved for future deregistration.
158
+
127
159
  ## Plug-in points
128
160
 
129
161
  These registries are re-exported from this package, so the editor is the single
@@ -133,10 +165,12 @@ import for extending the kernel without forking:
133
165
  import { registerBounder, registerElementRenderer } from "@oh-just-another/editor";
134
166
  ```
135
167
 
168
+ - `defineShape` — one-call custom shape (wraps the two registries below plus
169
+ `registerInteractiveHitTester` / `registerRotateAnchor`).
136
170
  - `registerBounder` (AABB) + `registerElementRenderer` (draw) — custom element types.
137
171
  - `registerMigration` — wire-format migrations.
138
172
  - `registerLayoutKind` / `registerAnimationAdapter` — or pass via the
139
173
  `layoutKinds` / `animationAdapters` props.
140
174
  - `exportSceneToPng` — render the full scene to a PNG `Blob` headlessly.
141
175
 
142
- `Diagram` is exported as a deprecated alias of `Editor` for back-compat.
176
+ `Diagram` is a deprecated alias of `Editor`.