@zsviczian/excalidraw 0.17.1-obsidian-19 → 0.17.1-obsidian-21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/excalidraw.development.js +267 -92
  2. package/dist/excalidraw.production.min.js +1 -1
  3. package/dist/styles.development.css +1103 -854
  4. package/dist/styles.production.css +16 -15
  5. package/package.json +5 -3
  6. package/types/excalidraw/actions/actionAddToLibrary.d.ts +20 -5
  7. package/types/excalidraw/actions/actionAlign.d.ts +39 -27
  8. package/types/excalidraw/actions/actionBoundText.d.ts +20 -10
  9. package/types/excalidraw/actions/actionCanvas.d.ts +148 -52
  10. package/types/excalidraw/actions/actionClipboard.d.ts +72 -30
  11. package/types/excalidraw/actions/actionDeleteSelected.d.ts +25 -9
  12. package/types/excalidraw/actions/actionDistribute.d.ts +10 -8
  13. package/types/excalidraw/actions/actionDuplicateSelection.d.ts +7 -7
  14. package/types/excalidraw/actions/actionElementLock.d.ts +24 -11
  15. package/types/excalidraw/actions/actionExport.d.ts +85 -32
  16. package/types/excalidraw/actions/actionFinalize.d.ts +19 -8
  17. package/types/excalidraw/actions/actionFlip.d.ts +13 -11
  18. package/types/excalidraw/actions/actionFrame.d.ts +30 -200
  19. package/types/excalidraw/actions/actionGroup.d.ts +15 -379
  20. package/types/excalidraw/actions/actionHistory.d.ts +3 -2
  21. package/types/excalidraw/actions/actionLinearEditor.d.ts +9 -3
  22. package/types/excalidraw/actions/actionLink.d.ts +12 -6
  23. package/types/excalidraw/actions/actionMenu.d.ts +25 -8
  24. package/types/excalidraw/actions/actionNavigate.d.ts +14 -3
  25. package/types/excalidraw/actions/actionProperties.d.ts +114 -32
  26. package/types/excalidraw/actions/actionSelectAll.d.ts +12 -5
  27. package/types/excalidraw/actions/actionStyles.d.ts +18 -14
  28. package/types/excalidraw/actions/actionToggleGridMode.d.ts +12 -5
  29. package/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +12 -6
  30. package/types/excalidraw/actions/actionToggleStats.d.ts +12 -5
  31. package/types/excalidraw/actions/actionToggleViewMode.d.ts +12 -5
  32. package/types/excalidraw/actions/actionToggleZenMode.d.ts +12 -5
  33. package/types/excalidraw/actions/actionZindex.d.ts +26 -23
  34. package/types/excalidraw/actions/manager.d.ts +3 -3
  35. package/types/excalidraw/actions/shortcuts.d.ts +2 -2
  36. package/types/excalidraw/actions/types.d.ts +10 -8
  37. package/types/excalidraw/appState.d.ts +4 -4
  38. package/types/excalidraw/change.d.ts +191 -0
  39. package/types/excalidraw/clients.d.ts +10 -1
  40. package/types/excalidraw/components/Actions.d.ts +3 -1
  41. package/types/excalidraw/components/App.d.ts +23 -9
  42. package/types/excalidraw/components/Avatar.d.ts +2 -3
  43. package/types/excalidraw/components/CommandPalette/CommandPalette.d.ts +18 -0
  44. package/types/excalidraw/components/CommandPalette/defaultCommandPaletteItems.d.ts +2 -0
  45. package/types/excalidraw/components/CommandPalette/types.d.ts +25 -0
  46. package/types/excalidraw/components/InlineIcon.d.ts +1 -1
  47. package/types/excalidraw/components/RadioGroup.d.ts +2 -1
  48. package/types/excalidraw/components/ToolButton.d.ts +1 -0
  49. package/types/excalidraw/components/UserList.d.ts +3 -7
  50. package/types/excalidraw/components/canvases/InteractiveCanvas.d.ts +2 -1
  51. package/types/excalidraw/components/dropdownMenu/DropdownMenuItemContentRadio.d.ts +17 -0
  52. package/types/excalidraw/components/hyperlink/Hyperlink.d.ts +2 -2
  53. package/types/excalidraw/components/icons.d.ts +26 -1
  54. package/types/excalidraw/components/main-menu/DefaultItems.d.ts +15 -1
  55. package/types/excalidraw/constants.d.ts +8 -0
  56. package/types/excalidraw/data/reconcile.d.ts +6 -0
  57. package/types/excalidraw/data/restore.d.ts +3 -3
  58. package/types/excalidraw/data/transform.d.ts +1 -1
  59. package/types/excalidraw/data/url.d.ts +1 -0
  60. package/types/excalidraw/deburr.d.ts +1 -0
  61. package/types/excalidraw/element/binding.d.ts +52 -9
  62. package/types/excalidraw/element/bounds.d.ts +0 -1
  63. package/types/excalidraw/element/collision.d.ts +14 -19
  64. package/types/excalidraw/element/embeddable.d.ts +14 -4
  65. package/types/excalidraw/element/index.d.ts +0 -1
  66. package/types/excalidraw/element/linearElementEditor.d.ts +17 -12
  67. package/types/excalidraw/element/mutateElement.d.ts +1 -2
  68. package/types/excalidraw/element/newElement.d.ts +1 -1
  69. package/types/excalidraw/element/resizeElements.d.ts +1 -1
  70. package/types/excalidraw/element/resizeTest.d.ts +4 -4
  71. package/types/excalidraw/element/textElement.d.ts +1 -7
  72. package/types/excalidraw/element/transformHandles.d.ts +22 -4
  73. package/types/excalidraw/element/typeChecks.d.ts +2 -2
  74. package/types/excalidraw/element/types.d.ts +22 -6
  75. package/types/excalidraw/errors.d.ts +3 -0
  76. package/types/excalidraw/fractionalIndex.d.ts +40 -0
  77. package/types/excalidraw/frame.d.ts +1 -1
  78. package/types/excalidraw/groups.d.ts +2 -0
  79. package/types/excalidraw/history.d.ts +34 -46
  80. package/types/excalidraw/hooks/useEmitter.d.ts +2 -0
  81. package/types/excalidraw/hooks/useStableCallback.d.ts +4 -0
  82. package/types/excalidraw/index.d.ts +3 -1
  83. package/types/excalidraw/keys.d.ts +1 -0
  84. package/types/excalidraw/renderer/interactiveScene.d.ts +1 -1
  85. package/types/excalidraw/scene/Scene.d.ts +7 -6
  86. package/types/excalidraw/scene/types.d.ts +11 -20
  87. package/types/excalidraw/store.d.ts +99 -0
  88. package/types/excalidraw/types.d.ts +39 -6
  89. package/types/excalidraw/utils.d.ts +7 -0
  90. package/types/excalidraw/webpack.prod.config.d.ts +1 -1
  91. package/types/excalidraw/zindex.d.ts +2 -2
  92. package/types/utils/collision.d.ts +4 -0
  93. package/types/utils/export.d.ts +2 -2
  94. package/types/utils/geometry/geometry.d.ts +71 -0
  95. package/types/utils/geometry/shape.d.ts +56 -0
@@ -0,0 +1,40 @@
1
+ import { ExcalidrawElement, OrderedExcalidrawElement } from "./element/types";
2
+ /**
3
+ * Envisioned relation between array order and fractional indices:
4
+ *
5
+ * 1) Array (or array-like ordered data structure) should be used as a cache of elements order, hiding the internal fractional indices implementation.
6
+ * - it's undesirable to to perform reorder for each related operation, thefeore it's necessary to cache the order defined by fractional indices into an ordered data structure
7
+ * - it's easy enough to define the order of the elements from the outside (boundaries), without worrying about the underlying structure of fractional indices (especially for the host apps)
8
+ * - it's necessary to always keep the array support for backwards compatibility (restore) - old scenes, old libraries, supporting multiple excalidraw versions etc.
9
+ * - it's necessary to always keep the fractional indices in sync with the array order
10
+ * - elements with invalid indices should be detected and synced, without altering the already valid indices
11
+ *
12
+ * 2) Fractional indices should be used to reorder the elements, whenever the cached order is expected to be invalidated.
13
+ * - as the fractional indices are encoded as part of the elements, it opens up possibilties for incremental-like APIs
14
+ * - re-order based on fractional indices should be part of (multiplayer) operations such as reconcillitation & undo/redo
15
+ * - technically all the z-index actions could perform also re-order based on fractional indices,but in current state it would not bring much benefits,
16
+ * as it's faster & more efficient to perform re-order based on array manipulation and later synchronisation of moved indices with the array order
17
+ */
18
+ /**
19
+ * Ensure that all elements have valid fractional indices.
20
+ *
21
+ * @throws `InvalidFractionalIndexError` if invalid index is detected.
22
+ */
23
+ export declare const validateFractionalIndices: (indices: (ExcalidrawElement["index"] | undefined)[]) => void;
24
+ /**
25
+ * Order the elements based on the fractional indices.
26
+ * - when fractional indices are identical, break the tie based on the element id
27
+ * - when there is no fractional index in one of the elements, respect the order of the array
28
+ */
29
+ export declare const orderByFractionalIndex: (elements: OrderedExcalidrawElement[]) => OrderedExcalidrawElement[];
30
+ /**
31
+ * Synchronizes invalid fractional indices of moved elements with the array order by mutating passed elements.
32
+ * If the synchronization fails or the result is invalid, it fallbacks to `syncInvalidIndices`.
33
+ */
34
+ export declare const syncMovedIndices: (elements: readonly ExcalidrawElement[], movedElements: Map<string, ExcalidrawElement>) => OrderedExcalidrawElement[];
35
+ /**
36
+ * Synchronizes all invalid fractional indices with the array order by mutating passed elements.
37
+ *
38
+ * WARN: in edge cases it could modify the elements which were not moved, as it's impossible to guess the actually moved elements from the elements array itself.
39
+ */
40
+ export declare const syncInvalidIndices: (elements: readonly ExcalidrawElement[]) => OrderedExcalidrawElement[];
@@ -2,7 +2,7 @@ import { ElementsMap, ElementsMapOrArray, ExcalidrawElement, ExcalidrawFrameLike
2
2
  import { AppClassProperties, AppState, StaticCanvasAppState } from "./types";
3
3
  import type { ExcalidrawElementsIncludingDeleted } from "./scene/Scene";
4
4
  import { ReadonlySetLike } from "./utility-types";
5
- export declare const bindElementsToFramesAfterDuplication: (nextElements: ExcalidrawElement[], oldElements: readonly ExcalidrawElement[], oldIdToDuplicatedId: Map<ExcalidrawElement["id"], ExcalidrawElement["id"]>) => void;
5
+ export declare const bindElementsToFramesAfterDuplication: (nextElements: readonly ExcalidrawElement[], oldElements: readonly ExcalidrawElement[], oldIdToDuplicatedId: Map<ExcalidrawElement["id"], ExcalidrawElement["id"]>) => void;
6
6
  export declare function isElementIntersectingFrame(element: ExcalidrawElement, frame: ExcalidrawFrameLikeElement, elementsMap: ElementsMap): boolean;
7
7
  export declare const getElementsCompletelyInFrame: (elements: readonly ExcalidrawElement[], frame: ExcalidrawFrameLikeElement, elementsMap: ElementsMap) => ExcalidrawElement[];
8
8
  export declare const isElementContainingFrame: (elements: readonly ExcalidrawElement[], element: ExcalidrawElement, frame: ExcalidrawFrameLikeElement, elementsMap: ElementsMap) => boolean;
@@ -28,4 +28,6 @@ export declare const removeFromSelectedGroups: (groupIds: ExcalidrawElement["gro
28
28
  [groupId: string]: boolean;
29
29
  }) => string[];
30
30
  export declare const getMaximumGroups: (elements: ExcalidrawElement[], elementsMap: ElementsMap) => ExcalidrawElement[][];
31
+ export declare const getNonDeletedGroupIds: (elements: ElementsMap) => Set<string>;
31
32
  export declare const elementsAreInSameGroup: (elements: ExcalidrawElement[]) => boolean;
33
+ export declare const isInGroup: (element: NonDeletedExcalidrawElement) => boolean;
@@ -1,52 +1,40 @@
1
+ import { AppStateChange, ElementsChange } from "./change";
2
+ import { SceneElementsMap } from "./element/types";
3
+ import { Emitter } from "./emitter";
4
+ import { Snapshot } from "./store";
1
5
  import { AppState } from "./types";
2
- import { ExcalidrawElement } from "./element/types";
3
- export interface HistoryEntry {
4
- appState: ReturnType<typeof clearAppStatePropertiesForHistory>;
5
- elements: ExcalidrawElement[];
6
+ export declare class HistoryChangedEvent {
7
+ readonly isUndoStackEmpty: boolean;
8
+ readonly isRedoStackEmpty: boolean;
9
+ constructor(isUndoStackEmpty?: boolean, isRedoStackEmpty?: boolean);
6
10
  }
7
- declare const clearAppStatePropertiesForHistory: (appState: AppState) => {
8
- selectedElementIds: Readonly<{
9
- [id: string]: true;
10
- }>;
11
- selectedGroupIds: {
12
- [groupId: string]: boolean;
13
- };
14
- viewBackgroundColor: string;
15
- editingLinearElement: import("./element/linearElementEditor").LinearElementEditor | null;
16
- editingGroupId: string | null;
17
- name: string | null;
18
- };
19
- declare class History {
20
- private elementCache;
21
- private recording;
22
- private stateHistory;
23
- private redoStack;
24
- private lastEntry;
25
- private hydrateHistoryEntry;
26
- private dehydrateHistoryEntry;
27
- getSnapshotForTest(): {
28
- recording: boolean;
29
- stateHistory: HistoryEntry[];
30
- redoStack: HistoryEntry[];
31
- };
11
+ export declare class History {
12
+ readonly onHistoryChangedEmitter: Emitter<[HistoryChangedEvent]>;
13
+ private readonly undoStack;
14
+ private readonly redoStack;
15
+ get isUndoStackEmpty(): boolean;
16
+ get isRedoStackEmpty(): boolean;
32
17
  clear(): void;
33
- private generateEntry;
34
- shouldCreateEntry(nextEntry: HistoryEntry): boolean;
35
- pushEntry(appState: AppState, elements: readonly ExcalidrawElement[]): void;
36
- clearRedoStack(): void;
37
- redoOnce(): HistoryEntry | null;
38
- undoOnce(): HistoryEntry | null;
39
18
  /**
40
- * Updates history's `lastEntry` to latest app state. This is necessary
41
- * when doing undo/redo which itself doesn't commit to history, but updates
42
- * app state in a way that would break `shouldCreateEntry` which relies on
43
- * `lastEntry` to reflect last comittable history state.
44
- * We can't update `lastEntry` from within history when calling undo/redo
45
- * because the action potentially mutates appState/elements before storing
46
- * it.
19
+ * Record a local change which will go into the history
47
20
  */
48
- setCurrentState(appState: AppState, elements: readonly ExcalidrawElement[]): void;
49
- resumeRecording(): void;
50
- record(state: AppState, elements: readonly ExcalidrawElement[]): void;
21
+ record(elementsChange: ElementsChange, appStateChange: AppStateChange): void;
22
+ undo(elements: SceneElementsMap, appState: AppState, snapshot: Readonly<Snapshot>): void | [SceneElementsMap, AppState];
23
+ redo(elements: SceneElementsMap, appState: AppState, snapshot: Readonly<Snapshot>): void | [SceneElementsMap, AppState];
24
+ private perform;
25
+ private static pop;
26
+ private static push;
27
+ }
28
+ export declare class HistoryEntry {
29
+ readonly appStateChange: AppStateChange;
30
+ readonly elementsChange: ElementsChange;
31
+ private constructor();
32
+ static create(appStateChange: AppStateChange, elementsChange: ElementsChange): HistoryEntry;
33
+ inverse(): HistoryEntry;
34
+ applyTo(elements: SceneElementsMap, appState: AppState, snapshot: Readonly<Snapshot>): [SceneElementsMap, AppState, boolean];
35
+ /**
36
+ * Apply latest (remote) changes to the history entry, creates new instance of `HistoryEntry`.
37
+ */
38
+ applyLatestChanges(elements: SceneElementsMap): HistoryEntry;
39
+ isEmpty(): boolean;
51
40
  }
52
- export default History;
@@ -0,0 +1,2 @@
1
+ import { Emitter } from "../emitter";
2
+ export declare const useEmitter: <TEvent extends unknown>(emitter: Emitter<[TEvent]>, initialState: TEvent) => TEvent;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Returns a stable function of the same type.
3
+ */
4
+ export declare const useStableCallback: <T extends (...args: any[]) => any>(userFn: T) => T;
@@ -11,6 +11,7 @@ export declare const Excalidraw: React.MemoExoticComponent<(props: ExcalidrawPro
11
11
  export { getSceneVersion, hashElementsVersion, hashString, isInvisiblySmallElement, getNonDeletedElements, } from "./element";
12
12
  export { defaultLang, useI18n, languages } from "./i18n";
13
13
  export { restore, restoreAppState, restoreElements, restoreLibraryItems, } from "./data/restore";
14
+ export { reconcileElements } from "./data/reconcile";
14
15
  export { exportToCanvas, exportToBlob, exportToSvg, exportToClipboard, getCommonBoundingBox, //zsviczian
15
16
  getMaximumGroups, //zsviczian
16
17
  intersectElementWithLine, //zsviczian
@@ -26,8 +27,9 @@ export { loadFromBlob, loadSceneOrLibraryFromBlob, loadLibraryFromBlob, } from "
26
27
  export { getFreeDrawSvgPath } from "./renderer/renderElement";
27
28
  export { mergeLibraryItems, getLibraryItemsHash } from "./data/library";
28
29
  export { isLinearElement } from "./element/typeChecks";
29
- export { FONT_FAMILY, THEME, MIME_TYPES, ROUNDNESS } from "./constants";
30
+ export { FONT_FAMILY, THEME, MIME_TYPES, ROUNDNESS, DEFAULT_LASER_COLOR, } from "./constants";
30
31
  export { mutateElement, newElementWith, bumpVersion, } from "./element/mutateElement";
32
+ export { StoreAction } from "./store";
31
33
  export { parseLibraryTokensFromUrl, useHandleLibrary } from "./data/library";
32
34
  export { sceneCoordsToViewportCoords, viewportCoordsToSceneCoords, } from "./utils";
33
35
  export { getEmbedLink } from "./element/embeddable";
@@ -42,6 +42,7 @@ export declare const KEYS: {
42
42
  readonly PERIOD: ".";
43
43
  readonly COMMA: ",";
44
44
  readonly SUBTRACT: "-";
45
+ readonly SLASH: "/";
45
46
  readonly A: "a";
46
47
  readonly C: "c";
47
48
  readonly D: "d";
@@ -9,7 +9,7 @@ export declare const renderInteractiveSceneThrottled: {
9
9
  * Interactive scene is the ui-canvas where we render bounding boxes, selections
10
10
  * and other ui stuff.
11
11
  */
12
- export declare const renderInteractiveScene: <U extends ({ canvas, elementsMap, visibleElements, selectedElements, scale, appState, renderConfig, }: InteractiveSceneRenderConfig) => {
12
+ export declare const renderInteractiveScene: <U extends ({ canvas, elementsMap, visibleElements, selectedElements, scale, appState, renderConfig, device, }: InteractiveSceneRenderConfig) => {
13
13
  atLeastOneVisibleElement: boolean;
14
14
  elementsMap: RenderableElementsMap;
15
15
  scrollBars?: undefined;
@@ -1,4 +1,4 @@
1
- import { ExcalidrawElement, NonDeletedExcalidrawElement, NonDeleted, ExcalidrawFrameLikeElement, ElementsMapOrArray } from "../element/types";
1
+ import { ExcalidrawElement, NonDeletedExcalidrawElement, NonDeleted, ExcalidrawFrameLikeElement, ElementsMapOrArray, OrderedExcalidrawElement, Ordered } from "../element/types";
2
2
  import { LinearElementEditor } from "../element/linearElementEditor";
3
3
  import { AppState } from "../types";
4
4
  type ElementIdKey = InstanceType<typeof LinearElementEditor>["elementId"];
@@ -20,10 +20,10 @@ declare class Scene {
20
20
  private elementsMap;
21
21
  private selectedElementsCache;
22
22
  private versionNonce;
23
- getElementsMapIncludingDeleted(): Map<string, ExcalidrawElement> & import("../utility-types").MakeBrand<"SceneElementsMap">;
24
- getNonDeletedElementsMap(): Map<string, NonDeletedExcalidrawElement> & import("../utility-types").MakeBrand<"NonDeletedSceneElementsMap">;
25
- getElementsIncludingDeleted(): readonly ExcalidrawElement[];
26
- getNonDeletedElements(): readonly NonDeletedExcalidrawElement[];
23
+ getNonDeletedElementsMap(): Map<string, Ordered<NonDeletedExcalidrawElement>> & import("../utility-types").MakeBrand<"NonDeletedSceneElementsMap">;
24
+ getElementsIncludingDeleted(): readonly OrderedExcalidrawElement[];
25
+ getElementsMapIncludingDeleted(): Map<string, Ordered<ExcalidrawElement>> & import("../utility-types").MakeBrand<"SceneElementsMap">;
26
+ getNonDeletedElements(): readonly Ordered<NonDeletedExcalidrawElement>[];
27
27
  getFramesIncludingDeleted(): readonly ExcalidrawFrameLikeElement[];
28
28
  getSelectedElements(opts: {
29
29
  selectedElementIds: AppState["selectedElementIds"];
@@ -59,7 +59,8 @@ declare class Scene {
59
59
  destroy(): void;
60
60
  insertElementAtIndex(element: ExcalidrawElement, index: number): void;
61
61
  insertElementsAtIndex(elements: ExcalidrawElement[], index: number): void;
62
- addNewElement: (element: ExcalidrawElement) => void;
62
+ insertElement: (element: ExcalidrawElement, idx?: number) => void;
63
+ insertElements: (elements: ExcalidrawElement[]) => void;
63
64
  getElementIndex(elementId: string): number;
64
65
  getContainerElement: (element: (ExcalidrawElement & {
65
66
  containerId: ExcalidrawElement["id"] | null;
@@ -1,7 +1,7 @@
1
1
  import type { RoughCanvas } from "roughjs/bin/canvas";
2
2
  import { Drawable } from "roughjs/bin/core";
3
- import { ExcalidrawTextElement, NonDeletedElementsMap, NonDeletedExcalidrawElement, NonDeletedSceneElementsMap } from "../element/types";
4
- import { AppClassProperties, AppState, EmbedsValidationStatus, ElementsPendingErasure, InteractiveCanvasAppState, StaticCanvasAppState } from "../types";
3
+ import { ExcalidrawElement, ExcalidrawTextElement, NonDeletedElementsMap, NonDeletedExcalidrawElement, NonDeletedSceneElementsMap } from "../element/types";
4
+ import { AppClassProperties, AppState, EmbedsValidationStatus, ElementsPendingErasure, InteractiveCanvasAppState, StaticCanvasAppState, SocketId, UserIdleState, Device } from "../types";
5
5
  import { MakeBrand } from "../utility-types";
6
6
  export type RenderableElementsMap = NonDeletedElementsMap & MakeBrand<"RenderableElementsMap">;
7
7
  export type StaticCanvasRenderConfig = {
@@ -26,24 +26,14 @@ export type SVGRenderConfig = {
26
26
  embedsValidationStatus: EmbedsValidationStatus;
27
27
  };
28
28
  export type InteractiveCanvasRenderConfig = {
29
- remoteSelectedElementIds: {
30
- [elementId: string]: string[];
31
- };
32
- remotePointerViewportCoords: {
33
- [id: string]: {
34
- x: number;
35
- y: number;
36
- };
37
- };
38
- remotePointerUserStates: {
39
- [id: string]: string;
40
- };
41
- remotePointerUsernames: {
42
- [id: string]: string;
43
- };
44
- remotePointerButton?: {
45
- [id: string]: string | undefined;
46
- };
29
+ remoteSelectedElementIds: Map<ExcalidrawElement["id"], SocketId[]>;
30
+ remotePointerViewportCoords: Map<SocketId, {
31
+ x: number;
32
+ y: number;
33
+ }>;
34
+ remotePointerUserStates: Map<SocketId, UserIdleState>;
35
+ remotePointerUsernames: Map<SocketId, string>;
36
+ remotePointerButton: Map<SocketId, string | undefined>;
47
37
  selectionColor?: string;
48
38
  renderScrollbars?: boolean;
49
39
  };
@@ -70,6 +60,7 @@ export type InteractiveSceneRenderConfig = {
70
60
  scale: number;
71
61
  appState: InteractiveCanvasAppState;
72
62
  renderConfig: InteractiveCanvasRenderConfig;
63
+ device: Device;
73
64
  callback: (data: RenderInteractiveSceneCallback) => void;
74
65
  };
75
66
  export type SceneScroll = {
@@ -0,0 +1,99 @@
1
+ import { AppStateChange, ElementsChange } from "./change";
2
+ import { OrderedExcalidrawElement } from "./element/types";
3
+ import { Emitter } from "./emitter";
4
+ import { AppState, ObservedAppState } from "./types";
5
+ export declare const getObservedAppState: (appState: AppState) => ObservedAppState;
6
+ export type StoreActionType = "capture" | "update" | "none";
7
+ export declare const StoreAction: {
8
+ [K in Uppercase<StoreActionType>]: StoreActionType;
9
+ };
10
+ /**
11
+ * Represent an increment to the Store.
12
+ */
13
+ declare class StoreIncrementEvent {
14
+ readonly elementsChange: ElementsChange;
15
+ readonly appStateChange: AppStateChange;
16
+ constructor(elementsChange: ElementsChange, appStateChange: AppStateChange);
17
+ }
18
+ /**
19
+ * Store which captures the observed changes and emits them as `StoreIncrementEvent` events.
20
+ *
21
+ * @experimental this interface is experimental and subject to change.
22
+ */
23
+ export interface IStore {
24
+ onStoreIncrementEmitter: Emitter<[StoreIncrementEvent]>;
25
+ get snapshot(): Snapshot;
26
+ set snapshot(snapshot: Snapshot);
27
+ /**
28
+ * Use to schedule update of the snapshot, useful on updates for which we don't need to calculate increments (i.e. remote updates).
29
+ */
30
+ shouldUpdateSnapshot(): void;
31
+ /**
32
+ * Use to schedule calculation of a store increment.
33
+ */
34
+ shouldCaptureIncrement(): void;
35
+ /**
36
+ * Based on the scheduled operation, either only updates store snapshot or also calculates increment and emits the result as a `StoreIncrementEvent`.
37
+ *
38
+ * @emits StoreIncrementEvent when increment is calculated.
39
+ */
40
+ commit(elements: Map<string, OrderedExcalidrawElement> | undefined, appState: AppState | ObservedAppState | undefined): void;
41
+ /**
42
+ * Clears the store instance.
43
+ */
44
+ clear(): void;
45
+ /**
46
+ * Filters out yet uncomitted elements from `nextElements`, which are part of in-progress local async actions (ephemerals) and thus were not yet commited to the snapshot.
47
+ *
48
+ * This is necessary in updates in which we receive reconciled elements, already containing elements which were not yet captured by the local store (i.e. collab).
49
+ */
50
+ filterUncomittedElements(prevElements: Map<string, OrderedExcalidrawElement>, nextElements: Map<string, OrderedExcalidrawElement>): Map<string, OrderedExcalidrawElement>;
51
+ }
52
+ export declare class Store implements IStore {
53
+ readonly onStoreIncrementEmitter: Emitter<[StoreIncrementEvent]>;
54
+ private scheduledActions;
55
+ private _snapshot;
56
+ get snapshot(): Snapshot;
57
+ set snapshot(snapshot: Snapshot);
58
+ shouldCaptureIncrement: () => void;
59
+ shouldUpdateSnapshot: () => void;
60
+ private scheduleAction;
61
+ commit: (elements: Map<string, OrderedExcalidrawElement> | undefined, appState: AppState | ObservedAppState | undefined) => void;
62
+ captureIncrement: (elements: Map<string, OrderedExcalidrawElement> | undefined, appState: AppState | ObservedAppState | undefined) => void;
63
+ updateSnapshot: (elements: Map<string, OrderedExcalidrawElement> | undefined, appState: AppState | ObservedAppState | undefined) => void;
64
+ filterUncomittedElements: (prevElements: Map<string, OrderedExcalidrawElement>, nextElements: Map<string, OrderedExcalidrawElement>) => Map<string, OrderedExcalidrawElement>;
65
+ clear: () => void;
66
+ private satisfiesScheduledActionsInvariant;
67
+ }
68
+ export declare class Snapshot {
69
+ readonly elements: Map<string, OrderedExcalidrawElement>;
70
+ readonly appState: ObservedAppState;
71
+ readonly meta: {
72
+ didElementsChange: boolean;
73
+ didAppStateChange: boolean;
74
+ isEmpty?: boolean;
75
+ };
76
+ private constructor();
77
+ static empty(): Snapshot;
78
+ isEmpty(): boolean | undefined;
79
+ /**
80
+ * Efficiently clone the existing snapshot, only if we detected changes.
81
+ *
82
+ * @returns same instance if there are no changes detected, new instance otherwise.
83
+ */
84
+ maybeClone(elements: Map<string, OrderedExcalidrawElement> | undefined, appState: AppState | ObservedAppState | undefined): Snapshot;
85
+ private maybeCreateAppStateSnapshot;
86
+ private detectChangedAppState;
87
+ private maybeCreateElementsSnapshot;
88
+ /**
89
+ * Detect if there any changed elements.
90
+ *
91
+ * NOTE: we shouldn't just use `sceneVersionNonce` instead, as we need to call this before the scene updates.
92
+ */
93
+ private detectChangedElements;
94
+ /**
95
+ * Perform structural clone, cloning only elements that changed.
96
+ */
97
+ private createElementsSnapshot;
98
+ }
99
+ export {};
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { PointerType, ExcalidrawLinearElement, NonDeletedExcalidrawElement, NonDeleted, TextAlign, ExcalidrawElement, GroupId, ExcalidrawBindableElement, Arrowhead, ChartType, FontFamilyValues, ExcalidrawTextElement, FileId, ExcalidrawImageElement, Theme, StrokeRoundness, ExcalidrawEmbeddableElement, ExcalidrawMagicFrameElement, ExcalidrawFrameLikeElement, ExcalidrawElementType, ExcalidrawIframeLikeElement } from "./element/types";
2
+ import { PointerType, ExcalidrawLinearElement, NonDeletedExcalidrawElement, NonDeleted, TextAlign, ExcalidrawElement, GroupId, ExcalidrawBindableElement, Arrowhead, ChartType, FontFamilyValues, ExcalidrawTextElement, FileId, ExcalidrawImageElement, Theme, StrokeRoundness, ExcalidrawEmbeddableElement, ExcalidrawMagicFrameElement, ExcalidrawFrameLikeElement, ExcalidrawElementType, ExcalidrawIframeLikeElement, OrderedExcalidrawElement } from "./element/types";
3
3
  import { Action } from "./actions/types";
4
4
  import { Point as RoughPoint } from "roughjs/bin/geometry";
5
5
  import { LinearElementEditor } from "./element/linearElementEditor";
@@ -19,6 +19,7 @@ import { ContextMenuItems } from "./components/ContextMenu";
19
19
  import { SnapLine } from "./snapping";
20
20
  import { Merge, MaybePromise, ValueOf } from "./utility-types";
21
21
  import { ColorPaletteCustom } from "./colors";
22
+ import { StoreActionType } from "./store";
22
23
  export type Point = Readonly<RoughPoint>;
23
24
  export type SocketId = string & {
24
25
  _brand: "SocketId";
@@ -37,11 +38,27 @@ export type Collaborator = Readonly<{
37
38
  id?: string;
38
39
  socketId?: SocketId;
39
40
  isCurrentUser?: boolean;
41
+ isInCall?: boolean;
42
+ isSpeaking?: boolean;
43
+ isMuted?: boolean;
40
44
  }>;
41
45
  export type CollaboratorPointer = {
42
46
  x: number;
43
47
  y: number;
44
48
  tool: "pointer" | "laser";
49
+ /**
50
+ * Whether to render cursor + username. Useful when you only want to render
51
+ * laser trail.
52
+ *
53
+ * @default true
54
+ */
55
+ renderCursor?: boolean;
56
+ /**
57
+ * Explicit laser color.
58
+ *
59
+ * @default string collaborator's cursor color
60
+ */
61
+ laserColor?: string;
45
62
  };
46
63
  export type DataURL = string & {
47
64
  _brand: "DataURL";
@@ -122,6 +139,18 @@ export type InteractiveCanvasAppState = Readonly<_CommonCanvasAppState & {
122
139
  snapLines: AppState["snapLines"];
123
140
  zenModeEnabled: AppState["zenModeEnabled"];
124
141
  }>;
142
+ export type ObservedAppState = ObservedStandaloneAppState & ObservedElementsAppState;
143
+ export type ObservedStandaloneAppState = {
144
+ name: AppState["name"];
145
+ viewBackgroundColor: AppState["viewBackgroundColor"];
146
+ };
147
+ export type ObservedElementsAppState = {
148
+ editingGroupId: AppState["editingGroupId"];
149
+ selectedElementIds: AppState["selectedElementIds"];
150
+ selectedGroupIds: AppState["selectedGroupIds"];
151
+ editingLinearElementId: LinearElementEditor["elementId"] | null;
152
+ selectedLinearElementId: LinearElementEditor["elementId"] | null;
153
+ };
125
154
  export interface AppState {
126
155
  contextMenu: {
127
156
  items: ContextMenuItems;
@@ -204,6 +233,8 @@ export interface AppState {
204
233
  } | {
205
234
  name: "ttd";
206
235
  tab: "text-to-diagram" | "mermaid";
236
+ } | {
237
+ name: "commandPalette";
207
238
  };
208
239
  /**
209
240
  * Reflects user preference for whether the default sidebar should be docked.
@@ -296,9 +327,9 @@ export interface AppState {
296
327
  y: number;
297
328
  } | null;
298
329
  objectsSnapModeEnabled: boolean;
299
- /** the user's clientId & username who is being followed on the canvas */
330
+ /** the user's socket id & username who is being followed on the canvas */
300
331
  userToFollow: UserToFollow | null;
301
- /** the clientIds of the users following the current user */
332
+ /** the socket ids of the users following the current user */
302
333
  followedBy: Set<SocketId>;
303
334
  }
304
335
  export type UIAppState = Omit<AppState, "suggestedBindings" | "startBoundElement" | "cursorButton" | "scrollX" | "scrollY">;
@@ -350,7 +381,7 @@ export type OnUserFollowedPayload = {
350
381
  action: "FOLLOW" | "UNFOLLOW";
351
382
  };
352
383
  export interface ExcalidrawProps {
353
- onChange?: (elements: readonly ExcalidrawElement[], appState: AppState, files: BinaryFiles) => void;
384
+ onChange?: (elements: readonly OrderedExcalidrawElement[], appState: AppState, files: BinaryFiles) => void;
354
385
  initialData?: MaybePromise<ExcalidrawInitialDataState | null>;
355
386
  excalidrawAPI?: (api: ExcalidrawImperativeAPI) => void;
356
387
  isCollaborating?: boolean;
@@ -408,7 +439,7 @@ export type SceneData = {
408
439
  elements?: ImportedDataState["elements"];
409
440
  appState?: ImportedDataState["appState"];
410
441
  collaborators?: Map<SocketId, Collaborator>;
411
- commitToHistory?: boolean;
442
+ storeAction?: StoreActionType;
412
443
  };
413
444
  export declare enum UserIdleState {
414
445
  ACTIVE = "active",
@@ -476,10 +507,12 @@ export type AppClassProperties = {
476
507
  addElementsFromPasteOrLibrary: App["addElementsFromPasteOrLibrary"];
477
508
  setSelection: App["setSelection"];
478
509
  togglePenMode: App["togglePenMode"];
510
+ toggleLock: App["toggleLock"];
479
511
  setActiveTool: App["setActiveTool"];
480
512
  setOpenDialog: App["setOpenDialog"];
481
513
  insertEmbeddableElement: App["insertEmbeddableElement"];
482
514
  onMagicframeToolSelect: App["onMagicframeToolSelect"];
515
+ getElementShape: App["getElementShape"];
483
516
  getName: App["getName"];
484
517
  };
485
518
  export type PointerDownState = Readonly<{
@@ -592,7 +625,7 @@ export type Device = Readonly<{
592
625
  };
593
626
  isTouchScreen: boolean;
594
627
  }>;
595
- type FrameNameBounds = {
628
+ export type FrameNameBounds = {
596
629
  x: number;
597
630
  y: number;
598
631
  width: number;
@@ -160,7 +160,14 @@ export declare const arrayToMap: <T extends string | {
160
160
  export declare const arrayToMapWithIndex: <T extends {
161
161
  id: string;
162
162
  }>(elements: readonly T[]) => Map<string, [element: T, index: number]>;
163
+ /**
164
+ * Transform array into an object, use only when array order is irrelevant.
165
+ */
166
+ export declare const arrayToObject: <T>(array: readonly T[], groupBy?: ((value: T) => string) | undefined) => {
167
+ [key: string]: T;
168
+ };
163
169
  export declare const isTestEnv: () => boolean;
170
+ export declare const isDevEnv: () => boolean;
164
171
  export declare const wrapEvent: <T extends Event>(name: EVENT, nativeEvent: T) => CustomEvent<{
165
172
  nativeEvent: T;
166
173
  }>;
@@ -78,7 +78,7 @@ export namespace module {
78
78
  }
79
79
  export namespace optimization {
80
80
  const minimize: boolean;
81
- const minimizer: TerserPlugin<import("terser").MinifyOptions>[];
81
+ const minimizer: TerserPlugin<import("terser-webpack-plugin/node_modules/terser").MinifyOptions>[];
82
82
  }
83
83
  export const plugins: any[];
84
84
  export const externals: {
@@ -1,6 +1,6 @@
1
1
  import { ExcalidrawElement } from "./element/types";
2
2
  import { AppState } from "./types";
3
- export declare const moveOneLeft: (allElements: readonly ExcalidrawElement[], appState: AppState) => ExcalidrawElement[];
4
- export declare const moveOneRight: (allElements: readonly ExcalidrawElement[], appState: AppState) => ExcalidrawElement[];
3
+ export declare const moveOneLeft: (allElements: readonly ExcalidrawElement[], appState: AppState) => readonly ExcalidrawElement[];
4
+ export declare const moveOneRight: (allElements: readonly ExcalidrawElement[], appState: AppState) => readonly ExcalidrawElement[];
5
5
  export declare const moveAllLeft: (allElements: readonly ExcalidrawElement[], appState: AppState) => readonly ExcalidrawElement[] | ExcalidrawElement[];
6
6
  export declare const moveAllRight: (allElements: readonly ExcalidrawElement[], appState: AppState) => readonly ExcalidrawElement[] | ExcalidrawElement[];
@@ -0,0 +1,4 @@
1
+ import { Point, Polygon, GeometricShape } from "./geometry/shape";
2
+ export declare const isPointOnShape: (point: Point, shape: GeometricShape, tolerance?: number) => boolean;
3
+ export declare const isPointInShape: (point: Point, shape: GeometricShape) => boolean;
4
+ export declare const isPointInBounds: (point: Point, bounds: Polygon) => boolean;
@@ -33,8 +33,8 @@ export declare const exportToClipboard: (opts: ExportOpts & {
33
33
  }) => Promise<void>;
34
34
  export { getCommonBoundingBox } from "../excalidraw/element/bounds";
35
35
  export { getMaximumGroups } from "../excalidraw/groups";
36
- export { intersectElementWithLine } from "../excalidraw/element/collision";
37
- export { determineFocusDistance } from "../excalidraw/element/collision";
36
+ export { intersectElementWithLine } from "../excalidraw/element/binding";
37
+ export { determineFocusDistance } from "../excalidraw/element/binding";
38
38
  export { measureText, wrapText, getDefaultLineHeight, } from "../excalidraw/element/textElement";
39
39
  export { getFontString } from "../excalidraw/utils";
40
40
  export { getBoundTextMaxWidth } from "../excalidraw/element/textElement";
@@ -0,0 +1,71 @@
1
+ import { Point, Line, Polygon, Curve, Ellipse, Polycurve, Polyline } from "./shape";
2
+ /**
3
+ * utils
4
+ */
5
+ export declare const cross: (a: Point, b: Point, o: Point) => number;
6
+ export declare const isClosed: (polygon: Polygon) => boolean;
7
+ export declare const close: (polygon: Polygon) => Polygon;
8
+ /**
9
+ * angles
10
+ */
11
+ export declare const angleToDegrees: (angle: number) => number;
12
+ export declare const angleToRadians: (angle: number) => number;
13
+ export declare const angleReflect: (incidenceAngle: number, surfaceAngle: number) => number;
14
+ export declare const pointRotate: (point: Point, angle: number, origin?: Point) => Point;
15
+ export declare const pointTranslate: (point: Point, angle?: number, distance?: number) => Point;
16
+ export declare const pointInverse: (point: Point) => Point;
17
+ export declare const pointAdd: (pointA: Point, pointB: Point) => Point;
18
+ export declare const distanceToPoint: (p1: Point, p2: Point) => number;
19
+ /**
20
+ * lines
21
+ */
22
+ export declare const lineAngle: (line: Line) => number;
23
+ export declare const lineLength: (line: Line) => number;
24
+ export declare const lineMidpoint: (line: Line) => Point;
25
+ export declare const lineRotate: (line: Line, angle: number, origin?: Point) => Line;
26
+ export declare const lineTranslate: (line: Line, angle: number, distance: number) => Point[];
27
+ export declare const lineInterpolate: (line: Line, clamp?: boolean) => (t: number) => Point;
28
+ export declare const curveToBezier: (pointsIn: readonly Point[], curveTightness?: number) => Point[];
29
+ export declare const curveRotate: (curve: Curve, angle: number, origin: Point) => Point[];
30
+ export declare const cubicBezierPoint: (t: number, controlPoints: Curve) => Point;
31
+ export declare const cubicBezierDistance: (point: Point, controlPoints: Curve) => number;
32
+ /**
33
+ * polygons
34
+ */
35
+ export declare const polygonRotate: (polygon: Polygon, angle: number, origin: Point) => Point[];
36
+ export declare const polygonBounds: (polygon: Polygon) => [Point, Point];
37
+ export declare const polygonCentroid: (vertices: Point[]) => Point;
38
+ export declare const polygonScale: (polygon: Polygon, scale: number, origin?: Point) => Polygon;
39
+ export declare const polygonScaleX: (polygon: Polygon, scale: number, origin?: Point) => Polygon;
40
+ export declare const polygonScaleY: (polygon: Polygon, scale: number, origin?: Point) => Polygon;
41
+ export declare const polygonReflectX: (polygon: Polygon, reflectFactor?: number) => Point[];
42
+ export declare const polygonReflectY: (polygon: Polygon, reflectFactor?: number) => Point[];
43
+ export declare const polygonTranslate: (polygon: Polygon, angle: number, distance: number) => Point[];
44
+ /**
45
+ * ellipses
46
+ */
47
+ export declare const ellipseAxes: (ellipse: Ellipse) => {
48
+ majorAxis: number;
49
+ minorAxis: number;
50
+ };
51
+ export declare const ellipseFocusToCenter: (ellipse: Ellipse) => number;
52
+ export declare const ellipseExtremes: (ellipse: Ellipse) => Point[];
53
+ export declare const pointRelativeToCenter: (point: Point, center: Point, angle: number) => Point;
54
+ export declare const pointLeftofLine: (point: Point, line: Line) => boolean;
55
+ export declare const pointRightofLine: (point: Point, line: Line) => boolean;
56
+ export declare const distanceToSegment: (point: Point, line: Line) => number;
57
+ export declare const pointOnLine: (point: Point, line: Line, threshold?: number) => boolean;
58
+ export declare const pointOnPolyline: (point: Point, polyline: Polyline, threshold?: number) => boolean;
59
+ export declare const lineIntersectsLine: (lineA: Line, lineB: Line) => boolean;
60
+ export declare const lineIntersectsPolygon: (line: Line, polygon: Polygon) => boolean;
61
+ export declare const pointInBezierEquation: (p0: Point, p1: Point, p2: Point, p3: Point, [mx, my]: Point, lineThreshold: number) => boolean;
62
+ export declare const cubicBezierEquation: (curve: Curve) => (t: number, idx: number) => number;
63
+ export declare const polyLineFromCurve: (curve: Curve, segments?: number) => Polyline;
64
+ export declare const pointOnCurve: (point: Point, curve: Curve, threshold?: number) => boolean;
65
+ export declare const pointOnPolycurve: (point: Point, polycurve: Polycurve, threshold?: number) => boolean;
66
+ export declare const pointInPolygon: (point: Point, polygon: Polygon) => boolean;
67
+ export declare const pointOnPolygon: (point: Point, polygon: Polygon, threshold?: number) => boolean;
68
+ export declare const polygonInPolygon: (polygonA: Polygon, polygonB: Polygon) => boolean;
69
+ export declare const polygonIntersectPolygon: (polygonA: Polygon, polygonB: Polygon) => boolean;
70
+ export declare const pointOnEllipse: (point: Point, ellipse: Ellipse, threshold?: number) => boolean;
71
+ export declare const pointInEllipse: (point: Point, ellipse: Ellipse) => boolean;