@excalidraw/math 0.18.0-a9ca16e → 0.18.0-abeeaeb

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 (184) hide show
  1. package/dist/dev/index.js +297 -99
  2. package/dist/dev/index.js.map +4 -4
  3. package/dist/prod/index.js +1 -1
  4. package/dist/types/common/src/colors.d.ts +15 -1
  5. package/dist/types/common/src/constants.d.ts +12 -7
  6. package/dist/types/common/src/keys.d.ts +2 -0
  7. package/dist/types/common/src/points.d.ts +1 -1
  8. package/dist/types/common/src/utils.d.ts +1 -43
  9. package/dist/types/element/src/Scene.d.ts +6 -4
  10. package/dist/types/element/src/align.d.ts +2 -2
  11. package/dist/types/element/src/arrowEndpointText.d.ts +49 -0
  12. package/dist/types/element/src/arrows/focus.d.ts +5 -2
  13. package/dist/types/element/src/binding.d.ts +17 -8
  14. package/dist/types/element/src/bounds.d.ts +22 -7
  15. package/dist/types/element/src/bucketFill.d.ts +110 -0
  16. package/dist/types/element/src/collision.d.ts +1 -1
  17. package/dist/types/element/src/comparisons.d.ts +5 -4
  18. package/dist/types/element/src/convertToShape.d.ts +23 -0
  19. package/dist/types/element/src/distribute.d.ts +2 -2
  20. package/dist/types/element/src/dragElements.d.ts +27 -0
  21. package/dist/types/element/src/duplicate.d.ts +4 -3
  22. package/dist/types/element/src/embeddable.d.ts +2 -2
  23. package/dist/types/element/src/flowchart.d.ts +7 -7
  24. package/dist/types/element/src/fractionalIndex.d.ts +2 -2
  25. package/dist/types/element/src/frame.d.ts +9 -8
  26. package/dist/types/element/src/groups.d.ts +9 -9
  27. package/dist/types/element/src/index.d.ts +4 -1
  28. package/dist/types/element/src/linearElementEditor.d.ts +17 -10
  29. package/dist/types/element/src/newElement.d.ts +14 -0
  30. package/dist/types/element/src/renderElement.d.ts +0 -3
  31. package/dist/types/element/src/resizeElements.d.ts +2 -2
  32. package/dist/types/element/src/selection.d.ts +6 -6
  33. package/dist/types/element/src/shape.d.ts +13 -1
  34. package/dist/types/element/src/sortElements.d.ts +10 -0
  35. package/dist/types/element/src/textElement.d.ts +12 -9
  36. package/dist/types/element/src/transform.d.ts +2 -2
  37. package/dist/types/element/src/typeChecks.d.ts +26 -25
  38. package/dist/types/element/src/types.d.ts +8 -1
  39. package/dist/types/element/src/utils.d.ts +1 -1
  40. package/dist/types/element/src/zindex.d.ts +2 -2
  41. package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +45 -18
  42. package/dist/types/excalidraw/actions/actionAlign.d.ts +6 -6
  43. package/dist/types/excalidraw/actions/actionBoundText.d.ts +30 -12
  44. package/dist/types/excalidraw/actions/actionCanvas.d.ts +167 -940
  45. package/dist/types/excalidraw/actions/actionClipboard.d.ts +30 -12
  46. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +15 -6
  47. package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +47 -19
  48. package/dist/types/excalidraw/actions/{actionEmbeddable.d.ts → actionDeselect.d.ts} +29 -35
  49. package/dist/types/excalidraw/actions/actionDistribute.d.ts +2 -3
  50. package/dist/types/excalidraw/actions/actionElementLink.d.ts +15 -6
  51. package/dist/types/excalidraw/actions/actionElementLock.d.ts +31 -13
  52. package/dist/types/excalidraw/actions/actionExport.d.ts +32 -14
  53. package/dist/types/excalidraw/actions/actionFrame.d.ts +57 -202
  54. package/dist/types/excalidraw/actions/actionGroup.d.ts +45 -27
  55. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +19 -8
  56. package/dist/types/excalidraw/actions/actionLink.d.ts +16 -7
  57. package/dist/types/excalidraw/actions/actionMenu.d.ts +15 -6
  58. package/dist/types/excalidraw/actions/actionProperties.d.ts +60 -30
  59. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +20 -11
  60. package/dist/types/excalidraw/actions/actionStyles.d.ts +15 -6
  61. package/dist/types/excalidraw/actions/actionTextAutoResize.d.ts +1 -1
  62. package/dist/types/excalidraw/actions/actionToggleArrowBinding.d.ts +16 -7
  63. package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +19 -11
  64. package/dist/types/excalidraw/actions/actionToggleMidpointSnapping.d.ts +16 -7
  65. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +16 -7
  66. package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +19 -11
  67. package/dist/types/excalidraw/actions/actionToggleShapeSwitch.d.ts +1 -1
  68. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +16 -7
  69. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +17 -8
  70. package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +16 -7
  71. package/dist/types/excalidraw/actions/index.d.ts +2 -2
  72. package/dist/types/excalidraw/actions/manager.d.ts +1 -0
  73. package/dist/types/excalidraw/actions/shortcuts.d.ts +1 -1
  74. package/dist/types/excalidraw/actions/types.d.ts +8 -4
  75. package/dist/types/excalidraw/{animated-trail.d.ts → animatedTrail.d.ts} +4 -3
  76. package/dist/types/excalidraw/appState.d.ts +12 -5
  77. package/dist/types/excalidraw/components/Actions.d.ts +17 -12
  78. package/dist/types/excalidraw/components/ActiveConfirmDialog.d.ts +1 -1
  79. package/dist/types/excalidraw/components/App.arrowText.d.ts +72 -0
  80. package/dist/types/excalidraw/components/App.bucketFill.d.ts +48 -0
  81. package/dist/types/excalidraw/components/App.cursor.d.ts +30 -0
  82. package/dist/types/excalidraw/components/App.d.ts +363 -66
  83. package/dist/types/excalidraw/components/App.drawshape.d.ts +55 -0
  84. package/dist/types/excalidraw/components/App.flowchart.d.ts +21 -0
  85. package/dist/types/excalidraw/components/App.viewport.d.ts +73 -0
  86. package/dist/types/excalidraw/components/ColorPicker/ColorPicker.d.ts +9 -3
  87. package/dist/types/excalidraw/components/ColorPicker/CustomColorList.d.ts +3 -1
  88. package/dist/types/excalidraw/components/ColorPicker/Picker.d.ts +3 -1
  89. package/dist/types/excalidraw/components/ColorPicker/PickerColorList.d.ts +9 -2
  90. package/dist/types/excalidraw/components/ColorPicker/ShadeList.d.ts +4 -2
  91. package/dist/types/excalidraw/components/ColorPicker/TopPicks.d.ts +8 -1
  92. package/dist/types/excalidraw/components/ColorPicker/colorPickerUtils.d.ts +1 -1
  93. package/dist/types/excalidraw/components/ColorPicker/keyboardNavHandlers.d.ts +2 -1
  94. package/dist/types/excalidraw/components/ColorPicker/topPicksDnD.d.ts +31 -0
  95. package/dist/types/excalidraw/components/CommandPalette/defaultCommandPaletteItems.d.ts +1 -2
  96. package/dist/types/excalidraw/components/ConvertElementTypePopup.d.ts +2 -2
  97. package/dist/types/excalidraw/components/CursorHint.d.ts +46 -0
  98. package/dist/types/excalidraw/components/EyeDropper.d.ts +1 -1
  99. package/dist/types/excalidraw/components/{ToolButton.d.ts → IconButton.d.ts} +16 -19
  100. package/dist/types/excalidraw/components/Island.d.ts +7 -0
  101. package/dist/types/excalidraw/components/LaserPointerButton.d.ts +2 -4
  102. package/dist/types/excalidraw/components/LayerUI.d.ts +5 -2
  103. package/dist/types/excalidraw/components/LibraryMenu.d.ts +1 -1
  104. package/dist/types/excalidraw/components/LockButton.d.ts +3 -4
  105. package/dist/types/excalidraw/components/MagicButton.d.ts +0 -2
  106. package/dist/types/excalidraw/components/MobileMenu.d.ts +4 -4
  107. package/dist/types/excalidraw/components/MobileToolbar.d.ts +9 -0
  108. package/dist/types/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.d.ts +1 -1
  109. package/dist/types/excalidraw/components/PenModeButton.d.ts +2 -5
  110. package/dist/types/excalidraw/components/Popover.d.ts +1 -3
  111. package/dist/types/excalidraw/components/{ButtonIcon.d.ts → RadioButton.d.ts} +2 -5
  112. package/dist/types/excalidraw/components/SVGLayer.d.ts +1 -1
  113. package/dist/types/excalidraw/components/SearchMenu.d.ts +1 -1
  114. package/dist/types/excalidraw/components/Sidebar/Sidebar.d.ts +1 -1
  115. package/dist/types/excalidraw/components/Stats/Angle.d.ts +2 -2
  116. package/dist/types/excalidraw/components/Stats/Dimension.d.ts +2 -2
  117. package/dist/types/excalidraw/components/Stats/DragInput.d.ts +2 -2
  118. package/dist/types/excalidraw/components/Stats/MultiAngle.d.ts +2 -2
  119. package/dist/types/excalidraw/components/Stats/MultiDimension.d.ts +2 -2
  120. package/dist/types/excalidraw/components/Stats/MultiPosition.d.ts +2 -2
  121. package/dist/types/excalidraw/components/Stats/Position.d.ts +3 -3
  122. package/dist/types/excalidraw/components/Stats/utils.d.ts +1 -1
  123. package/dist/types/excalidraw/components/TTDDialog/TTDContext.d.ts +4 -4
  124. package/dist/types/excalidraw/components/TTDDialog/useTTDChatStorage.d.ts +3 -3
  125. package/dist/types/excalidraw/components/ToolPopover.d.ts +3 -6
  126. package/dist/types/excalidraw/components/Toolbar.d.ts +11 -0
  127. package/dist/types/excalidraw/components/Tools.d.ts +146 -0
  128. package/dist/types/excalidraw/components/UserList.d.ts +3 -2
  129. package/dist/types/excalidraw/components/ViewportStatusFrame/ViewportStatusFrame.d.ts +11 -0
  130. package/dist/types/excalidraw/components/canvases/InteractiveCanvas.d.ts +3 -1
  131. package/dist/types/excalidraw/components/canvases/NewElementCanvas.d.ts +1 -0
  132. package/dist/types/excalidraw/components/canvases/StaticCanvas.d.ts +1 -1
  133. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItemContentRadio.d.ts +2 -1
  134. package/dist/types/excalidraw/components/footer/Footer.d.ts +3 -1
  135. package/dist/types/excalidraw/components/hyperlink/helpers.d.ts +2 -2
  136. package/dist/types/excalidraw/components/icons.d.ts +6 -1
  137. package/dist/types/excalidraw/components/main-menu/DefaultItems.d.ts +8 -4
  138. package/dist/types/excalidraw/components/positionElementBesideCursor.d.ts +26 -0
  139. package/dist/types/excalidraw/components/shapeActionPredicates.d.ts +39 -0
  140. package/dist/types/excalidraw/data/blob.d.ts +34 -16
  141. package/dist/types/excalidraw/data/index.d.ts +4 -4
  142. package/dist/types/excalidraw/data/json.d.ts +23 -14
  143. package/dist/types/excalidraw/data/library.d.ts +1 -1
  144. package/dist/types/excalidraw/drawShapeTrail.d.ts +16 -0
  145. package/dist/types/excalidraw/eraser/index.d.ts +2 -3
  146. package/dist/types/excalidraw/hooks/useAppStateValue.d.ts +29 -0
  147. package/dist/types/excalidraw/hooks/useLibraryItemSvg.d.ts +1 -1
  148. package/dist/types/excalidraw/{laser-trails.d.ts → laserTrails.d.ts} +5 -7
  149. package/dist/types/excalidraw/lasso/index.d.ts +2 -3
  150. package/dist/types/excalidraw/lasso/utils.d.ts +2 -0
  151. package/dist/types/excalidraw/renderer/animation.d.ts +5 -1
  152. package/dist/types/excalidraw/renderer/interactiveScene.d.ts +1 -3
  153. package/dist/types/excalidraw/scene/Renderer.d.ts +426 -19
  154. package/dist/types/excalidraw/scene/export.d.ts +3 -3
  155. package/dist/types/excalidraw/scene/index.d.ts +2 -2
  156. package/dist/types/excalidraw/scene/types.d.ts +4 -3
  157. package/dist/types/excalidraw/snapping.d.ts +7 -7
  158. package/dist/types/excalidraw/types.d.ts +415 -23
  159. package/dist/types/excalidraw/viewport.d.ts +275 -0
  160. package/dist/types/excalidraw/wysiwyg/textWysiwyg.d.ts +2 -3
  161. package/dist/types/fractional-indexing/src/index.d.ts +29 -0
  162. package/dist/types/laser-pointer/src/index.d.ts +2 -0
  163. package/dist/types/laser-pointer/src/math.d.ts +16 -0
  164. package/dist/types/laser-pointer/src/simplify.d.ts +2 -0
  165. package/dist/types/laser-pointer/src/state.d.ts +36 -0
  166. package/dist/types/math/src/constants.d.ts +0 -1
  167. package/dist/types/math/src/curve.d.ts +4 -1
  168. package/dist/types/math/src/index.d.ts +1 -0
  169. package/dist/types/math/src/pca.d.ts +79 -0
  170. package/dist/types/math/src/point.d.ts +1 -0
  171. package/dist/types/math/src/polygon.d.ts +25 -1
  172. package/dist/types/utils/src/export.d.ts +3 -3
  173. package/dist/types/utils/src/index.d.ts +1 -2
  174. package/package.json +2 -2
  175. package/dist/types/excalidraw/animation-frame-handler.d.ts +0 -16
  176. package/dist/types/excalidraw/components/FollowMode/FollowMode.d.ts +0 -10
  177. package/dist/types/excalidraw/components/HandButton.d.ts +0 -10
  178. package/dist/types/excalidraw/components/MobileToolBar.d.ts +0 -10
  179. package/dist/types/excalidraw/components/shapes.d.ts +0 -263
  180. package/dist/types/excalidraw/cursor.d.ts +0 -5
  181. package/dist/types/excalidraw/scene/scroll.d.ts +0 -18
  182. package/dist/types/excalidraw/scene/zoom.d.ts +0 -12
  183. package/dist/types/utils/src/bbox.d.ts +0 -9
  184. package/dist/types/utils/src/withinBounds.d.ts +0 -19
@@ -1,7 +1,7 @@
1
- import type { IMAGE_MIME_TYPES, UserIdleState, throttleRAF, MIME_TYPES, EditorInterface } from "@excalidraw/common";
1
+ import type { IMAGE_MIME_TYPES, UserIdleState, throttleRAF, MIME_TYPES, EditorInterface, StrokeWidthKey } from "@excalidraw/common";
2
2
  import type { LinearElementEditor } from "@excalidraw/element";
3
3
  import type { MaybeTransformHandleType } from "@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 "@excalidraw/element/types";
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 "@excalidraw/element/types";
5
5
  import type { Merge, MaybePromise, ValueOf, MakeBrand } from "@excalidraw/common/utility-types";
6
6
  import type { CaptureUpdateActionType, DurableIncrement, EphemeralIncrement } from "@excalidraw/element";
7
7
  import type { GlobalPoint } from "@excalidraw/math";
@@ -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" | "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
+ hoveredArrowTextAnchor: AppState["hoveredArrowTextAnchor"];
142
145
  isRotating: AppState["isRotating"];
143
146
  elementsToHighlight: AppState["elementsToHighlight"];
144
147
  collaborators: AppState["collaborators"];
@@ -172,6 +175,42 @@ export type ObservedElementsAppState = {
172
175
  lockedMultiSelections: AppState["lockedMultiSelections"];
173
176
  activeLockedId: AppState["activeLockedId"];
174
177
  };
178
+ export type BoxSelectionMode = "contain" | "overlap";
179
+ /**
180
+ * A box, in scene coordinates, that pan & zoom are constrained to.
181
+ *
182
+ * This is a private type. For public API, only use specific properties,
183
+ * needed.
184
+ */
185
+ export type ScrollConstraints = {
186
+ x: number;
187
+ y: number;
188
+ width: number;
189
+ height: number;
190
+ /** when set, panning is constrained so the viewport stays within the box */
191
+ lockScroll: boolean;
192
+ /** when set, the viewport cannot zoom out below `zoom` */
193
+ lockZoom: boolean;
194
+ /**
195
+ * The zoom resolved after the `setViewport` navigation settled.
196
+ */
197
+ zoom: number;
198
+ /**
199
+ * Pixel amount the viewport may overscroll past its resting clamp before
200
+ * snapping back (rubberband). Screen pixels, zoom-independent. Resolved
201
+ * from `lock.overscroll` at the time the lock was installed (`true` →
202
+ * default give, `false` → 0).
203
+ */
204
+ overscroll: number;
205
+ /**
206
+ * Extra scrollable margin around the box (CSS-style), letting the viewport
207
+ * scroll past each box edge to reveal that much empty space. Values are
208
+ * viewport pixels and zoom-independent (a fixed on-screen distance).
209
+ * Resolved from the `offsets` passed to `setViewport` (see
210
+ * {@link ViewportOffsets}) at the time the lock was installed.
211
+ */
212
+ offsets?: Offsets;
213
+ };
175
214
  export interface AppState {
176
215
  contextMenu: {
177
216
  items: ContextMenuItems;
@@ -210,15 +249,29 @@ export interface AppState {
210
249
  * `bindingPreference` and keyboard modifiers (ctrl/alt)
211
250
  */
212
251
  isBindingEnabled: boolean;
252
+ /** user box selection preference; defaults to "contain" when unset */
253
+ boxSelectionMode: BoxSelectionMode;
213
254
  /** user arrow binding preference */
214
255
  bindingPreference: "enabled" | "disabled";
215
256
  /** user preference whether arrow snap to midpoints while binding */
216
257
  isMidpointSnappingEnabled: boolean;
217
- startBoundElement: NonDeleted<ExcalidrawBindableElement> | null;
258
+ /**
259
+ * The bindable element the UI highlights for the user when an arrow is
260
+ * dragged or otherwise its endpoint being close to said element.
261
+ */
218
262
  suggestedBinding: {
219
263
  element: NonDeleted<ExcalidrawBindableElement>;
220
264
  midPoint?: GlobalPoint;
221
265
  } | null;
266
+ /**
267
+ * Where on a hovered arrow the text tool would attach text if clicked —
268
+ * a free endpoint (binds the arrow to a new text element positioned against
269
+ * that endpoint) or the arrow's midpoint (adds a label bound to the arrow).
270
+ */
271
+ hoveredArrowTextAnchor: {
272
+ elementId: ExcalidrawArrowElement["id"];
273
+ anchor: "start" | "end" | "label";
274
+ } | null;
222
275
  frameToHighlight: NonDeleted<ExcalidrawFrameLikeElement> | null;
223
276
  frameRendering: {
224
277
  enabled: boolean;
@@ -226,8 +279,11 @@ export interface AppState {
226
279
  outline: boolean;
227
280
  clip: boolean;
228
281
  };
229
- editingFrame: string | null;
230
- elementsToHighlight: NonDeleted<ExcalidrawElement>[] | null;
282
+ /**
283
+ * frame-like element whose name is currently being edited
284
+ */
285
+ editingFrame: ExcalidrawFrameLikeElement["id"] | null;
286
+ elementsToHighlight: readonly NonDeletedExcalidrawElement[] | null;
231
287
  /**
232
288
  * set when a new text is created or when an existing text is being edited
233
289
  */
@@ -254,9 +310,10 @@ export interface AppState {
254
310
  currentItemStrokeColor: string;
255
311
  currentItemBackgroundColor: string;
256
312
  currentItemFillStyle: ExcalidrawElement["fillStyle"];
257
- currentItemStrokeWidth: number;
313
+ currentItemStrokeWidthKey: StrokeWidthKey;
258
314
  currentItemStrokeStyle: ExcalidrawElement["strokeStyle"];
259
315
  currentItemRoughness: number;
316
+ currentItemStrokeVariability: StrokeVariability;
260
317
  currentItemOpacity: number;
261
318
  currentItemFontFamily: FontFamilyValues;
262
319
  currentItemFontSize: number;
@@ -269,6 +326,7 @@ export interface AppState {
269
326
  viewBackgroundColor: string;
270
327
  scrollX: number;
271
328
  scrollY: number;
329
+ scrollConstraints: ScrollConstraints | null;
272
330
  cursorButton: "up" | "down";
273
331
  scrolledOutside: boolean;
274
332
  name: string | null;
@@ -356,10 +414,6 @@ export interface AppState {
356
414
  y: number;
357
415
  } | null;
358
416
  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
417
  /** image cropping */
364
418
  isCropping: boolean;
365
419
  croppingElementId: ExcalidrawElement["id"] | null;
@@ -374,6 +428,17 @@ export interface AppState {
374
428
  [groupId: string]: true;
375
429
  };
376
430
  bindMode: BindMode;
431
+ /** user-customized color-picker top picks (pinned via drag & drop from the
432
+ * color picker popup). `null` means no customization (defaults, or
433
+ * host-supplied `topPicks`, are used). Kept per picker. */
434
+ colorTopPicks: {
435
+ elementStroke: readonly string[] | null;
436
+ elementBackground: readonly string[] | null;
437
+ /** the bucket-fill tool keeps a list separate from `elementBackground`
438
+ * even though both drive `currentItemBackgroundColor` (its defaults and
439
+ * use case differ — no transparent) */
440
+ bucketFill: readonly string[] | null;
441
+ };
377
442
  }
378
443
  export type SearchMatch = {
379
444
  id: string;
@@ -386,7 +451,7 @@ export type SearchMatch = {
386
451
  showOnCanvas: boolean;
387
452
  }[];
388
453
  };
389
- export type UIAppState = Omit<AppState, "startBoundElement" | "cursorButton" | "scrollX" | "scrollY">;
454
+ export type UIAppState = Omit<AppState, "cursorButton" | "scrollX" | "scrollY" | "zoom" | "shouldCacheIgnoreZoom" | "snapLines" | "originSnapOffset" | "suggestedBinding" | "hoveredArrowTextAnchor" | "frameToHighlight" | "elementsToHighlight">;
390
455
  export type NormalizedZoomValue = number & {
391
456
  _brand: "normalizedZoom";
392
457
  };
@@ -430,23 +495,151 @@ export type LibraryItemsSource = ((currentLibraryItems: LibraryItems) => MaybePr
430
495
  export type ExcalidrawInitialDataState = Merge<ImportedDataState, {
431
496
  libraryItems?: MaybePromise<Required<ImportedDataState>["libraryItems"]>;
432
497
  }>;
498
+ export type ExcalidrawInitialState = {
499
+ viewport?: Omit<SetViewportOptions, "animation">;
500
+ };
433
501
  export type OnUserFollowedPayload = {
434
502
  userToFollow: UserToFollow;
435
503
  action: "FOLLOW" | "UNFOLLOW";
436
504
  };
505
+ export type ViewportStatusFrame = {
506
+ /** the badge (bottom-center pill) */
507
+ label?: {
508
+ label: React.ReactNode;
509
+ icon?: React.ReactNode;
510
+ /** badge background; defaults to var(--color-primary-hover) */
511
+ background?: string;
512
+ /** badge text color; defaults to var(--color-primary-light) */
513
+ color?: string;
514
+ /** makes the badge label interactive */
515
+ onClick?: () => void;
516
+ /** renders a close button when set */
517
+ onClose?: () => void;
518
+ };
519
+ /** viewport-edge border: CSS color, or `false` for none */
520
+ border: false | string;
521
+ };
437
522
  export type OnExportProgress = {
438
523
  type: "progress";
439
524
  message?: React.ReactNode;
440
525
  /** 0-1 range */
441
526
  progress?: number;
442
527
  };
528
+ export type InteractionConfig = {
529
+ /**
530
+ * Interactions that stay enabled while the editor is otherwise
531
+ * non-interactive. Opt-in: anything omitted or `false` is disabled.
532
+ */
533
+ enabled?: {
534
+ /**
535
+ * Element links render their link icon and stay clickable — clicking
536
+ * anywhere on a linked element opens the link, same as in view mode.
537
+ * When disabled, link icons are not rendered at all.
538
+ *
539
+ * @default false
540
+ */
541
+ links?: boolean;
542
+ /**
543
+ * Embeddable & iframe elements stay interactive — hovering & clicking
544
+ * activates them so their content can be used, same as in view mode.
545
+ *
546
+ * @default false
547
+ */
548
+ embeds?: boolean;
549
+ /**
550
+ * Umbrella for all interactive content on canvas — shorthand for
551
+ * enabling `links` & `embeds` (and future interactive content kinds)
552
+ * together. Additive: `interactiveContent: true` enables them
553
+ * regardless of their individual values.
554
+ *
555
+ * @default false
556
+ */
557
+ interactiveContent?: boolean;
558
+ /**
559
+ * Canvas navigation — panning (pointer drag, wheel, PageUp/PageDown)
560
+ * and zooming (ctrl/cmd + wheel, pinch, and the canvas zoom &
561
+ * zoom-to-fit shortcuts: ctrl/cmd +/-/0, shift+1/2/3), same as in view
562
+ * mode. Respects `appState.scrollConstraints` if set, so it composes
563
+ * with viewport locking. The rest of the keyboard stays disabled. Note
564
+ * the editor consumes wheel & touch input again when enabled, so the
565
+ * page no longer scrolls over the editor.
566
+ *
567
+ * @default false
568
+ */
569
+ navigation?: boolean;
570
+ /**
571
+ * Whether the browser's own zoom remains available over the editor —
572
+ * ctrl/cmd + wheel, pinch, and (while the editor has focus)
573
+ * ctrl/cmd +/-/0 shortcuts. Prevented by default, mirroring the
574
+ * interactive editor. Regular page scrolling stays available either way.
575
+ * With `navigation` enabled, the zoom input (wheel, pinch, keyboard
576
+ * shortcuts) zooms the canvas instead either way, making this moot.
577
+ *
578
+ * @default false
579
+ */
580
+ browserZoom?: boolean;
581
+ /**
582
+ * Tools that stay user-driven while the editor is otherwise
583
+ * non-interactive: pointer input keeps driving the listed tool when it's
584
+ * the active tool. Does not enable user-driven tool *switching* — the
585
+ * keyboard stays disabled and tool selection remains host-driven
586
+ * (`ExcalidrawAPI.setActiveTool`).
587
+ *
588
+ * Composes with `navigation`: the enabled tool wins the primary-pointer
589
+ * drag, while wheel input (and wheel-button drag) still pans/zooms.
590
+ */
591
+ tools?: {
592
+ /**
593
+ * The laser pointer stays usable — pointer strokes draw laser trails
594
+ * and pointer positions keep broadcasting via `onPointerUpdate`, so
595
+ * e.g. collaborators see a presenter's laser & cursor.
596
+ *
597
+ * @default false
598
+ */
599
+ laser?: boolean;
600
+ /**
601
+ * Custom tools (`activeTool.type === "custom"`) stay usable — the
602
+ * editor keeps dispatching `onPointerDown` / `onPointerUp` for them.
603
+ * Tool behavior is host-implemented; activate custom tools with
604
+ * `locked: true` or they revert to the selection tool (and go inert)
605
+ * after the first pointer interaction.
606
+ *
607
+ * @default false
608
+ */
609
+ custom?: boolean;
610
+ };
611
+ };
612
+ };
613
+ export type UIConfig = {
614
+ /**
615
+ * Default UI controls that stay enabled while the rest of Excalidraw's
616
+ * default UI is hidden. Opt-in: anything omitted or `false` is disabled.
617
+ */
618
+ enabled: {
619
+ /**
620
+ * The zoom-out, reset-zoom, and zoom-in controls.
621
+ *
622
+ * @default false
623
+ */
624
+ zoom?: boolean;
625
+ /**
626
+ * The button shown when the viewport is scrolled away from all content.
627
+ *
628
+ * @default false
629
+ */
630
+ scrollBackToContent?: boolean;
631
+ };
632
+ };
443
633
  export interface ExcalidrawProps {
634
+ className?: string;
444
635
  onChange?: (elements: readonly OrderedExcalidrawElement[], appState: AppState, files: BinaryFiles) => void;
636
+ onThemeChange?: (theme: Theme | "system") => void;
445
637
  /**
446
638
  * note: only subscribes if the props.onIncrement is defined on initial render
447
639
  */
448
640
  onIncrement?: (event: DurableIncrement | EphemeralIncrement) => void;
449
641
  initialData?: (() => MaybePromise<ExcalidrawInitialDataState | null>) | MaybePromise<ExcalidrawInitialDataState | null>;
642
+ initialState?: ExcalidrawInitialState;
450
643
  /**
451
644
  * Invoked as soon as the Excalidraw API is available
452
645
  * NOTE editor is not yet mounted, and state is not yet initialized
@@ -493,6 +686,70 @@ export interface ExcalidrawProps {
493
686
  renderTopRightUI?: (isMobile: boolean, appState: UIAppState) => JSX.Element | null;
494
687
  langCode?: Language["code"];
495
688
  viewModeEnabled?: boolean;
689
+ /**
690
+ * Whether the editor accepts user input (pointer, keyboard, wheel, touch,
691
+ * clipboard, drag&drop). When `false`, the scene still renders and reacts
692
+ * to programmatic updates (imperative API), but the user cannot affect it
693
+ * in any way. Implies view mode.
694
+ *
695
+ * Pass a config object to keep specific interactions enabled while the
696
+ * editor is otherwise non-interactive (see `InteractionConfig`):
697
+ *
698
+ * ```tsx
699
+ * <Excalidraw interaction={{ enabled: { links: true } }} />
700
+ * ```
701
+ *
702
+ * @default true
703
+ */
704
+ interaction?: boolean | InteractionConfig;
705
+ /**
706
+ * Whether Excalidraw's default UI is rendered — toolbar, default menus,
707
+ * footer controls, sidebars, and canvas popups. Host UI passed through
708
+ * children (including exported components such as `MainMenu` and `Footer`)
709
+ * or render props continues to render, together with any supporting dialogs
710
+ * it opens.
711
+ *
712
+ * Canvas content (elements, text editing surface, frame names, embeds) still
713
+ * renders, and the editor remains interactive unless `interaction` is set to
714
+ * `false`.
715
+ *
716
+ * Pass a config object to keep specific default controls rendered while the
717
+ * rest of the default UI is hidden (see `UIConfig`):
718
+ *
719
+ * ```tsx
720
+ * <Excalidraw ui={{ enabled: { zoom: true } }} />
721
+ * ```
722
+ *
723
+ * NOTE: this is WIP and what default UI is/is not rendered when ui=false
724
+ * may yet change.
725
+ *
726
+ * @default true
727
+ */
728
+ ui?: boolean | UIConfig;
729
+ /**
730
+ * Forces the active editor tool (controlled). While set, user- and
731
+ * API-driven tool switching is ignored — `setActiveTool` refuses with a
732
+ * console warning, non-forced toolbar buttons render disabled — and the
733
+ * editor snaps back if internal flows reset the tool. The forced tool
734
+ * behaves as if locked (see the tool lock / padlock): it doesn't revert to
735
+ * the selection tool after use, and elements drawn with it aren't
736
+ * auto-selected — without mutating `appState.activeTool.locked`, so the
737
+ * user's persisted padlock preference stays untouched. Unset to return
738
+ * tool control to the editor (the current tool stays active).
739
+ *
740
+ * The forced tool must be activatable to take effect: not disabled via
741
+ * `UIOptions.tools`, and — while the editor is non-interactive — allowed
742
+ * via `interaction.enabled.tools`. Otherwise the editor stays on (or, when
743
+ * non-interactive, resets to) the `selection` tool, and the forced tool is
744
+ * applied once it becomes activatable. `image` cannot be forced (its
745
+ * activation opens the file picker).
746
+ */
747
+ activeTool?: {
748
+ type: Exclude<ToolType, "image">;
749
+ } | {
750
+ type: "custom";
751
+ customType: string;
752
+ };
496
753
  zenModeEnabled?: boolean;
497
754
  gridModeEnabled?: boolean;
498
755
  objectsSnapModeEnabled?: boolean;
@@ -501,6 +758,10 @@ export interface ExcalidrawProps {
501
758
  name?: string;
502
759
  renderCustomStats?: (elements: readonly NonDeletedExcalidrawElement[], appState: UIAppState) => JSX.Element;
503
760
  UIOptions?: Partial<UIOptions>;
761
+ /**
762
+ * dimensions and size constraints for inserted images
763
+ */
764
+ imageOptions?: ImageOptions;
504
765
  detectScroll?: boolean;
505
766
  handleKeyboardGlobally?: boolean;
506
767
  onLibraryChange?: (libraryItems: LibraryItems) => void | Promise<any>;
@@ -520,6 +781,21 @@ export interface ExcalidrawProps {
520
781
  aiEnabled?: boolean;
521
782
  showDeprecatedFonts?: boolean;
522
783
  renderScrollbars?: boolean;
784
+ viewportStatusFrame?: ViewportStatusFrame | null;
785
+ /**
786
+ * Rendered inside the UserList "who's here" dropdown (desktop) and inline
787
+ * in the mobile menu's collaborators section, below a divider. Accepts a
788
+ * render function — called with `isMobile` so hosts can render different
789
+ * UI for each surface — in addition to a plain node.
790
+ */
791
+ currentUserControls?: React.ReactNode | ((isMobile: boolean) => React.ReactNode);
792
+ /**
793
+ * The user being followed on the canvas, if any. Controlled by the host —
794
+ * the editor never sets it; it emits follow/unfollow intents via
795
+ * `onUserFollow` (prop or imperative API) and renders the followed
796
+ * user's avatar highlight from this value.
797
+ */
798
+ userToFollow?: UserToFollow | null;
523
799
  /**
524
800
  * Called before exporting to a file.
525
801
  *
@@ -555,12 +831,21 @@ export type ExportOpts = {
555
831
  onExportToBackend?: (exportedElements: readonly NonDeletedExcalidrawElement[], appState: UIAppState, files: BinaryFiles) => void;
556
832
  renderCustomUI?: (exportedElements: readonly NonDeletedExcalidrawElement[], appState: UIAppState, files: BinaryFiles, canvas: HTMLCanvasElement) => JSX.Element;
557
833
  };
834
+ export type ImageOptions = Partial<{
835
+ maxWidthOrHeight: number;
836
+ maxFileSizeBytes: number;
837
+ }>;
558
838
  export type CanvasActions = Partial<{
559
839
  changeViewBackgroundColor: boolean;
560
840
  clearCanvas: boolean;
561
841
  export: false | ExportOpts;
562
842
  loadScene: boolean;
563
843
  saveToActiveFile: boolean;
844
+ /**
845
+ * defaults to true if `props.theme` is omitted or `props.onThemeChange`
846
+ * is supplied (at which point the theme is considered as host-app controlled),
847
+ * else default to false
848
+ * */
564
849
  toggleTheme: boolean | null;
565
850
  saveAsImage: boolean;
566
851
  }>;
@@ -584,6 +869,7 @@ export type AppProps = Merge<ExcalidrawProps, {
584
869
  export: ExportOpts;
585
870
  };
586
871
  }>;
872
+ imageOptions: Required<ImageOptions>;
587
873
  detectScroll: boolean;
588
874
  handleKeyboardGlobally: boolean;
589
875
  isCollaborating: boolean;
@@ -615,8 +901,7 @@ export type AppClassProperties = {
615
901
  id: App["id"];
616
902
  onInsertElements: App["onInsertElements"];
617
903
  onExportImage: App["onExportImage"];
618
- lastViewportPosition: App["lastViewportPosition"];
619
- scrollToContent: App["scrollToContent"];
904
+ viewport: App["viewport"];
620
905
  addFiles: App["addFiles"];
621
906
  addElementsFromPasteOrLibrary: App["addElementsFromPasteOrLibrary"];
622
907
  togglePenMode: App["togglePenMode"];
@@ -627,11 +912,14 @@ export type AppClassProperties = {
627
912
  onMagicframeToolSelect: App["onMagicframeToolSelect"];
628
913
  getName: App["getName"];
629
914
  dismissLinearEditor: App["dismissLinearEditor"];
630
- flowChartCreator: App["flowChartCreator"];
915
+ flowchart: App["flowchart"];
916
+ drawShape: App["drawShape"];
917
+ cursor: App["cursor"];
918
+ bucketFill: App["bucketFill"];
919
+ isToolLocked: App["isToolLocked"];
631
920
  getEffectiveGridSize: App["getEffectiveGridSize"];
632
921
  setPlugins: App["setPlugins"];
633
922
  plugins: App["plugins"];
634
- getEditorUIOffsets: App["getEditorUIOffsets"];
635
923
  visibleElements: App["visibleElements"];
636
924
  excalidrawContainerValue: App["excalidrawContainerValue"];
637
925
  onPointerUpEmitter: App["onPointerUpEmitter"];
@@ -640,8 +928,13 @@ export type AppClassProperties = {
640
928
  onEvent: App["onEvent"];
641
929
  onStateChange: App["onStateChange"];
642
930
  lastPointerMoveCoords: App["lastPointerMoveCoords"];
931
+ lastPointerMoveEvent: App["lastPointerMoveEvent"];
643
932
  bindModeHandler: App["bindModeHandler"];
933
+ emitUserFollowIntent: App["emitUserFollowIntent"];
934
+ requestUnfollow: App["requestUnfollow"];
644
935
  setAppState: App["setAppState"];
936
+ isInteractionEnabled: App["isInteractionEnabled"];
937
+ isNavigationEnabled: App["isNavigationEnabled"];
645
938
  };
646
939
  export type PointerDownState = Readonly<{
647
940
  origin: Readonly<{
@@ -728,15 +1021,16 @@ export interface ExcalidrawImperativeAPI {
728
1021
  getAppState: () => InstanceType<typeof App>["state"];
729
1022
  getFiles: () => InstanceType<typeof App>["files"];
730
1023
  getName: InstanceType<typeof App>["getName"];
731
- scrollToContent: InstanceType<typeof App>["scrollToContent"];
1024
+ setViewport: InstanceType<typeof App>["viewport"]["setViewport"];
1025
+ getViewportOffsets: InstanceType<typeof App>["viewport"]["getOffsets"];
732
1026
  registerAction: (action: Action) => void;
733
1027
  refresh: InstanceType<typeof App>["refresh"];
734
1028
  setToast: InstanceType<typeof App>["setToast"];
735
1029
  addFiles: (data: BinaryFileData[]) => void;
736
1030
  id: string;
737
1031
  setActiveTool: InstanceType<typeof App>["setActiveTool"];
738
- setCursor: InstanceType<typeof App>["setCursor"];
739
- resetCursor: InstanceType<typeof App>["resetCursor"];
1032
+ setCursor: InstanceType<typeof App>["cursor"]["set"];
1033
+ resetCursor: InstanceType<typeof App>["cursor"]["reset"];
740
1034
  toggleSidebar: InstanceType<typeof App>["toggleSidebar"];
741
1035
  getEditorInterface: () => EditorInterface;
742
1036
  /**
@@ -759,7 +1053,6 @@ export type FrameNameBounds = {
759
1053
  y: number;
760
1054
  width: number;
761
1055
  height: number;
762
- angle: number;
763
1056
  };
764
1057
  export type FrameNameBoundsCache = {
765
1058
  get: (frameElement: ExcalidrawFrameLikeElement | ExcalidrawMagicFrameElement) => FrameNameBounds | null;
@@ -778,12 +1071,12 @@ export type Primitive = number | string | boolean | bigint | symbol | null | und
778
1071
  export type JSONValue = string | number | boolean | null | object;
779
1072
  export type EmbedsValidationStatus = Map<ExcalidrawIframeLikeElement["id"], boolean>;
780
1073
  export type ElementsPendingErasure = Set<ExcalidrawElement["id"]>;
781
- export type PendingExcalidrawElements = ExcalidrawElement[];
1074
+ export type PendingExcalidrawElements = NonDeletedExcalidrawElement[];
782
1075
  /** Runtime gridSize value. Null indicates disabled grid. */
783
1076
  export type NullableGridSize = (AppState["gridSize"] & MakeBrand<"NullableGridSize">) | null;
784
1077
  export type GenerateDiagramToCode = (props: {
785
- frame: ExcalidrawMagicFrameElement;
786
- children: readonly ExcalidrawElement[];
1078
+ frame: NonDeleted<ExcalidrawMagicFrameElement>;
1079
+ children: readonly NonDeletedExcalidrawElement[];
787
1080
  }) => MaybePromise<{
788
1081
  html: string;
789
1082
  }>;
@@ -793,3 +1086,102 @@ export type Offsets = Partial<{
793
1086
  bottom: number;
794
1087
  left: number;
795
1088
  }>;
1089
+ /**
1090
+ * Value of the `data-viewport-ui` attribute, marking a DOM node as a UI
1091
+ * surface that occludes the canvas. Such nodes are measured by
1092
+ * `getViewportOffsets` to compute the default per-side viewport offsets:
1093
+ *
1094
+ * - `top` / `bottom` — offsets that side by the node's bottom/top edge
1095
+ * - `side` — a panel hugging the left or right edge. Which side is not
1096
+ * declared but resolved geometrically: if the node's horizontal center
1097
+ * lies in the left half of the viewport it counts against the left
1098
+ * offset (by its right edge), otherwise against the right offset (by
1099
+ * `viewportWidth - left edge`). Measuring the rendered position instead
1100
+ * of declaring a side means RTL layouts and host-configurable docking
1101
+ * (e.g. sidebar side) are handled for free — but it assumes the surface
1102
+ * actually hugs one edge; don't mark a centered/near-full-width node as
1103
+ * `side` (its midpoint would classify it to one side and the offset
1104
+ * would swallow most of the viewport).
1105
+ *
1106
+ * The attribute should only be present while the surface is actually
1107
+ * rendered — omit it (don't just hide the node) when the surface shouldn't
1108
+ * push the viewport around.
1109
+ */
1110
+ export type ViewportUIDock = "top" | "bottom" | "side";
1111
+ /**
1112
+ * Options for `getViewportOffsets` (and the `ui` key of
1113
+ * {@link ViewportOffsets}), controlling how offsets are derived from the
1114
+ * currently rendered editor UI.
1115
+ *
1116
+ * NOTE unlike the physical sides of {@link Offsets}, the horizontal values
1117
+ * here are logical, i.e. flipped in RTL layouts (`left` refers to the
1118
+ * reading-direction start side).
1119
+ */
1120
+ export type ViewportOffsetsOptions = {
1121
+ /** padding added to each measured side (default 24) */
1122
+ padding?: number;
1123
+ paddingTop?: number;
1124
+ paddingRight?: number;
1125
+ paddingBottom?: number;
1126
+ paddingLeft?: number;
1127
+ /** final value for the given side, replacing the measured UI size
1128
+ * (padding is not added on top) */
1129
+ top?: number;
1130
+ bottom?: number;
1131
+ left?: number;
1132
+ right?: number;
1133
+ /**
1134
+ * Reserve space for the given conditionally-rendered surfaces even while
1135
+ * they're hidden, so the resulting offsets don't shift when they
1136
+ * (dis)appear. Uses the surface's last-measured footprint, falling back
1137
+ * to an approximate default if it hasn't been rendered yet. Ignored on
1138
+ * phones (where these surfaces never occlude the canvas).
1139
+ */
1140
+ reserve?: {
1141
+ /** styles panel (rendered when a tool or selection is active) */
1142
+ stylesPanel?: boolean;
1143
+ /** sidebar (e.g. library) */
1144
+ sidebar?: boolean;
1145
+ };
1146
+ };
1147
+ /**
1148
+ * Viewport offsets accepted by the `setViewport`-family APIs (`setViewport`,
1149
+ * `props.initialState.viewport`), insetting the usable viewport area per
1150
+ * side so the target isn't fitted/centered underneath overlaid UI.
1151
+ *
1152
+ * Two (combinable) ways to specify:
1153
+ *
1154
+ * - **Static sides** (`top`/`right`/`bottom`/`left`) — absolute pixel
1155
+ * values, used as-is: physical (not flipped in RTL), zoom-independent,
1156
+ * no padding added. Sides not specified default to `0` (unless `ui` is
1157
+ * set, see below).
1158
+ *
1159
+ * - **`ui`** — derive the offsets from the editor UI (toolbar, styles
1160
+ * panel, sidebar...) as rendered at the time the viewport is set,
1161
+ * equivalent to calling `getViewportOffsets()`. Pass `true` for the
1162
+ * defaults, or options ({@link ViewportOffsetsOptions}) to customize
1163
+ * padding or reserve space for currently-hidden surfaces.
1164
+ *
1165
+ * When both are given, a static side always wins for that side — it
1166
+ * replaces whatever `ui` would yield (including `ui`'s own side overrides,
1167
+ * which — unlike the physical static sides — are RTL-relative). The
1168
+ * remaining sides fall back to the `ui`-derived values.
1169
+ *
1170
+ * @example
1171
+ * { top: 40 } // top 40px, other sides 0
1172
+ * { ui: true } // measured UI + default padding
1173
+ * { ui: { reserve: { stylesPanel: true } } } // + keep space for hidden panel
1174
+ * { top: 40, ui: true } // top exactly 40px, rest from UI
1175
+ */
1176
+ export type ViewportOffsets = Offsets & {
1177
+ ui?: true | ViewportOffsetsOptions;
1178
+ };
1179
+ /**
1180
+ * Value of the `data-viewport-ui-name` attribute, identifying a
1181
+ * conditionally-rendered surface (marked with `data-viewport-ui`) so that
1182
+ * `getViewportOffsets` can reserve space for it while it's hidden (see the
1183
+ * `reserve` option). Whenever a named surface is rendered, its measured
1184
+ * footprint is remembered; reserving uses that remembered footprint, or an
1185
+ * approximate default if the surface hasn't been rendered yet.
1186
+ */
1187
+ export type ViewportUIName = "sidebar" | "stylesPanel";