@excalidraw/excalidraw 0.18.0-7ea3229 → 0.18.0-816c81c
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 +81 -0
- package/README.md +111 -14
- package/dist/dev/{chunk-FXVS2QTZ.js → chunk-LWYHXCPK.js} +33 -58
- package/dist/dev/chunk-LWYHXCPK.js.map +7 -0
- package/dist/dev/{chunk-IFMURN5W.js → chunk-PNUNMPKU.js} +25 -5
- package/dist/dev/chunk-PNUNMPKU.js.map +7 -0
- package/dist/dev/components/TTDDialog/CodeMirrorEditor-XRUBL3LG.js +259 -0
- package/dist/dev/components/TTDDialog/CodeMirrorEditor-XRUBL3LG.js.map +7 -0
- package/dist/dev/data/{image-X6URJSP5.js → image-3J4DLBV6.js} +2 -2
- package/dist/dev/index.css +255 -75
- package/dist/dev/index.css.map +3 -3
- package/dist/dev/index.js +5378 -3320
- package/dist/dev/index.js.map +4 -4
- package/dist/dev/locales/{en-ZZQASRYX.js → en-YPPLK6NW.js} +4 -2
- package/dist/prod/chunk-27N2SPOM.js +4 -0
- package/dist/prod/chunk-ETSVUAFD.js +12 -0
- package/dist/prod/components/TTDDialog/CodeMirrorEditor-UCMRAMCV.js +1 -0
- package/dist/prod/data/{image-N3OFZNE6.js → image-32MOCVDX.js} +1 -1
- package/dist/prod/index.css +1 -1
- package/dist/prod/index.js +37 -30
- package/dist/prod/locales/en-CTDJDZ6K.js +1 -0
- package/dist/types/common/src/appEventBus.d.ts +27 -0
- package/dist/types/common/src/colors.d.ts +1 -1
- package/dist/types/common/src/index.d.ts +2 -0
- package/dist/types/common/src/utils.d.ts +1 -3
- package/dist/types/common/src/versionedSnapshotStore.d.ts +17 -0
- package/dist/types/element/src/Scene.d.ts +2 -0
- package/dist/types/element/src/arrowheads.d.ts +3 -0
- package/dist/types/element/src/binding.d.ts +3 -4
- package/dist/types/element/src/bounds.d.ts +1 -1
- package/dist/types/element/src/elbowArrow.d.ts +2 -0
- package/dist/types/element/src/index.d.ts +1 -0
- package/dist/types/element/src/linearElementEditor.d.ts +3 -0
- package/dist/types/element/src/mutateElement.d.ts +2 -0
- package/dist/types/element/src/types.d.ts +5 -2
- package/dist/types/element/src/utils.d.ts +1 -1
- package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +23 -29
- package/dist/types/excalidraw/actions/actionBoundText.d.ts +16 -20
- package/dist/types/excalidraw/actions/actionCanvas.d.ts +97 -121
- package/dist/types/excalidraw/actions/actionClipboard.d.ts +16 -20
- package/dist/types/excalidraw/actions/actionCropEditor.d.ts +8 -10
- package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +24 -30
- package/dist/types/excalidraw/actions/actionElementLink.d.ts +4 -10
- package/dist/types/excalidraw/actions/actionElementLock.d.ts +16 -20
- package/dist/types/excalidraw/actions/actionEmbeddable.d.ts +8 -10
- package/dist/types/excalidraw/actions/actionExport.d.ts +60 -344
- package/dist/types/excalidraw/actions/actionFrame.d.ts +32 -40
- package/dist/types/excalidraw/actions/actionGroup.d.ts +16 -20
- package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +8 -10
- package/dist/types/excalidraw/actions/actionLink.d.ts +8 -10
- package/dist/types/excalidraw/actions/actionMenu.d.ts +4 -10
- package/dist/types/excalidraw/actions/actionProperties.d.ts +16 -20
- package/dist/types/excalidraw/actions/actionSelectAll.d.ts +8 -10
- package/dist/types/excalidraw/actions/actionStyles.d.ts +7 -9
- package/dist/types/excalidraw/actions/actionToggleArrowBinding.d.ts +172 -0
- package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +8 -10
- package/dist/types/excalidraw/actions/actionToggleMidpointSnapping.d.ts +172 -0
- package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +8 -10
- package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +4 -10
- package/dist/types/excalidraw/actions/actionToggleStats.d.ts +8 -10
- package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +8 -10
- package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +8 -10
- package/dist/types/excalidraw/actions/index.d.ts +2 -0
- package/dist/types/excalidraw/actions/types.d.ts +1 -1
- package/dist/types/excalidraw/appState.d.ts +4 -2
- package/dist/types/excalidraw/charts/charts.bar.d.ts +2 -0
- package/dist/types/excalidraw/charts/charts.constants.d.ts +48 -0
- package/dist/types/excalidraw/charts/charts.helpers.d.ts +32 -0
- package/dist/types/excalidraw/charts/charts.line.d.ts +2 -0
- package/dist/types/excalidraw/charts/charts.parse.d.ts +10 -0
- package/dist/types/excalidraw/charts/charts.radar.d.ts +2 -0
- package/dist/types/excalidraw/charts/charts.types.d.ts +18 -0
- package/dist/types/excalidraw/charts/index.d.ts +7 -0
- package/dist/types/excalidraw/clipboard.d.ts +2 -5
- package/dist/types/excalidraw/components/App.d.ts +33 -11
- package/dist/types/excalidraw/components/AppStateObserver.d.ts +37 -0
- package/dist/types/excalidraw/components/IconPicker.d.ts +14 -9
- package/dist/types/excalidraw/components/PasteChartDialog.d.ts +4 -5
- package/dist/types/excalidraw/components/TTDDialog/CodeMirrorEditor.d.ts +11 -0
- package/dist/types/excalidraw/components/TTDDialog/TTDDialogInput.d.ts +3 -3
- package/dist/types/excalidraw/components/TTDDialog/TTDDialogOutput.d.ts +4 -1
- package/dist/types/excalidraw/components/TTDDialog/mermaid-lang-lite.d.ts +2 -0
- package/dist/types/excalidraw/components/TTDDialog/utils/TTDStreamFetch.d.ts +1 -1
- package/dist/types/excalidraw/components/TTDDialog/utils/mermaidAutoFix.d.ts +1 -0
- package/dist/types/excalidraw/components/TTDDialog/utils/mermaidError.d.ts +10 -0
- package/dist/types/excalidraw/components/Toast.d.ts +8 -4
- package/dist/types/excalidraw/components/icons.d.ts +17 -8
- package/dist/types/excalidraw/components/main-menu/DefaultItems.d.ts +2 -0
- package/dist/types/excalidraw/data/blob.d.ts +25 -30
- package/dist/types/excalidraw/data/filesystem.d.ts +3 -5
- package/dist/types/excalidraw/data/index.d.ts +2 -3
- package/dist/types/excalidraw/data/json.d.ts +28 -22
- package/dist/types/excalidraw/data/resave.d.ts +7 -2
- package/dist/types/excalidraw/hooks/useAppStateValue.d.ts +29 -0
- package/dist/types/excalidraw/index.d.ts +23 -3
- package/dist/types/excalidraw/types.d.ts +84 -13
- package/package.json +12 -7
- package/dist/dev/chunk-FXVS2QTZ.js.map +0 -7
- package/dist/dev/chunk-IFMURN5W.js.map +0 -7
- package/dist/prod/chunk-MSBJ7C4T.js +0 -12
- package/dist/prod/chunk-RFLYRLPI.js +0 -4
- package/dist/prod/locales/en-RQF5X6GM.js +0 -1
- package/dist/types/excalidraw/charts.d.ts +0 -27
- /package/dist/dev/data/{image-X6URJSP5.js.map → image-3J4DLBV6.js.map} +0 -0
- /package/dist/dev/locales/{en-ZZQASRYX.js.map → en-YPPLK6NW.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,87 @@ The change should be grouped under one of the below section and must contain PR
|
|
|
11
11
|
Please add the latest change on the top under the correct section.
|
|
12
12
|
-->
|
|
13
13
|
|
|
14
|
+
## Unreleased
|
|
15
|
+
|
|
16
|
+
## Excalidraw API
|
|
17
|
+
|
|
18
|
+
### Breaking changes
|
|
19
|
+
|
|
20
|
+
- Renamed the `excalidrawAPI` prop to `onExcalidrawAPI`.
|
|
21
|
+
- `onExcalidrawAPI` is now called on mount (instead of during constructor), and later on unmount (with `null` value). The API may be removed altogether in the future (you can use `onMount` & `onUmount` to manage the `ExcalidrawAPI` object (e.g. to cache it to a global state), already).
|
|
22
|
+
|
|
23
|
+
### Features
|
|
24
|
+
|
|
25
|
+
- Added `ExcalidrawAPI.isDestroyed` flag. Set to `true` once the editor unmounts. Calling any `get*` method, `onStateChange`, or `onEvent` on a destroyed API instance will throw in development and `console.error` in production. The `ExcalidrawAPI` will be reset to `null` on umount, but to be extra safe, you should check `ExcalidrawAPI.isDestroyed` before calling these methods to guard against subtle race conditions in your code.
|
|
26
|
+
|
|
27
|
+
- Added `onMount`, `onInitialize`, and `onUnmount` props. `onMount` receives `{ excalidrawAPI, container }` once the editor root is mounted. `onInitialize` fires once the initial scene has loaded. `onUnmount` fires just before unmounting.
|
|
28
|
+
|
|
29
|
+
- Same events are also accessible imperatively through `api.onEvent(...)`.
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
<Excalidraw
|
|
33
|
+
onExcalidrawAPI={(api) => {
|
|
34
|
+
api.onEvent("editor:mount", ({ excalidrawAPI, container }) => {
|
|
35
|
+
console.log(container);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
api.onEvent("editor:initialize").then((readyApi) => {
|
|
39
|
+
readyApi.scrollToContent();
|
|
40
|
+
});
|
|
41
|
+
}}
|
|
42
|
+
/>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Note that in future releases, most, if not all, `excalidrawAPI.on*` subscriptions will be removed in favor of `excalidrawAPI.onEvent(name)`.
|
|
46
|
+
|
|
47
|
+
- Also added `"editor:unmount"` lifecycle event, only accessible via `api.onEvent("editor:unmount")`.
|
|
48
|
+
|
|
49
|
+
- Exported `<ExcalidrawAPIProvider/>`, `useExcalidrawAPI()`, `useAppStateValue(prop | props | selectorFunction)`, and `useOnExcalidrawStateChange(prop | props | selectorFunction, callback)` from the package. The imperative API also now exposes `onStateChange(prop | props | selectorFunction, callback?)`, and `onEvent(name, callback)`.
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
<ExcalidrawAPIProvider>
|
|
53
|
+
<Excalidraw />
|
|
54
|
+
<Logger />
|
|
55
|
+
</ExcalidrawAPIProvider>;
|
|
56
|
+
|
|
57
|
+
function Logger() {
|
|
58
|
+
// initially null before the ExcalidrawAPIProvider initializes ater
|
|
59
|
+
// <Excalidraw/> renders
|
|
60
|
+
// When <Excalidraw/> unmounts, is reset back to null
|
|
61
|
+
const api = useExcalidrawAPI();
|
|
62
|
+
|
|
63
|
+
useAppStateValue("viewModeEnabled", (viewModeEnabled) => {
|
|
64
|
+
console.log("view mode changed:", viewModeEnabled);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
React.useEffect(() => {
|
|
68
|
+
if (api) {
|
|
69
|
+
console.log("editor instance id:", api.id);
|
|
70
|
+
}
|
|
71
|
+
}, [api]);
|
|
72
|
+
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
- Added `onExport` so host apps can delay JSON export until async work completes. The handler receives the export data plus an `AbortSignal`, and may return a `Promise` or an async generator that yields progress updates for the built-in toast UI.
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
<Excalidraw
|
|
81
|
+
onExport={async function* (_type, { files }, { signal }) {
|
|
82
|
+
yield { type: "progress", message: "Waiting for images..." };
|
|
83
|
+
|
|
84
|
+
await waitForImagesToLoad(files, signal);
|
|
85
|
+
|
|
86
|
+
if (signal.aborted) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
yield { type: "progress", message: "Export ready", progress: 1 };
|
|
91
|
+
}}
|
|
92
|
+
/>
|
|
93
|
+
```
|
|
94
|
+
|
|
14
95
|
## Excalidraw Library
|
|
15
96
|
|
|
16
97
|
## 0.18.0 (2025-03-11)
|
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Excalidraw
|
|
2
2
|
|
|
3
|
-
**Excalidraw** is exported as a component
|
|
3
|
+
**Excalidraw** is exported as a React component that you can embed directly in your app.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Install the package together with its React peer dependencies.
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
npm install react react-dom @excalidraw/excalidraw
|
|
@@ -12,34 +12,131 @@ npm install react react-dom @excalidraw/excalidraw
|
|
|
12
12
|
yarn add react react-dom @excalidraw/excalidraw
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
> **Note**: If you
|
|
15
|
+
> **Note**: If you want to try unreleased changes, use `@excalidraw/excalidraw@next`.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
## Quick start
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
The minimum working setup has two easy-to-miss requirements:
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
1. Import the package CSS:
|
|
22
22
|
|
|
23
|
-
```
|
|
24
|
-
|
|
23
|
+
```ts
|
|
24
|
+
import "@excalidraw/excalidraw/index.css";
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
2. Render Excalidraw inside a container with a non-zero height.
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
```tsx
|
|
30
|
+
import { Excalidraw } from "@excalidraw/excalidraw";
|
|
31
|
+
import "@excalidraw/excalidraw/index.css";
|
|
32
|
+
|
|
33
|
+
export default function App() {
|
|
34
|
+
return (
|
|
35
|
+
<div style={{ height: "100vh" }}>
|
|
36
|
+
<Excalidraw />
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Excalidraw fills `100%` of the width and height of its parent. If the parent has no height, the canvas will not be visible.
|
|
43
|
+
|
|
44
|
+
## Next.js / SSR frameworks
|
|
45
|
+
|
|
46
|
+
Excalidraw should be rendered on the client. In SSR frameworks such as Next.js, use a client component and load it dynamically with SSR disabled.
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
// app/components/ExcalidrawClient.tsx
|
|
50
|
+
"use client";
|
|
51
|
+
|
|
52
|
+
import { Excalidraw } from "@excalidraw/excalidraw";
|
|
53
|
+
import "@excalidraw/excalidraw/index.css";
|
|
54
|
+
|
|
55
|
+
export default function ExcalidrawClient() {
|
|
56
|
+
return (
|
|
57
|
+
<div style={{ height: "100vh" }}>
|
|
58
|
+
<Excalidraw />
|
|
59
|
+
</div>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
// app/page.tsx
|
|
66
|
+
import dynamic from "next/dynamic";
|
|
67
|
+
|
|
68
|
+
const ExcalidrawClient = dynamic(
|
|
69
|
+
() => import("./components/ExcalidrawClient"),
|
|
70
|
+
{ ssr: false },
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
export default function Page() {
|
|
74
|
+
return <ExcalidrawClient />;
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
See the local examples for complete setups:
|
|
79
|
+
|
|
80
|
+
- [examples/with-nextjs](https://github.com/excalidraw/excalidraw/tree/master/examples/with-nextjs)
|
|
81
|
+
- [examples/with-script-in-browser](https://github.com/excalidraw/excalidraw/tree/master/examples/with-script-in-browser)
|
|
82
|
+
|
|
83
|
+
## LLM / agent tips
|
|
84
|
+
|
|
85
|
+
If an LLM or coding agent is setting up Excalidraw, these shortcuts usually save more time than re-prompting:
|
|
86
|
+
|
|
87
|
+
- Start with a plain `<Excalidraw />` in a `100vh` container. Add refs, `initialData`, persistence, or custom UI only after the base embed works.
|
|
88
|
+
- If the canvas is blank, check the CSS import and parent height first. Those are the two most common integration failures.
|
|
89
|
+
- In Next.js or other SSR frameworks, assume client-only rendering first. Use `"use client"` and `dynamic(..., { ssr: false })` before debugging hydration or `window is not defined` errors.
|
|
90
|
+
- If imports or entrypoints are unclear, inspect `node_modules/@excalidraw/excalidraw/package.json`. The installed package exports are the source of truth.
|
|
91
|
+
- Do not set `window.EXCALIDRAW_ASSET_PATH` unless you are intentionally self-hosting fonts/assets.
|
|
92
|
+
- When docs and generated code drift, copy the nearest working example from this repo, especially `examples/with-nextjs` or `examples/with-script-in-browser`.
|
|
93
|
+
|
|
94
|
+
## Migrating to `@excalidraw/excalidraw@0.18.x`
|
|
95
|
+
|
|
96
|
+
Version `0.18.x` removes the old `types/`-prefixed deep import paths. If you were importing types from `@excalidraw/excalidraw/types/...`, switch to the new type-only subpaths below.
|
|
97
|
+
|
|
98
|
+
| Old path | New path |
|
|
99
|
+
| --- | --- |
|
|
100
|
+
| `@excalidraw/excalidraw/types/data/transform.js` | `@excalidraw/excalidraw/element/transform` |
|
|
101
|
+
| `@excalidraw/excalidraw/types/data/types.js` | `@excalidraw/excalidraw/data/types` |
|
|
102
|
+
| `@excalidraw/excalidraw/types/element/types.js` | `@excalidraw/excalidraw/element/types` |
|
|
103
|
+
| `@excalidraw/excalidraw/types/utility-types.js` | `@excalidraw/excalidraw/common/utility-types` |
|
|
104
|
+
| `@excalidraw/excalidraw/types/types.js` | `@excalidraw/excalidraw/types` |
|
|
105
|
+
|
|
106
|
+
Drop the `.js` extension. The new package `exports` map resolves these paths without it.
|
|
107
|
+
|
|
108
|
+
These deep subpaths are for `import type` only. Runtime imports should come from the package root, plus `@excalidraw/excalidraw/index.css` for styles.
|
|
109
|
+
|
|
110
|
+
For example:
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
import { exportToSvg } from "@excalidraw/excalidraw";
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Self-hosting fonts
|
|
117
|
+
|
|
118
|
+
By default, Excalidraw downloads the fonts it needs from the [CDN](https://esm.run/@excalidraw/excalidraw/dist/prod).
|
|
119
|
+
|
|
120
|
+
For self-hosting, copy the contents of `node_modules/@excalidraw/excalidraw/dist/prod/fonts` into the path where your app serves static assets, for example `public/`. Then set `window.EXCALIDRAW_ASSET_PATH` to that same path:
|
|
121
|
+
|
|
122
|
+
```html
|
|
123
|
+
<script>
|
|
124
|
+
window.EXCALIDRAW_ASSET_PATH = "/";
|
|
125
|
+
</script>
|
|
126
|
+
```
|
|
30
127
|
|
|
31
128
|
## Demo
|
|
32
129
|
|
|
33
|
-
|
|
130
|
+
Try the [CodeSandbox example](https://codesandbox.io/p/sandbox/github/excalidraw/excalidraw/tree/master/examples/with-script-in-browser).
|
|
34
131
|
|
|
35
132
|
## Integration
|
|
36
133
|
|
|
37
|
-
|
|
134
|
+
Read the [integration docs](https://docs.excalidraw.com/docs/@excalidraw/excalidraw/integration).
|
|
38
135
|
|
|
39
136
|
## API
|
|
40
137
|
|
|
41
|
-
|
|
138
|
+
Read the [API docs](https://docs.excalidraw.com/docs/@excalidraw/excalidraw/api).
|
|
42
139
|
|
|
43
140
|
## Contributing
|
|
44
141
|
|
|
45
|
-
|
|
142
|
+
Read the [contributing docs](https://docs.excalidraw.com/docs/@excalidraw/excalidraw/contributing).
|
|
@@ -41,7 +41,6 @@ var getDefaultAppState = () => {
|
|
|
41
41
|
showWelcomeScreen: false,
|
|
42
42
|
theme: THEME.LIGHT,
|
|
43
43
|
collaborators: /* @__PURE__ */ new Map(),
|
|
44
|
-
currentChartType: "bar",
|
|
45
44
|
currentItemBackgroundColor: DEFAULT_ELEMENT_PROPS.backgroundColor,
|
|
46
45
|
currentItemEndArrowhead: "arrow",
|
|
47
46
|
currentItemFillStyle: DEFAULT_ELEMENT_PROPS.fillStyle,
|
|
@@ -85,6 +84,8 @@ var getDefaultAppState = () => {
|
|
|
85
84
|
gridStep: DEFAULT_GRID_STEP,
|
|
86
85
|
gridModeEnabled: false,
|
|
87
86
|
isBindingEnabled: true,
|
|
87
|
+
bindingPreference: "enabled",
|
|
88
|
+
isMidpointSnappingEnabled: true,
|
|
88
89
|
defaultSidebarDockedPreference: false,
|
|
89
90
|
isLoading: false,
|
|
90
91
|
isResizing: false,
|
|
@@ -97,7 +98,6 @@ var getDefaultAppState = () => {
|
|
|
97
98
|
openPopup: null,
|
|
98
99
|
openSidebar: null,
|
|
99
100
|
openDialog: null,
|
|
100
|
-
pasteDialog: { shown: false, data: null },
|
|
101
101
|
previousSelectedElementIds: {},
|
|
102
102
|
resizingElement: null,
|
|
103
103
|
scrolledOutside: false,
|
|
@@ -148,7 +148,6 @@ var APP_STATE_STORAGE_CONF = /* @__PURE__ */ ((config) => config)({
|
|
|
148
148
|
showWelcomeScreen: { browser: true, export: false, server: false },
|
|
149
149
|
theme: { browser: true, export: false, server: false },
|
|
150
150
|
collaborators: { browser: false, export: false, server: false },
|
|
151
|
-
currentChartType: { browser: true, export: false, server: false },
|
|
152
151
|
currentItemBackgroundColor: { browser: true, export: false, server: false },
|
|
153
152
|
currentItemEndArrowhead: { browser: true, export: false, server: false },
|
|
154
153
|
currentItemFillStyle: { browser: true, export: false, server: false },
|
|
@@ -191,7 +190,9 @@ var APP_STATE_STORAGE_CONF = /* @__PURE__ */ ((config) => config)({
|
|
|
191
190
|
gridStep: { browser: true, export: true, server: true },
|
|
192
191
|
gridModeEnabled: { browser: true, export: true, server: true },
|
|
193
192
|
height: { browser: false, export: false, server: false },
|
|
194
|
-
isBindingEnabled: { browser:
|
|
193
|
+
isBindingEnabled: { browser: true, export: false, server: false },
|
|
194
|
+
bindingPreference: { browser: true, export: false, server: false },
|
|
195
|
+
isMidpointSnappingEnabled: { browser: true, export: false, server: false },
|
|
195
196
|
defaultSidebarDockedPreference: {
|
|
196
197
|
browser: true,
|
|
197
198
|
export: false,
|
|
@@ -210,7 +211,6 @@ var APP_STATE_STORAGE_CONF = /* @__PURE__ */ ((config) => config)({
|
|
|
210
211
|
openPopup: { browser: false, export: false, server: false },
|
|
211
212
|
openSidebar: { browser: true, export: false, server: false },
|
|
212
213
|
openDialog: { browser: false, export: false, server: false },
|
|
213
|
-
pasteDialog: { browser: false, export: false, server: false },
|
|
214
214
|
previousSelectedElementIds: { browser: true, export: false, server: false },
|
|
215
215
|
resizingElement: { browser: false, export: false, server: false },
|
|
216
216
|
scrolledOutside: { browser: true, export: false, server: false },
|
|
@@ -535,7 +535,6 @@ var decode = (data) => {
|
|
|
535
535
|
|
|
536
536
|
// data/json.ts
|
|
537
537
|
import {
|
|
538
|
-
DEFAULT_FILENAME,
|
|
539
538
|
EXPORT_DATA_TYPES,
|
|
540
539
|
getExportSource,
|
|
541
540
|
MIME_TYPES as MIME_TYPES2,
|
|
@@ -548,8 +547,7 @@ import {
|
|
|
548
547
|
fileSave as _fileSave,
|
|
549
548
|
supported as nativeFileSystemSupported
|
|
550
549
|
} from "browser-fs-access";
|
|
551
|
-
import {
|
|
552
|
-
var INPUT_CHANGE_INTERVAL_MS = 5e3;
|
|
550
|
+
import { MIME_TYPES } from "@excalidraw/common";
|
|
553
551
|
var fileOpen = async (opts) => {
|
|
554
552
|
const mimeTypes = opts.extensions?.reduce((mimeTypes2, type) => {
|
|
555
553
|
mimeTypes2.push(MIME_TYPES[type]);
|
|
@@ -565,39 +563,7 @@ var fileOpen = async (opts) => {
|
|
|
565
563
|
description: opts.description,
|
|
566
564
|
extensions,
|
|
567
565
|
mimeTypes,
|
|
568
|
-
multiple: opts.multiple ?? false
|
|
569
|
-
legacySetup: (resolve, reject, input) => {
|
|
570
|
-
const scheduleRejection = debounce(reject, INPUT_CHANGE_INTERVAL_MS);
|
|
571
|
-
const focusHandler = () => {
|
|
572
|
-
checkForFile();
|
|
573
|
-
document.addEventListener(EVENT.KEYUP, scheduleRejection);
|
|
574
|
-
document.addEventListener(EVENT.POINTER_UP, scheduleRejection);
|
|
575
|
-
scheduleRejection();
|
|
576
|
-
};
|
|
577
|
-
const checkForFile = () => {
|
|
578
|
-
if (input.files?.length) {
|
|
579
|
-
const ret = opts.multiple ? [...input.files] : input.files[0];
|
|
580
|
-
resolve(ret);
|
|
581
|
-
}
|
|
582
|
-
};
|
|
583
|
-
requestAnimationFrame(() => {
|
|
584
|
-
window.addEventListener(EVENT.FOCUS, focusHandler);
|
|
585
|
-
});
|
|
586
|
-
const interval = window.setInterval(() => {
|
|
587
|
-
checkForFile();
|
|
588
|
-
}, INPUT_CHANGE_INTERVAL_MS);
|
|
589
|
-
return (rejectPromise) => {
|
|
590
|
-
clearInterval(interval);
|
|
591
|
-
scheduleRejection.cancel();
|
|
592
|
-
window.removeEventListener(EVENT.FOCUS, focusHandler);
|
|
593
|
-
document.removeEventListener(EVENT.KEYUP, scheduleRejection);
|
|
594
|
-
document.removeEventListener(EVENT.POINTER_UP, scheduleRejection);
|
|
595
|
-
if (rejectPromise) {
|
|
596
|
-
console.warn("Opening the file was canceled (legacy-fs).");
|
|
597
|
-
rejectPromise(new AbortError());
|
|
598
|
-
}
|
|
599
|
-
};
|
|
600
|
-
}
|
|
566
|
+
multiple: opts.multiple ?? false
|
|
601
567
|
});
|
|
602
568
|
if (Array.isArray(files)) {
|
|
603
569
|
return await Promise.all(
|
|
@@ -615,7 +581,8 @@ var fileSave = (blob, opts) => {
|
|
|
615
581
|
extensions: [`.${opts.extension}`],
|
|
616
582
|
mimeTypes: opts.mimeTypes
|
|
617
583
|
},
|
|
618
|
-
opts.fileHandle
|
|
584
|
+
opts.fileHandle,
|
|
585
|
+
false
|
|
619
586
|
);
|
|
620
587
|
};
|
|
621
588
|
|
|
@@ -643,18 +610,24 @@ var serializeAsJSON = (elements, appState, files, type) => {
|
|
|
643
610
|
};
|
|
644
611
|
return JSON.stringify(data, null, 2);
|
|
645
612
|
};
|
|
646
|
-
var saveAsJSON = async (
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
613
|
+
var saveAsJSON = async ({
|
|
614
|
+
data,
|
|
615
|
+
filename,
|
|
616
|
+
fileHandle
|
|
617
|
+
}) => {
|
|
618
|
+
const blob = Promise.resolve(data).then(({ elements, appState, files }) => {
|
|
619
|
+
const serialized = serializeAsJSON(elements, appState, files, "local");
|
|
620
|
+
return new Blob([serialized], {
|
|
621
|
+
type: MIME_TYPES2.excalidraw
|
|
622
|
+
});
|
|
650
623
|
});
|
|
651
|
-
const
|
|
652
|
-
name,
|
|
624
|
+
const savedFileHandle = await fileSave(blob, {
|
|
625
|
+
name: filename,
|
|
653
626
|
extension: "excalidraw",
|
|
654
627
|
description: "Excalidraw file",
|
|
655
|
-
fileHandle: isImageFileHandle(
|
|
628
|
+
fileHandle: isImageFileHandle(fileHandle) ? null : fileHandle
|
|
656
629
|
});
|
|
657
|
-
return { fileHandle };
|
|
630
|
+
return { fileHandle: savedFileHandle };
|
|
658
631
|
};
|
|
659
632
|
var loadFromJSON = async (localAppState, localElements) => {
|
|
660
633
|
const file = await fileOpen({
|
|
@@ -778,7 +751,7 @@ import { promiseTry as promiseTry2, LOCAL_FONT_PROTOCOL as LOCAL_FONT_PROTOCOL2
|
|
|
778
751
|
import { isServerEnv, promiseTry } from "@excalidraw/common";
|
|
779
752
|
|
|
780
753
|
// workers.ts
|
|
781
|
-
import { debounce
|
|
754
|
+
import { debounce } from "@excalidraw/common";
|
|
782
755
|
var IdleWorker = class {
|
|
783
756
|
constructor(workerUrl) {
|
|
784
757
|
__publicField(this, "instance");
|
|
@@ -852,7 +825,7 @@ var WorkerPool = class _WorkerPool {
|
|
|
852
825
|
*/
|
|
853
826
|
async createWorker() {
|
|
854
827
|
const worker = new IdleWorker(this.workerUrl);
|
|
855
|
-
worker.debounceTerminate =
|
|
828
|
+
worker.debounceTerminate = debounce((reject) => {
|
|
856
829
|
worker.instance.terminate();
|
|
857
830
|
if (this.idleWorkers.has(worker)) {
|
|
858
831
|
this.idleWorkers.delete(worker);
|
|
@@ -3545,8 +3518,7 @@ var _renderStaticScene = ({
|
|
|
3545
3518
|
var renderStaticSceneThrottled = throttleRAF(
|
|
3546
3519
|
(config) => {
|
|
3547
3520
|
_renderStaticScene(config);
|
|
3548
|
-
}
|
|
3549
|
-
{ trailing: true }
|
|
3521
|
+
}
|
|
3550
3522
|
);
|
|
3551
3523
|
var renderStaticScene = (renderConfig, throttle) => {
|
|
3552
3524
|
if (throttle) {
|
|
@@ -4508,6 +4480,7 @@ import {
|
|
|
4508
4480
|
import {
|
|
4509
4481
|
calculateFixedPointForNonElbowArrowBinding,
|
|
4510
4482
|
getNonDeletedElements,
|
|
4483
|
+
normalizeArrowhead,
|
|
4511
4484
|
isPointInElement,
|
|
4512
4485
|
isValidPolygon,
|
|
4513
4486
|
projectFixedPointOntoDiagonal
|
|
@@ -4736,7 +4709,8 @@ var restoreElement = (element, targetElementsMap, existingElementsMap, opts) =>
|
|
|
4736
4709
|
});
|
|
4737
4710
|
case "line":
|
|
4738
4711
|
case "draw":
|
|
4739
|
-
const
|
|
4712
|
+
const startArrowhead = normalizeArrowhead(element.startArrowhead);
|
|
4713
|
+
const endArrowhead = normalizeArrowhead(element.endArrowhead);
|
|
4740
4714
|
let x = element.x;
|
|
4741
4715
|
let y = element.y;
|
|
4742
4716
|
let points = (
|
|
@@ -4761,7 +4735,8 @@ var restoreElement = (element, targetElementsMap, existingElementsMap, opts) =>
|
|
|
4761
4735
|
...getSizeFromPoints(points)
|
|
4762
4736
|
});
|
|
4763
4737
|
case "arrow": {
|
|
4764
|
-
const
|
|
4738
|
+
const startArrowhead2 = normalizeArrowhead(element.startArrowhead);
|
|
4739
|
+
const endArrowhead2 = element.endArrowhead === void 0 ? "arrow" : normalizeArrowhead(element.endArrowhead);
|
|
4765
4740
|
const x2 = element.x;
|
|
4766
4741
|
const y2 = element.y;
|
|
4767
4742
|
const points2 = (
|
|
@@ -5102,7 +5077,7 @@ var parseFileContents = async (blob) => {
|
|
|
5102
5077
|
let contents;
|
|
5103
5078
|
if (blob.type === MIME_TYPES6.png) {
|
|
5104
5079
|
try {
|
|
5105
|
-
return await (await import("./data/image-
|
|
5080
|
+
return await (await import("./data/image-3J4DLBV6.js")).decodePngMetadata(blob);
|
|
5106
5081
|
} catch (error) {
|
|
5107
5082
|
if (error.message === "INVALID") {
|
|
5108
5083
|
throw new ImageSceneDataError(
|
|
@@ -5536,4 +5511,4 @@ export {
|
|
|
5536
5511
|
createFile,
|
|
5537
5512
|
normalizeFile
|
|
5538
5513
|
};
|
|
5539
|
-
//# sourceMappingURL=chunk-
|
|
5514
|
+
//# sourceMappingURL=chunk-LWYHXCPK.js.map
|