Repository: excalidraw/excalidraw
File: src/types.ts (TypeScript)

Code before:
        | typeof SHAPES[number]["value"]
        | "eraser"
        | "hand"
        | "frame"
        | "embeddable";
      customType: null;
    }
  | {
      type: "custom";
      customType: string;
    }
  | null;

export type SidebarName = string;
export type SidebarTabName = string;

export type CommonCanvasAppState = {
  zoom: AppState["zoom"];
  scrollX: AppState["scrollX"];
  scrollY: AppState["scrollY"];
  width: AppState["width"];
  height: AppState["height"];
  viewModeEnabled: AppState["viewModeEnabled"];
  editingElement: AppState["editingElement"];
  editingGroupId: AppState["editingGroupId"]; // TODO: move to interactive canvas if possible
  selectedElementIds: AppState["selectedElementIds"]; // TODO: move to interactive canvas if possible
  frameToHighlight: AppState["frameToHighlight"]; // TODO: move to interactive canvas if possible
  offsetLeft: AppState["offsetLeft"];
  offsetTop: AppState["offsetTop"];
  theme: AppState["theme"];
  pendingImageElementId: AppState["pendingImageElementId"];
};

export type StaticCanvasAppState = CommonCanvasAppState & {
  shouldCacheIgnoreZoom: AppState["shouldCacheIgnoreZoom"];
  /** null indicates transparent bg */
  viewBackgroundColor: AppState["viewBackgroundColor"] | null;
  exportScale: AppState["exportScale"];
  selectedElementsAreBeingDragged: AppState["selectedElementsAreBeingDragged"];
  gridSize: AppState["gridSize"];
  frameRendering: AppState["frameRendering"];
};

export type InteractiveCanvasAppState = CommonCanvasAppState & {
  // renderInteractiveScene
  activeEmbeddable: AppState["activeEmbeddable"];
  editingLinearElement: AppState["editingLinearElement"];
  selectionElement: AppState["selectionElement"];
  selectedGroupIds: AppState["selectedGroupIds"];
  selectedLinearElement: AppState["selectedLinearElement"];
  multiElement: AppState["multiElement"];

Review comment (bug):
I've made the TODO comment because these three props conceptually did not seem like a reason for re-rendering the StaticCanvas - all of them seemed related only to the interactive part.

It looks like my assumption was incorrect here, but it still feels confusing and IMO should be still refactored away (not necessarily as part of this fix).

Code after:
        | typeof SHAPES[number]["value"]
        | "eraser"
        | "hand"
        | "frame"
        | "embeddable";
      customType: null;
    }
  | {
      type: "custom";
      customType: string;
    }
  | null;

export type SidebarName = string;
export type SidebarTabName = string;

type _CommonCanvasAppState = {
  zoom: AppState["zoom"];
  scrollX: AppState["scrollX"];
  scrollY: AppState["scrollY"];
  width: AppState["width"];
  height: AppState["height"];
  viewModeEnabled: AppState["viewModeEnabled"];
  editingGroupId: AppState["editingGroupId"]; // TODO: move to interactive canvas if possible
  selectedElementIds: AppState["selectedElementIds"]; // TODO: move to interactive canvas if possible
  frameToHighlight: AppState["frameToHighlight"]; // TODO: move to interactive canvas if possible
  offsetLeft: AppState["offsetLeft"];
  offsetTop: AppState["offsetTop"];
  theme: AppState["theme"];
  pendingImageElementId: AppState["pendingImageElementId"];
};

export type StaticCanvasAppState = Readonly<
  _CommonCanvasAppState & {
    shouldCacheIgnoreZoom: AppState["shouldCacheIgnoreZoom"];
    /** null indicates transparent bg */
    viewBackgroundColor: AppState["viewBackgroundColor"] | null;
    exportScale: AppState["exportScale"];
    selectedElementsAreBeingDragged: AppState["selectedElementsAreBeingDragged"];
    gridSize: AppState["gridSize"];
    frameRendering: AppState["frameRendering"];
  }
>;

export type InteractiveCanvasAppState = Readonly<
  _CommonCanvasAppState & {
    // renderInteractiveScene
    activeEmbeddable: AppState["activeEmbeddable"];
    editingLinearElement: AppState["editingLinearElement"];
    selectionElement: AppState["selectionElement"];
    selectedGroupIds: AppState["selectedGroupIds"];