@excalidraw/element 0.18.0-ab0255f → 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 (53) hide show
  1. package/dist/dev/index.js +1 -0
  2. package/dist/dev/index.js.map +2 -2
  3. package/dist/prod/index.js +1 -1
  4. package/dist/types/common/src/colors.d.ts +5 -7
  5. package/dist/types/element/src/sortElements.d.ts +10 -0
  6. package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +15 -6
  7. package/dist/types/excalidraw/actions/actionBoundText.d.ts +10 -4
  8. package/dist/types/excalidraw/actions/actionCanvas.d.ts +35 -14
  9. package/dist/types/excalidraw/actions/actionClipboard.d.ts +10 -4
  10. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +5 -2
  11. package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +15 -6
  12. package/dist/types/excalidraw/actions/actionDeselect.d.ts +5 -2
  13. package/dist/types/excalidraw/actions/actionElementLink.d.ts +5 -2
  14. package/dist/types/excalidraw/actions/actionElementLock.d.ts +10 -4
  15. package/dist/types/excalidraw/actions/actionExport.d.ts +10 -4
  16. package/dist/types/excalidraw/actions/actionFrame.d.ts +15 -6
  17. package/dist/types/excalidraw/actions/actionGroup.d.ts +11 -5
  18. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +5 -2
  19. package/dist/types/excalidraw/actions/actionLink.d.ts +5 -2
  20. package/dist/types/excalidraw/actions/actionMenu.d.ts +5 -2
  21. package/dist/types/excalidraw/actions/actionProperties.d.ts +10 -4
  22. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +5 -2
  23. package/dist/types/excalidraw/actions/actionStyles.d.ts +5 -2
  24. package/dist/types/excalidraw/actions/actionToggleArrowBinding.d.ts +5 -2
  25. package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +5 -2
  26. package/dist/types/excalidraw/actions/actionToggleMidpointSnapping.d.ts +5 -2
  27. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +5 -2
  28. package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +5 -2
  29. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +5 -2
  30. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +5 -2
  31. package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +5 -2
  32. package/dist/types/excalidraw/appState.d.ts +5 -0
  33. package/dist/types/excalidraw/components/App.bucketFill.d.ts +14 -0
  34. package/dist/types/excalidraw/components/App.cursor.d.ts +2 -3
  35. package/dist/types/excalidraw/components/App.d.ts +12 -5
  36. package/dist/types/excalidraw/components/ColorPicker/ColorPicker.d.ts +6 -2
  37. package/dist/types/excalidraw/components/ColorPicker/CustomColorList.d.ts +3 -1
  38. package/dist/types/excalidraw/components/ColorPicker/Picker.d.ts +2 -1
  39. package/dist/types/excalidraw/components/ColorPicker/PickerColorList.d.ts +4 -2
  40. package/dist/types/excalidraw/components/ColorPicker/ShadeList.d.ts +4 -2
  41. package/dist/types/excalidraw/components/ColorPicker/TopPicks.d.ts +8 -1
  42. package/dist/types/excalidraw/components/ColorPicker/topPicksDnD.d.ts +31 -0
  43. package/dist/types/excalidraw/components/LayerUI.d.ts +2 -1
  44. package/dist/types/excalidraw/components/UserList.d.ts +3 -2
  45. package/dist/types/excalidraw/components/ViewportStatusFrame/ViewportStatusFrame.d.ts +11 -0
  46. package/dist/types/excalidraw/components/icons.d.ts +3 -0
  47. package/dist/types/excalidraw/data/blob.d.ts +10 -4
  48. package/dist/types/excalidraw/data/json.d.ts +5 -2
  49. package/dist/types/excalidraw/lasso/utils.d.ts +2 -0
  50. package/dist/types/excalidraw/types.d.ts +47 -4
  51. package/dist/types/excalidraw/viewport.d.ts +5 -2
  52. package/package.json +4 -4
  53. package/dist/types/excalidraw/components/FollowMode/FollowMode.d.ts +0 -10
@@ -157,8 +157,6 @@ export declare const actionToggleZenMode: {
157
157
  y: number;
158
158
  } | null;
159
159
  objectsSnapModeEnabled: boolean;
160
- userToFollow: import("../types").UserToFollow | null;
161
- followedBy: Set<import("../types").SocketId>;
162
160
  isCropping: boolean;
163
161
  croppingElementId: import("@excalidraw/element/types").ExcalidrawElement["id"] | null;
164
162
  searchMatches: Readonly<{
@@ -170,6 +168,11 @@ export declare const actionToggleZenMode: {
170
168
  [groupId: string]: true;
171
169
  };
172
170
  bindMode: import("@excalidraw/element/types").BindMode;
171
+ colorTopPicks: {
172
+ elementStroke: readonly string[] | null;
173
+ elementBackground: readonly string[] | null;
174
+ bucketFill: readonly string[] | null;
175
+ };
173
176
  };
174
177
  captureUpdate: "EVENTUALLY";
175
178
  };
@@ -78,6 +78,11 @@ export declare const clearAppStateForLocalStorage: (appState: Partial<AppState>)
78
78
  lockedMultiSelections?: {
79
79
  [groupId: string]: true;
80
80
  } | undefined;
81
+ colorTopPicks?: {
82
+ elementStroke: readonly string[] | null;
83
+ elementBackground: readonly string[] | null;
84
+ bucketFill: readonly string[] | null;
85
+ } | undefined;
81
86
  };
82
87
  export declare const cleanAppStateForExport: (appState: Partial<AppState>) => {
83
88
  viewBackgroundColor?: string | undefined;
@@ -1,3 +1,4 @@
1
+ import type { Theme } from "@excalidraw/element/types";
1
2
  import type App from "./App";
2
3
  type ScenePoint = {
3
4
  x: number;
@@ -7,6 +8,7 @@ type ScenePoint = {
7
8
  export declare class AppBucketFill {
8
9
  private app;
9
10
  constructor(app: App);
11
+ private temporaryEyeDropper;
10
12
  /**
11
13
  * The click armed on pointer down, committed on pointer up. Deferring the
12
14
  * scene mutation to pointer up is what lets a pinch/pan second finger, a
@@ -24,11 +26,23 @@ export declare class AppBucketFill {
24
26
  handlePointerUp: () => void;
25
27
  /** Abort the armed fill (second finger, context menu, pointercancel). */
26
28
  cancel: () => void;
29
+ cycleBackgroundColor: () => void;
30
+ openTemporaryEyeDropper: () => void;
31
+ closeTemporaryEyeDropper: () => void;
27
32
  /**
28
33
  * Apply the current bucket fill settings to an existing fill-compatible
29
34
  * element (no-op when nothing would change). One undoable step.
30
35
  */
31
36
  private restyle;
32
37
  private fill;
38
+ /**
39
+ * The color the bucket fill tool actually fills with: the shared
40
+ * `currentItemBackgroundColor`, falling back to green when that is
41
+ * transparent (the tool's picker doesn't offer transparent, but the shared
42
+ * state can hold it from the generic shape picker).
43
+ */
44
+ getBucketFillBackgroundColor: (backgroundColor: string,
45
+ /** supply only for display purposes such as when applying to the cursor */
46
+ theme?: Theme) => string;
33
47
  }
34
48
  export {};
@@ -1,5 +1,5 @@
1
- import type App from "./App";
2
1
  import type { AppState } from "../types";
2
+ import type App from "./App";
3
3
  /**
4
4
  * Captures all cursor management for the interactive canvas.
5
5
  *
@@ -10,10 +10,9 @@ import type { AppState } from "../types";
10
10
  */
11
11
  export declare class AppCursor {
12
12
  private app;
13
+ private toolCursorMemo;
13
14
  private eraserCanvasCache;
14
15
  private eraserPreviewDataURL;
15
- private drawShapeCanvasCache;
16
- private drawShapePreviewDataURL;
17
16
  constructor(app: App);
18
17
  private get canvas();
19
18
  set: (cursor: string) => void;
@@ -338,10 +338,11 @@ declare class App extends React.Component<AppProps, AppState> {
338
338
  isToolLocked(): boolean;
339
339
  /**
340
340
  * Whether the active tool captures the primary pointer instead of the
341
- * view-mode drag-to-pan — the laser always does; while non-interactive,
342
- * any tool allowed via `interaction.enabled.tools` does. (Editing tools
343
- * capture the pointer trivially since view mode implies they're not
344
- * active; this predicate only matters where view-mode gates apply.)
341
+ * view-mode drag-to-pan — the laser and host-implemented custom tools do;
342
+ * while non-interactive, any tool allowed via
343
+ * `interaction.enabled.tools` does. (Editing tools capture the pointer
344
+ * trivially since view mode implies they're not active; this predicate only
345
+ * matters where view-mode gates apply.)
345
346
  */
346
347
  isActiveToolPointerCapturing(): boolean;
347
348
  /** Whether Excalidraw's full default UI is rendered. */
@@ -476,7 +477,13 @@ declare class App extends React.Component<AppProps, AppState> {
476
477
  updateFrameRendering: (opts: Partial<AppState["frameRendering"]> | ((prevState: AppState["frameRendering"]) => Partial<AppState["frameRendering"]>)) => void;
477
478
  togglePenMode: (force: boolean | null) => void;
478
479
  revealIfHidden: (elements: NonDeletedExcalidrawElement[]) => void;
479
- private maybeUnfollowRemoteUser;
480
+ /** emits a follow/unfollow intent to the host (which owns the
481
+ * `userToFollow` state) via both the `onUserFollow` prop and the
482
+ * imperative API emitter */
483
+ emitUserFollowIntent: (payload: OnUserFollowedPayload) => void;
484
+ /** emits an UNFOLLOW intent if currently following someone — use on
485
+ * user-initiated viewport changes which should break follow mode */
486
+ requestUnfollow: () => void;
480
487
  setToast: (toast: AppState["toast"]) => void;
481
488
  restoreFileFromShare: () => Promise<void>;
482
489
  /**
@@ -2,7 +2,7 @@ import type { ColorTuple, ColorPaletteCustom } from "@excalidraw/common";
2
2
  import type { ExcalidrawElement } from "@excalidraw/element/types";
3
3
  import "./ColorPicker.scss";
4
4
  import type { ColorPickerType } from "./colorPickerUtils";
5
- import type { UIAppState } from "../../types";
5
+ import type { AppState, UIAppState } from "../../types";
6
6
  interface ColorPickerProps {
7
7
  type: ColorPickerType;
8
8
  /**
@@ -19,6 +19,10 @@ interface ColorPickerProps {
19
19
  updateData: (formData?: any) => void;
20
20
  /** palette colors to hide from the popup, keeping hotkey positions */
21
21
  excludedColors?: readonly string[];
22
+ /** allow users to customize the top picks strip by drag & dropping colors
23
+ * from the picker popup onto it. The value names the
24
+ * `appState.colorTopPicks` slot the customization is stored in */
25
+ customizableTopPicks?: keyof AppState["colorTopPicks"];
22
26
  }
23
- export declare const ColorPicker: ({ type, color, onChange, label, elements, palette, topPicks, updateData, appState, excludedColors, }: ColorPickerProps) => import("react/jsx-runtime").JSX.Element;
27
+ export declare const ColorPicker: import("react").MemoExoticComponent<({ type, color, onChange, label, elements, palette, topPicks, updateData, appState, excludedColors, customizableTopPicks, }: ColorPickerProps) => import("react/jsx-runtime").JSX.Element>;
24
28
  export {};
@@ -1,8 +1,10 @@
1
+ import type { Theme } from "@excalidraw/element/types";
1
2
  interface CustomColorListProps {
3
+ theme: Theme;
2
4
  colors: string[];
3
5
  color: string | null;
4
6
  onChange: (color: string) => void;
5
7
  label: string;
6
8
  }
7
- export declare const CustomColorList: ({ colors, color, onChange, label, }: CustomColorListProps) => import("react/jsx-runtime").JSX.Element;
9
+ export declare const CustomColorList: ({ theme, colors, color, onChange, label, }: CustomColorListProps) => import("react/jsx-runtime").JSX.Element;
8
10
  export {};
@@ -1,8 +1,9 @@
1
1
  import React from "react";
2
- import type { ExcalidrawElement } from "@excalidraw/element/types";
2
+ import type { ExcalidrawElement, Theme } from "@excalidraw/element/types";
3
3
  import type { ColorPaletteCustom } from "@excalidraw/common";
4
4
  import type { ColorPickerType } from "./colorPickerUtils";
5
5
  interface PickerProps {
6
+ theme: Theme;
6
7
  color: string | null;
7
8
  onChange: (color: string) => void;
8
9
  type: ColorPickerType;
@@ -1,5 +1,7 @@
1
- import type { ColorPaletteCustom } from "@excalidraw/common";
1
+ import { type ColorPaletteCustom } from "@excalidraw/common";
2
+ import type { Theme } from "@excalidraw/element/types";
2
3
  interface PickerColorListProps {
4
+ theme: Theme;
3
5
  palette: ColorPaletteCustom;
4
6
  color: string | null;
5
7
  onChange: (color: string) => void;
@@ -11,5 +13,5 @@ interface PickerColorListProps {
11
13
  */
12
14
  excludedColors?: readonly string[];
13
15
  }
14
- declare const PickerColorList: ({ palette, color, onChange, activeShade, showHotKey, excludedColors, }: PickerColorListProps) => import("react/jsx-runtime").JSX.Element;
16
+ declare const PickerColorList: ({ theme, palette, color, onChange, activeShade, showHotKey, excludedColors, }: PickerColorListProps) => import("react/jsx-runtime").JSX.Element;
15
17
  export default PickerColorList;
@@ -1,9 +1,11 @@
1
- import type { ColorPaletteCustom } from "@excalidraw/common";
1
+ import { type ColorPaletteCustom } from "@excalidraw/common";
2
+ import type { Theme } from "@excalidraw/element/types";
2
3
  interface ShadeListProps {
4
+ theme: Theme;
3
5
  color: string | null;
4
6
  onChange: (color: string) => void;
5
7
  palette: ColorPaletteCustom;
6
8
  showHotKey?: boolean;
7
9
  }
8
- export declare const ShadeList: ({ color, onChange, palette, showHotKey, }: ShadeListProps) => import("react/jsx-runtime").JSX.Element;
10
+ export declare const ShadeList: ({ theme, color, onChange, palette, showHotKey, }: ShadeListProps) => import("react/jsx-runtime").JSX.Element;
9
11
  export {};
@@ -1,9 +1,16 @@
1
+ import type { Theme } from "@excalidraw/element/types";
1
2
  import type { ColorPickerType } from "./colorPickerUtils";
2
3
  interface TopPicksProps {
4
+ theme: Theme;
3
5
  onChange: (color: string) => void;
4
6
  type: ColorPickerType;
5
7
  activeColor: string | null;
6
8
  topPicks?: readonly string[];
9
+ /** present when the strip is user-customizable — enables the right-click
10
+ * context menu resetting the strip to its default picks */
11
+ onReset?: () => void;
12
+ /** whether custom picks are currently applied (enables the reset item) */
13
+ isCustomized?: boolean;
7
14
  }
8
- export declare const TopPicks: ({ onChange, type, activeColor, topPicks, }: TopPicksProps) => import("react/jsx-runtime").JSX.Element | null;
15
+ export declare const TopPicks: ({ theme, onChange, type, activeColor, topPicks, onReset, isCustomized, }: TopPicksProps) => import("react/jsx-runtime").JSX.Element | null;
9
16
  export {};
@@ -0,0 +1,31 @@
1
+ type DragOrigin = {
2
+ kind: "swatch";
3
+ } | {
4
+ kind: "pick";
5
+ index: number;
6
+ };
7
+ export type TopPicksDragState = {
8
+ color: string;
9
+ origin: DragOrigin;
10
+ /** hovered strip slot — the slot to replace (swatch drags) or the final
11
+ * position (pick reorders). null while the pointer is outside the strip */
12
+ overIndex: number | null;
13
+ /** index of an already-pinned identical color that blocks the drop */
14
+ duplicateIndex: number | null;
15
+ /** signed distance between strip slot centers (for reorder preview) */
16
+ slotSpan: number;
17
+ } | null;
18
+ export type ColorPickerDnD = {
19
+ dragState: TopPicksDragState;
20
+ startSwatchDrag: (event: React.PointerEvent, color: string | null) => void;
21
+ startPickDrag: (event: React.PointerEvent, index: number, color: string) => void;
22
+ setStripEl: (el: HTMLDivElement | null) => void;
23
+ };
24
+ export declare const ColorPickerDnDContext: import("react").Context<ColorPickerDnD | null>;
25
+ export declare const useColorPickerDnD: () => ColorPickerDnD | null;
26
+ export declare const useTopPicksDnD: ({ enabled, picks, onPicksChange, }: {
27
+ enabled: boolean;
28
+ picks: readonly string[];
29
+ onPicksChange: (picks: string[]) => void;
30
+ }) => ColorPickerDnD;
31
+ export {};
@@ -29,6 +29,7 @@ interface LayerUIProps {
29
29
  scrollBackToContentUIEnabled: boolean;
30
30
  isCollaborating: boolean;
31
31
  generateLinkForSelection?: AppProps["generateLinkForSelection"];
32
+ currentUserControls?: ExcalidrawProps["currentUserControls"];
32
33
  }
33
- declare const _default: React.MemoExoticComponent<({ actionManager, appState, files, setAppState, elements, canvas, onLockToggle, onPenModeToggle, showExitZenModeBtn, renderTopLeftUI, renderTopRightUI, renderCustomStats, UIOptions, onExportImage, renderWelcomeScreen, children, app, defaultUIEnabled, zoomUIEnabled, scrollBackToContentUIEnabled, isCollaborating, generateLinkForSelection, }: LayerUIProps) => import("react/jsx-runtime").JSX.Element>;
34
+ declare const _default: React.MemoExoticComponent<({ actionManager, appState, files, setAppState, elements, canvas, onLockToggle, onPenModeToggle, showExitZenModeBtn, renderTopLeftUI, renderTopRightUI, renderCustomStats, UIOptions, onExportImage, renderWelcomeScreen, children, app, defaultUIEnabled, zoomUIEnabled, scrollBackToContentUIEnabled, isCollaborating, generateLinkForSelection, currentUserControls, }: LayerUIProps) => import("react/jsx-runtime").JSX.Element>;
34
35
  export default _default;
@@ -7,12 +7,13 @@ export type GoToCollaboratorComponentProps = {
7
7
  withName: boolean;
8
8
  isBeingFollowed: boolean;
9
9
  };
10
- type UserListUserObject = Pick<Collaborator, "avatarUrl" | "id" | "socketId" | "username" | "isInCall" | "isSpeaking" | "isMuted">;
10
+ type UserListUserObject = Pick<Collaborator, "avatarUrl" | "id" | "socketId" | "username" | "isInCall" | "isSpeaking" | "isMuted" | "isCurrentUser">;
11
11
  type UserListProps = {
12
12
  className?: string;
13
13
  mobile?: boolean;
14
14
  collaborators: Map<SocketId, UserListUserObject>;
15
15
  userToFollow: SocketId | null;
16
+ currentUserControls?: React.ReactNode | ((isMobile: boolean) => React.ReactNode);
16
17
  };
17
- export declare const UserList: React.MemoExoticComponent<({ className, mobile, collaborators, userToFollow }: UserListProps) => import("react/jsx-runtime").JSX.Element>;
18
+ export declare const UserList: React.MemoExoticComponent<({ className, mobile, collaborators, userToFollow, currentUserControls, }: UserListProps) => import("react/jsx-runtime").JSX.Element>;
18
19
  export {};
@@ -0,0 +1,11 @@
1
+ import "./ViewportStatusFrame.scss";
2
+ import type { CSSProperties } from "react";
3
+ import type { ViewportStatusFrame as ViewportStatusFrameType } from "../../types";
4
+ export declare const ViewportStatusBorder: ({ border, style, }: {
5
+ border: string;
6
+ style?: CSSProperties;
7
+ }) => import("react/jsx-runtime").JSX.Element;
8
+ export declare const ViewportStatusBadge: ({ label, border, }: {
9
+ label: NonNullable<ViewportStatusFrameType["label"]>;
10
+ border?: ViewportStatusFrameType["border"];
11
+ }) => import("react/jsx-runtime").JSX.Element;
@@ -57,6 +57,7 @@ export declare const saveAs: import("react/jsx-runtime").JSX.Element;
57
57
  export declare const LoadIcon: import("react/jsx-runtime").JSX.Element;
58
58
  export declare const clipboard: import("react/jsx-runtime").JSX.Element;
59
59
  export declare const palette: import("react/jsx-runtime").JSX.Element;
60
+ export declare const bucketFillIconSvgPaths: readonly ["M5 16l1.465 1.638a2 2 0 1 1 -3.015 .099l1.55 -1.737z", "M13.737 9.737c2.299 -2.3 3.23 -5.095 2.081 -6.245c-1.15 -1.15 -3.945 -.217 -6.244 2.082c-2.3 2.299 -3.231 5.095 -2.082 6.244c1.15 1.15 3.946 .218 6.245 -2.081z", "M7.492 11.818c.362 .362 .768 .676 1.208 .934l6.895 4.047c1.078 .557 2.255 -.075 3.692 -1.512c1.437 -1.437 2.07 -2.614 1.512 -3.692c-.372 -.718 -1.72 -3.017 -4.047 -6.895a6.015 6.015 0 0 0 -.934 -1.208"];
60
61
  export declare const bucketFillIcon: import("react/jsx-runtime").JSX.Element;
61
62
  export declare const slashIcon: import("react/jsx-runtime").JSX.Element;
62
63
  export declare const ExportImageIcon: import("react/jsx-runtime").JSX.Element;
@@ -196,6 +197,7 @@ export declare const playerPlayIcon: import("react/jsx-runtime").JSX.Element;
196
197
  export declare const playerStopFilledIcon: import("react/jsx-runtime").JSX.Element;
197
198
  export declare const tablerCheckIcon: import("react/jsx-runtime").JSX.Element;
198
199
  export declare const alertTriangleIcon: import("react/jsx-runtime").JSX.Element;
200
+ export declare const eyeDropperIconSvgPaths: readonly ["M4 16l11.7 -11.7a1 1 0 0 1 1.4 0l2.6 2.6a1 1 0 0 1 0 1.4l-11.7 11.7h-4v-4z", "M11 7l6 6"];
199
201
  export declare const eyeDropperIcon: import("react/jsx-runtime").JSX.Element;
200
202
  export declare const frameToolIcon: import("react/jsx-runtime").JSX.Element;
201
203
  export declare const mermaidLogoIcon: import("react/jsx-runtime").JSX.Element;
@@ -250,6 +252,7 @@ export declare const sidebarRightIcon: import("react/jsx-runtime").JSX.Element;
250
252
  export declare const messageCircleIcon: import("react/jsx-runtime").JSX.Element;
251
253
  export declare const presentationIcon: import("react/jsx-runtime").JSX.Element;
252
254
  export declare const emptyIcon: import("react/jsx-runtime").JSX.Element;
255
+ export declare const chevronDownIcon: import("react/jsx-runtime").JSX.Element;
253
256
  export declare const chevronRight: import("react/jsx-runtime").JSX.Element;
254
257
  export declare const settingsIcon: import("react/jsx-runtime").JSX.Element;
255
258
  export {};
@@ -172,11 +172,14 @@ fileHandle?: FileSystemFileHandle | null) => Promise<{
172
172
  y: number;
173
173
  } | null;
174
174
  objectsSnapModeEnabled: boolean;
175
- userToFollow: import("../types").UserToFollow | null;
176
- followedBy: Set<import("../types").SocketId>;
177
175
  lockedMultiSelections: {
178
176
  [groupId: string]: true;
179
177
  };
178
+ colorTopPicks: {
179
+ elementStroke: readonly string[] | null;
180
+ elementBackground: readonly string[] | null;
181
+ bucketFill: readonly string[] | null;
182
+ };
180
183
  };
181
184
  files: import("../types").BinaryFiles;
182
185
  };
@@ -343,11 +346,14 @@ fileHandle?: FileSystemFileHandle | null) => Promise<{
343
346
  y: number;
344
347
  } | null;
345
348
  objectsSnapModeEnabled: boolean;
346
- userToFollow: import("../types").UserToFollow | null;
347
- followedBy: Set<import("../types").SocketId>;
348
349
  lockedMultiSelections: {
349
350
  [groupId: string]: true;
350
351
  };
352
+ colorTopPicks: {
353
+ elementStroke: readonly string[] | null;
354
+ elementBackground: readonly string[] | null;
355
+ bucketFill: readonly string[] | null;
356
+ };
351
357
  };
352
358
  files: import("../types").BinaryFiles;
353
359
  }>;
@@ -170,11 +170,14 @@ export declare const loadFromJSON: (localAppState: AppState, localElements: read
170
170
  y: number;
171
171
  } | null;
172
172
  objectsSnapModeEnabled: boolean;
173
- userToFollow: import("../types").UserToFollow | null;
174
- followedBy: Set<import("../types").SocketId>;
175
173
  lockedMultiSelections: {
176
174
  [groupId: string]: true;
177
175
  };
176
+ colorTopPicks: {
177
+ elementStroke: readonly string[] | null;
178
+ elementBackground: readonly string[] | null;
179
+ bucketFill: readonly string[] | null;
180
+ };
178
181
  };
179
182
  files: BinaryFiles;
180
183
  }>;
@@ -1,5 +1,6 @@
1
1
  import type { ElementsSegmentsMap, GlobalPoint } from "@excalidraw/math/types";
2
2
  import type { ElementsMap, ExcalidrawElement } from "@excalidraw/element/types";
3
+ import type { BoxSelectionMode } from "../types";
3
4
  export declare const getLassoSelectedElementIds: (input: {
4
5
  lassoPath: GlobalPoint[];
5
6
  elements: readonly ExcalidrawElement[];
@@ -8,6 +9,7 @@ export declare const getLassoSelectedElementIds: (input: {
8
9
  intersectedElements: Set<ExcalidrawElement["id"]>;
9
10
  enclosedElements: Set<ExcalidrawElement["id"]>;
10
11
  simplifyDistance?: number;
12
+ mode?: BoxSelectionMode;
11
13
  }) => {
12
14
  selectedElementIds: string[];
13
15
  };
@@ -414,10 +414,6 @@ export interface AppState {
414
414
  y: number;
415
415
  } | null;
416
416
  objectsSnapModeEnabled: boolean;
417
- /** the user's socket id & username who is being followed on the canvas */
418
- userToFollow: UserToFollow | null;
419
- /** the socket ids of the users following the current user */
420
- followedBy: Set<SocketId>;
421
417
  /** image cropping */
422
418
  isCropping: boolean;
423
419
  croppingElementId: ExcalidrawElement["id"] | null;
@@ -432,6 +428,17 @@ export interface AppState {
432
428
  [groupId: string]: true;
433
429
  };
434
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
+ };
435
442
  }
436
443
  export type SearchMatch = {
437
444
  id: string;
@@ -495,6 +502,23 @@ export type OnUserFollowedPayload = {
495
502
  userToFollow: UserToFollow;
496
503
  action: "FOLLOW" | "UNFOLLOW";
497
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
+ };
498
522
  export type OnExportProgress = {
499
523
  type: "progress";
500
524
  message?: React.ReactNode;
@@ -607,6 +631,7 @@ export type UIConfig = {
607
631
  };
608
632
  };
609
633
  export interface ExcalidrawProps {
634
+ className?: string;
610
635
  onChange?: (elements: readonly OrderedExcalidrawElement[], appState: AppState, files: BinaryFiles) => void;
611
636
  onThemeChange?: (theme: Theme | "system") => void;
612
637
  /**
@@ -756,6 +781,21 @@ export interface ExcalidrawProps {
756
781
  aiEnabled?: boolean;
757
782
  showDeprecatedFonts?: boolean;
758
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;
759
799
  /**
760
800
  * Called before exporting to a file.
761
801
  *
@@ -875,6 +915,7 @@ export type AppClassProperties = {
875
915
  flowchart: App["flowchart"];
876
916
  drawShape: App["drawShape"];
877
917
  cursor: App["cursor"];
918
+ bucketFill: App["bucketFill"];
878
919
  isToolLocked: App["isToolLocked"];
879
920
  getEffectiveGridSize: App["getEffectiveGridSize"];
880
921
  setPlugins: App["setPlugins"];
@@ -889,6 +930,8 @@ export type AppClassProperties = {
889
930
  lastPointerMoveCoords: App["lastPointerMoveCoords"];
890
931
  lastPointerMoveEvent: App["lastPointerMoveEvent"];
891
932
  bindModeHandler: App["bindModeHandler"];
933
+ emitUserFollowIntent: App["emitUserFollowIntent"];
934
+ requestUnfollow: App["requestUnfollow"];
892
935
  setAppState: App["setAppState"];
893
936
  isInteractionEnabled: App["isInteractionEnabled"];
894
937
  isNavigationEnabled: App["isNavigationEnabled"];
@@ -233,8 +233,6 @@ export declare const zoomToFitBounds: ({ bounds, appState, canvasOffsets, fit, m
233
233
  y: number;
234
234
  } | null;
235
235
  objectsSnapModeEnabled: boolean;
236
- userToFollow: import("./types").UserToFollow | null;
237
- followedBy: Set<import("./types").SocketId>;
238
236
  isCropping: boolean;
239
237
  croppingElementId: ExcalidrawElement["id"] | null;
240
238
  searchMatches: Readonly<{
@@ -246,6 +244,11 @@ export declare const zoomToFitBounds: ({ bounds, appState, canvasOffsets, fit, m
246
244
  [groupId: string]: true;
247
245
  };
248
246
  bindMode: import("@excalidraw/element/types").BindMode;
247
+ colorTopPicks: {
248
+ elementStroke: readonly string[] | null;
249
+ elementBackground: readonly string[] | null;
250
+ bucketFill: readonly string[] | null;
251
+ };
249
252
  };
250
253
  captureUpdate: "EVENTUALLY";
251
254
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@excalidraw/element",
3
- "version": "0.18.0-ab0255f",
3
+ "version": "0.18.0-abeeaeb",
4
4
  "type": "module",
5
5
  "types": "./dist/types/element/src/index.d.ts",
6
6
  "main": "./dist/prod/index.js",
@@ -63,8 +63,8 @@
63
63
  "build:esm": "rimraf dist && node ../../scripts/buildBase.js && yarn gen:types"
64
64
  },
65
65
  "dependencies": {
66
- "@excalidraw/common": "0.18.0-ab0255f",
67
- "@excalidraw/math": "0.18.0-ab0255f",
68
- "@excalidraw/fractional-indexing": "0.18.0-ab0255f"
66
+ "@excalidraw/common": "0.18.0-abeeaeb",
67
+ "@excalidraw/math": "0.18.0-abeeaeb",
68
+ "@excalidraw/fractional-indexing": "0.18.0-abeeaeb"
69
69
  }
70
70
  }
@@ -1,10 +0,0 @@
1
- import "./FollowMode.scss";
2
- import type { UserToFollow } from "../../types";
3
- interface FollowModeProps {
4
- width: number;
5
- height: number;
6
- userToFollow: UserToFollow;
7
- onDisconnect: () => void;
8
- }
9
- declare const FollowMode: ({ height, width, userToFollow, onDisconnect, }: FollowModeProps) => import("react/jsx-runtime").JSX.Element;
10
- export default FollowMode;