@nextcloud/excalidraw-common 0.18.0-4e1c0ab → 0.18.0-nc.1

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 (225) hide show
  1. package/dist/dev/index.js +204 -85
  2. package/dist/dev/index.js.map +3 -3
  3. package/dist/prod/index.js +3 -3
  4. package/dist/types/common/src/colors.d.ts +23 -1
  5. package/dist/types/common/src/constants.d.ts +66 -7
  6. package/dist/types/common/src/keys.d.ts +4 -0
  7. package/dist/types/common/src/points.d.ts +1 -1
  8. package/dist/types/common/src/random.d.ts +7 -0
  9. package/dist/types/common/src/utils.d.ts +6 -43
  10. package/dist/types/element/src/Scene.d.ts +16 -5
  11. package/dist/types/element/src/align.d.ts +2 -2
  12. package/dist/types/element/src/arrowEndpointText.d.ts +49 -0
  13. package/dist/types/element/src/arrows/focus.d.ts +5 -2
  14. package/dist/types/element/src/binding.d.ts +28 -13
  15. package/dist/types/element/src/bounds.d.ts +24 -7
  16. package/dist/types/element/src/bucketFill.d.ts +110 -0
  17. package/dist/types/element/src/collision.d.ts +14 -5
  18. package/dist/types/element/src/comparisons.d.ts +8 -5
  19. package/dist/types/element/src/convertToShape.d.ts +23 -0
  20. package/dist/types/element/src/cropElement.d.ts +36 -4
  21. package/dist/types/element/src/delta.d.ts +23 -1
  22. package/dist/types/element/src/distribute.d.ts +2 -2
  23. package/dist/types/element/src/dragElements.d.ts +27 -0
  24. package/dist/types/element/src/duplicate.d.ts +64 -3
  25. package/dist/types/element/src/embeddable.d.ts +2 -2
  26. package/dist/types/element/src/flowchart.d.ts +11 -7
  27. package/dist/types/element/src/fractionalIndex.d.ts +2 -2
  28. package/dist/types/element/src/frame.d.ts +11 -10
  29. package/dist/types/element/src/groups.d.ts +10 -15
  30. package/dist/types/element/src/index.d.ts +6 -1
  31. package/dist/types/element/src/linearElementEditor.d.ts +27 -10
  32. package/dist/types/element/src/listMarker.d.ts +34 -0
  33. package/dist/types/element/src/mutateElement.d.ts +1 -1
  34. package/dist/types/element/src/newElement.d.ts +53 -3
  35. package/dist/types/element/src/renderElement.d.ts +21 -7
  36. package/dist/types/element/src/resizeElements.d.ts +8 -1
  37. package/dist/types/element/src/selection.d.ts +6 -12
  38. package/dist/types/element/src/shape.d.ts +27 -1
  39. package/dist/types/element/src/sizeHelpers.d.ts +6 -0
  40. package/dist/types/element/src/sortElements.d.ts +10 -0
  41. package/dist/types/element/src/stickyNote.d.ts +183 -0
  42. package/dist/types/element/src/textElement.d.ts +20 -9
  43. package/dist/types/element/src/transform.d.ts +26 -7
  44. package/dist/types/element/src/typeChecks.d.ts +29 -27
  45. package/dist/types/element/src/types.d.ts +43 -7
  46. package/dist/types/element/src/utils.d.ts +15 -4
  47. package/dist/types/element/src/zindex.d.ts +2 -2
  48. package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +87 -18
  49. package/dist/types/excalidraw/actions/actionAlign.d.ts +6 -6
  50. package/dist/types/excalidraw/actions/actionBoundText.d.ts +74 -203
  51. package/dist/types/excalidraw/actions/actionCanvas.d.ts +266 -941
  52. package/dist/types/excalidraw/actions/actionClipboard.d.ts +58 -12
  53. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +29 -6
  54. package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +4 -518
  55. package/dist/types/excalidraw/actions/actionDeselect.d.ts +30 -7
  56. package/dist/types/excalidraw/actions/actionDistribute.d.ts +2 -3
  57. package/dist/types/excalidraw/actions/actionElementLink.d.ts +29 -6
  58. package/dist/types/excalidraw/actions/actionElementLock.d.ts +59 -13
  59. package/dist/types/excalidraw/actions/actionExport.d.ts +64 -18
  60. package/dist/types/excalidraw/actions/actionFinalize.d.ts +1 -0
  61. package/dist/types/excalidraw/actions/actionFrame.d.ts +114 -651
  62. package/dist/types/excalidraw/actions/actionGroup.d.ts +73 -27
  63. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +84 -9
  64. package/dist/types/excalidraw/actions/actionLink.d.ts +30 -7
  65. package/dist/types/excalidraw/actions/actionMenu.d.ts +29 -6
  66. package/dist/types/excalidraw/actions/actionProperties.d.ts +96 -34
  67. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +34 -11
  68. package/dist/types/excalidraw/actions/actionStyles.d.ts +30 -7
  69. package/dist/types/excalidraw/actions/actionTextAutoResize.d.ts +1 -1
  70. package/dist/types/excalidraw/actions/actionToggleArrowBinding.d.ts +30 -7
  71. package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +33 -11
  72. package/dist/types/excalidraw/actions/actionToggleMidpointSnapping.d.ts +30 -7
  73. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +30 -7
  74. package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +33 -11
  75. package/dist/types/excalidraw/actions/actionToggleShapeSwitch.d.ts +1 -1
  76. package/dist/types/excalidraw/actions/{actionEmbeddable.d.ts → actionToggleShowHints.d.ts} +45 -19
  77. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +30 -7
  78. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +31 -8
  79. package/dist/types/excalidraw/actions/actionToggleWrap.d.ts +12 -0
  80. package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +30 -7
  81. package/dist/types/excalidraw/actions/colorTargets.d.ts +39 -0
  82. package/dist/types/excalidraw/actions/index.d.ts +3 -2
  83. package/dist/types/excalidraw/actions/manager.d.ts +1 -0
  84. package/dist/types/excalidraw/actions/shortcuts.d.ts +1 -1
  85. package/dist/types/excalidraw/actions/types.d.ts +8 -4
  86. package/dist/types/excalidraw/{animated-trail.d.ts → animatedTrail.d.ts} +4 -3
  87. package/dist/types/excalidraw/appState.d.ts +34 -10
  88. package/dist/types/excalidraw/components/Actions.d.ts +17 -12
  89. package/dist/types/excalidraw/components/ActiveConfirmDialog.d.ts +1 -1
  90. package/dist/types/excalidraw/components/App.arrowText.d.ts +70 -0
  91. package/dist/types/excalidraw/components/App.bucketFill.d.ts +48 -0
  92. package/dist/types/excalidraw/components/App.clipboard.d.ts +31 -0
  93. package/dist/types/excalidraw/components/App.cursor.d.ts +38 -0
  94. package/dist/types/excalidraw/components/App.d.ts +324 -111
  95. package/dist/types/excalidraw/components/App.drawshape.d.ts +55 -0
  96. package/dist/types/excalidraw/components/App.duplicate.d.ts +101 -0
  97. package/dist/types/excalidraw/components/App.flowchart.d.ts +21 -0
  98. package/dist/types/excalidraw/components/App.modifiers.d.ts +38 -0
  99. package/dist/types/excalidraw/components/App.pan.d.ts +62 -0
  100. package/dist/types/excalidraw/components/App.selection.d.ts +265 -0
  101. package/dist/types/excalidraw/components/App.selectionTool.d.ts +93 -0
  102. package/dist/types/excalidraw/components/App.text.d.ts +146 -0
  103. package/dist/types/excalidraw/components/App.textTool.d.ts +140 -0
  104. package/dist/types/excalidraw/components/App.toolDrag.d.ts +63 -0
  105. package/dist/types/excalidraw/components/App.viewport.d.ts +113 -0
  106. package/dist/types/excalidraw/components/App.wheel.d.ts +26 -0
  107. package/dist/types/excalidraw/components/App.wrap.d.ts +31 -0
  108. package/dist/types/excalidraw/components/ColorPicker/ColorPicker.d.ts +9 -3
  109. package/dist/types/excalidraw/components/ColorPicker/CustomColorList.d.ts +3 -1
  110. package/dist/types/excalidraw/components/ColorPicker/Picker.d.ts +5 -1
  111. package/dist/types/excalidraw/components/ColorPicker/PickerColorList.d.ts +9 -2
  112. package/dist/types/excalidraw/components/ColorPicker/ShadeList.d.ts +4 -2
  113. package/dist/types/excalidraw/components/ColorPicker/TopPicks.d.ts +8 -1
  114. package/dist/types/excalidraw/components/ColorPicker/colorPickerUtils.d.ts +1 -1
  115. package/dist/types/excalidraw/components/ColorPicker/colorTopPicksDnD.d.ts +11 -0
  116. package/dist/types/excalidraw/components/ColorPicker/keyboardNavHandlers.d.ts +2 -1
  117. package/dist/types/excalidraw/components/CommandPalette/defaultCommandPaletteItems.d.ts +1 -2
  118. package/dist/types/excalidraw/components/ConvertElementTypePopup.d.ts +2 -2
  119. package/dist/types/excalidraw/components/CursorHint.d.ts +46 -0
  120. package/dist/types/excalidraw/components/EyeDropper.d.ts +1 -1
  121. package/dist/types/excalidraw/components/FileDropOverlay.d.ts +2 -0
  122. package/dist/types/excalidraw/components/FontPicker/FontPicker.d.ts +4 -1
  123. package/dist/types/excalidraw/components/FontPicker/FontPickerList.d.ts +6 -1
  124. package/dist/types/excalidraw/components/FontPicker/fontTopPicksDnD.d.ts +12 -0
  125. package/dist/types/excalidraw/components/IconButton.d.ts +48 -0
  126. package/dist/types/excalidraw/components/Island.d.ts +7 -0
  127. package/dist/types/excalidraw/components/LaserPointerButton.d.ts +2 -4
  128. package/dist/types/excalidraw/components/LayerUI.d.ts +5 -2
  129. package/dist/types/excalidraw/components/LibraryMenu.d.ts +1 -1
  130. package/dist/types/excalidraw/components/LibraryMenuHeaderContent.d.ts +3 -1
  131. package/dist/types/excalidraw/components/LibraryMenuItems.d.ts +3 -1
  132. package/dist/types/excalidraw/components/LibraryMenuSection.d.ts +6 -2
  133. package/dist/types/excalidraw/components/LibraryUnit.d.ts +7 -2
  134. package/dist/types/excalidraw/components/LockButton.d.ts +3 -4
  135. package/dist/types/excalidraw/components/MagicButton.d.ts +0 -2
  136. package/dist/types/excalidraw/components/MobileMenu.d.ts +4 -4
  137. package/dist/types/excalidraw/components/MobileToolbar.d.ts +9 -0
  138. package/dist/types/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.d.ts +1 -1
  139. package/dist/types/excalidraw/components/PenModeButton.d.ts +2 -5
  140. package/dist/types/excalidraw/components/Popover.d.ts +1 -3
  141. package/dist/types/excalidraw/components/{ButtonIcon.d.ts → RadioButton.d.ts} +2 -5
  142. package/dist/types/excalidraw/components/SVGLayer.d.ts +1 -1
  143. package/dist/types/excalidraw/components/SearchMenu.d.ts +1 -1
  144. package/dist/types/excalidraw/components/Sidebar/Sidebar.d.ts +1 -1
  145. package/dist/types/excalidraw/components/Stats/Angle.d.ts +2 -2
  146. package/dist/types/excalidraw/components/Stats/Dimension.d.ts +2 -2
  147. package/dist/types/excalidraw/components/Stats/DragInput.d.ts +2 -2
  148. package/dist/types/excalidraw/components/Stats/MultiAngle.d.ts +2 -2
  149. package/dist/types/excalidraw/components/Stats/MultiDimension.d.ts +2 -2
  150. package/dist/types/excalidraw/components/Stats/MultiPosition.d.ts +2 -2
  151. package/dist/types/excalidraw/components/Stats/Position.d.ts +3 -3
  152. package/dist/types/excalidraw/components/Stats/utils.d.ts +1 -1
  153. package/dist/types/excalidraw/components/TTDDialog/TTDContext.d.ts +4 -4
  154. package/dist/types/excalidraw/components/TTDDialog/useTTDChatStorage.d.ts +3 -3
  155. package/dist/types/excalidraw/components/ToolPopover.d.ts +3 -6
  156. package/dist/types/excalidraw/components/Toolbar.d.ts +11 -0
  157. package/dist/types/excalidraw/components/Tools.d.ts +151 -0
  158. package/dist/types/excalidraw/components/Tooltip.d.ts +15 -1
  159. package/dist/types/excalidraw/components/TopPicksDnD/TopPicksContextMenu.d.ts +14 -0
  160. package/dist/types/excalidraw/components/TopPicksDnD/TopPicksTip.d.ts +11 -0
  161. package/dist/types/excalidraw/components/TopPicksDnD/topPicksDnD.d.ts +58 -0
  162. package/dist/types/excalidraw/components/UserList.d.ts +3 -2
  163. package/dist/types/excalidraw/components/ViewportStatusFrame/ViewportStatusFrame.d.ts +11 -0
  164. package/dist/types/excalidraw/components/canvases/InteractiveCanvas.d.ts +3 -1
  165. package/dist/types/excalidraw/components/canvases/NewElementCanvas.d.ts +3 -0
  166. package/dist/types/excalidraw/components/canvases/StaticCanvas.d.ts +1 -1
  167. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItemContentRadio.d.ts +2 -1
  168. package/dist/types/excalidraw/components/footer/Footer.d.ts +3 -1
  169. package/dist/types/excalidraw/components/hyperlink/helpers.d.ts +2 -2
  170. package/dist/types/excalidraw/components/icons.d.ts +7 -1
  171. package/dist/types/excalidraw/components/main-menu/DefaultItems.d.ts +10 -4
  172. package/dist/types/excalidraw/components/positionElementBesideCursor.d.ts +26 -0
  173. package/dist/types/excalidraw/components/shapeActionPredicates.d.ts +39 -0
  174. package/dist/types/excalidraw/data/blob.d.ts +70 -24
  175. package/dist/types/excalidraw/data/index.d.ts +4 -4
  176. package/dist/types/excalidraw/data/json.d.ts +41 -18
  177. package/dist/types/excalidraw/data/library.d.ts +1 -1
  178. package/dist/types/excalidraw/drawShapeTrail.d.ts +16 -0
  179. package/dist/types/excalidraw/eraser/index.d.ts +2 -3
  180. package/dist/types/excalidraw/fonts/Fonts.d.ts +3 -2
  181. package/dist/types/excalidraw/hooks/useAppStateValue.d.ts +29 -0
  182. package/dist/types/excalidraw/hooks/useLibraryItemSvg.d.ts +1 -1
  183. package/dist/types/excalidraw/hooks/useTextEditorFocus.d.ts +5 -5
  184. package/dist/types/excalidraw/{laser-trails.d.ts → laserTrails.d.ts} +5 -7
  185. package/dist/types/excalidraw/lasso/index.d.ts +2 -3
  186. package/dist/types/excalidraw/lasso/utils.d.ts +2 -0
  187. package/dist/types/excalidraw/renderOverrides.d.ts +9 -0
  188. package/dist/types/excalidraw/renderer/animation.d.ts +5 -1
  189. package/dist/types/excalidraw/renderer/helpers.d.ts +25 -0
  190. package/dist/types/excalidraw/renderer/interactiveScene.d.ts +2 -4
  191. package/dist/types/excalidraw/scene/Renderer.d.ts +489 -20
  192. package/dist/types/excalidraw/scene/export.d.ts +3 -3
  193. package/dist/types/excalidraw/scene/index.d.ts +2 -2
  194. package/dist/types/excalidraw/scene/types.d.ts +7 -4
  195. package/dist/types/excalidraw/snapping.d.ts +7 -7
  196. package/dist/types/excalidraw/types.d.ts +574 -29
  197. package/dist/types/excalidraw/viewport.d.ts +302 -0
  198. package/dist/types/excalidraw/wysiwyg/textWysiwyg.d.ts +13 -3
  199. package/dist/types/fractional-indexing/src/index.d.ts +29 -0
  200. package/dist/types/laser-pointer/src/index.d.ts +2 -0
  201. package/dist/types/laser-pointer/src/math.d.ts +16 -0
  202. package/dist/types/laser-pointer/src/simplify.d.ts +2 -0
  203. package/dist/types/laser-pointer/src/state.d.ts +36 -0
  204. package/dist/types/math/src/constants.d.ts +0 -1
  205. package/dist/types/math/src/curve.d.ts +23 -13
  206. package/dist/types/math/src/index.d.ts +1 -0
  207. package/dist/types/math/src/pca.d.ts +79 -0
  208. package/dist/types/math/src/point.d.ts +1 -0
  209. package/dist/types/math/src/polygon.d.ts +25 -1
  210. package/dist/types/math/src/segment.d.ts +6 -0
  211. package/dist/types/utils/src/export.d.ts +4 -3
  212. package/dist/types/utils/src/index.d.ts +1 -2
  213. package/dist/types/utils/src/shape.d.ts +2 -2
  214. package/package.json +1 -1
  215. package/dist/types/excalidraw/animation-frame-handler.d.ts +0 -16
  216. package/dist/types/excalidraw/components/FollowMode/FollowMode.d.ts +0 -10
  217. package/dist/types/excalidraw/components/HandButton.d.ts +0 -10
  218. package/dist/types/excalidraw/components/MobileToolBar.d.ts +0 -10
  219. package/dist/types/excalidraw/components/ToolButton.d.ts +0 -49
  220. package/dist/types/excalidraw/components/shapes.d.ts +0 -263
  221. package/dist/types/excalidraw/cursor.d.ts +0 -5
  222. package/dist/types/excalidraw/scene/scroll.d.ts +0 -18
  223. package/dist/types/excalidraw/scene/zoom.d.ts +0 -12
  224. package/dist/types/utils/src/bbox.d.ts +0 -9
  225. package/dist/types/utils/src/withinBounds.d.ts +0 -19
@@ -1,9 +1,9 @@
1
- import type { IMAGE_MIME_TYPES, UserIdleState, throttleRAF, MIME_TYPES, EditorInterface } from "@nextcloud/excalidraw-common";
1
+ import type { IMAGE_MIME_TYPES, UserIdleState, throttleRAF, MIME_TYPES, EditorInterface, StrokeWidthKey } from "@nextcloud/excalidraw-common";
2
2
  import type { LinearElementEditor } from "@nextcloud/excalidraw-element";
3
- import type { MaybeTransformHandleType } from "@nextcloud/excalidraw-element";
4
- import type { PointerType, ExcalidrawLinearElement, NonDeletedExcalidrawElement, NonDeleted, TextAlign, ExcalidrawElement, GroupId, ExcalidrawBindableElement, Arrowhead, FontFamilyValues, FileId, Theme, StrokeRoundness, ExcalidrawEmbeddableElement, ExcalidrawMagicFrameElement, ExcalidrawFrameLikeElement, ExcalidrawElementType, ExcalidrawIframeLikeElement, OrderedExcalidrawElement, ExcalidrawNonSelectionElement, BindMode, ExcalidrawTextElement } from "@nextcloud/excalidraw-element/types";
3
+ import type { ListMarkerAdvance, MaybeTransformHandleType } from "@nextcloud/excalidraw-element";
4
+ import type { PointerType, ExcalidrawLinearElement, NonDeletedExcalidrawElement, NonDeleted, TextAlign, ExcalidrawElement, GroupId, ExcalidrawBindableElement, ExcalidrawArrowElement, Arrowhead, FontFamilyValues, FileId, Theme, StrokeRoundness, ExcalidrawEmbeddableElement, ExcalidrawMagicFrameElement, ExcalidrawFrameLikeElement, ExcalidrawElementType, ExcalidrawIframeLikeElement, OrderedExcalidrawElement, ExcalidrawNonSelectionElement, BindMode, ExcalidrawTextElement, StrokeVariability } from "@nextcloud/excalidraw-element/types";
5
5
  import type { Merge, MaybePromise, ValueOf, MakeBrand } from "@nextcloud/excalidraw-common/utility-types";
6
- import type { CaptureUpdateActionType, DurableIncrement, EphemeralIncrement } from "@nextcloud/excalidraw-element";
6
+ import type { CaptureUpdateActionType, DurableIncrement, EphemeralIncrement, OnDuplicateData } from "@nextcloud/excalidraw-element";
7
7
  import type { GlobalPoint } from "@nextcloud/excalidraw-math";
8
8
  import type { Action } from "./actions/types";
9
9
  import type { Spreadsheet } from "./charts";
@@ -13,6 +13,7 @@ import type Library from "./data/library";
13
13
  import type { ContextMenuItems } from "./components/ContextMenu";
14
14
  import type { SnapLine } from "./snapping";
15
15
  import type { ImportedDataState } from "./data/types";
16
+ import type { SetViewportOptions } from "./viewport";
16
17
  import type { Language } from "./i18n";
17
18
  import type { isOverScrollBars } from "./scene/scrollbars";
18
19
  import type React from "react";
@@ -84,7 +85,7 @@ export type BinaryFileData = {
84
85
  };
85
86
  export type BinaryFileMetadata = Omit<BinaryFileData, "dataURL">;
86
87
  export type BinaryFiles = Record<ExcalidrawElement["id"], BinaryFileData>;
87
- export type ToolType = "selection" | "lasso" | "rectangle" | "diamond" | "ellipse" | "arrow" | "line" | "freedraw" | "text" | "image" | "eraser" | "hand" | "frame" | "magicframe" | "embeddable" | "laser";
88
+ export type ToolType = "selection" | "lasso" | "rectangle" | "diamond" | "ellipse" | "arrow" | "line" | "freedraw" | "text" | "image" | "eraser" | "hand" | "frame" | "magicframe" | "stickynote" | "embeddable" | "laser" | "autoshape" | "bucketfill";
88
89
  export type ElementOrToolType = ExcalidrawElementType | ToolType | "custom";
89
90
  export type ActiveTool = {
90
91
  type: ToolType;
@@ -138,7 +139,9 @@ export type InteractiveCanvasAppState = Readonly<_CommonCanvasAppState & {
138
139
  newElement: AppState["newElement"];
139
140
  isBindingEnabled: AppState["isBindingEnabled"];
140
141
  isMidpointSnappingEnabled: AppState["isMidpointSnappingEnabled"];
142
+ gridModeEnabled: AppState["gridModeEnabled"];
141
143
  suggestedBinding: AppState["suggestedBinding"];
144
+ textToolHover: AppState["textToolHover"];
142
145
  isRotating: AppState["isRotating"];
143
146
  elementsToHighlight: AppState["elementsToHighlight"];
144
147
  collaborators: AppState["collaborators"];
@@ -172,6 +175,47 @@ export type ObservedElementsAppState = {
172
175
  lockedMultiSelections: AppState["lockedMultiSelections"];
173
176
  activeLockedId: AppState["activeLockedId"];
174
177
  };
178
+ export type BoxSelectionMode = "contain" | "overlap";
179
+ /**
180
+ * The pointing device the wheel mappings are tuned for. `auto` is reserved
181
+ * for detecting it from the wheel events; see `resolveInputDevice`.
182
+ */
183
+ export type InputDevice = "auto" | "mouse" | "trackpad";
184
+ /**
185
+ * A box, in scene coordinates, that pan & zoom are constrained to.
186
+ *
187
+ * This is a private type. For public API, only use specific properties,
188
+ * needed.
189
+ */
190
+ export type ScrollConstraints = {
191
+ x: number;
192
+ y: number;
193
+ width: number;
194
+ height: number;
195
+ /** when set, panning is constrained so the viewport stays within the box */
196
+ lockScroll: boolean;
197
+ /** when set, the viewport cannot zoom out below `zoom` */
198
+ lockZoom: boolean;
199
+ /**
200
+ * The zoom resolved after the `setViewport` navigation settled.
201
+ */
202
+ zoom: number;
203
+ /**
204
+ * Pixel amount the viewport may overscroll past its resting clamp before
205
+ * snapping back (rubberband). Screen pixels, zoom-independent. Resolved
206
+ * from `lock.overscroll` at the time the lock was installed (`true` →
207
+ * default give, `false` → 0).
208
+ */
209
+ overscroll: number;
210
+ /**
211
+ * Extra scrollable margin around the box (CSS-style), letting the viewport
212
+ * scroll past each box edge to reveal that much empty space. Values are
213
+ * viewport pixels and zoom-independent (a fixed on-screen distance).
214
+ * Resolved from the `offsets` passed to `setViewport` (see
215
+ * {@link ViewportOffsets}) at the time the lock was installed.
216
+ */
217
+ offsets?: Offsets;
218
+ };
175
219
  export interface AppState {
176
220
  contextMenu: {
177
221
  items: ContextMenuItems;
@@ -210,15 +254,48 @@ export interface AppState {
210
254
  * `bindingPreference` and keyboard modifiers (ctrl/alt)
211
255
  */
212
256
  isBindingEnabled: boolean;
257
+ /** user box selection preference; defaults to "contain" when unset */
258
+ boxSelectionMode: BoxSelectionMode;
213
259
  /** user arrow binding preference */
214
260
  bindingPreference: "enabled" | "disabled";
215
261
  /** user preference whether arrow snap to midpoints while binding */
216
262
  isMidpointSnappingEnabled: boolean;
217
- startBoundElement: NonDeleted<ExcalidrawBindableElement> | null;
263
+ /** user preference whether to show contextual hints above the toolbar */
264
+ showHints: boolean;
265
+ /**
266
+ * user preference for what the wheel does: with a `trackpad` a plain wheel
267
+ * pans; with a `mouse` a plain wheel zooms. Ctrl/cmd+wheel (how a pinch is
268
+ * delivered) zooms with either device. Shift+wheel pans horizontally;
269
+ * ctrl/cmd+shift+wheel pans vertically. `auto` resolves to `trackpad` until
270
+ * device detection exists — see `resolveInputDevice`
271
+ */
272
+ inputDevice: InputDevice;
273
+ /**
274
+ * The bindable element the UI highlights for the user when an arrow is
275
+ * dragged or otherwise its endpoint being close to said element.
276
+ */
218
277
  suggestedBinding: {
219
278
  element: NonDeleted<ExcalidrawBindableElement>;
220
279
  midPoint?: GlobalPoint;
221
280
  } | null;
281
+ /**
282
+ * What a text-tool click at the hovered position would act on — the text
283
+ * it would edit, the empty container it would label, or the arrow anchor
284
+ * (a free endpoint, or the midpoint for a label) it would attach text to.
285
+ * `null` when the click would create free text, or the tool isn't active.
286
+ * Drives the hover affordance only.
287
+ */
288
+ textToolHover: {
289
+ type: "text";
290
+ elementId: ExcalidrawElement["id"];
291
+ } | {
292
+ type: "container";
293
+ elementId: ExcalidrawElement["id"];
294
+ } | {
295
+ type: "arrow";
296
+ elementId: ExcalidrawArrowElement["id"];
297
+ anchor: "start" | "end" | "label";
298
+ } | null;
222
299
  frameToHighlight: NonDeleted<ExcalidrawFrameLikeElement> | null;
223
300
  frameRendering: {
224
301
  enabled: boolean;
@@ -226,8 +303,15 @@ export interface AppState {
226
303
  outline: boolean;
227
304
  clip: boolean;
228
305
  };
229
- editingFrame: string | null;
230
- elementsToHighlight: NonDeleted<ExcalidrawElement>[] | null;
306
+ /**
307
+ * frame-like element whose name is currently being edited
308
+ */
309
+ editingFrame: ExcalidrawFrameLikeElement["id"] | null;
310
+ /**
311
+ * Elements the UI highlights with a bounding-box outline — those that
312
+ * would get added to a frame being dragged/resized.
313
+ */
314
+ elementsToHighlight: readonly NonDeletedExcalidrawElement[] | null;
231
315
  /**
232
316
  * set when a new text is created or when an existing text is being edited
233
317
  */
@@ -252,11 +336,14 @@ export interface AppState {
252
336
  exportWithDarkMode: boolean;
253
337
  exportScale: number;
254
338
  currentItemStrokeColor: string;
339
+ currentItemStickynoteStrokeColor: string;
340
+ currentItemStickynoteBackgroundColor: string;
255
341
  currentItemBackgroundColor: string;
256
342
  currentItemFillStyle: ExcalidrawElement["fillStyle"];
257
- currentItemStrokeWidth: number;
343
+ currentItemStrokeWidthKey: StrokeWidthKey;
258
344
  currentItemStrokeStyle: ExcalidrawElement["strokeStyle"];
259
345
  currentItemRoughness: number;
346
+ currentItemStrokeVariability: StrokeVariability;
260
347
  currentItemOpacity: number;
261
348
  currentItemFontFamily: FontFamilyValues;
262
349
  currentItemFontSize: number;
@@ -269,6 +356,7 @@ export interface AppState {
269
356
  viewBackgroundColor: string;
270
357
  scrollX: number;
271
358
  scrollY: number;
359
+ scrollConstraints: ScrollConstraints | null;
272
360
  cursorButton: "up" | "down";
273
361
  scrolledOutside: boolean;
274
362
  name: string | null;
@@ -356,10 +444,6 @@ export interface AppState {
356
444
  y: number;
357
445
  } | null;
358
446
  objectsSnapModeEnabled: boolean;
359
- /** the user's socket id & username who is being followed on the canvas */
360
- userToFollow: UserToFollow | null;
361
- /** the socket ids of the users following the current user */
362
- followedBy: Set<SocketId>;
363
447
  /** image cropping */
364
448
  isCropping: boolean;
365
449
  croppingElementId: ExcalidrawElement["id"] | null;
@@ -374,6 +458,23 @@ export interface AppState {
374
458
  [groupId: string]: true;
375
459
  };
376
460
  bindMode: BindMode;
461
+ /** user-customized color-picker top picks (pinned via drag & drop from the
462
+ * color picker popup). `null` means no customization (defaults, or
463
+ * host-supplied `topPicks`, are used). Kept per picker. */
464
+ colorTopPicks: {
465
+ elementStroke: readonly string[] | null;
466
+ elementBackground: readonly string[] | null;
467
+ /** the bucket-fill tool keeps a list separate from `elementBackground`
468
+ * even though both drive `currentItemBackgroundColor` (its defaults and
469
+ * use case differ — no transparent) */
470
+ bucketFill: readonly string[] | null;
471
+ /** sticky notes are their own color domain (own defaults, own picks) */
472
+ stickyNoteStroke: readonly string[] | null;
473
+ stickyNoteBackground: readonly string[] | null;
474
+ };
475
+ /** user-customized font-picker top picks (pinned via drag & drop from the
476
+ * font picker popup). `null` means no customization (defaults are used) */
477
+ fontTopPicks: readonly FontFamilyValues[] | null;
377
478
  }
378
479
  export type SearchMatch = {
379
480
  id: string;
@@ -386,7 +487,7 @@ export type SearchMatch = {
386
487
  showOnCanvas: boolean;
387
488
  }[];
388
489
  };
389
- export type UIAppState = Omit<AppState, "startBoundElement" | "cursorButton" | "scrollX" | "scrollY">;
490
+ export type UIAppState = Omit<AppState, "cursorButton" | "scrollX" | "scrollY" | "zoom" | "shouldCacheIgnoreZoom" | "snapLines" | "originSnapOffset" | "suggestedBinding" | "textToolHover" | "frameToHighlight" | "elementsToHighlight">;
390
491
  export type NormalizedZoomValue = number & {
391
492
  _brand: "normalizedZoom";
392
493
  };
@@ -425,28 +526,196 @@ export type LibraryItem = {
425
526
  error?: string;
426
527
  };
427
528
  export type LibraryItems = readonly LibraryItem[];
529
+ /**
530
+ * A library item the host app may have tagged with the name of the read-only
531
+ * source library it was resolved from (rendered as a separate, non-editable
532
+ * section). Untagged items belong to the writable personal library and are
533
+ * the only ones persisted back. See `onLibrarySaveAs`.
534
+ */
535
+ export type TaggedLibraryItem = LibraryItem & {
536
+ libraryName?: string;
537
+ };
428
538
  export type LibraryItems_anyVersion = LibraryItems | LibraryItems_v1;
429
539
  export type LibraryItemsSource = ((currentLibraryItems: LibraryItems) => MaybePromise<LibraryItems_anyVersion | Blob>) | MaybePromise<LibraryItems_anyVersion | Blob>;
430
540
  export type ExcalidrawInitialDataState = Merge<ImportedDataState, {
431
541
  libraryItems?: MaybePromise<Required<ImportedDataState>["libraryItems"]>;
432
542
  }>;
543
+ export type ExcalidrawInitialState = {
544
+ viewport?: Omit<SetViewportOptions, "animation">;
545
+ };
433
546
  export type OnUserFollowedPayload = {
434
547
  userToFollow: UserToFollow;
435
548
  action: "FOLLOW" | "UNFOLLOW";
436
549
  };
550
+ export type ViewportStatusFrame = {
551
+ /** the badge (bottom-center pill) */
552
+ label?: {
553
+ label: React.ReactNode;
554
+ icon?: React.ReactNode;
555
+ /** badge background; defaults to var(--color-primary-hover) */
556
+ background?: string;
557
+ /** badge text color; defaults to var(--color-primary-light) */
558
+ color?: string;
559
+ /** makes the badge label interactive */
560
+ onClick?: () => void;
561
+ /** renders a close button when set */
562
+ onClose?: () => void;
563
+ };
564
+ /** viewport-edge border: CSS color, or `false` for none */
565
+ border: false | string;
566
+ };
437
567
  export type OnExportProgress = {
438
568
  type: "progress";
439
569
  message?: React.ReactNode;
440
570
  /** 0-1 range */
441
571
  progress?: number;
442
572
  };
573
+ export type InteractionConfig = {
574
+ /**
575
+ * Interactions that stay enabled while the editor is otherwise
576
+ * non-interactive. Opt-in: anything omitted or `false` is disabled.
577
+ */
578
+ enabled?: {
579
+ /**
580
+ * Element links render their link icon and stay clickable — clicking
581
+ * anywhere on a linked element opens the link, same as in view mode.
582
+ * When disabled, link icons are not rendered at all.
583
+ *
584
+ * @default false
585
+ */
586
+ links?: boolean;
587
+ /**
588
+ * Embeddable & iframe elements stay interactive — hovering & clicking
589
+ * activates them so their content can be used, same as in view mode.
590
+ *
591
+ * @default false
592
+ */
593
+ embeds?: boolean;
594
+ /**
595
+ * Umbrella for all interactive content on canvas — shorthand for
596
+ * enabling `links` & `embeds` (and future interactive content kinds)
597
+ * together. Additive: `interactiveContent: true` enables them
598
+ * regardless of their individual values.
599
+ *
600
+ * @default false
601
+ */
602
+ interactiveContent?: boolean;
603
+ /**
604
+ * Canvas navigation — panning (pointer drag, wheel, PageUp/PageDown)
605
+ * and zooming (ctrl/cmd + wheel, pinch, and the canvas zoom &
606
+ * zoom-to-fit shortcuts: ctrl/cmd +/-/0, shift+1/2/3), same as in view
607
+ * mode. Respects `appState.scrollConstraints` if set, so it composes
608
+ * with viewport locking. The rest of the keyboard stays disabled. Note
609
+ * the editor consumes wheel & touch input again when enabled, so the
610
+ * page no longer scrolls over the editor.
611
+ *
612
+ * @default false
613
+ */
614
+ navigation?: boolean;
615
+ /**
616
+ * Whether the browser's own zoom remains available over the editor —
617
+ * ctrl/cmd + wheel, pinch, and (while the editor has focus)
618
+ * ctrl/cmd +/-/0 shortcuts. Prevented by default, mirroring the
619
+ * interactive editor. Regular page scrolling stays available either way.
620
+ * With `navigation` enabled, the zoom input (wheel, pinch, keyboard
621
+ * shortcuts) zooms the canvas instead either way, making this moot.
622
+ *
623
+ * @default false
624
+ */
625
+ browserZoom?: boolean;
626
+ /**
627
+ * Tools that stay user-driven while the editor is otherwise
628
+ * non-interactive: pointer input keeps driving the listed tool when it's
629
+ * the active tool. Does not enable user-driven tool *switching* — the
630
+ * keyboard stays disabled and tool selection remains host-driven
631
+ * (`ExcalidrawAPI.setActiveTool`).
632
+ *
633
+ * Composes with `navigation`: the enabled tool wins the primary-pointer
634
+ * drag, while wheel input (and wheel-button drag) still pans/zooms.
635
+ */
636
+ tools?: {
637
+ /**
638
+ * The laser pointer stays usable — pointer strokes draw laser trails
639
+ * and pointer positions keep broadcasting via `onPointerUpdate`, so
640
+ * e.g. collaborators see a presenter's laser & cursor.
641
+ *
642
+ * @default false
643
+ */
644
+ laser?: boolean;
645
+ /**
646
+ * Custom tools (`activeTool.type === "custom"`) stay usable — the
647
+ * editor keeps dispatching `onPointerDown` / `onPointerUp` for them.
648
+ * Tool behavior is host-implemented; activate custom tools with
649
+ * `locked: true` or they revert to the selection tool (and go inert)
650
+ * after the first pointer interaction.
651
+ *
652
+ * @default false
653
+ */
654
+ custom?: boolean;
655
+ };
656
+ };
657
+ };
658
+ export type UIConfig = {
659
+ /**
660
+ * Default UI controls that stay enabled while the rest of Excalidraw's
661
+ * default UI is hidden. Opt-in: anything omitted or `false` is disabled.
662
+ */
663
+ enabled: {
664
+ /**
665
+ * The zoom-out, reset-zoom, and zoom-in controls.
666
+ *
667
+ * @default false
668
+ */
669
+ zoom?: boolean;
670
+ /**
671
+ * The button shown when the viewport is scrolled away from all content.
672
+ *
673
+ * @default false
674
+ */
675
+ scrollBackToContent?: boolean;
676
+ };
677
+ };
678
+ /** Supported visual changes. Geometry, content, bindings and styles are not overridable. */
679
+ export type ElementRenderOverride = Readonly<{
680
+ /** Absolute render opacity (0–100, clamped). Omitted: use element.opacity. */
681
+ opacity?: number;
682
+ /** Translation in scene units. Bound labels inherit their container's offset and ignore this field. */
683
+ offset?: Readonly<{
684
+ x: number;
685
+ y: number;
686
+ }>;
687
+ }>;
688
+ /** see {@link ExcalidrawImperativeAPI.setElementRenderOverrides} for details */
689
+ export type ElementRenderOverrides = ReadonlyMap<ExcalidrawElement["id"], ElementRenderOverride>;
690
+ /** The translation part of a snapshot: only the entries that carry an offset. */
691
+ export type ElementRenderOffsets = ReadonlyMap<ExcalidrawElement["id"], NonNullable<ElementRenderOverride["offset"]>>;
443
692
  export interface ExcalidrawProps {
693
+ className?: string;
694
+ /**
695
+ * Document that owns Excalidraw's mounted DOM.
696
+ *
697
+ * Set only when it differs from the global `document`, such as when code
698
+ * executing in a parent window mounts Excalidraw into an iframe document.
699
+ * The value must remain stable for the editor's lifetime.
700
+ *
701
+ * @default document
702
+ */
703
+ ownerDocument?: Document;
444
704
  onChange?: (elements: readonly OrderedExcalidrawElement[], appState: AppState, files: BinaryFiles) => void;
705
+ onThemeChange?: (theme: Theme | "system") => void;
706
+ /**
707
+ * Called with each element the user creates (shapes, text, bound text,
708
+ * bucket fill, images...) before it is added to the scene, and returns it.
709
+ * Not called for restored elements, collaboration updates, or duplicates
710
+ * (pasted elements, library items, duplication; see `onDuplicate`).
711
+ */
712
+ beforeElementCreated?: (element: ExcalidrawElement) => ExcalidrawElement;
445
713
  /**
446
714
  * note: only subscribes if the props.onIncrement is defined on initial render
447
715
  */
448
716
  onIncrement?: (event: DurableIncrement | EphemeralIncrement) => void;
449
717
  initialData?: (() => MaybePromise<ExcalidrawInitialDataState | null>) | MaybePromise<ExcalidrawInitialDataState | null>;
718
+ initialState?: ExcalidrawInitialState;
450
719
  /**
451
720
  * Invoked as soon as the Excalidraw API is available
452
721
  * NOTE editor is not yet mounted, and state is not yet initialized
@@ -484,15 +753,95 @@ export interface ExcalidrawProps {
484
753
  *
485
754
  * Returned elements will be used in place of the next elements
486
755
  * (you should return all elements, including deleted, and not mutate
487
- * the element if changes are made)
756
+ * the element if changes are made).
757
+ *
758
+ * The duplicates are the elements in `nextElements` which are not in
759
+ * `prevElements` (see also `data.duplicateElements`). When pasting or
760
+ * inserting onto a frame, their `frameId` is already set. To change a
761
+ * duplicate, return a new object with the same `id`. It is shallow-merged
762
+ * into the duplicate (omitted properties are kept), and your changes are
763
+ * part of the duplication itself (same undo entry, same durable increment).
764
+ *
765
+ * To prevent an element from being duplicated, omit its duplicate from the
766
+ * returned array. References to it from the remaining duplicates are
767
+ * cleared, and a bound text isn't duplicated without its container. To
768
+ * prevent the duplication as a whole, return `false`. If no duplicate
769
+ * remains, the duplication is cancelled and the returned elements are
770
+ * ignored (alt-drag then moves the original elements instead).
488
771
  */
489
772
  onDuplicate?: (nextElements: readonly ExcalidrawElement[],
490
773
  /** excludes the duplicated elements */
491
- prevElements: readonly ExcalidrawElement[]) => ExcalidrawElement[] | void;
774
+ prevElements: readonly ExcalidrawElement[],
775
+ /** lookups covering just the elements taking part in the duplication */
776
+ data: OnDuplicateData) => ExcalidrawElement[] | void | false;
492
777
  renderTopLeftUI?: (isMobile: boolean, appState: UIAppState) => JSX.Element | null;
493
778
  renderTopRightUI?: (isMobile: boolean, appState: UIAppState) => JSX.Element | null;
494
779
  langCode?: Language["code"];
495
780
  viewModeEnabled?: boolean;
781
+ /**
782
+ * Whether the editor accepts user input (pointer, keyboard, wheel, touch,
783
+ * clipboard, drag&drop). When `false`, the scene still renders and reacts
784
+ * to programmatic updates (imperative API), but the user cannot affect it
785
+ * in any way. Implies view mode.
786
+ *
787
+ * Pass a config object to keep specific interactions enabled while the
788
+ * editor is otherwise non-interactive (see `InteractionConfig`):
789
+ *
790
+ * ```tsx
791
+ * <Excalidraw interaction={{ enabled: { links: true } }} />
792
+ * ```
793
+ *
794
+ * @default true
795
+ */
796
+ interaction?: boolean | InteractionConfig;
797
+ /**
798
+ * Whether Excalidraw's default UI is rendered — toolbar, default menus,
799
+ * footer controls, sidebars, and canvas popups. Host UI passed through
800
+ * children (including exported components such as `MainMenu` and `Footer`)
801
+ * or render props continues to render, together with any supporting dialogs
802
+ * it opens.
803
+ *
804
+ * Canvas content (elements, text editing surface, frame names, embeds) still
805
+ * renders, and the editor remains interactive unless `interaction` is set to
806
+ * `false`.
807
+ *
808
+ * Pass a config object to keep specific default controls rendered while the
809
+ * rest of the default UI is hidden (see `UIConfig`):
810
+ *
811
+ * ```tsx
812
+ * <Excalidraw ui={{ enabled: { zoom: true } }} />
813
+ * ```
814
+ *
815
+ * NOTE: this is WIP and what default UI is/is not rendered when ui=false
816
+ * may yet change.
817
+ *
818
+ * @default true
819
+ */
820
+ ui?: boolean | UIConfig;
821
+ /**
822
+ * Forces the active editor tool (controlled). While set, user- and
823
+ * API-driven tool switching is ignored — `setActiveTool` refuses with a
824
+ * console warning, non-forced toolbar buttons render disabled — and the
825
+ * editor snaps back if internal flows reset the tool. The forced tool
826
+ * behaves as if locked (see the tool lock / padlock): it doesn't revert to
827
+ * the selection tool after use, and elements drawn with it aren't
828
+ * auto-selected — without mutating `appState.activeTool.locked`, so the
829
+ * user's persisted padlock preference stays untouched. Unset to return
830
+ * tool control to the editor (the current tool stays active).
831
+ *
832
+ * The forced tool must be activatable to take effect: not disabled via
833
+ * `UIOptions.tools`, and — while the editor is non-interactive — allowed
834
+ * via `interaction.enabled.tools`. Otherwise the editor stays on (or, when
835
+ * non-interactive, resets to) the `selection` tool, and the forced tool is
836
+ * applied once it becomes activatable. `image` cannot be forced (its
837
+ * activation opens the file picker).
838
+ */
839
+ activeTool?: {
840
+ type: Exclude<ToolType, "image">;
841
+ } | {
842
+ type: "custom";
843
+ customType: string;
844
+ };
496
845
  zenModeEnabled?: boolean;
497
846
  gridModeEnabled?: boolean;
498
847
  objectsSnapModeEnabled?: boolean;
@@ -501,9 +850,17 @@ export interface ExcalidrawProps {
501
850
  name?: string;
502
851
  renderCustomStats?: (elements: readonly NonDeletedExcalidrawElement[], appState: UIAppState) => JSX.Element;
503
852
  UIOptions?: Partial<UIOptions>;
853
+ /**
854
+ * dimensions and size constraints for inserted images
855
+ */
856
+ imageOptions?: ImageOptions;
504
857
  detectScroll?: boolean;
505
858
  handleKeyboardGlobally?: boolean;
506
859
  onLibraryChange?: (libraryItems: LibraryItems) => void | Promise<any>;
860
+ libraryMenuTitle?: string;
861
+ libraryMenuDescription?: string;
862
+ onLibrarySaveAs?: (libraryItems: LibraryItems) => void | Promise<void>;
863
+ onSaveAsCanvasTemplate?: () => void | Promise<void>;
507
864
  autoFocus?: boolean;
508
865
  generateIdForFile?: (file: File) => string | Promise<string>;
509
866
  generateLinkForSelection?: (id: string, type: "element" | "group") => string;
@@ -520,6 +877,21 @@ export interface ExcalidrawProps {
520
877
  aiEnabled?: boolean;
521
878
  showDeprecatedFonts?: boolean;
522
879
  renderScrollbars?: boolean;
880
+ viewportStatusFrame?: ViewportStatusFrame | null;
881
+ /**
882
+ * Rendered inside the UserList "who's here" dropdown (desktop) and inline
883
+ * in the mobile menu's collaborators section, below a divider. Accepts a
884
+ * render function — called with `isMobile` so hosts can render different
885
+ * UI for each surface — in addition to a plain node.
886
+ */
887
+ currentUserControls?: React.ReactNode | ((isMobile: boolean) => React.ReactNode);
888
+ /**
889
+ * The user being followed on the canvas, if any. Controlled by the host —
890
+ * the editor never sets it; it emits follow/unfollow intents via
891
+ * `onUserFollow` (prop or imperative API) and renders the followed
892
+ * user's avatar highlight from this value.
893
+ */
894
+ userToFollow?: UserToFollow | null;
523
895
  /**
524
896
  * Called before exporting to a file.
525
897
  *
@@ -545,7 +917,8 @@ export interface ExcalidrawProps {
545
917
  }) => MaybePromise<void> | AsyncGenerator<OnExportProgress, void>;
546
918
  }
547
919
  export type SceneData = {
548
- elements?: ImportedDataState["elements"];
920
+ /** Expects normalized elements; restore imported data before updating the scene. */
921
+ elements?: readonly ExcalidrawElement[] | null;
549
922
  appState?: ImportedDataState["appState"];
550
923
  collaborators?: Map<SocketId, Collaborator>;
551
924
  captureUpdate?: CaptureUpdateActionType;
@@ -555,12 +928,21 @@ export type ExportOpts = {
555
928
  onExportToBackend?: (exportedElements: readonly NonDeletedExcalidrawElement[], appState: UIAppState, files: BinaryFiles) => void;
556
929
  renderCustomUI?: (exportedElements: readonly NonDeletedExcalidrawElement[], appState: UIAppState, files: BinaryFiles, canvas: HTMLCanvasElement) => JSX.Element;
557
930
  };
931
+ export type ImageOptions = Partial<{
932
+ maxWidthOrHeight: number;
933
+ maxFileSizeBytes: number;
934
+ }>;
558
935
  export type CanvasActions = Partial<{
559
936
  changeViewBackgroundColor: boolean;
560
937
  clearCanvas: boolean;
561
938
  export: false | ExportOpts;
562
939
  loadScene: boolean;
563
940
  saveToActiveFile: boolean;
941
+ /**
942
+ * defaults to true if `props.theme` is omitted or `props.onThemeChange`
943
+ * is supplied (at which point the theme is considered as host-app controlled),
944
+ * else default to false
945
+ * */
564
946
  toggleTheme: boolean | null;
565
947
  saveAsImage: boolean;
566
948
  }>;
@@ -584,6 +966,7 @@ export type AppProps = Merge<ExcalidrawProps, {
584
966
  export: ExportOpts;
585
967
  };
586
968
  }>;
969
+ imageOptions: Required<ImageOptions>;
587
970
  detectScroll: boolean;
588
971
  handleKeyboardGlobally: boolean;
589
972
  isCollaborating: boolean;
@@ -595,6 +978,8 @@ export type AppProps = Merge<ExcalidrawProps, {
595
978
  export type AppClassProperties = {
596
979
  props: AppProps;
597
980
  state: AppState;
981
+ readonly ownerDocument: Document;
982
+ readonly ownerWindow: Window & typeof globalThis;
598
983
  api: App["api"];
599
984
  sessionExportThemeOverride: App["sessionExportThemeOverride"];
600
985
  interactiveCanvas: HTMLCanvasElement | null;
@@ -611,12 +996,11 @@ export type AppClassProperties = {
611
996
  scene: App["scene"];
612
997
  syncActionResult: App["syncActionResult"];
613
998
  fonts: App["fonts"];
614
- pasteFromClipboard: App["pasteFromClipboard"];
999
+ clipboard: App["clipboard"];
615
1000
  id: App["id"];
616
1001
  onInsertElements: App["onInsertElements"];
617
1002
  onExportImage: App["onExportImage"];
618
- lastViewportPosition: App["lastViewportPosition"];
619
- scrollToContent: App["scrollToContent"];
1003
+ viewport: App["viewport"];
620
1004
  addFiles: App["addFiles"];
621
1005
  addElementsFromPasteOrLibrary: App["addElementsFromPasteOrLibrary"];
622
1006
  togglePenMode: App["togglePenMode"];
@@ -627,11 +1011,22 @@ export type AppClassProperties = {
627
1011
  onMagicframeToolSelect: App["onMagicframeToolSelect"];
628
1012
  getName: App["getName"];
629
1013
  dismissLinearEditor: App["dismissLinearEditor"];
630
- flowChartCreator: App["flowChartCreator"];
1014
+ flowchart: App["flowchart"];
1015
+ drawShape: App["drawShape"];
1016
+ arrowText: App["arrowText"];
1017
+ textTool: App["textTool"];
1018
+ cursor: App["cursor"];
1019
+ bucketFill: App["bucketFill"];
1020
+ duplicate: App["duplicate"];
1021
+ toolDrag: App["toolDrag"];
1022
+ activeResizeHandle: App["activeResizeHandle"];
1023
+ selectionTool: App["selectionTool"];
1024
+ wrap: App["wrap"];
1025
+ modifiers: App["modifiers"];
1026
+ isToolLocked: App["isToolLocked"];
631
1027
  getEffectiveGridSize: App["getEffectiveGridSize"];
632
1028
  setPlugins: App["setPlugins"];
633
1029
  plugins: App["plugins"];
634
- getEditorUIOffsets: App["getEditorUIOffsets"];
635
1030
  visibleElements: App["visibleElements"];
636
1031
  excalidrawContainerValue: App["excalidrawContainerValue"];
637
1032
  onPointerUpEmitter: App["onPointerUpEmitter"];
@@ -640,8 +1035,13 @@ export type AppClassProperties = {
640
1035
  onEvent: App["onEvent"];
641
1036
  onStateChange: App["onStateChange"];
642
1037
  lastPointerMoveCoords: App["lastPointerMoveCoords"];
1038
+ lastPointerMoveEvent: App["lastPointerMoveEvent"];
643
1039
  bindModeHandler: App["bindModeHandler"];
1040
+ emitUserFollowIntent: App["emitUserFollowIntent"];
1041
+ requestUnfollow: App["requestUnfollow"];
644
1042
  setAppState: App["setAppState"];
1043
+ isInteractionEnabled: App["isInteractionEnabled"];
1044
+ isNavigationEnabled: App["isNavigationEnabled"];
645
1045
  };
646
1046
  export type PointerDownState = Readonly<{
647
1047
  origin: Readonly<{
@@ -675,8 +1075,12 @@ export type PointerDownState = Readonly<{
675
1075
  element: NonDeleted<ExcalidrawElement> | null;
676
1076
  allHitElements: NonDeleted<ExcalidrawElement>[];
677
1077
  wasAddedToSelection: boolean;
1078
+ cycleTarget: NonDeleted<ExcalidrawElement> | null;
678
1079
  hasBeenDuplicated: boolean;
1080
+ advancedListMarkers: readonly ListMarkerAdvance[];
1081
+ editedTextId: ExcalidrawTextElement["id"] | null;
679
1082
  hasHitCommonBoundingBoxOfSelectedElements: boolean;
1083
+ arrowLabel: boolean;
680
1084
  };
681
1085
  withCmdOrCtrl: boolean;
682
1086
  drag: {
@@ -689,6 +1093,10 @@ export type PointerDownState = Readonly<{
689
1093
  x: number;
690
1094
  y: number;
691
1095
  };
1096
+ lastOffset: {
1097
+ x: number;
1098
+ y: number;
1099
+ };
692
1100
  blockDragging: boolean;
693
1101
  };
694
1102
  eventListeners: {
@@ -724,19 +1132,51 @@ export interface ExcalidrawImperativeAPI {
724
1132
  history: {
725
1133
  clear: InstanceType<typeof App>["resetHistory"];
726
1134
  };
1135
+ /**
1136
+ * Selects elements (or their ids — one or many), adds them to or removes
1137
+ * them from the selection, or clears it — as the editor does: an element is
1138
+ * selected with its group (unless `deep`), a frame and its children aren't
1139
+ * selected at the same time, and locked elements are skipped (unless
1140
+ * `includeLocked`). Text editing and cropping end, and the link popup of a
1141
+ * lone selected element shows. Missing and deleted elements are skipped.
1142
+ *
1143
+ * By default the change is recorded for undo along with the next undoable
1144
+ * change — pass `captureUpdate` as for `updateScene()` otherwise. Like
1145
+ * `updateScene()`, it applies on the next render: read it back through
1146
+ * `onChange()` or `getAppState()` after that. Works in view mode too, where
1147
+ * the selection shows without transform handles.
1148
+ */
1149
+ selection: Pick<InstanceType<typeof App>["selection"], "select" | "add" | "remove" | "clear">;
727
1150
  getSceneElements: InstanceType<typeof App>["getSceneElements"];
728
1151
  getAppState: () => InstanceType<typeof App>["state"];
729
1152
  getFiles: () => InstanceType<typeof App>["files"];
730
1153
  getName: InstanceType<typeof App>["getName"];
731
- scrollToContent: InstanceType<typeof App>["scrollToContent"];
1154
+ setViewport: InstanceType<typeof App>["viewport"]["setViewport"];
1155
+ getViewportOffsets: InstanceType<typeof App>["viewport"]["getOffsets"];
1156
+ /**
1157
+ * Atomically replaces all transient visual overrides. Values are copied;
1158
+ * omitted IDs/fields use document values, except for inherited label offsets.
1159
+ * null clears the snapshot.
1160
+ * Repaints without document changes, history entries or onChange events;
1161
+ * an equivalent snapshot may still repaint (clearing an already clear
1162
+ * snapshot does not), so submit only when something changed.
1163
+ * Finite opacity is clamped to 0–100; non-finite values reject the snapshot.
1164
+ * Unknown/deleted IDs are ignored when rendering. Reset/unmount clears it.
1165
+ * Bound labels inherit their container's offset; offsets targeting them are
1166
+ * ignored. Label opacity remains independent. Target frame children explicitly.
1167
+ * Frame opacity still multiplies child opacity. Decorations follow their owner.
1168
+ * Exports and interactive geometry (hit tests, selection, editing) use document
1169
+ * values, including while authoring an animation preview in edit mode.
1170
+ */
1171
+ setElementRenderOverrides: InstanceType<typeof App>["setElementRenderOverrides"];
732
1172
  registerAction: (action: Action) => void;
733
1173
  refresh: InstanceType<typeof App>["refresh"];
734
1174
  setToast: InstanceType<typeof App>["setToast"];
735
1175
  addFiles: (data: BinaryFileData[]) => void;
736
1176
  id: string;
737
1177
  setActiveTool: InstanceType<typeof App>["setActiveTool"];
738
- setCursor: InstanceType<typeof App>["setCursor"];
739
- resetCursor: InstanceType<typeof App>["resetCursor"];
1178
+ setCursor: InstanceType<typeof App>["cursor"]["set"];
1179
+ resetCursor: InstanceType<typeof App>["cursor"]["reset"];
740
1180
  toggleSidebar: InstanceType<typeof App>["toggleSidebar"];
741
1181
  getEditorInterface: () => EditorInterface;
742
1182
  /**
@@ -759,7 +1199,6 @@ export type FrameNameBounds = {
759
1199
  y: number;
760
1200
  width: number;
761
1201
  height: number;
762
- angle: number;
763
1202
  };
764
1203
  export type FrameNameBoundsCache = {
765
1204
  get: (frameElement: ExcalidrawFrameLikeElement | ExcalidrawMagicFrameElement) => FrameNameBounds | null;
@@ -778,12 +1217,18 @@ export type Primitive = number | string | boolean | bigint | symbol | null | und
778
1217
  export type JSONValue = string | number | boolean | null | object;
779
1218
  export type EmbedsValidationStatus = Map<ExcalidrawIframeLikeElement["id"], boolean>;
780
1219
  export type ElementsPendingErasure = Set<ExcalidrawElement["id"]>;
781
- export type PendingExcalidrawElements = ExcalidrawElement[];
1220
+ export type PendingExcalidrawElements = NonDeletedExcalidrawElement[];
782
1221
  /** Runtime gridSize value. Null indicates disabled grid. */
783
1222
  export type NullableGridSize = (AppState["gridSize"] & MakeBrand<"NullableGridSize">) | null;
784
1223
  export type GenerateDiagramToCode = (props: {
785
- frame: ExcalidrawMagicFrameElement;
786
- children: readonly ExcalidrawElement[];
1224
+ frame: NonDeleted<ExcalidrawMagicFrameElement>;
1225
+ children: readonly NonDeletedExcalidrawElement[];
1226
+ /**
1227
+ * Optional streaming hook. Call with the accumulated response text as it
1228
+ * streams in so the editor can progressively render the partial HTML
1229
+ * inside the generated frame.
1230
+ */
1231
+ onPartial?: (html: string) => void;
787
1232
  }) => MaybePromise<{
788
1233
  html: string;
789
1234
  }>;
@@ -793,3 +1238,103 @@ export type Offsets = Partial<{
793
1238
  bottom: number;
794
1239
  left: number;
795
1240
  }>;
1241
+ /**
1242
+ * Value of the `data-viewport-ui` attribute, marking a DOM node as a UI
1243
+ * surface that occludes the canvas. Such nodes are measured by
1244
+ * `getViewportOffsets` to compute the default per-side viewport offsets:
1245
+ *
1246
+ * - `top` / `bottom` — offsets that side by the node's bottom/top edge
1247
+ * - `side` — a panel hugging the left or right edge. Which side is not
1248
+ * declared but resolved geometrically: if the node's horizontal center
1249
+ * lies in the left half of the viewport it counts against the left
1250
+ * offset (by its right edge), otherwise against the right offset (by
1251
+ * `viewportWidth - left edge`). Measuring the rendered position instead
1252
+ * of declaring a side means RTL layouts and host-configurable docking
1253
+ * (e.g. sidebar side) are handled for free — but it assumes the surface
1254
+ * actually hugs one edge; don't mark a centered/near-full-width node as
1255
+ * `side` (its midpoint would classify it to one side and the offset
1256
+ * would swallow most of the viewport).
1257
+ *
1258
+ * The attribute should only be present while the surface is actually
1259
+ * rendered — omit it (don't just hide the node) when the surface shouldn't
1260
+ * push the viewport around.
1261
+ */
1262
+ export type ViewportUIDock = "top" | "bottom" | "side";
1263
+ /**
1264
+ * Options for `getViewportOffsets` (and the `ui` key of
1265
+ * {@link ViewportOffsets}), controlling how offsets are derived from the
1266
+ * currently rendered editor UI.
1267
+ *
1268
+ * NOTE unlike the physical sides of {@link Offsets}, the horizontal values
1269
+ * here are logical, i.e. flipped in RTL layouts (`left` refers to the
1270
+ * reading-direction start side).
1271
+ */
1272
+ export type ViewportOffsetsOptions = {
1273
+ /** padding added to each measured side (default 24) */
1274
+ padding?: number;
1275
+ paddingTop?: number;
1276
+ paddingRight?: number;
1277
+ paddingBottom?: number;
1278
+ paddingLeft?: number;
1279
+ /** final value for the given side, replacing the measured UI size
1280
+ * (padding is not added on top) */
1281
+ top?: number;
1282
+ bottom?: number;
1283
+ left?: number;
1284
+ right?: number;
1285
+ /**
1286
+ * Reserve space for the given conditionally-rendered surfaces even while
1287
+ * they're hidden, so the resulting offsets don't shift when they
1288
+ * (dis)appear. Uses the surface's last-measured footprint, falling back
1289
+ * to an approximate default if it hasn't been rendered yet. Ignored on
1290
+ * phones (where these surfaces never occlude the canvas).
1291
+ */
1292
+ reserve?: {
1293
+ /** styles panel (rendered when a tool or selection is active) */
1294
+ stylesPanel?: boolean;
1295
+ /** sidebar (e.g. library) */
1296
+ sidebar?: boolean;
1297
+ };
1298
+ };
1299
+ /**
1300
+ * Viewport offsets accepted by the `setViewport`-family APIs (`setViewport`,
1301
+ * `props.initialState.viewport`), insetting the usable viewport area per
1302
+ * side so the target isn't fitted/centered underneath overlaid UI.
1303
+ *
1304
+ * Two (combinable) ways to specify:
1305
+ *
1306
+ * - **Static sides** (`top`/`right`/`bottom`/`left`) — absolute pixel
1307
+ * values, used as-is: physical (not flipped in RTL), zoom-independent,
1308
+ * no padding added. Sides not specified default to `0` (unless `ui` is
1309
+ * set, see below).
1310
+ *
1311
+ * - **`ui`** — derive the offsets from the editor UI (toolbar, styles
1312
+ * panel, sidebar...) as rendered at the time the viewport is set,
1313
+ * equivalent to calling `getViewportOffsets()`. Pass `true` for the
1314
+ * defaults, or options ({@link ViewportOffsetsOptions}) to customize
1315
+ * padding or reserve space for currently-hidden surfaces.
1316
+ *
1317
+ * When both are given, a static side always wins for that side — it
1318
+ * replaces whatever `ui` would yield (including `ui`'s own side overrides,
1319
+ * which — unlike the physical static sides — are RTL-relative). The
1320
+ * remaining sides fall back to the `ui`-derived values.
1321
+ *
1322
+ * @example
1323
+ * { top: 40 } // top 40px, other sides 0
1324
+ * { ui: true } // measured UI + default padding
1325
+ * { ui: { reserve: { stylesPanel: true } } } // + keep space for hidden panel
1326
+ * { top: 40, ui: true } // top exactly 40px, rest from UI
1327
+ */
1328
+ export type ViewportOffsets = Offsets & {
1329
+ ui?: true | ViewportOffsetsOptions;
1330
+ };
1331
+ /**
1332
+ * Value of the `data-viewport-ui-name` attribute, identifying a
1333
+ * conditionally-rendered surface (marked with `data-viewport-ui`) so that
1334
+ * it can be measured on its own, and so that `getViewportOffsets` can
1335
+ * reserve space for it while it's hidden (see the `reserve` option).
1336
+ * Whenever a named surface is rendered, its measured footprint is
1337
+ * remembered; reserving uses that remembered footprint, or an approximate
1338
+ * default if the surface hasn't been rendered yet.
1339
+ */
1340
+ export type ViewportUIName = "sidebar" | "stylesPanel" | "stats";