@excalidraw/element 0.18.0-abeeaeb → 0.18.0-afa3a65

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 (79) hide show
  1. package/dist/dev/index.js +4889 -3737
  2. package/dist/dev/index.js.map +4 -4
  3. package/dist/prod/index.js +12 -12
  4. package/dist/types/common/src/colors.d.ts +8 -0
  5. package/dist/types/common/src/constants.d.ts +44 -0
  6. package/dist/types/common/src/keys.d.ts +2 -0
  7. package/dist/types/common/src/random.d.ts +7 -0
  8. package/dist/types/element/src/Scene.d.ts +1 -1
  9. package/dist/types/element/src/comparisons.d.ts +5 -3
  10. package/dist/types/element/src/delta.d.ts +23 -1
  11. package/dist/types/element/src/flowchart.d.ts +5 -1
  12. package/dist/types/element/src/frame.d.ts +2 -2
  13. package/dist/types/element/src/index.d.ts +1 -0
  14. package/dist/types/element/src/linearElementEditor.d.ts +10 -0
  15. package/dist/types/element/src/mutateElement.d.ts +1 -1
  16. package/dist/types/element/src/newElement.d.ts +24 -2
  17. package/dist/types/element/src/sizeHelpers.d.ts +6 -0
  18. package/dist/types/element/src/stickyNote.d.ts +183 -0
  19. package/dist/types/element/src/textElement.d.ts +2 -1
  20. package/dist/types/element/src/transform.d.ts +25 -6
  21. package/dist/types/element/src/typeChecks.d.ts +3 -2
  22. package/dist/types/element/src/types.d.ts +35 -6
  23. package/dist/types/element/src/utils.d.ts +7 -3
  24. package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +12 -0
  25. package/dist/types/excalidraw/actions/actionAlign.d.ts +6 -6
  26. package/dist/types/excalidraw/actions/actionBoundText.d.ts +8 -0
  27. package/dist/types/excalidraw/actions/actionCanvas.d.ts +28 -0
  28. package/dist/types/excalidraw/actions/actionClipboard.d.ts +8 -0
  29. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +4 -0
  30. package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +13 -1
  31. package/dist/types/excalidraw/actions/actionDeselect.d.ts +4 -0
  32. package/dist/types/excalidraw/actions/actionDistribute.d.ts +2 -2
  33. package/dist/types/excalidraw/actions/actionElementLink.d.ts +4 -0
  34. package/dist/types/excalidraw/actions/actionElementLock.d.ts +8 -0
  35. package/dist/types/excalidraw/actions/actionExport.d.ts +8 -0
  36. package/dist/types/excalidraw/actions/actionFinalize.d.ts +1 -0
  37. package/dist/types/excalidraw/actions/actionFrame.d.ts +63 -1
  38. package/dist/types/excalidraw/actions/actionGroup.d.ts +8 -0
  39. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +55 -1
  40. package/dist/types/excalidraw/actions/actionLink.d.ts +4 -0
  41. package/dist/types/excalidraw/actions/actionMenu.d.ts +4 -0
  42. package/dist/types/excalidraw/actions/actionProperties.d.ts +18 -6
  43. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +4 -0
  44. package/dist/types/excalidraw/actions/actionStyles.d.ts +5 -1
  45. package/dist/types/excalidraw/actions/actionToggleArrowBinding.d.ts +4 -0
  46. package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +4 -0
  47. package/dist/types/excalidraw/actions/actionToggleMidpointSnapping.d.ts +4 -0
  48. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +4 -0
  49. package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +4 -0
  50. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +4 -0
  51. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +4 -0
  52. package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +4 -0
  53. package/dist/types/excalidraw/actions/colorTargets.d.ts +39 -0
  54. package/dist/types/excalidraw/appState.d.ts +4 -0
  55. package/dist/types/excalidraw/components/App.arrowText.d.ts +40 -8
  56. package/dist/types/excalidraw/components/App.cursor.d.ts +8 -0
  57. package/dist/types/excalidraw/components/App.d.ts +92 -6
  58. package/dist/types/excalidraw/components/App.toolDrag.d.ts +63 -0
  59. package/dist/types/excalidraw/components/IconButton.d.ts +2 -0
  60. package/dist/types/excalidraw/components/Tools.d.ts +7 -2
  61. package/dist/types/excalidraw/components/canvases/NewElementCanvas.d.ts +2 -0
  62. package/dist/types/excalidraw/components/icons.d.ts +1 -0
  63. package/dist/types/excalidraw/components/shapeActionPredicates.d.ts +2 -2
  64. package/dist/types/excalidraw/data/blob.d.ts +8 -0
  65. package/dist/types/excalidraw/data/json.d.ts +4 -0
  66. package/dist/types/excalidraw/fonts/Fonts.d.ts +3 -2
  67. package/dist/types/excalidraw/hooks/useTextEditorFocus.d.ts +5 -5
  68. package/dist/types/excalidraw/renderer/helpers.d.ts +25 -0
  69. package/dist/types/excalidraw/renderer/interactiveScene.d.ts +1 -1
  70. package/dist/types/excalidraw/scene/Renderer.d.ts +50 -1
  71. package/dist/types/excalidraw/scene/index.d.ts +1 -1
  72. package/dist/types/excalidraw/scene/types.d.ts +1 -0
  73. package/dist/types/excalidraw/types.d.ts +30 -2
  74. package/dist/types/excalidraw/viewport.d.ts +4 -0
  75. package/dist/types/math/src/curve.d.ts +19 -12
  76. package/dist/types/math/src/segment.d.ts +6 -0
  77. package/dist/types/utils/src/export.d.ts +1 -0
  78. package/dist/types/utils/src/shape.d.ts +2 -2
  79. package/package.json +4 -4
@@ -62,6 +62,8 @@ export declare const actionToggleMidpointSnapping: {
62
62
  exportWithDarkMode: boolean;
63
63
  exportScale: number;
64
64
  currentItemStrokeColor: string;
65
+ currentItemStickynoteStrokeColor: string;
66
+ currentItemStickynoteBackgroundColor: string;
65
67
  currentItemBackgroundColor: string;
66
68
  currentItemFillStyle: import("@excalidraw/element/types").ExcalidrawElement["fillStyle"];
67
69
  currentItemStrokeWidthKey: import("@excalidraw/common").StrokeWidthKey;
@@ -171,6 +173,8 @@ export declare const actionToggleMidpointSnapping: {
171
173
  elementStroke: readonly string[] | null;
172
174
  elementBackground: readonly string[] | null;
173
175
  bucketFill: readonly string[] | null;
176
+ stickyNoteStroke: readonly string[] | null;
177
+ stickyNoteBackground: readonly string[] | null;
174
178
  };
175
179
  };
176
180
  captureUpdate: "NEVER";
@@ -65,6 +65,8 @@ export declare const actionToggleObjectsSnapMode: {
65
65
  exportWithDarkMode: boolean;
66
66
  exportScale: number;
67
67
  currentItemStrokeColor: string;
68
+ currentItemStickynoteStrokeColor: string;
69
+ currentItemStickynoteBackgroundColor: string;
68
70
  currentItemBackgroundColor: string;
69
71
  currentItemFillStyle: import("@excalidraw/element/types").ExcalidrawElement["fillStyle"];
70
72
  currentItemStrokeWidthKey: import("@excalidraw/common").StrokeWidthKey;
@@ -172,6 +174,8 @@ export declare const actionToggleObjectsSnapMode: {
172
174
  elementStroke: readonly string[] | null;
173
175
  elementBackground: readonly string[] | null;
174
176
  bucketFill: readonly string[] | null;
177
+ stickyNoteStroke: readonly string[] | null;
178
+ stickyNoteBackground: readonly string[] | null;
175
179
  };
176
180
  };
177
181
  captureUpdate: "EVENTUALLY";
@@ -70,6 +70,8 @@ export declare const actionToggleSearchMenu: {
70
70
  exportWithDarkMode: boolean;
71
71
  exportScale: number;
72
72
  currentItemStrokeColor: string;
73
+ currentItemStickynoteStrokeColor: string;
74
+ currentItemStickynoteBackgroundColor: string;
73
75
  currentItemBackgroundColor: string;
74
76
  currentItemFillStyle: import("@excalidraw/element/types").ExcalidrawElement["fillStyle"];
75
77
  currentItemStrokeWidthKey: import("@excalidraw/common").StrokeWidthKey;
@@ -158,6 +160,8 @@ export declare const actionToggleSearchMenu: {
158
160
  elementStroke: readonly string[] | null;
159
161
  elementBackground: readonly string[] | null;
160
162
  bucketFill: readonly string[] | null;
163
+ stickyNoteStroke: readonly string[] | null;
164
+ stickyNoteBackground: readonly string[] | null;
161
165
  };
162
166
  };
163
167
  captureUpdate: "EVENTUALLY";
@@ -67,6 +67,8 @@ export declare const actionToggleStats: {
67
67
  exportWithDarkMode: boolean;
68
68
  exportScale: number;
69
69
  currentItemStrokeColor: string;
70
+ currentItemStickynoteStrokeColor: string;
71
+ currentItemStickynoteBackgroundColor: string;
70
72
  currentItemBackgroundColor: string;
71
73
  currentItemFillStyle: import("@excalidraw/element/types").ExcalidrawElement["fillStyle"];
72
74
  currentItemStrokeWidthKey: import("@excalidraw/common").StrokeWidthKey;
@@ -172,6 +174,8 @@ export declare const actionToggleStats: {
172
174
  elementStroke: readonly string[] | null;
173
175
  elementBackground: readonly string[] | null;
174
176
  bucketFill: readonly string[] | null;
177
+ stickyNoteStroke: readonly string[] | null;
178
+ stickyNoteBackground: readonly string[] | null;
175
179
  };
176
180
  };
177
181
  captureUpdate: "EVENTUALLY";
@@ -64,6 +64,8 @@ export declare const actionToggleViewMode: {
64
64
  exportWithDarkMode: boolean;
65
65
  exportScale: number;
66
66
  currentItemStrokeColor: string;
67
+ currentItemStickynoteStrokeColor: string;
68
+ currentItemStickynoteBackgroundColor: string;
67
69
  currentItemBackgroundColor: string;
68
70
  currentItemFillStyle: import("@excalidraw/element/types").ExcalidrawElement["fillStyle"];
69
71
  currentItemStrokeWidthKey: import("@excalidraw/common").StrokeWidthKey;
@@ -172,6 +174,8 @@ export declare const actionToggleViewMode: {
172
174
  elementStroke: readonly string[] | null;
173
175
  elementBackground: readonly string[] | null;
174
176
  bucketFill: readonly string[] | null;
177
+ stickyNoteStroke: readonly string[] | null;
178
+ stickyNoteBackground: readonly string[] | null;
175
179
  };
176
180
  };
177
181
  captureUpdate: "EVENTUALLY";
@@ -64,6 +64,8 @@ export declare const actionToggleZenMode: {
64
64
  exportWithDarkMode: boolean;
65
65
  exportScale: number;
66
66
  currentItemStrokeColor: string;
67
+ currentItemStickynoteStrokeColor: string;
68
+ currentItemStickynoteBackgroundColor: string;
67
69
  currentItemBackgroundColor: string;
68
70
  currentItemFillStyle: import("@excalidraw/element/types").ExcalidrawElement["fillStyle"];
69
71
  currentItemStrokeWidthKey: import("@excalidraw/common").StrokeWidthKey;
@@ -172,6 +174,8 @@ export declare const actionToggleZenMode: {
172
174
  elementStroke: readonly string[] | null;
173
175
  elementBackground: readonly string[] | null;
174
176
  bucketFill: readonly string[] | null;
177
+ stickyNoteStroke: readonly string[] | null;
178
+ stickyNoteBackground: readonly string[] | null;
175
179
  };
176
180
  };
177
181
  captureUpdate: "EVENTUALLY";
@@ -0,0 +1,39 @@
1
+ import type { ColorPaletteCustom, ColorTuple } from "@excalidraw/common";
2
+ import type { ExcalidrawElement } from "@excalidraw/element/types";
3
+ import type { AppState } from "../types";
4
+ export type ColorProperty = "strokeColor" | "backgroundColor";
5
+ /**
6
+ * Sticky notes are their own color domain: own defaults, own top picks, no
7
+ * transparent. A pick targets the regular domain, the sticky domain, or both
8
+ * ("mixed" selections write both defaults and use the regular picker).
9
+ */
10
+ export type ColorTargetKind = "regular" | "sticky" | "mixed";
11
+ export type ColorDefaultKey = "currentItemStrokeColor" | "currentItemBackgroundColor" | "currentItemStickynoteStrokeColor" | "currentItemStickynoteBackgroundColor";
12
+ export type ColorTargetAppState = Pick<AppState, "selectedElementIds" | "editingTextElement" | "activeTool" | ColorDefaultKey>;
13
+ export type ColorTarget = {
14
+ kind: ColorTargetKind;
15
+ property: ColorProperty;
16
+ /** the current-item defaults a pick is written to (normalized per domain) */
17
+ appStateKeys: readonly ColorDefaultKey[];
18
+ /** the default shown when no element is targeted */
19
+ currentValue: string;
20
+ palette: ColorPaletteCustom;
21
+ topPicks: ColorTuple;
22
+ customizableTopPicks: keyof AppState["colorTopPicks"];
23
+ excludedColors: readonly string[] | undefined;
24
+ };
25
+ /**
26
+ * Who a stroke/background pick targets. Resolve it from the state an action
27
+ * runs against, at execution time — never capture it in a render closure:
28
+ * the memoized picker keeps a stale `onChange`, and the always-visible top
29
+ * picks fire it without a re-render.
30
+ *
31
+ * Targets are the selected color-capable elements (for stroke incl. bound
32
+ * labels, since a note's visible text is its label) plus the text being
33
+ * edited (`handleTextWysiwyg` deselects while editing) — or, for a
34
+ * background pick on a note's label, the note (see `getColorTargetElement`).
35
+ * With no target, the active tool decides the domain.
36
+ */
37
+ export declare const resolveColorTarget: (appState: ColorTargetAppState, elements: readonly ExcalidrawElement[], property: ColorProperty) => ColorTarget;
38
+ /** the current-item default updates for a picked color */
39
+ export declare const getColorTargetAppStateUpdates: (target: ColorTarget, color: string) => Partial<AppState>;
@@ -44,6 +44,8 @@ export declare const clearAppStateForLocalStorage: (appState: Partial<AppState>)
44
44
  exportEmbedScene?: boolean | undefined;
45
45
  exportWithDarkMode?: boolean | undefined;
46
46
  currentItemStrokeColor?: string | undefined;
47
+ currentItemStickynoteStrokeColor?: string | undefined;
48
+ currentItemStickynoteBackgroundColor?: string | undefined;
47
49
  currentItemBackgroundColor?: string | undefined;
48
50
  currentItemFillStyle?: import("@excalidraw/element/types").FillStyle | undefined;
49
51
  currentItemStrokeWidthKey?: import("@excalidraw/common").StrokeWidthKey | undefined;
@@ -82,6 +84,8 @@ export declare const clearAppStateForLocalStorage: (appState: Partial<AppState>)
82
84
  elementStroke: readonly string[] | null;
83
85
  elementBackground: readonly string[] | null;
84
86
  bucketFill: readonly string[] | null;
87
+ stickyNoteStroke: readonly string[] | null;
88
+ stickyNoteBackground: readonly string[] | null;
85
89
  } | undefined;
86
90
  };
87
91
  export declare const cleanAppStateForExport: (appState: Partial<AppState>) => {
@@ -1,15 +1,23 @@
1
+ import { LinearElementEditor } from "@excalidraw/element";
1
2
  import type { ArrowEndpoint } from "@excalidraw/element";
2
- import type { ExcalidrawElement, ExcalidrawTextElement, FixedPoint, NonDeleted } from "@excalidraw/element/types";
3
+ import type { ExcalidrawElement, ExcalidrawTextElement, FixedPoint, NonDeleted, NonDeletedExcalidrawElement } from "@excalidraw/element/types";
3
4
  import type App from "./App";
4
- import type { AppState } from "../types";
5
+ import type { AppState, PointerDownState } from "../types";
5
6
  /**
6
- * The text tool's interaction with arrows: the hover affordance showing where
7
- * a click would attach text to an arrow — a free endpoint (binds the arrow to
8
- * a new text element positioned against that endpoint) or the arrow's midpoint
9
- * (adds a label bound to the arrow) — and the endpoint-bound flavor of
10
- * drag-sizing a new text.
7
+ * Text ↔ arrow interactions.
11
8
  *
12
- * The scene-level logic lives in `@excalidraw/element`'s `arrowEndpointText.ts`.
9
+ * With the text tool: the hover affordance showing where a click would attach
10
+ * text to an arrow — a free endpoint (binds the arrow to a new text element
11
+ * positioned against that endpoint) or the arrow's midpoint (adds a label
12
+ * bound to the arrow) — and the endpoint-bound flavor of drag-sizing a new
13
+ * text.
14
+ *
15
+ * With the selection tool: dragging an arrow's existing label along the arrow
16
+ * — the grab affordance, the drag itself, and where a double-click starts
17
+ * editing a label the drag has moved.
18
+ *
19
+ * The scene-level logic lives in `@excalidraw/element`'s
20
+ * `arrowEndpointText.ts` and `linearElementEditor.ts`.
13
21
  */
14
22
  export declare class AppArrowText {
15
23
  private app;
@@ -69,4 +77,28 @@ export declare class AppArrowText {
69
77
  x: number;
70
78
  y: number;
71
79
  }): boolean;
80
+ /**
81
+ * Whether the arrow's label is what a grab at this position would pick up:
82
+ * the pointer is over the label, and no element stacked above the arrow
83
+ * owns the hit instead.
84
+ */
85
+ isBoundTextGrabbable(element: NonDeletedExcalidrawElement, x: number, y: number): boolean;
86
+ /**
87
+ * The pointer-move half of dragging a label along its arrow. Owns the move
88
+ * whenever the gesture started on the label (`pointerDownState.hit.arrowLabel`),
89
+ * dragging only once past the threshold. Returns whether it owned it.
90
+ */
91
+ maybeDragLabel(linearElementEditor: LinearElementEditor, pointerDownState: PointerDownState, pointerCoords: {
92
+ x: number;
93
+ y: number;
94
+ }): boolean;
95
+ /**
96
+ * Where a double-click on a labeled arrow should start text editing: the
97
+ * center of the label itself, which a label drag may have moved away from
98
+ * the arrow's midpoint. Null when the element is not a labeled arrow.
99
+ */
100
+ getLabelCenter(element: ExcalidrawElement): {
101
+ x: number;
102
+ y: number;
103
+ } | null;
72
104
  }
@@ -24,6 +24,14 @@ export declare class AppCursor {
24
24
  reset: () => void;
25
25
  /** applies the given tool's cursor (defaults to the active tool) */
26
26
  applyForTool: (activeTool?: AppState["activeTool"]) => void;
27
+ /**
28
+ * Re-runs the hover cursor logic at the last known pointer position by
29
+ * re-dispatching a synthetic pointermove — for state changes that alter
30
+ * what hovering means without the pointer moving (e.g. the tool reverting
31
+ * to selection after an element is created). Mouse only: touch and pen
32
+ * have no resting hover to restore.
33
+ */
34
+ refreshHover: () => void;
27
35
  /** clears the inline cursor so the environment default (CSS) applies */
28
36
  private clear;
29
37
  private applyEraser;
@@ -3,6 +3,7 @@ import { AppEventBus, type EXPORT_IMAGE_TYPES, Emitter, type EditorInterface, ty
3
3
  import { LinearElementEditor, Scene, Store, type ElementUpdate, StoreDelta, type ApplyToOptions } from "@excalidraw/element";
4
4
  import type { LocalPoint, Radians } from "@excalidraw/math";
5
5
  import type { ExcalidrawElement, ExcalidrawTextElement, NonDeleted, NonDeletedExcalidrawElement, ExcalidrawTextContainer, ExcalidrawFrameLikeElement, ExcalidrawIframeElement, ExcalidrawEmbeddableElement, Ordered, SceneElementsMap } from "@excalidraw/element/types";
6
+ import type { ArrowEndpoint, TransformHandleDirection } from "@excalidraw/element";
6
7
  import type { Mutable } from "@excalidraw/common/utility-types";
7
8
  import { ActionManager } from "../actions/manager";
8
9
  import { History } from "../history";
@@ -16,6 +17,7 @@ import { LassoTrail } from "../lasso";
16
17
  import { EraserTrail } from "../eraser";
17
18
  import { AppArrowText } from "./App.arrowText";
18
19
  import { AppBucketFill } from "./App.bucketFill";
20
+ import { AppToolDrag } from "./App.toolDrag";
19
21
  import { AppCursor } from "./App.cursor";
20
22
  import { AppDrawShape } from "./App.drawshape";
21
23
  import { AppFlowchart } from "./App.flowchart";
@@ -82,6 +84,8 @@ declare class App extends React.Component<AppProps, AppState> {
82
84
  editorInterface: EditorInterface;
83
85
  private stylesPanelMode;
84
86
  private excalidrawContainerRef;
87
+ get ownerDocument(): Document;
88
+ get ownerWindow(): Window & typeof globalThis;
85
89
  scene: Scene;
86
90
  fonts: Fonts;
87
91
  renderer: Renderer;
@@ -93,7 +97,7 @@ declare class App extends React.Component<AppProps, AppState> {
93
97
  library: AppClassProperties["library"];
94
98
  libraryItemsFromStorage: LibraryItems | undefined;
95
99
  id: string;
96
- private store;
100
+ store: Store;
97
101
  private history;
98
102
  excalidrawContainerValue: {
99
103
  container: HTMLDivElement | null;
@@ -119,6 +123,7 @@ declare class App extends React.Component<AppProps, AppState> {
119
123
  private appStateObserver;
120
124
  onStateChange: OnStateChange;
121
125
  bucketFill: AppBucketFill;
126
+ toolDrag: AppToolDrag;
122
127
  flowchart: AppFlowchart;
123
128
  cursor: AppCursor;
124
129
  arrowText: AppArrowText;
@@ -127,6 +132,13 @@ declare class App extends React.Component<AppProps, AppState> {
127
132
  private textWysiwygSubmitHandler;
128
133
  hitLinkElement?: NonDeletedExcalidrawElement;
129
134
  lastPointerDownEvent: React.PointerEvent<HTMLElement> | null;
135
+ /**
136
+ * the handle of the resize in progress while `state.isResizing` — for UI
137
+ * that words itself by handle (a sticky note's corners resize
138
+ * proportionally, its edges freely); not app state, so it costs no
139
+ * re-render of its own
140
+ */
141
+ activeResizeHandle: TransformHandleDirection | null;
130
142
  lastPointerUpEvent: React.PointerEvent<HTMLElement> | PointerEvent | null;
131
143
  lastPointerUpIsDoubleClick: boolean;
132
144
  lastPointerMoveEvent: PointerEvent | null;
@@ -185,6 +197,7 @@ declare class App extends React.Component<AppProps, AppState> {
185
197
  wasAddedToSelection: boolean;
186
198
  hasBeenDuplicated: boolean;
187
199
  hasHitCommonBoundingBoxOfSelectedElements: boolean;
200
+ arrowLabel: boolean;
188
201
  };
189
202
  withCmdOrCtrl: boolean;
190
203
  drag: {
@@ -247,6 +260,7 @@ declare class App extends React.Component<AppProps, AppState> {
247
260
  wasAddedToSelection: boolean;
248
261
  hasBeenDuplicated: boolean;
249
262
  hasHitCommonBoundingBoxOfSelectedElements: boolean;
263
+ arrowLabel: boolean;
250
264
  };
251
265
  withCmdOrCtrl: boolean;
252
266
  drag: {
@@ -363,6 +377,11 @@ declare class App extends React.Component<AppProps, AppState> {
363
377
  getEffectiveGridSize: () => NullableGridSize;
364
378
  private getTextCreationGridPoint;
365
379
  private getHTMLIFrameElement;
380
+ /**
381
+ * AI-generated iframe elements aren't interactive while their generation
382
+ * is still in progress (the partial content is render-only).
383
+ */
384
+ private isIframeLikeInteractive;
366
385
  private handleIframeLikeElementHover;
367
386
  /** @returns true if iframe-like element click handled */
368
387
  private handleIframeLikeCenterClick;
@@ -571,9 +590,12 @@ declare class App extends React.Component<AppProps, AppState> {
571
590
  }) & {
572
591
  preferSelected?: boolean;
573
592
  }): NonDeleted<ExcalidrawElement> | null;
574
- private getElementsAtPosition;
593
+ getElementsAtPosition(x: number, y: number, opts?: {
594
+ includeBoundTextElement?: boolean;
595
+ includeLockedElements?: boolean;
596
+ }): NonDeleted<ExcalidrawElement>[];
575
597
  getElementHitThreshold(element: ExcalidrawElement): number;
576
- private hitElement;
598
+ hitElement(x: number, y: number, element: NonDeletedExcalidrawElement, considerBoundingBox?: boolean): boolean;
577
599
  getTextBindableContainerAtPosition(x: number, y: number): (Readonly<{
578
600
  id: string;
579
601
  x: number;
@@ -601,6 +623,7 @@ declare class App extends React.Component<AppProps, AppState> {
601
623
  frameId: string | null;
602
624
  boundElements: readonly import("@excalidraw/element/types").BoundElement[] | null;
603
625
  updated: number;
626
+ created: number | null;
604
627
  link: string | null;
605
628
  locked: boolean;
606
629
  customData?: Record<string, any>;
@@ -635,6 +658,43 @@ declare class App extends React.Component<AppProps, AppState> {
635
658
  frameId: string | null;
636
659
  boundElements: readonly import("@excalidraw/element/types").BoundElement[] | null;
637
660
  updated: number;
661
+ created: number | null;
662
+ link: string | null;
663
+ locked: boolean;
664
+ customData?: Record<string, any>;
665
+ }> & Readonly<{
666
+ type: "stickynote";
667
+ baseHeight: number;
668
+ }> & {
669
+ isDeleted: false;
670
+ }) | (Readonly<{
671
+ id: string;
672
+ x: number;
673
+ y: number;
674
+ strokeColor: string;
675
+ backgroundColor: string;
676
+ fillStyle: import("@excalidraw/element/types").FillStyle;
677
+ strokeWidth: number;
678
+ strokeStyle: import("@excalidraw/element/types").StrokeStyle;
679
+ roundness: null | {
680
+ type: import("@excalidraw/element/types").RoundnessType;
681
+ value?: number;
682
+ };
683
+ roughness: number;
684
+ opacity: number;
685
+ width: number;
686
+ height: number;
687
+ angle: Radians;
688
+ seed: number;
689
+ version: number;
690
+ versionNonce: number;
691
+ index: import("@excalidraw/element/types").FractionalIndex | null;
692
+ isDeleted: boolean;
693
+ groupIds: readonly import("@excalidraw/element/types").GroupId[];
694
+ frameId: string | null;
695
+ boundElements: readonly import("@excalidraw/element/types").BoundElement[] | null;
696
+ updated: number;
697
+ created: number | null;
638
698
  link: string | null;
639
699
  locked: boolean;
640
700
  customData?: Record<string, any>;
@@ -669,6 +729,7 @@ declare class App extends React.Component<AppProps, AppState> {
669
729
  frameId: string | null;
670
730
  boundElements: readonly import("@excalidraw/element/types").BoundElement[] | null;
671
731
  updated: number;
732
+ created: number | null;
672
733
  link: string | null;
673
734
  locked: boolean;
674
735
  customData?: Record<string, any>;
@@ -703,6 +764,7 @@ declare class App extends React.Component<AppProps, AppState> {
703
764
  frameId: string | null;
704
765
  boundElements: readonly import("@excalidraw/element/types").BoundElement[] | null;
705
766
  updated: number;
767
+ created: number | null;
706
768
  link: string | null;
707
769
  locked: boolean;
708
770
  customData?: Record<string, any>;
@@ -731,7 +793,25 @@ declare class App extends React.Component<AppProps, AppState> {
731
793
  * so the whole create-and-type lands in a single entry.
732
794
  */
733
795
  private isEditingTextContent;
734
- private startTextEditing;
796
+ startTextEditing: ({ sceneX, sceneY, insertAtParentCenter, container, autoEdit, initialCaretSceneCoords, arrowEndpoint, }: {
797
+ /** X position to insert text at */
798
+ sceneX: number;
799
+ /** Y position to insert text at */
800
+ sceneY: number;
801
+ /** whether to attempt to insert at element center if applicable */
802
+ insertAtParentCenter?: boolean;
803
+ container?: ExcalidrawTextContainer | null;
804
+ autoEdit?: boolean;
805
+ initialCaretSceneCoords?: {
806
+ x: number;
807
+ y: number;
808
+ };
809
+ /**
810
+ * creates the text as a label for this arrow endpoint: the binding then
811
+ * dictates the text's position and alignment, overriding (sceneX, sceneY)
812
+ */
813
+ arrowEndpoint?: ArrowEndpoint | null;
814
+ }) => void;
735
815
  private startImageCropping;
736
816
  private finishImageCropping;
737
817
  private shouldHandleBrowserCanvasDoubleClick;
@@ -784,6 +864,10 @@ declare class App extends React.Component<AppProps, AppState> {
784
864
  private handleCanvasPointerMove;
785
865
  private handleEraser;
786
866
  private handleTouchMove;
867
+ /**
868
+ * Applies the hover affordances of a selected linear element: the cursor,
869
+ * plus the hovered-handle state that renders them highlighted.
870
+ */
787
871
  handleHoverSelectedLinearElement(linearElementEditor: LinearElementEditor, scenePointerX: number, scenePointerY: number): void;
788
872
  private handleCanvasPointerDown;
789
873
  private handleCanvasPointerUp;
@@ -826,8 +910,10 @@ declare class App extends React.Component<AppProps, AppState> {
826
910
  }) => NonDeleted<ExcalidrawEmbeddableElement> | undefined;
827
911
  private newImagePlaceholder;
828
912
  private handleLinearElementOnPointerDown;
829
- private getCurrentItemRoundness;
830
- private getCurrentItemStrokeWidth;
913
+ getCurrentItemRoundness(elementType: "selection" | "rectangle" | "stickynote" | "diamond" | "ellipse" | "iframe" | "embeddable"): {
914
+ type: 2 | 3;
915
+ } | null;
916
+ getCurrentItemStrokeWidth(elementType: ExcalidrawElement["type"]): number;
831
917
  private createGenericElementOnPointerDown;
832
918
  private createFrameElementOnPointerDown;
833
919
  private maybeCacheReferenceSnapPoints;
@@ -0,0 +1,63 @@
1
+ import type { ExcalidrawNonSelectionElement, NonDeleted } from "@excalidraw/element/types";
2
+ import type App from "./App";
3
+ import type { ToolType } from "../types";
4
+ type ScenePoint = {
5
+ x: number;
6
+ y: number;
7
+ };
8
+ /** what a drag places: any element the new-element canvas can preview */
9
+ type DraggedElement = NonDeleted<ExcalidrawNonSelectionElement>;
10
+ /**
11
+ * A tool the user can drag out of the toolbar to drop a default-sized element
12
+ * where the pointer is released.
13
+ */
14
+ type DraggableTool = {
15
+ /** the element the drop creates, centered on the pointer */
16
+ createElement: (app: App, center: ScenePoint) => DraggedElement;
17
+ /** what the tool does once its element is on the canvas (e.g. start editing) */
18
+ onDrop?: (app: App, element: DraggedElement) => void;
19
+ };
20
+ /**
21
+ * The tools that can be dragged out of the toolbar. Add an entry to make a
22
+ * tool's button draggable — the gesture, preview and drop are shared.
23
+ */
24
+ export declare const DRAGGABLE_TOOLS: Partial<Record<ToolType, DraggableTool>>;
25
+ /** CSS opacity of the preview canvas while dragging */
26
+ export declare const TOOL_DRAG_PREVIEW_OPACITY = 0.5;
27
+ /**
28
+ * Dragging a tool out of the toolbar. The preview element exists only here
29
+ * until the drop — it is not in the scene, the store or the history, so
30
+ * collaborators never see it and an aborted drag leaves nothing behind. It
31
+ * is painted by the `NewElementCanvas`, drawn exactly as it will land, with
32
+ * the canvas itself made translucent.
33
+ *
34
+ * The button arms on pointerdown; the drag starts once the pointer has
35
+ * moved `DRAGGING_THRESHOLD`, so a plain click still selects the tool. The
36
+ * gesture lives on the owner window (the pointer leaves the button at once),
37
+ * like the other pointer gestures in `App`.
38
+ */
39
+ export declare class AppToolDrag {
40
+ private app;
41
+ constructor(app: App);
42
+ /** the element under the pointer while dragging, `null` otherwise */
43
+ preview: DraggedElement | null;
44
+ private armed;
45
+ private tool;
46
+ private type;
47
+ static isDraggable: (type: ToolType) => boolean;
48
+ isDragging: () => boolean;
49
+ /**
50
+ * Arm a drag from a tool button's pointerdown. Returns whether the tool is
51
+ * draggable (the caller lets a non-draggable press fall through).
52
+ */
53
+ handleButtonPointerDown: (type: ToolType, event: PointerEvent) => boolean;
54
+ private onPointerMove;
55
+ private onPointerUp;
56
+ private onKeyDown;
57
+ /** drop the gesture without a trace */
58
+ cancel: () => void;
59
+ private isOverCanvas;
60
+ private addListeners;
61
+ private removeListeners;
62
+ }
63
+ export {};
@@ -41,6 +41,8 @@ type IconButtonProps = (IconButtonBaseProps & {
41
41
  onSelect?(data: {
42
42
  pointerType: PointerType | null;
43
43
  }): void;
44
+ /** the press that may become a click — e.g. to arm a drag out of the toolbar */
45
+ onPointerDown?(event: React.PointerEvent<HTMLButtonElement>): void;
44
46
  });
45
47
  export declare const IconButton: React.ForwardRefExoticComponent<IconButtonProps & React.RefAttributes<unknown>>;
46
48
  export {};
@@ -1,7 +1,7 @@
1
1
  import type { AppClassProperties, AppState, ToolType, UIAppState } from "../types";
2
2
  export type ToolConfig = {
3
3
  icon: React.ReactNode;
4
- /** letter shortcut(s) — the first one is shown in tooltips */
4
+ /** letter shortcut(s) — the first one is shown in tooltips and badges */
5
5
  letterKey?: string | readonly string[];
6
6
  /** whether `letterKey` requires Shift to be held (e.g. Shift+X) */
7
7
  shiftKey?: boolean;
@@ -31,6 +31,7 @@ export declare const TOOLS: {
31
31
  line: ToolConfig;
32
32
  freedraw: ToolConfig;
33
33
  text: ToolConfig;
34
+ stickynote: ToolConfig;
34
35
  image: ToolConfig;
35
36
  eraser: ToolConfig;
36
37
  frame: ToolConfig;
@@ -49,7 +50,7 @@ export declare const TOGGLE_TOOLS: readonly (ToolType | "custom")[];
49
50
  export declare const getToolLetter: (type: ToolbarToolType) => string | undefined;
50
51
  /** human-readable shortcut hint, e.g. "R or 2", used in tooltips & aria */
51
52
  export declare const getToolShortcut: (type: ToolbarToolType) => string;
52
- export declare const findShapeByKey: (key: string, app: AppClassProperties, shiftKey?: boolean) => "line" | "arrow" | "text" | "selection" | "rectangle" | "diamond" | "ellipse" | "embeddable" | "image" | "frame" | "freedraw" | "lasso" | "eraser" | "hand" | "laser" | "autoshape" | "bucketfill" | null;
53
+ export declare const findShapeByKey: (key: string, app: AppClassProperties, shiftKey?: boolean) => "line" | "arrow" | "text" | "selection" | "rectangle" | "stickynote" | "diamond" | "ellipse" | "embeddable" | "image" | "frame" | "freedraw" | "lasso" | "eraser" | "hand" | "laser" | "autoshape" | "bucketfill" | null;
53
54
  /**
54
55
  * Whether a toolbar entry activating the given tool renders disabled — true
55
56
  * when the active tool is host-controlled (`props.activeTool`) and the entry
@@ -99,6 +100,10 @@ export declare const TextToolButton: {
99
100
  ({ app, activeTool, hideKeyBinding, hideShortcut, }: ToolButtonComponentProps): import("react/jsx-runtime").JSX.Element;
100
101
  displayName: string;
101
102
  };
103
+ export declare const StickyNoteToolButton: {
104
+ ({ app, activeTool, hideKeyBinding, hideShortcut, }: ToolButtonComponentProps): import("react/jsx-runtime").JSX.Element;
105
+ displayName: string;
106
+ };
102
107
  export declare const ImageToolButton: {
103
108
  ({ app, activeTool, hideKeyBinding, hideShortcut, }: ToolButtonComponentProps): import("react/jsx-runtime").JSX.Element;
104
109
  displayName: string;
@@ -10,6 +10,8 @@ interface NewElementCanvasProps {
10
10
  scale: number;
11
11
  rc: RoughCanvas;
12
12
  renderConfig: StaticCanvasRenderConfig;
13
+ /** CSS opacity of the whole canvas — a translucent preview of a finished element */
14
+ opacity?: number;
13
15
  }
14
16
  declare const NewElementCanvas: (props: NewElementCanvasProps) => import("react/jsx-runtime").JSX.Element;
15
17
  export default NewElementCanvas;
@@ -200,6 +200,7 @@ export declare const alertTriangleIcon: import("react/jsx-runtime").JSX.Element;
200
200
  export declare const eyeDropperIconSvgPaths: readonly ["M4 16l11.7 -11.7a1 1 0 0 1 1.4 0l2.6 2.6a1 1 0 0 1 0 1.4l-11.7 11.7h-4v-4z", "M11 7l6 6"];
201
201
  export declare const eyeDropperIcon: import("react/jsx-runtime").JSX.Element;
202
202
  export declare const frameToolIcon: import("react/jsx-runtime").JSX.Element;
203
+ export declare const stickyNoteToolIcon: import("react/jsx-runtime").JSX.Element;
203
204
  export declare const mermaidLogoIcon: import("react/jsx-runtime").JSX.Element;
204
205
  export declare const RetryIcon: import("react/jsx-runtime").JSX.Element;
205
206
  export declare const stackPushIcon: import("react/jsx-runtime").JSX.Element;
@@ -1,7 +1,7 @@
1
- import type { ExcalidrawElement, NonDeletedElementsMap, NonDeletedSceneElementsMap } from "@excalidraw/element/types";
1
+ import type { ElementsMap, ExcalidrawElement, NonDeletedElementsMap, NonDeletedSceneElementsMap } from "@excalidraw/element/types";
2
2
  import type { AppClassProperties, UIAppState } from "../types";
3
3
  export declare const canChangeStrokeColor: (appState: UIAppState, targetElements: ExcalidrawElement[]) => boolean;
4
- export declare const canChangeBackgroundColor: (appState: UIAppState, targetElements: ExcalidrawElement[]) => boolean;
4
+ export declare const canChangeBackgroundColor: (appState: UIAppState, targetElements: ExcalidrawElement[], elementsMap: ElementsMap) => boolean;
5
5
  /**
6
6
  * Single source of truth for "which shape-action controls are relevant right
7
7
  * now". Each flag answers whether a given control should be shown, given the
@@ -125,6 +125,8 @@ fileHandle?: FileSystemFileHandle | null) => Promise<{
125
125
  exportEmbedScene: boolean;
126
126
  exportWithDarkMode: boolean;
127
127
  currentItemStrokeColor: string;
128
+ currentItemStickynoteStrokeColor: string;
129
+ currentItemStickynoteBackgroundColor: string;
128
130
  currentItemBackgroundColor: string;
129
131
  currentItemFillStyle: ExcalidrawElement["fillStyle"];
130
132
  currentItemStrokeWidthKey: import("@excalidraw/common").StrokeWidthKey;
@@ -179,6 +181,8 @@ fileHandle?: FileSystemFileHandle | null) => Promise<{
179
181
  elementStroke: readonly string[] | null;
180
182
  elementBackground: readonly string[] | null;
181
183
  bucketFill: readonly string[] | null;
184
+ stickyNoteStroke: readonly string[] | null;
185
+ stickyNoteBackground: readonly string[] | null;
182
186
  };
183
187
  };
184
188
  files: import("../types").BinaryFiles;
@@ -299,6 +303,8 @@ fileHandle?: FileSystemFileHandle | null) => Promise<{
299
303
  exportEmbedScene: boolean;
300
304
  exportWithDarkMode: boolean;
301
305
  currentItemStrokeColor: string;
306
+ currentItemStickynoteStrokeColor: string;
307
+ currentItemStickynoteBackgroundColor: string;
302
308
  currentItemBackgroundColor: string;
303
309
  currentItemFillStyle: ExcalidrawElement["fillStyle"];
304
310
  currentItemStrokeWidthKey: import("@excalidraw/common").StrokeWidthKey;
@@ -353,6 +359,8 @@ fileHandle?: FileSystemFileHandle | null) => Promise<{
353
359
  elementStroke: readonly string[] | null;
354
360
  elementBackground: readonly string[] | null;
355
361
  bucketFill: readonly string[] | null;
362
+ stickyNoteStroke: readonly string[] | null;
363
+ stickyNoteBackground: readonly string[] | null;
356
364
  };
357
365
  };
358
366
  files: import("../types").BinaryFiles;
@@ -123,6 +123,8 @@ export declare const loadFromJSON: (localAppState: AppState, localElements: read
123
123
  exportEmbedScene: boolean;
124
124
  exportWithDarkMode: boolean;
125
125
  currentItemStrokeColor: string;
126
+ currentItemStickynoteStrokeColor: string;
127
+ currentItemStickynoteBackgroundColor: string;
126
128
  currentItemBackgroundColor: string;
127
129
  currentItemFillStyle: ExcalidrawElement["fillStyle"];
128
130
  currentItemStrokeWidthKey: import("@excalidraw/common").StrokeWidthKey;
@@ -177,6 +179,8 @@ export declare const loadFromJSON: (localAppState: AppState, localElements: read
177
179
  elementStroke: readonly string[] | null;
178
180
  elementBackground: readonly string[] | null;
179
181
  bucketFill: readonly string[] | null;
182
+ stickyNoteStroke: readonly string[] | null;
183
+ stickyNoteBackground: readonly string[] | null;
180
184
  };
181
185
  };
182
186
  files: BinaryFiles;