@excalidraw/excalidraw 0.17.1-7441-4e2c539 → 0.17.1-a38e82f
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 +52 -2
- package/dist/browser/dev/excalidraw-assets-dev/chunk-5VWQDKDR.js +20279 -0
- package/dist/browser/dev/excalidraw-assets-dev/chunk-5VWQDKDR.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-2W5GQUR4.js → chunk-IM4WTX2M.js} +12 -6
- package/dist/browser/dev/excalidraw-assets-dev/chunk-IM4WTX2M.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{en-OC6JWP3X.js → en-IOBA4CS2.js} +4 -2
- package/dist/browser/dev/excalidraw-assets-dev/image-LK4UNFRZ.css +6 -0
- package/dist/browser/dev/excalidraw-assets-dev/image-LK4UNFRZ.css.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{image-HYNUJ3XL.js → image-VKDAL6BQ.js} +2 -4
- package/dist/browser/dev/excalidraw-assets-dev/roundRect-T5BX56ZF.js +161 -0
- package/dist/browser/dev/excalidraw-assets-dev/roundRect-T5BX56ZF.js.map +7 -0
- package/dist/browser/dev/index.css +189 -129
- package/dist/browser/dev/index.css.map +3 -3
- package/dist/browser/dev/index.js +34707 -26
- package/dist/browser/dev/index.js.map +4 -4
- package/dist/browser/prod/excalidraw-assets/chunk-LIG3S5TN.js +11 -0
- package/dist/browser/prod/excalidraw-assets/chunk-N2C5DK3B.js +55 -0
- package/dist/browser/prod/excalidraw-assets/en-WFZVQ7I6.js +1 -0
- package/dist/browser/prod/excalidraw-assets/image-4AT7LYMR.js +1 -0
- package/dist/browser/prod/excalidraw-assets/image-X66R2EM5.css +1 -0
- package/dist/browser/prod/excalidraw-assets/roundRect-2ACQK4DA.js +1 -0
- package/dist/browser/prod/index.css +1 -1
- package/dist/browser/prod/index.js +203 -1
- package/dist/{prod/en-RLIAOBCI.json → dev/en-TDNWCAOT.json} +9 -5
- package/dist/dev/index.css +189 -129
- package/dist/dev/index.css.map +3 -3
- package/dist/dev/index.js +38445 -39402
- package/dist/dev/index.js.map +4 -4
- package/dist/excalidraw/actions/actionAddToLibrary.d.ts +12 -12
- package/dist/excalidraw/actions/actionAlign.d.ts +6 -6
- package/dist/excalidraw/actions/actionAlign.js +2 -1
- package/dist/excalidraw/actions/actionBoundText.d.ts +8 -8
- package/dist/excalidraw/actions/actionBoundText.js +8 -8
- package/dist/excalidraw/actions/actionCanvas.d.ts +46 -46
- package/dist/excalidraw/actions/actionClipboard.d.ts +27 -27
- package/dist/excalidraw/actions/actionClipboard.js +9 -2
- package/dist/excalidraw/actions/actionDeleteSelected.d.ts +12 -12
- package/dist/excalidraw/actions/actionDeleteSelected.js +3 -2
- package/dist/excalidraw/actions/actionDistribute.d.ts +2 -2
- package/dist/excalidraw/actions/actionDistribute.js +1 -1
- package/dist/excalidraw/actions/actionDuplicateSelection.d.ts +1 -1
- package/dist/excalidraw/actions/actionDuplicateSelection.js +4 -3
- package/dist/excalidraw/actions/actionElementLock.d.ts +8 -8
- package/dist/excalidraw/actions/actionExport.d.ts +35 -35
- package/dist/excalidraw/actions/actionExport.js +4 -4
- package/dist/excalidraw/actions/actionFinalize.d.ts +7 -7
- package/dist/excalidraw/actions/actionFinalize.js +7 -6
- package/dist/excalidraw/actions/actionFlip.d.ts +2 -2
- package/dist/excalidraw/actions/actionFlip.js +11 -11
- package/dist/excalidraw/actions/actionFrame.d.ts +13 -13
- package/dist/excalidraw/actions/actionFrame.js +1 -1
- package/dist/excalidraw/actions/actionGroup.d.ts +8 -8
- package/dist/excalidraw/actions/actionGroup.js +3 -2
- package/dist/excalidraw/actions/actionLinearEditor.d.ts +4 -4
- package/dist/excalidraw/actions/actionLinearEditor.js +1 -1
- package/dist/excalidraw/{element/Hyperlink.d.ts → actions/actionLink.d.ts} +28 -50
- package/dist/excalidraw/actions/actionLink.js +40 -0
- package/dist/excalidraw/actions/actionMenu.d.ts +11 -11
- package/dist/excalidraw/actions/actionNavigate.d.ts +8 -8
- package/dist/excalidraw/actions/actionNavigate.js +1 -1
- package/dist/excalidraw/actions/actionProperties.d.ts +64 -64
- package/dist/excalidraw/actions/actionProperties.js +32 -27
- package/dist/excalidraw/actions/actionSelectAll.d.ts +4 -4
- package/dist/excalidraw/actions/actionSelectAll.js +1 -1
- package/dist/excalidraw/actions/actionStyles.d.ts +6 -6
- package/dist/excalidraw/actions/actionStyles.js +4 -4
- package/dist/excalidraw/actions/actionToggleGridMode.d.ts +4 -4
- package/dist/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +4 -4
- package/dist/excalidraw/actions/actionToggleStats.d.ts +4 -4
- package/dist/excalidraw/actions/actionToggleViewMode.d.ts +4 -4
- package/dist/excalidraw/actions/actionToggleZenMode.d.ts +4 -4
- package/dist/excalidraw/actions/index.d.ts +1 -1
- package/dist/excalidraw/actions/index.js +1 -1
- package/dist/excalidraw/actions/manager.js +2 -1
- package/dist/excalidraw/align.d.ts +2 -2
- package/dist/excalidraw/align.js +2 -2
- package/dist/excalidraw/animated-trail.d.ts +33 -0
- package/dist/excalidraw/animated-trail.js +96 -0
- package/dist/excalidraw/animation-frame-handler.d.ts +16 -0
- package/dist/excalidraw/animation-frame-handler.js +55 -0
- package/dist/excalidraw/appState.d.ts +1 -1
- package/dist/excalidraw/appState.js +1 -3
- package/dist/excalidraw/clipboard.js +5 -5
- package/dist/excalidraw/components/Actions.d.ts +3 -3
- package/dist/excalidraw/components/Actions.js +18 -7
- package/dist/excalidraw/components/App.d.ts +32 -17
- package/dist/excalidraw/components/App.js +474 -339
- package/dist/excalidraw/components/Button.d.ts +1 -1
- package/dist/excalidraw/components/FilledButton.d.ts +2 -2
- package/dist/excalidraw/components/FilledButton.js +27 -3
- package/dist/excalidraw/components/FollowMode/FollowMode.js +1 -1
- package/dist/excalidraw/components/ImageExportDialog.d.ts +2 -1
- package/dist/excalidraw/components/ImageExportDialog.js +16 -12
- package/dist/excalidraw/components/JSONExportDialog.js +1 -1
- package/dist/excalidraw/components/{LaserTool/LaserPointerButton.d.ts → LaserPointerButton.d.ts} +1 -1
- package/dist/excalidraw/components/{LaserTool/LaserPointerButton.js → LaserPointerButton.js} +2 -2
- package/dist/excalidraw/components/LayerUI.js +3 -3
- package/dist/excalidraw/components/MobileMenu.js +1 -1
- package/dist/excalidraw/components/ProjectName.d.ts +0 -1
- package/dist/excalidraw/components/ProjectName.js +1 -1
- package/dist/excalidraw/components/SVGLayer.d.ts +8 -0
- package/dist/excalidraw/components/SVGLayer.js +20 -0
- package/dist/excalidraw/components/ShareableLinkDialog.js +10 -10
- package/dist/excalidraw/components/Stack.d.ts +2 -2
- package/dist/excalidraw/components/TTDDialog/common.js +10 -1
- package/dist/excalidraw/components/TextField.d.ts +5 -2
- package/dist/excalidraw/components/TextField.js +6 -3
- package/dist/excalidraw/components/Toast.d.ts +3 -2
- package/dist/excalidraw/components/Toast.js +2 -2
- package/dist/excalidraw/components/ToolButton.js +2 -1
- package/dist/excalidraw/components/canvases/InteractiveCanvas.d.ts +2 -2
- package/dist/excalidraw/components/canvases/InteractiveCanvas.js +6 -5
- package/dist/excalidraw/components/canvases/StaticCanvas.d.ts +4 -3
- package/dist/excalidraw/components/canvases/StaticCanvas.js +7 -5
- package/dist/excalidraw/components/dropdownMenu/DropdownMenuContent.js +22 -2
- package/dist/excalidraw/components/dropdownMenu/common.d.ts +1 -1
- package/dist/excalidraw/components/hyperlink/Hyperlink.d.ts +19 -0
- package/dist/excalidraw/{element → components/hyperlink}/Hyperlink.js +40 -115
- package/dist/excalidraw/components/hyperlink/helpers.d.ts +7 -0
- package/dist/excalidraw/components/hyperlink/helpers.js +49 -0
- package/dist/excalidraw/components/icons.d.ts +2 -1
- package/dist/excalidraw/components/icons.js +2 -1
- package/dist/excalidraw/components/live-collaboration/LiveCollaborationTrigger.js +3 -2
- package/dist/excalidraw/components/main-menu/DefaultItems.js +5 -2
- package/dist/excalidraw/constants.d.ts +8 -0
- package/dist/excalidraw/constants.js +10 -0
- package/dist/excalidraw/data/blob.js +13 -14
- package/dist/excalidraw/data/filesystem.d.ts +1 -1
- package/dist/excalidraw/data/index.d.ts +2 -1
- package/dist/excalidraw/data/index.js +20 -16
- package/dist/excalidraw/data/json.d.ts +1 -1
- package/dist/excalidraw/data/json.js +5 -3
- package/dist/excalidraw/data/resave.d.ts +1 -1
- package/dist/excalidraw/data/resave.js +2 -2
- package/dist/excalidraw/data/restore.js +8 -13
- package/dist/excalidraw/data/transform.js +13 -9
- package/dist/excalidraw/distribute.d.ts +2 -2
- package/dist/excalidraw/distribute.js +2 -2
- package/dist/excalidraw/element/ElementCanvasButtons.d.ts +3 -2
- package/dist/excalidraw/element/ElementCanvasButtons.js +4 -4
- package/dist/excalidraw/element/binding.d.ts +9 -9
- package/dist/excalidraw/element/binding.js +61 -59
- package/dist/excalidraw/element/bounds.d.ts +5 -5
- package/dist/excalidraw/element/bounds.js +29 -32
- package/dist/excalidraw/element/collision.d.ts +11 -11
- package/dist/excalidraw/element/collision.js +49 -46
- package/dist/excalidraw/element/containerCache.d.ts +11 -0
- package/dist/excalidraw/element/containerCache.js +14 -0
- package/dist/excalidraw/element/dragElements.js +10 -19
- package/dist/excalidraw/element/embeddable.d.ts +11 -12
- package/dist/excalidraw/element/embeddable.js +17 -27
- package/dist/excalidraw/element/image.js +1 -2
- package/dist/excalidraw/element/index.d.ts +0 -1
- package/dist/excalidraw/element/index.js +0 -1
- package/dist/excalidraw/element/linearElementEditor.d.ts +35 -35
- package/dist/excalidraw/element/linearElementEditor.js +79 -80
- package/dist/excalidraw/element/newElement.d.ts +4 -6
- package/dist/excalidraw/element/newElement.js +11 -16
- package/dist/excalidraw/element/resizeElements.d.ts +6 -6
- package/dist/excalidraw/element/resizeElements.js +40 -46
- package/dist/excalidraw/element/resizeTest.d.ts +3 -3
- package/dist/excalidraw/element/resizeTest.js +4 -4
- package/dist/excalidraw/element/sizeHelpers.d.ts +2 -2
- package/dist/excalidraw/element/sizeHelpers.js +2 -2
- package/dist/excalidraw/element/textElement.d.ts +18 -20
- package/dist/excalidraw/element/textElement.js +80 -111
- package/dist/excalidraw/element/textWysiwyg.d.ts +1 -6
- package/dist/excalidraw/element/textWysiwyg.js +15 -37
- package/dist/excalidraw/element/transformHandles.d.ts +4 -4
- package/dist/excalidraw/element/transformHandles.js +6 -6
- package/dist/excalidraw/element/typeChecks.js +4 -1
- package/dist/excalidraw/element/types.d.ts +24 -11
- package/dist/excalidraw/emitter.d.ts +5 -9
- package/dist/excalidraw/emitter.js +12 -12
- package/dist/excalidraw/frame.d.ts +26 -20
- package/dist/excalidraw/frame.js +157 -84
- package/dist/excalidraw/groups.d.ts +3 -3
- package/dist/excalidraw/groups.js +11 -3
- package/dist/excalidraw/history.d.ts +1 -1
- package/dist/excalidraw/index.d.ts +7 -3
- package/dist/excalidraw/index.js +14 -5
- package/dist/excalidraw/laser-trails.d.ts +19 -0
- package/dist/excalidraw/laser-trails.js +95 -0
- package/dist/excalidraw/locales/en.json +9 -5
- package/dist/excalidraw/reactUtils.d.ts +14 -0
- package/dist/excalidraw/reactUtils.js +45 -0
- package/dist/excalidraw/renderer/helpers.d.ts +13 -0
- package/dist/excalidraw/renderer/helpers.js +39 -0
- package/dist/excalidraw/renderer/interactiveScene.d.ts +20 -0
- package/dist/excalidraw/renderer/{renderScene.js → interactiveScene.js} +199 -474
- package/dist/excalidraw/renderer/renderElement.d.ts +6 -6
- package/dist/excalidraw/renderer/renderElement.js +54 -366
- package/dist/excalidraw/renderer/staticScene.d.ts +11 -0
- package/dist/excalidraw/renderer/staticScene.js +205 -0
- package/dist/excalidraw/renderer/staticSvgScene.d.ts +5 -0
- package/dist/excalidraw/renderer/staticSvgScene.js +385 -0
- package/dist/excalidraw/scene/Fonts.js +2 -1
- package/dist/excalidraw/scene/Renderer.d.ts +1 -1
- package/dist/excalidraw/scene/Renderer.js +32 -20
- package/dist/excalidraw/scene/Scene.d.ts +10 -9
- package/dist/excalidraw/scene/Scene.js +45 -21
- package/dist/excalidraw/scene/Shape.d.ts +3 -1
- package/dist/excalidraw/scene/Shape.js +7 -5
- package/dist/excalidraw/scene/ShapeCache.d.ts +2 -1
- package/dist/excalidraw/scene/ShapeCache.js +1 -0
- package/dist/excalidraw/scene/comparisons.js +2 -1
- package/dist/excalidraw/scene/export.d.ts +3 -0
- package/dist/excalidraw/scene/export.js +20 -40
- package/dist/excalidraw/scene/index.d.ts +0 -1
- package/dist/excalidraw/scene/index.js +0 -1
- package/dist/excalidraw/scene/scrollbars.d.ts +1 -1
- package/dist/excalidraw/scene/scrollbars.js +1 -1
- package/dist/excalidraw/scene/selection.d.ts +5 -5
- package/dist/excalidraw/scene/selection.js +16 -14
- package/dist/excalidraw/scene/types.d.ts +11 -5
- package/dist/excalidraw/snapping.d.ts +7 -7
- package/dist/excalidraw/snapping.js +21 -20
- package/dist/excalidraw/types.d.ts +11 -12
- package/dist/excalidraw/utility-types.d.ts +5 -0
- package/dist/excalidraw/utils.d.ts +25 -16
- package/dist/excalidraw/utils.js +52 -45
- package/dist/{dev/en-RLIAOBCI.json → prod/en-TDNWCAOT.json} +9 -5
- package/dist/prod/index.css +1 -1
- package/dist/prod/index.js +45 -45
- package/dist/utils/export.d.ts +0 -6
- package/dist/utils/export.js +0 -6
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/withinBounds.js +2 -1
- package/package.json +4 -4
- package/dist/browser/dev/excalidraw-assets-dev/chunk-2W5GQUR4.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/chunk-SUHLFFEF.js +0 -53449
- package/dist/browser/dev/excalidraw-assets-dev/chunk-SUHLFFEF.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/image-NOPDRTTM.css +0 -5797
- package/dist/browser/dev/excalidraw-assets-dev/image-NOPDRTTM.css.map +0 -7
- package/dist/browser/prod/excalidraw-assets/chunk-HE2P7BQ6.js +0 -257
- package/dist/browser/prod/excalidraw-assets/chunk-OWLL6VOG.js +0 -11
- package/dist/browser/prod/excalidraw-assets/en-ERQOR3OC.js +0 -1
- package/dist/browser/prod/excalidraw-assets/image-DZ6B4AID.js +0 -1
- package/dist/browser/prod/excalidraw-assets/image-J2QCCYAR.css +0 -1
- package/dist/excalidraw/components/LaserTool/LaserPathManager.d.ts +0 -28
- package/dist/excalidraw/components/LaserTool/LaserPathManager.js +0 -225
- package/dist/excalidraw/components/LaserTool/LaserTool.d.ts +0 -8
- package/dist/excalidraw/components/LaserTool/LaserTool.js +0 -15
- package/dist/excalidraw/renderer/renderScene.d.ts +0 -25
- package/dist/excalidraw/vite.config.d.mts +0 -2
- package/dist/excalidraw/vite.config.mjs +0 -13
- /package/dist/browser/dev/excalidraw-assets-dev/{en-OC6JWP3X.js.map → en-IOBA4CS2.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{image-HYNUJ3XL.js.map → image-VKDAL6BQ.js.map} +0 -0
|
@@ -6,12 +6,12 @@ export type ButtonSize = "medium" | "large";
|
|
|
6
6
|
export type FilledButtonProps = {
|
|
7
7
|
label: string;
|
|
8
8
|
children?: React.ReactNode;
|
|
9
|
-
onClick?: () => void;
|
|
9
|
+
onClick?: (event: React.MouseEvent) => void;
|
|
10
10
|
variant?: ButtonVariant;
|
|
11
11
|
color?: ButtonColor;
|
|
12
12
|
size?: ButtonSize;
|
|
13
13
|
className?: string;
|
|
14
14
|
fullWidth?: boolean;
|
|
15
|
-
|
|
15
|
+
icon?: React.ReactNode;
|
|
16
16
|
};
|
|
17
17
|
export declare const FilledButton: React.ForwardRefExoticComponent<FilledButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -1,7 +1,31 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef } from "react";
|
|
2
|
+
import { forwardRef, useState } from "react";
|
|
3
3
|
import clsx from "clsx";
|
|
4
4
|
import "./FilledButton.scss";
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
import { AbortError } from "../errors";
|
|
6
|
+
import Spinner from "./Spinner";
|
|
7
|
+
import { isPromiseLike } from "../utils";
|
|
8
|
+
export const FilledButton = forwardRef(({ children, icon, onClick, label, variant = "filled", color = "primary", size = "medium", fullWidth, className, }, ref) => {
|
|
9
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
10
|
+
const _onClick = async (event) => {
|
|
11
|
+
const ret = onClick?.(event);
|
|
12
|
+
if (isPromiseLike(ret)) {
|
|
13
|
+
try {
|
|
14
|
+
setIsLoading(true);
|
|
15
|
+
await ret;
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
if (!(error instanceof AbortError)) {
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
console.warn(error);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
finally {
|
|
26
|
+
setIsLoading(false);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
return (_jsx("button", { className: clsx("ExcButton", `ExcButton--color-${color}`, `ExcButton--variant-${variant}`, `ExcButton--size-${size}`, { "ExcButton--fullWidth": fullWidth }, className), onClick: _onClick, type: "button", "aria-label": label, ref: ref, disabled: isLoading, children: _jsxs("div", { className: "ExcButton__contents", children: [isLoading && _jsx(Spinner, {}), icon && (_jsx("div", { className: "ExcButton__icon", "aria-hidden": true, children: icon })), variant !== "icon" && (children ?? label)] }) }));
|
|
7
31
|
});
|
|
@@ -2,6 +2,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { CloseIcon } from "../icons";
|
|
3
3
|
import "./FollowMode.scss";
|
|
4
4
|
const FollowMode = ({ height, width, userToFollow, onDisconnect, }) => {
|
|
5
|
-
return (_jsx("div", {
|
|
5
|
+
return (_jsx("div", { className: "follow-mode", style: { width, height }, children: _jsxs("div", { className: "follow-mode__badge", children: [_jsxs("div", { className: "follow-mode__badge__label", children: ["Following", " ", _jsx("span", { className: "follow-mode__badge__username", title: userToFollow.username, children: userToFollow.username })] }), _jsx("button", { onClick: onDisconnect, className: "follow-mode__disconnect-btn", children: CloseIcon })] }) }));
|
|
6
6
|
};
|
|
7
7
|
export default FollowMode;
|
|
@@ -4,11 +4,12 @@ import type { AppClassProperties, BinaryFiles, UIAppState } from "../types";
|
|
|
4
4
|
import { NonDeletedExcalidrawElement } from "../element/types";
|
|
5
5
|
import "./ImageExportDialog.scss";
|
|
6
6
|
export declare const ErrorCanvasPreview: () => JSX.Element;
|
|
7
|
-
export declare const ImageExportDialog: ({ elements, appState, files, actionManager, onExportImage, onCloseRequest, }: {
|
|
7
|
+
export declare const ImageExportDialog: ({ elements, appState, files, actionManager, onExportImage, onCloseRequest, name, }: {
|
|
8
8
|
appState: UIAppState;
|
|
9
9
|
elements: readonly NonDeletedExcalidrawElement[];
|
|
10
10
|
files: BinaryFiles;
|
|
11
11
|
actionManager: ActionManager;
|
|
12
12
|
onExportImage: AppClassProperties["onExportImage"];
|
|
13
13
|
onCloseRequest: () => void;
|
|
14
|
+
name: string;
|
|
14
15
|
}) => JSX.Element;
|
|
@@ -14,7 +14,6 @@ import { RadioGroup } from "./RadioGroup";
|
|
|
14
14
|
import { Switch } from "./Switch";
|
|
15
15
|
import { Tooltip } from "./Tooltip";
|
|
16
16
|
import "./ImageExportDialog.scss";
|
|
17
|
-
import { useAppProps } from "./App";
|
|
18
17
|
import { FilledButton } from "./FilledButton";
|
|
19
18
|
import { cloneJSON } from "../utils";
|
|
20
19
|
import { prepareElementsForExport } from "../data";
|
|
@@ -22,10 +21,9 @@ const supportsContextFilters = "filter" in document.createElement("canvas").getC
|
|
|
22
21
|
export const ErrorCanvasPreview = () => {
|
|
23
22
|
return (_jsxs("div", { children: [_jsx("h3", { children: t("canvasError.cannotShowPreview") }), _jsx("p", { children: _jsx("span", { children: t("canvasError.canvasTooBig") }) }), _jsxs("em", { children: ["(", t("canvasError.canvasTooBigTip"), ")"] })] }));
|
|
24
23
|
};
|
|
25
|
-
const ImageExportModal = ({ appStateSnapshot, elementsSnapshot, files, actionManager, onExportImage, }) => {
|
|
24
|
+
const ImageExportModal = ({ appStateSnapshot, elementsSnapshot, files, actionManager, onExportImage, name, }) => {
|
|
26
25
|
const hasSelection = isSomeElementSelected(elementsSnapshot, appStateSnapshot);
|
|
27
|
-
const
|
|
28
|
-
const [projectName, setProjectName] = useState(appStateSnapshot.name);
|
|
26
|
+
const [projectName, setProjectName] = useState(name);
|
|
29
27
|
const [exportSelectionOnly, setExportSelectionOnly] = useState(hasSelection);
|
|
30
28
|
const [exportWithBackground, setExportWithBackground] = useState(appStateSnapshot.exportBackground);
|
|
31
29
|
const [exportDarkMode, setExportDarkMode] = useState(appStateSnapshot.exportWithDarkMode);
|
|
@@ -63,8 +61,15 @@ const ImageExportModal = ({ appStateSnapshot, elementsSnapshot, files, actionMan
|
|
|
63
61
|
setRenderError(null);
|
|
64
62
|
// if converting to blob fails, there's some problem that will
|
|
65
63
|
// likely prevent preview and export (e.g. canvas too big)
|
|
66
|
-
return canvasToBlob(canvas)
|
|
64
|
+
return canvasToBlob(canvas)
|
|
65
|
+
.then(() => {
|
|
67
66
|
previewNode.replaceChildren(canvas);
|
|
67
|
+
})
|
|
68
|
+
.catch((e) => {
|
|
69
|
+
if (e.name === "CANVAS_POSSIBLY_TOO_BIG") {
|
|
70
|
+
throw new Error(t("canvasError.canvasTooBig"));
|
|
71
|
+
}
|
|
72
|
+
throw e;
|
|
68
73
|
});
|
|
69
74
|
})
|
|
70
75
|
.catch((error) => {
|
|
@@ -82,8 +87,7 @@ const ImageExportModal = ({ appStateSnapshot, elementsSnapshot, files, actionMan
|
|
|
82
87
|
exportScale,
|
|
83
88
|
embedScene,
|
|
84
89
|
]);
|
|
85
|
-
return (_jsxs("div", { className: "ImageExportModal", children: [_jsx("h3", { children: t("imageExportDialog.header") }), _jsxs("div", { className: "ImageExportModal__preview", children: [_jsx("div", { className: "ImageExportModal__preview__canvas", ref: previewRef, children: renderError && _jsx(ErrorCanvasPreview, {}) }), _jsx("div", { className: "ImageExportModal__preview__filename", children: !nativeFileSystemSupported && (_jsx("input", { type: "text", className: "TextInput", value: projectName, style: { width: "30ch" },
|
|
86
|
-
appStateSnapshot.viewModeEnabled, onChange: (event) => {
|
|
90
|
+
return (_jsxs("div", { className: "ImageExportModal", children: [_jsx("h3", { children: t("imageExportDialog.header") }), _jsxs("div", { className: "ImageExportModal__preview", children: [_jsx("div", { className: "ImageExportModal__preview__canvas", ref: previewRef, children: renderError && _jsx(ErrorCanvasPreview, {}) }), _jsx("div", { className: "ImageExportModal__preview__filename", children: !nativeFileSystemSupported && (_jsx("input", { type: "text", className: "TextInput", value: projectName, style: { width: "30ch" }, onChange: (event) => {
|
|
87
91
|
setProjectName(event.target.value);
|
|
88
92
|
actionManager.executeAction(actionChangeProjectName, "ui", event.target.value);
|
|
89
93
|
} })) })] }), _jsxs("div", { className: "ImageExportModal__settings", children: [_jsx("h3", { children: t("imageExportDialog.header") }), hasSelection && (_jsx(ExportSetting, { label: t("imageExportDialog.label.onlySelected"), name: "exportOnlySelected", children: _jsx(Switch, { name: "exportOnlySelected", checked: exportSelectionOnly, onChange: (checked) => {
|
|
@@ -105,16 +109,16 @@ const ImageExportModal = ({ appStateSnapshot, elementsSnapshot, files, actionMan
|
|
|
105
109
|
label: `${scale}\u00d7`,
|
|
106
110
|
})) }) }), _jsxs("div", { className: "ImageExportModal__settings__buttons", children: [_jsx(FilledButton, { className: "ImageExportModal__settings__buttons__button", label: t("imageExportDialog.title.exportToPng"), onClick: () => onExportImage(EXPORT_IMAGE_TYPES.png, exportedElements, {
|
|
107
111
|
exportingFrame,
|
|
108
|
-
}),
|
|
112
|
+
}), icon: downloadIcon, children: t("imageExportDialog.button.exportToPng") }), _jsx(FilledButton, { className: "ImageExportModal__settings__buttons__button", label: t("imageExportDialog.title.exportToSvg"), onClick: () => onExportImage(EXPORT_IMAGE_TYPES.svg, exportedElements, {
|
|
109
113
|
exportingFrame,
|
|
110
|
-
}),
|
|
114
|
+
}), icon: downloadIcon, children: t("imageExportDialog.button.exportToSvg") }), (probablySupportsClipboardBlob || isFirefox) && (_jsx(FilledButton, { className: "ImageExportModal__settings__buttons__button", label: t("imageExportDialog.title.copyPngToClipboard"), onClick: () => onExportImage(EXPORT_IMAGE_TYPES.clipboard, exportedElements, {
|
|
111
115
|
exportingFrame,
|
|
112
|
-
}),
|
|
116
|
+
}), icon: copyIcon, children: t("imageExportDialog.button.copyPngToClipboard") }))] })] })] }));
|
|
113
117
|
};
|
|
114
118
|
const ExportSetting = ({ label, children, tooltip, name, }) => {
|
|
115
119
|
return (_jsxs("div", { className: "ImageExportModal__settings__setting", title: label, children: [_jsxs("label", { htmlFor: name, className: "ImageExportModal__settings__setting__label", children: [label, tooltip && (_jsx(Tooltip, { label: tooltip, long: true, children: helpIcon }))] }), _jsx("div", { className: "ImageExportModal__settings__setting__content", children: children })] }));
|
|
116
120
|
};
|
|
117
|
-
export const ImageExportDialog = ({ elements, appState, files, actionManager, onExportImage, onCloseRequest, }) => {
|
|
121
|
+
export const ImageExportDialog = ({ elements, appState, files, actionManager, onExportImage, onCloseRequest, name, }) => {
|
|
118
122
|
// we need to take a snapshot so that the exported state can't be modified
|
|
119
123
|
// while the dialog is open
|
|
120
124
|
const [{ appStateSnapshot, elementsSnapshot }] = useState(() => {
|
|
@@ -123,5 +127,5 @@ export const ImageExportDialog = ({ elements, appState, files, actionManager, on
|
|
|
123
127
|
elementsSnapshot: cloneJSON(elements),
|
|
124
128
|
};
|
|
125
129
|
});
|
|
126
|
-
return (_jsx(Dialog, { onCloseRequest: onCloseRequest, size: "wide", title: false, children: _jsx(ImageExportModal, { elementsSnapshot: elementsSnapshot, appStateSnapshot: appStateSnapshot, files: files, actionManager: actionManager, onExportImage: onExportImage }) }));
|
|
130
|
+
return (_jsx(Dialog, { onCloseRequest: onCloseRequest, size: "wide", title: false, children: _jsx(ImageExportModal, { elementsSnapshot: elementsSnapshot, appStateSnapshot: appStateSnapshot, files: files, actionManager: actionManager, onExportImage: onExportImage, name: name }) }));
|
|
127
131
|
};
|
|
@@ -18,7 +18,7 @@ const JSONExportModal = ({ elements, appState, setAppState, files, actionManager
|
|
|
18
18
|
} })] })), onExportToBackend && (_jsxs(Card, { color: "pink", children: [_jsx("div", { className: "Card-icon", children: LinkIcon }), _jsx("h2", { children: t("exportDialog.link_title") }), _jsx("div", { className: "Card-details", children: t("exportDialog.link_details") }), _jsx(ToolButton, { className: "Card-button", type: "button", title: t("exportDialog.link_button"), "aria-label": t("exportDialog.link_button"), showAriaLabel: true, onClick: async () => {
|
|
19
19
|
try {
|
|
20
20
|
trackEvent("export", "link", `ui (${getFrame()})`);
|
|
21
|
-
await onExportToBackend(elements, appState, files
|
|
21
|
+
await onExportToBackend(elements, appState, files);
|
|
22
22
|
onCloseRequest();
|
|
23
23
|
}
|
|
24
24
|
catch (error) {
|
package/dist/excalidraw/components/{LaserTool/LaserPointerButton.js → LaserPointerButton.js}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import "
|
|
2
|
+
import "./ToolIcon.scss";
|
|
3
3
|
import clsx from "clsx";
|
|
4
|
-
import { laserPointerToolIcon } from "
|
|
4
|
+
import { laserPointerToolIcon } from "./icons";
|
|
5
5
|
const DEFAULT_SIZE = "small";
|
|
6
6
|
export const LaserPointerButton = (props) => {
|
|
7
7
|
return (_jsxs("label", { className: clsx("ToolIcon ToolIcon__LaserPointer", `ToolIcon_size_${DEFAULT_SIZE}`, {
|
|
@@ -45,7 +45,7 @@ import "./Toolbar.scss";
|
|
|
45
45
|
import { mutateElement } from "../element/mutateElement";
|
|
46
46
|
import { ShapeCache } from "../scene/ShapeCache";
|
|
47
47
|
import Scene from "../scene/Scene";
|
|
48
|
-
import { LaserPointerButton } from "./
|
|
48
|
+
import { LaserPointerButton } from "./LaserPointerButton";
|
|
49
49
|
import { MagicSettings } from "./MagicSettings";
|
|
50
50
|
import { TTDDialog } from "./TTDDialog/TTDDialog";
|
|
51
51
|
const DefaultMainMenu = ({ UIOptions }) => {
|
|
@@ -69,7 +69,7 @@ const LayerUI = ({ actionManager, appState, files, setAppState, elements, canvas
|
|
|
69
69
|
appState.openDialog?.name !== "imageExport") {
|
|
70
70
|
return null;
|
|
71
71
|
}
|
|
72
|
-
return (_jsx(ImageExportDialog, { elements: elements, appState: appState, files: files, actionManager: actionManager, onExportImage: onExportImage, onCloseRequest: () => setAppState({ openDialog: null }) }));
|
|
72
|
+
return (_jsx(ImageExportDialog, { elements: elements, appState: appState, files: files, actionManager: actionManager, onExportImage: onExportImage, onCloseRequest: () => setAppState({ openDialog: null }), name: app.getName() }));
|
|
73
73
|
};
|
|
74
74
|
const renderCanvasActions = () => (_jsxs("div", { style: { position: "relative" }, children: [_jsx(tunnels.MainMenuTunnel.Out, {}), renderWelcomeScreen && _jsx(tunnels.WelcomeScreenMenuHintTunnel.Out, {})] }));
|
|
75
75
|
const renderSelectedShapeActions = () => (_jsx(Section, { heading: "selectedShapeActions", className: clsx("selected-shape-actions zen-mode-transition", {
|
|
@@ -78,7 +78,7 @@ const LayerUI = ({ actionManager, appState, files, setAppState, elements, canvas
|
|
|
78
78
|
// we want to make sure this doesn't overflow so subtracting the
|
|
79
79
|
// approximate height of hamburgerMenu + footer
|
|
80
80
|
maxHeight: `${appState.height - 166}px`,
|
|
81
|
-
}, children: _jsx(SelectedShapeActions, { appState: appState,
|
|
81
|
+
}, children: _jsx(SelectedShapeActions, { appState: appState, elementsMap: app.scene.getNonDeletedElementsMap(), renderAction: actionManager.renderAction }) }) }));
|
|
82
82
|
const renderFixedSideContainer = () => {
|
|
83
83
|
const shouldRenderSelectedShapeActions = showSelectedShapeActions(appState, elements);
|
|
84
84
|
return (_jsx(FixedSideContainer, { side: "top", children: _jsxs("div", { className: "App-menu App-menu_top", children: [_jsxs(Stack.Col, { gap: 6, className: clsx("App-menu_top__left"), children: [renderCanvasActions(), shouldRenderSelectedShapeActions && renderSelectedShapeActions()] }), !appState.viewModeEnabled && (_jsx(Section, { heading: "shapes", className: "shapes-section", children: (heading) => (_jsxs("div", { style: { position: "relative" }, children: [renderWelcomeScreen && (_jsx(tunnels.WelcomeScreenToolbarHintTunnel.Out, {})), _jsx(Stack.Col, { gap: 4, align: "start", children: _jsxs(Stack.Row, { gap: 1, className: clsx("App-toolbar-container", {
|
|
@@ -35,7 +35,7 @@ export const MobileMenu = ({ appState, elements, actionManager, setAppState, onL
|
|
|
35
35
|
marginRight: SCROLLBAR_WIDTH + SCROLLBAR_MARGIN * 2,
|
|
36
36
|
}, children: _jsxs(Island, { padding: 0, children: [appState.openMenu === "shape" &&
|
|
37
37
|
!appState.viewModeEnabled &&
|
|
38
|
-
showSelectedShapeActions(appState, elements) ? (_jsx(Section, { className: "App-mobile-menu", heading: "selectedShapeActions", children: _jsx(SelectedShapeActions, { appState: appState,
|
|
38
|
+
showSelectedShapeActions(appState, elements) ? (_jsx(Section, { className: "App-mobile-menu", heading: "selectedShapeActions", children: _jsx(SelectedShapeActions, { appState: appState, elementsMap: app.scene.getNonDeletedElementsMap(), renderAction: actionManager.renderAction }) })) : null, _jsxs("footer", { className: "App-toolbar", children: [renderAppToolbar(), appState.scrolledOutside &&
|
|
39
39
|
!appState.openMenu &&
|
|
40
40
|
!appState.openSidebar && (_jsx("button", { className: "scroll-back-to-content", onClick: () => {
|
|
41
41
|
setAppState((appState) => ({
|
|
@@ -26,5 +26,5 @@ export const ProjectName = (props) => {
|
|
|
26
26
|
event.currentTarget.blur();
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
|
-
return (_jsxs("div", { className: "ProjectName", children: [_jsx("label", { className: "ProjectName-label", htmlFor: "filename", children: `${props.label}
|
|
29
|
+
return (_jsxs("div", { className: "ProjectName", children: [_jsx("label", { className: "ProjectName-label", htmlFor: "filename", children: `${props.label}:` }), _jsx("input", { type: "text", className: "TextInput", onBlur: handleBlur, onKeyDown: handleKeyDown, id: `${id}-filename`, value: fileName, onChange: (event) => setFileName(event.target.value) })] }));
|
|
30
30
|
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef } from "react";
|
|
3
|
+
import "./SVGLayer.scss";
|
|
4
|
+
export const SVGLayer = ({ trails }) => {
|
|
5
|
+
const svgRef = useRef(null);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (svgRef.current) {
|
|
8
|
+
for (const trail of trails) {
|
|
9
|
+
trail.start(svgRef.current);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return () => {
|
|
13
|
+
for (const trail of trails) {
|
|
14
|
+
trail.stop();
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
18
|
+
}, trails);
|
|
19
|
+
return (_jsx("div", { className: "SVGLayer", children: _jsx("svg", { ref: svgRef }) }));
|
|
20
|
+
};
|
|
@@ -16,18 +16,18 @@ export const ShareableLinkDialog = ({ link, onCloseRequest, setErrorMessage, })
|
|
|
16
16
|
const copyRoomLink = async () => {
|
|
17
17
|
try {
|
|
18
18
|
await copyTextToSystemClipboard(link);
|
|
19
|
-
setJustCopied(true);
|
|
20
|
-
if (timerRef.current) {
|
|
21
|
-
window.clearTimeout(timerRef.current);
|
|
22
|
-
}
|
|
23
|
-
timerRef.current = window.setTimeout(() => {
|
|
24
|
-
setJustCopied(false);
|
|
25
|
-
}, 3000);
|
|
26
19
|
}
|
|
27
|
-
catch (
|
|
28
|
-
setErrorMessage(
|
|
20
|
+
catch (e) {
|
|
21
|
+
setErrorMessage(t("errors.copyToSystemClipboardFailed"));
|
|
29
22
|
}
|
|
23
|
+
setJustCopied(true);
|
|
24
|
+
if (timerRef.current) {
|
|
25
|
+
window.clearTimeout(timerRef.current);
|
|
26
|
+
}
|
|
27
|
+
timerRef.current = window.setTimeout(() => {
|
|
28
|
+
setJustCopied(false);
|
|
29
|
+
}, 3000);
|
|
30
30
|
ref.current?.select();
|
|
31
31
|
};
|
|
32
|
-
return (_jsx(Dialog, { onCloseRequest: onCloseRequest, title: false, size: "small", children: _jsxs("div", { className: "ShareableLinkDialog", children: [_jsx("h3", { children: "Shareable link" }), _jsxs("div", { className: "ShareableLinkDialog__linkRow", children: [_jsx(TextField, { ref: ref, label: "Link", readonly: true, fullWidth: true, value: link, selectOnRender: true }), _jsxs(Popover.Root, { open: justCopied, children: [_jsx(Popover.Trigger, { asChild: true, children: _jsx(FilledButton, { size: "large", label: "Copy link",
|
|
32
|
+
return (_jsx(Dialog, { onCloseRequest: onCloseRequest, title: false, size: "small", children: _jsxs("div", { className: "ShareableLinkDialog", children: [_jsx("h3", { children: "Shareable link" }), _jsxs("div", { className: "ShareableLinkDialog__linkRow", children: [_jsx(TextField, { ref: ref, label: "Link", readonly: true, fullWidth: true, value: link, selectOnRender: true }), _jsxs(Popover.Root, { open: justCopied, children: [_jsx(Popover.Trigger, { asChild: true, children: _jsx(FilledButton, { size: "large", label: "Copy link", icon: copyIcon, onClick: copyRoomLink }) }), _jsxs(Popover.Content, { onOpenAutoFocus: (event) => event.preventDefault(), onCloseAutoFocus: (event) => event.preventDefault(), className: "ShareableLinkDialog__popover", side: "top", align: "end", sideOffset: 5.5, children: [tablerCheckIcon, " copied"] })] })] }), _jsxs("div", { className: "ShareableLinkDialog__description", children: ["\uD83D\uDD12 ", t("alerts.uploadedSecurly")] })] }) }));
|
|
33
33
|
};
|
|
@@ -10,7 +10,7 @@ type StackProps = {
|
|
|
10
10
|
ref: React.RefObject<HTMLDivElement>;
|
|
11
11
|
};
|
|
12
12
|
declare const _default: {
|
|
13
|
-
Row: React.ForwardRefExoticComponent<Pick<StackProps, "children" | "style" | "
|
|
14
|
-
Col: React.ForwardRefExoticComponent<Pick<StackProps, "children" | "style" | "
|
|
13
|
+
Row: React.ForwardRefExoticComponent<Pick<StackProps, "children" | "style" | "gap" | "className" | "align" | "justifyContent"> & React.RefAttributes<HTMLDivElement>>;
|
|
14
|
+
Col: React.ForwardRefExoticComponent<Pick<StackProps, "children" | "style" | "gap" | "className" | "align" | "justifyContent"> & React.RefAttributes<HTMLDivElement>>;
|
|
15
15
|
};
|
|
16
16
|
export default _default;
|
|
@@ -2,6 +2,7 @@ import { DEFAULT_EXPORT_PADDING, DEFAULT_FONT_SIZE, EDITOR_LS_KEYS, } from "../.
|
|
|
2
2
|
import { convertToExcalidrawElements, exportToCanvas } from "../../index";
|
|
3
3
|
import { canvasToBlob } from "../../data/blob";
|
|
4
4
|
import { EditorLocalStorage } from "../../data/EditorLocalStorage";
|
|
5
|
+
import { t } from "../../i18n";
|
|
5
6
|
const resetPreview = ({ canvasRef, setError, }) => {
|
|
6
7
|
const canvasNode = canvasRef.current;
|
|
7
8
|
if (!canvasNode) {
|
|
@@ -55,7 +56,15 @@ export const convertMermaidToExcalidraw = async ({ canvasRef, mermaidToExcalidra
|
|
|
55
56
|
});
|
|
56
57
|
// if converting to blob fails, there's some problem that will
|
|
57
58
|
// likely prevent preview and export (e.g. canvas too big)
|
|
58
|
-
|
|
59
|
+
try {
|
|
60
|
+
await canvasToBlob(canvas);
|
|
61
|
+
}
|
|
62
|
+
catch (e) {
|
|
63
|
+
if (e.name === "CANVAS_POSSIBLY_TOO_BIG") {
|
|
64
|
+
throw new Error(t("canvasError.canvasTooBig"));
|
|
65
|
+
}
|
|
66
|
+
throw e;
|
|
67
|
+
}
|
|
59
68
|
parent.style.background = "var(--default-bg-color)";
|
|
60
69
|
canvasNode.replaceChildren(canvas);
|
|
61
70
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { KeyboardEvent } from "react";
|
|
2
2
|
import "./TextField.scss";
|
|
3
3
|
type TextFieldProps = {
|
|
4
|
-
value?: string;
|
|
5
4
|
onChange?: (value: string) => void;
|
|
6
5
|
onClick?: () => void;
|
|
7
6
|
onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void;
|
|
@@ -11,6 +10,10 @@ type TextFieldProps = {
|
|
|
11
10
|
label?: string;
|
|
12
11
|
placeholder?: string;
|
|
13
12
|
isRedacted?: boolean;
|
|
14
|
-
}
|
|
13
|
+
} & ({
|
|
14
|
+
value: string;
|
|
15
|
+
} | {
|
|
16
|
+
defaultValue: string;
|
|
17
|
+
});
|
|
15
18
|
export declare const TextField: import("react").ForwardRefExoticComponent<TextFieldProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
16
19
|
export {};
|
|
@@ -4,7 +4,7 @@ import clsx from "clsx";
|
|
|
4
4
|
import "./TextField.scss";
|
|
5
5
|
import { Button } from "./Button";
|
|
6
6
|
import { eyeIcon, eyeClosedIcon } from "./icons";
|
|
7
|
-
export const TextField = forwardRef(({
|
|
7
|
+
export const TextField = forwardRef(({ onChange, label, fullWidth, placeholder, readonly, selectOnRender, onKeyDown, isRedacted = false, ...rest }, ref) => {
|
|
8
8
|
const innerRef = useRef(null);
|
|
9
9
|
useImperativeHandle(ref, () => innerRef.current);
|
|
10
10
|
useLayoutEffect(() => {
|
|
@@ -20,6 +20,9 @@ export const TextField = forwardRef(({ value, onChange, label, fullWidth, placeh
|
|
|
20
20
|
}, children: [_jsx("div", { className: "ExcTextField__label", children: label }), _jsxs("div", { className: clsx("ExcTextField__input", {
|
|
21
21
|
"ExcTextField__input--readonly": readonly,
|
|
22
22
|
}), children: [_jsx("input", { className: clsx({
|
|
23
|
-
"is-redacted": value
|
|
24
|
-
|
|
23
|
+
"is-redacted": "value" in rest &&
|
|
24
|
+
rest.value &&
|
|
25
|
+
isRedacted &&
|
|
26
|
+
!isTemporarilyUnredacted,
|
|
27
|
+
}), readOnly: readonly, value: "value" in rest ? rest.value : undefined, defaultValue: "defaultValue" in rest ? rest.defaultValue : undefined, placeholder: placeholder, ref: innerRef, onChange: (event) => onChange?.(event.target.value), onKeyDown: onKeyDown }), isRedacted && (_jsx(Button, { onSelect: () => setIsTemporarilyUnredacted(!isTemporarilyUnredacted), style: { border: 0, userSelect: "none" }, children: isTemporarilyUnredacted ? eyeClosedIcon : eyeIcon }))] })] }));
|
|
25
28
|
});
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { CSSProperties } from "react";
|
|
2
2
|
import "./Toast.scss";
|
|
3
|
-
export declare const Toast: ({ message, onClose, closable, duration, }: {
|
|
3
|
+
export declare const Toast: ({ message, onClose, closable, duration, style, }: {
|
|
4
4
|
message: string;
|
|
5
5
|
onClose: () => void;
|
|
6
6
|
closable?: boolean | undefined;
|
|
7
7
|
duration?: number | undefined;
|
|
8
|
+
style?: CSSProperties | undefined;
|
|
8
9
|
}) => JSX.Element;
|
|
@@ -6,7 +6,7 @@ import { ToolButton } from "./ToolButton";
|
|
|
6
6
|
const DEFAULT_TOAST_TIMEOUT = 5000;
|
|
7
7
|
export const Toast = ({ message, onClose, closable = false,
|
|
8
8
|
// To prevent autoclose, pass duration as Infinity
|
|
9
|
-
duration = DEFAULT_TOAST_TIMEOUT, }) => {
|
|
9
|
+
duration = DEFAULT_TOAST_TIMEOUT, style, }) => {
|
|
10
10
|
const timerRef = useRef(0);
|
|
11
11
|
const shouldAutoClose = duration !== Infinity;
|
|
12
12
|
const scheduleTimeout = useCallback(() => {
|
|
@@ -26,5 +26,5 @@ duration = DEFAULT_TOAST_TIMEOUT, }) => {
|
|
|
26
26
|
? () => clearTimeout(timerRef?.current)
|
|
27
27
|
: undefined;
|
|
28
28
|
const onMouseLeave = shouldAutoClose ? scheduleTimeout : undefined;
|
|
29
|
-
return (_jsxs("div", { className: "Toast", onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, children: [_jsx("p", { className: "Toast__message", children: message }), closable && (_jsx(ToolButton, { icon: CloseIcon, "aria-label": "close", type: "icon", onClick: onClose, className: "close" }))] }));
|
|
29
|
+
return (_jsxs("div", { className: "Toast", onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, style: style, children: [_jsx("p", { className: "Toast__message", children: message }), closable && (_jsx(ToolButton, { icon: CloseIcon, "aria-label": "close", type: "icon", onClick: onClose, className: "close" }))] }));
|
|
30
30
|
};
|
|
@@ -5,6 +5,7 @@ import clsx from "clsx";
|
|
|
5
5
|
import { useExcalidrawContainer } from "./App";
|
|
6
6
|
import { AbortError } from "../errors";
|
|
7
7
|
import Spinner from "./Spinner";
|
|
8
|
+
import { isPromiseLike } from "../utils";
|
|
8
9
|
export const ToolButton = React.forwardRef((props, ref) => {
|
|
9
10
|
const { id: excalId } = useExcalidrawContainer();
|
|
10
11
|
const innerRef = React.useRef(null);
|
|
@@ -14,7 +15,7 @@ export const ToolButton = React.forwardRef((props, ref) => {
|
|
|
14
15
|
const isMountedRef = useRef(true);
|
|
15
16
|
const onClick = async (event) => {
|
|
16
17
|
const ret = "onClick" in props && props.onClick?.(event);
|
|
17
|
-
if (ret
|
|
18
|
+
if (isPromiseLike(ret)) {
|
|
18
19
|
try {
|
|
19
20
|
setIsLoading(true);
|
|
20
21
|
await ret;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { DOMAttributes } from "react";
|
|
3
3
|
import type { InteractiveCanvasAppState } from "../../types";
|
|
4
|
-
import type { RenderInteractiveSceneCallback } from "../../scene/types";
|
|
4
|
+
import type { RenderableElementsMap, RenderInteractiveSceneCallback } from "../../scene/types";
|
|
5
5
|
import type { NonDeletedExcalidrawElement } from "../../element/types";
|
|
6
6
|
type InteractiveCanvasProps = {
|
|
7
7
|
containerRef: React.RefObject<HTMLDivElement>;
|
|
8
8
|
canvas: HTMLCanvasElement | null;
|
|
9
|
-
|
|
9
|
+
elementsMap: RenderableElementsMap;
|
|
10
10
|
visibleElements: readonly NonDeletedExcalidrawElement[];
|
|
11
11
|
selectedElements: readonly NonDeletedExcalidrawElement[];
|
|
12
12
|
versionNonce: number | undefined;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import React, { useEffect, useRef } from "react";
|
|
3
|
-
import {
|
|
4
|
-
import { isRenderThrottlingEnabled, isShallowEqual, sceneCoordsToViewportCoords, } from "../../utils";
|
|
3
|
+
import { isShallowEqual, sceneCoordsToViewportCoords } from "../../utils";
|
|
5
4
|
import { CURSOR_TYPE } from "../../constants";
|
|
6
5
|
import { t } from "../../i18n";
|
|
6
|
+
import { isRenderThrottlingEnabled } from "../../reactUtils";
|
|
7
|
+
import { renderInteractiveScene } from "../../renderer/interactiveScene";
|
|
7
8
|
const InteractiveCanvas = (props) => {
|
|
8
9
|
const isComponentMounted = useRef(false);
|
|
9
10
|
useEffect(() => {
|
|
@@ -45,7 +46,7 @@ const InteractiveCanvas = (props) => {
|
|
|
45
46
|
"#6965db";
|
|
46
47
|
renderInteractiveScene({
|
|
47
48
|
canvas: props.canvas,
|
|
48
|
-
|
|
49
|
+
elementsMap: props.elementsMap,
|
|
49
50
|
visibleElements: props.visibleElements,
|
|
50
51
|
selectedElements: props.selectedElements,
|
|
51
52
|
scale: window.devicePixelRatio,
|
|
@@ -103,10 +104,10 @@ const areEqual = (prevProps, nextProps) => {
|
|
|
103
104
|
if (prevProps.selectionNonce !== nextProps.selectionNonce ||
|
|
104
105
|
prevProps.versionNonce !== nextProps.versionNonce ||
|
|
105
106
|
prevProps.scale !== nextProps.scale ||
|
|
106
|
-
// we need to memoize on
|
|
107
|
+
// we need to memoize on elementsMap because they may have renewed
|
|
107
108
|
// even if versionNonce didn't change (e.g. we filter elements out based
|
|
108
109
|
// on appState)
|
|
109
|
-
prevProps.
|
|
110
|
+
prevProps.elementsMap !== nextProps.elementsMap ||
|
|
110
111
|
prevProps.visibleElements !== nextProps.visibleElements ||
|
|
111
112
|
prevProps.selectedElements !== nextProps.selectedElements) {
|
|
112
113
|
return false;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { RoughCanvas } from "roughjs/bin/canvas";
|
|
3
3
|
import type { StaticCanvasAppState } from "../../types";
|
|
4
|
-
import type { StaticCanvasRenderConfig } from "../../scene/types";
|
|
5
|
-
import type { NonDeletedExcalidrawElement } from "../../element/types";
|
|
4
|
+
import type { RenderableElementsMap, StaticCanvasRenderConfig } from "../../scene/types";
|
|
5
|
+
import type { NonDeletedExcalidrawElement, NonDeletedSceneElementsMap } from "../../element/types";
|
|
6
6
|
type StaticCanvasProps = {
|
|
7
7
|
canvas: HTMLCanvasElement;
|
|
8
8
|
rc: RoughCanvas;
|
|
9
|
-
|
|
9
|
+
elementsMap: RenderableElementsMap;
|
|
10
|
+
allElementsMap: NonDeletedSceneElementsMap;
|
|
10
11
|
visibleElements: readonly NonDeletedExcalidrawElement[];
|
|
11
12
|
versionNonce: number | undefined;
|
|
12
13
|
selectionNonce: number | undefined;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import React, { useEffect, useRef } from "react";
|
|
3
|
-
import { renderStaticScene } from "../../renderer/
|
|
4
|
-
import {
|
|
3
|
+
import { renderStaticScene } from "../../renderer/staticScene";
|
|
4
|
+
import { isShallowEqual } from "../../utils";
|
|
5
|
+
import { isRenderThrottlingEnabled } from "../../reactUtils";
|
|
5
6
|
const StaticCanvas = (props) => {
|
|
6
7
|
const wrapperRef = useRef(null);
|
|
7
8
|
const isComponentMounted = useRef(false);
|
|
@@ -38,7 +39,8 @@ const StaticCanvas = (props) => {
|
|
|
38
39
|
canvas,
|
|
39
40
|
rc: props.rc,
|
|
40
41
|
scale: props.scale,
|
|
41
|
-
|
|
42
|
+
elementsMap: props.elementsMap,
|
|
43
|
+
allElementsMap: props.allElementsMap,
|
|
42
44
|
visibleElements: props.visibleElements,
|
|
43
45
|
appState: props.appState,
|
|
44
46
|
renderConfig: props.renderConfig,
|
|
@@ -70,10 +72,10 @@ const getRelevantAppStateProps = (appState) => ({
|
|
|
70
72
|
const areEqual = (prevProps, nextProps) => {
|
|
71
73
|
if (prevProps.versionNonce !== nextProps.versionNonce ||
|
|
72
74
|
prevProps.scale !== nextProps.scale ||
|
|
73
|
-
// we need to memoize on
|
|
75
|
+
// we need to memoize on elementsMap because they may have renewed
|
|
74
76
|
// even if versionNonce didn't change (e.g. we filter elements out based
|
|
75
77
|
// on appState)
|
|
76
|
-
prevProps.
|
|
78
|
+
prevProps.elementsMap !== nextProps.elementsMap ||
|
|
77
79
|
prevProps.visibleElements !== nextProps.visibleElements) {
|
|
78
80
|
return false;
|
|
79
81
|
}
|
|
@@ -3,15 +3,35 @@ import { Island } from "../Island";
|
|
|
3
3
|
import { useDevice } from "../App";
|
|
4
4
|
import clsx from "clsx";
|
|
5
5
|
import Stack from "../Stack";
|
|
6
|
-
import { useRef } from "react";
|
|
6
|
+
import { useEffect, useRef } from "react";
|
|
7
7
|
import { DropdownMenuContentPropsContext } from "./common";
|
|
8
8
|
import { useOutsideClick } from "../../hooks/useOutsideClick";
|
|
9
|
+
import { KEYS } from "../../keys";
|
|
10
|
+
import { EVENT } from "../../constants";
|
|
11
|
+
import { useStable } from "../../hooks/useStable";
|
|
9
12
|
const MenuContent = ({ children, onClickOutside, className = "", onSelect, style, }) => {
|
|
10
13
|
const device = useDevice();
|
|
11
14
|
const menuRef = useRef(null);
|
|
15
|
+
const callbacksRef = useStable({ onClickOutside });
|
|
12
16
|
useOutsideClick(menuRef, () => {
|
|
13
|
-
onClickOutside?.();
|
|
17
|
+
callbacksRef.onClickOutside?.();
|
|
14
18
|
});
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
const onKeyDown = (event) => {
|
|
21
|
+
if (event.key === KEYS.ESCAPE) {
|
|
22
|
+
event.stopImmediatePropagation();
|
|
23
|
+
callbacksRef.onClickOutside?.();
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
document.addEventListener(EVENT.KEYDOWN, onKeyDown, {
|
|
27
|
+
// so that we can stop propagation of the event before it reaches
|
|
28
|
+
// event handlers that were bound before this one
|
|
29
|
+
capture: true,
|
|
30
|
+
});
|
|
31
|
+
return () => {
|
|
32
|
+
document.removeEventListener(EVENT.KEYDOWN, onKeyDown);
|
|
33
|
+
};
|
|
34
|
+
}, [callbacksRef]);
|
|
15
35
|
const classNames = clsx(`dropdown-menu ${className}`, {
|
|
16
36
|
"dropdown-menu--mobile": device.editor.isMobile,
|
|
17
37
|
}).trim();
|
|
@@ -3,4 +3,4 @@ export declare const DropdownMenuContentPropsContext: React.Context<{
|
|
|
3
3
|
onSelect?: ((event: Event) => void) | undefined;
|
|
4
4
|
}>;
|
|
5
5
|
export declare const getDropdownMenuItemClassName: (className?: string, selected?: boolean) => string;
|
|
6
|
-
export declare const useHandleDropdownMenuItemClick: (origOnClick: React.MouseEventHandler<HTMLAnchorElement | HTMLButtonElement> | undefined, onSelect: ((event: Event) => void) | undefined) => (event: React.MouseEvent<
|
|
6
|
+
export declare const useHandleDropdownMenuItemClick: (origOnClick: React.MouseEventHandler<HTMLAnchorElement | HTMLButtonElement> | undefined, onSelect: ((event: Event) => void) | undefined) => (event: React.MouseEvent<HTMLAnchorElement | HTMLButtonElement, MouseEvent>) => void;
|