@oh-just-another/editor 0.59.0 → 0.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +139 -0
- package/README.md +36 -2
- package/dist/.tsbuildinfo +1 -1
- package/dist/Diagram.d.ts +15 -4
- package/dist/Diagram.d.ts.map +1 -1
- package/dist/Diagram.js +82 -130
- package/dist/Diagram.js.map +1 -1
- package/dist/define-shape.d.ts +71 -0
- package/dist/define-shape.d.ts.map +1 -0
- package/dist/define-shape.js +41 -0
- package/dist/define-shape.js.map +1 -0
- package/dist/file-actions.d.ts +41 -0
- package/dist/file-actions.d.ts.map +1 -0
- package/dist/file-actions.js +201 -0
- package/dist/file-actions.js.map +1 -0
- package/dist/index.d.ts +10 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/package.json +11 -11
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Scene } from "@oh-just-another/scene";
|
|
2
|
+
import { type Action, type ActionRegistry, type Editor } from "@oh-just-another/state";
|
|
3
|
+
import { type PngExportBackground } from "./png-export.js";
|
|
4
|
+
/** Override the notifier used by the file actions (host toast, etc). */
|
|
5
|
+
export declare const setFileActionNotifier: (fn: (message: string) => void) => void;
|
|
6
|
+
/** "Save as JSON" — serialises the scene through `@serialization`. */
|
|
7
|
+
export declare const downloadScene: (scene: Scene) => void;
|
|
8
|
+
/**
|
|
9
|
+
* "Open…" — file picker that accepts `.diagram.json`, parses it, and
|
|
10
|
+
* replaces the editor's scene (history reset — the default `loadScene`
|
|
11
|
+
* behaviour). User cancellation = no-op; a parse failure shows a toast.
|
|
12
|
+
*/
|
|
13
|
+
export declare const openSceneFile: (editor: Editor) => void;
|
|
14
|
+
/**
|
|
15
|
+
* "Export as PNG" — renders the full scene (not just the viewport) via
|
|
16
|
+
* {@link exportSceneToPng} and downloads it. `background` picks the
|
|
17
|
+
* transparent / solid / solid+grid variant.
|
|
18
|
+
*/
|
|
19
|
+
export declare const downloadPng: (editor: Editor, background: PngExportBackground) => Promise<void>;
|
|
20
|
+
/** "Export as SVG" — vector export via `renderSceneToSvg`. */
|
|
21
|
+
export declare const downloadSvg: (scene: Scene) => void;
|
|
22
|
+
/**
|
|
23
|
+
* "Copy as image" — writes a PNG of the full scene to the system
|
|
24
|
+
* clipboard via the async Clipboard API. SVG-to-clipboard is a follow-up
|
|
25
|
+
* (no reliable cross-browser `image/svg+xml` clipboard support today, so
|
|
26
|
+
* we ship the PNG path that works everywhere the API exists).
|
|
27
|
+
*/
|
|
28
|
+
export declare const copySceneAsImage: (editor: Editor) => Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* File-ops actions. `save` / `export` / `copy-as-image` are flagged
|
|
31
|
+
* `viewMode` (non-mutating — fine in read-only); `open` replaces the
|
|
32
|
+
* document, so it stays gated in read-only.
|
|
33
|
+
*/
|
|
34
|
+
export declare const fileActions: readonly Action[];
|
|
35
|
+
/**
|
|
36
|
+
* Register the file-ops actions on a registry (defaults to the shared
|
|
37
|
+
* {@link defaultActionRegistry}). Idempotent — safe to call on every
|
|
38
|
+
* `<Editor>` mount; re-registers in place via `replace`.
|
|
39
|
+
*/
|
|
40
|
+
export declare const registerFileActions: (registry?: ActionRegistry) => void;
|
|
41
|
+
//# sourceMappingURL=file-actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-actions.d.ts","sourceRoot":"","sources":["../src/file-actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAGpD,OAAO,EACL,KAAK,MAAM,EACX,KAAK,cAAc,EACnB,KAAK,MAAM,EAEZ,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAoB,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AA0B7E,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,GAAI,IAAI,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,KAAG,IAErE,CAAC;AAoBF,sEAAsE;AACtE,eAAO,MAAM,aAAa,GAAI,OAAO,KAAK,KAAG,IAG5C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ,MAAM,KAAG,IAmB9C,CAAC;AAaF;;;;GAIG;AACH,eAAO,MAAM,WAAW,GACtB,QAAQ,MAAM,EACd,YAAY,mBAAmB,KAC9B,OAAO,CAAC,IAAI,CAWd,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,WAAW,GAAI,OAAO,KAAK,KAAG,IAG1C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAwBnE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,MAAM,EAyCxC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,WAAU,cAAsC,KAAG,IAEtF,CAAC"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { parseScene, stringifyScene } from "@oh-just-another/serialization";
|
|
2
|
+
import { renderSceneToSvg } from "@oh-just-another/renderer-svg";
|
|
3
|
+
import { defaultActionRegistry, } from "@oh-just-another/state";
|
|
4
|
+
import { exportSceneToPng } from "./png-export.js";
|
|
5
|
+
/**
|
|
6
|
+
* File operations for the editor — Save / Open / Export / Copy-as-image —
|
|
7
|
+
* wired as {@link Action}s so hosts binding the action registry (hotkeys,
|
|
8
|
+
* menus, command palette) get them for free. Each action just glues the
|
|
9
|
+
* existing serialization + exporter pipelines to the browser's file /
|
|
10
|
+
* clipboard APIs; nothing here re-implements serialization or rendering.
|
|
11
|
+
*
|
|
12
|
+
* Lives in `@oh-just-another/editor` (not the lower `state` / `react-ui`
|
|
13
|
+
* layers) because it needs `@oh-just-another/serialization` +
|
|
14
|
+
* {@link exportSceneToPng}, which are only available here.
|
|
15
|
+
*/
|
|
16
|
+
/** Device-pixel scale for PNG export / copy. 2 = retina-quality. */
|
|
17
|
+
const PNG_EXPORT_SCALE = 2;
|
|
18
|
+
/**
|
|
19
|
+
* Host notifier for user-facing errors (bad file, empty canvas,
|
|
20
|
+
* clipboard unsupported). Defaults to `window.alert`; `<Editor>` swaps
|
|
21
|
+
* it for its toast via {@link setFileActionNotifier}.
|
|
22
|
+
*/
|
|
23
|
+
let notify = (message) => {
|
|
24
|
+
if (typeof window !== "undefined")
|
|
25
|
+
window.alert(message);
|
|
26
|
+
};
|
|
27
|
+
/** Override the notifier used by the file actions (host toast, etc). */
|
|
28
|
+
export const setFileActionNotifier = (fn) => {
|
|
29
|
+
notify = fn;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Trigger a browser download of arbitrary bytes. Creates a temporary
|
|
33
|
+
* `<a>`, clicks it, and revokes the object URL on the next frame so the
|
|
34
|
+
* browser has time to start the download.
|
|
35
|
+
*/
|
|
36
|
+
const downloadBlob = (blob, filename) => {
|
|
37
|
+
const url = URL.createObjectURL(blob);
|
|
38
|
+
const a = document.createElement("a");
|
|
39
|
+
a.href = url;
|
|
40
|
+
a.download = filename;
|
|
41
|
+
document.body.appendChild(a);
|
|
42
|
+
a.click();
|
|
43
|
+
document.body.removeChild(a);
|
|
44
|
+
requestAnimationFrame(() => {
|
|
45
|
+
URL.revokeObjectURL(url);
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
/** "Save as JSON" — serialises the scene through `@serialization`. */
|
|
49
|
+
export const downloadScene = (scene) => {
|
|
50
|
+
const json = stringifyScene(scene, 2);
|
|
51
|
+
downloadBlob(new Blob([json], { type: "application/json" }), "scene.diagram.json");
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* "Open…" — file picker that accepts `.diagram.json`, parses it, and
|
|
55
|
+
* replaces the editor's scene (history reset — the default `loadScene`
|
|
56
|
+
* behaviour). User cancellation = no-op; a parse failure shows a toast.
|
|
57
|
+
*/
|
|
58
|
+
export const openSceneFile = (editor) => {
|
|
59
|
+
if (typeof document === "undefined")
|
|
60
|
+
return;
|
|
61
|
+
const input = document.createElement("input");
|
|
62
|
+
input.type = "file";
|
|
63
|
+
input.accept = "application/json,.json";
|
|
64
|
+
input.onchange = () => {
|
|
65
|
+
const file = input.files?.[0];
|
|
66
|
+
if (!file)
|
|
67
|
+
return;
|
|
68
|
+
void file.text().then((text) => {
|
|
69
|
+
try {
|
|
70
|
+
const scene = parseScene(text);
|
|
71
|
+
editor.loadScene(scene);
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
console.error("[diagram] failed to parse scene file:", err);
|
|
75
|
+
notify("Failed to parse the file — make sure it was saved through this app's Save action.");
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
input.click();
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Read the host's current `--du-canvas-bg` CSS variable (falls back to
|
|
83
|
+
* white). Matches what the user sees behind the shapes on the live canvas.
|
|
84
|
+
*/
|
|
85
|
+
const readCanvasBackgroundColor = () => {
|
|
86
|
+
if (typeof document === "undefined")
|
|
87
|
+
return "#ffffff";
|
|
88
|
+
const probe = document.querySelector('canvas[data-layer="main"]') ?? document.body;
|
|
89
|
+
const value = getComputedStyle(probe).getPropertyValue("--du-canvas-bg").trim();
|
|
90
|
+
return value || "#ffffff";
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* "Export as PNG" — renders the full scene (not just the viewport) via
|
|
94
|
+
* {@link exportSceneToPng} and downloads it. `background` picks the
|
|
95
|
+
* transparent / solid / solid+grid variant.
|
|
96
|
+
*/
|
|
97
|
+
export const downloadPng = async (editor, background) => {
|
|
98
|
+
const blob = await exportSceneToPng(editor.scene, {
|
|
99
|
+
background,
|
|
100
|
+
scale: PNG_EXPORT_SCALE,
|
|
101
|
+
backgroundColor: readCanvasBackgroundColor(),
|
|
102
|
+
});
|
|
103
|
+
if (!blob) {
|
|
104
|
+
notify("Nothing to export — the canvas is empty.");
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
downloadBlob(blob, "scene.png");
|
|
108
|
+
};
|
|
109
|
+
/** "Export as SVG" — vector export via `renderSceneToSvg`. */
|
|
110
|
+
export const downloadSvg = (scene) => {
|
|
111
|
+
const svg = renderSceneToSvg(scene);
|
|
112
|
+
downloadBlob(new Blob([svg], { type: "image/svg+xml" }), "scene.svg");
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* "Copy as image" — writes a PNG of the full scene to the system
|
|
116
|
+
* clipboard via the async Clipboard API. SVG-to-clipboard is a follow-up
|
|
117
|
+
* (no reliable cross-browser `image/svg+xml` clipboard support today, so
|
|
118
|
+
* we ship the PNG path that works everywhere the API exists).
|
|
119
|
+
*/
|
|
120
|
+
export const copySceneAsImage = async (editor) => {
|
|
121
|
+
// `navigator.clipboard` is typed as always-present but is absent in
|
|
122
|
+
// insecure contexts / older browsers, so probe it through an optional cast.
|
|
123
|
+
const clipboard = typeof navigator === "undefined" ? undefined : navigator.clipboard;
|
|
124
|
+
if (typeof clipboard?.write !== "function" || typeof ClipboardItem === "undefined") {
|
|
125
|
+
notify("Copy to clipboard isn't supported in this browser.");
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const blob = await exportSceneToPng(editor.scene, {
|
|
129
|
+
background: "color",
|
|
130
|
+
scale: PNG_EXPORT_SCALE,
|
|
131
|
+
backgroundColor: readCanvasBackgroundColor(),
|
|
132
|
+
});
|
|
133
|
+
if (!blob) {
|
|
134
|
+
notify("Nothing to copy — the canvas is empty.");
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
await clipboard.write([new ClipboardItem({ "image/png": blob })]);
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
console.error("[diagram] copy-as-image failed:", err);
|
|
142
|
+
notify("Couldn't copy the image to the clipboard.");
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* File-ops actions. `save` / `export` / `copy-as-image` are flagged
|
|
147
|
+
* `viewMode` (non-mutating — fine in read-only); `open` replaces the
|
|
148
|
+
* document, so it stays gated in read-only.
|
|
149
|
+
*/
|
|
150
|
+
export const fileActions = [
|
|
151
|
+
{
|
|
152
|
+
id: "save-scene",
|
|
153
|
+
label: "Save as JSON",
|
|
154
|
+
category: "other",
|
|
155
|
+
viewMode: true,
|
|
156
|
+
hotkey: { key: "s", meta: true },
|
|
157
|
+
perform: ({ editor }) => {
|
|
158
|
+
downloadScene(editor.scene);
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
id: "open-scene",
|
|
163
|
+
label: "Open…",
|
|
164
|
+
category: "other",
|
|
165
|
+
hotkey: { key: "o", meta: true },
|
|
166
|
+
perform: ({ editor }) => {
|
|
167
|
+
openSceneFile(editor);
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
id: "export-png",
|
|
172
|
+
label: "Export as PNG",
|
|
173
|
+
category: "other",
|
|
174
|
+
viewMode: true,
|
|
175
|
+
hotkey: { key: "e", meta: true, shift: true },
|
|
176
|
+
perform: ({ editor }) => {
|
|
177
|
+
void downloadPng(editor, "color");
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
id: "copy-as-image",
|
|
182
|
+
label: "Copy as image",
|
|
183
|
+
category: "other",
|
|
184
|
+
viewMode: true,
|
|
185
|
+
// ⇧⌥C — distinct from ⌘C (copy selection) and ⌥⌘C (copy style).
|
|
186
|
+
hotkey: { key: "c", shift: true, alt: true },
|
|
187
|
+
perform: ({ editor }) => {
|
|
188
|
+
void copySceneAsImage(editor);
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
];
|
|
192
|
+
/**
|
|
193
|
+
* Register the file-ops actions on a registry (defaults to the shared
|
|
194
|
+
* {@link defaultActionRegistry}). Idempotent — safe to call on every
|
|
195
|
+
* `<Editor>` mount; re-registers in place via `replace`.
|
|
196
|
+
*/
|
|
197
|
+
export const registerFileActions = (registry = defaultActionRegistry) => {
|
|
198
|
+
for (const action of fileActions)
|
|
199
|
+
registry.replace(action);
|
|
200
|
+
};
|
|
201
|
+
//# sourceMappingURL=file-actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-actions.js","sourceRoot":"","sources":["../src/file-actions.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -22,13 +22,21 @@ export { detectCapabilities, logCapabilities, type CapabilityProfile, type Capab
|
|
|
22
22
|
export { isEditableTarget } from "./dom-focus.js";
|
|
23
23
|
export { bindEditorHotkeys, type HotkeyBindingOptions } from "@oh-just-another/state";
|
|
24
24
|
export { exportSceneToPng, type PngExportBackground, type PngExportOptions } from "./png-export.js";
|
|
25
|
+
export { fileActions, registerFileActions, setFileActionNotifier, downloadScene, downloadSvg, downloadPng, openSceneFile, copySceneAsImage, } from "./file-actions.js";
|
|
25
26
|
export { registerBounder, registerLayoutKind } from "@oh-just-another/scene";
|
|
26
27
|
export { registerElementRenderer, registerAnimationAdapter } from "@oh-just-another/renderer-core";
|
|
28
|
+
export { registerInteractiveHitTester, registerRotateAnchor } from "@oh-just-another/state";
|
|
27
29
|
export { registerMigration } from "@oh-just-another/serialization";
|
|
30
|
+
export { defineShape, type ShapeSpec, type ShapeRegistration } from "./define-shape.js";
|
|
28
31
|
export { installGifAnimationAdapter } from "./gif-animation.js";
|
|
29
32
|
export type { ElementId } from "@oh-just-another/types";
|
|
30
|
-
export type { Editor as EditorInstance, Mode, FileDropHandler } from "@oh-just-another/state";
|
|
31
|
-
export
|
|
33
|
+
export type { ActiveTool, Editor as EditorInstance, Mode, FileDropHandler, } from "@oh-just-another/state";
|
|
34
|
+
export { clampCrop, computeConvertType, computeSetImageCrop, computeCommitImageCrop, computeSpawnConnectedNode, cropFullImageLocalRect, cropHandleWorldPoints, computeCropHandleDrag, computeCropBodyPan, CROP_HANDLES, FULL_CROP, pickColorAt, } from "@oh-just-another/state";
|
|
35
|
+
export type { ConvertTarget, CropDragResult, CropHandle, SpawnDirection, } from "@oh-just-another/state";
|
|
36
|
+
export type { ImageCrop } from "@oh-just-another/scene";
|
|
37
|
+
export type { Scene, LayoutKindEntry, ElementBase, ElementBounder, AnchorRef, } from "@oh-just-another/scene";
|
|
38
|
+
export type { ElementRenderer, RenderTarget } from "@oh-just-another/renderer-core";
|
|
39
|
+
export type { InteractiveHitTester } from "@oh-just-another/state";
|
|
32
40
|
export type { Template } from "@oh-just-another/templates";
|
|
33
41
|
export type { AnimatedSourceAdapter } from "@oh-just-another/renderer-core";
|
|
34
42
|
export type { RendererBackend } from "@oh-just-another/renderer-canvas";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,OAAO,IAAI,MAAM,EACjB,OAAO,EACP,KAAK,UAAU,IAAI,SAAS,EAC5B,KAAK,UAAU,EACf,KAAK,YAAY,IAAI,WAAW,EAChC,KAAK,YAAY,EACjB,KAAK,YAAY,IAAI,WAAW,EAChC,KAAK,YAAY,GAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,KAAK,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,gBAAgB,EAAE,KAAK,mBAAmB,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,OAAO,IAAI,MAAM,EACjB,OAAO,EACP,KAAK,UAAU,IAAI,SAAS,EAC5B,KAAK,UAAU,EACf,KAAK,YAAY,IAAI,WAAW,EAChC,KAAK,YAAY,EACjB,KAAK,YAAY,IAAI,WAAW,EAChC,KAAK,YAAY,GAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,KAAK,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,gBAAgB,EAAE,KAAK,mBAAmB,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAIpG,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,qBAAqB,EACrB,aAAa,EACb,WAAW,EACX,WAAW,EACX,aAAa,EACb,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AACnG,OAAO,EAAE,4BAA4B,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAGnE,OAAO,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGxF,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAOhE,YAAY,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,YAAY,EACV,UAAU,EACV,MAAM,IAAI,cAAc,EACxB,IAAI,EACJ,eAAe,GAChB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,WAAW,GACZ,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,aAAa,EACb,cAAc,EACd,UAAU,EACV,cAAc,GACf,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,YAAY,EACV,KAAK,EACL,eAAe,EACf,WAAW,EACX,cAAc,EACd,SAAS,GACV,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACpF,YAAY,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,YAAY,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,YAAY,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC5E,YAAY,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -22,13 +22,23 @@ export { detectCapabilities, logCapabilities, } from "./capabilities.js";
|
|
|
22
22
|
export { isEditableTarget } from "./dom-focus.js";
|
|
23
23
|
export { bindEditorHotkeys } from "@oh-just-another/state";
|
|
24
24
|
export { exportSceneToPng } from "./png-export.js";
|
|
25
|
+
// File operations (Save / Open / Export / Copy-as-image) — registered on
|
|
26
|
+
// the action registry by `<Editor>`; exported so hosts can wire them to
|
|
27
|
+
// their own chrome or a custom registry.
|
|
28
|
+
export { fileActions, registerFileActions, setFileActionNotifier, downloadScene, downloadSvg, downloadPng, openSceneFile, copySceneAsImage, } from "./file-actions.js";
|
|
25
29
|
// Plug-in registries from the underlying packages, surfaced here so the
|
|
26
30
|
// umbrella package is the single import for extending the editor without
|
|
27
31
|
// reaching into the lower-level packages.
|
|
28
32
|
export { registerBounder, registerLayoutKind } from "@oh-just-another/scene";
|
|
29
33
|
export { registerElementRenderer, registerAnimationAdapter } from "@oh-just-another/renderer-core";
|
|
34
|
+
export { registerInteractiveHitTester, registerRotateAnchor } from "@oh-just-another/state";
|
|
30
35
|
export { registerMigration } from "@oh-just-another/serialization";
|
|
36
|
+
// `defineShape` — one-call facade over the registries above for adding a
|
|
37
|
+
// custom shape type (bounds + render + optional interaction hooks).
|
|
38
|
+
export { defineShape } from "./define-shape.js";
|
|
31
39
|
// Built-in GIF decoder — `<Editor>` installs it by default; exported so hosts
|
|
32
40
|
// can install it explicitly or opt into it without the component.
|
|
33
41
|
export { installGifAnimationAdapter } from "./gif-animation.js";
|
|
42
|
+
// Tool operations + types (eyedropper / convert-type / image-crop / spawn).
|
|
43
|
+
export { clampCrop, computeConvertType, computeSetImageCrop, computeCommitImageCrop, computeSpawnConnectedNode, cropFullImageLocalRect, cropHandleWorldPoints, computeCropHandleDrag, computeCropBodyPan, CROP_HANDLES, FULL_CROP, pickColorAt, } from "@oh-just-another/state";
|
|
34
44
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,OAAO,IAAI,MAAM,EACjB,OAAO,GAOR,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,EAClB,eAAe,GAGhB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAA6B,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,gBAAgB,EAAmD,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,OAAO,IAAI,MAAM,EACjB,OAAO,GAOR,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,EAClB,eAAe,GAGhB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAA6B,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,gBAAgB,EAAmD,MAAM,iBAAiB,CAAC;AACpG,yEAAyE;AACzE,wEAAwE;AACxE,yCAAyC;AACzC,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,qBAAqB,EACrB,aAAa,EACb,WAAW,EACX,WAAW,EACX,aAAa,EACb,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,wEAAwE;AACxE,yEAAyE;AACzE,0CAA0C;AAC1C,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AACnG,OAAO,EAAE,4BAA4B,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,yEAAyE;AACzE,oEAAoE;AACpE,OAAO,EAAE,WAAW,EAA0C,MAAM,mBAAmB,CAAC;AACxF,8EAA8E;AAC9E,kEAAkE;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAchE,4EAA4E;AAC5E,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,WAAW,GACZ,MAAM,wBAAwB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-just-another/editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.61.0",
|
|
4
4
|
"description": "Drop-in diagram editor as a single React component. Auto-detects renderer / WASM / worker capabilities and exposes a programmatic editor API.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Rustam Garifulin <rustam@n69.in>",
|
|
@@ -42,16 +42,16 @@
|
|
|
42
42
|
"gifuct-js": "2.1.2",
|
|
43
43
|
"lucide-react": "1.16.0",
|
|
44
44
|
"@oh-just-another/fonts": "0.1.0",
|
|
45
|
-
"@oh-just-another/raster-wasm": "0.57.
|
|
46
|
-
"@oh-just-another/react-ui": "0.
|
|
47
|
-
"@oh-just-another/renderer-canvas": "0.
|
|
48
|
-
"@oh-just-another/renderer-core": "0.
|
|
49
|
-
"@oh-just-another/renderer-svg": "0.57.
|
|
50
|
-
"@oh-just-another/scene": "0.
|
|
51
|
-
"@oh-just-another/serialization": "0.
|
|
52
|
-
"@oh-just-another/state": "0.
|
|
53
|
-
"@oh-just-another/templates": "0.57.
|
|
54
|
-
"@oh-just-another/text-wasm": "0.57.
|
|
45
|
+
"@oh-just-another/raster-wasm": "0.57.4",
|
|
46
|
+
"@oh-just-another/react-ui": "0.60.0",
|
|
47
|
+
"@oh-just-another/renderer-canvas": "0.61.0",
|
|
48
|
+
"@oh-just-another/renderer-core": "0.60.0",
|
|
49
|
+
"@oh-just-another/renderer-svg": "0.57.4",
|
|
50
|
+
"@oh-just-another/scene": "0.61.0",
|
|
51
|
+
"@oh-just-another/serialization": "0.60.0",
|
|
52
|
+
"@oh-just-another/state": "0.61.0",
|
|
53
|
+
"@oh-just-another/templates": "0.57.4",
|
|
54
|
+
"@oh-just-another/text-wasm": "0.57.4",
|
|
55
55
|
"@oh-just-another/types": "0.57.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|